craig-cli 0.7.12 → 0.8.0

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 (3) hide show
  1. package/README.md +5 -0
  2. package/dist/cli.js +46 -46
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- var kl=Object.defineProperty;var gr=(e,t)=>{for(var r in t)kl(e,r,{get:t[r],enumerable:!0})};import{readFile as Pl}from"node:fs/promises";import{randomUUID as wl}from"node:crypto";import{open as Tl,readFile as wf,rename as Rl,rm as yl}from"node:fs/promises";import hr from"node:path";async function N(e,t){let r=hr.dirname(e),n=hr.join(r,`.${hr.basename(e)}.${process.pid}.${Date.now()}.${wl()}.tmp`),s=await Tl(n,"w");try{let o=`${JSON.stringify(t,null,2)}
3
- `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Rl(n,e)}catch(o){throw await s.close().catch(()=>{}),await yl(n,{force:!0}).catch(()=>{}),o}}async function Fe(e){try{let t=await Pl(e.uiStateFile,"utf8"),r=JSON.parse(t);return Sl(r,e.uiStateFile)}catch(t){if(Il(t))return null;throw t}}async function he(e,t){await N(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Ct(){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 Sl(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")||!Oe(e,"inputMode")||!Oe(e,"focusedRegion")||!Oe(e,"activeTab")||!Oe(e,"inspectorSection")||!Oe(e,"inspectionMode")||!It(e,"openInspectionKind")||!It(e,"selectedFileTreePath")||!It(e,"selectedFilePath")||!It(e,"selectedDiffPath")||!bl(e,"collapsedFileTreePaths")||!Oe(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 Oe(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function It(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function bl(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function Il(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var kr={};gr(kr,{RUNNER_IDS:()=>x,assertEnabled:()=>hs,buildCommand:()=>Ts,getConfiguredProfile:()=>vt,getDefault:()=>gs,getDisplayName:()=>ws,getEnabled:()=>Et,getProfile:()=>We,isRunnerType:()=>At,parse:()=>ks,setRunnerEnabled:()=>Rs,setRunnerPath:()=>ys});var x=["codex","cursor","claude"];var fs={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 We=e=>fs[e];var vt=(e,t={})=>{let r=We(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var Et=(e={})=>x.filter(t=>e.runners?.[t]?.enabled!==!1);var gs=(e={})=>{let t=Et(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 hs=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var At=e=>x.includes(e);var ks=e=>{if(!e||e.length===0)return"codex";if(!At(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${x.join(", ")}.`);return e};var ws=e=>We(e).displayName;var Ts=(e,t,r={})=>{let n=[vt(e,r).executable];return t&&t.length>0&&n.push(t),n};var Rs=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var ys=(e,t,r)=>{let n=e.runners?.[t]??{},{path:s,...o}=n;return{...e,runners:{...e.runners??{},[t]:r!=null?{...n,path:r}:o}}};import{mkdir as Cl,readFile as vl,writeFile as El}from"node:fs/promises";import Al from"node:path";var xl=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Ps=async e=>{try{return await vl(e,"utf8")}catch(t){if(xl(t))return null;throw t}},Ss=async(e,t)=>{await Cl(Al.dirname(e),{recursive:!0}),await El(e,t,"utf8")};var xt=(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(!x.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${x.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 wr=async(e,t={readConfigFile:Ps})=>{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 xt(n,e.configFile)};var Tr=async(e,t,r={writeConfigFile:Ss})=>{xt(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
4
- `)};var Rr={};gr(Rr,{checkForUpdate:()=>bs,getCurrent:()=>Dt});var Dt=()=>{try{return"0.7.12"}catch{return"unknown"}};var Dl="https://registry.npmjs.org/craig-cli/latest",$l=3600*1e3,Ll={value:null},jl=(e,t)=>{let r=c=>c.split(".").map(Number),[n=0,s=0,o=0]=r(e),[i=0,a=0,l=0]=r(t);return n!==i?n>i:s!==a?s>a:o>l},bs=async(e={fetch:globalThis.fetch,getCurrent:Dt,cache:Ll})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<$l)return e.cache.value.result;let n=null;try{let o=await e.fetch(Dl,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&jl(n,t)};return e.cache.value={result:s,cachedAt:r},s};var k={load:wr,save:Tr,runners:kr,version:Rr};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 r=t.slice(2).join(" ").trim();if(r.length===0)throw new Error(`Repo path cannot be empty.
2
+ var xl=Object.defineProperty;var Et=(e,t)=>{for(var r in t)xl(e,r,{get:t[r],enumerable:!0})};import{readFile as jl}from"node:fs/promises";import{randomUUID as Dl}from"node:crypto";import{open as $l,readFile as jf,rename as Ml,rm as Ll}from"node:fs/promises";import Rr from"node:path";async function O(e,t){let r=Rr.dirname(e),n=Rr.join(r,`.${Rr.basename(e)}.${process.pid}.${Date.now()}.${Dl()}.tmp`),s=await $l(n,"w");try{let o=`${JSON.stringify(t,null,2)}
3
+ `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Ml(n,e)}catch(o){throw await s.close().catch(()=>{}),await Ll(n,{force:!0}).catch(()=>{}),o}}async function We(e){try{let t=await jl(e.uiStateFile,"utf8"),r=JSON.parse(t);return Ol(r,e.uiStateFile)}catch(t){if(Nl(t))return null;throw t}}async function we(e,t){await O(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function xt(){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 Ol(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")||!Ne(e,"inputMode")||!Ne(e,"focusedRegion")||!Ne(e,"activeTab")||!Ne(e,"inspectorSection")||!Ne(e,"inspectionMode")||!At(e,"openInspectionKind")||!At(e,"selectedFileTreePath")||!At(e,"selectedFilePath")||!At(e,"selectedDiffPath")||!Fl(e,"collapsedFileTreePaths")||!Ne(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 Ne(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function At(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Fl(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function Nl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var yr={};Et(yr,{RUNNER_IDS:()=>x,assertEnabled:()=>Rs,buildCommand:()=>bs,getConfiguredProfile:()=>Dt,getDefault:()=>Ts,getDisplayName:()=>Ps,getEnabled:()=>$t,getProfile:()=>_e,isRunnerType:()=>Mt,parse:()=>ys,setRunnerEnabled:()=>Ss,setRunnerPath:()=>Is});var x=["codex","cursor","claude"];var ks={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 _e=e=>ks[e];var Dt=(e,t={})=>{let r=_e(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var $t=(e={})=>x.filter(t=>e.runners?.[t]?.enabled!==!1);var Ts=(e={})=>{let t=$t(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 Rs=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var Mt=e=>x.includes(e);var ys=e=>{if(!e||e.length===0)return"codex";if(!Mt(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${x.join(", ")}.`);return e};var Ps=e=>_e(e).displayName;var bs=(e,t,r={})=>{let n=[Dt(e,r).executable];return t&&t.length>0&&n.push(t),n};var Ss=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var Is=(e,t,r)=>{let n=e.runners?.[t]??{},{path:s,...o}=n;return{...e,runners:{...e.runners??{},[t]:r!=null?{...n,path:r}:o}}};var Pr={};Et(Pr,{PREVIEW_FEATURE_IDS:()=>te,isEnabled:()=>Cs,setEnabled:()=>vs});var te=["incrementalCenterPane"];function Cs(e,t){return e.previews?.[t]===!0}function vs(e,t,r){return{...e,previews:{...e.previews,[t]:r}}}import{mkdir as Wl,readFile as _l,writeFile as ql}from"node:fs/promises";import Ul from"node:path";var Bl=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Es=async e=>{try{return await _l(e,"utf8")}catch(t){if(Bl(t))return null;throw t}},As=async(e,t)=>{await Wl(Ul.dirname(e),{recursive:!0}),await ql(e,t,"utf8")};var Lt=(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(!x.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${x.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.`)}if(r.previews!==void 0){if(typeof r.previews!="object"||r.previews===null||Array.isArray(r.previews))throw new Error(`Craig config at ${t} is invalid. "previews" must be an object.`);for(let[n,s]of Object.entries(r.previews)){if(!te.includes(n))throw new Error(`Craig config at ${t} is invalid. "previews.${n}" is not supported. Expected one of: ${te.join(", ")}.`);if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${n}" must be a boolean.`)}}return r};var br=async(e,t={readConfigFile:Es})=>{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 Lt(n,e.configFile)};var Sr=async(e,t,r={writeConfigFile:As})=>{Lt(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
4
+ `)};var Ir={};Et(Ir,{checkForUpdate:()=>xs,getCurrent:()=>jt});var jt=()=>{try{return"0.8.0"}catch{return"unknown"}};var Kl="https://registry.npmjs.org/craig-cli/latest",Vl=3600*1e3,Gl={value:null},Hl=(e,t)=>{let r=c=>c.split(".").map(Number),[n=0,s=0,o=0]=r(e),[i=0,a=0,l=0]=r(t);return n!==i?n>i:s!==a?s>a:o>l},xs=async(e={fetch:globalThis.fetch,getCurrent:jt,cache:Gl})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<Vl)return e.cache.value.result;let n=null;try{let o=await e.fetch(Kl,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&Hl(n,t)};return e.cache.value={result:s,cachedAt:r},s};var h={load:br,save:Sr,previews:Pr,runners:yr,version:Ir};function Ds(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.
5
5
 
6
6
  `+K());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.
7
7
 
@@ -11,7 +11,7 @@ ${K()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:r}}}if(t.
11
11
 
12
12
  `+K());if(r!==-1&&n!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
13
13
 
14
- `+K());let o=r===-1?void 0:t[r+1]?.trim()??"",i=n===-1?void 0:t[n+1]?.trim()??"",a=s===-1?void 0:k.runners.parse(t[s+1]?.trim()??""),c=t.filter((d,p)=>p>1&&p!==r&&p!==r+1&&p!==n&&p!==n+1&&p!==s&&p!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
14
+ `+K());let o=r===-1?void 0:t[r+1]?.trim()??"",i=n===-1?void 0:t[n+1]?.trim()??"",a=s===-1?void 0:h.runners.parse(t[s+1]?.trim()??""),c=t.filter((d,p)=>p>1&&p!==r&&p!==r+1&&p!==n&&p!==n+1&&p!==s&&p!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
15
15
 
16
16
  `+K());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
17
17
 
@@ -19,19 +19,19 @@ ${K()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:r}}}if(t.
19
19
 
20
20
  `+K());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:c,...a?{runner:a}:{}}}}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(" ")}
21
21
 
22
- ${K()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:se(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:se(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:se(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:se(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:se(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:se(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:se(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:se(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:se(t[2]),repoId:Ml(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:se(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
22
+ ${K()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:oe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:oe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:oe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:oe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:oe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:oe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:oe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:oe(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:oe(t[2]),repoId:zl(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:oe(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
23
23
 
24
24
  ${K()}`)}function K(){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(`
25
- `)}function se(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
25
+ `)}function oe(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
26
26
 
27
- ${K()}`);return t}function Ml(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
27
+ ${K()}`);return t}function zl(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
28
28
 
29
- ${K()}`);return t}var F=(e,t)=>{let r=yr(e);if(!Ol(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},yr=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Pr(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:_l(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:Fl(t.repoTargets),runnerSession:t.runnerSession??Nl(t),checks:Hl(t),lastCommit:t.lastCommit??null,prs:zl(t),artifacts:Xl(t),cleanup:Zl(t)}},Nl=e=>{if(typeof e.title!="string")return null;let t=Pr(e.runner);return{command:k.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},Ol=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"&&k.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"&&vs(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||Wl(t.repoTargets))&&Bl(t.runnerSession)&&Ul(t.prompt)&&Es(t.checks)&&As(t.lastCommit)&&Vl(t.prs)&&Gl(t.artifacts)&&Ds(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Fl=e=>{if(Array.isArray(e))return e.filter(Cs)},Wl=e=>Array.isArray(e)&&e.every(Cs),Cs=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)&&Es(t.checks)&&As(t.lastCommit)&&xs(t.pullRequest)&&Ds(t.cleanup)},_l=e=>{if(vs(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 ql(e.id,e.title,t,Pr(e.runner))},ql=(e,t,r,n)=>{let s=k.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:k.runners.buildCommand(n),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Pr=e=>e&&k.runners.isRunnerType(e)?e:"codex",vs=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"),Bl=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),Ul=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",Es=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"),As=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",xs=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&Kl(e.requiredChecks),Kl=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)),Vl=e=>Array.isArray(e)&&e.every(xs),Gl=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),Ds=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),Hl=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},zl=e=>{if(Array.isArray(e.prs))return e.prs.map(Ql);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:$s(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Ls(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},Ql=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:$s(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Yl(t.reviewDecision),requiredChecks:Ls(t.requiredChecks),comments:Jl(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},$s=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,Yl=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Jl=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}]}):[],Ls=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})):[],Xl=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},Zl=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as Pc}from"node:fs/promises";import{readFile as ec,readdir as tc,rm as rc}from"node:fs/promises";import js from"node:path";var Sr=(e,t)=>js.join(e.workspacesDir,`${t}.json`),nc=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"):[]}},Ms=(e,t)=>{let r=nc(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},be=async(e,t)=>{let r=Sr(e,t),n=await ec(r,"utf8");return Ms(JSON.parse(n),r)},Ie=async(e,t)=>{await N(Sr(e,t.id),{...t,updatedAt:new Date().toISOString()})},Y=async e=>{let t=await tc(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>be(e,js.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},Ns=async(e,t)=>{await rc(Sr(e,t),{force:!0})};import{readFile as sc,readdir as oc,rm as ic}from"node:fs/promises";import Os from"node:path";var br=(e,t)=>Os.join(e.reposDir,`${t}.json`),Fs=(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},Z=async(e,t)=>{let r=br(e,t),n=await sc(r,"utf8");return Fs(JSON.parse(n),r)},Ir=async(e,t)=>{await N(br(e,t.id),{...t,updatedAt:new Date().toISOString()})},tt=async e=>{let t=await oc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Z(e,Os.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Ws=async(e,t)=>{await ic(br(e,t),{force:!0})};import{readFile as ac}from"node:fs/promises";var lc=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"},$t=(e,t,r)=>{if(!lc(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},V=async e=>{let t=await ac(e.indexFile,"utf8");return $t(JSON.parse(t),e.workspaceRoot,e.indexFile)},ce=async(e,t)=>{await N(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as mc,stat as fc}from"node:fs/promises";import qe from"node:path";import{realpath as Bs}from"node:fs/promises";import Us from"node:path";import{execFile as cc}from"node:child_process";import{promisify as dc}from"node:util";var _s=dc(cc);async function R(e,t,r={}){try{let n=await _s(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(qs(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function v(e,t,r={}){try{let n=await _s(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(qs(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function qs(e){return e instanceof Error}var Cr=async e=>{try{let r=(await R("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([Bs(r).catch(()=>Us.resolve(r)),Bs(e).catch(()=>Us.resolve(e))]);return n===s}catch{return!1}},vr=async e=>{let t=await v("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 v("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await R("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as ie,readFile as uc}from"node:fs/promises";import G from"node:path";function oe(e){let t=G.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:G.join(t,"index.json"),reposDir:G.join(t,"repos"),workspacesDir:G.join(t,"workspaces"),sessionsDir:G.join(t,"sessions"),runtimeDir:G.join(t,"runtime"),uiStateFile:G.join(t,"runtime","ui-state.json"),tasksDir:G.join(t,"tasks"),jobsDir:G.join(t,"jobs"),logsDir:G.join(t,"logs"),errorLogFile:G.join(t,"logs","errors.log"),artifactsDir:G.join(t,"artifacts"),worktreesDir:G.join(t,"worktrees"),configFile:G.join(t,"config.json")}}var pc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",_e=async e=>{let t=oe(e);await ie(t.craigDir,{recursive:!0}),await Promise.all([ie(t.reposDir,{recursive:!0}),ie(t.workspacesDir,{recursive:!0}),ie(t.sessionsDir,{recursive:!0}),ie(t.runtimeDir,{recursive:!0}),ie(t.tasksDir,{recursive:!0}),ie(t.jobsDir,{recursive:!0}),ie(t.logsDir,{recursive:!0}),ie(t.artifactsDir,{recursive:!0}),ie(t.worktreesDir,{recursive:!0})]);try{let s=await uc(t.indexFile,"utf8"),o=JSON.parse(s);return $t(o,e,t.indexFile)}catch(s){if(!pc(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 N(t.indexFile,n),n};var Ks=(e,t,r)=>{let n=new Date().toISOString();return{id:gc(e,qe.basename(t)),name:qe.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},Vs=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},gc=(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},hc=(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},Gs=async(e,t)=>{let r=await V(e);await ce(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},kc=async(e,t)=>{let r=await mc(t,{withFileTypes:!0}),n=await tt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=qe.join(t,o.name);if(!await Cr(i))continue;let a=n.find(c=>c.rootPath===i)??s.find(c=>c.rootPath===i),l=await vr(i);s.push(a?Vs(a,l):Ks([...n,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},wc=async(e,t)=>{let r=await vr(t),n=await tt(e),s=n.find(p=>p.rootPath===t)??null,o=s?Vs(s,r):Ks(n,t,r),i=`workspace_${o.id}`,l=(await Y(e)).find(p=>p.id===i)??null,c=new Date().toISOString(),d=l??{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:c,updatedAt:c};return await Ir(e,o),l||await Ie(e,d),await Gs(e,{repoIds:[o.id],workspaceIds:[d.id]}),{kind:"createWorkspace",workspace:d,repos:[o],created:!l}},Tc=async(e,t)=>{let r=await kc(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await Y(e),s=hc(n,qe.basename(t)),o=n.find(c=>c.kind==="project"&&c.rootPath===t)??null,i=new Date().toISOString(),a=r.map(c=>c.id),l=o?{...o,discoveredRepoIds:a,primaryRepoId:a[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:qe.basename(t),rootPath:t,primaryRepoId:a[0]??"",discoveredRepoIds:a,branch:"project",status:"active",linkedRepoIds:a,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(r.map(c=>Ir(e,c))),await Ie(e,l),await Gs(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!o}},rt=async(e,t)=>{await _e(e.workspaceRoot);let r=qe.resolve(e.workspaceRoot,t);if(!(await fc(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await Cr(r)?wc(e,r):Tc(e,r)};var Er=async(e,t,r={listWorkspaceRecords:Y,ensureCraigState:_e})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var Ar=async(e,t,r={readWorkspace:be,writeWorkspace:Ie})=>{let s={...await r.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};return await r.writeWorkspace(e,s),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var xr=async(e,t)=>{let n={...await be(e,t),status:"active",archivedAt:null};await Ie(e,n);let s=n.kind==="project"?n.discoveredRepoIds?.[0]??null:n.primaryRepoId;return{kind:"restoreWorkspace",workspaceId:n.id,status:n.status,branch:n.branch,primaryRepoId:s}};var Ce=async(e,t,r={deleteWorkspace:Ns,readCraigIndex:V,writeCraigIndex:ce})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var Dr=async(e,t,r)=>{let n=await be(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 Ce(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var $r={};gr($r,{addRepo:()=>Hs,listRegisteredRepos:()=>zs,removeRepo:()=>Qs});import Rc from"node:path";import{stat as yc}from"node:fs/promises";var Hs=async(e,t)=>{let r=Rc.resolve(e.workspaceRoot,t);if(!(await yc(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await rt(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 zs=async(e,t={listRepos:tt,ensureCraigState:_e})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var Qs=async(e,t,r)=>{let n=await Z(e,t),o=(await Y(e)).filter(c=>c.primaryRepoId===t),i=o.filter(c=>c.status==="active"),a=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(a.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(o.map(c=>Ce(e,c.id))),await Ws(e,t);let l=await V(e);return await ce(e,{...l,repoIds:l.repoIds.filter(c=>c!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var H={addWorkspace:rt,listWorkspaces:Er,archiveWorkspace:Ar,restoreWorkspace:xr,removeWorkspace:Dr,removeWorkspaceRecord:Ce,repos:$r};var z=async(e,t)=>{let r=await Pc(jr(e,t),"utf8");return JSON.parse(r)},J=async(e,t)=>{let r=await z(e,t);return F(r,jr(e,t))},y=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await N(jr(e,t.id),r)},Lr=async(e,t)=>{let r=await V(e);r.taskIds.includes(t)||await ce(e,{...r,taskIds:[...r.taskIds,t]})},jr=(e,t)=>`${e.tasksDir}/${t}.json`;var E=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,ke=e=>e.status==="merged"||e.status==="closed",Be=(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}},nt=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return jt(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},jt=e=>e.mergeable&&!Sc(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),Sc=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",Mr=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),st=(e,t)=>{let r=e.isDraft??!1,n=bc(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:Ic(e.reviewDecision??null),requiredChecks:ot(e.statusCheckRollup),comments:Ac(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}},bc=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Ic=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,ot=e=>{let t=e.map(n=>Cc(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||vc(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},Cc=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:Js(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:Ec(t)}:null},vc=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Lt(e)&&!Lt(t)?!0:!Lt(e)&&Lt(t)?!1:Ys(t.status)>=Ys(e.status),Lt=e=>e.conclusion?.toUpperCase()==="CANCELLED",Ys=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},Ec=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},Ac=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(xc).filter(r=>r!==null).slice(-4):[]},xc=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=Dc(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},Dc=e=>e.replace(/\s+/g," ").trim(),Js=(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?Js(n,n):"unknown"};import{access as $c}from"node:fs/promises";import Xs from"node:path";var S=async(e,t,r={readRawTask:z,validateTaskRecord:F})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Oc(n)?new Error(`Craig task "${t}" was not found.`):n}},W=async e=>{if(!await Nr(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},Ue=(e,t)=>t.artifacts.logPath?Xs.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:Xs.join(e.workspaceRoot,t.artifacts.logPath):null,it=async(e,t)=>{let r=await Nr(t.worktreePath),n=Ue(e,t),s=n?await Nr(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Lc(t),lastCommitSummary:jc(t),prSummary:Mc(t),cleanupSummary:Nc(t)}},Nr=async e=>{try{return await $c(e),!0}catch{return!1}},Lc=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}`},jc=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",Mc=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,c)=>{let d=c.pullRequest.status??"unknown";return l[d]=(l[d]??0)+1,l},{}),a=Object.entries(i).map(([l,c])=>`${c} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${a})
29
+ ${K()}`);return t}var N=(e,t)=>{let r=Cr(e);if(!Yl(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},Cr=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:vr(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:Zl(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:Jl(t.repoTargets),runnerSession:t.runnerSession??Ql(t),checks:ic(t),lastCommit:t.lastCommit??null,prs:ac(t),artifacts:uc(t),cleanup:pc(t)}},Ql=e=>{if(typeof e.title!="string")return null;let t=vr(e.runner);return{command:h.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"&&h.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"&&Ms(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||Xl(t.repoTargets))&&tc(t.runnerSession)&&rc(t.prompt)&&Ls(t.checks)&&js(t.lastCommit)&&sc(t.prs)&&oc(t.artifacts)&&Fs(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Jl=e=>{if(Array.isArray(e))return e.filter($s)},Xl=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)&&Ls(t.checks)&&js(t.lastCommit)&&Os(t.pullRequest)&&Fs(t.cleanup)},Zl=e=>{if(Ms(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 ec(e.id,e.title,t,vr(e.runner))},ec=(e,t,r,n)=>{let s=h.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:h.runners.buildCommand(n),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},vr=e=>e&&h.runners.isRunnerType(e)?e:"codex",Ms=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"),tc=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),rc=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",Ls=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"),js=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",Os=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&nc(e.requiredChecks),nc=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)),sc=e=>Array.isArray(e)&&e.every(Os),oc=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),Fs=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),ic=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},ac=e=>{if(Array.isArray(e.prs))return e.prs.map(lc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:Ns(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Ws(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},lc=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:Ns(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:cc(t.reviewDecision),requiredChecks:Ws(t.requiredChecks),comments:dc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},Ns=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,cc=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,dc=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}]}):[],Ws=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})):[],uc=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},pc=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as jc}from"node:fs/promises";import{readFile as mc,readdir as fc,rm as gc}from"node:fs/promises";import _s from"node:path";var Er=(e,t)=>_s.join(e.workspacesDir,`${t}.json`),hc=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"):[]}},qs=(e,t)=>{let r=hc(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},Ie=async(e,t)=>{let r=Er(e,t),n=await mc(r,"utf8");return qs(JSON.parse(n),r)},Ce=async(e,t)=>{await O(Er(e,t.id),{...t,updatedAt:new Date().toISOString()})},Y=async e=>{let t=await fc(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Ie(e,_s.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},Us=async(e,t)=>{await gc(Er(e,t),{force:!0})};import{readFile as wc,readdir as kc,rm as Tc}from"node:fs/promises";import Bs from"node:path";var Ar=(e,t)=>Bs.join(e.reposDir,`${t}.json`),Ks=(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},Z=async(e,t)=>{let r=Ar(e,t),n=await wc(r,"utf8");return Ks(JSON.parse(n),r)},xr=async(e,t)=>{await O(Ar(e,t.id),{...t,updatedAt:new Date().toISOString()})},rt=async e=>{let t=await kc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Z(e,Bs.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Vs=async(e,t)=>{await Tc(Ar(e,t),{force:!0})};import{readFile as Rc}from"node:fs/promises";var yc=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"},Ot=(e,t,r)=>{if(!yc(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},V=async e=>{let t=await Rc(e.indexFile,"utf8");return Ot(JSON.parse(t),e.workspaceRoot,e.indexFile)},de=async(e,t)=>{await O(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as Cc,stat as vc}from"node:fs/promises";import Ue from"node:path";import{realpath as zs}from"node:fs/promises";import Qs from"node:path";import{execFile as Pc}from"node:child_process";import{promisify as bc}from"node:util";var Gs=bc(Pc);async function R(e,t,r={}){try{let n=await Gs(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(Hs(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function E(e,t,r={}){try{let n=await Gs(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(Hs(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function Hs(e){return e instanceof Error}var Dr=async e=>{try{let r=(await R("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([zs(r).catch(()=>Qs.resolve(r)),zs(e).catch(()=>Qs.resolve(e))]);return n===s}catch{return!1}},$r=async e=>{let t=await E("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 E("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await R("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as ae,readFile as Sc}from"node:fs/promises";import G from"node:path";function ie(e){let t=G.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:G.join(t,"index.json"),reposDir:G.join(t,"repos"),workspacesDir:G.join(t,"workspaces"),sessionsDir:G.join(t,"sessions"),runtimeDir:G.join(t,"runtime"),uiStateFile:G.join(t,"runtime","ui-state.json"),tasksDir:G.join(t,"tasks"),jobsDir:G.join(t,"jobs"),logsDir:G.join(t,"logs"),errorLogFile:G.join(t,"logs","errors.log"),artifactsDir:G.join(t,"artifacts"),worktreesDir:G.join(t,"worktrees"),configFile:G.join(t,"config.json")}}var Ic=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",qe=async e=>{let t=ie(e);await ae(t.craigDir,{recursive:!0}),await Promise.all([ae(t.reposDir,{recursive:!0}),ae(t.workspacesDir,{recursive:!0}),ae(t.sessionsDir,{recursive:!0}),ae(t.runtimeDir,{recursive:!0}),ae(t.tasksDir,{recursive:!0}),ae(t.jobsDir,{recursive:!0}),ae(t.logsDir,{recursive:!0}),ae(t.artifactsDir,{recursive:!0}),ae(t.worktreesDir,{recursive:!0})]);try{let s=await Sc(t.indexFile,"utf8"),o=JSON.parse(s);return Ot(o,e,t.indexFile)}catch(s){if(!Ic(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 O(t.indexFile,n),n};var Ys=(e,t,r)=>{let n=new Date().toISOString();return{id:Ec(e,Ue.basename(t)),name:Ue.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},Js=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},Ec=(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},Ac=(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},Xs=async(e,t)=>{let r=await V(e);await de(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},xc=async(e,t)=>{let r=await Cc(t,{withFileTypes:!0}),n=await rt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Ue.join(t,o.name);if(!await Dr(i))continue;let a=n.find(c=>c.rootPath===i)??s.find(c=>c.rootPath===i),l=await $r(i);s.push(a?Js(a,l):Ys([...n,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},Dc=async(e,t)=>{let r=await $r(t),n=await rt(e),s=n.find(p=>p.rootPath===t)??null,o=s?Js(s,r):Ys(n,t,r),i=`workspace_${o.id}`,l=(await Y(e)).find(p=>p.id===i)??null,c=new Date().toISOString(),d=l??{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:c,updatedAt:c};return await xr(e,o),l||await Ce(e,d),await Xs(e,{repoIds:[o.id],workspaceIds:[d.id]}),{kind:"createWorkspace",workspace:d,repos:[o],created:!l}},$c=async(e,t)=>{let r=await xc(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await Y(e),s=Ac(n,Ue.basename(t)),o=n.find(c=>c.kind==="project"&&c.rootPath===t)??null,i=new Date().toISOString(),a=r.map(c=>c.id),l=o?{...o,discoveredRepoIds:a,primaryRepoId:a[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:Ue.basename(t),rootPath:t,primaryRepoId:a[0]??"",discoveredRepoIds:a,branch:"project",status:"active",linkedRepoIds:a,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(r.map(c=>xr(e,c))),await Ce(e,l),await Xs(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!o}},nt=async(e,t)=>{await qe(e.workspaceRoot);let r=Ue.resolve(e.workspaceRoot,t);if(!(await vc(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await Dr(r)?Dc(e,r):$c(e,r)};var Mr=async(e,t,r={listWorkspaceRecords:Y,ensureCraigState:qe})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var Lr=async(e,t,r={readWorkspace:Ie,writeWorkspace:Ce})=>{let s={...await r.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};return await r.writeWorkspace(e,s),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var jr=async(e,t)=>{let n={...await Ie(e,t),status:"active",archivedAt:null};await Ce(e,n);let s=n.kind==="project"?n.discoveredRepoIds?.[0]??null:n.primaryRepoId;return{kind:"restoreWorkspace",workspaceId:n.id,status:n.status,branch:n.branch,primaryRepoId:s}};var ve=async(e,t,r={deleteWorkspace:Us,readCraigIndex:V,writeCraigIndex:de})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var Or=async(e,t,r)=>{let n=await Ie(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 ve(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var Fr={};Et(Fr,{addRepo:()=>Zs,listRegisteredRepos:()=>eo,removeRepo:()=>to});import Mc from"node:path";import{stat as Lc}from"node:fs/promises";var Zs=async(e,t)=>{let r=Mc.resolve(e.workspaceRoot,t);if(!(await Lc(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await nt(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 eo=async(e,t={listRepos:rt,ensureCraigState:qe})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var to=async(e,t,r)=>{let n=await Z(e,t),o=(await Y(e)).filter(c=>c.primaryRepoId===t),i=o.filter(c=>c.status==="active"),a=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(a.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(o.map(c=>ve(e,c.id))),await Vs(e,t);let l=await V(e);return await de(e,{...l,repoIds:l.repoIds.filter(c=>c!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var H={addWorkspace:nt,listWorkspaces:Mr,archiveWorkspace:Lr,restoreWorkspace:jr,removeWorkspace:Or,removeWorkspaceRecord:ve,repos:Fr};var z=async(e,t)=>{let r=await jc(Wr(e,t),"utf8");return JSON.parse(r)},J=async(e,t)=>{let r=await z(e,t);return N(r,Wr(e,t))},y=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await O(Wr(e,t.id),r)},Nr=async(e,t)=>{let r=await V(e);r.taskIds.includes(t)||await de(e,{...r,taskIds:[...r.taskIds,t]})},Wr=(e,t)=>`${e.tasksDir}/${t}.json`;var A=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,ke=e=>e.status==="merged"||e.status==="closed",Be=(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}},st=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return Nt(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},Nt=e=>e.mergeable&&!Oc(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),Oc=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",_r=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),ot=(e,t)=>{let r=e.isDraft??!1,n=Fc(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:Nc(e.reviewDecision??null),requiredChecks:it(e.statusCheckRollup),comments:Uc(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}},Fc=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Nc=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,it=e=>{let t=e.map(n=>Wc(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||_c(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},Wc=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:no(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:qc(t)}:null},_c=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Ft(e)&&!Ft(t)?!0:!Ft(e)&&Ft(t)?!1:ro(t.status)>=ro(e.status),Ft=e=>e.conclusion?.toUpperCase()==="CANCELLED",ro=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},qc=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},Uc=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=Kc(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},Kc=e=>e.replace(/\s+/g," ").trim(),no=(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?no(n,n):"unknown"};import{access as Vc}from"node:fs/promises";import so from"node:path";var b=async(e,t,r={readRawTask:z,validateTaskRecord:N})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Yc(n)?new Error(`Craig task "${t}" was not found.`):n}},W=async e=>{if(!await qr(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},Ke=(e,t)=>t.artifacts.logPath?so.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:so.join(e.workspaceRoot,t.artifacts.logPath):null,at=async(e,t)=>{let r=await qr(t.worktreePath),n=Ke(e,t),s=n?await qr(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Gc(t),lastCommitSummary:Hc(t),prSummary:zc(t),cleanupSummary:Qc(t)}},qr=async e=>{try{return await Vc(e),!0}catch{return!1}},Gc=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}`},Hc=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",zc=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,c)=>{let d=c.pullRequest.status??"unknown";return l[d]=(l[d]??0)+1,l},{}),a=Object.entries(i).map(([l,c])=>`${c} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${a})
30
30
  ${o.join(`
31
- `)}`}let t=E(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})`},Nc=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",Oc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var Zs=async(e,t)=>{let r=await v("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.")},Or=async(e,t,r,n="main")=>{let s=n.trim()||"main";if((await v("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 Fc(e,s);await R("git",["worktree","add","-b",t,r,i],{cwd:e})},Fc=async(e,t)=>(await v("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await v("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await v("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t,Mt=async e=>{let t=await v("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},eo=async e=>{await R("git",["add","-A"],{cwd:e})},to=async(e,t)=>{await R("git",["commit","-m",t],{cwd:e})},ro=async e=>{let t=await R("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}},no=async e=>{let t=await v("git",["branch","--show-current"],{cwd:e});if(t.exitCode!==0)return null;let r=t.stdout.trim();return r.length>0?r:null};var so=async(e,t)=>{await R("git",["worktree","remove","--force",t],{cwd:e})};var Fr=async e=>Ke(e,e.repoRoot),Ke=async(e,t)=>{let r=await V(e),n=oo(new Date),s=io(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await Zs(t,i))return o;s+=1}},at=async e=>{let t=await V(e),r=oo(new Date),n=io(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},oo=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},io=(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 Wr=async(e,t,r={readRawTask:z,validateTaskRecord:F})=>{let n=await V(e),s=[],o=[];await Promise.all(n.taskIds.map(async l=>{try{let c=await r.readRawTask(e,l);s.push(r.validateTaskRecord(c,`${e.tasksDir}/${l}.json`))}catch(c){if(Wc(c)){o.push(l);return}throw c}}));let a=(t?.includeClosed?s:s.filter(l=>l.status!=="closed")).filter(l=>!(t?.workspaceId&&l.workspaceId!==t.workspaceId||t?.repoId&&l.repoId!==t.repoId&&!(l.repoTargets??[]).some(c=>c.repoId===t.repoId)));return a.sort((l,c)=>l.id.localeCompare(c.id)),o.sort(),{kind:"listTasks",tasks:a,missingTaskIds:o,repoId:t?.repoId??null}},Wc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var ao=["merge_ready","pr_open","checked","review","running","draft"],_r=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),qr=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(_c)[0]?.id??null,_c=(e,t)=>{let r=lo(e.status),n=lo(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},lo=e=>{let t=ao.indexOf(e);return t>=0?t:ao.length};import co from"node:path";var ve=(e,t)=>t?co.isAbsolute(t)?t:co.join(e.repoRoot,t):null;import{mkdir as lt,rm as qc,writeFile as Nt}from"node:fs/promises";import C from"node:path";var po=["AGENTS","md"].join("."),Ve=async(e,t,r,n={})=>{let s=await Z(e,t),o=await Gc(e,s.id),i=await Ke(e,s.rootPath),a=n.sessionId??null,l=`craig/${i}`,c=C.join(e.worktreesDir,s.id,i),d=C.join(e.logsDir,`${i}.log`),p=C.join(e.artifactsDir,i);await lt(C.dirname(c),{recursive:!0}),await lt(p,{recursive:!0}),await Nt(d,"","utf8");let m=Bc(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:a,repoRoot:s.rootPath,prompt:r,runner:n.runner??"codex",config:n.config??{},branch:l,worktreePath:c});return await y(e,m),await Lr(e,i),await Or(s.rootPath,l,c,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:a,workspaceId:o.id,task:m}},ct=async(e,t,r,n={})=>{let s=(await Y(e)).find(T=>T.id===t&&T.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 T=await Ve(e,s.primaryRepoId,r,n);return{...T,bundlePath:T.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await at(e),a=new Date().toISOString(),l=n.runner??"codex",c=n.sessionId??null,d=`craig/${i}`,p=C.join(e.craigDir,"task-bundles",i),m=C.join(e.logsDir,`${i}.log`),f=C.join(e.artifactsDir,i);await lt(p,{recursive:!0}),await lt(f,{recursive:!0}),await Nt(m,"","utf8");let w=await Promise.all(o.map(T=>Z(e,T))),u=Kc(w),D=await Promise.all(w.map(T=>Uc(e,T,i,d,C.join(p,u.get(T.id))))),B=D.find(T=>T.status==="ready")??D[0];if(!D.some(T=>T.status==="ready"))throw await qc(p,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${D.map(T=>`${T.repoId}: ${T.failureReason??"unknown error"}`).join("; ")}`);await Nt(C.join(p,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:D.map(T=>({repoId:T.repoId,repoName:w.find(Ne=>Ne.id===T.repoId)?.name??T.repoId,path:C.relative(p,T.worktreePath),status:T.status,worktreePath:T.worktreePath,failureReason:T.failureReason}))},null,2),"utf8"),await Nt(C.join(p,po),Vc({taskId:i,workspaceId:t,prompt:r,repos:w,repoTargets:D,bundlePath:p}),"utf8");let fe=dt(i,r,a,l,n.config??{}),ge={id:i,title:r,slug:mo(r),type:"project",status:"draft",runner:l,repoId:B.repoId,workspaceId:s.id,sessionId:c,selectedPtyTabId:fe[0]?.id??null,linkedRepoIds:o.filter(T=>T!==B.repoId),repoRoot:p,worktreePath:p,branch:d,bundlePath:p,selectedRepoTargetId:B.repoId,repoTargets:D,ptyTabs:fe,runnerSession:{command:k.runners.buildCommand(l,r,n.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:r},checks:B.checks,lastCommit:null,prs:[],artifacts:{logPath:C.relative(e.workspaceRoot,m),checkSummaryPath:C.relative(e.workspaceRoot,C.join(f,"check-summary.json")),prDraftPath:null,prStatusPath:C.relative(e.workspaceRoot,C.join(f,"pr-status.json"))},cleanup:Ot(),lastFailureReason:D.every(T=>T.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:a,updatedAt:a};return await y(e,ge),await Lr(e,i),{repoId:B.repoId,repoRoot:p,sessionId:c,workspaceId:s.id,task:ge,bundlePath:p,repoTargets:D}},dt=(e,t,r,n="codex",s={})=>{let o=k.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:k.runners.buildCommand(n,void 0,s),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Bc=(e,t)=>{let r=new Date().toISOString(),n=dt(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:mo(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:k.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:{...Br(C.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:C.relative(e.workspaceRoot,C.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:C.relative(e.workspaceRoot,C.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:C.relative(e.workspaceRoot,C.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:Ot(),lastFailureReason:null,createdAt:r,updatedAt:r}},Uc=async(e,t,r,n,s)=>{await lt(C.dirname(s),{recursive:!0});try{return await Or(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:Br(C.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:uo(),cleanup:Ot()}}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:Br(C.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:uo(),cleanup:Ot()}}},Kc=e=>{let t=new Set(["manifest.json",po]),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},Vc=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=C.relative(e.bundlePath,n.worktreePath),i=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${n.repoId}, ${i})`}).join(`
31
+ `)}`}let t=A(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})`},Qc=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",Yc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var oo=async(e,t)=>{let r=await E("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.")},Ur=async(e,t,r,n="main")=>{let s=n.trim()||"main";if((await E("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 Jc(e,s);await R("git",["worktree","add","-b",t,r,i],{cwd:e})},Jc=async(e,t)=>(await E("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await E("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await E("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t,Wt=async e=>{let t=await E("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},io=async e=>{await R("git",["add","-A"],{cwd:e})},ao=async(e,t)=>{await R("git",["commit","-m",t],{cwd:e})},lo=async e=>{let t=await R("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}},co=async e=>{let t=await E("git",["branch","--show-current"],{cwd:e});if(t.exitCode!==0)return null;let r=t.stdout.trim();return r.length>0?r:null};var uo=async(e,t)=>{await R("git",["worktree","remove","--force",t],{cwd:e})};var Br=async e=>Ve(e,e.repoRoot),Ve=async(e,t)=>{let r=await V(e),n=po(new Date),s=mo(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await oo(t,i))return o;s+=1}},lt=async e=>{let t=await V(e),r=po(new Date),n=mo(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},po=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},mo=(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 Kr=async(e,t,r={readRawTask:z,validateTaskRecord:N})=>{let n=await V(e),s=[],o=[];await Promise.all(n.taskIds.map(async l=>{try{let c=await r.readRawTask(e,l);s.push(r.validateTaskRecord(c,`${e.tasksDir}/${l}.json`))}catch(c){if(Xc(c)){o.push(l);return}throw c}}));let a=(t?.includeClosed?s:s.filter(l=>l.status!=="closed")).filter(l=>!(t?.workspaceId&&l.workspaceId!==t.workspaceId||t?.repoId&&l.repoId!==t.repoId&&!(l.repoTargets??[]).some(c=>c.repoId===t.repoId)));return a.sort((l,c)=>l.id.localeCompare(c.id)),o.sort(),{kind:"listTasks",tasks:a,missingTaskIds:o,repoId:t?.repoId??null}},Xc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var fo=["merge_ready","pr_open","checked","review","running","draft"],Vr=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),Gr=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(Zc)[0]?.id??null,Zc=(e,t)=>{let r=go(e.status),n=go(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},go=e=>{let t=fo.indexOf(e);return t>=0?t:fo.length};import ho from"node:path";var Ee=(e,t)=>t?ho.isAbsolute(t)?t:ho.join(e.repoRoot,t):null;import{mkdir as ct,rm as ed,writeFile as _t}from"node:fs/promises";import C from"node:path";var ko=["AGENTS","md"].join("."),Ge=async(e,t,r,n={})=>{let s=await Z(e,t),o=await od(e,s.id),i=await Ve(e,s.rootPath),a=n.sessionId??null,l=`craig/${i}`,c=C.join(e.worktreesDir,s.id,i),d=C.join(e.logsDir,`${i}.log`),p=C.join(e.artifactsDir,i);await ct(C.dirname(c),{recursive:!0}),await ct(p,{recursive:!0}),await _t(d,"","utf8");let m=td(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:a,repoRoot:s.rootPath,prompt:r,runner:n.runner??"codex",config:n.config??{},branch:l,worktreePath:c});return await y(e,m),await Nr(e,i),await Ur(s.rootPath,l,c,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:a,workspaceId:o.id,task:m}},dt=async(e,t,r,n={})=>{let s=(await Y(e)).find(T=>T.id===t&&T.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 T=await Ge(e,s.primaryRepoId,r,n);return{...T,bundlePath:T.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await lt(e),a=new Date().toISOString(),l=n.runner??"codex",c=n.sessionId??null,d=`craig/${i}`,p=C.join(e.craigDir,"task-bundles",i),m=C.join(e.logsDir,`${i}.log`),f=C.join(e.artifactsDir,i);await ct(p,{recursive:!0}),await ct(f,{recursive:!0}),await _t(m,"","utf8");let k=await Promise.all(o.map(T=>Z(e,T))),u=nd(k),D=await Promise.all(k.map(T=>rd(e,T,i,d,C.join(p,u.get(T.id))))),U=D.find(T=>T.status==="ready")??D[0];if(!D.some(T=>T.status==="ready"))throw await ed(p,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${D.map(T=>`${T.repoId}: ${T.failureReason??"unknown error"}`).join("; ")}`);await _t(C.join(p,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:D.map(T=>({repoId:T.repoId,repoName:k.find(Fe=>Fe.id===T.repoId)?.name??T.repoId,path:C.relative(p,T.worktreePath),status:T.status,worktreePath:T.worktreePath,failureReason:T.failureReason}))},null,2),"utf8"),await _t(C.join(p,ko),sd({taskId:i,workspaceId:t,prompt:r,repos:k,repoTargets:D,bundlePath:p}),"utf8");let ge=ut(i,r,a,l,n.config??{}),he={id:i,title:r,slug:To(r),type:"project",status:"draft",runner:l,repoId:U.repoId,workspaceId:s.id,sessionId:c,selectedPtyTabId:ge[0]?.id??null,linkedRepoIds:o.filter(T=>T!==U.repoId),repoRoot:p,worktreePath:p,branch:d,bundlePath:p,selectedRepoTargetId:U.repoId,repoTargets:D,ptyTabs:ge,runnerSession:{command:h.runners.buildCommand(l,r,n.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:r},checks:U.checks,lastCommit:null,prs:[],artifacts:{logPath:C.relative(e.workspaceRoot,m),checkSummaryPath:C.relative(e.workspaceRoot,C.join(f,"check-summary.json")),prDraftPath:null,prStatusPath:C.relative(e.workspaceRoot,C.join(f,"pr-status.json"))},cleanup:qt(),lastFailureReason:D.every(T=>T.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:a,updatedAt:a};return await y(e,he),await Nr(e,i),{repoId:U.repoId,repoRoot:p,sessionId:c,workspaceId:s.id,task:he,bundlePath:p,repoTargets:D}},ut=(e,t,r,n="codex",s={})=>{let o=h.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:h.runners.buildCommand(n,void 0,s),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},td=(e,t)=>{let r=new Date().toISOString(),n=ut(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:To(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:h.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:{...Hr(C.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:C.relative(e.workspaceRoot,C.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:C.relative(e.workspaceRoot,C.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:C.relative(e.workspaceRoot,C.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:qt(),lastFailureReason:null,createdAt:r,updatedAt:r}},rd=async(e,t,r,n,s)=>{await ct(C.dirname(s),{recursive:!0});try{return await Ur(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:Hr(C.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:wo(),cleanup:qt()}}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:Hr(C.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:wo(),cleanup:qt()}}},nd=e=>{let t=new Set(["manifest.json",ko]),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},sd=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=C.relative(e.bundlePath,n.worktreePath),i=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${n.repoId}, ${i})`}).join(`
33
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
- `)},Br=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),uo=()=>({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}),Ot=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),Gc=async(e,t)=>{let n=(await Y(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},mo=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import bo from"node:path";import{readFile as Hc,rm as Ek}from"node:fs/promises";import zc from"node:path";var we=async(e,t)=>{let r=await Hc(Ur(e,t),"utf8"),n=JSON.parse(r);return Qc(n,Ur(e,t))},Ee=async(e,t)=>{await N(Ur(e,t.id),{...t,updatedAt:new Date().toISOString()})};var Ur=(e,t)=>zc.join(e.sessionsDir,`${t}.json`);function Qc(e,t){let r=Xc(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")||!Jc(r.attach)||!Yc(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 Yc(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 Jc(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 Xc(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??""}}import{spawn as Zc}from"node:child_process";import{createHash as ed}from"node:crypto";import td from"node:path";function Ft(e){return`'${e.replace(/'/g,"'\\''")}'`}var rd="craig",fo=async(e,t,r)=>{let n=Kr(e,t),s=sd(),o=await R("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=id(o.stdout);return await nd(e,n),i};var nd=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 R("tmux",n,{cwd:e})},go=async(e,t,r)=>{await R("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},ho=async(e,t,r)=>{await R("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var ko=async(e,t,r)=>{await R("tmux",["pipe-pane","-o","-t",e,`cat >> ${Ft(t)}`],{cwd:r})},Wt=async(e,t,r,n)=>{let s=n??To(e);if(r?await R("tmux",["select-window","-t",r],{cwd:e}):await R("tmux",["select-window","-t",t],{cwd:e}),await R("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await R("tmux",["switch-client","-t",s],{cwd:e});return}await ld(e,["attach-session","-t",s])};var wo=async(e,t)=>{await R("tmux",["kill-session","-t",t],{cwd:e})};var To=e=>{let r=td.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=ed("sha1").update(e).digest("hex").slice(0,8);return`${rd}-${r}-${n}`},Kr=(e,t)=>`${To(e)}-${t.toLowerCase()}`,sd=()=>{let e=od();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},od=()=>{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},id=e=>{let t=ad(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]}},ad=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),ld=async(e,t)=>{await new Promise((r,n)=>{let s=Zc("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 cd,constants as dd}from"node:fs";import{homedir as Ro}from"node:os";import Te from"node:path";var ud=[Te.join(Ro(),".local","bin"),Te.join(Ro(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Po(e=process.env){return pd([...(e.PATH??"").split(Te.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:ud])}function Ae(e=process.env){return{...e,PATH:Po(e).join(Te.delimiter)}}function Vr(e,t={}){if(e.includes(Te.sep)){let r=Te.isAbsolute(e)?e:Te.resolve(t.cwd??process.cwd(),e);return yo(r)?r:null}for(let r of Po(t.env)){let n=Te.join(r,e);if(yo(n))return n}return null}function xe(e,t={}){let r=Vr(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 yo(e){try{return cd(e,dd.X_OK),!0}catch{return!1}}function pd(e){return[...new Set(e)]}var ut={async create(e,t){let r=await fo(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await ko(r.paneId,t.logPath,t.repoRoot);let n=await So({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||Kr(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 Ee(e,s),s},async attach(e,t,r){let n=await ut.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Wt(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await Ee(e,s),s},async resize(e,t,r,n){await go(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await Ee(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 Ee(e,n),n},async snapshot(e,t){return md(e,t)}},Gr={async prepare(e,t){let n=e.runnerSession.command[0],s=Ae();await R(xe(n,{cwd:t.repoRoot,env:s}),["--help"],{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=xe(r[0],{cwd:e.worktreePath,env:Ae()});await ho(t.session.paneId,[n,...r.slice(1)].map(s=>Ft(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},md=async(e,t)=>{let r=await v("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return So({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},So=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var Hr=async(e,t,r,n={})=>{let s=r.trim(),o=await k.load(e),i=n.runner??k.runners.getDefault(o);if(k.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 a=n.workspaceId?await ct(e,n.workspaceId,s,{runner:i,config:o}):await Ve(e,t,s,{runner:i,config:o}),l=a.task,c=k.runners.buildCommand(i,s,o),d=`session_${l.id}`,p=l.artifacts.logPath?bo.resolve(e.workspaceRoot,l.artifacts.logPath):bo.join(e.logsDir,`${l.id}.log`);try{await Gr.prepare(l,{repoRoot:a.repoRoot});let m=await ut.create(e,{sessionId:d,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:p,command:c});await Gr.launch(l,{repoRoot:a.repoRoot,session:m});let f=new Date().toISOString();m={...m,status:"running",startedAt:f,command:c};let w={...l,status:"running",runner:i,sessionId:m.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:m.command,pid:null,startedAt:f,lastKnownState:"running",exitCode:null,exitedAt:null}};return await y(e,w),await Ee(e,m),{kind:"createTask",taskId:w.id,repoId:w.repoId,workspaceId:w.workspaceId,sessionId:m.id,status:w.status,branch:w.branch,worktreePath:w.worktreePath,runner:w.runner}}catch(m){let f={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:m instanceof Error?m.message:"Unknown Craig error"};throw await y(e,f),m}};import{mkdir as Sd}from"node:fs/promises";import bd from"node:path";var Io=3,fd=1e3,gd=1e4,Ge=async e=>{let t=await v("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var Co=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await R("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},_t=async(e,t)=>{let r=await R("gh",Ao(e),{cwd:t});return JSON.parse(r.stdout)},He=async(e,t)=>{let r=await v("gh",Ao(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},vo=async(e,t,r)=>{if(r.length===0)return[];let n=yd(r),s=await hd(e,["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return r.map((a,l)=>{let c=i[`item${l}`],d=Pd(c);return{id:a.id,found:d!==null,view:d}})},Eo=async e=>{let t=await v("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:Rd(t.stdout.trim())},hd=async(e,t)=>{let r;for(let n=0;n<=Io;n+=1)try{return await R("gh",t,{cwd:e})}catch(s){if(r=s,n===Io||!kd(s))throw s;await Td(wd(n))}throw r},kd=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")},wd=e=>{let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||fd,r=Math.min(t*2**e,gd),n=Math.floor(Math.random()*Math.max(1,Math.floor(r*.25)));return r+n},Td=e=>new Promise(t=>setTimeout(t,e)),Ao=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],Rd=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},yd=e=>`
34
+ `)},Hr=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),wo=()=>({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}),qt=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),od=async(e,t)=>{let n=(await Y(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},To=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import xo from"node:path";import{readFile as id,rm as Zw}from"node:fs/promises";import ad from"node:path";var Te=async(e,t)=>{let r=await id(zr(e,t),"utf8"),n=JSON.parse(r);return ld(n,zr(e,t))},Ae=async(e,t)=>{await O(zr(e,t.id),{...t,updatedAt:new Date().toISOString()})};var zr=(e,t)=>ad.join(e.sessionsDir,`${t}.json`);function ld(e,t){let r=ud(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")||!dd(r.attach)||!cd(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 cd(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 dd(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 ud(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??""}}import{spawn as pd}from"node:child_process";import{createHash as md}from"node:crypto";import fd from"node:path";function Ut(e){return`'${e.replace(/'/g,"'\\''")}'`}var gd="craig",Ro=async(e,t,r)=>{let n=Qr(e,t),s=wd(),o=await R("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=Td(o.stdout);return await hd(e,n),i};var hd=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 R("tmux",n,{cwd:e})},yo=async(e,t,r)=>{await R("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},Po=async(e,t,r)=>{await R("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var bo=async(e,t,r)=>{await R("tmux",["pipe-pane","-o","-t",e,`cat >> ${Ut(t)}`],{cwd:r})},Bt=async(e,t,r,n)=>{let s=n??Io(e);if(r?await R("tmux",["select-window","-t",r],{cwd:e}):await R("tmux",["select-window","-t",t],{cwd:e}),await R("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await R("tmux",["switch-client","-t",s],{cwd:e});return}await yd(e,["attach-session","-t",s])};var So=async(e,t)=>{await R("tmux",["kill-session","-t",t],{cwd:e})};var Io=e=>{let r=fd.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=md("sha1").update(e).digest("hex").slice(0,8);return`${gd}-${r}-${n}`},Qr=(e,t)=>`${Io(e)}-${t.toLowerCase()}`,wd=()=>{let e=kd();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},kd=()=>{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},Td=e=>{let t=Rd(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]}},Rd=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),yd=async(e,t)=>{await new Promise((r,n)=>{let s=pd("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 Pd,constants as bd}from"node:fs";import{homedir as Co}from"node:os";import Re from"node:path";var Sd=[Re.join(Co(),".local","bin"),Re.join(Co(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Eo(e=process.env){return Id([...(e.PATH??"").split(Re.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:Sd])}function xe(e=process.env){return{...e,PATH:Eo(e).join(Re.delimiter)}}function Yr(e,t={}){if(e.includes(Re.sep)){let r=Re.isAbsolute(e)?e:Re.resolve(t.cwd??process.cwd(),e);return vo(r)?r:null}for(let r of Eo(t.env)){let n=Re.join(r,e);if(vo(n))return n}return null}function De(e,t={}){let r=Yr(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 vo(e){try{return Pd(e,bd.X_OK),!0}catch{return!1}}function Id(e){return[...new Set(e)]}var pt={async create(e,t){let r=await Ro(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await bo(r.paneId,t.logPath,t.repoRoot);let n=await Ao({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||Qr(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 Ae(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 Bt(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await Ae(e,s),s},async resize(e,t,r,n){await yo(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await Ae(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 Ae(e,n),n},async snapshot(e,t){return Cd(e,t)}},Jr={async prepare(e,t){let n=e.runnerSession.command[0],s=xe();await R(De(n,{cwd:t.repoRoot,env:s}),["--help"],{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=De(r[0],{cwd:e.worktreePath,env:xe()});await Po(t.session.paneId,[n,...r.slice(1)].map(s=>Ut(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},Cd=async(e,t)=>{let r=await E("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Ao({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},Ao=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var Xr=async(e,t,r,n={})=>{let s=r.trim(),o=await h.load(e),i=n.runner??h.runners.getDefault(o);if(h.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 a=n.workspaceId?await dt(e,n.workspaceId,s,{runner:i,config:o}):await Ge(e,t,s,{runner:i,config:o}),l=a.task,c=h.runners.buildCommand(i,s,o),d=`session_${l.id}`,p=l.artifacts.logPath?xo.resolve(e.workspaceRoot,l.artifacts.logPath):xo.join(e.logsDir,`${l.id}.log`);try{await Jr.prepare(l,{repoRoot:a.repoRoot});let m=await pt.create(e,{sessionId:d,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:p,command:c});await Jr.launch(l,{repoRoot:a.repoRoot,session:m});let f=new Date().toISOString();m={...m,status:"running",startedAt:f,command:c};let k={...l,status:"running",runner:i,sessionId:m.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:m.command,pid:null,startedAt:f,lastKnownState:"running",exitCode:null,exitedAt:null}};return await y(e,k),await Ae(e,m),{kind:"createTask",taskId:k.id,repoId:k.repoId,workspaceId:k.workspaceId,sessionId:m.id,status:k.status,branch:k.branch,worktreePath:k.worktreePath,runner:k.runner}}catch(m){let f={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:m instanceof Error?m.message:"Unknown Craig error"};throw await y(e,f),m}};import{mkdir as Od}from"node:fs/promises";import Fd from"node:path";var Do=3,vd=1e3,Ed=1e4,He=async e=>{let t=await E("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var $o=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await R("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},Kt=async(e,t)=>{let r=await R("gh",jo(e),{cwd:t});return JSON.parse(r.stdout)},ze=async(e,t)=>{let r=await E("gh",jo(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},Mo=async(e,t,r)=>{if(r.length===0)return[];let n=Ld(r),s=await Ad(e,["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return r.map((a,l)=>{let c=i[`item${l}`],d=jd(c);return{id:a.id,found:d!==null,view:d}})},Lo=async e=>{let t=await E("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:Md(t.stdout.trim())},Ad=async(e,t)=>{let r;for(let n=0;n<=Do;n+=1)try{return await R("gh",t,{cwd:e})}catch(s){if(r=s,n===Do||!xd(s))throw s;await $d(Dd(n))}throw r},xd=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)||vd,r=Math.min(t*2**e,Ed),n=Math.floor(Math.random()*Math.max(1,Math.floor(r*.25)));return r+n},$d=e=>new Promise(t=>setTimeout(t,e)),jo=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],Md=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},Ld=e=>`
35
35
  query CraigPullRequestBatch($owner: String!, $name: String!) {
36
36
  repository(owner: $owner, name: $name) {
37
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(`
@@ -110,57 +110,57 @@ fragment PrFields on PullRequest {
110
110
  }
111
111
  }
112
112
  }
113
- `,Pd=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 De=async(e,t)=>{let r=ve(e,t.artifacts.prStatusPath);r&&(await Sd(bd.dirname(r),{recursive:!0}),await N(r,{taskId:t.id,prs:t.prs}))},pt=async(e,t,r,n,s={readRawTask:z,validateTaskRecord:F,writeTask:y,writePrStatusArtifact:De})=>{let o=st(r,n),i=Be(t,o),a=nt(i.prs),l={...i,status:a};await s.writePrStatusArtifact(e,l);let c=await s.readRawTask(e,t.id),d=s.validateTaskRecord(c,`${e.tasksDir}/${t.id}.json`),p=d.status==="closed"?d.status:a,m=Be({...d,status:p},o);return await s.writeTask(e,m),m},mt=async(e,t)=>{let r=E(t),n=r?.number?String(r.number):t.branch,s=await _t(n,t.worktreePath);return pt(e,t,s,r)},ft=async(e,t)=>{for(let r of await zr(t)){let n=await He(r,t.worktreePath);if(!n)continue;return{discovered:!0,task:await pt(e,t,n,null)}}return{discovered:!1,task:t}},zr=async e=>{let t=await no(e.worktreePath).catch(()=>null);return[...new Set([t,e.branch].filter(r=>!!r))]};var ze=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await _t(n,r.worktreePath),a=Do(i);return r.pullRequest=a,await xo(e,t,r.repoId,a),"synced"}let s=await He(n,r.worktreePath);if(!s)return"not_found";let o=Do(s);return r.pullRequest=o,await xo(e,t,r.repoId,o),"discovered"},xo=async(e,t,r,n)=>{let s=await z(e,t.id),o=F(s,`${e.tasksDir}/${t.id}.json`),i=(o.repoTargets??t.repoTargets??[]).map(l=>l.repoId===r?{...l,pullRequest:n}:l),a={...o,repoTargets:i};return await y(e,a),a},Do=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:Id(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:Cd(e.reviewDecision??null),requiredChecks:ot(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),Id=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Cd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var gt=async(e,t)=>{let r=await S(e,t),n=E(r);return n?.number?(await Ge(r.worktreePath),ke(n)?(await ft(e,r)).task:mt(e,r)):r},Yr=async(e,t)=>{let r=await S(e,t);if(r.type==="project"&&r.repoTargets?.length)return await Qe(e,t),S(e,t);let n=E(r);if(await W(r),await Ge(r.worktreePath),!n?.number||ke(n)){let o=await ft(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return await De(e,o.task),o.task}let s=await mt(e,r);return await De(e,s),s},Qe=async(e,t)=>{let r=await S(e,t),n=(r.repoTargets??[]).filter(a=>a.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let a of n){await Ge(a.worktreePath);let l=a.pullRequest.number?await ze(e,r,a):await ze(e,r,a).catch(()=>"not_found");s[l==="not_found"?"notFound":l]++}let o=await z(e,r.id),i=F(o,`${e.tasksDir}/${r.id}.json`);return i.status!=="closed"&&(i.status=Lo(i),await y(e,i)),s},Jr=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=Qr(r,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",fallbackSelectors:[]};await $o(n,p).catch(async()=>{try{let m=d.pullRequest.number?await ze(e,s,d):await ze(e,s,d).catch(()=>"not_found");qt(o,m,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=E(s),a=i?.number&&!ke(i),l=a?[]:await zr(s),c={id:s.id,task:s,worktreePath:s.worktreePath,selector:a?String(i.number):l[0]??s.branch,mode:a?"number":"head",fallbackSelectors:a?[]:l.slice(1)};await $o(n,c).catch(async()=>{try{let{disposition:d,task:p}=await Bt(e,s.id),m=E(p);qt(o,d,m?.number??null,m?.url??null)}catch{}})}for(let s of n.values())try{await Ge(s.worktreePath);let o=await vo(s.worktreePath,s.repository,s.items),i=new Map(o.map(a=>[a.id,a]));for(let a of s.items){let l=Qr(r,a.task),d=i.get(a.id)?.view??await Dd(s.worktreePath,a);if(!d){qt(l,"not_found",null,null);continue}if(a.targetRepoId){let p=await z(e,a.task.id),m=F(p,`${e.tasksDir}/${a.task.id}.json`);await vd(e,m,a.targetRepoId,d)}else{let p=await z(e,a.task.id),m=F(p,`${e.tasksDir}/${a.task.id}.json`);await pt(e,m,d,a.mode==="number"?E(m):null)}qt(l,a.mode==="number"?"synced":"discovered",d.number,d.url)}}catch{}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await z(e,s.id),i=F(o,`${e.tasksDir}/${s.id}.json`);i.status!=="closed"&&(i.status=Lo(i),await y(e,i))}return t.map(s=>Qr(r,s))},Bt=async(e,t)=>{let r=await S(e,t);await W(r),await Ge(r.worktreePath);let n=E(r);if(n?.number&&!ke(n))return{disposition:"synced",task:await mt(e,r)};let s=await ft(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},Lo=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($d)?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"},vd=async(e,t,r,n)=>{let s=Ed(n),o=(t.repoTargets??[]).map(a=>a.repoId===r?{...a,pullRequest:s}:a),i={...t,repoTargets:o};return await y(e,i),i},Ed=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:Ad(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:xd(e.reviewDecision??null),requiredChecks:ot(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),Ad=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,xd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Dd=async(e,t)=>{if(t.mode!=="head")return null;for(let r of t.fallbackSelectors){let n=await He(r,e);if(n)return n}return null},$o=async(e,t)=>{let r=await Eo(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]})},Qr=(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):!!E(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},qt=(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},$d=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 Xr=async(e,t)=>{let r=await S(e,t);try{r.type==="project"&&r.repoTargets?.length?(await Qe(e,t),r=await S(e,t)):r.prs.some(o=>o.number)&&(r=await gt(e,t))}catch{}let n=await it(e,r),s=r.sessionId?await we(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var Zr=async(e,t)=>{let r=await S(e,t);if(await W(r),(await R("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await Ld(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},Ld=async e=>{let t=[],r=await R("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await jd(e);for(let s of n){let o=await v("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
113
+ `,jd=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 $e=async(e,t)=>{let r=Ee(e,t.artifacts.prStatusPath);r&&(await Od(Fd.dirname(r),{recursive:!0}),await O(r,{taskId:t.id,prs:t.prs}))},mt=async(e,t,r,n,s={readRawTask:z,validateTaskRecord:N,writeTask:y,writePrStatusArtifact:$e})=>{let o=ot(r,n),i=Be(t,o),a=st(i.prs),l={...i,status:a};await s.writePrStatusArtifact(e,l);let c=await s.readRawTask(e,t.id),d=s.validateTaskRecord(c,`${e.tasksDir}/${t.id}.json`),p=d.status==="closed"?d.status:a,m=Be({...d,status:p},o);return await s.writeTask(e,m),m},ft=async(e,t)=>{let r=A(t),n=r?.number?String(r.number):t.branch,s=await Kt(n,t.worktreePath);return mt(e,t,s,r)},gt=async(e,t)=>{for(let r of await Zr(t)){let n=await ze(r,t.worktreePath);if(!n)continue;return{discovered:!0,task:await mt(e,t,n,null)}}return{discovered:!1,task:t}},Zr=async e=>{let t=await co(e.worktreePath).catch(()=>null);return[...new Set([t,e.branch].filter(r=>!!r))]};var Qe=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await Kt(n,r.worktreePath),a=Fo(i);return r.pullRequest=a,await Oo(e,t,r.repoId,a),"synced"}let s=await ze(n,r.worktreePath);if(!s)return"not_found";let o=Fo(s);return r.pullRequest=o,await Oo(e,t,r.repoId,o),"discovered"},Oo=async(e,t,r,n)=>{let s=await z(e,t.id),o=N(s,`${e.tasksDir}/${t.id}.json`),i=(o.repoTargets??t.repoTargets??[]).map(l=>l.repoId===r?{...l,pullRequest:n}:l),a={...o,repoTargets:i};return await y(e,a),a},Fo=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:Nd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:Wd(e.reviewDecision??null),requiredChecks:it(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),Nd=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Wd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var ht=async(e,t)=>{let r=await b(e,t),n=A(r);return n?.number?(await He(r.worktreePath),ke(n)?(await gt(e,r)).task:ft(e,r)):r},tn=async(e,t)=>{let r=await b(e,t);if(r.type==="project"&&r.repoTargets?.length)return await Ye(e,t),b(e,t);let n=A(r);if(await W(r),await He(r.worktreePath),!n?.number||ke(n)){let o=await gt(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return await $e(e,o.task),o.task}let s=await ft(e,r);return await $e(e,s),s},Ye=async(e,t)=>{let r=await b(e,t),n=(r.repoTargets??[]).filter(a=>a.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let a of n){await He(a.worktreePath);let l=a.pullRequest.number?await Qe(e,r,a):await Qe(e,r,a).catch(()=>"not_found");s[l==="not_found"?"notFound":l]++}let o=await z(e,r.id),i=N(o,`${e.tasksDir}/${r.id}.json`);return i.status!=="closed"&&(i.status=Wo(i),await y(e,i)),s},rn=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=en(r,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",fallbackSelectors:[]};await No(n,p).catch(async()=>{try{let m=d.pullRequest.number?await Qe(e,s,d):await Qe(e,s,d).catch(()=>"not_found");Vt(o,m,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=A(s),a=i?.number&&!ke(i),l=a?[]:await Zr(s),c={id:s.id,task:s,worktreePath:s.worktreePath,selector:a?String(i.number):l[0]??s.branch,mode:a?"number":"head",fallbackSelectors:a?[]:l.slice(1)};await No(n,c).catch(async()=>{try{let{disposition:d,task:p}=await Gt(e,s.id),m=A(p);Vt(o,d,m?.number??null,m?.url??null)}catch{}})}for(let s of n.values())try{await He(s.worktreePath);let o=await Mo(s.worktreePath,s.repository,s.items),i=new Map(o.map(a=>[a.id,a]));for(let a of s.items){let l=en(r,a.task),d=i.get(a.id)?.view??await Kd(s.worktreePath,a);if(!d){Vt(l,"not_found",null,null);continue}if(a.targetRepoId){let p=await z(e,a.task.id),m=N(p,`${e.tasksDir}/${a.task.id}.json`);await _d(e,m,a.targetRepoId,d)}else{let p=await z(e,a.task.id),m=N(p,`${e.tasksDir}/${a.task.id}.json`);await mt(e,m,d,a.mode==="number"?A(m):null)}Vt(l,a.mode==="number"?"synced":"discovered",d.number,d.url)}}catch{}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await z(e,s.id),i=N(o,`${e.tasksDir}/${s.id}.json`);i.status!=="closed"&&(i.status=Wo(i),await y(e,i))}return t.map(s=>en(r,s))},Gt=async(e,t)=>{let r=await b(e,t);await W(r),await He(r.worktreePath);let n=A(r);if(n?.number&&!ke(n))return{disposition:"synced",task:await ft(e,r)};let s=await gt(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},Wo=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(Vd)?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"},_d=async(e,t,r,n)=>{let s=qd(n),o=(t.repoTargets??[]).map(a=>a.repoId===r?{...a,pullRequest:s}:a),i={...t,repoTargets:o};return await y(e,i),i},qd=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:Ud(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:Bd(e.reviewDecision??null),requiredChecks:it(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),Ud=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Bd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Kd=async(e,t)=>{if(t.mode!=="head")return null;for(let r of t.fallbackSelectors){let n=await ze(r,e);if(n)return n}return null},No=async(e,t)=>{let r=await Lo(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]})},en=(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):!!A(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},Vt=(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},Vd=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 nn=async(e,t)=>{let r=await b(e,t);try{r.type==="project"&&r.repoTargets?.length?(await Ye(e,t),r=await b(e,t)):r.prs.some(o=>o.number)&&(r=await ht(e,t))}catch{}let n=await at(e,r),s=r.sessionId?await Te(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var sn=async(e,t)=>{let r=await b(e,t);if(await W(r),(await R("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await Gd(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},Gd=async e=>{let t=[],r=await R("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await Hd(e);for(let s of n){let o=await E("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
114
114
 
115
- `)},jd=async e=>(await R("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
- `).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as Md}from"node:child_process";import{access as Nd}from"node:fs/promises";var en=async(e,t)=>{let r=await S(e,t),n=Ue(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await Nd(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},tn=async e=>{await new Promise((t,r)=>{let n=!1,s=Md("tail",["-n","+1","-f",e],{stdio:"inherit"}),o=()=>{n=!0,s.kill("SIGINT")};process.on("SIGINT",o),s.on("error",a=>{i(),r(a)}),s.on("exit",(a,l)=>{if(i(),n||l==="SIGINT"){t();return}if(a===0){t();return}r(new Error(`tail -n +1 -f ${e} failed with exit code ${a??"unknown"}.`))});function i(){process.off("SIGINT",o)}})};import{mkdir as Od}from"node:fs/promises";import Fd from"node:path";var rn=async(e,t)=>{let r=await S(e,t);if(await W(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 Mt(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 k.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 y(e,r);let o=[];for(let i of s){let a=new Date().toISOString(),l=await v("sh",["-lc",i],{cwd:r.worktreePath}),c=new Date().toISOString(),d=l.exitCode??1;if(o.push({command:i,startedAt:a,finishedAt:c,exitCode:d}),d!==0)return r.checks.results=o,r.checks.status="failed",r.checks.lastRunAt=c,r.status="review",r.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await jo(e,r),await y(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 jo(e,r),await y(e,r),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},jo=async(e,t)=>{let r=ve(e,t.artifacts.checkSummaryPath);r&&(await Od(Fd.dirname(r),{recursive:!0}),await N(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var nn=async(e,t)=>{let r=await S(e,t);await W(r);let n=await Mt(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 eo(r.worktreePath),await to(r.worktreePath,s);let o=await ro(r.worktreePath);return r.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},r.lastFailureReason=null,await y(e,r),{kind:"commitTask",taskId:r.id,status:r.status,commitSha:o.sha,message:o.message}};import{access as Wd}from"node:fs/promises";var sn=async(e,t)=>{let r=await S(e,t),n=await _d(r.worktreePath),s={...r,status:"closed",cleanup:{...r.cleanup,preservedWorktree:n&&r.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await y(e,s),s},_d=async e=>{try{return await Wd(e),!0}catch{return!1}};var on=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await we(e,t.sessionId);await wo(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 so(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 y(e,t)};var an=async(e,t,r)=>{let[n,s]=await Promise.all([S(e,t),Z(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 y(e,{...n,linkedRepoIds:o}),{kind:"addTaskLink",taskId:n.id,repoId:s.id,linkedRepoIds:o}},ln=async(e,t)=>{let r=await S(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>Z(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var cn=async(e,t)=>{let r=await S(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([Z(e,r.repoId),we(e,r.sessionId)]),o=await ut.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var dn=async(e,t)=>{let r=await S(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await we(e,r.sessionId).catch(s=>{throw qd(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 Wt(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},qd=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as Bd}from"node:child_process";var un=async(e,t)=>{let r=await S(e,t);await W(r);let s=(await k.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 Ud(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},Ud=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=Bd(s,o,{cwd:t,stdio:"inherit"});i.on("error",n),i.on("exit",a=>{if(a===0){r();return}n(new Error(`${e.join(" ")} failed with exit code ${a??"unknown"}.`))})})};var pn=async(e,t,r)=>{let n=await J(e,t);await y(e,{...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})},mn=async(e,t,r)=>{let n=await J(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await y(e,s),s},fn=async(e,t)=>{let r=await J(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 y(e,s),s};var gn=async(e,t,r="merge",n)=>{let s=await S(e,t),o=n??E(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await Co(s.worktreePath,o,r)};var b={listTasks:Wr,getTask:S,provisionTask:Ve,provisionProjectTask:ct,createTask:Hr,showTask:Xr,showTaskDiff:Zr,prepareTaskLogs:en,streamTaskLogs:tn,runChecks:rn,commitTask:nn,closeTask:sn,cleanupTask:on,addTaskLink:an,listTaskLinks:ln,sortTasksForDisplay:_r,resolveSelectedTaskId:qr,allocateTaskId:Fr,allocateTaskIdForRepo:Ke,allocateProjectTaskId:at,createDefaultTaskPtyTabs:dt,assertTaskWorktreeExists:W,resolveTaskLogPath:Ue,buildTaskInspection:it,resolveArtifactPath:ve,attachTask:cn,focusTask:dn,openTask:un,markRunnerFailed:pn,recordStartupFailure:mn,markTaskStarted:fn,prs:{refresh:gt,refreshChecks:Yr,discoverOrRefresh:Bt,discoverOrRefreshAll:Qe,discoverOrRefreshMany:Jr,merge:gn,getPrimaryPr:E,isPrTerminal:ke,isMergeReady:jt,deriveTaskStatus:nt,upsertPr:Be,normalizePr:st,summarizeRequiredChecks:Mr,writePrStatusArtifact:De}};async function Mo(e,t){switch(e.kind){case"addWorkspace":{let r=await H.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await hn(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await H.repos.addRepo(t.paths,e.path);return await hn(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return H.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await Fe({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await Y(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await H.repos.removeRepo(t.paths,e.repoId,{listTasks:b.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await he({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await he({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return H.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await H.archiveWorkspace(t.paths,e.workspaceId);return await Kd(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await H.restoreWorkspace(t.paths,e.workspaceId);return await hn(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return H.removeWorkspace(t.paths,e.workspaceId,{listTasks:b.listTasks});case"createTask":return b.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?b.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):b.listTasks(t.paths);case"attachTask":return b.attachTask(t.paths,e.taskId);case"addTaskLink":return b.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return b.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return b.showTask(t.paths,e.taskId);case"showSelectedTask":return b.showTask(t.paths,$e(t,"show"));case"streamTaskLogs":return b.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return b.prepareTaskLogs(t.paths,$e(t,"logs"));case"showTaskDiff":return b.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return b.showTaskDiff(t.paths,$e(t,"diff"));case"focusTask":return b.focusTask(t.paths,e.taskId);case"focusSelectedTask":return b.focusTask(t.paths,$e(t,"focus"));case"openTask":return b.openTask(t.paths,e.taskId);case"openSelectedTask":return b.openTask(t.paths,$e(t,"open"));case"runChecks":return b.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return b.runChecks(t.paths,$e(t,"check"));case"commitTask":return b.commitTask(t.paths,e.taskId);case"commitSelectedTask":return b.commitTask(t.paths,$e(t,"commit"));case"help":return{kind:"help",text:K()};case"exit":return{kind:"exit"};default:return Vd(e)}}async function hn(e,t,r){let n=await Fe({uiStateFile:e.uiStateFile})??Ct();await he({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function Kd(e,t){let r=await Fe({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await he({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function Vd(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function $e(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 No(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
+ `)},Hd=async e=>(await R("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
+ `).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as zd}from"node:child_process";import{access as Qd}from"node:fs/promises";var on=async(e,t)=>{let r=await b(e,t),n=Ke(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await Qd(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},an=async e=>{await new Promise((t,r)=>{let n=!1,s=zd("tail",["-n","+1","-f",e],{stdio:"inherit"}),o=()=>{n=!0,s.kill("SIGINT")};process.on("SIGINT",o),s.on("error",a=>{i(),r(a)}),s.on("exit",(a,l)=>{if(i(),n||l==="SIGINT"){t();return}if(a===0){t();return}r(new Error(`tail -n +1 -f ${e} failed with exit code ${a??"unknown"}.`))});function i(){process.off("SIGINT",o)}})};import{mkdir as Yd}from"node:fs/promises";import Jd from"node:path";var ln=async(e,t)=>{let r=await b(e,t);if(await W(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 Wt(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 h.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 y(e,r);let o=[];for(let i of s){let a=new Date().toISOString(),l=await E("sh",["-lc",i],{cwd:r.worktreePath}),c=new Date().toISOString(),d=l.exitCode??1;if(o.push({command:i,startedAt:a,finishedAt:c,exitCode:d}),d!==0)return r.checks.results=o,r.checks.status="failed",r.checks.lastRunAt=c,r.status="review",r.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await _o(e,r),await y(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 _o(e,r),await y(e,r),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},_o=async(e,t)=>{let r=Ee(e,t.artifacts.checkSummaryPath);r&&(await Yd(Jd.dirname(r),{recursive:!0}),await O(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var cn=async(e,t)=>{let r=await b(e,t);await W(r);let n=await Wt(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 io(r.worktreePath),await ao(r.worktreePath,s);let o=await lo(r.worktreePath);return r.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},r.lastFailureReason=null,await y(e,r),{kind:"commitTask",taskId:r.id,status:r.status,commitSha:o.sha,message:o.message}};import{access as Xd}from"node:fs/promises";var dn=async(e,t)=>{let r=await b(e,t),n=await Zd(r.worktreePath),s={...r,status:"closed",cleanup:{...r.cleanup,preservedWorktree:n&&r.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await y(e,s),s},Zd=async e=>{try{return await Xd(e),!0}catch{return!1}};var un=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await Te(e,t.sessionId);await So(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 uo(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 y(e,t)};var pn=async(e,t,r)=>{let[n,s]=await Promise.all([b(e,t),Z(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 y(e,{...n,linkedRepoIds:o}),{kind:"addTaskLink",taskId:n.id,repoId:s.id,linkedRepoIds:o}},mn=async(e,t)=>{let r=await b(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>Z(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var fn=async(e,t)=>{let r=await b(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([Z(e,r.repoId),Te(e,r.sessionId)]),o=await pt.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var gn=async(e,t)=>{let r=await b(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await Te(e,r.sessionId).catch(s=>{throw eu(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 Bt(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},eu=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as tu}from"node:child_process";var hn=async(e,t)=>{let r=await b(e,t);await W(r);let s=(await h.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 ru(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},ru=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=tu(s,o,{cwd:t,stdio:"inherit"});i.on("error",n),i.on("exit",a=>{if(a===0){r();return}n(new Error(`${e.join(" ")} failed with exit code ${a??"unknown"}.`))})})};var wn=async(e,t,r)=>{let n=await J(e,t);await y(e,{...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})},kn=async(e,t,r)=>{let n=await J(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await y(e,s),s},Tn=async(e,t)=>{let r=await J(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 y(e,s),s};var Rn=async(e,t,r="merge",n)=>{let s=await b(e,t),o=n??A(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await $o(s.worktreePath,o,r)};var S={listTasks:Kr,getTask:b,provisionTask:Ge,provisionProjectTask:dt,createTask:Xr,showTask:nn,showTaskDiff:sn,prepareTaskLogs:on,streamTaskLogs:an,runChecks:ln,commitTask:cn,closeTask:dn,cleanupTask:un,addTaskLink:pn,listTaskLinks:mn,sortTasksForDisplay:Vr,resolveSelectedTaskId:Gr,allocateTaskId:Br,allocateTaskIdForRepo:Ve,allocateProjectTaskId:lt,createDefaultTaskPtyTabs:ut,assertTaskWorktreeExists:W,resolveTaskLogPath:Ke,buildTaskInspection:at,resolveArtifactPath:Ee,attachTask:fn,focusTask:gn,openTask:hn,markRunnerFailed:wn,recordStartupFailure:kn,markTaskStarted:Tn,prs:{refresh:ht,refreshChecks:tn,discoverOrRefresh:Gt,discoverOrRefreshAll:Ye,discoverOrRefreshMany:rn,merge:Rn,getPrimaryPr:A,isPrTerminal:ke,isMergeReady:Nt,deriveTaskStatus:st,upsertPr:Be,normalizePr:ot,summarizeRequiredChecks:_r,writePrStatusArtifact:$e}};async function qo(e,t){switch(e.kind){case"addWorkspace":{let r=await H.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await yn(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await H.repos.addRepo(t.paths,e.path);return await yn(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return H.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await We({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await Y(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await H.repos.removeRepo(t.paths,e.repoId,{listTasks:S.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await we({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await we({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return H.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await H.archiveWorkspace(t.paths,e.workspaceId);return await nu(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await H.restoreWorkspace(t.paths,e.workspaceId);return await yn(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return H.removeWorkspace(t.paths,e.workspaceId,{listTasks:S.listTasks});case"createTask":return S.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?S.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):S.listTasks(t.paths);case"attachTask":return S.attachTask(t.paths,e.taskId);case"addTaskLink":return S.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return S.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return S.showTask(t.paths,e.taskId);case"showSelectedTask":return S.showTask(t.paths,Me(t,"show"));case"streamTaskLogs":return S.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return S.prepareTaskLogs(t.paths,Me(t,"logs"));case"showTaskDiff":return S.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return S.showTaskDiff(t.paths,Me(t,"diff"));case"focusTask":return S.focusTask(t.paths,e.taskId);case"focusSelectedTask":return S.focusTask(t.paths,Me(t,"focus"));case"openTask":return S.openTask(t.paths,e.taskId);case"openSelectedTask":return S.openTask(t.paths,Me(t,"open"));case"runChecks":return S.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return S.runChecks(t.paths,Me(t,"check"));case"commitTask":return S.commitTask(t.paths,e.taskId);case"commitSelectedTask":return S.commitTask(t.paths,Me(t,"commit"));case"help":return{kind:"help",text:K()};case"exit":return{kind:"exit"};default:return su(e)}}async function yn(e,t,r){let n=await We({uiStateFile:e.uiStateFile})??xt();await we({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function nu(e,t){let r=await We({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await we({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function su(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Me(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 Uo(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} ${zd(t)} ${Qd(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}`,...Gd(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} ${au(t)} ${lu(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}`,...ou(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 Hd(e)}}function Gd(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 Hd(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function zd(e){return e.checks.status}function Qd(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 cf}from"node:module";import{readFile as Yd,stat as Jd}from"node:fs/promises";import kn from"node:path";var Xd=200*1024,Zd=500*1024,Ut="100000";async function Fo(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return eu(e,t,r);try{let n=Re(r.selectedFilePath??null,t.filePaths),s=Re(r.selectedDiffPath??null,t.diffPaths),o=s?await ht(e.worktreePath):null,[i,a]=await Promise.all([Vt(e.worktreePath,n),s?wn(e.worktreePath,s,t.diffRows,o):Promise.resolve(U("No diff selected","No local changes found.","empty"))]),l=s?{[s]:a}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:l,selectedFile:i,selectedDiff:a,error:null}}catch(n){let s=n instanceof Error?n.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function eu(e,t,r){let n=Re(r.selectedFilePath??null,t.filePaths),s=Re(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([_o(e,n),(async()=>{if(!s)return U("No diff selected","No local changes found.","empty");let l=Kt(e,s),c=l?await ht(l.target.worktreePath).catch(()=>null):null;return qo(e,s,t.diffRows,c)})()]),a=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:a,selectedFile:o,selectedDiff:i}}async function Wo(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return tu(e,t);try{await W(e);let r=await ht(e.worktreePath),[n,s]=await Promise.all([Bo(e.worktreePath),Uo(e.worktreePath,r)]),o=[...new Set(s.map(p=>p.path))],i=Re(t.selectedFilePath??null,n),a=Re(t.selectedDiffPath??null,o),[l,c]=await Promise.all([Vt(e.worktreePath,i),a?wn(e.worktreePath,a,s,r):Promise.resolve(U("No diff selected","No local changes found.","empty"))]),d=a?{[a]:c}:{};return{taskId:e.id,fileRows:Go(n),filePaths:n,diffRows:s,diffPaths:o,diffContents:d,selectedFilePath:i,selectedDiffPath:a,selectedFile:l,selectedDiff:c,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:U("Files unavailable",n,"error"),selectedDiff:U("Diff unavailable",n,"error"),error:n}}}async function tu(e,t){let r=(e.repoTargets??[]).filter(m=>m.status==="ready"),n=await Promise.all(r.map(async m=>{let f=await ht(m.worktreePath).catch(()=>null),[w,u]=await Promise.all([Bo(m.worktreePath).catch(()=>[]),Uo(m.worktreePath,f).catch(()=>[])]);return{target:m,baseRef:f,targetFiles:w,targetDiffRows:u}})),s=[],o=[];for(let{target:m,targetFiles:f,targetDiffRows:w}of n)s.push(...f.map(u=>`${m.repoId}/${u}`)),o.push(...w.map(u=>({...u,path:`${m.repoId}/${u.path}`})));let i=[...new Set(o.map(m=>m.path))].sort(),a=Re(t.selectedFilePath??null,s),l=Re(t.selectedDiffPath??null,i),[c,d]=await Promise.all([_o(e,a),(async()=>{if(!l)return U("No diff selected","No local changes found.","empty");let m=Kt(e,l),f=m?n.find(w=>w.target.repoId===m.target.repoId):null;return qo(e,l,o,f?.baseRef??null)})()]),p=l?{[l]:d}:{};return{taskId:e.id,fileRows:Go(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:p,selectedFilePath:a,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}async function _o(e,t){let r=Kt(e,t);if(!r)return U("No file selected","No Git-visible files found.","empty");let n=await Vt(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function qo(e,t,r,n=null){let s=Kt(e,t);return s?{...await wn(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}:U(t,"Repo target is unavailable.","error",t)}function Kt(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 Bo(e){let t=await R("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return Ho(t.stdout)}async function Uo(e,t){let[r,n,s,o]=await Promise.all([ru(e,t),Oo(e,"staged"),Oo(e,"unstaged"),nu(e)]);return[...r,...n,...s,...o]}async function ru(e,t){if(!t)return[];let[r,n]=await Promise.all([R("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),R("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=Ko(r.stdout),o=Vo(n.stdout);return s.map(i=>{let a=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:a.additions,deletions:a.deletions}}).sort((i,a)=>i.path.localeCompare(a.path))}async function Oo(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([R("git",[...r,"--name-status"],{cwd:e}),R("git",[...r,"--numstat"],{cwd:e})]),o=Ko(n.stdout),i=Vo(s.stdout);return o.map(a=>{let l=i.get(a.path)??{additions:null,deletions:null};return{group:t,path:a.path,status:a.status,additions:l.additions,deletions:l.deletions}}).sort((a,l)=>a.path.localeCompare(l.path))}async function nu(e){let t=await R("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=Ho(t.stdout);return await Promise.all(r.map(async s=>{let o=await Vt(e,s),i=o.status==="ready"?su(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function Ko(e){return e.split(`
126
- `).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 Vo(e){let t=new Map;for(let r of e.split(`
127
- `)){let n=r.trim();if(!n)continue;let[s="-",o="-",...i]=n.split(" "),a=i.join(" ");a&&t.set(a,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function ht(e){return(await v("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await v("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function Vt(e,t){if(!t)return U("No file selected","No Git-visible files found.","empty");let r=ou(e,t);try{let n=await Jd(r);if(n.size>Xd)return U(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await Yd(r);return iu(s)?U(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
128
- `),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return U(t,s,"missing",t,null)}}async function wn(e,t,r,n=null){if(!t)return U("No diff selected","No local changes found.","empty");let s=[],o=r.filter(a=>a.path===t).map(a=>a.group);if(o.includes("branch")){let a=n??await ht(e);if(a){let l=await R("git",["diff","--stat","--patch",`--unified=${Ut}`,`${a}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
129
- ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let a=await R("git",["diff","--cached","--stat","--patch",`--unified=${Ut}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`staged
130
- ${a.stdout.trimEnd()}`)}if(o.includes("unstaged")){let a=await R("git",["diff","--stat","--patch",`--unified=${Ut}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`unstaged
131
- ${a.stdout.trimEnd()}`)}if(o.includes("untracked")){let a=await v("git",["diff","--no-index","--stat","--patch",`--unified=${Ut}`,"--","/dev/null",t],{cwd:e});a.stdout.trim().length>0&&s.push(`untracked
125
+ `);default:return iu(e)}}function ou(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 iu(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function au(e){return e.checks.status}function lu(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 Cf}from"node:module";import{readFile as cu,stat as du}from"node:fs/promises";import Pn from"node:path";var uu=200*1024,pu=500*1024,Ht="100000";async function Ko(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return mu(e,t,r);try{let n=ye(r.selectedFilePath??null,t.filePaths),s=ye(r.selectedDiffPath??null,t.diffPaths),o=s?await wt(e.worktreePath):null,[i,a]=await Promise.all([Qt(e.worktreePath,n),s?bn(e.worktreePath,s,t.diffRows,o):Promise.resolve(B("No diff selected","No local changes found.","empty"))]),l=s?{[s]:a}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:l,selectedFile:i,selectedDiff:a,error:null}}catch(n){let s=n instanceof Error?n.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function mu(e,t,r){let n=ye(r.selectedFilePath??null,t.filePaths),s=ye(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([Go(e,n),(async()=>{if(!s)return B("No diff selected","No local changes found.","empty");let l=zt(e,s),c=l?await wt(l.target.worktreePath).catch(()=>null):null;return Ho(e,s,t.diffRows,c)})()]),a=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:a,selectedFile:o,selectedDiff:i}}async function Vo(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return fu(e,t);try{await W(e);let r=await wt(e.worktreePath),[n,s]=await Promise.all([zo(e.worktreePath),Qo(e.worktreePath,r)]),o=[...new Set(s.map(p=>p.path))],i=ye(t.selectedFilePath??null,n),a=ye(t.selectedDiffPath??null,o),[l,c]=await Promise.all([Qt(e.worktreePath,i),a?bn(e.worktreePath,a,s,r):Promise.resolve(B("No diff selected","No local changes found.","empty"))]),d=a?{[a]:c}:{};return{taskId:e.id,fileRows:Xo(n),filePaths:n,diffRows:s,diffPaths:o,diffContents:d,selectedFilePath:i,selectedDiffPath:a,selectedFile:l,selectedDiff:c,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:B("Files unavailable",n,"error"),selectedDiff:B("Diff unavailable",n,"error"),error:n}}}async function fu(e,t){let r=(e.repoTargets??[]).filter(m=>m.status==="ready"),n=await Promise.all(r.map(async m=>{let f=await wt(m.worktreePath).catch(()=>null),[k,u]=await Promise.all([zo(m.worktreePath).catch(()=>[]),Qo(m.worktreePath,f).catch(()=>[])]);return{target:m,baseRef:f,targetFiles:k,targetDiffRows:u}})),s=[],o=[];for(let{target:m,targetFiles:f,targetDiffRows:k}of n)s.push(...f.map(u=>`${m.repoId}/${u}`)),o.push(...k.map(u=>({...u,path:`${m.repoId}/${u.path}`})));let i=[...new Set(o.map(m=>m.path))].sort(),a=ye(t.selectedFilePath??null,s),l=ye(t.selectedDiffPath??null,i),[c,d]=await Promise.all([Go(e,a),(async()=>{if(!l)return B("No diff selected","No local changes found.","empty");let m=zt(e,l),f=m?n.find(k=>k.target.repoId===m.target.repoId):null;return Ho(e,l,o,f?.baseRef??null)})()]),p=l?{[l]:d}:{};return{taskId:e.id,fileRows:Xo(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:p,selectedFilePath:a,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}async function Go(e,t){let r=zt(e,t);if(!r)return B("No file selected","No Git-visible files found.","empty");let n=await Qt(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function Ho(e,t,r,n=null){let s=zt(e,t);return s?{...await bn(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}:B(t,"Repo target is unavailable.","error",t)}function zt(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 zo(e){let t=await R("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return Zo(t.stdout)}async function Qo(e,t){let[r,n,s,o]=await Promise.all([gu(e,t),Bo(e,"staged"),Bo(e,"unstaged"),hu(e)]);return[...r,...n,...s,...o]}async function gu(e,t){if(!t)return[];let[r,n]=await Promise.all([R("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),R("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=Yo(r.stdout),o=Jo(n.stdout);return s.map(i=>{let a=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:a.additions,deletions:a.deletions}}).sort((i,a)=>i.path.localeCompare(a.path))}async function Bo(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([R("git",[...r,"--name-status"],{cwd:e}),R("git",[...r,"--numstat"],{cwd:e})]),o=Yo(n.stdout),i=Jo(s.stdout);return o.map(a=>{let l=i.get(a.path)??{additions:null,deletions:null};return{group:t,path:a.path,status:a.status,additions:l.additions,deletions:l.deletions}}).sort((a,l)=>a.path.localeCompare(l.path))}async function hu(e){let t=await R("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=Zo(t.stdout);return await Promise.all(r.map(async s=>{let o=await Qt(e,s),i=o.status==="ready"?wu(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function Yo(e){return e.split(`
126
+ `).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 Jo(e){let t=new Map;for(let r of e.split(`
127
+ `)){let n=r.trim();if(!n)continue;let[s="-",o="-",...i]=n.split(" "),a=i.join(" ");a&&t.set(a,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function wt(e){return(await E("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await E("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function Qt(e,t){if(!t)return B("No file selected","No Git-visible files found.","empty");let r=ku(e,t);try{let n=await du(r);if(n.size>uu)return B(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await cu(r);return Tu(s)?B(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
128
+ `),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return B(t,s,"missing",t,null)}}async function bn(e,t,r,n=null){if(!t)return B("No diff selected","No local changes found.","empty");let s=[],o=r.filter(a=>a.path===t).map(a=>a.group);if(o.includes("branch")){let a=n??await wt(e);if(a){let l=await R("git",["diff","--stat","--patch",`--unified=${Ht}`,`${a}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
129
+ ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let a=await R("git",["diff","--cached","--stat","--patch",`--unified=${Ht}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`staged
130
+ ${a.stdout.trimEnd()}`)}if(o.includes("unstaged")){let a=await R("git",["diff","--stat","--patch",`--unified=${Ht}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`unstaged
131
+ ${a.stdout.trimEnd()}`)}if(o.includes("untracked")){let a=await E("git",["diff","--no-index","--stat","--patch",`--unified=${Ht}`,"--","/dev/null",t],{cwd:e});a.stdout.trim().length>0&&s.push(`untracked
132
132
  ${a.stdout.trimEnd()}`)}let i=s.join(`
133
133
 
134
- `);return i.length>Zd?U(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?U(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(`
135
- `):["No diff for this file."],byteLength:i.length}}function Go(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 Re(e,t){return e&&t.includes(e)?e:t[0]??null}function su(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function Ho(e){return[...new Set(e.split(`
136
- `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function ou(e,t){let r=kn.resolve(e,t),n=kn.resolve(e);if(r!==n&&!r.startsWith(`${n}${kn.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function iu(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function U(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}var au=["tasks","center","inspector","actions"],zo=["agent","terminal"],Qo=[],I="inspection",IR=[...zo,...Qo],Tn=["commit","push","refresh-checks","close-task"],Yo=["refresh-checks","close-task"],Jo=["task","checks","pr","setup-run","actions","next-action"],Rn=["diff","files","review"];function Xo(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=mu(e?.openInspectionKind)??r,s=k.runners.getEnabled(t);return{inputMode:gu(e?.inputMode),focusedRegion:uu(e?.focusedRegion),selectedRepoId:de(e?.selectedRepoId),selectedWorkspaceId:de(e?.selectedWorkspaceId),selectedTaskId:de(e?.selectedTaskId),selectedPtyTabId:de(e?.selectedPtyTabId),selectedLeftItemId:yu(de(e?.selectedTaskId)),activeTab:r?I:de(e?.activeTab)??"agent",preferredPtyTabKind:fu(e?.preferredPtyTabKind),inspectorSection:kt(e?.inspectorSection,Jo,"task"),inspectionMode:pu(e?.inspectionMode,r==="diff"?"diff":"files"),openInspectionKind:n,selectedFileTreePath:de(e?.selectedFileTreePath),selectedFilePath:de(e?.selectedFilePath),selectedDiffPath:de(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:kt(e?.selectedActionId,Tn,"commit"),selectedProjectTargetId:null,selectedRunner:hu(e?.selectedRunner,s,k.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,fileSearchQuery:null,workspaceBrowser:null,terminal:lu(),centerZoomed:!1}}function lu(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function Zo(e,t){return{...e??Ct(),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 wt(e,t,r={}){let n=Ru(e,t),s=yn(n),o=(s?.kind==="workspace"?t.workspaces?.find(d=>d.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(d=>d.id===t.tasks.find(p=>p.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(d=>d.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,a=((s?.kind==="repo"?t.repos.find(d=>d.id===s.id)??null:s?.kind==="task"?t.repos.find(d=>d.id===t.tasks.find(p=>p.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(d=>d.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(d.id))??null:null)??(o?.kind!=="project"?t.repos.find(d=>d.id===o?.primaryRepoId)??null:null)??t.repos.find(d=>d.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(d=>d.workspaceId===o.id):a?t.tasks.filter(d=>d.repoId===a):[],c=(s?.kind==="task"?l.find(d=>d.id===s.id)??null:null)??l.find(d=>d.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:r.resetInputMode?"control":e.inputMode,selectedLeftItemId:n,selectedWorkspaceId:o?.id??null,selectedRepoId:a,selectedTaskId:c?.id??null,...ku(c,e.activeTab,e.selectedPtyTabId),selectedFilePath:du(e,t,c?.id??null),...wu(e,t,c?.id??null),selectedDiffPath:cu(e,t,c?.id??null),inspectorSection:kt(e.inspectorSection,Jo,"task")}}function ue(e,t){return{...e,terminal:t}}function ei(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function ti(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function te(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
137
- `}function ri(e){return e.length===1&&e>=" "&&e!=="\x7F"}function ni(e){return oi(e)||Ye(e)!==null}function si(e){return Qo.includes(e)}function oi(e){return zo.includes(e)}function ii(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[I]:[]]}function cu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function du(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function kt(e,t,r){return t.includes(e??"")?e:r}function uu(e){return e==="tabs"?"center":kt(e,au,"tasks")}function pu(e,t){return e==="checks"||e==="actions"||e==="review"?"review":kt(e,Rn,t)}function mu(e){return e==="file"||e==="diff"?e:null}function fu(e){return e==="terminal"?"terminal":"agent"}function gu(e){return e==="terminal"?"terminal":"control"}function hu(e,t=[...x],r="codex"){return e&&k.runners.isRunnerType(e)&&t.includes(e)?e:r}function Gt(e,t=x){let r=t.length>0?t:x,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function Ye(e){let t=x.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function ku(e,t,r){if(!e)return{activeTab:t===I?t:"agent",selectedPtyTabId:null};let n=e.ptyTabs.find(a=>a.id===r)??null,s=e.selectedPtyTabId?e.ptyTabs.find(a=>a.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(a=>a.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(oi(t)){let l=e.ptyTabs.find(c=>c.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:l?.id??I,selectedPtyTabId:l?.id??null}}if(t===I)return{activeTab:I,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??I,selectedPtyTabId:i?.id??null}}function wu(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?Tu(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function Tu(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 Ru(e,t){let r=Le(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 Le(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 yn(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 de(e){return typeof e=="string"?e:null}function yu(e){return e?`task:${e}`:null}function Tt(e){return typeof e=="string"&&e.startsWith("task:")}function Ht(e){return typeof e=="string"&&e.startsWith("new-task:")}function zt(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function ai(e){return typeof e=="string"&&e.startsWith("workspace:")}function Pn(e){return Ht(e)?e.slice(9):null}function Sn(e){return zt(e)?e.slice(19):null}async function ye(e,t,r){let n=oe(e),[s,o]=await Promise.all([H.repos.listRegisteredRepos(n),H.listWorkspaces(n,{archived:!1})]),i=await b.listTasks(n),a=bn(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},c=a?await Wo(a,l):null;return{workspaceRoot:e,workspaces:o.workspaces,repos:s.repos,tasks:i.tasks,inspection:c,...r?{enabledRunnerIds:r}:{}}}function bn(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function li(e,t){return wt(e,t)}import Dn from"node:path";import jR from"picocolors";var Pu=[" \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 In(){return[...Pu]}var Qt={width:120,height:36},ee={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function re(e,t){return{width:Math.max(e??Qt.width,Qt.width),height:Math.max(t??Qt.height,Qt.height)}}var Su=["Start","Options","Exit"],bu=["Resume","Options","Exit"],Xt=2,Zt=2,er=2,Iu=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Cu=new RegExp("\x1B\\[(?:0)?m","g"),vu=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),Eu=/https?:\/\/[^\s<>"']+/g,Cn="\x1B[0m",vn="\x1B]8;;\x1B\\",P={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 ui(e,t={}){return An(e,{subtitle:"crAIg is that you?",menuItems:Su,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function pi(e,t={}){return An(e,{subtitle:"Control mode is paused.",menuItems:bu,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var Yt=[" 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."],Au=["Help"];function En(e,t={}){return An(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Au,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function mi(e,t={}){let r=t.color??!0,n=P.overlay,s=new Array(e.height).fill(L(" ".repeat(e.width),r,n)),o=In(),i=Math.max(1,Math.floor((e.height-o.length-2-Yt.length)/2));for(let d=0;d<o.length&&!(i+d>=e.height);d+=1)s[i+d]=L(wi(o[d]??"",e.width),r,P.overlayLogo);let a=Math.max(...Yt.map(d=>d.length)),l=Math.max(0,Math.floor((e.width-a)/2)),c=i+o.length+2;for(let d=0;d<Yt.length;d+=1){let p=c+d;if(p>=e.height)break;let m=Yt[d]??"";s[p]=L(ae(" ".repeat(l)+m,e.width),r,n)}return s.join(`
138
- `)}function fi(e,t={}){let r=t.color??!0,n=P.overlay,s=new Array(e.height).fill(L(" ".repeat(e.width),r,n)),o="Error Log",i=t.errorLogPath??"",a=t.errorLogLines??[],l=Math.max(20,e.width-8),c=Math.max(0,Math.floor((e.width-l)/2)),d=[{text:o,tone:"selected"},{text:i,tone:"muted"},X(),...a.length>0?a.map(f=>({text:f})):[{text:"No Craig errors have been logged.",tone:"muted"}],X(),{text:"Esc returns to Options.",tone:"muted"}],p=Rt(d,e.height-2),m=Math.max(1,Math.floor((e.height-p.length)/2));for(let f=0;f<p.length;f+=1){let w=m+f;if(w>=e.height)break;let u=p[f]??X(),D=`${" ".repeat(c)}${rr(u.text,l)}`,B=u.tone==="selected"?P.overlayMenuSelected:u.tone==="muted"?P.overlay:P.panelBg;s[w]=L(ae(D,e.width),r,B)}return s.join(`
139
- `)}function gi(e,t,r={}){let n=r.color??!0,s=ee.leftWidth,o=ee.rightWidth,i=ee.dividerWidth,a=r.centerOnly??!1,l=a?e.width:e.width-s-o-i*2,c=e.height-ee.topRailHeight-1,d=r.focusFlashActive??!1,p={bg:P.divider.bg,fg:"9ece6a"},m=d&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?p:P.divider,f=d&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?p:P.divider,w=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,u=L(ae(w,e.width),n,P.rail),D=Du(t,s-Xt-Zt,c,n),B=$u(t,l,c,n),fe=ju(t,o,c,n),ge=t.inputMode==="terminal",T=[];for(let le=0;le<c;le+=1){if(a){T.push(Jt(B[le]??X(),l,n,"center"));continue}let pl=Jt(D[le]??X(),s,n,"left"),ml=L("\u2502",n,m),fl=Jt(B[le]??X(),l,n,"center"),gl=L("\u2502",n,f),hl=Jt(fe[le]??X(),o,n,"right");T.push(`${pl}${ml}${fl}${gl}${hl}`)}let Ne=ge||t.modalInput?P.panelBg:P.panelMuted,A=xu(t.footerText,t.footerToast,e.width,n,Ne);return[u,...T,A].join(`
140
- `)}function xu(e,t,r,n,s){let o=` ${e}`;if(!t)return L(ae(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,a=Q(i),l=Q(o),c=Math.max(1,r-l-a-2),d=l+c+a+2>r?rr(o,Math.max(0,r-a-3)):o,p=Math.max(1,r-Q(d)-a-2),m=t.tone==="error"?Zu(i,n,s):Je(i,n,s),f=`${d}${" ".repeat(p)}${m} `;return L(ae(f,r),n,s)}function An(e,t){let r=new Array(e.height).fill(L(" ".repeat(e.width),t.color,P.overlay)),n=In(),s=Math.max(...t.menuItems.map(c=>c.length)),o=t.menuItems.map((c,d)=>`${d===t.menuIndex?">":" "} ${c.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],a=[...n,"",t.subtitle,"",...o,...i],l=Math.max(1,Math.floor((e.height-a.length)/2));for(let c=0;c<a.length;c+=1){let d=wi(a[c]??"",e.width);if(c<n.length){r[l+c]=L(d,t.color,P.overlayLogo);continue}if(c===n.length+1){r[l+c]=L(d,t.color,P.overlaySubtitle);continue}let p=c-(n.length+3),f=p>=0&&p<t.menuItems.length&&p===t.menuIndex?P.overlayMenuSelected:P.overlay;r[l+c]=L(d,t.color,f)}if(t.versionText){let c=t.updateText?" (update available)":"",d=`${t.versionText}${c} `,p=" ".repeat(Math.max(0,e.width-Q(d)));r[e.height-1]=L(`${p}${xn(d,t.color,P.overlay)}`,t.color,P.overlay)}return r.join(`
141
- `)}function Du(e,t,r,n){let s=Ou(e.runners),o=1,i=e.leftTree.map(l=>Nu(l,t,n));return[...Rt(i,r-o),s]}function $u(e,t,r,n){let s=t-2,o=e.tabs.find(T=>T.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:Yu(e.tabs),a=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,a)),c=`${" ".repeat(i)}${e.inputMode==="terminal"?Je(l,n,P.panelBg):tr(l,n,P.panelMuted)}`,d=[`${tr(e.centerHeader.tabLabel,n,P.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),p=e.tabs.find(T=>T.active)?.id??"agent",m=e.centerHeader.tabLabel==="BROWSER"||!ni(p)?e.centerTranscript.map(T=>({...T})):Lu(e),f=Fu(e.tabs,n,e.focusedRegion==="center"),w=" engaged ",u=w.length+2,D=e.inputMode==="terminal"?Je(`${w}\u25CF `,n,P.panelBg):"",B=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-Q(f)-u)):"",ge=[{text:e.inputMode==="terminal"?`${f}${B}${D}`:f},{text:c,tone:"muted"},{text:d},X(),...m];return Rt(ge,r)}function Lu(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},X(),{text:e.terminal.error},X(),{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:yi(n.segments),segments:n.segments,fullBleed:!0}))}function ju(e,t,r,n){let s=e.rightInspection?Mu(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):Rt([{text:"CONTEXT"},X(),...e.rightContext.map(o=>Wu(o,n)),...e.actionMessage?[X(),{text:e.actionMessage}]:[]],r);return Rt(s,r)}function Mu(e,t){let r=e.slice(0,2),n=e.slice(2),s=Math.max(0,t-r.length),o=n.findIndex(a=>a.focused||a.selected),i=o===-1?0:Xu(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(a=>ci(a)),...n.slice(i,i+s).map(a=>ci(a))]}function ci(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 Nu(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${Je("\u25CF",r,e.selected?P.panelSelected:P.panelBg)}`:"",a=e.prBadge?e.prBadge.reduce((f,w)=>f+Q(w.text),0):0,l=t-Q(o)-Q(s)-a,c=e.selected?e.text:e.focused?Je(e.text,r,P.panelBg):e.panelHeader?tr(e.text,r,P.panelMuted):e.text,d=ae(`${n}${c}`,Math.max(0,l)),p=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let f=[{text:`${d}${o}${i}`},...e.prBadge];return{text:`${d}${o}${e.prBadge.map(u=>u.text).join("")}`,segments:f,tone:p}}return{text:`${d}${o}${i}`,tone:p}}function Ou(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:P.success.fg}}):r.push({text:s.text,style:{fg:P.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function Fu(e,t,r){return e.map(n=>n.active?r?Je(n.label,t,P.panelBg):tr(n.label,t,P.panelBg):xn(n.label,t,P.panelBg)).join(" ")}function Wu(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?xn(e.value,t,P.panelBg):e.value}`}}function Jt(e,t,r,n){let s=_u(n,e.tone??"default"),o=qu(e,r,s);if(n==="left"){if(e.fullBleed)return L(ae(o,t),r,s);let a=t-Xt-Zt;if(e.rightAlign){let c=Q(o),d=Math.max(0,a-c),p=`${" ".repeat(Xt)}${" ".repeat(d)}${o}${" ".repeat(Zt)}`;return L(p,r,s)}let l=`${" ".repeat(Xt)}${ae(o,a)}${" ".repeat(Zt)}`;return L(l,r,s)}return n==="center"&&e.fullBleed?Bu(e,t,r,s):L(ae(` ${o}`,t),r,s)}function _u(e,t){return t==="selected"||t==="focused"?P.panelSelected:t==="muted"?P.panelMuted:P.panelBg}function Rt(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(X());return r}function X(){return{text:""}}function qu(e,t,r){return e.segments?e.segments.map(n=>hi(n,t,r)).join(""):e.text}function Bu(e,t,r,n){let s=" ".repeat(er),o=Math.max(0,t-er*2);if(!e.segments)return L(`${s}${ae(e.text,o)}${s}`,r,n);let i=Vu(e.segments,o),a=`${s}${i.map(l=>hi(l,r,n)).join("")}${s}${r?vn:""}`;return L(a,r,n)}function hi(e,t,r){let n=e.href?`${ki(e.href)}${e.text}${vn}`:Uu(e.text);return!t||!e.style?n:`${yt(zu(e.style,r))}${Qu(e.style)}${n}${Cn}${yt(r)}`}function Uu(e){return e.replace(Eu,t=>{let[r,n]=Ku(t);return`${ki(r)}${r}${vn}${n}`})}function Ku(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ki(e){return`\x1B]8;;${e}\x1B\\`}function Vu(e,t){let r=Gu(e,t);return Hu(r,t)}function Gu(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=Q(s.text);if(o<=n){r.push(s),n-=o;continue}let i=rr(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function Hu(e,t){let r=Q(yi(e));if(r>=t)return e;let n=[...e].reverse().find(s=>s.style?.bg)?.style;return n?.bg?[...e,{text:" ".repeat(t-r),style:n}]:[...e,{text:" ".repeat(t-r)}]}function zu(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 Qu(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 Yu(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+3}return 0}function wi(e,t){let r=Math.max(0,t-Q(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function ae(e,t){let r=Q(e);return r>=t?Ju(e,t):e+" ".repeat(t-r)}function Ju(e,t){if(t<=0)return"";if(Q(e)<=t)return e;let r=Ri(e);return rr(r,Math.max(0,t-1))+"\u2026"}function Q(e){let t=0;for(let r of Array.from(Ri(e)))t+=Ti(r);return t}function rr(e,t){let r="",n=0;for(let s of Array.from(e)){let o=Ti(s);if(n+o>t)break;r+=s,n+=o}return r}function Ti(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 Xu(e,t,r){return Math.min(Math.max(e,t),r)}function Ri(e){return e.replace(vu,"").replace(Iu,"")}function yi(e){return e.map(t=>t.text).join("")}function L(e,t,r){if(!t)return e;let n=yt(r),s=e.replace(Cu,`${Cn}${n}`);return`${n}${s}${Cn}`}function yt(e){let t=[];return e.fg&&t.push(`38;2;${di(e.fg).join(";")}`),e.bg&&t.push(`48;2;${di(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function di(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,r){return nr(e,t,P.success.fg,r)}function Zu(e,t,r){return nr(e,t,P.error.fg,r)}function tr(e,t,r){return nr(e,t,P.accent.fg,r)}function xn(e,t,r){return nr(e,t,P.mutedfg.fg,r)}function nr(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${yt(s)}${e}${yt(n)}`}function Pi(e,t,r){let n=e.tasks.find(a=>a.ptyTabs.some(l=>l.id===t))??null,s=n?.ptyTabs.find(a=>a.id===t)??null,o=n?.worktreePath??r,i=s?.kind==="agent"?tp(s):[];return n?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:ep(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function ep(e,t){let r=(e??"").split(Dn.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(Dn.delimiter):[...r,t].join(Dn.delimiter)}function tp(e){return e.command.length>0?e.command:["codex"]}function Si(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 Pe(e){return{columns:Math.max(20,e.width-ee.leftWidth-ee.rightWidth-ee.dividerWidth-er*2),rows:Math.max(5,e.height-ee.topRailHeight-5)}}function bi(e){return e.length===1||te(e)||e==="BACKSPACE"||e==="TAB"}function Pt(e){return typeof e=="string"&&new RegExp(`:(?:agent|${x.join("|")})(?:-\\d+)?$`).test(e)}function Ii(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 $n(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Ci(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 St(e){return Ei.includes(e)?"SHIFT_ENTER":null}function Ln(e){return Ei.some(t=>t.startsWith(e))}function vi(e){return e==="ESCAPE"?"\x1B":e.length===1?e:null}var Ei=["\x1B[13;2u","\x1B[13;2~","\x1B[27;2;13~","\x1B[27;2;10~"];function Ai(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
134
+ `);return i.length>pu?B(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?B(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(`
135
+ `):["No diff for this file."],byteLength:i.length}}function Xo(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 ye(e,t){return e&&t.includes(e)?e:t[0]??null}function wu(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function Zo(e){return[...new Set(e.split(`
136
+ `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function ku(e,t){let r=Pn.resolve(e,t),n=Pn.resolve(e);if(r!==n&&!r.startsWith(`${n}${Pn.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function Tu(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function B(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}var Ru=["tasks","center","inspector","actions"],ei=["agent","terminal"],ti=[],I="inspection",YR=[...ei,...ti],Sn=["commit","push","refresh-checks","close-task"],ri=["refresh-checks","close-task"],ni=["task","checks","pr","setup-run","actions","next-action"],In=["files","review"];function si(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=Cu(e?.openInspectionKind)??r,s=h.runners.getEnabled(t);return{inputMode:Eu(e?.inputMode),focusedRegion:Su(e?.focusedRegion),selectedRepoId:ue(e?.selectedRepoId),selectedWorkspaceId:ue(e?.selectedWorkspaceId),selectedTaskId:ue(e?.selectedTaskId),selectedPtyTabId:ue(e?.selectedPtyTabId),selectedLeftItemId:Lu(ue(e?.selectedTaskId)),activeTab:r?I:ue(e?.activeTab)??"agent",preferredPtyTabKind:vu(e?.preferredPtyTabKind),inspectorSection:kt(e?.inspectorSection,ni,"task"),inspectionMode:Iu(e?.inspectionMode,r==="diff"?"review":"files"),openInspectionKind:n,selectedFileTreePath:ue(e?.selectedFileTreePath),selectedFilePath:ue(e?.selectedFilePath),selectedDiffPath:ue(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:kt(e?.selectedActionId,Sn,"commit"),selectedProjectTargetId:null,selectedRunner:Au(e?.selectedRunner,s,h.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,fileSearchQuery:null,workspaceBrowser:null,terminal:yu(),centerZoomed:!1}}function yu(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function oi(e,t){return{...e??xt(),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 Tt(e,t,r={}){let n=Mu(e,t),s=Cn(n),o=(s?.kind==="workspace"?t.workspaces?.find(d=>d.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(d=>d.id===t.tasks.find(p=>p.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(d=>d.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,a=((s?.kind==="repo"?t.repos.find(d=>d.id===s.id)??null:s?.kind==="task"?t.repos.find(d=>d.id===t.tasks.find(p=>p.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(d=>d.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(d.id))??null:null)??(o?.kind!=="project"?t.repos.find(d=>d.id===o?.primaryRepoId)??null:null)??t.repos.find(d=>d.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(d=>d.workspaceId===o.id):a?t.tasks.filter(d=>d.repoId===a):[],c=(s?.kind==="task"?l.find(d=>d.id===s.id)??null:null)??l.find(d=>d.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:r.resetInputMode?"control":e.inputMode,selectedLeftItemId:n,selectedWorkspaceId:o?.id??null,selectedRepoId:a,selectedTaskId:c?.id??null,...xu(c,e.activeTab,e.selectedPtyTabId),selectedFilePath:bu(e,t,c?.id??null),...Du(e,t,c?.id??null),selectedDiffPath:Pu(e,t,c?.id??null),inspectorSection:kt(e.inspectorSection,ni,"task")}}function pe(e,t){return{...e,terminal:t}}function ii(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function ai(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function re(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
137
+ `}function li(e){return e.length===1&&e>=" "&&e!=="\x7F"}function ci(e){return ui(e)||Je(e)!==null}function di(e){return ti.includes(e)}function ui(e){return ei.includes(e)}function pi(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[I]:[]]}function Pu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function bu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function kt(e,t,r){return t.includes(e??"")?e:r}function Su(e){return e==="tabs"?"center":kt(e,Ru,"tasks")}function Iu(e,t){return e==="checks"||e==="actions"||e==="diff"||e==="review"?"review":kt(e,In,t)}function Cu(e){return e==="file"||e==="diff"?e:null}function vu(e){return e==="terminal"?"terminal":"agent"}function Eu(e){return e==="terminal"?"terminal":"control"}function Au(e,t=[...x],r="codex"){return e&&h.runners.isRunnerType(e)&&t.includes(e)?e:r}function Yt(e,t=x){let r=t.length>0?t:x,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function Je(e){let t=x.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function xu(e,t,r){if(!e)return{activeTab:t===I?t:"agent",selectedPtyTabId:null};let n=e.ptyTabs.find(a=>a.id===r)??null,s=e.selectedPtyTabId?e.ptyTabs.find(a=>a.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(a=>a.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(ui(t)){let l=e.ptyTabs.find(c=>c.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:l?.id??I,selectedPtyTabId:l?.id??null}}if(t===I)return{activeTab:I,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??I,selectedPtyTabId:i?.id??null}}function Du(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?$u(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function $u(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 Mu(e,t){let r=Le(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 Le(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 Cn(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 ue(e){return typeof e=="string"?e:null}function Lu(e){return e?`task:${e}`:null}function Rt(e){return typeof e=="string"&&e.startsWith("task:")}function Jt(e){return typeof e=="string"&&e.startsWith("new-task:")}function Xt(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function mi(e){return typeof e=="string"&&e.startsWith("workspace:")}function vn(e){return Jt(e)?e.slice(9):null}function En(e){return Xt(e)?e.slice(19):null}async function Pe(e,t,r){let n=ie(e),[s,o]=await Promise.all([H.repos.listRegisteredRepos(n),H.listWorkspaces(n,{archived:!1})]),i=await S.listTasks(n),a=An(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},c=a?await Vo(a,l):null;return{workspaceRoot:e,workspaces:o.workspaces,repos:s.repos,tasks:i.tasks,inspection:c,...r?{enabledRunnerIds:r}:{}}}function An(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function fi(e,t){return Tt(e,t)}import jn from"node:path";import oy from"picocolors";var ju=[" \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 xn(){return[...ju]}var Zt={width:120,height:36},ee={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function ne(e,t){return{width:Math.max(e??Zt.width,Zt.width),height:Math.max(t??Zt.height,Zt.height)}}var Ou=["Start","Options","Exit"],Fu=["Resume","Options","Exit"],rr=2,nr=2,sr=2,Nu=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Wu=new RegExp("\x1B\\[(?:0)?m","g"),_u=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),qu=/https?:\/\/[^\s<>"']+/g,Dn="\x1B[0m",$n="\x1B]8;;\x1B\\",P={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 wi(e,t={}){return Mn(e,{subtitle:"crAIg is that you?",menuItems:Ou,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function ki(e,t={}){return Mn(e,{subtitle:"Control mode is paused.",menuItems:Fu,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var er=[" 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."],Uu=["Help"],Bu=5;function ir(e,t={}){return Mn(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Uu,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Ti(e,t={}){let r=t.color??!0,n=P.overlay,s=new Array(e.height).fill(M(" ".repeat(e.width),r,n)),o=xn(),i=Math.max(1,Math.floor((e.height-o.length-2-er.length)/2));for(let d=0;d<o.length&&!(i+d>=e.height);d+=1)s[i+d]=M(Si(o[d]??"",e.width),r,P.overlayLogo);let a=Math.max(...er.map(d=>d.length)),l=Math.max(0,Math.floor((e.width-a)/2)),c=i+o.length+2;for(let d=0;d<er.length;d+=1){let p=c+d;if(p>=e.height)break;let m=er[d]??"";s[p]=M(le(" ".repeat(l)+m,e.width),r,n)}return s.join(`
138
+ `)}function Ri(e,t={}){let r=t.color??!0,n=P.overlay,s=new Array(e.height).fill(M(" ".repeat(e.width),r,n)),o="Error Log",i=t.errorLogPath??"",a=t.errorLogLines??[],l=Math.max(20,e.width-8),c=Math.max(0,Math.floor((e.width-l)/2)),d=[{text:o,tone:"selected"},{text:i,tone:"muted"},X(),...a.length>0?a.map(f=>({text:f})):[{text:"No Craig errors have been logged.",tone:"muted"}],X(),{text:"Esc returns to Options.",tone:"muted"}],p=yt(d,e.height-2),m=Math.max(1,Math.floor((e.height-p.length)/2));for(let f=0;f<p.length;f+=1){let k=m+f;if(k>=e.height)break;let u=p[f]??X(),D=`${" ".repeat(c)}${ar(u.text,l)}`,U=u.tone==="selected"?P.overlayMenuSelected:u.tone==="muted"?P.overlay:P.panelBg;s[k]=M(le(D,e.width),r,U)}return s.join(`
139
+ `)}function yi(e,t,r={}){let n=r.color??!0,s=ee.leftWidth,o=ee.rightWidth,i=ee.dividerWidth,a=r.centerOnly??!1,l=a?e.width:e.width-s-o-i*2,c=e.height-ee.topRailHeight-1,d=r.focusFlashActive??!1,p={bg:P.divider.bg,fg:"9ece6a"},m=d&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?p:P.divider,f=d&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?p:P.divider,k=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,u=M(le(k,e.width),n,P.rail),D=Vu(t,s-rr-nr,c,n),U=Gu(t,l,c,n),ge=zu(t,o,c,n),he=t.inputMode==="terminal",T=[];for(let ce=0;ce<c;ce+=1){if(a){T.push(tr(U[ce]??X(),l,n,"center"));continue}let Il=tr(D[ce]??X(),s,n,"left"),Cl=M("\u2502",n,m),vl=tr(U[ce]??X(),l,n,"center"),El=M("\u2502",n,f),Al=tr(ge[ce]??X(),o,n,"right");T.push(`${Il}${Cl}${vl}${El}${Al}`)}let Fe=he||t.modalInput?P.panelBg:P.panelMuted,v=Ku(t.footerText,t.footerToast,e.width,n,Fe);return[u,...T,v].join(`
140
+ `)}function Ku(e,t,r,n,s){let o=` ${e}`;if(!t)return M(le(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,a=Q(i),l=Q(o),c=Math.max(1,r-l-a-2),d=l+c+a+2>r?ar(o,Math.max(0,r-a-3)):o,p=Math.max(1,r-Q(d)-a-2),m=t.tone==="error"?mp(i,n,s):Xe(i,n,s),f=`${d}${" ".repeat(p)}${m} `;return M(le(f,r),n,s)}function Mn(e,t){let r=new Array(e.height).fill(M(" ".repeat(e.width),t.color,P.overlay)),n=xn(),s=t.menuItems.map((c,d)=>`${d===t.menuIndex?">":" "} ${c}`),o=t.optionsMessage?["",t.optionsMessage]:[],i=[...s,...o];for(;i.length<Bu;)i.push("");let a=[...n,"",t.subtitle,"",...i],l=Math.max(1,Math.floor((e.height-a.length)/2));for(let c=0;c<a.length;c+=1){let d=Si(a[c]??"",e.width);if(c<n.length){r[l+c]=M(d,t.color,P.overlayLogo);continue}if(c===n.length+1){r[l+c]=M(d,t.color,P.overlaySubtitle);continue}let p=c-(n.length+3),f=p>=0&&p<t.menuItems.length&&p===t.menuIndex?P.overlayMenuSelected:P.overlay;r[l+c]=M(d,t.color,f)}if(t.versionText){let c=t.updateText?" (update available)":"",d=`${t.versionText}${c} `,p=" ".repeat(Math.max(0,e.width-Q(d)));r[e.height-1]=M(`${p}${Ln(d,t.color,P.overlay)}`,t.color,P.overlay)}return r.join(`
141
+ `)}function Vu(e,t,r,n){let s=Ju(e.runners),o=1,i=e.leftTree.map(l=>Yu(l,t,n));return[...yt(i,r-o),s]}function Gu(e,t,r,n){let s=t-2,o=e.tabs.find(T=>T.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:dp(e.tabs),a=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,a)),c=`${" ".repeat(i)}${e.inputMode==="terminal"?Xe(l,n,P.panelBg):or(l,n,P.panelMuted)}`,d=[`${or(e.centerHeader.tabLabel,n,P.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),p=e.tabs.find(T=>T.active)?.id??"agent",m=e.centerHeader.tabLabel==="BROWSER"||!ci(p)?e.centerTranscript.map(T=>({...T})):Hu(e),f=Xu(e.tabs,n,e.focusedRegion==="center"),k=" engaged ",u=k.length+2,D=e.inputMode==="terminal"?Xe(`${k}\u25CF `,n,P.panelBg):"",U=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-Q(f)-u)):"",he=[{text:e.inputMode==="terminal"?`${f}${U}${D}`:f},{text:c,tone:"muted"},{text:d},X(),...m];return yt(he,r)}function Hu(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},X(),{text:e.terminal.error},X(),{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:vi(n.segments),segments:n.segments,fullBleed:!0}))}function zu(e,t,r,n){let s=e.rightInspection?Qu(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):yt([{text:"CONTEXT"},X(),...e.rightContext.map(o=>Zu(o,n)),...e.actionMessage?[X(),{text:e.actionMessage}]:[]],r);return yt(s,r)}function Qu(e,t){let r=e.slice(0,2),n=e.slice(2),s=Math.max(0,t-r.length),o=n.findIndex(a=>a.focused||a.selected),i=o===-1?0:pp(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(a=>gi(a)),...n.slice(i,i+s).map(a=>gi(a))]}function gi(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 Yu(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${Xe("\u25CF",r,e.selected?P.panelSelected:P.panelBg)}`:"",a=e.prBadge?e.prBadge.reduce((f,k)=>f+Q(k.text),0):0,l=t-Q(o)-Q(s)-a,c=e.selected?e.text:e.focused?Xe(e.text,r,P.panelBg):e.panelHeader?or(e.text,r,P.panelMuted):e.text,d=le(`${n}${c}`,Math.max(0,l)),p=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let f=[{text:`${d}${o}${i}`},...e.prBadge];return{text:`${d}${o}${e.prBadge.map(u=>u.text).join("")}`,segments:f,tone:p}}return{text:`${d}${o}${i}`,tone:p}}function Ju(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:P.success.fg}}):r.push({text:s.text,style:{fg:P.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function Xu(e,t,r){return e.map(n=>n.active?r?Xe(n.label,t,P.panelBg):or(n.label,t,P.panelBg):Ln(n.label,t,P.panelBg)).join(" ")}function Zu(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?Ln(e.value,t,P.panelBg):e.value}`}}function tr(e,t,r,n){let s=ep(n,e.tone??"default"),o=tp(e,r,s);if(n==="left"){if(e.fullBleed)return M(le(o,t),r,s);let a=t-rr-nr;if(e.rightAlign){let c=Q(o),d=Math.max(0,a-c),p=`${" ".repeat(rr)}${" ".repeat(d)}${o}${" ".repeat(nr)}`;return M(p,r,s)}let l=`${" ".repeat(rr)}${le(o,a)}${" ".repeat(nr)}`;return M(l,r,s)}return n==="center"&&e.fullBleed?rp(e,t,r,s):M(le(` ${o}`,t),r,s)}function ep(e,t){return t==="selected"||t==="focused"?P.panelSelected:t==="muted"?P.panelMuted:P.panelBg}function yt(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(X());return r}function X(){return{text:""}}function tp(e,t,r){return e.segments?e.segments.map(n=>Pi(n,t,r)).join(""):e.text}function rp(e,t,r,n){let s=" ".repeat(sr),o=Math.max(0,t-sr*2);if(!e.segments)return M(`${s}${le(e.text,o)}${s}`,r,n);let i=op(e.segments,o),a=`${s}${i.map(l=>Pi(l,r,n)).join("")}${s}${r?$n:""}`;return M(a,r,n)}function Pi(e,t,r){let n=e.href?`${bi(e.href)}${e.text}${$n}`:np(e.text);return!t||!e.style?n:`${Pt(lp(e.style,r))}${cp(e.style)}${n}${Dn}${Pt(r)}`}function np(e){return e.replace(qu,t=>{let[r,n]=sp(t);return`${bi(r)}${r}${$n}${n}`})}function sp(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function bi(e){return`\x1B]8;;${e}\x1B\\`}function op(e,t){let r=ip(e,t);return ap(r,t)}function ip(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=Q(s.text);if(o<=n){r.push(s),n-=o;continue}let i=ar(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function ap(e,t){let r=Q(vi(e));if(r>=t)return e;let n=[...e].reverse().find(s=>s.style?.bg)?.style;return n?.bg?[...e,{text:" ".repeat(t-r),style:n}]:[...e,{text:" ".repeat(t-r)}]}function lp(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 cp(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 dp(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+3}return 0}function Si(e,t){let r=Math.max(0,t-Q(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function le(e,t){let r=Q(e);return r>=t?up(e,t):e+" ".repeat(t-r)}function up(e,t){if(t<=0)return"";if(Q(e)<=t)return e;let r=Ci(e);return ar(r,Math.max(0,t-1))+"\u2026"}function Q(e){let t=0;for(let r of Array.from(Ci(e)))t+=Ii(r);return t}function ar(e,t){let r="",n=0;for(let s of Array.from(e)){let o=Ii(s);if(n+o>t)break;r+=s,n+=o}return r}function Ii(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 pp(e,t,r){return Math.min(Math.max(e,t),r)}function Ci(e){return e.replace(_u,"").replace(Nu,"")}function vi(e){return e.map(t=>t.text).join("")}function M(e,t,r){if(!t)return e;let n=Pt(r),s=e.replace(Wu,`${Dn}${n}`);return`${n}${s}${Dn}`}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 Xe(e,t,r){return lr(e,t,P.success.fg,r)}function mp(e,t,r){return lr(e,t,P.error.fg,r)}function or(e,t,r){return lr(e,t,P.accent.fg,r)}function Ln(e,t,r){return lr(e,t,P.mutedfg.fg,r)}function lr(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${Pt(s)}${e}${Pt(n)}`}function Ei(e,t,r){let n=e.tasks.find(a=>a.ptyTabs.some(l=>l.id===t))??null,s=n?.ptyTabs.find(a=>a.id===t)??null,o=n?.worktreePath??r,i=s?.kind==="agent"?gp(s):[];return n?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:fp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function fp(e,t){let r=(e??"").split(jn.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(jn.delimiter):[...r,t].join(jn.delimiter)}function gp(e){return e.command.length>0?e.command:["codex"]}function Ai(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 be(e){return{columns:Math.max(20,e.width-ee.leftWidth-ee.rightWidth-ee.dividerWidth-sr*2),rows:Math.max(5,e.height-ee.topRailHeight-5)}}function xi(e){return e.length===1||re(e)||e==="BACKSPACE"||e==="TAB"}function bt(e){return typeof e=="string"&&new RegExp(`:(?:agent|${x.join("|")})(?:-\\d+)?$`).test(e)}function Di(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 On(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function $i(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 St(e){return Li.includes(e)?"SHIFT_ENTER":null}function Fn(e){return Li.some(t=>t.startsWith(e))}function Mi(e){return e==="ESCAPE"?"\x1B":e.length===1?e:null}var Li=["\x1B[13;2u","\x1B[13;2~","\x1B[27;2;13~","\x1B[27;2;10~"];function ji(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
142
142
  `||r===`\r
143
- `)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function xi(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Di(e,t=null){let r=t?.split(`
143
+ `)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function Oi(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Fi(e,t=null){let r=t?.split(`
144
144
  `)??[];return e.split(`
145
- `).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}import{spawn as Ip}from"node:child_process";import{createHash as Cp}from"node:crypto";import{createServer as vp,createConnection as _i}from"node:net";import{openSync as Ep}from"node:fs";import{mkdir as Ap,readFile as _n,rm as je,writeFile as xp}from"node:fs/promises";import{tmpdir as Dp}from"node:os";import Xe from"node:path";import{createRequire as up}from"node:module";import rp from"@xterm/headless";var np=1e3,sp=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function Li(e){return new rp.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:np,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function ji(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Mn(e,t){return new Promise(r=>{e.write(t,r)})}function Mi(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 a=0;a<e.rows;a+=1){let l=r.getLine(i+a);if(!l){n.push({segments:[]});continue}let c=[];for(let d=0;d<e.cols;d+=1){let p=l.getCell(d,s);!p||p.getWidth()===0||c.push({text:p.getChars()||" ",style:ap(p,i+a===o&&d===r.cursorX)})}n.push({segments:op(ip(c))})}return n}function op(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&dp(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};Ni(r.style)||(s.style=r.style),t.push(s)}return t}function ip(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!Ni(r.style))break;t-=1}return e.slice(0,t)}function ap(e,t){let r={},n=$i(e,"fg"),s=$i(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 $i(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"):sp[s]??lp(s)}function lp(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 dp(e,t){return jn(e)===jn(t)}function jn(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Ni(e){return jn(e)===""}var pp=up(import.meta.url),mp=/^CTRL_([A-Z])$/,fp="\x1B[6n",gp="\x1B[c",hp="\x1B[?u",kp={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
146
- `,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:""},sr=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")Nn(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,Oi(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=wp(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&&Oi(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let r=this.sessions.get(t);r&&(Nn(r),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Nn(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:Tp(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??yp().spawn,i=Li(n),a=s??this.resolveSessionSpec(t,r),l=Ae({...this.env,...a.env??{}}),{executable:c,args:d}=Pp(this.shell,a.command,{cwd:a.cwd,env:l}),p=o(c,d,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:a.cwd,env:Sp(l)}),m={taskId:t,tabId:r,pty:p,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0,rows:[],renderedScrollbackLines:null,screenDirty:!0};return m.disposables.push(p.onData(f=>{bp(p,f),Mn(m.terminal,f).then(()=>{m.screenDirty=!0,this.onUpdate?.(m.tabId)})})),m.disposables.push(p.onExit(f=>{m.status="exited",Mn(m.terminal,`\r
147
- [process exited ${f.exitCode}]`).then(()=>{m.screenDirty=!0,this.onUpdate?.(m.tabId)})})),m}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function wp(e){if(e.length===1)return e;let t=kp[e];if(t!==void 0)return t;let r=mp.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function Oi(e,t){Rp(e.pty,t),ji(e.terminal,t),e.screenDirty=!0}function Tp(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=Mi(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function Nn(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function Rp(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function yp(){return pp("node-pty")}function Pp(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[xe(t[0],r),...t.slice(1)].map(Fi).join(" ")}; exec ${Fi(e)} -l`;return{executable:e,args:["-lc",s]}}function Fi(e){return`'${e.replaceAll("'","'\\''")}'`}function Sp(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 bp(e,t){for(let r=0;r<On(t,fp);r+=1)e.write("\x1B[1;1R");for(let r=0;r<On(t,gp);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<On(t,hp);r+=1)e.write("\x1B[?0u")}function On(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 qn=3;async function qi(e){let t=Bn(e.paths);await $p(t,e.paths,e.spawnDaemon);let r=await Hi(t.socketPath),n=new Fn(r,e);return await n.ready(),n}async function Bi(e,t={}){let r=Bn(e);await Ap(e.runtimeDir,{recursive:!0}),await je(r.socketPath,{force:!0});let n=new Wn(e,t),s=vp(o=>n.handleConnection(o));await Fp(s,r.socketPath),await xp(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 je(r.socketPath,{force:!0}),await je(r.pidPath,{force:!0}),n.disposeAll()}async function Ui(e){let t=Bn(e);return await ir(t.socketPath)?(await Vi(t.socketPath),!0):!1}var Fn=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!==qn)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,a)=>{this.pending.set(r,{resolve:i,reject:a})});if(this.socket.destroyed)throw this.pending.delete(r),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(n)}
145
+ `).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}import{spawn as Wp}from"node:child_process";import{createHash as _p}from"node:crypto";import{createServer as qp,createConnection as Gi}from"node:net";import{openSync as Up}from"node:fs";import{mkdir as Bp,readFile as Kn,rm as je,writeFile as Kp}from"node:fs/promises";import{tmpdir as Vp}from"node:os";import Ze from"node:path";import{createRequire as Ip}from"node:module";import hp from"@xterm/headless";var wp=1e3,kp=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function Wi(e){return new hp.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:wp,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function _i(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Wn(e,t){return new Promise(r=>{e.write(t,r)})}function qi(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 a=0;a<e.rows;a+=1){let l=r.getLine(i+a);if(!l){n.push({segments:[]});continue}let c=[];for(let d=0;d<e.cols;d+=1){let p=l.getCell(d,s);!p||p.getWidth()===0||c.push({text:p.getChars()||" ",style:yp(p,i+a===o&&d===r.cursorX)})}n.push({segments:Tp(Rp(c))})}return n}function Tp(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&Sp(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};Ui(r.style)||(s.style=r.style),t.push(s)}return t}function Rp(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!Ui(r.style))break;t-=1}return e.slice(0,t)}function yp(e,t){let r={},n=Ni(e,"fg"),s=Ni(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 Ni(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"):kp[s]??Pp(s)}function Pp(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(bp).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 bp(e){return e===0?0:55+e*40}function Sp(e,t){return Nn(e)===Nn(t)}function Nn(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Ui(e){return Nn(e)===""}var Cp=Ip(import.meta.url),vp=/^CTRL_([A-Z])$/,Ep="\x1B[6n",Ap="\x1B[c",xp="\x1B[?u",Dp={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
146
+ `,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:""},cr=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")_n(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,Bi(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=$p(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&&Bi(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let r=this.sessions.get(t);r&&(_n(r),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())_n(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:Mp(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??jp().spawn,i=Wi(n),a=s??this.resolveSessionSpec(t,r),l=xe({...this.env,...a.env??{}}),{executable:c,args:d}=Op(this.shell,a.command,{cwd:a.cwd,env:l}),p=o(c,d,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:a.cwd,env:Fp(l)}),m={taskId:t,tabId:r,pty:p,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0,rows:[],renderedScrollbackLines:null,screenDirty:!0};return m.disposables.push(p.onData(f=>{Np(p,f),Wn(m.terminal,f).then(()=>{m.screenDirty=!0,this.onUpdate?.(m.tabId)})})),m.disposables.push(p.onExit(f=>{m.status="exited",Wn(m.terminal,`\r
147
+ [process exited ${f.exitCode}]`).then(()=>{m.screenDirty=!0,this.onUpdate?.(m.tabId)})})),m}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function $p(e){if(e.length===1)return e;let t=Dp[e];if(t!==void 0)return t;let r=vp.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function Bi(e,t){Lp(e.pty,t),_i(e.terminal,t),e.screenDirty=!0}function Mp(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=qi(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function _n(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function Lp(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function jp(){return Cp("node-pty")}function Op(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[De(t[0],r),...t.slice(1)].map(Ki).join(" ")}; exec ${Ki(e)} -l`;return{executable:e,args:["-lc",s]}}function Ki(e){return`'${e.replaceAll("'","'\\''")}'`}function Fp(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 Np(e,t){for(let r=0;r<qn(t,Ep);r+=1)e.write("\x1B[1;1R");for(let r=0;r<qn(t,Ap);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<qn(t,xp);r+=1)e.write("\x1B[?0u")}function qn(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 Vn=4,Gp=50;async function Hi(e){let t=Gn(e.paths);await Qp(t,e.paths,e.spawnDaemon);let r=await Zi(t.socketPath),n=new Un(r,e);return await n.ready(),n}async function zi(e,t={}){let r=Gn(e);await Bp(e.runtimeDir,{recursive:!0}),await je(r.socketPath,{force:!0});let n=new Bn(e,t),s=qp(o=>n.handleConnection(o));await tm(s,r.socketPath),await Kp(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 je(r.socketPath,{force:!0}),await je(r.pidPath,{force:!0}),n.disposeAll()}async function Qi(e){let t=Gn(e);return await ur(t.socketPath)?(await Ji(t.socketPath),!0):!1}var Un=class{constructor(t,r){this.socket=t;this.options=r,this.viewUpdateMode=r.viewUpdateMode??"snapshot",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;viewedTabId=null;subscribedTabId=null;viewUpdateMode;buffer="";closed=!1;options;async ready(){if((await this.send({type:"ping"})).protocolVersion!==Vn)throw new Error("Craig PTY daemon protocol mismatch.");await this.send({type:"setViewUpdateMode",mode:this.viewUpdateMode})}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,this.viewedTabId=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(()=>{})}setViewedTab(t){this.closed||(this.viewedTabId=t,this.viewUpdateMode==="incremental"&&this.subscribeToView(t))}setViewUpdateMode(t){if(this.closed||this.viewUpdateMode===t)return;this.viewUpdateMode=t,this.subscribedTabId=null;let r=this.viewedTabId;this.send({type:"setViewUpdateMode",mode:t}).then(n=>{r&&n.view&&this.viewCache.set(r,n.view),this.viewUpdateMode===t&&this.viewedTabId===r&&this.options.onUpdate?.(r??""),t==="incremental"&&this.viewUpdateMode===t&&(this.viewedTabId===r&&this.subscribedTabId===null?this.subscribedTabId=r:this.viewedTabId!==r&&this.subscribeToView(this.viewedTabId))}).catch(()=>{this.viewUpdateMode===t&&(this.subscribedTabId=null)})}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,a)=>{this.pending.set(r,{resolve:i,reject:a})});if(this.socket.destroyed)throw this.pending.delete(r),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(n)}
148
148
  `);let o=await s;if(!o.ok)throw new Error(o.error);return o}handleData(t){this.buffer+=t;let r=this.buffer.indexOf(`
149
149
  `);for(;r!==-1;){let n=this.buffer.slice(0,r);this.buffer=this.buffer.slice(r+1),this.handleMessage(n),r=this.buffer.indexOf(`
150
- `)}}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()}},Wn=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,r){this.runtime=new sr({...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(`
151
- `);for(;s!==-1;){let o=r.slice(0,s);r=r.slice(s+1),this.handleLine(t,o),s=r.indexOf(`
152
- `)}}),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{or(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(n);or(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:qn}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);or(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 Wp(t)}}broadcastUpdate(t){let r=this.runtime.getViewState(t);for(let n of this.clients)or(n,{type:"update",tabId:t,view:r})}};function Bn(e){let t=Cp("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:Xe.join(Dp(),`craig-${t}.sock`),pidPath:Xe.join(e.runtimeDir,"pty-daemon.pid")}}async function $p(e,t,r){if(await Lp(e.socketPath,1e3))return;await ir(e.socketPath)&&(await Vi(e.socketPath),await Wi(e.socketPath,1e3)),await ir(e.socketPath)&&(await Np(e),await Wi(e.socketPath,1e3)),await Mp(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:a}=jp(n),l=Ep(Xe.join(t.runtimeDir,"pty-daemon.log"),"a");Ip(i,a,{cwd:n,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await Ki(e.socketPath))return;await Un(50)}let o=await _n(Xe.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
153
- ${o.slice(-2e3)}`:""}`)}async function Ki(e){let t=await Op(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===qn}async function Lp(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await Ki(e))return!0;await Un(50)}return!1}function jp(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=Xe.resolve(Xe.dirname(t),"..","node_modules",".bin","tsx");return{command:Vr("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 Mp(e){let t=await _n(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&zi(r))return}await je(e.socketPath,{force:!0}),await je(e.pidPath,{force:!0})}async function ir(e){let t=await Hi(e).catch(()=>null);return t?(t.end(),!0):!1}async function Vi(e){await Gi(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Np(e){let t=await _n(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!zi(r)){await je(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await je(e.socketPath,{force:!0})}}async function Op(e){return Gi(e,{id:1,type:"ping"})}function Gi(e,t){return new Promise((r,n)=>{let s=_i(e),o="",i=setTimeout(()=>{s.destroy(),n(new Error("Craig PTY daemon request timed out."))},500),a=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
150
+ `)}}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}if(r.type==="update"){if("view"in r){this.viewCache.set(r.tabId,r.view),this.options.onUpdate?.(r.tabId);return}let s=(this.viewCache.get(r.tabId)??{status:"idle",rows:[],error:null,scrolledBack:!1}).rows.slice(0,r.patch.rowCount);for(let o of r.patch.rows)s[o.index]=o.row;this.viewCache.set(r.tabId,{status:r.patch.status,rows:s,error:r.patch.error,scrolledBack:r.patch.scrolledBack}),this.viewUpdateMode==="incremental"&&this.viewedTabId===r.tabId&&this.options.onUpdate?.(r.tabId)}}subscribeToView(t){this.closed||this.viewUpdateMode!=="incremental"||this.subscribedTabId===t||(this.subscribedTabId=t,this.send({type:"subscribeView",tabId:t}).then(r=>{t&&r.view&&this.viewCache.set(t,r.view),this.viewUpdateMode==="incremental"&&this.viewedTabId===t&&this.subscribedTabId===t&&this.options.onUpdate?.(t??"")}).catch(()=>{this.subscribedTabId===t&&(this.subscribedTabId=null)}))}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}},Bn=class{onShutdown=null;clients=new Set;subscriptions=new Map;updateTimers=new Map;runtime;attachedTabId=null;constructor(t,r){this.runtime=new cr({...r,workspaceRoot:t.workspaceRoot,onUpdate:n=>this.handleRuntimeUpdate(n)})}handleConnection(t){let r="";this.clients.add(t),this.subscriptions.set(t,{mode:"snapshot",tabId:null,view:null,rowKeys:[]}),t.setEncoding("utf8"),t.on("data",s=>{r+=String(s);let o=r.indexOf(`
151
+ `);for(;o!==-1;){let i=r.slice(0,o);r=r.slice(o+1),this.handleLine(t,i),o=r.indexOf(`
152
+ `)}});let n=()=>{this.clients.delete(t),this.subscriptions.delete(t)};t.on("close",n),t.on("error",n)}disposeAll(){for(let t of this.updateTimers.values())clearTimeout(t);this.updateTimers.clear(),this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear(),this.subscriptions.clear()}async handleLine(t,r){if(r.trim().length===0)return;let n;try{n=JSON.parse(r)}catch{It(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(t,n);It(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:Vn}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);It(t,{id:n.id,ok:!1,error:o})}}handleRequest(t,r){switch(r.type){case"ping":return null;case"ensureSession":return this.attachedTabId=r.tabId,this.subscribe(t,r.tabId,this.runtime.ensureSession(r.taskId,r.tabId,r.size,r.spec));case"hydrateSession":return this.runtime.getViewState(r.tabId);case"write":return this.runtime.write(r.input),null;case"writeKey":return this.runtime.writeKey(r.key),null;case"scrollViewport":return this.runtime.scrollViewport(r.lines),this.runtime.getViewState(this.attachedTabId);case"resize":return this.runtime.resize(r.size),this.runtime.getViewState(this.attachedTabId);case"detach":return this.runtime.detach(),this.attachedTabId=null,null;case"disposeSession":return this.runtime.disposeSession(r.tabId),this.attachedTabId===r.tabId&&(this.attachedTabId=null),null;case"setViewUpdateMode":return this.setViewUpdateMode(t,r.mode);case"subscribeView":return this.subscribe(t,r.tabId,this.runtime.getViewState(r.tabId));case"pruneStale":{let n=new Set(r.keepTabIds);for(let s of this.runtime.sessionTabIds())n.has(s)||(this.runtime.disposeSession(s),this.attachedTabId===s&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(r.tabId);case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return rm(r)}}subscribe(t,r,n){let s=this.subscriptions.get(t)?.mode??"snapshot";return this.subscriptions.set(t,{mode:s,tabId:r,view:n,rowKeys:n.rows.map(dr)}),n}setViewUpdateMode(t,r){let s=this.subscriptions.get(t)?.tabId??null,o=this.runtime.getViewState(s);return this.subscriptions.set(t,{mode:r,tabId:s,view:o,rowKeys:o.rows.map(dr)}),o}handleRuntimeUpdate(t){let r=this.runtime.getViewState(t);for(let n of this.clients)this.subscriptions.get(n)?.mode==="snapshot"&&It(n,{type:"update",tabId:t,view:r});this.scheduleBroadcastUpdate(t)}scheduleBroadcastUpdate(t){this.updateTimers.has(t)||!this.hasViewSubscriber(t)||this.updateTimers.set(t,setTimeout(()=>{this.updateTimers.delete(t),this.broadcastUpdate(t)},Gp))}hasViewSubscriber(t){for(let r of this.subscriptions.values())if(r.mode==="incremental"&&r.tabId===t)return!0;return!1}broadcastUpdate(t){let r=this.runtime.getViewState(t);for(let n of this.clients){let s=this.subscriptions.get(n);if(!s||s.mode!=="incremental"||s.tabId!==t)continue;let o=Hp(s,r),i=zp(s.view,r);s.view=r,s.rowKeys=r.rows.map(dr),(o.rows.length>0||i)&&It(n,{type:"update",tabId:t,patch:o})}}};function Hp(e,t){let r=[];for(let n=0;n<t.rows.length;n+=1){let s=t.rows[n];e.rowKeys[n]!==dr(s)&&r.push({index:n,row:s})}return{status:t.status,error:t.error,scrolledBack:t.scrolledBack??!1,rowCount:t.rows.length,rows:r}}function zp(e,t){return!e||e.status!==t.status||e.error!==t.error||(e.scrolledBack??!1)!==(t.scrolledBack??!1)||e.rows.length!==t.rows.length}function dr(e){return JSON.stringify(e)}function Gn(e){let t=_p("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:Ze.join(Vp(),`craig-${t}.sock`),pidPath:Ze.join(e.runtimeDir,"pty-daemon.pid")}}async function Qp(e,t,r){if(await Yp(e.socketPath,1e3))return;await ur(e.socketPath)&&(await Ji(e.socketPath),await Vi(e.socketPath,1e3)),await ur(e.socketPath)&&(await Zp(e),await Vi(e.socketPath,1e3)),await Xp(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:a}=Jp(n),l=Up(Ze.join(t.runtimeDir,"pty-daemon.log"),"a");Wp(i,a,{cwd:n,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await Yi(e.socketPath))return;await Hn(50)}let o=await Kn(Ze.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
153
+ ${o.slice(-2e3)}`:""}`)}async function Yi(e){let t=await em(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===Vn}async function Yp(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await Yi(e))return!0;await Hn(50)}return!1}function Jp(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=Ze.resolve(Ze.dirname(t),"..","node_modules",".bin","tsx");return{command:Yr("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 Xp(e){let t=await Kn(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&ea(r))return}await je(e.socketPath,{force:!0}),await je(e.pidPath,{force:!0})}async function ur(e){let t=await Zi(e).catch(()=>null);return t?(t.end(),!0):!1}async function Ji(e){await Xi(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Zp(e){let t=await Kn(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!ea(r)){await je(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await je(e.socketPath,{force:!0})}}async function em(e){return Xi(e,{id:1,type:"ping"})}function Xi(e,t){return new Promise((r,n)=>{let s=Gi(e),o="",i=setTimeout(()=>{s.destroy(),n(new Error("Craig PTY daemon request timed out."))},500),a=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
154
154
  `)),s.once("error",l=>{a(),n(l)}),s.on("data",l=>{o+=String(l);let c=o.indexOf(`
155
- `);if(c===-1)return;let d=o.slice(0,c);a(),s.end();try{r(JSON.parse(d))}catch(p){n(p instanceof Error?p:new Error(String(p)))}}),s.once("close",()=>a())})}async function Wi(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await ir(e))return;await Un(50)}}function Hi(e){return new Promise((t,r)=>{let n=_i(e);n.once("connect",()=>t(n)),n.once("error",r)})}function Fp(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function or(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
156
- `)}catch{}}function zi(e){try{return process.kill(e,0),!0}catch{return!1}}function Un(e){return new Promise(t=>setTimeout(t,e))}function Wp(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var Kn=["Runners","Error Log","Help"];function Vn(e,t){return x.map(r=>{let n=k.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 Yi(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 Ji(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Kn.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Gn(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Xi(e,t,r,n){if(e.pathEdit)return _p({...e,pathEdit:e.pathEdit},t,r);let s=Vn(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 a=x[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:a,value:t.runners?.[a]?.path??""}}}}if(!Gn(r))return{kind:"noop",state:e};let o=x[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-enabled",runner:o,enabled:!i,state:{...e,message:`${k.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function _p(e,t,r){if(r==="ESCAPE")return{kind:"render",state:Qi({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Gn(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:Qi({...e,message:s.length>0?`${k.runners.getProfile(n).displayName} executable saved.`:`${k.runners.getProfile(n).displayName} executable reset to default.`})}}return qp(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function Qi(e){let t={...e};return delete t.pathEdit,t}function Gn(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
157
- `}function qp(e){return e.length===1&&e>=" "&&e!==""}import bt from"node:path";function Zi(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 ea="\u{F024B} ",ta="\u{F0DCF} ",ra="\u25CB",Hn="\uEA64",na="\uEAFE",sa="\uEBDA",zn="\u25CB",Qn="\u25CF",Yn="\u2713",Jn="\u2715";function oa(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 lr="empty",O={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function ca(e,t){let r=Kp(t,e),n=t.repos.find(u=>u.id===e.selectedRepoId)??t.repos[0]??null,s=r?t.tasks.filter(u=>u.workspaceId===r.id):t.tasks,o=r?.kind==="project"?s:n?s.filter(u=>u.repoId===n.id):[],i=o.find(u=>u.id===e.selectedTaskId)??o[0]??null,a=i?.type==="project",l=Im(t.tasks),c=Hp(e,i),d=Gp(e,i,c),p=d.find(u=>u.id===c)??d[0]??{id:"agent",label:"CODEX"},m=t.inspection?.taskId===i?.id?t.inspection:null,f=n?.name??"no repo",w=i?k.runners.getDisplayName(i.runner):k.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?e.workspaceBrowser.query!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} Search: ${e.workspaceBrowser.query} \u2191\u2193 move Enter select Esc clear search`:`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up / search Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${n?`[${n.name}]`:"[no repo]"} \xB7 ${k.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 [${k.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:Tt(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":c===I?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${k.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?a?"\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"?e.fileSearchQuery!==null?`Search: ${e.fileSearchQuery} \u2191\u2193 navigate Enter open Esc cancel search`:"\u2191\u2193 navigate / search Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:bt.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${bt.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:w},leftTree:Bp(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(u=>Cm(u,l[u])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":p.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:f,agent:w},centerTranscript:Vp(c,e,n,i,e.workspaceBrowser,m,r),tabs:d,rightContext:bm(n,i),rightInspection:im(e,i,m)}}function Bp(e,t){let r=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return Up(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 a=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],l=t.tasks.filter(c=>c.workspaceId===o.id);if(l.length===0)r.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let c of l){let d=e.selectedLeftItemId===`task:${c.id}`,p=d?"\u25B8":"\u2022",m=c.title.length>28?`${c.title.slice(0,25)}\u2026`:c.title,f={id:`task:${c.id}`,taskId:c.id,text:`${p} ${m}`,indent:2,selected:d,focused:d&&e.focusedRegion==="tasks"},w=ua(c);w&&(f.prBadge=w),r.push(f)}if(o.kind==="project"){let c=`new-task-workspace:${o.id}`,d=e.selectedLeftItemId===c;r.push({id:c,text:`+ New Project Task [${k.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:d,focused:d&&e.focusedRegion==="tasks",muted:!d})}if(o.kind==="repo"){let c=`new-task:${o.primaryRepoId}`,d=e.selectedLeftItemId===c;r.push({id:c,text:`+ New Task [${k.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:d,focused:d&&e.focusedRegion==="tasks",muted:!d})}else{r.push({text:` Repos (${a.length})`,indent:0,muted:!0});for(let c of a.slice(0,6)){let d=t.repos.find(p=>p.id===c);r.push({text:` \xB7 ${d?.name??c}`,indent:0,muted:!0})}a.length>6&&r.push({text:` \xB7 ${a.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 Up(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 a=n.filter(d=>d.repoId===o.id);if(a.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of a){let p=t.selectedLeftItemId===`task:${d.id}`,m=p?"\u25B8":"\u2022",f=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,w={id:`task:${d.id}`,taskId:d.id,text:`${m} ${f}`,indent:2,selected:p,focused:p&&t.focusedRegion==="tasks"},u=ua(d);u&&(w.prBadge=u),e.push(w)}let l=`new-task:${o.id}`,c=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${k.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:c,focused:c&&t.focusedRegion==="tasks",muted:!c})}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 Kp(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 Vp(e,t,r,n,s,o=null,i=null){if(s){let l=s.query?s.entries.filter(p=>p.name.toLowerCase().includes(s.query.toLowerCase())):s.entries,c=l.length===0?["No matching directories or git repos."]:l.map((p,m)=>{let f=m===s.selectedIndex?"\u25B8":" ",w=p.kind==="repo"?" [git repo]":"/";return`${f} ${p.name}${w}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return ne(["Browse for a workspace to register.",s.cwd,...d?[d]:[],"",...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 ne(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let l=i?.kind==="project",c=l?i.name??"this workspace":r.name,d=l?"Project Task":"Task";return ne([`No tasks in ${c}.`,"",`Press n or choose + New ${d} to create one with ${k.runners.getDisplayName(t.selectedRunner)}.`])}let a=n.ptyTabs.find(l=>l.id===e)??null;return a?a.kind==="agent"?ne([`${a.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."]):ne([`${a.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===I&&t.openInspectionKind==="file"?Yp(n,o,t.fileScrollOffset):e===I&&t.openInspectionKind==="diff"?Jp(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?ne(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ne(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Gp(e,t,r){let n=t?.ptyTabs.map(o=>({id:o.id,label:zp(o)}))??[];if(!t)return[{id:lr,label:"EMPTY",active:r===lr,focused:e.focusedRegion==="center"&&r===lr}];let s=e.openInspectionKind||r===I?[{id:I,label:Qp(e)}]:[];return[...n,...s].map(o=>({...o,active:o.id===r,focused:e.focusedRegion==="center"&&o.id===r}))}function Hp(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===I&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??I:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??I:lr}function zp(e){return e.title.toUpperCase()}function Qp(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?bt.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function Yp(e,t,r){if(!e)return ne(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ne(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=da(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:""},...Xp(n.lines,r,s)]}function Jp(e,t,r){if(!e)return ne(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ne(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=da(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:""},...Zp(n.lines,r,s)]}function ne(e){return e.map(t=>({text:t}))}function Xp(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 a=s+i+1;return{text:`${`${String(a).padStart(n," ")} \u2502 `}${o}`,segments:[{text:String(a).padStart(n," "),style:{fg:O.lineNumber}},{text:" \u2502 ",style:{fg:O.gutter}},...Xn(o,r)],tone:"default"}})}function Zp(e,t,r){let n=em(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>tm(o,r))}function em(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 tm(e,t){let r=ia(e.oldNumber),n=ia(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:O.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:O.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?nm(Xn(e.text,t),o.bg,o.fallbackFg):Xn(e.text,t),l=o?{fg:O.lineNumber,bg:o.bg}:{fg:O.lineNumber},c=o?{fg:O.gutter,bg:o.bg}:{fg:O.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:o!==null}}function ia(e){return e===null?" ":String(e).padStart(4," ")}function da(e){let t=bt.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 Xn(e,t){return t==="diff"?rm(e):t==="markdown"?sm(e):t==="json"?Zn(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Zn(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 rm(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:O.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:O.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:O.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:O.diffMeta}}]:[{text:e}]}function nm(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function sm(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:O.markup,bold:!0}}]:Zn(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Zn(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:om(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function om(e){return e.startsWith("//")||e.startsWith("/*")?{fg:O.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:O.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:O.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:O.markup}:{fg:O.keyword}}function im(e,t,r){let n=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&n?t.repoTargets?.find(a=>a.repoId===n)??null:null,o=t?.type==="project"?pa(t.repoTargets??[]):s?.pullRequest??(t?E(t):null),i=[am(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...ga(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,...Rm(e,r)]}:{title:"",rows:[...i,...ym(e,r)]}}function am(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 l=0;l<n.length;l++){let c=n[l];l>0&&s.push({text:" "});let d=c.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:c.label,style:{fg:d}})}let o=es(t),i=ts(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function aa(e){return[{text:" "},es(e),{text:" "},ts(e)]}function ua(e){if(e.type==="project"&&e.repoTargets?.length){let r=pa(e.repoTargets);return r?aa(r):null}let t=E(e);return t?.number?aa(t):null}function pa(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=cm(r);return{number:-1,status:lm(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 lm(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 cm(e){let t=e.map(r=>ma(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 es(e){return!e||!e.number?{text:ra,style:{fg:"565f89"}}:e.status==="merged"?{text:na,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:sa,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Hn,style:{fg:"565f89"}}:{text:Hn,style:{fg:"9ece6a"}}}function ts(e){return e?.aggregateReadiness?la(e.aggregateReadiness):la(ma(e))}function la(e){return e==="failed"?{text:Jn,style:{fg:"f7768e"}}:e==="pending"?{text:Qn,style:{fg:"e0af68"}}:e==="success"?{text:Yn,style:{fg:"9ece6a"}}:{text:zn,style:{fg:"565f89"}}}function ma(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")?fa(e)?"failed":dm(e)?"success":"pending":"pending"}function dm(e){return!!(e.mergeable&&!e.draft&&!fa(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function fa(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function ga(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return um(e,t);let r=E(t),n=ka("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}),pm(n,e)}var ar=32;function um(e,t){let r=[],n=t.repoTargets??[],s=e.selectedProjectTargetId??n[0]?.repoId??null;for(let i of n){let a=s===i.repoId,l=e.focusedRegion==="inspector"&&a,c=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let p=i.failureReason?i.failureReason.slice(0,14):i.status,m=ar-p.length-1,f=c.length>m?c.slice(0,m-1)+"\u2026":c,w=ar-f.length-p.length;r.push({id:`project-review:${i.repoId}`,text:f+" ".repeat(Math.max(1,w))+p,selected:a,focused:l,muted:!0})}else{let d=es(i.pullRequest),p=ts(i.pullRequest),m=`${d.text} ${p.text}`,f=ar-m.length-1,w=c.length>f?c.slice(0,f-1)+"\u2026":c,u=ar-w.length-m.length,D=w+" ".repeat(Math.max(1,u));r.push({id:`project-review:${i.repoId}`,text:D+m,selected:a,focused:l,segments:[{text:D},{...d,text:d.text},{text:" "},{...p,text:p.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(...ka("target",o.branch,o.pullRequest))),r}function ha(e,t){return ga(e,t).length}function ka(e,t,r){let n=p=>`${e}-${p}`;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??"?",a=r.headBranch??t;s.push({id:n("pr-branches"),text:`${i} \u2192 ${a}`,muted:!0});let l=mm(r.reviewDecision,r.mergeStateStatus),c=l&&l!=="review approved"?"merge blocked":r.mergeable?"merge ready":r.mergeStateStatus?`merge ${r.mergeStateStatus}`:"merge unknown";l?s.push({id:n("pr-merge"),text:`${c} \xB7 ${l}`,muted:!0,segments:[{text:c},{text:" \xB7 "},{text:l,style:{fg:fm(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${wa(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(gm)):s.push({id:n("checks-none"),text:r.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let d=r.comments??[];return d.length>0&&(s.push({id:n("comments-spacer"),text:""}),s.push({id:n("comments-header"),text:`Review comments (${d.length})`}),s.push(...d.slice(-4).flatMap((p,m)=>hm(p,n(`comment:${m}`))))),s}function pm(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 mm(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function fm(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function wa(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 gm(e){let{icon:t,color:r}=wm(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," ")} ${Tm(e.status)}`,color:r,muted:!1}}function hm(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${wa(e.createdAt)}`:"",s=km(e.body,30),o=s.slice(0,4),i=o.length<s.length,a=[{id:`${t}:author`,text:`${r}${n}`,muted:!0},...o.map((l,c)=>({id:`${t}:body:${c}`,text:` ${i&&c===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return a.push({id:`${t}:spacer`,text:"",muted:!0}),a}function km(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 wm(e){switch(e){case"success":return{icon:Yn,color:"9ece6a"};case"pending":return{icon:Qn,color:"e0af68"};case"failed":return{icon:Jn,color:"f7768e"};case"skipped":return{icon:zn,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function Tm(e){return e==="success"?"passing":e==="failed"?"failing":e}function Rm(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(l=>[l.path,l.status])),n=rs(t.fileRows,e.collapsedFileTreePaths),s=e.fileSearchQuery,o=s?n.filter(l=>l.path.toLowerCase().includes(s.toLowerCase())):n,i=s!==null?[{id:"file-search",text:`Search: ${s}\u2588`,muted:!1}]:[],a=e.selectedFileTreePath??t.selectedFilePath;return[...i,...o.map(l=>{let c=l.kind==="file"?r.get(l.path):void 0,d=c==="A"?"9ece6a":c==="M"?"e0af68":c==="D"?"f7768e":c==="??"?"565f89":void 0,p=l.kind==="directory"?e.collapsedFileTreePaths.includes(l.path)?ea:ta:Zi(l.label),m=l.kind==="directory"?"7aa2f7":oa(l.label),f=" ".repeat(l.depth),w=m?{text:p,style:{fg:m}}:{text:p},u=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},D=[{text:f},w,u];return{id:l.path,text:`${f}${p}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:D}})]}function rs(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 ym(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(Pm(t))return Sm(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=>Ta(o,e,t))))}return r}function Pm(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Sm(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(a=>a.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;r.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let a of["branch","staged","unstaged","untracked"]){let l=o.filter(c=>c.group===a);l.length!==0&&(r.push({id:`repo-diff:${s}:${a}`,text:` ${a}`,muted:!0}),r.push(...l.map(c=>Ta(c,e,t,s.length+1))))}}return r}function Ta(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",a=n>0?e.path.slice(n):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${a} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??r.selectedDiffPath),focused:e.path===(t.selectedDiffPath??r.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function bm(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:k.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:bt.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 Im(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Cm(e,t){return{name:k.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}import{appendFile as vm,mkdir as Em,readFile as Am}from"node:fs/promises";import xm from"node:path";var Ra=80,ns=async(e,t)=>{await Em(xm.dirname(e.errorLogFile),{recursive:!0}),await vm(e.errorLogFile,Dm(t),"utf8")},ya=async(e,t)=>{try{await ns(e,t)}catch{}},ss=async(e,t=Ra)=>{try{let n=(await Am(e.errorLogFile,"utf8")).trimEnd().split(`
158
- `).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($m(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},Pa=async(e,t=Ra)=>ss(e,t);function Dm(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(`
155
+ `);if(c===-1)return;let d=o.slice(0,c);a(),s.end();try{r(JSON.parse(d))}catch(p){n(p instanceof Error?p:new Error(String(p)))}}),s.once("close",()=>a())})}async function Vi(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await ur(e))return;await Hn(50)}}function Zi(e){return new Promise((t,r)=>{let n=Gi(e);n.once("connect",()=>t(n)),n.once("error",r)})}function tm(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function It(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
156
+ `)}catch{}}function ea(e){try{return process.kill(e,0),!0}catch{return!1}}function Hn(e){return new Promise(t=>setTimeout(t,e))}function rm(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var zn=["Runners","Feature Previews","Error Log","Help"],ra={incrementalCenterPane:"Incremental center pane"};function Qn(e,t){return x.map(r=>{let n=h.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 na(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 sa(e){return te.map(t=>`${h.previews.isEnabled(e,t)?"[x]":"[ ]"} ${ra[t]}`)}function oa(e){return e.message??"Experimental features may change or be removed. Enter toggles."}function ia(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(zn.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:pr(t)?e===0?{kind:"runners"}:e===1?{kind:"previews"}:e===2?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function aa(e,t,r){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(te.length-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(!pr(r))return{kind:"noop",state:e};let n=te[e.menuIndex]??te[0],s=!h.previews.isEnabled(t,n);return{kind:"save-enabled",feature:n,enabled:s,state:{...e,message:`${ra[n]} ${s?"enabled":"disabled"}.`}}}function la(e,t,r,n){if(e.pathEdit)return nm({...e,pathEdit:e.pathEdit},t,r);let s=Qn(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 a=x[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:a,value:t.runners?.[a]?.path??""}}}}if(!pr(r))return{kind:"noop",state:e};let o=x[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-enabled",runner:o,enabled:!i,state:{...e,message:`${h.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function nm(e,t,r){if(r==="ESCAPE")return{kind:"render",state:ta({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(pr(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:ta({...e,message:s.length>0?`${h.runners.getProfile(n).displayName} executable saved.`:`${h.runners.getProfile(n).displayName} executable reset to default.`})}}return sm(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function ta(e){let t={...e};return delete t.pathEdit,t}function pr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
157
+ `}function sm(e){return e.length===1&&e>=" "&&e!==""}import Ct from"node:path";function ca(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 da="\u{F024B} ",ua="\u{F0DCF} ",pa="\u25CB",Yn="\uEA64",ma="\uEAFE",fa="\uEBDA",Jn="\u25CB",Xn="\u25CF",Zn="\u2713",es="\u2715";function ga(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 fr="empty",F={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Ta(e,t){let r=am(t,e),n=t.repos.find(u=>u.id===e.selectedRepoId)??t.repos[0]??null,s=r?t.tasks.filter(u=>u.workspaceId===r.id):t.tasks,o=r?.kind==="project"?s:n?s.filter(u=>u.repoId===n.id):[],i=o.find(u=>u.id===e.selectedTaskId)??o[0]??null,a=i?.type==="project",l=qm(t.tasks),c=dm(e,i),d=cm(e,i,c),p=d.find(u=>u.id===c)??d[0]??{id:"agent",label:"CODEX"},m=t.inspection?.taskId===i?.id?t.inspection:null,f=n?.name??"no repo",k=i?h.runners.getDisplayName(i.runner):h.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?e.workspaceBrowser.query!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} Search: ${e.workspaceBrowser.query} \u2191\u2193 move Enter select Esc clear search`:`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up / search Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${n?`[${n.name}]`:"[no repo]"} \xB7 ${h.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 [${h.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:Rt(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":c===I?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${h.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?a?"\u2191\u2193 targets Enter open change Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 changes Enter open change Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?e.fileSearchQuery!==null?`Search: ${e.fileSearchQuery} \u2191\u2193 navigate Enter open Esc cancel search`:"\u2191\u2193 navigate / search Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:Ct.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Ct.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:k},leftTree:om(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(u=>Um(u,l[u])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":p.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:f,agent:k},centerTranscript:lm(c,e,n,i,e.workspaceBrowser,m,r),tabs:d,rightContext:_m(n,i),rightInspection:bm(e,i,m)}}function om(e,t){let r=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return im(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 a=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],l=t.tasks.filter(c=>c.workspaceId===o.id);if(l.length===0)r.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let c of l){let d=e.selectedLeftItemId===`task:${c.id}`,p=d?"\u25B8":"\u2022",m=c.title.length>28?`${c.title.slice(0,25)}\u2026`:c.title,f={id:`task:${c.id}`,taskId:c.id,text:`${p} ${m}`,indent:2,selected:d,focused:d&&e.focusedRegion==="tasks"},k=ya(c);k&&(f.prBadge=k),r.push(f)}if(o.kind==="project"){let c=`new-task-workspace:${o.id}`,d=e.selectedLeftItemId===c;r.push({id:c,text:`+ New Project Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:d,focused:d&&e.focusedRegion==="tasks",muted:!d})}if(o.kind==="repo"){let c=`new-task:${o.primaryRepoId}`,d=e.selectedLeftItemId===c;r.push({id:c,text:`+ New Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:d,focused:d&&e.focusedRegion==="tasks",muted:!d})}else{r.push({text:` Repos (${a.length})`,indent:0,muted:!0});for(let c of a.slice(0,6)){let d=t.repos.find(p=>p.id===c);r.push({text:` \xB7 ${d?.name??c}`,indent:0,muted:!0})}a.length>6&&r.push({text:` \xB7 ${a.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 im(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 a=n.filter(d=>d.repoId===o.id);if(a.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of a){let p=t.selectedLeftItemId===`task:${d.id}`,m=p?"\u25B8":"\u2022",f=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,k={id:`task:${d.id}`,taskId:d.id,text:`${m} ${f}`,indent:2,selected:p,focused:p&&t.focusedRegion==="tasks"},u=ya(d);u&&(k.prBadge=u),e.push(k)}let l=`new-task:${o.id}`,c=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${h.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:c,focused:c&&t.focusedRegion==="tasks",muted:!c})}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 am(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 lm(e,t,r,n,s,o=null,i=null){if(s){let l=s.query?s.entries.filter(p=>p.name.toLowerCase().includes(s.query.toLowerCase())):s.entries,c=l.length===0?["No matching directories or git repos."]:l.map((p,m)=>{let f=m===s.selectedIndex?"\u25B8":" ",k=p.kind==="repo"?" [git repo]":"/";return`${f} ${p.name}${k}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return se(["Browse for a workspace to register.",s.cwd,...d?[d]:[],"",...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 se(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let l=i?.kind==="project",c=l?i.name??"this workspace":r.name,d=l?"Project Task":"Task";return se([`No tasks in ${c}.`,"",`Press n or choose + New ${d} to create one with ${h.runners.getDisplayName(t.selectedRunner)}.`])}let a=n.ptyTabs.find(l=>l.id===e)??null;return a?a.kind==="agent"?se([`${a.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."]):se([`${a.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===I&&t.openInspectionKind==="file"?mm(n,o,t.fileScrollOffset):e===I&&t.openInspectionKind==="diff"?fm(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?se(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):se(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function cm(e,t,r){let n=t?.ptyTabs.map(o=>({id:o.id,label:um(o)}))??[];if(!t)return[{id:fr,label:"EMPTY",active:r===fr,focused:e.focusedRegion==="center"&&r===fr}];let s=e.openInspectionKind||r===I?[{id:I,label:pm(e)}]:[];return[...n,...s].map(o=>({...o,active:o.id===r,focused:e.focusedRegion==="center"&&o.id===r}))}function dm(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===I&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??I:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??I:fr}function um(e){return e.title.toUpperCase()}function pm(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?Ct.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function mm(e,t,r){if(!e)return se(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return se(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=Ra(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:""},...gm(n.lines,r,s)]}function fm(e,t,r){if(!e)return se(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return se(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=Ra(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:""},...hm(n.lines,r,s)]}function se(e){return e.map(t=>({text:t}))}function gm(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 a=s+i+1;return{text:`${`${String(a).padStart(n," ")} \u2502 `}${o}`,segments:[{text:String(a).padStart(n," "),style:{fg:F.lineNumber}},{text:" \u2502 ",style:{fg:F.gutter}},...ts(o,r)],tone:"default"}})}function hm(e,t,r){let n=wm(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>km(o,r))}function wm(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 km(e,t){let r=ha(e.oldNumber),n=ha(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:F.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:F.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?Rm(ts(e.text,t),o.bg,o.fallbackFg):ts(e.text,t),l=o?{fg:F.lineNumber,bg:o.bg}:{fg:F.lineNumber},c=o?{fg:F.gutter,bg:o.bg}:{fg:F.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:o!==null}}function ha(e){return e===null?" ":String(e).padStart(4," ")}function Ra(e){let t=Ct.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 ts(e,t){return t==="diff"?Tm(e):t==="markdown"?ym(e):t==="json"?rs(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?rs(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 Tm(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:F.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:F.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:F.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:F.diffMeta}}]:[{text:e}]}function Rm(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function ym(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:F.markup,bold:!0}}]:rs(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function rs(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:Pm(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function Pm(e){return e.startsWith("//")||e.startsWith("/*")?{fg:F.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:F.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:F.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:F.markup}:{fg:F.keyword}}function bm(e,t,r){let n=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&n?t.repoTargets?.find(a=>a.repoId===n)??null:null,o=t?.type==="project"?Pa(t.repoTargets??[]):s?.pullRequest??(t?A(t):null),i=[Sm(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=Ia(e,t),l=ns(e,r),c=Am([{id:"review-pr-header",text:"PULL REQUEST",muted:!0},...a,{id:"review-changes-spacer",text:"",muted:!0},{id:"review-changes-header",text:"CHANGES",muted:!0},...l],e);return{title:"",rows:[...i,...c]}}return e.inspectionMode==="files"?{title:"",rows:[...i,...Fm(e,r)]}:{title:"",rows:[...i,...ns(e,r)]}}function Sm(e,t){let r=e.inspectionMode,n=[{label:"FILES",active:r==="files"},{label:"REVIEW",active:r==="review"}],s=[];for(let l=0;l<n.length;l++){let c=n[l];l>0&&s.push({text:" "});let d=c.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:c.label,style:{fg:d}})}let o=ss(t),i=os(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function wa(e){return[{text:" "},ss(e),{text:" "},os(e)]}function ya(e){if(e.type==="project"&&e.repoTargets?.length){let r=Pa(e.repoTargets);return r?wa(r):null}let t=A(e);return t?.number?wa(t):null}function Pa(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=Cm(r);return{number:-1,status:Im(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 Im(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 Cm(e){let t=e.map(r=>ba(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 ss(e){return!e||!e.number?{text:pa,style:{fg:"565f89"}}:e.status==="merged"?{text:ma,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:fa,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Yn,style:{fg:"565f89"}}:{text:Yn,style:{fg:"9ece6a"}}}function os(e){return e?.aggregateReadiness?ka(e.aggregateReadiness):ka(ba(e))}function ka(e){return e==="failed"?{text:es,style:{fg:"f7768e"}}:e==="pending"?{text:Xn,style:{fg:"e0af68"}}:e==="success"?{text:Zn,style:{fg:"9ece6a"}}:{text:Jn,style:{fg:"565f89"}}}function ba(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")?Sa(e)?"failed":vm(e)?"success":"pending":"pending"}function vm(e){return!!(e.mergeable&&!e.draft&&!Sa(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Sa(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Ia(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return Em(e,t);let r=A(t),n=va("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}),n}var mr=32;function Em(e,t){let r=[],n=t.repoTargets??[],s=e.selectedProjectTargetId??n[0]?.repoId??null;for(let i of n){let a=s===i.repoId,l=e.focusedRegion==="inspector"&&a,c=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let p=i.failureReason?i.failureReason.slice(0,14):i.status,m=mr-p.length-1,f=c.length>m?c.slice(0,m-1)+"\u2026":c,k=mr-f.length-p.length;r.push({id:`project-review:${i.repoId}`,text:f+" ".repeat(Math.max(1,k))+p,selected:a,focused:l,muted:!0})}else{let d=ss(i.pullRequest),p=os(i.pullRequest),m=`${d.text} ${p.text}`,f=mr-m.length-1,k=c.length>f?c.slice(0,f-1)+"\u2026":c,u=mr-k.length-m.length,D=k+" ".repeat(Math.max(1,u));r.push({id:`project-review:${i.repoId}`,text:D+m,selected:a,focused:l,segments:[{text:D},{...d,text:d.text},{text:" "},{...p,text:p.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(...va("target",o.branch,o.pullRequest))),r}function Ca(e,t,r=null){return 3+Ia(e,t).length+ns(e,r).length}function va(e,t,r){let n=p=>`${e}-${p}`;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??"?",a=r.headBranch??t;s.push({id:n("pr-branches"),text:`${i} \u2192 ${a}`,muted:!0});let l=xm(r.reviewDecision,r.mergeStateStatus),c=l&&l!=="review approved"?"merge blocked":r.mergeable?"merge ready":r.mergeStateStatus?`merge ${r.mergeStateStatus}`:"merge unknown";l?s.push({id:n("pr-merge"),text:`${c} \xB7 ${l}`,muted:!0,segments:[{text:c},{text:" \xB7 "},{text:l,style:{fg:Dm(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${Ea(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($m)):s.push({id:n("checks-none"),text:r.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let d=r.comments??[];return d.length>0&&(s.push({id:n("comments-spacer"),text:""}),s.push({id:n("comments-header"),text:`Review comments (${d.length})`}),s.push(...d.slice(-4).flatMap((p,m)=>Mm(p,n(`comment:${m}`))))),s}function Am(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 xm(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Dm(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function Ea(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 $m(e){let{icon:t,color:r}=jm(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," ")} ${Om(e.status)}`,color:r,muted:!1}}function Mm(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${Ea(e.createdAt)}`:"",s=Lm(e.body,30),o=s.slice(0,4),i=o.length<s.length,a=[{id:`${t}:author`,text:`${r}${n}`,muted:!0},...o.map((l,c)=>({id:`${t}:body:${c}`,text:` ${i&&c===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return a.push({id:`${t}:spacer`,text:"",muted:!0}),a}function Lm(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 jm(e){switch(e){case"success":return{icon:Zn,color:"9ece6a"};case"pending":return{icon:Xn,color:"e0af68"};case"failed":return{icon:es,color:"f7768e"};case"skipped":return{icon:Jn,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function Om(e){return e==="success"?"passing":e==="failed"?"failing":e}function Fm(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(l=>[l.path,l.status])),n=is(t.fileRows,e.collapsedFileTreePaths),s=e.fileSearchQuery,o=s?n.filter(l=>l.path.toLowerCase().includes(s.toLowerCase())):n,i=s!==null?[{id:"file-search",text:`Search: ${s}\u2588`,muted:!1}]:[],a=e.selectedFileTreePath??t.selectedFilePath;return[...i,...o.map(l=>{let c=l.kind==="file"?r.get(l.path):void 0,d=c==="A"?"9ece6a":c==="M"?"e0af68":c==="D"?"f7768e":c==="??"?"565f89":void 0,p=l.kind==="directory"?e.collapsedFileTreePaths.includes(l.path)?da:ua:ca(l.label),m=l.kind==="directory"?"7aa2f7":ga(l.label),f=" ".repeat(l.depth),k=m?{text:p,style:{fg:m}}:{text:p},u=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},D=[{text:f},k,u];return{id:l.path,text:`${f}${p}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:D}})]}function is(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 ns(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(Nm(t))return Wm(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=>Aa(o,e,t))))}return r}function Nm(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Wm(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(a=>a.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;r.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let a of["branch","staged","unstaged","untracked"]){let l=o.filter(c=>c.group===a);l.length!==0&&(r.push({id:`repo-diff:${s}:${a}`,text:` ${a}`,muted:!0}),r.push(...l.map(c=>Aa(c,e,t,s.length+1))))}}return r}function Aa(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",a=n>0?e.path.slice(n):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${a} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??r.selectedDiffPath),focused:e.path===(t.selectedDiffPath??r.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function _m(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:h.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Ct.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 qm(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Um(e,t){return{name:h.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}import{appendFile as Bm,mkdir as Km,readFile as Vm}from"node:fs/promises";import Gm from"node:path";var xa=80,as=async(e,t)=>{await Km(Gm.dirname(e.errorLogFile),{recursive:!0}),await Bm(e.errorLogFile,Hm(t),"utf8")},Da=async(e,t)=>{try{await as(e,t)}catch{}},ls=async(e,t=xa)=>{try{let n=(await Vm(e.errorLogFile,"utf8")).trimEnd().split(`
158
+ `).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(zm(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},$a=async(e,t=xa)=>ls(e,t);function Hm(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(`
159
159
  `).map(n=>` ${n}`))),`${r.join(`
160
160
  `)}
161
161
 
162
- `}function $m(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Ze={appendErrorLog:ns,appendErrorLogBestEffort:ya,readErrorLog:ss,readRecentErrorLines:Pa};var Lm=["tasks","center","inspector"];function jm(e,t,r){if(t==="ESCAPE")return h({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return h({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return is(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return as({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return h({state:{...e,fileSearchQuery:n},changed:!0})}return h({state:e})}function as(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return ti(t)?h({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):h({state:e});if(e.fileSearchQuery!==null)return jm(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return h({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return h({state:e,exit:!0});if(t==="ESCAPE")return h({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return h({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(Ht(e.selectedLeftItemId)||zt(e.selectedLeftItemId)))return h({state:{...e,selectedRunner:Gt(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return Sa(e,1);if(t==="SHIFT_TAB"||t==="[")return Sa(e,-1);if(t==="z"||t==="Z")return h({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===I?Se(e,-1,r):is(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===I?Se(e,1,r):is(e,1,r);if(t==="PAGE_UP")return Se(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Se(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Se(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Se(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??x,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return h({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=Bm(e,t);return h({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 h({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return h({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return h({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Tt(e.selectedLeftItemId)&&e.selectedTaskId)return h({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&ai(e.selectedLeftItemId)&&e.selectedWorkspaceId)return h({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Ca(e.activeTab,r.ptyTabIds??[]))return h({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return os(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return ba(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return os(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return ba(e,1)}if(te(t)){if(e.focusedRegion==="tasks"&&(Ht(e.selectedLeftItemId)||zt(e.selectedLeftItemId))){let n=Pn(e.selectedLeftItemId),s=Sn(e.selectedLeftItemId);return h({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 h({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&Tt(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return h({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Ye(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Ca(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return h({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Ye(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===I)return h({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 h({state:Om({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return h({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:I,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?h({state:{...e,activeTab:I,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?h({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):h({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?h({state:e}):e.selectedActionId==="refresh-checks"?h({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?h({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):h({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return h({state:e})}function Se(e,t,r){if(t===0)return h({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return va(e,t,r);if(e.inspectionMode==="diff"){let n=dr(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,diffScrollOffset:0}}:n}return e.inspectionMode==="review"?Ia(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):h({state:e})}if(e.focusedRegion==="center"&&e.activeTab===I){if(e.openInspectionKind==="file")return Ia(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return Fm(e,t,r)}return h({state:e})}function Sa(e,t){return cr(e,"focusedRegion",Lm,t)}function os(e,t,r){let n=cr(e,"activeTab",r&&r.length>0?r:Um(e),t);return!n.changed||si(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Ye(n.state.activeTab)??n.state.preferredPtyTabKind}}}function is(e,t,r){if(e.focusedRegion==="tasks")return Mm(e,t,r.leftItemIds);if(e.focusedRegion==="center")return os(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return va(e,t,r);if(e.inspectionMode==="diff"){let n=dr(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:I,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:n}if(r.projectTargetIds?.length){let n=dr(e,"selectedProjectTargetId",r.projectTargetIds,t);return n.changed?{...n,state:{...n.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:n}return cr(e,"selectedActionId",Yo,t)}return cr(e,"selectedActionId",Tn,t)}function Mm(e,t,r){let n=dr(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=yn(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=Pn(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=Sn(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function Nm(e,t){if(e.inspectionMode===t)return h({state:e});let r=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,n=t==="diff"||t==="files"?I:e.activeTab;return h({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 ba(e,t){return Nm(e,qm(e.inspectionMode,Rn,t))}function va(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return h({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=pe(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return h({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return h({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?I:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function Om(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 Ia(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=pe(e[t]+r,0,o);return i===e[t]?h({state:e}):h({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Fm(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return Wm(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,a=r.diffPathIds??[];if(a.length===0||!e.selectedDiffPath){let d=pe(i,0,o);return d===e.diffScrollOffset?h({state:e}):h({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let d=pe(i,0,o);return d===e.diffScrollOffset?h({state:e}):h({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}if(t>0&&i>o){let d=a[l+1]??null;return d?h({state:{...e,selectedDiffPath:d,activeTab:I,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?h({state:e}):h({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let d=a[l-1]??null;return d?h({state:{...e,selectedDiffPath:d,activeTab:I,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?h({state:e}):h({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let c=pe(i,0,o);return c===e.diffScrollOffset?h({state:e}):h({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function Wm(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=pe(e.diffScrollOffset+t,0,o),a=_m(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?h({state:e}):h({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function _m(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function cr(e,t,r,n){let s=r.indexOf(e[t]),o=pe(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?h({state:e}):h({state:{...e,[t]:i,actionMessage:null},changed:!0})}function dr(e,t,r,n,s=!1){if(r.length===0)return h({state:e});let o=r.indexOf(e[t]??r[0]??""),i=pe(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?h({state:e}):h({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function qm(e,t,r){let n=t.indexOf(e);return t[pe(n+r,0,t.length-1)]??e}function h(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 Ca(e,t){return t.includes(e)}function Bm(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Ye(e.activeTab)??e.preferredPtyTabKind}function Um(e){return[e.selectedPtyTabId,e.openInspectionKind?I:null].filter(t=>typeof t=="string")}function pe(e,t,r){return Math.min(r,Math.max(t,e))}var Ea=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>{let o=await J(n.paths,e.selectedTaskId),i=t??Km(o,e.activeTab,e.preferredPtyTabKind),a=$a(o,i,r??void 0,n.config),l={...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id};return await y(n.paths,l),l});return{updatedTask:s,nextShell:{activeTab:s.selectedPtyTabId??e.activeTab,selectedPtyTabId:s.selectedPtyTabId,preferredPtyTabKind:s.ptyTabs.at(-1)?.kind??e.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${s.ptyTabs.at(-1)?.title??"tab"}`}}},Aa=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:r,nextSelectedTab:n}=await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.selectedTaskId),o=s.ptyTabs.findIndex(c=>c.id===e.activeTab);if(o===-1)throw new Error("Only PTY tabs can be closed.");let i=s.ptyTabs[o],a=s.ptyTabs.filter(c=>c.id!==i.id),l=a[Math.min(o,a.length-1)]??null;return await y(t.paths,{...s,ptyTabs:a,selectedPtyTabId:l?.id??null}),{closedTab:i,nextSelectedTab:l}});return{closedTab:r,nextSelectedTab:n,nextShell:{activeTab:n?.id??(e.openInspectionKind?"inspection":e.activeTab),selectedPtyTabId:n?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${r.title}`}}},xa=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{let n=await J(t.paths,r);!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab||await y(t.paths,{...n,selectedPtyTabId:e.activeTab})})},Da=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;o&&await y(t.paths,{...s,selectedPtyTabId:o.id})}),{...e,selectedPtyTabId:r.id};let n=$a(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;if(o){await y(t.paths,{...s,selectedPtyTabId:o.id});return}await y(t.paths,{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function Km(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function $a(e,t,r,n={}){let s=r??e.runner,o=k.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",a=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(f=>f.id)),c=1,d=a;for(;l.has(d);)c+=1,d=`${a}-${c}`;let p=new Date().toISOString(),m=r&&r!==e.runner?r:void 0;return{id:d,kind:t,...m?{runner:m}:{},title:c===1?i:`${i} ${c}`,command:t==="agent"?k.runners.buildCommand(s,void 0,n):[],createdAt:p,updatedAt:p}}var et=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},La=async(e,t,r,n,s)=>{k.runners.assertEnabled(n,s.config);let o=t?await s.taskService.provisionProjectTask(s.paths,t,r,{runner:n,config:s.config}):await s.taskService.provisionTask(s.paths,e??"",r,{runner:n,config:s.config});try{let l=Ae();await R(xe(k.runners.getConfiguredProfile(n,s.config).executable,{cwd:o.repoRoot,env:l}),["--help"],{cwd:o.repoRoot,env:l})}catch(l){let c=l instanceof Error?l.message:"Failed to start runner.",d=await s.taskService.recordStartupFailure(s.paths,o.task.id,c);throw new et(c,d)}let i=await s.taskService.markTaskStarted(s.paths,o.task.id),a={selectedRepoId:i.repoId,selectedWorkspaceId:i.workspaceId,selectedTaskId:i.id,selectedPtyTabId:i.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:i.selectedPtyTabId??"agent",selectedActionId:"commit"};return{task:i,nextShell:a}},ja=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},Ma=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:r,task:n}=await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.selectedTaskId),o=await t.taskService.closeTask(t.paths,e.selectedTaskId);return{taskBeforeClose:s,task:o}});return{closedTabIds:r.ptyTabs.map(s=>s.id),nextShell:{selectedActionId:"close-task",actionMessage:n.cleanup.preservedWorktree?`Archived task ${n.id}; worktree preserved`:`Archived task ${n.id}`}}},Na=async(e,t)=>{await t.taskService.prs.discoverOrRefreshMany(t.paths,e)},Oa=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await Ze.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var Fa=async(e,t)=>{if(!e.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await t.taskService.listTasks(t.paths,{workspaceId:e.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${e.selectedWorkspaceId} while task records still reference it.`);return await t.workspaceService.archiveWorkspace(t.paths,e.selectedWorkspaceId),{nextShell:{selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${(await t.workspaceService.removeWorkspace(t.paths,e.selectedWorkspaceId,{listTasks:t.taskService.listTasks})).workspaceId}`}}};var Wa=async(e,t,r)=>{let n=k.runners.setRunnerEnabled(r.config,e,t);return await k.save(r.paths,n),n},_a=async(e,t,r)=>{let n=k.runners.setRunnerPath(r.config,e,t);return await k.save(r.paths,n),n};var Vm=250;function me(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function Me(e,t){return ue(t,e.ptyRuntime.getViewState(ls(e,t)))}function ls(e,t){let r=me(e.model.tasks,t);return r?r.ptyTabs.some(n=>n.id===t.activeTab)?t.activeTab:t.activeTab==="agent"||t.activeTab==="terminal"?r.ptyTabs.find(n=>n.kind===t.activeTab)?.id??t.selectedPtyTabId:t.selectedPtyTabId:t.selectedPtyTabId}function g(e,t){return Me(e,li(t,e.model))}function qa(e,t,r){return e.footerToastTimer&&(clearTimeout(e.footerToastTimer),e.footerToastTimer=null),r?(e.footerToastTimer=setTimeout(()=>{e.footerToastTimer=null,!(e.state.mode!=="main"||e.state.shell.footerToast!==r)&&(e.state={mode:"main",shell:g(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function Ba(e,t,r){return qa(e,t,r?{tone:"success",message:r}:null)}function j(e,t,r){return qa(e,t,{tone:"error",message:r})}function M(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return Ze.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function $(e,t){if(!e.uiStateFile)return;e.runtimeState=Zo(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>he({uiStateFile:e.uiStateFile},r),()=>he({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function Gm(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function _(e){return{paths:e.paths,config:e.config,taskService:b,workspaceService:H,queueTaskMutation:t=>Gm(e,t)}}function cs(e,t){let r=me(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?rs(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:Le(e.model),centerTabIds:ii(r,t),ptyTabIds:r?.ptyTabs.map(a=>a.id)??[],filePathIds:s?.filePaths??[],fileTreeRowIds:i.map(a=>a.path),fileTreeFileIds:i.filter(a=>a.kind==="file").map(a=>a.path),fileTreeDirectoryIds:i.filter(a=>a.kind==="directory").map(a=>a.path),diffPathIds:s?.diffPaths??[],diffPathRanges:[],fileLineCount:s?.selectedFile.lines.length??0,diffLineCount:s?.selectedDiff.lines.length??0,reviewRowCount:ha(t,r),pageRows:Math.max(5,re(e.activeTerminal.width,e.activeTerminal.height).height-ee.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function Ua(e,t){await xa(t,_(e))}async function q(e){e.model=await ye(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:g(e,e.state.shell)}:e.state={...e.state,shell:g(e,e.state.shell)}}async function ur(e,t){let r=++e.inspectionRefreshSequence,n=bn(e.model.tasks,t),s=e.model.inspection,o;if(n&&s?.taskId===n.id){let i={selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath},a=await Fo(n,s,i);if(r!==e.inspectionRefreshSequence)return;o={...e.model,inspection:a}}else if(o=await ye(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=o,e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},$(e,e.state.shell),e.render())}function Ka(e,t){e.pendingLeftNavInspectionShell=t,!e.leftNavInspectionTimer&&(e.leftNavInspectionTimer=setTimeout(()=>{e.leftNavInspectionTimer=null;let r=e.pendingLeftNavInspectionShell;e.pendingLeftNavInspectionShell=null,!(!r||e.state.mode!=="main"||e.state.shell!==r)&&ur(e,r).catch(n=>{let s=M(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},Vm))}function Va(e,t){t!==0&&(e.pendingInspectionScrollLines+=t,!e.inspectionScrollRenderTimer&&(e.inspectionScrollRenderTimer=setTimeout(()=>{e.inspectionScrollRenderTimer=null;let r=e.pendingInspectionScrollLines;if(e.pendingInspectionScrollLines=0,r===0||e.state.mode!=="main"||e.state.shell.inputMode!=="control")return;let n=Se(e.state.shell,r,cs(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render(),ur(e,e.state.shell).catch(s=>{let o=M(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render()}},16)))}function ds(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function us(e){let t=e.model.tasks.flatMap(r=>r.ptyTabs.map(n=>n.id));await e.ptyRuntime.pruneStale?.(t),await e.ptyRuntime.hydrateSessions?.(t)}function Ha(e){us(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.render())})}async function za(e,t){let r=g(e,t),n=me(e.model.tasks,r),s=ls(e,r);if(!n||!s||!n.ptyTabs.some(a=>a.id===s))return r;let o=e.ptyRuntime.getViewState(s);if(o.status!=="idle"||o.rows.length>0||o.error)return ue(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,Pe(re(e.activeTerminal.width,e.activeTerminal.height)));return ue({...r,inputMode:"control"},i)}function Qa(e){let t=e.state.mode==="main"&&e.state.shell.inputMode==="terminal"?"terminal":"control";t!==e.inputCaptureMode&&(e.inputCaptureMode=t,e.activeTerminal.grabInput(t==="terminal"?{mouse:"button"}:!0))}async function ps(e,t){try{let r=g(e,t),n=me(e.model.tasks,r),s=r.selectedPtyTabId;if(n&&r.focusedRegion==="tasks"){let a=n.ptyTabs.find(l=>l.kind==="agent")??null;a?s=a.id:(n=await Ga(e,n),await q(e),s=n.selectedPtyTabId)}n&&!s&&(n=await Ga(e,n),await q(e),s=n.selectedPtyTabId);let o=g(e,{...r,activeTab:s??r.activeTab,selectedPtyTabId:s,focusedRegion:s?"center":r.focusedRegion});if(!o.selectedTaskId||!s){e.state={mode:"main",shell:o},e.render();return}e.state={mode:"main",shell:ue({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},$(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,Pe(re(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Pt(s),e.lastTerminalKey=null,e.state={mode:"main",shell:ue({...o,inputMode:"terminal"},i)},$(e,e.state.shell)}catch(r){let n=M(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Pt(t.selectedPtyTabId)&&(await Hm(e,t.selectedTaskId,n).catch(()=>{}),await q(e).catch(()=>{})),e.state={mode:"main",shell:j(e,ei(g(e,t),n),n)},$(e,e.state.shell)}e.render()}async function Hm(e,t,r){await ja(t,r,_(e))}async function Ya(e,t,r,n){let s=g(e,t),{nextShell:o}=await Ea(s,r,n,_(e));return await q(e),g(e,{...s,...o})}async function Ja(e,t){let r=g(e,t),{closedTab:n,nextShell:s}=await Aa(r,_(e));return e.ptyRuntime.disposeSession(n.id),await q(e),g(e,{...r,...s})}async function Xa(e,t){let r=g(e,t),n=Le(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await Ma(r,_(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await q(e),g(e,{...r,...i,selectedLeftItemId:zm(n,Le(e.model),s)})}async function Za(e,t){let r=g(e,t),{nextShell:n}=await Fa(r,_(e));return await q(e),g(e,{...r,...n})}async function Ga(e,t){return Da(t,_(e))}function pr(e,t){e.pendingScrollLines+=t,!e.scrollRenderTimer&&(e.scrollRenderTimer=setTimeout(()=>{e.scrollRenderTimer=null;let r=e.pendingScrollLines;e.pendingScrollLines=0,r!==0&&(e.ptyRuntime.scrollViewport(r),e.state={mode:"main",shell:Me(e,e.state.shell)},e.render())},16))}function zm(e,t,r){if(t.length===0)return null;for(let n=r-1;n>=0;n-=1){let s=e[n];if(s&&t.includes(s))return s}return t[Math.min(Math.max(0,r),t.length-1)]??null}async function el(e){if(!(e.prPollInFlight||e.state.mode!=="main")){e.prPollInFlight=!0;try{if(await Na(e.model.tasks,_(e)),e.lastBackgroundPrPollError=null,e.state.mode!=="main")return;e.model=await ye(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state={mode:"main",shell:g(e,e.state.shell)},e.render()}catch(t){let r=t instanceof Error?t.message:"Background PR discovery failed.";r!==e.lastBackgroundPrPollError&&(e.lastBackgroundPrPollError=r,Oa("background PR polling",t,_(e)))}finally{e.prPollInFlight=!1}}}async function tl(e,t){let r=g(e,t),n=me(e.model.tasks,r),s=null,o=null;if(n?.type==="project"&&n.repoTargets?.length){let i=await b.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await q(e);let a=i.synced+i.discovered+i.notFound;o=`Refreshed ${i.synced}/${a} targets`}else{let{disposition:i,task:a}=await b.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await q(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${E(a)?.requiredChecks.length??0} reported`)}return g(e,{...Ba(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}import Zm from"node:path";import{readdir as Qm,stat as Ym}from"node:fs/promises";import rl from"node:path";async function Jm(e){let t=await Qm(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=rl.join(e,n.name);r.push({name:n.name,path:s,kind:await Xm(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,query:null,error:null}}function nl(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function sl(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 mr(e,t){let r=await Jm(t);e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function Xm(e){let t=rl.join(e,".git");return await Ym(t).catch(()=>null)!==null}function ol(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function ef(e){if(e.state.mode!=="main"||e.creatingTask)return;let t=e.state.shell,r=t.taskPromptInput?.trim()??"";if(!t.selectedRepoId&&!t.selectedWorkspaceId){e.state={mode:"main",shell:g(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:g(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:g(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await La(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,_(e));n=s.task,await q(e);let o=g(e,{...e.state.shell,...s.nextShell,selectedLeftItemId:`task:${n.id}`,inputMode:"terminal",taskPromptInput:null,taskPromptError:null,actionMessage:null}),i=await e.ptyRuntime.ensureSession(n.id,o.selectedPtyTabId??Si(n,"agent"),Pe(re(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Pt(o.selectedPtyTabId),e.state={mode:"main",shell:ue(o,i)},$(e,e.state.shell)}catch(s){s instanceof et&&(n=s.task);let o=M(e,"create task",s,"Failed to create task.");n&&!(s instanceof et)?(await y(e.paths,{...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o}).catch(()=>{}),await q(e).catch(()=>{})):n&&(await y(e.paths,{...n,lastFailureReason:o}).catch(()=>{}),await q(e).catch(()=>{})),e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,inputMode:"control",selectedTaskId:n?.id??e.state.shell.selectedTaskId,selectedPtyTabId:n?.selectedPtyTabId??e.state.shell.selectedPtyTabId,selectedLeftItemId:n?`task:${n.id}`:e.state.shell.selectedLeftItemId,activeTab:n?.selectedPtyTabId??e.state.shell.activeTab,taskPromptInput:n?null:"",taskPromptError:o,actionMessage:null}),o)}}finally{e.creatingTask=!1,e.render()}}function tf(e,t){if(e.state.mode!=="main")return;let r=e.state.shell;if(r.taskPromptInput!==null){if(t==="ESCAPE"){e.state={mode:"main",shell:g(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(te(t)){ef(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:g(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:g(e,{...r,selectedRunner:Gt(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}ri(t)&&(e.state={mode:"main",shell:g(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function rf(e,t){if(e.state.mode!=="main")return;let r=e.state.shell.workspaceBrowser;if(!r)return;if(t==="ESCAPE"){if(r.query!==null){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:"",selectedIndex:0}})},e.render();return}if(r.query!==null&&(t==="BACKSPACE"||t==="DELETE")){let s=r.query.slice(0,-1);e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}if(r.query!==null&&t.length===1&&t>=" "){let s=r.query+t;e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=nl(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.max(0,r.selectedIndex-1),error:null}})},e.render();return}if(t==="DOWN"||t==="j"){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.min(Math.max(0,n.length-1),r.selectedIndex+1),error:null}})},e.render();return}if(t==="LEFT"||t==="h"){mr(e,Zm.dirname(r.cwd)).catch(s=>{let o=M(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:o}}),o)},e.render()});return}if(t==="RIGHT"||t==="l"||te(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){mr(e,s.path).catch(i=>{let a=M(e,"open workspace directory",i,"Failed to open directory.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:o}=_(e);o.addWorkspace(e.paths,s.path).then(async i=>{await q(e);let a=i.repos[0]??null,l=g(e,{...e.state.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${i.workspace.id}`,selectedWorkspaceId:i.workspace.id,selectedRepoId:a?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${i.workspace.name??i.workspace.id}`});e.state={mode:"main",shell:l},$(e,e.state.shell),e.render()}).catch(i=>{let a=M(e,"add workspace",i,"Failed to add workspace.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function nf(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=Ji(e.state.menuIndex,t);if(r.kind!=="noop"){if(r.kind==="render"){e.state={...e.state,menuIndex:r.menuIndex},e.render();return}if(r.kind==="back"){e.state.parentVariant&&(e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render());return}if(r.kind==="help"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell,viaOptions:!0,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="runners"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="error-log"){let n=e.state.parentVariant;sf(e,n)}}}async function sf(e,t){let r;try{r=await Ze.readRecentErrorLines(e.paths)}catch(n){let s=M(e,"open error log",n,"Failed to read Craig error log.");r={path:e.paths.errorLogFile,lines:[`Unable to read error log: ${s}`],empty:!1}}e.state.mode==="overlay"&&(e.state={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:e.state.shell,errorLog:r,...t!==void 0?{parentVariant:t}:{}},e.pendingClear=!0,e.render())}function of(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=Xi(ol(e),e.config,t,e.enabledRunnerIds);if(r.kind==="noop")return;if(r.kind==="back"){let s=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...s!==void 0?{parentVariant:s}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="render"){e.state={...e.state,runnerOptions:r.state},e.render();return}(r.kind==="save-enabled"?Wa(r.runner,r.enabled,_(e)):_a(r.runner,r.path,_(e))).then(s=>{e.state.mode!=="overlay"||e.state.variant!=="runners"||(e.config=s,e.enabledRunnerIds=k.runners.getEnabled(e.config),e.model={...e.model,enabledRunnerIds:e.enabledRunnerIds},e.state={...e.state,shell:g(e,{...e.state.shell,selectedRunner:e.enabledRunnerIds.includes(e.state.shell.selectedRunner)?e.state.shell.selectedRunner:k.runners.getDefault(e.config)}),runnerOptions:r.state},e.render())}).catch(s=>{if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let o=M(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:j(e,g(e,e.state.shell),o),runnerOptions:{...ol(e),message:o}},e.render()})}function il(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){tf(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){rf(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){lf(e),e.render();return}e.focusFlashUntil!==null&&(e.focusFlashUntil=null,e.focusFlashTimer&&(clearTimeout(e.focusFlashTimer),e.focusFlashTimer=null))}if(e.state.mode==="main"){let n=as(e.state.shell,r,cs(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&te(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=St(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(af(e,r))return;e.lastTerminalKey=bi(r)?{key:r,at:Date.now()}:null;let o=Ii(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){pr(e,o);return}e.ptyRuntime.writeKey(r);return}if(r==="CTRL_C"){e.exit(0);return}if(r==="?"&&e.state.shell.inputMode==="control"){e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render();return}if(n.pause){e.state={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:g(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){mr(e,e.workspaceRoot).catch(s=>{let o=M(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:j(e,g(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:o}}),o)},e.render()});return}if(n.createPtyTab){Ya(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{ps(e,s)}).catch(s=>{let o=M(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.closePtyTab){Ja(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=M(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.refreshPullRequestChecks){tl(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=M(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.openPrUrl){let s=me(e.model.tasks,n.state),o=s?E(s)?.url??null:null;o?sl(o).catch(i=>{let a=M(e,"open PR URL",i,"Failed to open PR in browser.");e.state={mode:"main",shell:j(e,g(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:j(e,g(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){Xa(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=M(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.removeWorkspace){Za(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=M(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.attachTerminal){ps(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render(),e.state.shell.focusedRegion==="tasks"){Ka(e,e.state.shell);return}ur(e,e.state.shell).catch(s=>{let o=M(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}n.changed&&(e.state={mode:"main",shell:g(e,n.state)},Ua(e,e.state.shell).catch(()=>{}),$(e,e.state.shell),e.render());return}if(e.state.variant==="help"){e.state.viaOptions&&e.state.parentVariant?e.state={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:e.state.shell,parentVariant:e.state.parentVariant}:e.state.parentVariant?e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell}:e.state={mode:"main",shell:g(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){nf(e,r);return}if(e.state.variant==="runners"){of(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||te(r)){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render()}return}if(e.state.optionsMessage){(r==="ESCAPE"||te(r))&&(e.state={...e.state,optionsMessage:null},e.render());return}if(r==="UP"||r==="k"){e.state={...e.state,menuIndex:Math.max(0,e.state.menuIndex-1)},e.render();return}if(r==="DOWN"||r==="j"){e.state={...e.state,menuIndex:Math.min(2,e.state.menuIndex+1)},e.render();return}if(r==="ESCAPE"){e.state.variant==="pause"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(te(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:g(e,{...e.state.shell,inputMode:"control"})},e.pendingClear=!0,e.render(),n?e.bootHydrationReady.then(()=>{if(e.state.mode!=="main")return;let s=e.state.shell;za(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},$(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=M(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:j(e,g(e,e.state.shell),i)},$(e,e.state.shell),e.render()})}):Ha(e);return}if(e.state.menuIndex===1){let n=e.state.variant==="boot"||e.state.variant==="pause"?e.state.variant:void 0;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}e.exit(0)}}function al(e,t){let r=xi(t);if(e.state.mode!=="main"||e.state.shell.inputMode!=="terminal"||r.length===0)return;if(e.pendingTerminalKeySequence){let o=`${e.pendingTerminalKeySequence.raw}${r}`,i=St(o);if(i){cl(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(Ln(o)){e.pendingTerminalKeySequence.raw=o,ll(e);return}fr(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:g(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},$(e,e.state.shell),e.render();return}let n=Ci(r);if(n!==0){pr(e,n);return}let s=St(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
162
+ `}function zm(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var et={appendErrorLog:as,appendErrorLogBestEffort:Da,readErrorLog:ls,readRecentErrorLines:$a};var Qm=["tasks","center","inspector"];function Ym(e,t,r){if(t==="ESCAPE")return w({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return w({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return ds(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return ps({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return w({state:{...e,fileSearchQuery:n},changed:!0})}return w({state:e})}function ps(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return ai(t)?w({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):w({state:e});if(e.fileSearchQuery!==null)return Ym(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return w({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return w({state:e,exit:!0});if(t==="ESCAPE")return w({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return w({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(Jt(e.selectedLeftItemId)||Xt(e.selectedLeftItemId)))return w({state:{...e,selectedRunner:Yt(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return Ma(e,1);if(t==="SHIFT_TAB"||t==="[")return Ma(e,-1);if(t==="z"||t==="Z")return w({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===I?Se(e,-1,r):ds(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===I?Se(e,1,r):ds(e,1,r);if(t==="PAGE_UP")return Se(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Se(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Se(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Se(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??x,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return w({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=sf(e,t);return w({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 w({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return w({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return w({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Rt(e.selectedLeftItemId)&&e.selectedTaskId)return w({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&mi(e.selectedLeftItemId)&&e.selectedWorkspaceId)return w({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Oa(e.activeTab,r.ptyTabIds??[]))return w({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return cs(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return La(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return cs(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return La(e,1)}if(re(t)){if(e.focusedRegion==="tasks"&&(Jt(e.selectedLeftItemId)||Xt(e.selectedLeftItemId))){let n=vn(e.selectedLeftItemId),s=En(e.selectedLeftItemId);return w({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 w({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&Rt(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return w({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Je(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Oa(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return w({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Je(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===I)return w({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 w({state:Zm({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return w({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:I,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}if(e.focusedRegion==="inspector"&&e.inspectionMode==="review"){let n=e.selectedDiffPath??r.diffPathIds?.[0]??null;return n?w({state:{...e,selectedDiffPath:n,activeTab:I,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?w({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):w({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?w({state:e}):e.selectedActionId==="refresh-checks"?w({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?w({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):w({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return w({state:e})}function Se(e,t,r){if(t===0)return w({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?Fa(e,t,r):e.inspectionMode==="review"?ja(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):w({state:e});if(e.focusedRegion==="center"&&e.activeTab===I){if(e.openInspectionKind==="file")return ja(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return ef(e,t,r)}return w({state:e})}function Ma(e,t){return gr(e,"focusedRegion",Qm,t)}function cs(e,t,r){let n=gr(e,"activeTab",r&&r.length>0?r:of(e),t);return!n.changed||di(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Je(n.state.activeTab)??n.state.preferredPtyTabKind}}}function ds(e,t,r){if(e.focusedRegion==="tasks")return Jm(e,t,r.leftItemIds);if(e.focusedRegion==="center")return cs(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Fa(e,t,r);if(r.projectTargetIds?.length){let s=us(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=us(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:I,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:gr(e,"selectedActionId",ri,t)}return gr(e,"selectedActionId",Sn,t)}function Jm(e,t,r){let n=us(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Cn(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=vn(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=En(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function Xm(e,t){if(e.inspectionMode===t)return w({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?I:e.activeTab;return w({state:{...e,inspectionMode:t,activeTab:n,openInspectionKind:r,fileScrollOffset:t==="files"?0:e.fileScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function La(e,t){return Xm(e,nf(e.inspectionMode,In,t))}function Fa(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return w({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=me(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return w({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return w({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?I:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function Zm(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 ja(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=me(e[t]+r,0,o);return i===e[t]?w({state:e}):w({state:{...e,[t]:i,actionMessage:null},changed:!0})}function ef(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return tf(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,a=r.diffPathIds??[];if(a.length===0||!e.selectedDiffPath){let d=me(i,0,o);return d===e.diffScrollOffset?w({state:e}):w({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let d=me(i,0,o);return d===e.diffScrollOffset?w({state:e}):w({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}if(t>0&&i>o){let d=a[l+1]??null;return d?w({state:{...e,selectedDiffPath:d,activeTab:I,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?w({state:e}):w({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let d=a[l-1]??null;return d?w({state:{...e,selectedDiffPath:d,activeTab:I,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?w({state:e}):w({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let c=me(i,0,o);return c===e.diffScrollOffset?w({state:e}):w({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function tf(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=me(e.diffScrollOffset+t,0,o),a=rf(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?w({state:e}):w({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function rf(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function gr(e,t,r,n){let s=r.indexOf(e[t]),o=me(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?w({state:e}):w({state:{...e,[t]:i,actionMessage:null},changed:!0})}function us(e,t,r,n,s=!1){if(r.length===0)return w({state:e});let o=r.indexOf(e[t]??r[0]??""),i=me(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?w({state:e}):w({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function nf(e,t,r){let n=t.indexOf(e);return t[me(n+r,0,t.length-1)]??e}function w(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 Oa(e,t){return t.includes(e)}function sf(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Je(e.activeTab)??e.preferredPtyTabKind}function of(e){return[e.selectedPtyTabId,e.openInspectionKind?I:null].filter(t=>typeof t=="string")}function me(e,t,r){return Math.min(r,Math.max(t,e))}var Na=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>{let o=await J(n.paths,e.selectedTaskId),i=t??af(o,e.activeTab,e.preferredPtyTabKind),a=Ua(o,i,r??void 0,n.config),l={...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id};return await y(n.paths,l),l});return{updatedTask:s,nextShell:{activeTab:s.selectedPtyTabId??e.activeTab,selectedPtyTabId:s.selectedPtyTabId,preferredPtyTabKind:s.ptyTabs.at(-1)?.kind??e.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${s.ptyTabs.at(-1)?.title??"tab"}`}}},Wa=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:r,nextSelectedTab:n}=await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.selectedTaskId),o=s.ptyTabs.findIndex(c=>c.id===e.activeTab);if(o===-1)throw new Error("Only PTY tabs can be closed.");let i=s.ptyTabs[o],a=s.ptyTabs.filter(c=>c.id!==i.id),l=a[Math.min(o,a.length-1)]??null;return await y(t.paths,{...s,ptyTabs:a,selectedPtyTabId:l?.id??null}),{closedTab:i,nextSelectedTab:l}});return{closedTab:r,nextSelectedTab:n,nextShell:{activeTab:n?.id??(e.openInspectionKind?"inspection":e.activeTab),selectedPtyTabId:n?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${r.title}`}}},_a=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{let n=await J(t.paths,r);!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab||await y(t.paths,{...n,selectedPtyTabId:e.activeTab})})},qa=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;o&&await y(t.paths,{...s,selectedPtyTabId:o.id})}),{...e,selectedPtyTabId:r.id};let n=Ua(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;if(o){await y(t.paths,{...s,selectedPtyTabId:o.id});return}await y(t.paths,{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function af(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Ua(e,t,r,n={}){let s=r??e.runner,o=h.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",a=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(f=>f.id)),c=1,d=a;for(;l.has(d);)c+=1,d=`${a}-${c}`;let p=new Date().toISOString(),m=r&&r!==e.runner?r:void 0;return{id:d,kind:t,...m?{runner:m}:{},title:c===1?i:`${i} ${c}`,command:t==="agent"?h.runners.buildCommand(s,void 0,n):[],createdAt:p,updatedAt:p}}var tt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Ba=async(e,t,r,n,s)=>{h.runners.assertEnabled(n,s.config);let o=t?await s.taskService.provisionProjectTask(s.paths,t,r,{runner:n,config:s.config}):await s.taskService.provisionTask(s.paths,e??"",r,{runner:n,config:s.config});try{let l=xe();await R(De(h.runners.getConfiguredProfile(n,s.config).executable,{cwd:o.repoRoot,env:l}),["--help"],{cwd:o.repoRoot,env:l})}catch(l){let c=l instanceof Error?l.message:"Failed to start runner.",d=await s.taskService.recordStartupFailure(s.paths,o.task.id,c);throw new tt(c,d)}let i=await s.taskService.markTaskStarted(s.paths,o.task.id),a={selectedRepoId:i.repoId,selectedWorkspaceId:i.workspaceId,selectedTaskId:i.id,selectedPtyTabId:i.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:i.selectedPtyTabId??"agent",selectedActionId:"commit"};return{task:i,nextShell:a}},Ka=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},Va=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:r,task:n}=await t.queueTaskMutation(async()=>{let s=await J(t.paths,e.selectedTaskId),o=await t.taskService.closeTask(t.paths,e.selectedTaskId);return{taskBeforeClose:s,task:o}});return{closedTabIds:r.ptyTabs.map(s=>s.id),nextShell:{selectedActionId:"close-task",actionMessage:n.cleanup.preservedWorktree?`Archived task ${n.id}; worktree preserved`:`Archived task ${n.id}`}}},Ga=async(e,t)=>{await t.taskService.prs.discoverOrRefreshMany(t.paths,e)},Ha=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await et.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var za=async(e,t)=>{if(!e.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await t.taskService.listTasks(t.paths,{workspaceId:e.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${e.selectedWorkspaceId} while task records still reference it.`);return await t.workspaceService.archiveWorkspace(t.paths,e.selectedWorkspaceId),{nextShell:{selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${(await t.workspaceService.removeWorkspace(t.paths,e.selectedWorkspaceId,{listTasks:t.taskService.listTasks})).workspaceId}`}}};var Qa=async(e,t,r)=>{let n=h.runners.setRunnerEnabled(r.config,e,t);return await h.save(r.paths,n),n},Ya=async(e,t,r)=>{let n=h.runners.setRunnerPath(r.config,e,t);return await h.save(r.paths,n),n},Ja=async(e,t,r)=>{let n=h.previews.setEnabled(r.config,e,t);return await h.save(r.paths,n),n};var lf=250;function fe(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function Oe(e,t){return pe(t,e.ptyRuntime.getViewState(vt(e,t)))}function vt(e,t){let r=fe(e.model.tasks,t);return r?r.ptyTabs.some(n=>n.id===t.activeTab)?t.activeTab:t.activeTab==="agent"||t.activeTab==="terminal"?r.ptyTabs.find(n=>n.kind===t.activeTab)?.id??t.selectedPtyTabId:t.selectedPtyTabId:t.selectedPtyTabId}function g(e,t){return Oe(e,fi(t,e.model))}function Xa(e,t,r){return e.footerToastTimer&&(clearTimeout(e.footerToastTimer),e.footerToastTimer=null),r?(e.footerToastTimer=setTimeout(()=>{e.footerToastTimer=null,!(e.state.mode!=="main"||e.state.shell.footerToast!==r)&&(e.state={mode:"main",shell:g(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function Za(e,t,r){return Xa(e,t,r?{tone:"success",message:r}:null)}function L(e,t,r){return Xa(e,t,{tone:"error",message:r})}function j(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return et.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function $(e,t){if(!e.uiStateFile)return;e.runtimeState=oi(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>we({uiStateFile:e.uiStateFile},r),()=>we({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function cf(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function _(e){return{paths:e.paths,config:e.config,taskService:S,workspaceService:H,queueTaskMutation:t=>cf(e,t)}}function ms(e,t){let r=fe(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?is(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:Le(e.model),centerTabIds:pi(r,t),ptyTabIds:r?.ptyTabs.map(a=>a.id)??[],filePathIds:s?.filePaths??[],fileTreeRowIds:i.map(a=>a.path),fileTreeFileIds:i.filter(a=>a.kind==="file").map(a=>a.path),fileTreeDirectoryIds:i.filter(a=>a.kind==="directory").map(a=>a.path),diffPathIds:s?.diffPaths??[],diffPathRanges:[],fileLineCount:s?.selectedFile.lines.length??0,diffLineCount:s?.selectedDiff.lines.length??0,reviewRowCount:Ca(t,r,s),pageRows:Math.max(5,ne(e.activeTerminal.width,e.activeTerminal.height).height-ee.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function el(e,t){await _a(t,_(e))}async function q(e){e.model=await Pe(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:g(e,e.state.shell)}:e.state={...e.state,shell:g(e,e.state.shell)}}async function hr(e,t){let r=++e.inspectionRefreshSequence,n=An(e.model.tasks,t),s=e.model.inspection,o=t.focusedRegion==="inspector"&&t.inspectionMode==="review"&&t.openInspectionKind!=="diff",i;if(n&&s?.taskId===n.id&&!o){let a={selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath},l=await Ko(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await Pe(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=i,e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},$(e,e.state.shell),e.render())}function tl(e,t){e.pendingLeftNavInspectionShell=t,!e.leftNavInspectionTimer&&(e.leftNavInspectionTimer=setTimeout(()=>{e.leftNavInspectionTimer=null;let r=e.pendingLeftNavInspectionShell;e.pendingLeftNavInspectionShell=null,!(!r||e.state.mode!=="main"||e.state.shell!==r)&&hr(e,r).catch(n=>{let s=j(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:L(e,g(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},lf))}function rl(e,t){t!==0&&(e.pendingInspectionScrollLines+=t,!e.inspectionScrollRenderTimer&&(e.inspectionScrollRenderTimer=setTimeout(()=>{e.inspectionScrollRenderTimer=null;let r=e.pendingInspectionScrollLines;if(e.pendingInspectionScrollLines=0,r===0||e.state.mode!=="main"||e.state.shell.inputMode!=="control")return;let n=Se(e.state.shell,r,ms(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render(),hr(e,e.state.shell).catch(s=>{let o=j(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:L(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render()}},16)))}function fs(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function gs(e){let t=e.model.tasks.flatMap(r=>r.ptyTabs.map(n=>n.id));await e.ptyRuntime.pruneStale?.(t),await e.ptyRuntime.hydrateSessions?.(t)}function sl(e){gs(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.render())})}async function ol(e,t){let r=g(e,t),n=fe(e.model.tasks,r),s=vt(e,r);if(!n||!s||!n.ptyTabs.some(a=>a.id===s))return r;let o=e.ptyRuntime.getViewState(s);if(o.status!=="idle"||o.rows.length>0||o.error)return pe(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,be(ne(e.activeTerminal.width,e.activeTerminal.height)));return pe({...r,inputMode:"control"},i)}function il(e){let t=e.state.mode==="main"&&e.state.shell.inputMode==="terminal"?"terminal":"control";t!==e.inputCaptureMode&&(e.inputCaptureMode=t,e.activeTerminal.grabInput(t==="terminal"?{mouse:"button"}:!0))}async function hs(e,t){try{let r=g(e,t),n=fe(e.model.tasks,r),s=r.selectedPtyTabId;if(n&&r.focusedRegion==="tasks"){let a=n.ptyTabs.find(l=>l.kind==="agent")??null;a?s=a.id:(n=await nl(e,n),await q(e),s=n.selectedPtyTabId)}n&&!s&&(n=await nl(e,n),await q(e),s=n.selectedPtyTabId);let o=g(e,{...r,activeTab:s??r.activeTab,selectedPtyTabId:s,focusedRegion:s?"center":r.focusedRegion});if(!o.selectedTaskId||!s){e.state={mode:"main",shell:o},e.render();return}e.state={mode:"main",shell:pe({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},$(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,be(ne(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=bt(s),e.lastTerminalKey=null,e.state={mode:"main",shell:pe({...o,inputMode:"terminal"},i)},$(e,e.state.shell)}catch(r){let n=j(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&bt(t.selectedPtyTabId)&&(await df(e,t.selectedTaskId,n).catch(()=>{}),await q(e).catch(()=>{})),e.state={mode:"main",shell:L(e,ii(g(e,t),n),n)},$(e,e.state.shell)}e.render()}async function df(e,t,r){await Ka(t,r,_(e))}async function al(e,t,r,n){let s=g(e,t),{nextShell:o}=await Na(s,r,n,_(e));return await q(e),g(e,{...s,...o})}async function ll(e,t){let r=g(e,t),{closedTab:n,nextShell:s}=await Wa(r,_(e));return e.ptyRuntime.disposeSession(n.id),await q(e),g(e,{...r,...s})}async function cl(e,t){let r=g(e,t),n=Le(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await Va(r,_(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await q(e),g(e,{...r,...i,selectedLeftItemId:uf(n,Le(e.model),s)})}async function dl(e,t){let r=g(e,t),{nextShell:n}=await za(r,_(e));return await q(e),g(e,{...r,...n})}async function nl(e,t){return qa(t,_(e))}function wr(e,t){e.pendingScrollLines+=t,!e.scrollRenderTimer&&(e.scrollRenderTimer=setTimeout(()=>{e.scrollRenderTimer=null;let r=e.pendingScrollLines;e.pendingScrollLines=0,r!==0&&(e.ptyRuntime.scrollViewport(r),e.state={mode:"main",shell:Oe(e,e.state.shell)},e.render())},16))}function uf(e,t,r){if(t.length===0)return null;for(let n=r-1;n>=0;n-=1){let s=e[n];if(s&&t.includes(s))return s}return t[Math.min(Math.max(0,r),t.length-1)]??null}async function ul(e){if(!(e.prPollInFlight||e.state.mode!=="main")){e.prPollInFlight=!0;try{if(await Ga(e.model.tasks,_(e)),e.lastBackgroundPrPollError=null,e.state.mode!=="main")return;e.model=await Pe(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state={mode:"main",shell:g(e,e.state.shell)},e.render()}catch(t){let r=t instanceof Error?t.message:"Background PR discovery failed.";r!==e.lastBackgroundPrPollError&&(e.lastBackgroundPrPollError=r,Ha("background PR polling",t,_(e)))}finally{e.prPollInFlight=!1}}}async function pl(e,t){let r=g(e,t),n=fe(e.model.tasks,r),s=null,o=null;if(n?.type==="project"&&n.repoTargets?.length){let i=await S.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await q(e);let a=i.synced+i.discovered+i.notFound;o=`Refreshed ${i.synced}/${a} targets`}else{let{disposition:i,task:a}=await S.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await q(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${A(a)?.requiredChecks.length??0} reported`)}return g(e,{...Za(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}import hf from"node:path";import{readdir as pf,stat as mf}from"node:fs/promises";import ml from"node:path";async function ff(e){let t=await pf(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=ml.join(e,n.name);r.push({name:n.name,path:s,kind:await gf(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,query:null,error:null}}function fl(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function gl(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 kr(e,t){let r=await ff(t);e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function gf(e){let t=ml.join(e,".git");return await mf(t).catch(()=>null)!==null}function hl(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function wl(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function wf(e){if(e.state.mode!=="main"||e.creatingTask)return;let t=e.state.shell,r=t.taskPromptInput?.trim()??"";if(!t.selectedRepoId&&!t.selectedWorkspaceId){e.state={mode:"main",shell:g(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:g(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:g(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await Ba(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,_(e));n=s.task,await q(e);let o=g(e,{...e.state.shell,...s.nextShell,selectedLeftItemId:`task:${n.id}`,inputMode:"terminal",taskPromptInput:null,taskPromptError:null,actionMessage:null}),i=await e.ptyRuntime.ensureSession(n.id,o.selectedPtyTabId??Ai(n,"agent"),be(ne(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=bt(o.selectedPtyTabId),e.state={mode:"main",shell:pe(o,i)},$(e,e.state.shell)}catch(s){s instanceof tt&&(n=s.task);let o=j(e,"create task",s,"Failed to create task.");n&&!(s instanceof tt)?(await y(e.paths,{...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o}).catch(()=>{}),await q(e).catch(()=>{})):n&&(await y(e.paths,{...n,lastFailureReason:o}).catch(()=>{}),await q(e).catch(()=>{})),e.state={mode:"main",shell:L(e,g(e,{...e.state.shell,inputMode:"control",selectedTaskId:n?.id??e.state.shell.selectedTaskId,selectedPtyTabId:n?.selectedPtyTabId??e.state.shell.selectedPtyTabId,selectedLeftItemId:n?`task:${n.id}`:e.state.shell.selectedLeftItemId,activeTab:n?.selectedPtyTabId??e.state.shell.activeTab,taskPromptInput:n?null:"",taskPromptError:o,actionMessage:null}),o)}}finally{e.creatingTask=!1,e.render()}}function kf(e,t){if(e.state.mode!=="main")return;let r=e.state.shell;if(r.taskPromptInput!==null){if(t==="ESCAPE"){e.state={mode:"main",shell:g(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(re(t)){wf(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:g(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:g(e,{...r,selectedRunner:Yt(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}li(t)&&(e.state={mode:"main",shell:g(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function Tf(e,t){if(e.state.mode!=="main")return;let r=e.state.shell.workspaceBrowser;if(!r)return;if(t==="ESCAPE"){if(r.query!==null){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:"",selectedIndex:0}})},e.render();return}if(r.query!==null&&(t==="BACKSPACE"||t==="DELETE")){let s=r.query.slice(0,-1);e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}if(r.query!==null&&t.length===1&&t>=" "){let s=r.query+t;e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=fl(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.max(0,r.selectedIndex-1),error:null}})},e.render();return}if(t==="DOWN"||t==="j"){e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.min(Math.max(0,n.length-1),r.selectedIndex+1),error:null}})},e.render();return}if(t==="LEFT"||t==="h"){kr(e,hf.dirname(r.cwd)).catch(s=>{let o=j(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:L(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:o}}),o)},e.render()});return}if(t==="RIGHT"||t==="l"||re(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){kr(e,s.path).catch(i=>{let a=j(e,"open workspace directory",i,"Failed to open directory.");e.state={mode:"main",shell:L(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:o}=_(e);o.addWorkspace(e.paths,s.path).then(async i=>{await q(e);let a=i.repos[0]??null,l=g(e,{...e.state.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${i.workspace.id}`,selectedWorkspaceId:i.workspace.id,selectedRepoId:a?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${i.workspace.name??i.workspace.id}`});e.state={mode:"main",shell:l},$(e,e.state.shell),e.render()}).catch(i=>{let a=j(e,"add workspace",i,"Failed to add workspace.");e.state={mode:"main",shell:L(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function Rf(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=ia(e.state.menuIndex,t);if(r.kind!=="noop"){if(r.kind==="render"){e.state={...e.state,menuIndex:r.menuIndex},e.render();return}if(r.kind==="back"){e.state.parentVariant&&(e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render());return}if(r.kind==="help"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell,viaOptions:!0,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="runners"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="previews"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"previews",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="error-log"){let n=e.state.parentVariant;yf(e,n)}}}async function yf(e,t){let r;try{r=await et.readRecentErrorLines(e.paths)}catch(n){let s=j(e,"open error log",n,"Failed to read Craig error log.");r={path:e.paths.errorLogFile,lines:[`Unable to read error log: ${s}`],empty:!1}}e.state.mode==="overlay"&&(e.state={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:e.state.shell,errorLog:r,...t!==void 0?{parentVariant:t}:{}},e.pendingClear=!0,e.render())}function Pf(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=la(hl(e),e.config,t,e.enabledRunnerIds);if(r.kind==="noop")return;if(r.kind==="back"){let s=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...s!==void 0?{parentVariant:s}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="render"){e.state={...e.state,runnerOptions:r.state},e.render();return}(r.kind==="save-enabled"?Qa(r.runner,r.enabled,_(e)):Ya(r.runner,r.path,_(e))).then(s=>{e.state.mode!=="overlay"||e.state.variant!=="runners"||(e.config=s,e.enabledRunnerIds=h.runners.getEnabled(e.config),e.model={...e.model,enabledRunnerIds:e.enabledRunnerIds},e.state={...e.state,shell:g(e,{...e.state.shell,selectedRunner:e.enabledRunnerIds.includes(e.state.shell.selectedRunner)?e.state.shell.selectedRunner:h.runners.getDefault(e.config)}),runnerOptions:r.state},e.render())}).catch(s=>{if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let o=j(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:L(e,g(e,e.state.shell),o),runnerOptions:{...hl(e),message:o}},e.render()})}function bf(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=aa(wl(e),e.config,t);if(r.kind!=="noop"){if(r.kind==="back"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="render"){e.state={...e.state,previewOptions:r.state},e.render();return}Ja(r.feature,r.enabled,_(e)).then(n=>{e.state.mode!=="overlay"||e.state.variant!=="previews"||(e.config=n,e.ptyRuntime.setViewUpdateMode?.(r.enabled?"incremental":"snapshot"),e.state={...e.state,previewOptions:r.state},e.render())}).catch(n=>{if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let s=j(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:L(e,g(e,e.state.shell),s),previewOptions:{...wl(e),message:s}},e.render()})}}function kl(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){kf(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){Tf(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){If(e),e.render();return}e.focusFlashUntil!==null&&(e.focusFlashUntil=null,e.focusFlashTimer&&(clearTimeout(e.focusFlashTimer),e.focusFlashTimer=null))}if(e.state.mode==="main"){let n=ps(e.state.shell,r,ms(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&re(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=St(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(Sf(e,r))return;e.lastTerminalKey=xi(r)?{key:r,at:Date.now()}:null;let o=Di(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){wr(e,o);return}e.ptyRuntime.writeKey(r);return}if(r==="CTRL_C"){e.exit(0);return}if(r==="?"&&e.state.shell.inputMode==="control"){e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render();return}if(n.pause){e.state={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:g(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){kr(e,e.workspaceRoot).catch(s=>{let o=j(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:L(e,g(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:o}}),o)},e.render()});return}if(n.createPtyTab){al(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{hs(e,s)}).catch(s=>{let o=j(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:L(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.closePtyTab){ll(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:L(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.refreshPullRequestChecks){pl(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:L(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.openPrUrl){let s=fe(e.model.tasks,n.state),o=s?A(s)?.url??null:null;o?gl(o).catch(i=>{let a=j(e,"open PR URL",i,"Failed to open PR in browser.");e.state={mode:"main",shell:L(e,g(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:L(e,g(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){cl(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:L(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.removeWorkspace){dl(e,n.state).then(s=>{e.state={mode:"main",shell:s},$(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:L(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.attachTerminal){hs(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:g(e,n.state)},$(e,e.state.shell),e.render(),e.state.shell.focusedRegion==="tasks"){tl(e,e.state.shell);return}hr(e,e.state.shell).catch(s=>{let o=j(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:L(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}n.changed&&(e.state={mode:"main",shell:g(e,n.state)},el(e,e.state.shell).catch(()=>{}),$(e,e.state.shell),e.render());return}if(e.state.variant==="help"){e.state.viaOptions&&e.state.parentVariant?e.state={mode:"overlay",variant:"options",menuIndex:3,optionsMessage:null,shell:e.state.shell,parentVariant:e.state.parentVariant}:e.state.parentVariant?e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell}:e.state={mode:"main",shell:g(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){Rf(e,r);return}if(e.state.variant==="runners"){Pf(e,r);return}if(e.state.variant==="previews"){bf(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||re(r)){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render()}return}if(e.state.optionsMessage){(r==="ESCAPE"||re(r))&&(e.state={...e.state,optionsMessage:null},e.render());return}if(r==="UP"||r==="k"){e.state={...e.state,menuIndex:Math.max(0,e.state.menuIndex-1)},e.render();return}if(r==="DOWN"||r==="j"){e.state={...e.state,menuIndex:Math.min(2,e.state.menuIndex+1)},e.render();return}if(r==="ESCAPE"){e.state.variant==="pause"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(re(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:g(e,{...e.state.shell,inputMode:"control"})},e.pendingClear=!0,e.render(),n?e.bootHydrationReady.then(()=>{if(e.state.mode!=="main")return;let s=e.state.shell;ol(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},$(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=j(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:L(e,g(e,e.state.shell),i)},$(e,e.state.shell),e.render()})}):sl(e);return}if(e.state.menuIndex===1){let n=e.state.variant==="boot"||e.state.variant==="pause"?e.state.variant:void 0;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}e.exit(0)}}function Tl(e,t){let r=Oi(t);if(e.state.mode!=="main"||e.state.shell.inputMode!=="terminal"||r.length===0)return;if(e.pendingTerminalKeySequence){let o=`${e.pendingTerminalKeySequence.raw}${r}`,i=St(o);if(i){yl(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(Fn(o)){e.pendingTerminalKeySequence.raw=o,Rl(e);return}Tr(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:g(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},$(e,e.state.shell),e.render();return}let n=$i(r);if(n!==0){wr(e,n);return}let s=St(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
163
163
  `&&r!==`\r
164
- `&&(e.suppressTerminalEnterOnAttach=!1),Ai(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function af(e,t){if(e.pendingTerminalKeySequence){let r=vi(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=St(n);if(s)return cl(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(Ln(n))return e.pendingTerminalKeySequence.raw=n,ll(e),!0}return fr(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>fr(e),30)},!0)}function ll(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>fr(e),30))}function fr(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function cl(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function dl(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){Va(e,$n(t));return}let r=$n(t);r!==0&&pr(e,r)}function lf(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var df=cf(import.meta.url),uf=df("terminal-kit"),pf=uf.terminal;function ms(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}async function ul(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=oe(t),n=await k.load(r),s=k.runners.getEnabled(n),o=e.uiStateFile?await Fe({uiStateFile:e.uiStateFile}):null,i=await ye(t,void 0,s),a=wt(Xo(o,n),i);i=await ye(t,a,s);let l={current:i},c=()=>{},d={workspaceRoot:t,onUpdate:()=>c(),resolveSessionSpec:(m,f)=>Pi(l.current,f,t)},p=e.ptyRuntime??await qi({...d,paths:r});return new Promise(m=>{let f=e.terminal??pf,w=null,u={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:wt(a,i)},get model(){return l.current},set model(A){l.current=A},config:n,enabledRunnerIds:s,creatingTask:!1,suppressTerminalEnterOnAttach:!1,lastTerminalKey:null,pendingScrollLines:0,pendingInspectionScrollLines:0,leftNavInspectionTimer:null,pendingLeftNavInspectionShell:null,pendingTerminalKeySequence:null,scrollRenderTimer:null,inspectionScrollRenderTimer:null,ptyRenderTimer:null,footerToastTimer:null,focusFlashUntil:null,focusFlashTimer:null,prPollTimer:null,prPollInFlight:!1,lastBackgroundPrPollError:null,versionText:`Craig v${k.version.getCurrent()}`,updateText:null,inspectionRefreshSequence:0,pendingClear:!0,inputCaptureMode:null,runtimeState:o,persistQueue:Promise.resolve(),taskMutationQueue:Promise.resolve(),bootHydrationReady:Promise.resolve(),paths:r,workspaceRoot:t,uiStateFile:e.uiStateFile,activeTerminal:f,ptyRuntime:p,resolve:m,render:()=>{},exit:A=>m(A)};c=()=>{u.state.mode==="main"&&(u.ptyRenderTimer||(u.ptyRenderTimer=setTimeout(()=>{u.ptyRenderTimer=null,u.state.mode==="main"&&(u.state={mode:"main",shell:Me(u,u.state.shell)},u.render())},50)))},u.render=()=>{Qa(u);let A=re(f.width,f.height),le=u.state.mode==="main"?gi(A,ca(g(u,u.state.shell),u.model),{centerOnly:u.state.shell.centerZoomed,focusFlashActive:u.focusFlashUntil!==null&&Date.now()<u.focusFlashUntil}):u.state.variant==="boot"?ui(A,{menuIndex:u.state.menuIndex,optionsMessage:u.state.optionsMessage,versionText:u.versionText,updateText:u.updateText}):u.state.variant==="pause"?pi(A,{menuIndex:u.state.menuIndex,optionsMessage:u.state.optionsMessage,versionText:u.versionText,updateText:u.updateText}):u.state.variant==="options"?En(A,{menuIndex:u.state.menuIndex,optionsMenuItems:Kn}):u.state.variant==="runners"?En(A,{menuIndex:ms(u.state).menuIndex,optionsMenuItems:Vn(u.config,ms(u.state)),optionsMessage:Yi(ms(u.state)),optionsSubtitle:"Runners"}):u.state.variant==="error-log"?fi(A,{errorLogPath:u.state.errorLog?.path??r.errorLogFile,errorLogLines:u.state.errorLog?.lines??[]}):mi(A);u.pendingClear&&(f.moveTo(1,1),f.eraseDisplayBelow(),u.pendingClear=!1,w=null),f.noFormat(Di(le,w)),w=le,f.hideCursor(!0)};let D=A=>il(u,A),B=A=>al(u,A),fe=A=>dl(u,A),ge=()=>{process.stdout.off("resize",T),process.off("SIGCONT",Ne),f.removeListener("key",D),f.removeListener("unknown",B),f.removeListener("mouse",fe),u.scrollRenderTimer&&(clearTimeout(u.scrollRenderTimer),u.scrollRenderTimer=null),u.inspectionScrollRenderTimer&&(clearTimeout(u.inspectionScrollRenderTimer),u.inspectionScrollRenderTimer=null),u.leftNavInspectionTimer&&(clearTimeout(u.leftNavInspectionTimer),u.leftNavInspectionTimer=null),u.pendingTerminalKeySequence&&(clearTimeout(u.pendingTerminalKeySequence.timer),u.pendingTerminalKeySequence=null),u.ptyRenderTimer&&(clearTimeout(u.ptyRenderTimer),u.ptyRenderTimer=null),u.footerToastTimer&&(clearTimeout(u.footerToastTimer),u.footerToastTimer=null),u.focusFlashTimer&&(clearTimeout(u.focusFlashTimer),u.focusFlashTimer=null),u.prPollTimer&&(clearInterval(u.prPollTimer),u.prPollTimer=null),u.ptyRuntime.disposeAll(),f.grabInput(!1),f.hideCursor(!1),f.fullscreen(!1)};u.exit=A=>{ge(),m(A)};let T=()=>{ds(u),u.state.mode==="main"&&u.state.shell.inputMode==="terminal"&&(u.ptyRuntime.resize(Pe(re(f.width,f.height))),u.state={mode:"main",shell:Me(u,u.state.shell)}),u.render()},Ne=()=>{ds(u),u.state.mode==="main"&&u.state.shell.inputMode==="terminal"&&(u.ptyRuntime.resize(Pe(re(f.width,f.height))),u.state={mode:"main",shell:Me(u,u.state.shell)}),u.render()};process.stdout.on("resize",T),process.on("SIGCONT",Ne),f.grabInput(!0),u.inputCaptureMode="control",f.hideCursor(!0),f.fullscreen(!0),f.on("key",D),f.on("unknown",B),f.on("mouse",fe),u.prPollTimer=setInterval(()=>{el(u)},(u.config.github?.watchIntervalSeconds??5)*1e3),k.version.checkForUpdate().then(A=>{A.updateAvailable&&A.latest&&(u.updateText=`Update available: v${A.latest}`,u.render())}),u.bootHydrationReady=us(u).catch(()=>{}),u.render()})}async function mf(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??process.cwd(),a=oe(i);return await Bi(a),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??process.cwd(),a=oe(i);return await Ui(a),0}let e=Is(process.argv.slice(2)),t=process.cwd(),r=oe(t),n={paths:r};if(e.mode==="interactive")return await ul({uiStateFile:r.uiStateFile,workspaceRoot:r.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await Mo(e.command,n),o=No(s);return o.length>0&&process.stdout.write(`${o}
164
+ `&&(e.suppressTerminalEnterOnAttach=!1),ji(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function Sf(e,t){if(e.pendingTerminalKeySequence){let r=Mi(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=St(n);if(s)return yl(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(Fn(n))return e.pendingTerminalKeySequence.raw=n,Rl(e),!0}return Tr(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>Tr(e),30)},!0)}function Rl(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>Tr(e),30))}function Tr(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function yl(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function Pl(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){rl(e,On(t));return}let r=On(t);r!==0&&wr(e,r)}function If(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var vf=Cf(import.meta.url),Ef=vf("terminal-kit"),Af=Ef.terminal;function ws(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function bl(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}async function Sl(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=ie(t),n=await h.load(r),s=h.runners.getEnabled(n),o=e.uiStateFile?await We({uiStateFile:e.uiStateFile}):null,i=await Pe(t,void 0,s),a=Tt(si(o,n),i);i=await Pe(t,a,s);let l={current:i},c=()=>{},d={workspaceRoot:t,onUpdate:()=>c(),resolveSessionSpec:(m,f)=>Ei(l.current,f,t)},p=e.ptyRuntime??await Hi({...d,paths:r,viewUpdateMode:h.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot"});return new Promise(m=>{let f=e.terminal??Af,k=null,u={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Tt(a,i)},get model(){return l.current},set model(v){l.current=v},config:n,enabledRunnerIds:s,creatingTask:!1,suppressTerminalEnterOnAttach:!1,lastTerminalKey:null,pendingScrollLines:0,pendingInspectionScrollLines:0,leftNavInspectionTimer:null,pendingLeftNavInspectionShell:null,pendingTerminalKeySequence:null,scrollRenderTimer:null,inspectionScrollRenderTimer:null,ptyRenderTimer:null,footerToastTimer:null,focusFlashUntil:null,focusFlashTimer:null,prPollTimer:null,prPollInFlight:!1,lastBackgroundPrPollError:null,versionText:`Craig v${h.version.getCurrent()}`,updateText:null,inspectionRefreshSequence:0,pendingClear:!0,inputCaptureMode:null,runtimeState:o,persistQueue:Promise.resolve(),taskMutationQueue:Promise.resolve(),bootHydrationReady:Promise.resolve(),paths:r,workspaceRoot:t,uiStateFile:e.uiStateFile,activeTerminal:f,ptyRuntime:p,resolve:m,render:()=>{},exit:v=>m(v)};c=()=>{u.state.mode==="main"&&(u.ptyRenderTimer||(u.ptyRenderTimer=setTimeout(()=>{u.ptyRenderTimer=null,u.state.mode==="main"&&(u.state={mode:"main",shell:Oe(u,u.state.shell)},u.render())},50)))},u.render=()=>{il(u),u.ptyRuntime.setViewedTab?.(u.state.mode==="main"?vt(u,u.state.shell):null);let v=ne(f.width,f.height),ce=u.state.mode==="main"?yi(v,Ta(g(u,u.state.shell),u.model),{centerOnly:u.state.shell.centerZoomed,focusFlashActive:u.focusFlashUntil!==null&&Date.now()<u.focusFlashUntil}):u.state.variant==="boot"?wi(v,{menuIndex:u.state.menuIndex,optionsMessage:u.state.optionsMessage,versionText:u.versionText,updateText:u.updateText}):u.state.variant==="pause"?ki(v,{menuIndex:u.state.menuIndex,optionsMessage:u.state.optionsMessage,versionText:u.versionText,updateText:u.updateText}):u.state.variant==="options"?ir(v,{menuIndex:u.state.menuIndex,optionsMenuItems:zn}):u.state.variant==="runners"?ir(v,{menuIndex:ws(u.state).menuIndex,optionsMenuItems:Qn(u.config,ws(u.state)),optionsMessage:na(ws(u.state)),optionsSubtitle:"Runners"}):u.state.variant==="previews"?ir(v,{menuIndex:bl(u.state).menuIndex,optionsMenuItems:sa(u.config),optionsMessage:oa(bl(u.state)),optionsSubtitle:"Feature Previews - Experimental"}):u.state.variant==="error-log"?Ri(v,{errorLogPath:u.state.errorLog?.path??r.errorLogFile,errorLogLines:u.state.errorLog?.lines??[]}):Ti(v);u.pendingClear&&(f.moveTo(1,1),f.eraseDisplayBelow(),u.pendingClear=!1,k=null),f.noFormat(Fi(ce,k)),k=ce,f.hideCursor(!0)};let D=v=>kl(u,v),U=v=>Tl(u,v),ge=v=>Pl(u,v),he=()=>{process.stdout.off("resize",T),process.off("SIGCONT",Fe),f.removeListener("key",D),f.removeListener("unknown",U),f.removeListener("mouse",ge),u.scrollRenderTimer&&(clearTimeout(u.scrollRenderTimer),u.scrollRenderTimer=null),u.inspectionScrollRenderTimer&&(clearTimeout(u.inspectionScrollRenderTimer),u.inspectionScrollRenderTimer=null),u.leftNavInspectionTimer&&(clearTimeout(u.leftNavInspectionTimer),u.leftNavInspectionTimer=null),u.pendingTerminalKeySequence&&(clearTimeout(u.pendingTerminalKeySequence.timer),u.pendingTerminalKeySequence=null),u.ptyRenderTimer&&(clearTimeout(u.ptyRenderTimer),u.ptyRenderTimer=null),u.footerToastTimer&&(clearTimeout(u.footerToastTimer),u.footerToastTimer=null),u.focusFlashTimer&&(clearTimeout(u.focusFlashTimer),u.focusFlashTimer=null),u.prPollTimer&&(clearInterval(u.prPollTimer),u.prPollTimer=null),u.ptyRuntime.disposeAll(),f.grabInput(!1),f.hideCursor(!1),f.fullscreen(!1)};u.exit=v=>{he(),m(v)};let T=()=>{fs(u),u.state.mode==="main"&&u.state.shell.inputMode==="terminal"&&(u.ptyRuntime.resize(be(ne(f.width,f.height))),u.state={mode:"main",shell:Oe(u,u.state.shell)}),u.render()},Fe=()=>{fs(u),u.state.mode==="main"&&u.state.shell.inputMode==="terminal"&&(u.ptyRuntime.resize(be(ne(f.width,f.height))),u.state={mode:"main",shell:Oe(u,u.state.shell)}),u.render()};process.stdout.on("resize",T),process.on("SIGCONT",Fe),f.grabInput(!0),u.inputCaptureMode="control",f.hideCursor(!0),f.fullscreen(!0),f.on("key",D),f.on("unknown",U),f.on("mouse",ge),u.prPollTimer=setInterval(()=>{ul(u)},(u.config.github?.watchIntervalSeconds??5)*1e3),h.version.checkForUpdate().then(v=>{v.updateAvailable&&v.latest&&(u.updateText=`Update available: v${v.latest}`,u.render())}),u.bootHydrationReady=gs(u).catch(()=>{}),u.render()})}async function xf(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??process.cwd(),a=ie(i);return await zi(a),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??process.cwd(),a=ie(i);return await Qi(a),0}let e=Ds(process.argv.slice(2)),t=process.cwd(),r=ie(t),n={paths:r};if(e.mode==="interactive")return await Sl({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=Uo(s);return o.length>0&&process.stdout.write(`${o}
165
165
  `),0}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
166
- `),1}}var ff=await mf();process.exit(ff);
166
+ `),1}}var Df=await xf();process.exit(Df);