craig-cli 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +53 -53
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,37 +1,37 @@
1
1
  #!/usr/bin/env node
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.
2
+ var Ml=Object.defineProperty;var Mt=(e,t)=>{for(var r in t)Ml(e,r,{get:t[r],enumerable:!0})};import{readFile as Nl}from"node:fs/promises";import{randomUUID as Ll}from"node:crypto";import{open as jl,readFile as Wf,rename as Ol,rm as Fl}from"node:fs/promises";import Sr from"node:path";async function F(e,t){let r=Sr.dirname(e),n=Sr.join(r,`.${Sr.basename(e)}.${process.pid}.${Date.now()}.${Ll()}.tmp`),s=await jl(n,"w");try{let o=`${JSON.stringify(t,null,2)}
3
+ `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Ol(n,e)}catch(o){throw await s.close().catch(()=>{}),await Fl(n,{force:!0}).catch(()=>{}),o}}async function qe(e){try{let t=await Nl(e.uiStateFile,"utf8"),r=JSON.parse(t);return Wl(r,e.uiStateFile)}catch(t){if(ql(t))return null;throw t}}async function Te(e,t){await F(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function jt(){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 Wl(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")||!_e(e,"inputMode")||!_e(e,"focusedRegion")||!_e(e,"activeTab")||!_e(e,"inspectorSection")||!_e(e,"inspectionMode")||!Lt(e,"openInspectionKind")||!Lt(e,"selectedFileTreePath")||!Lt(e,"selectedFilePath")||!Lt(e,"selectedDiffPath")||!_l(e,"collapsedFileTreePaths")||!_e(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 _e(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Lt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function _l(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function ql(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Ir={};Mt(Ir,{RUNNER_IDS:()=>$,assertEnabled:()=>Cs,buildCommand:()=>As,getConfiguredProfile:()=>Ot,getDefault:()=>Is,getDisplayName:()=>Es,getEnabled:()=>Ft,getProfile:()=>Ue,isRunnerType:()=>Nt,parse:()=>vs,setRunnerEnabled:()=>xs,setRunnerPath:()=>Ds});var $=["codex","cursor","claude"];var Ss={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 Ue=e=>Ss[e];var Ot=(e,t={})=>{let r=Ue(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var Ft=(e={})=>$.filter(t=>e.runners?.[t]?.enabled!==!1);var Is=(e={})=>{let t=Ft(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 Cs=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var Nt=e=>$.includes(e);var vs=e=>{if(!e||e.length===0)return"codex";if(!Nt(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${$.join(", ")}.`);return e};var Es=e=>Ue(e).displayName;var As=(e,t,r={})=>{let n=[Ot(e,r).executable];return t&&t.length>0&&n.push(t),n};var xs=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var Ds=(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 Cr={};Mt(Cr,{PREVIEW_FEATURE_IDS:()=>re,isEnabled:()=>$s,setEnabled:()=>Ms});var re=["incrementalCenterPane"];function $s(e,t){return e.previews?.[t]===!0}function Ms(e,t,r){return{...e,previews:{...e.previews,[t]:r}}}import{mkdir as Ul,readFile as Bl,writeFile as Kl}from"node:fs/promises";import Vl from"node:path";var Gl=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Ls=async e=>{try{return await Bl(e,"utf8")}catch(t){if(Gl(t))return null;throw t}},js=async(e,t)=>{await Ul(Vl.dirname(e),{recursive:!0}),await Kl(e,t,"utf8")};var Wt=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let r=e;if(r.runners!==void 0){if(typeof r.runners!="object"||r.runners===null||Array.isArray(r.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[n,s]of Object.entries(r.runners)){if(!$.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${$.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(!re.includes(n))throw new Error(`Craig config at ${t} is invalid. "previews.${n}" is not supported. Expected one of: ${re.join(", ")}.`);if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${n}" must be a boolean.`)}}return r};var vr=async(e,t={readConfigFile:Ls})=>{let r=await t.readConfigFile(e.configFile);if(!r)return{};if(r.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let n;try{n=JSON.parse(r)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Wt(n,e.configFile)};var Er=async(e,t,r={writeConfigFile:js})=>{Wt(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
4
+ `)};var Ar={};Mt(Ar,{checkForUpdate:()=>Os,getCurrent:()=>_t});var _t=()=>{try{return"0.8.1"}catch{return"unknown"}};var Hl="https://registry.npmjs.org/craig-cli/latest",zl=3600*1e3,Ql={value:null},Yl=(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},Os=async(e={fetch:globalThis.fetch,getCurrent:_t,cache:Ql})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<zl)return e.cache.value.result;let n=null;try{let o=await e.fetch(Hl,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&Yl(n,t)};return e.cache.value={result:s,cachedAt:r},s};var h={load:vr,save:Er,previews:Cr,runners:Ir,version:Ar};function Fs(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
- `+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.
6
+ `+V());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
 
8
- `+K());return{mode:"command",command:{kind:"addWorkspace",path:r}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let r=t[2]==="--archived";if(t.length===3&&!r)throw new Error(`Unsupported command: ${t.join(" ")}
8
+ `+V());return{mode:"command",command:{kind:"addWorkspace",path:r}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let r=t[2]==="--archived";if(t.length===3&&!r)throw new Error(`Unsupported command: ${t.join(" ")}
9
9
 
10
- ${K()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:r}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let r=t.indexOf("--repo"),n=t.indexOf("--workspace"),s=t.indexOf("--runner");if(r===-1&&n===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
10
+ ${V()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:r}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let r=t.indexOf("--repo"),n=t.indexOf("--workspace"),s=t.indexOf("--runner");if(r===-1&&n===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
11
11
 
12
- `+K());if(r!==-1&&n!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
12
+ `+V());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: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.
14
+ `+V());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,u)=>u>1&&u!==r&&u!==r+1&&u!==n&&u!==n+1&&u!==s&&u!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
15
15
 
16
- `+K());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
16
+ `+V());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
17
17
 
18
- `+K());if(c.length===0)throw new Error(`Task prompt cannot be empty.
18
+ `+V());if(c.length===0)throw new Error(`Task prompt cannot be empty.
19
19
 
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(" ")}
20
+ `+V());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: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(" ")}
22
+ ${V()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:le(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:le(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:le(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:le(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:le(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:le(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:le(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:le(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:le(t[2]),repoId:Jl(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:le(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
23
23
 
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 oe(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
24
+ ${V()}`)}function V(){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 le(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
26
26
 
27
- ${K()}`);return t}function zl(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
27
+ ${V()}`);return t}function Jl(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
28
28
 
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})
29
+ ${V()}`);return t}var _=(e,t)=>{let r=xr(e);if(!Zl(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},xr=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Dr(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:rc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:ec(t.repoTargets),runnerSession:t.runnerSession??Xl(t),checks:cc(t),lastCommit:t.lastCommit??null,prs:dc(t),artifacts:fc(t),cleanup:gc(t)}},Xl=e=>{if(typeof e.title!="string")return null;let t=Dr(e.runner);return{command:h.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},Zl=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"&&Ws(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||tc(t.repoTargets))&&sc(t.runnerSession)&&oc(t.prompt)&&_s(t.checks)&&qs(t.lastCommit)&&ac(t.prs)&&lc(t.artifacts)&&Bs(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},ec=e=>{if(Array.isArray(e))return e.filter(Ns)},tc=e=>Array.isArray(e)&&e.every(Ns),Ns=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)&&_s(t.checks)&&qs(t.lastCommit)&&Us(t.pullRequest)&&Bs(t.cleanup)},rc=e=>{if(Ws(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 nc(e.id,e.title,t,Dr(e.runner))},nc=(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}]},Dr=e=>e&&h.runners.isRunnerType(e)?e:"codex",Ws=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"),sc=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),oc=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",_s=e=>typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number"),qs=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",Us=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&ic(e.requiredChecks),ic=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)),ac=e=>Array.isArray(e)&&e.every(Us),lc=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),Bs=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),cc=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},dc=e=>{if(Array.isArray(e.prs))return e.prs.map(uc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:Ks(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Vs(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},uc=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:Ks(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:pc(t.reviewDecision),requiredChecks:Vs(t.requiredChecks),comments:mc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},Ks=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,pc=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,mc=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}]}):[],Vs=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})):[],fc=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},gc=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as Nc}from"node:fs/promises";import{readFile as hc,readdir as wc,rm as kc}from"node:fs/promises";import Gs from"node:path";var $r=(e,t)=>Gs.join(e.workspacesDir,`${t}.json`),Tc=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"):[]}},Hs=(e,t)=>{let r=Tc(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},Ee=async(e,t)=>{let r=$r(e,t),n=await hc(r,"utf8");return Hs(JSON.parse(n),r)},Ae=async(e,t)=>{await F($r(e,t.id),{...t,updatedAt:new Date().toISOString()})},J=async e=>{let t=await wc(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Ee(e,Gs.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},zs=async(e,t)=>{await kc($r(e,t),{force:!0})};import{readFile as Rc,readdir as yc,rm as Pc}from"node:fs/promises";import Qs from"node:path";var Mr=(e,t)=>Qs.join(e.reposDir,`${t}.json`),Ys=(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=Mr(e,t),n=await Rc(r,"utf8");return Ys(JSON.parse(n),r)},Lr=async(e,t)=>{await F(Mr(e,t.id),{...t,updatedAt:new Date().toISOString()})},ot=async e=>{let t=await yc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Z(e,Qs.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Js=async(e,t)=>{await Pc(Mr(e,t),{force:!0})};import{readFile as bc}from"node:fs/promises";var Sc=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"},qt=(e,t,r)=>{if(!Sc(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},G=async e=>{let t=await bc(e.indexFile,"utf8");return qt(JSON.parse(t),e.workspaceRoot,e.indexFile)},me=async(e,t)=>{await F(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as Ac,stat as xc}from"node:fs/promises";import Ke from"node:path";import{realpath as eo}from"node:fs/promises";import to from"node:path";import{execFile as Ic}from"node:child_process";import{promisify as Cc}from"node:util";var Xs=Cc(Ic);async function y(e,t,r={}){try{let n=await Xs(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(Zs(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function x(e,t,r={}){try{let n=await Xs(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(Zs(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function Zs(e){return e instanceof Error}var jr=async e=>{try{let r=(await y("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([eo(r).catch(()=>to.resolve(r)),eo(e).catch(()=>to.resolve(e))]);return n===s}catch{return!1}},Or=async e=>{let t=await x("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 x("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await y("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as de,readFile as vc}from"node:fs/promises";import H from"node:path";function ce(e){let t=H.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:H.join(t,"index.json"),reposDir:H.join(t,"repos"),workspacesDir:H.join(t,"workspaces"),sessionsDir:H.join(t,"sessions"),runtimeDir:H.join(t,"runtime"),uiStateFile:H.join(t,"runtime","ui-state.json"),tasksDir:H.join(t,"tasks"),jobsDir:H.join(t,"jobs"),logsDir:H.join(t,"logs"),errorLogFile:H.join(t,"logs","errors.log"),artifactsDir:H.join(t,"artifacts"),worktreesDir:H.join(t,"worktrees"),configFile:H.join(t,"config.json")}}var Ec=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Be=async e=>{let t=ce(e);await de(t.craigDir,{recursive:!0}),await Promise.all([de(t.reposDir,{recursive:!0}),de(t.workspacesDir,{recursive:!0}),de(t.sessionsDir,{recursive:!0}),de(t.runtimeDir,{recursive:!0}),de(t.tasksDir,{recursive:!0}),de(t.jobsDir,{recursive:!0}),de(t.logsDir,{recursive:!0}),de(t.artifactsDir,{recursive:!0}),de(t.worktreesDir,{recursive:!0})]);try{let s=await vc(t.indexFile,"utf8"),o=JSON.parse(s);return qt(o,e,t.indexFile)}catch(s){if(!Ec(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 F(t.indexFile,n),n};var ro=(e,t,r)=>{let n=new Date().toISOString();return{id:Dc(e,Ke.basename(t)),name:Ke.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},no=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},Dc=(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},$c=(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},so=async(e,t)=>{let r=await G(e);await me(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},Mc=async(e,t)=>{let r=await Ac(t,{withFileTypes:!0}),n=await ot(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Ke.join(t,o.name);if(!await jr(i))continue;let a=n.find(c=>c.rootPath===i)??s.find(c=>c.rootPath===i),l=await Or(i);s.push(a?no(a,l):ro([...n,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},Lc=async(e,t)=>{let r=await Or(t),n=await ot(e),s=n.find(u=>u.rootPath===t)??null,o=s?no(s,r):ro(n,t,r),i=`workspace_${o.id}`,l=(await J(e)).find(u=>u.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 Lr(e,o),l||await Ae(e,d),await so(e,{repoIds:[o.id],workspaceIds:[d.id]}),{kind:"createWorkspace",workspace:d,repos:[o],created:!l}},jc=async(e,t)=>{let r=await Mc(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await J(e),s=$c(n,Ke.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:Ke.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=>Lr(e,c))),await Ae(e,l),await so(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!o}},it=async(e,t)=>{await Be(e.workspaceRoot);let r=Ke.resolve(e.workspaceRoot,t);if(!(await xc(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await jr(r)?Lc(e,r):jc(e,r)};var Fr=async(e,t,r={listWorkspaceRecords:J,ensureCraigState:Be})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var Nr=async(e,t,r={readWorkspace:Ee,writeWorkspace:Ae})=>{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 Wr=async(e,t)=>{let n={...await Ee(e,t),status:"active",archivedAt:null};await Ae(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 xe=async(e,t,r={deleteWorkspace:zs,readCraigIndex:G,writeCraigIndex:me})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var _r=async(e,t,r)=>{let n=await Ee(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 xe(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var qr={};Mt(qr,{addRepo:()=>oo,listRegisteredRepos:()=>io,removeRepo:()=>ao});import Oc from"node:path";import{stat as Fc}from"node:fs/promises";var oo=async(e,t)=>{let r=Oc.resolve(e.workspaceRoot,t);if(!(await Fc(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await it(e,t),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${r}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}};var io=async(e,t={listRepos:ot,ensureCraigState:Be})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var ao=async(e,t,r)=>{let n=await Z(e,t),o=(await J(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=>xe(e,c.id))),await Js(e,t);let l=await G(e);return await me(e,{...l,repoIds:l.repoIds.filter(c=>c!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var z={addWorkspace:it,listWorkspaces:Fr,archiveWorkspace:Nr,restoreWorkspace:Wr,removeWorkspace:_r,removeWorkspaceRecord:xe,repos:qr};var Q=async(e,t)=>{let r=await Nc(Br(e,t),"utf8");return JSON.parse(r)},X=async(e,t)=>{let r=await Q(e,t);return _(r,Br(e,t))},P=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await F(Br(e,t.id),r)},Ur=async(e,t)=>{let r=await G(e);r.taskIds.includes(t)||await me(e,{...r,taskIds:[...r.taskIds,t]})},Br=(e,t)=>`${e.tasksDir}/${t}.json`;var D=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,Re=e=>e.status==="merged"||e.status==="closed",Ve=(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}},at=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return Bt(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},Bt=e=>e.mergeable&&!Wc(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),Wc=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",Kr=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),lt=(e,t)=>{let r=e.isDraft??!1,n=_c(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:qc(e.reviewDecision??null),requiredChecks:ct(e.statusCheckRollup),comments:Vc(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}},_c=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,qc=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,ct=e=>{let t=e.map(n=>Uc(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||Bc(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},Uc=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:co(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:Kc(t)}:null},Bc=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Ut(e)&&!Ut(t)?!0:!Ut(e)&&Ut(t)?!1:lo(t.status)>=lo(e.status),Ut=e=>e.conclusion?.toUpperCase()==="CANCELLED",lo=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},Kc=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},Vc=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(Gc).filter(r=>r!==null).slice(-4):[]},Gc=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=Hc(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},Hc=e=>e.replace(/\s+/g," ").trim(),co=(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?co(n,n):"unknown"};import{access as zc}from"node:fs/promises";import uo from"node:path";var I=async(e,t,r={readRawTask:Q,validateTaskRecord:_})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Zc(n)?new Error(`Craig task "${t}" was not found.`):n}},q=async e=>{if(!await Vr(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},Ge=(e,t)=>t.artifacts.logPath?uo.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:uo.join(e.workspaceRoot,t.artifacts.logPath):null,dt=async(e,t)=>{let r=await Vr(t.worktreePath),n=Ge(e,t),s=n?await Vr(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Qc(t),lastCommitSummary:Yc(t),prSummary:Jc(t),cleanupSummary:Xc(t)}},Vr=async e=>{try{return await zc(e),!0}catch{return!1}},Qc=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}`},Yc=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",Jc=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=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(`
31
+ `)}`}let t=D(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})`},Xc=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",Zc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var po=async(e,t)=>{let r=await x("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.")},Gr=async(e,t,r,n="main")=>{let s=n.trim()||"main";if((await x("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 ed(e,s);await y("git",["worktree","add","-b",t,r,i],{cwd:e})},ed=async(e,t)=>(await x("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await x("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await x("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t,Kt=async e=>{let t=await x("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},mo=async e=>{await y("git",["add","-A"],{cwd:e})},fo=async(e,t)=>{await y("git",["commit","-m",t],{cwd:e})},go=async e=>{let t=await y("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}},ho=async e=>{let t=await x("git",["branch","--show-current"],{cwd:e});if(t.exitCode!==0)return null;let r=t.stdout.trim();return r.length>0?r:null};var wo=async(e,t)=>{await y("git",["worktree","remove","--force",t],{cwd:e})};var Hr=async e=>He(e,e.repoRoot),He=async(e,t)=>{let r=await G(e),n=ko(new Date),s=To(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await po(t,i))return o;s+=1}},ut=async e=>{let t=await G(e),r=ko(new Date),n=To(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},ko=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},To=(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 zr=async(e,t,r={readRawTask:Q,validateTaskRecord:_})=>{let n=await G(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(td(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}},td=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var Ro=["merge_ready","pr_open","checked","review","running","draft"],Qr=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),Yr=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(rd)[0]?.id??null,rd=(e,t)=>{let r=yo(e.status),n=yo(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},yo=e=>{let t=Ro.indexOf(e);return t>=0?t:Ro.length};import Po from"node:path";var De=(e,t)=>t?Po.isAbsolute(t)?t:Po.join(e.repoRoot,t):null;import{mkdir as pt,rm as nd,writeFile as Vt}from"node:fs/promises";import E from"node:path";var So=["AGENTS","md"].join("."),ze=async(e,t,r,n={})=>{let s=await Z(e,t),o=await ld(e,s.id),i=await He(e,s.rootPath),a=n.sessionId??null,l=`craig/${i}`,c=E.join(e.worktreesDir,s.id,i),d=E.join(e.logsDir,`${i}.log`),u=E.join(e.artifactsDir,i);await pt(E.dirname(c),{recursive:!0}),await pt(u,{recursive:!0}),await Vt(d,"","utf8");let p=sd(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 P(e,p),await Ur(e,i),await Gr(s.rootPath,l,c,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:a,workspaceId:o.id,task:p}},mt=async(e,t,r,n={})=>{let s=(await J(e)).find(b=>b.id===t&&b.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 b=await ze(e,s.primaryRepoId,r,n);return{...b,bundlePath:b.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await ut(e),a=new Date().toISOString(),l=n.runner??"codex",c=n.sessionId??null,d=`craig/${i}`,u=E.join(e.craigDir,"task-bundles",i),p=E.join(e.logsDir,`${i}.log`),f=E.join(e.artifactsDir,i);await pt(u,{recursive:!0}),await pt(f,{recursive:!0}),await Vt(p,"","utf8");let k=await Promise.all(o.map(b=>Z(e,b))),T=id(k),A=await Promise.all(k.map(b=>od(e,b,i,d,E.join(u,T.get(b.id))))),m=A.find(b=>b.status==="ready")??A[0];if(!A.some(b=>b.status==="ready"))throw await nd(u,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${A.map(b=>`${b.repoId}: ${b.failureReason??"unknown error"}`).join("; ")}`);await Vt(E.join(u,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:A.map(b=>({repoId:b.repoId,repoName:k.find(ae=>ae.id===b.repoId)?.name??b.repoId,path:E.relative(u,b.worktreePath),status:b.status,worktreePath:b.worktreePath,failureReason:b.failureReason}))},null,2),"utf8"),await Vt(E.join(u,So),ad({taskId:i,workspaceId:t,prompt:r,repos:k,repoTargets:A,bundlePath:u}),"utf8");let ie=ft(i,r,a,l,n.config??{}),pe={id:i,title:r,slug:Io(r),type:"project",status:"draft",runner:l,repoId:m.repoId,workspaceId:s.id,sessionId:c,selectedPtyTabId:ie[0]?.id??null,linkedRepoIds:o.filter(b=>b!==m.repoId),repoRoot:u,worktreePath:u,branch:d,bundlePath:u,selectedRepoTargetId:m.repoId,repoTargets:A,ptyTabs:ie,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:m.checks,lastCommit:null,prs:[],artifacts:{logPath:E.relative(e.workspaceRoot,p),checkSummaryPath:E.relative(e.workspaceRoot,E.join(f,"check-summary.json")),prDraftPath:null,prStatusPath:E.relative(e.workspaceRoot,E.join(f,"pr-status.json"))},cleanup:Gt(),lastFailureReason:A.every(b=>b.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:a,updatedAt:a};return await P(e,pe),await Ur(e,i),{repoId:m.repoId,repoRoot:u,sessionId:c,workspaceId:s.id,task:pe,bundlePath:u,repoTargets:A}},ft=(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}]},sd=(e,t)=>{let r=new Date().toISOString(),n=ft(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:Io(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:{...Jr(E.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:E.relative(e.workspaceRoot,E.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:E.relative(e.workspaceRoot,E.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:E.relative(e.workspaceRoot,E.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:Gt(),lastFailureReason:null,createdAt:r,updatedAt:r}},od=async(e,t,r,n,s)=>{await pt(E.dirname(s),{recursive:!0});try{return await Gr(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:Jr(E.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:bo(),cleanup:Gt()}}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:Jr(E.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:bo(),cleanup:Gt()}}},id=e=>{let t=new Set(["manifest.json",So]),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},ad=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=E.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
- `)},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=>`
34
+ `)},Jr=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),bo=()=>({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}),Gt=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),ld=async(e,t)=>{let n=(await J(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},Io=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import Oo from"node:path";import{readFile as cd,rm as nk}from"node:fs/promises";import dd from"node:path";var ye=async(e,t)=>{let r=await cd(Xr(e,t),"utf8"),n=JSON.parse(r);return ud(n,Xr(e,t))},$e=async(e,t)=>{await F(Xr(e,t.id),{...t,updatedAt:new Date().toISOString()})};var Xr=(e,t)=>dd.join(e.sessionsDir,`${t}.json`);function ud(e,t){let r=fd(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")||!md(r.attach)||!pd(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 pd(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 md(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 fd(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 gd}from"node:child_process";import{createHash as hd}from"node:crypto";import wd from"node:path";function Ht(e){return`'${e.replace(/'/g,"'\\''")}'`}var kd="craig",Co=async(e,t,r)=>{let n=Zr(e,t),s=Rd(),o=await y("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=Pd(o.stdout);return await Td(e,n),i};var Td=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 y("tmux",n,{cwd:e})},vo=async(e,t,r)=>{await y("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},Eo=async(e,t,r)=>{await y("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var Ao=async(e,t,r)=>{await y("tmux",["pipe-pane","-o","-t",e,`cat >> ${Ht(t)}`],{cwd:r})},zt=async(e,t,r,n)=>{let s=n??Do(e);if(r?await y("tmux",["select-window","-t",r],{cwd:e}):await y("tmux",["select-window","-t",t],{cwd:e}),await y("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await y("tmux",["switch-client","-t",s],{cwd:e});return}await Sd(e,["attach-session","-t",s])};var xo=async(e,t)=>{await y("tmux",["kill-session","-t",t],{cwd:e})};var Do=e=>{let r=wd.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=hd("sha1").update(e).digest("hex").slice(0,8);return`${kd}-${r}-${n}`},Zr=(e,t)=>`${Do(e)}-${t.toLowerCase()}`,Rd=()=>{let e=yd();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},yd=()=>{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},Pd=e=>{let t=bd(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]}},bd=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),Sd=async(e,t)=>{await new Promise((r,n)=>{let s=gd("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 Id,constants as Cd}from"node:fs";import{homedir as $o}from"node:os";import Pe from"node:path";var vd=[Pe.join($o(),".local","bin"),Pe.join($o(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Lo(e=process.env){return Ed([...(e.PATH??"").split(Pe.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:vd])}function Me(e=process.env){return{...e,PATH:Lo(e).join(Pe.delimiter)}}function en(e,t={}){if(e.includes(Pe.sep)){let r=Pe.isAbsolute(e)?e:Pe.resolve(t.cwd??process.cwd(),e);return Mo(r)?r:null}for(let r of Lo(t.env)){let n=Pe.join(r,e);if(Mo(n))return n}return null}function Le(e,t={}){let r=en(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 Mo(e){try{return Id(e,Cd.X_OK),!0}catch{return!1}}function Ed(e){return[...new Set(e)]}var gt={async create(e,t){let r=await Co(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await Ao(r.paneId,t.logPath,t.repoRoot);let n=await jo({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||Zr(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 $e(e,s),s},async attach(e,t,r){let n=await gt.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await zt(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await $e(e,s),s},async resize(e,t,r,n){await vo(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await $e(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 $e(e,n),n},async snapshot(e,t){return Ad(e,t)}},tn={async prepare(e,t){let n=e.runnerSession.command[0],s=Me();await y(Le(n,{cwd:t.repoRoot,env:s}),["--help"],{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=Le(r[0],{cwd:e.worktreePath,env:Me()});await Eo(t.session.paneId,[n,...r.slice(1)].map(s=>Ht(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},Ad=async(e,t)=>{let r=await x("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return jo({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},jo=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var rn=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 mt(e,n.workspaceId,s,{runner:i,config:o}):await ze(e,t,s,{runner:i,config:o}),l=a.task,c=h.runners.buildCommand(i,s,o),d=`session_${l.id}`,u=l.artifacts.logPath?Oo.resolve(e.workspaceRoot,l.artifacts.logPath):Oo.join(e.logsDir,`${l.id}.log`);try{await tn.prepare(l,{repoRoot:a.repoRoot});let p=await gt.create(e,{sessionId:d,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:u,command:c});await tn.launch(l,{repoRoot:a.repoRoot,session:p});let f=new Date().toISOString();p={...p,status:"running",startedAt:f,command:c};let k={...l,status:"running",runner:i,sessionId:p.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:p.command,pid:null,startedAt:f,lastKnownState:"running",exitCode:null,exitedAt:null}};return await P(e,k),await $e(e,p),{kind:"createTask",taskId:k.id,repoId:k.repoId,workspaceId:k.workspaceId,sessionId:p.id,status:k.status,branch:k.branch,worktreePath:k.worktreePath,runner:k.runner}}catch(p){let f={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:p instanceof Error?p.message:"Unknown Craig error"};throw await P(e,f),p}};import{mkdir as Wd}from"node:fs/promises";import _d from"node:path";var Fo=3,xd=1e3,Dd=1e4,Qe=async e=>{let t=await x("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var No=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await y("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},Qt=async(e,t)=>{let r=await y("gh",qo(e),{cwd:t});return JSON.parse(r.stdout)},Ye=async(e,t)=>{let r=await x("gh",qo(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},Wo=async(e,t,r)=>{if(r.length===0)return[];let n=Fd(r),s=await $d(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=Nd(c);return{id:a.id,found:d!==null,view:d}})},_o=async e=>{let t=await x("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:Od(t.stdout.trim())},$d=async(e,t)=>{let r;for(let n=0;n<=Fo;n+=1)try{return await y("gh",t,{cwd:e})}catch(s){if(r=s,n===Fo||!Md(s))throw s;await jd(Ld(n))}throw r},Md=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")},Ld=e=>{let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||xd,r=Math.min(t*2**e,Dd),n=Math.floor(Math.random()*Math.max(1,Math.floor(r*.25)));return r+n},jd=e=>new Promise(t=>setTimeout(t,e)),qo=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],Od=e=>{let t=e.replace(/\.git$/,""),r=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let n=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null},Fd=e=>`
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
- `,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(`
113
+ `,Nd=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 je=async(e,t)=>{let r=De(e,t.artifacts.prStatusPath);r&&(await Wd(_d.dirname(r),{recursive:!0}),await F(r,{taskId:t.id,prs:t.prs}))},ht=async(e,t,r,n,s={readRawTask:Q,validateTaskRecord:_,writeTask:P,writePrStatusArtifact:je})=>{let o=lt(r,n),i=Ve(t,o),a=at(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`),u=d.status==="closed"?d.status:a,p=Ve({...d,status:u},o);return await s.writeTask(e,p),p},wt=async(e,t)=>{let r=D(t),n=r?.number?String(r.number):t.branch,s=await Qt(n,t.worktreePath);return ht(e,t,s,r)},kt=async(e,t)=>{for(let r of await nn(t)){let n=await Ye(r,t.worktreePath);if(!n)continue;return{discovered:!0,task:await ht(e,t,n,null)}}return{discovered:!1,task:t}},nn=async e=>{let t=await ho(e.worktreePath).catch(()=>null);return[...new Set([t,e.branch].filter(r=>!!r))]};var Je=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await Qt(n,r.worktreePath),a=Bo(i);return r.pullRequest=a,await Uo(e,t,r.repoId,a),"synced"}let s=await Ye(n,r.worktreePath);if(!s)return"not_found";let o=Bo(s);return r.pullRequest=o,await Uo(e,t,r.repoId,o),"discovered"},Uo=async(e,t,r,n)=>{let s=await Q(e,t.id),o=_(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 P(e,a),a},Bo=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:qd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:Ud(e.reviewDecision??null),requiredChecks:ct(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),qd=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Ud=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var Tt=async(e,t)=>{let r=await I(e,t),n=D(r);return n?.number?(await Qe(r.worktreePath),Re(n)?(await kt(e,r)).task:wt(e,r)):r},on=async(e,t)=>{let r=await I(e,t);if(r.type==="project"&&r.repoTargets?.length)return await Xe(e,t),I(e,t);let n=D(r);if(await q(r),await Qe(r.worktreePath),!n?.number||Re(n)){let o=await kt(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return await je(e,o.task),o.task}let s=await wt(e,r);return await je(e,s),s},Xe=async(e,t)=>{let r=await I(e,t),n=(r.repoTargets??[]).filter(a=>a.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let a of n){await Qe(a.worktreePath);let l=a.pullRequest.number?await Je(e,r,a):await Je(e,r,a).catch(()=>"not_found");s[l==="not_found"?"notFound":l]++}let o=await Q(e,r.id),i=_(o,`${e.tasksDir}/${r.id}.json`);return i.status!=="closed"&&(i.status=Vo(i),await P(e,i)),s},an=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=sn(r,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(u=>u.status==="ready")){let u={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head",fallbackSelectors:[]};await Ko(n,u).catch(async()=>{try{let p=d.pullRequest.number?await Je(e,s,d):await Je(e,s,d).catch(()=>"not_found");Yt(o,p,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=D(s),a=i?.number&&!Re(i),l=a?[]:await nn(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 Ko(n,c).catch(async()=>{try{let{disposition:d,task:u}=await Jt(e,s.id),p=D(u);Yt(o,d,p?.number??null,p?.url??null)}catch{}})}for(let s of n.values())try{await Qe(s.worktreePath);let o=await Wo(s.worktreePath,s.repository,s.items),i=new Map(o.map(a=>[a.id,a]));for(let a of s.items){let l=sn(r,a.task),d=i.get(a.id)?.view??await Hd(s.worktreePath,a);if(!d){Yt(l,"not_found",null,null);continue}if(a.targetRepoId){let u=await Q(e,a.task.id),p=_(u,`${e.tasksDir}/${a.task.id}.json`);await Bd(e,p,a.targetRepoId,d)}else{let u=await Q(e,a.task.id),p=_(u,`${e.tasksDir}/${a.task.id}.json`);await ht(e,p,d,a.mode==="number"?D(p):null)}Yt(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 Q(e,s.id),i=_(o,`${e.tasksDir}/${s.id}.json`);i.status!=="closed"&&(i.status=Vo(i),await P(e,i))}return t.map(s=>sn(r,s))},Jt=async(e,t)=>{let r=await I(e,t);await q(r),await Qe(r.worktreePath);let n=D(r);if(n?.number&&!Re(n))return{disposition:"synced",task:await wt(e,r)};let s=await kt(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},Vo=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(zd)?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"},Bd=async(e,t,r,n)=>{let s=Kd(n),o=(t.repoTargets??[]).map(a=>a.repoId===r?{...a,pullRequest:s}:a),i={...t,repoTargets:o};return await P(e,i),i},Kd=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:Vd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:Gd(e.reviewDecision??null),requiredChecks:ct(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),Vd=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Gd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Hd=async(e,t)=>{if(t.mode!=="head")return null;for(let r of t.fallbackSelectors){let n=await Ye(r,e);if(n)return n}return null},Ko=async(e,t)=>{let r=await _o(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]})},sn=(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):!!D(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},Yt=(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},zd=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 ln=async(e,t)=>{let r=await I(e,t);try{r.type==="project"&&r.repoTargets?.length?(await Xe(e,t),r=await I(e,t)):r.prs.some(o=>o.number)&&(r=await Tt(e,t))}catch{}let n=await dt(e,r),s=r.sessionId?await ye(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var cn=async(e,t)=>{let r=await I(e,t);if(await q(r),(await y("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await Qd(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},Qd=async e=>{let t=[],r=await y("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await Yd(e);for(let s of n){let o=await x("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
114
114
 
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(`
115
+ `)},Yd=async e=>(await y("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
+ `).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as Jd}from"node:child_process";import{access as Xd}from"node:fs/promises";var dn=async(e,t)=>{let r=await I(e,t),n=Ge(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await Xd(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},un=async e=>{await new Promise((t,r)=>{let n=!1,s=Jd("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 Zd}from"node:fs/promises";import eu from"node:path";var pn=async(e,t)=>{let r=await I(e,t);if(await q(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 Kt(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 P(e,r);let o=[];for(let i of s){let a=new Date().toISOString(),l=await x("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 Go(e,r),await P(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 Go(e,r),await P(e,r),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},Go=async(e,t)=>{let r=De(e,t.artifacts.checkSummaryPath);r&&(await Zd(eu.dirname(r),{recursive:!0}),await F(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var mn=async(e,t)=>{let r=await I(e,t);await q(r);let n=await Kt(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 mo(r.worktreePath),await fo(r.worktreePath,s);let o=await go(r.worktreePath);return r.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},r.lastFailureReason=null,await P(e,r),{kind:"commitTask",taskId:r.id,status:r.status,commitSha:o.sha,message:o.message}};import{access as tu}from"node:fs/promises";var fn=async(e,t)=>{let r=await I(e,t),n=await ru(r.worktreePath),s={...r,status:"closed",cleanup:{...r.cleanup,preservedWorktree:n&&r.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await P(e,s),s},ru=async e=>{try{return await tu(e),!0}catch{return!1}};var gn=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await ye(e,t.sessionId);await xo(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 wo(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 P(e,t)};var hn=async(e,t,r)=>{let[n,s]=await Promise.all([I(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 P(e,{...n,linkedRepoIds:o}),{kind:"addTaskLink",taskId:n.id,repoId:s.id,linkedRepoIds:o}},wn=async(e,t)=>{let r=await I(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>Z(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var kn=async(e,t)=>{let r=await I(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),ye(e,r.sessionId)]),o=await gt.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var Tn=async(e,t)=>{let r=await I(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await ye(e,r.sessionId).catch(s=>{throw nu(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 zt(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},nu=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as su}from"node:child_process";var Rn=async(e,t)=>{let r=await I(e,t);await q(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 ou(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},ou=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=su(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 yn=async(e,t,r)=>{let n=await X(e,t);await P(e,{...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})},Pn=async(e,t,r)=>{let n=await X(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await P(e,s),s},bn=async(e,t)=>{let r=await X(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 P(e,s),s};var Sn=async(e,t,r="merge",n)=>{let s=await I(e,t),o=n??D(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await No(s.worktreePath,o,r)};var C={listTasks:zr,getTask:I,provisionTask:ze,provisionProjectTask:mt,createTask:rn,showTask:ln,showTaskDiff:cn,prepareTaskLogs:dn,streamTaskLogs:un,runChecks:pn,commitTask:mn,closeTask:fn,cleanupTask:gn,addTaskLink:hn,listTaskLinks:wn,sortTasksForDisplay:Qr,resolveSelectedTaskId:Yr,allocateTaskId:Hr,allocateTaskIdForRepo:He,allocateProjectTaskId:ut,createDefaultTaskPtyTabs:ft,assertTaskWorktreeExists:q,resolveTaskLogPath:Ge,buildTaskInspection:dt,resolveArtifactPath:De,attachTask:kn,focusTask:Tn,openTask:Rn,markRunnerFailed:yn,recordStartupFailure:Pn,markTaskStarted:bn,prs:{refresh:Tt,refreshChecks:on,discoverOrRefresh:Jt,discoverOrRefreshAll:Xe,discoverOrRefreshMany:an,merge:Sn,getPrimaryPr:D,isPrTerminal:Re,isMergeReady:Bt,deriveTaskStatus:at,upsertPr:Ve,normalizePr:lt,summarizeRequiredChecks:Kr,writePrStatusArtifact:je}};async function Ho(e,t){switch(e.kind){case"addWorkspace":{let r=await z.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await In(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await z.repos.addRepo(t.paths,e.path);return await In(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return z.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await qe({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await J(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await z.repos.removeRepo(t.paths,e.repoId,{listTasks:C.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await Te({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await Te({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return z.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await z.archiveWorkspace(t.paths,e.workspaceId);return await iu(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await z.restoreWorkspace(t.paths,e.workspaceId);return await In(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return z.removeWorkspace(t.paths,e.workspaceId,{listTasks:C.listTasks});case"createTask":return C.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?C.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):C.listTasks(t.paths);case"attachTask":return C.attachTask(t.paths,e.taskId);case"addTaskLink":return C.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return C.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return C.showTask(t.paths,e.taskId);case"showSelectedTask":return C.showTask(t.paths,Oe(t,"show"));case"streamTaskLogs":return C.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return C.prepareTaskLogs(t.paths,Oe(t,"logs"));case"showTaskDiff":return C.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return C.showTaskDiff(t.paths,Oe(t,"diff"));case"focusTask":return C.focusTask(t.paths,e.taskId);case"focusSelectedTask":return C.focusTask(t.paths,Oe(t,"focus"));case"openTask":return C.openTask(t.paths,e.taskId);case"openSelectedTask":return C.openTask(t.paths,Oe(t,"open"));case"runChecks":return C.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return C.runChecks(t.paths,Oe(t,"check"));case"commitTask":return C.commitTask(t.paths,e.taskId);case"commitSelectedTask":return C.commitTask(t.paths,Oe(t,"commit"));case"help":return{kind:"help",text:V()};case"exit":return{kind:"exit"};default:return au(e)}}async function In(e,t,r){let n=await qe({uiStateFile:e.uiStateFile})??jt();await Te({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function iu(e,t){let r=await qe({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Te({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function au(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Oe(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 zo(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} ${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(`
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} ${du(t)} ${uu(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}`,...lu(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 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
125
+ `);default:return cu(e)}}function lu(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 cu(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function du(e){return e.checks.status}function uu(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 xf}from"node:module";import{readFile as pu,stat as mu}from"node:fs/promises";import Cn from"node:path";var fu=200*1024,gu=500*1024,Xt="100000";async function Yo(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return hu(e,t,r);try{let n=be(r.selectedFilePath??null,t.filePaths),s=be(r.selectedDiffPath??null,t.diffPaths),o=s?await Rt(e.worktreePath):null,[i,a]=await Promise.all([er(e.worktreePath,n),s?vn(e.worktreePath,s,t.diffRows,o):Promise.resolve(K("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 hu(e,t,r){let n=be(r.selectedFilePath??null,t.filePaths),s=be(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([Xo(e,n),(async()=>{if(!s)return K("No diff selected","No local changes found.","empty");let l=Zt(e,s),c=l?await Rt(l.target.worktreePath).catch(()=>null):null;return Zo(e,s,t.diffRows,c)})()]),a=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:a,selectedFile:o,selectedDiff:i}}async function Jo(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return wu(e,t);try{await q(e);let r=await Rt(e.worktreePath),[n,s]=await Promise.all([ei(e.worktreePath),ti(e.worktreePath,r)]),o=[...new Set(s.map(u=>u.path))],i=be(t.selectedFilePath??null,n),a=be(t.selectedDiffPath??null,o),[l,c]=await Promise.all([er(e.worktreePath,i),a?vn(e.worktreePath,a,s,r):Promise.resolve(K("No diff selected","No local changes found.","empty"))]),d=a?{[a]:c}:{};return{taskId:e.id,fileRows:si(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:K("Files unavailable",n,"error"),selectedDiff:K("Diff unavailable",n,"error"),error:n}}}async function wu(e,t){let r=(e.repoTargets??[]).filter(p=>p.status==="ready"),n=await Promise.all(r.map(async p=>{let f=await Rt(p.worktreePath).catch(()=>null),[k,T]=await Promise.all([ei(p.worktreePath).catch(()=>[]),ti(p.worktreePath,f).catch(()=>[])]);return{target:p,baseRef:f,targetFiles:k,targetDiffRows:T}})),s=[],o=[];for(let{target:p,targetFiles:f,targetDiffRows:k}of n)s.push(...f.map(T=>`${p.repoId}/${T}`)),o.push(...k.map(T=>({...T,path:`${p.repoId}/${T.path}`})));let i=[...new Set(o.map(p=>p.path))].sort(),a=be(t.selectedFilePath??null,s),l=be(t.selectedDiffPath??null,i),[c,d]=await Promise.all([Xo(e,a),(async()=>{if(!l)return K("No diff selected","No local changes found.","empty");let p=Zt(e,l),f=p?n.find(k=>k.target.repoId===p.target.repoId):null;return Zo(e,l,o,f?.baseRef??null)})()]),u=l?{[l]:d}:{};return{taskId:e.id,fileRows:si(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:u,selectedFilePath:a,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}async function Xo(e,t){let r=Zt(e,t);if(!r)return K("No file selected","No Git-visible files found.","empty");let n=await er(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function Zo(e,t,r,n=null){let s=Zt(e,t);return s?{...await vn(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}:K(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 ei(e){let t=await y("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return oi(t.stdout)}async function ti(e,t){let[r,n,s,o]=await Promise.all([ku(e,t),Qo(e,"staged"),Qo(e,"unstaged"),Tu(e)]);return[...r,...n,...s,...o]}async function ku(e,t){if(!t)return[];let[r,n]=await Promise.all([y("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),y("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=ri(r.stdout),o=ni(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 Qo(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([y("git",[...r,"--name-status"],{cwd:e}),y("git",[...r,"--numstat"],{cwd:e})]),o=ri(n.stdout),i=ni(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 Tu(e){let t=await y("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=oi(t.stdout);return await Promise.all(r.map(async s=>{let o=await er(e,s),i=o.status==="ready"?Ru(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function ri(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 ni(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 Rt(e){return(await x("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await x("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function er(e,t){if(!t)return K("No file selected","No Git-visible files found.","empty");let r=yu(e,t);try{let n=await mu(r);if(n.size>fu)return K(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await pu(r);return Pu(s)?K(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 K(t,s,"missing",t,null)}}async function vn(e,t,r,n=null){if(!t)return K("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 Rt(e);if(a){let l=await y("git",["diff","--stat","--patch",`--unified=${Xt}`,`${a}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
129
+ ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let a=await y("git",["diff","--cached","--stat","--patch",`--unified=${Xt}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`staged
130
+ ${a.stdout.trimEnd()}`)}if(o.includes("unstaged")){let a=await y("git",["diff","--stat","--patch",`--unified=${Xt}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`unstaged
131
+ ${a.stdout.trimEnd()}`)}if(o.includes("untracked")){let a=await x("git",["diff","--no-index","--stat","--patch",`--unified=${Xt}`,"--","/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>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===`
134
+ `);return i.length>gu?K(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?K(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 si(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 be(e,t){return e&&t.includes(e)?e:t[0]??null}function Ru(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function oi(e){return[...new Set(e.split(`
136
+ `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function yu(e,t){let r=Cn.resolve(e,t),n=Cn.resolve(e);if(r!==n&&!r.startsWith(`${n}${Cn.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function Pu(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function K(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}var bu=["tasks","center","inspector","actions"],ii=["agent","terminal"],ai=[],v="inspection",ey=[...ii,...ai],En=["commit","push","refresh-checks","close-task"],li=["refresh-checks","close-task"],ci=["task","checks","pr","setup-run","actions","next-action"],An=["files","review"];function di(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=Au(e?.openInspectionKind)??r,s=h.runners.getEnabled(t);return{inputMode:Du(e?.inputMode),focusedRegion:vu(e?.focusedRegion),selectedRepoId:fe(e?.selectedRepoId),selectedWorkspaceId:fe(e?.selectedWorkspaceId),selectedTaskId:fe(e?.selectedTaskId),selectedPtyTabId:fe(e?.selectedPtyTabId),selectedLeftItemId:Fu(fe(e?.selectedTaskId)),activeTab:r?v:fe(e?.activeTab)??"agent",preferredPtyTabKind:xu(e?.preferredPtyTabKind),inspectorSection:yt(e?.inspectorSection,ci,"task"),inspectionMode:Eu(e?.inspectionMode,r==="diff"?"review":"files"),openInspectionKind:n,selectedFileTreePath:fe(e?.selectedFileTreePath),selectedFilePath:fe(e?.selectedFilePath),selectedDiffPath:fe(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:yt(e?.selectedActionId,En,"commit"),selectedProjectTargetId:null,selectedRunner:$u(e?.selectedRunner,s,h.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,fileSearchQuery:null,workspaceBrowser:null,terminal:Su(),centerZoomed:!1}}function Su(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function ui(e,t){return{...e??jt(),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 Pt(e,t,r={}){let n=Ou(e,t),s=xn(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(u=>u.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(u=>u.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,...Mu(c,e.activeTab,e.selectedPtyTabId),selectedFilePath:Cu(e,t,c?.id??null),...Lu(e,t,c?.id??null),selectedDiffPath:Iu(e,t,c?.id??null),inspectorSection:yt(e.inspectorSection,ci,"task")}}function ge(e,t){return{...e,terminal:t}}function pi(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function mi(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function ne(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
137
+ `}function fi(e){return e.length===1&&e>=" "&&e!=="\x7F"}function gi(e){return wi(e)||Ze(e)!==null}function hi(e){return ai.includes(e)}function wi(e){return ii.includes(e)}function ki(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[v]:[]]}function Iu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function Cu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function yt(e,t,r){return t.includes(e??"")?e:r}function vu(e){return e==="tabs"?"center":yt(e,bu,"tasks")}function Eu(e,t){return e==="checks"||e==="actions"||e==="diff"||e==="review"?"review":yt(e,An,t)}function Au(e){return e==="file"||e==="diff"?e:null}function xu(e){return e==="terminal"?"terminal":"agent"}function Du(e){return e==="terminal"?"terminal":"control"}function $u(e,t=[...$],r="codex"){return e&&h.runners.isRunnerType(e)&&t.includes(e)?e:r}function tr(e,t=$){let r=t.length>0?t:$,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function Ze(e){let t=$.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Mu(e,t,r){if(!e)return{activeTab:t===v?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(wi(t)){let l=e.ptyTabs.find(c=>c.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:l?.id??v,selectedPtyTabId:l?.id??null}}if(t===v)return{activeTab:v,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??v,selectedPtyTabId:i?.id??null}}function Lu(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?ju(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function ju(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 Ou(e,t){let r=Fe(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 Fe(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 xn(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 fe(e){return typeof e=="string"?e:null}function Fu(e){return e?`task:${e}`:null}function bt(e){return typeof e=="string"&&e.startsWith("task:")}function rr(e){return typeof e=="string"&&e.startsWith("new-task:")}function nr(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function Ti(e){return typeof e=="string"&&e.startsWith("workspace:")}function Dn(e){return rr(e)?e.slice(9):null}function $n(e){return nr(e)?e.slice(19):null}async function Se(e,t,r){let n=ce(e),[s,o]=await Promise.all([z.repos.listRegisteredRepos(n),z.listWorkspaces(n,{archived:!1})]),i=await C.listTasks(n),a=Mn(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},c=a?await Jo(a,l):null;return{workspaceRoot:e,workspaces:o.workspaces,repos:s.repos,tasks:i.tasks,inspection:c,...r?{enabledRunnerIds:r}:{}}}function Mn(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function Ri(e,t){return Pt(e,t)}import qn from"node:path";import cy from"picocolors";var Nu=[" \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 Ln(){return[...Nu]}var sr={width:120,height:36},N={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function ee(e,t){return{width:Math.max(e??sr.width,sr.width),height:Math.max(t??sr.height,sr.height)}}var Wu=["Start","Options","Exit"],_u=["Resume","Options","Exit"],ir=2,ar=2,lr=2,qu=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Uu=new RegExp("\x1B\\[(?:0)?m","g"),Bu=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),Ku=/https?:\/\/[^\s<>"']+/g,jn="\x1B[0m",Fn="\x1B]8;;\x1B\\",S={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 bi(e,t={}){return Wn(e,{subtitle:"crAIg is that you?",menuItems:Wu,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function Si(e,t={}){return Wn(e,{subtitle:"Control mode is paused.",menuItems:_u,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var or=[" 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."],Vu=["Help"],Gu=5;function dr(e,t={}){return Wn(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Vu,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Ii(e,t={}){let r=t.color??!0,n=S.overlay,s=new Array(e.height).fill(L(" ".repeat(e.width),r,n)),o=Ln(),i=Math.max(1,Math.floor((e.height-o.length-2-or.length)/2));for(let d=0;d<o.length&&!(i+d>=e.height);d+=1)s[i+d]=L(xi(o[d]??"",e.width),r,S.overlayLogo);let a=Math.max(...or.map(d=>d.length)),l=Math.max(0,Math.floor((e.width-a)/2)),c=i+o.length+2;for(let d=0;d<or.length;d+=1){let u=c+d;if(u>=e.height)break;let p=or[d]??"";s[u]=L(ue(" ".repeat(l)+p,e.width),r,n)}return s.join(`
138
+ `)}function Ci(e,t={}){let r=t.color??!0,n=S.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"},se(),...a.length>0?a.map(f=>({text:f})):[{text:"No Craig errors have been logged.",tone:"muted"}],se(),{text:"Esc returns to Options.",tone:"muted"}],u=St(d,e.height-2),p=Math.max(1,Math.floor((e.height-u.length)/2));for(let f=0;f<u.length;f+=1){let k=p+f;if(k>=e.height)break;let T=u[f]??se(),A=`${" ".repeat(c)}${ur(T.text,l)}`,m=T.tone==="selected"?S.overlayMenuSelected:T.tone==="muted"?S.overlay:S.panelBg;s[k]=L(ue(A,e.width),r,m)}return s.join(`
139
+ `)}function vi(e,t,r={}){let n=r.color??!0,s=N.leftWidth,o=N.rightWidth,i=r.centerOnly??!1,a=e.height-N.topRailHeight-1,l=r.focusFlashActive??!1,c={bg:S.divider.bg,fg:"9ece6a"},d=l&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?c:S.divider,u=l&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?c:S.divider,p=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,f=L(ue(p,e.width),n,S.rail),k=zu(t,s-ir-ar,a,n),T=Nn(e,t,{color:n,centerOnly:i}),A=Ju(t,o,a,n),m=t.inputMode==="terminal",ie=[];for(let ae=0;ae<a;ae+=1){if(i){ie.push(T.rows[ae]??"");continue}let Dt=On(k[ae]??se(),s,n,"left"),$t=L("\u2502",n,d),R=T.rows[ae]??"",te=L("\u2502",n,u),ke=On(A[ae]??se(),o,n,"right");ie.push(`${Dt}${$t}${R}${te}${ke}`)}let pe=m||t.modalInput?S.panelBg:S.panelMuted,b=Hu(t.footerText,t.footerToast,e.width,n,pe);return{frame:[f,...ie,b].join(`
140
+ `),center:T}}function Nn(e,t,r={}){let n=r.color??!0,s=r.centerOnly??!1,o=s?e.width:e.width-N.leftWidth-N.rightWidth-N.dividerWidth*2,i=e.height-N.topRailHeight-1,a=Qu(t,o,i,n);return{row:N.topRailHeight+1,column:s?1:N.leftWidth+N.dividerWidth+1,width:o,rows:a.map(l=>On(l,o,n,"center"))}}function Hu(e,t,r,n,s){let o=` ${e}`;if(!t)return L(ue(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,a=Y(i),l=Y(o),c=Math.max(1,r-l-a-2),d=l+c+a+2>r?ur(o,Math.max(0,r-a-3)):o,u=Math.max(1,r-Y(d)-a-2),p=t.tone==="error"?hp(i,n,s):et(i,n,s),f=`${d}${" ".repeat(u)}${p} `;return L(ue(f,r),n,s)}function Wn(e,t){let r=new Array(e.height).fill(L(" ".repeat(e.width),t.color,S.overlay)),n=Ln(),s=t.menuItems.map((c,d)=>`${d===t.menuIndex?">":" "} ${c}`),o=t.optionsMessage?["",t.optionsMessage]:[],i=[...s,...o];for(;i.length<Gu;)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=xi(a[c]??"",e.width);if(c<n.length){r[l+c]=L(d,t.color,S.overlayLogo);continue}if(c===n.length+1){r[l+c]=L(d,t.color,S.overlaySubtitle);continue}let u=c-(n.length+3),f=u>=0&&u<t.menuItems.length&&u===t.menuIndex?S.overlayMenuSelected:S.overlay;r[l+c]=L(d,t.color,f)}if(t.versionText){let c=t.updateText?" (update available)":"",d=`${t.versionText}${c} `,u=" ".repeat(Math.max(0,e.width-Y(d)));r[e.height-1]=L(`${u}${_n(d,t.color,S.overlay)}`,t.color,S.overlay)}return r.join(`
141
+ `)}function zu(e,t,r,n){let s=ep(e.runners),o=1,i=e.leftTree.map(l=>Zu(l,t,n));return[...St(i,r-o),s]}function Qu(e,t,r,n){let s=t-2,o=e.tabs.find(b=>b.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:mp(e.tabs),a=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,a)),c=`${" ".repeat(i)}${e.inputMode==="terminal"?et(l,n,S.panelBg):cr(l,n,S.panelMuted)}`,d=[`${cr(e.centerHeader.tabLabel,n,S.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),u=e.tabs.find(b=>b.active)?.id??"agent",p=e.centerHeader.tabLabel==="BROWSER"||!gi(u)?e.centerTranscript.map(b=>({...b})):Yu(e),f=tp(e.tabs,n,e.focusedRegion==="center"),k=" engaged ",T=k.length+2,A=e.inputMode==="terminal"?et(`${k}\u25CF `,n,S.panelBg):"",m=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-Y(f)-T)):"",pe=[{text:e.inputMode==="terminal"?`${f}${m}${A}`:f},{text:c,tone:"muted"},{text:d},se(),...p];return St(pe,r)}function Yu(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},se(),{text:e.terminal.error},se(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(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:Mi(n.segments),segments:n.segments,fullBleed:!0}))}function Ju(e,t,r,n){let s=e.rightInspection?Xu(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):St([{text:"CONTEXT"},se(),...e.rightContext.map(o=>rp(o,n)),...e.actionMessage?[se(),{text:e.actionMessage}]:[]],r);return St(s,r)}function Xu(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:gp(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(a=>yi(a)),...n.slice(i,i+s).map(a=>yi(a))]}function yi(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 Zu(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${et("\u25CF",r,e.selected?S.panelSelected:S.panelBg)}`:"",a=e.prBadge?e.prBadge.reduce((f,k)=>f+Y(k.text),0):0,l=t-Y(o)-Y(s)-a,c=e.selected?e.text:e.focused?et(e.text,r,S.panelBg):e.panelHeader?cr(e.text,r,S.panelMuted):e.text,d=ue(`${n}${c}`,Math.max(0,l)),u=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(T=>T.text).join("")}`,segments:f,tone:u}}return{text:`${d}${o}${i}`,tone:u}}function ep(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:S.success.fg}}):r.push({text:s.text,style:{fg:S.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function tp(e,t,r){return e.map(n=>n.active?r?et(n.label,t,S.panelBg):cr(n.label,t,S.panelBg):_n(n.label,t,S.panelBg)).join(" ")}function rp(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?_n(e.value,t,S.panelBg):e.value}`}}function On(e,t,r,n){let s=np(n,e.tone??"default"),o=sp(e,r,s);if(n==="left"){if(e.fullBleed)return L(ue(o,t),r,s);let a=t-ir-ar;if(e.rightAlign){let c=Y(o),d=Math.max(0,a-c),u=`${" ".repeat(ir)}${" ".repeat(d)}${o}${" ".repeat(ar)}`;return L(u,r,s)}let l=`${" ".repeat(ir)}${ue(o,a)}${" ".repeat(ar)}`;return L(l,r,s)}return n==="center"&&e.fullBleed?op(e,t,r,s):L(ue(` ${o}`,t),r,s)}function np(e,t){return t==="selected"||t==="focused"?S.panelSelected:t==="muted"?S.panelMuted:S.panelBg}function St(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(se());return r}function se(){return{text:""}}function sp(e,t,r){return e.segments?e.segments.map(n=>Ei(n,t,r)).join(""):e.text}function op(e,t,r,n){let s=" ".repeat(lr),o=Math.max(0,t-lr*2);if(!e.segments)return L(`${s}${ue(e.text,o)}${s}`,r,n);let i=lp(e.segments,o),a=`${s}${i.map(l=>Ei(l,r,n)).join("")}${s}${r?Fn:""}`;return L(a,r,n)}function Ei(e,t,r){let n=e.href?`${Ai(e.href)}${e.text}${Fn}`:ip(e.text);return!t||!e.style?n:`${It(up(e.style,r))}${pp(e.style)}${n}${jn}${It(r)}`}function ip(e){return e.replace(Ku,t=>{let[r,n]=ap(t);return`${Ai(r)}${r}${Fn}${n}`})}function ap(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function Ai(e){return`\x1B]8;;${e}\x1B\\`}function lp(e,t){let r=cp(e,t);return dp(r,t)}function cp(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=Y(s.text);if(o<=n){r.push(s),n-=o;continue}let i=ur(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function dp(e,t){let r=Y(Mi(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 up(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 pp(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 mp(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+3}return 0}function xi(e,t){let r=Math.max(0,t-Y(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function ue(e,t){let r=Y(e);return r>=t?fp(e,t):e+" ".repeat(t-r)}function fp(e,t){if(t<=0)return"";if(Y(e)<=t)return e;let r=$i(e);return ur(r,Math.max(0,t-1))+"\u2026"}function Y(e){let t=0;for(let r of Array.from($i(e)))t+=Di(r);return t}function ur(e,t){let r="",n=0;for(let s of Array.from(e)){let o=Di(s);if(n+o>t)break;r+=s,n+=o}return r}function Di(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 gp(e,t,r){return Math.min(Math.max(e,t),r)}function $i(e){return e.replace(Bu,"").replace(qu,"")}function Mi(e){return e.map(t=>t.text).join("")}function L(e,t,r){if(!t)return e;let n=It(r),s=e.replace(Uu,`${jn}${n}`);return`${n}${s}${jn}`}function It(e){let t=[];return e.fg&&t.push(`38;2;${Pi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Pi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Pi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function et(e,t,r){return pr(e,t,S.success.fg,r)}function hp(e,t,r){return pr(e,t,S.error.fg,r)}function cr(e,t,r){return pr(e,t,S.accent.fg,r)}function _n(e,t,r){return pr(e,t,S.mutedfg.fg,r)}function pr(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${It(s)}${e}${It(n)}`}function Li(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"?kp(s):[];return n?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:wp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function wp(e,t){let r=(e??"").split(qn.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(qn.delimiter):[...r,t].join(qn.delimiter)}function kp(e){return e.command.length>0?e.command:["codex"]}function ji(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 Ie(e){return{columns:Math.max(20,e.width-N.leftWidth-N.rightWidth-N.dividerWidth-lr*2),rows:Math.max(5,e.height-N.topRailHeight-5)}}function Oi(e){return e.length===1||ne(e)||e==="BACKSPACE"||e==="TAB"}function Ct(e){return typeof e=="string"&&new RegExp(`:(?:agent|${$.join("|")})(?:-\\d+)?$`).test(e)}function Fi(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 Un(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Ni(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 vt(e){return _i.includes(e)?"SHIFT_ENTER":null}function Bn(e){return _i.some(t=>t.startsWith(e))}function Wi(e){return e==="ESCAPE"?"\x1B":e.length===1?e:null}var _i=["\x1B[13;2u","\x1B[13;2~","\x1B[27;2;13~","\x1B[27;2;10~"];function qi(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 Oi(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Fi(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 Ui(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Bi(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 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)}
145
+ `).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function Ki(e,t,r,n){return e.map((s,o)=>t?.[o]===s?"":`\x1B[${r+o};${n}H${s}`).join("")}import{spawn as Up}from"node:child_process";import{createHash as Bp}from"node:crypto";import{createServer as Kp,createConnection as Zi}from"node:net";import{openSync as Vp}from"node:fs";import{mkdir as Gp,readFile as Yn,rm as Ne,writeFile as Hp}from"node:fs/promises";import{tmpdir as zp}from"node:os";import tt from"node:path";import{createRequire as Ep}from"node:module";import Tp from"@xterm/headless";var Rp=1e3,yp=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function Gi(e){return new Tp.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:Rp,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function Hi(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Vn(e,t){return new Promise(r=>{e.write(t,r)})}function zi(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 u=l.getCell(d,s);!u||u.getWidth()===0||c.push({text:u.getChars()||" ",style:Sp(u,i+a===o&&d===r.cursorX)})}n.push({segments:Pp(bp(c))})}return n}function Pp(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&vp(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};Qi(r.style)||(s.style=r.style),t.push(s)}return t}function bp(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!Qi(r.style))break;t-=1}return e.slice(0,t)}function Sp(e,t){let r={},n=Vi(e,"fg"),s=Vi(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 Vi(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let n=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return n?s.toString(16).padStart(6,"0"):yp[s]??Ip(s)}function Ip(e){if(e>=16&&e<=231){let t=e-16,r=Math.floor(t/36),n=Math.floor(t%36/6),s=t%6;return[r,n,s].map(Cp).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(r=>r.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function Cp(e){return e===0?0:55+e*40}function vp(e,t){return Kn(e)===Kn(t)}function Kn(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Qi(e){return Kn(e)===""}var Ap=Ep(import.meta.url),xp=/^CTRL_([A-Z])$/,Dp="\x1B[6n",$p="\x1B[c",Mp="\x1B[?u",Lp={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:""},mr=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")Gn(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,Yi(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=jp(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&&Yi(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let r=this.sessions.get(t);r&&(Gn(r),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Gn(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:Op(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??Np().spawn,i=Gi(n),a=s??this.resolveSessionSpec(t,r),l=Me({...this.env,...a.env??{}}),{executable:c,args:d}=Wp(this.shell,a.command,{cwd:a.cwd,env:l}),u=o(c,d,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:a.cwd,env:_p(l)}),p={taskId:t,tabId:r,pty:u,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0,rows:[],renderedScrollbackLines:null,screenDirty:!0};return p.disposables.push(u.onData(f=>{qp(u,f),Vn(p.terminal,f).then(()=>{p.screenDirty=!0,this.onUpdate?.(p.tabId)})})),p.disposables.push(u.onExit(f=>{p.status="exited",Vn(p.terminal,`\r
147
+ [process exited ${f.exitCode}]`).then(()=>{p.screenDirty=!0,this.onUpdate?.(p.tabId)})})),p}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function jp(e){if(e.length===1)return e;let t=Lp[e];if(t!==void 0)return t;let r=xp.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function Yi(e,t){Fp(e.pty,t),Hi(e.terminal,t),e.screenDirty=!0}function Op(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=zi(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function Gn(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function Fp(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Np(){return Ap("node-pty")}function Wp(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[Le(t[0],r),...t.slice(1)].map(Ji).join(" ")}; exec ${Ji(e)} -l`;return{executable:e,args:["-lc",s]}}function Ji(e){return`'${e.replaceAll("'","'\\''")}'`}function _p(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 qp(e,t){for(let r=0;r<Hn(t,Dp);r+=1)e.write("\x1B[1;1R");for(let r=0;r<Hn(t,$p);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<Hn(t,Mp);r+=1)e.write("\x1B[?0u")}function Hn(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 Jn=4,Qp=50;async function ea(e){let t=Xn(e.paths);await Xp(t,e.paths,e.spawnDaemon);let r=await ia(t.socketPath),n=new zn(r,e);return await n.ready(),n}async function ta(e,t={}){let r=Xn(e);await Gp(e.runtimeDir,{recursive:!0}),await Ne(r.socketPath,{force:!0});let n=new Qn(e,t),s=Kp(o=>n.handleConnection(o));await sm(s,r.socketPath),await Hp(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 Ne(r.socketPath,{force:!0}),await Ne(r.pidPath,{force:!0}),n.disposeAll()}async function ra(e){let t=Xn(e);return await gr(t.socketPath)?(await sa(t.socketPath),!0):!1}var zn=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!==Jn)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}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(`
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()}},Qn=class{onShutdown=null;clients=new Set;subscriptions=new Map;updateTimers=new Map;runtime;attachedTabId=null;constructor(t,r){this.runtime=new mr({...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
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)}
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{Et(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(t,n);Et(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:Jn}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);Et(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 om(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(fr)}),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(fr)}),o}handleRuntimeUpdate(t){let r=this.runtime.getViewState(t);for(let n of this.clients)this.subscriptions.get(n)?.mode==="snapshot"&&Et(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)},Qp))}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=Yp(s,r),i=Jp(s.view,r);s.view=r,s.rowKeys=r.rows.map(fr),(o.rows.length>0||i)&&Et(n,{type:"update",tabId:t,patch:o})}}};function Yp(e,t){let r=[];for(let n=0;n<t.rows.length;n+=1){let s=t.rows[n];e.rowKeys[n]!==fr(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 Jp(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 fr(e){return JSON.stringify(e)}function Xn(e){let t=Bp("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:tt.join(zp(),`craig-${t}.sock`),pidPath:tt.join(e.runtimeDir,"pty-daemon.pid")}}async function Xp(e,t,r){if(await Zp(e.socketPath,1e3))return;await gr(e.socketPath)&&(await sa(e.socketPath),await Xi(e.socketPath,1e3)),await gr(e.socketPath)&&(await rm(e),await Xi(e.socketPath,1e3)),await tm(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:a}=em(n),l=Vp(tt.join(t.runtimeDir,"pty-daemon.log"),"a");Up(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 na(e.socketPath))return;await Zn(50)}let o=await Yn(tt.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
153
+ ${o.slice(-2e3)}`:""}`)}async function na(e){let t=await nm(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===Jn}async function Zp(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await na(e))return!0;await Zn(50)}return!1}function em(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=tt.resolve(tt.dirname(t),"..","node_modules",".bin","tsx");return{command:en("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 tm(e){let t=await Yn(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&aa(r))return}await Ne(e.socketPath,{force:!0}),await Ne(e.pidPath,{force:!0})}async function gr(e){let t=await ia(e).catch(()=>null);return t?(t.end(),!0):!1}async function sa(e){await oa(e,{id:1,type:"shutdown"}).catch(()=>null)}async function rm(e){let t=await Yn(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!aa(r)){await Ne(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await Ne(e.socketPath,{force:!0})}}async function nm(e){return oa(e,{id:1,type:"ping"})}function oa(e,t){return new Promise((r,n)=>{let s=Zi(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 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(`
155
+ `);if(c===-1)return;let d=o.slice(0,c);a(),s.end();try{r(JSON.parse(d))}catch(u){n(u instanceof Error?u:new Error(String(u)))}}),s.once("close",()=>a())})}async function Xi(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await gr(e))return;await Zn(50)}}function ia(e){return new Promise((t,r)=>{let n=Zi(e);n.once("connect",()=>t(n)),n.once("error",r)})}function sm(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function Et(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
156
+ `)}catch{}}function aa(e){try{return process.kill(e,0),!0}catch{return!1}}function Zn(e){return new Promise(t=>setTimeout(t,e))}function om(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var es=["Runners","Feature Previews","Error Log","Help"],ca={incrementalCenterPane:"Incremental center pane"};function ts(e,t){return $.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 da(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 ua(e){return re.map(t=>`${h.previews.isEnabled(e,t)?"[x]":"[ ]"} ${ca[t]}`)}function pa(e){return e.message??"Experimental features may change or be removed. Enter toggles."}function ma(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(es.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:hr(t)?e===0?{kind:"runners"}:e===1?{kind:"previews"}:e===2?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function fa(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(re.length-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(!hr(r))return{kind:"noop",state:e};let n=re[e.menuIndex]??re[0],s=!h.previews.isEnabled(t,n);return{kind:"save-enabled",feature:n,enabled:s,state:{...e,message:`${ca[n]} ${s?"enabled":"disabled"}.`}}}function ga(e,t,r,n){if(e.pathEdit)return im({...e,pathEdit:e.pathEdit},t,r);let s=ts(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=$[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:a,value:t.runners?.[a]?.path??""}}}}if(!hr(r))return{kind:"noop",state:e};let o=$[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 im(e,t,r){if(r==="ESCAPE")return{kind:"render",state:la({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(hr(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:la({...e,message:s.length>0?`${h.runners.getProfile(n).displayName} executable saved.`:`${h.runners.getProfile(n).displayName} executable reset to default.`})}}return am(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function la(e){let t={...e};return delete t.pathEdit,t}function hr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
157
+ `}function am(e){return e.length===1&&e>=" "&&e!==""}import At from"node:path";function ha(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 wa="\u{F024B} ",ka="\u{F0DCF} ",Ta="\u25CB",rs="\uEA64",Ra="\uEAFE",ya="\uEBDA",ns="\u25CB",ss="\u25CF",os="\u2713",is="\u2715";function Pa(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 kr="empty",W={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=dm(t,e),n=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=r?t.tasks.filter(T=>T.workspaceId===r.id):t.tasks,o=r?.kind==="project"?s:n?s.filter(T=>T.repoId===n.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,a=i?.type==="project",l=Km(t.tasks),c=mm(e,i),d=pm(e,i,c),u=d.find(T=>T.id===c)??d[0]??{id:"agent",label:"CODEX"},p=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`:bt(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===v?"\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:At.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${At.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:k},leftTree:lm(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>Vm(T,l[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":u.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:f,agent:k},centerTranscript:um(c,e,n,i,e.workspaceBrowser,p,r),tabs:d,rightContext:Bm(n,i),rightInspection:Cm(e,i,p)}}function lm(e,t){let r=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return cm(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}`,u=d?"\u25B8":"\u2022",p=c.title.length>28?`${c.title.slice(0,25)}\u2026`:c.title,f={id:`task:${c.id}`,taskId:c.id,text:`${u} ${p}`,indent:2,selected:d,focused:d&&e.focusedRegion==="tasks"},k=Ea(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(u=>u.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 cm(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 u=t.selectedLeftItemId===`task:${d.id}`,p=u?"\u25B8":"\u2022",f=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,k={id:`task:${d.id}`,taskId:d.id,text:`${p} ${f}`,indent:2,selected:u,focused:u&&t.focusedRegion==="tasks"},T=Ea(d);T&&(k.prBadge=T),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 dm(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 um(e,t,r,n,s,o=null,i=null){if(s){let l=s.query?s.entries.filter(u=>u.name.toLowerCase().includes(s.query.toLowerCase())):s.entries,c=l.length===0?["No matching directories or git repos."]:l.map((u,p)=>{let f=p===s.selectedIndex?"\u25B8":" ",k=u.kind==="repo"?" [git repo]":"/";return`${f} ${u.name}${k}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return oe(["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 oe(["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 oe([`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"?oe([`${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."]):oe([`${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===v&&t.openInspectionKind==="file"?hm(n,o,t.fileScrollOffset):e===v&&t.openInspectionKind==="diff"?wm(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?oe(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):oe(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function pm(e,t,r){let n=t?.ptyTabs.map(o=>({id:o.id,label:fm(o)}))??[];if(!t)return[{id:kr,label:"EMPTY",active:r===kr,focused:e.focusedRegion==="center"&&r===kr}];let s=e.openInspectionKind||r===v?[{id:v,label:gm(e)}]:[];return[...n,...s].map(o=>({...o,active:o.id===r,focused:e.focusedRegion==="center"&&o.id===r}))}function mm(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===v&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??v:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??v:kr}function fm(e){return e.title.toUpperCase()}function gm(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?At.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function hm(e,t,r){if(!e)return oe(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return oe(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=va(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:""},...km(n.lines,r,s)]}function wm(e,t,r){if(!e)return oe(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return oe(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=va(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:""},...Tm(n.lines,r,s)]}function oe(e){return e.map(t=>({text:t}))}function km(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:W.lineNumber}},{text:" \u2502 ",style:{fg:W.gutter}},...as(o,r)],tone:"default"}})}function Tm(e,t,r){let n=Rm(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>ym(o,r))}function Rm(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 ym(e,t){let r=ba(e.oldNumber),n=ba(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:W.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:W.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?bm(as(e.text,t),o.bg,o.fallbackFg):as(e.text,t),l=o?{fg:W.lineNumber,bg:o.bg}:{fg:W.lineNumber},c=o?{fg:W.gutter,bg:o.bg}:{fg:W.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:o!==null}}function ba(e){return e===null?" ":String(e).padStart(4," ")}function va(e){let t=At.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function as(e,t){return t==="diff"?Pm(e):t==="markdown"?Sm(e):t==="json"?ls(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?ls(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 Pm(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:W.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:W.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:W.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:W.diffMeta}}]:[{text:e}]}function bm(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:W.markup,bold:!0}}]:ls(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function ls(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:Im(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function Im(e){return e.startsWith("//")||e.startsWith("/*")?{fg:W.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:W.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:W.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:W.markup}:{fg:W.keyword}}function Cm(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"?Aa(t.repoTargets??[]):s?.pullRequest??(t?D(t):null),i=[vm(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=$a(e,t),l=cs(e,r),c=$m([{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,..._m(e,r)]}:{title:"",rows:[...i,...cs(e,r)]}}function vm(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=ds(t),i=us(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function Sa(e){return[{text:" "},ds(e),{text:" "},us(e)]}function Ea(e){if(e.type==="project"&&e.repoTargets?.length){let r=Aa(e.repoTargets);return r?Sa(r):null}let t=D(e);return t?.number?Sa(t):null}function Aa(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=Am(r);return{number:-1,status:Em(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 Em(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 Am(e){let t=e.map(r=>xa(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 ds(e){return!e||!e.number?{text:Ta,style:{fg:"565f89"}}:e.status==="merged"?{text:Ra,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:ya,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:rs,style:{fg:"565f89"}}:{text:rs,style:{fg:"9ece6a"}}}function us(e){return e?.aggregateReadiness?Ia(e.aggregateReadiness):Ia(xa(e))}function Ia(e){return e==="failed"?{text:is,style:{fg:"f7768e"}}:e==="pending"?{text:ss,style:{fg:"e0af68"}}:e==="success"?{text:os,style:{fg:"9ece6a"}}:{text:ns,style:{fg:"565f89"}}}function xa(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")?Da(e)?"failed":xm(e)?"success":"pending":"pending"}function xm(e){return!!(e.mergeable&&!e.draft&&!Da(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Da(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function $a(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return Dm(e,t);let r=D(t),n=La("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 wr=32;function Dm(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 u=i.failureReason?i.failureReason.slice(0,14):i.status,p=wr-u.length-1,f=c.length>p?c.slice(0,p-1)+"\u2026":c,k=wr-f.length-u.length;r.push({id:`project-review:${i.repoId}`,text:f+" ".repeat(Math.max(1,k))+u,selected:a,focused:l,muted:!0})}else{let d=ds(i.pullRequest),u=us(i.pullRequest),p=`${d.text} ${u.text}`,f=wr-p.length-1,k=c.length>f?c.slice(0,f-1)+"\u2026":c,T=wr-k.length-p.length,A=k+" ".repeat(Math.max(1,T));r.push({id:`project-review:${i.repoId}`,text:A+p,selected:a,focused:l,segments:[{text:A},{...d,text:d.text},{text:" "},{...u,text:u.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(...La("target",o.branch,o.pullRequest))),r}function Ma(e,t,r=null){return 3+$a(e,t).length+cs(e,r).length}function La(e,t,r){let n=u=>`${e}-${u}`;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:Lm(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${ja(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(jm)):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((u,p)=>Om(u,n(`comment:${p}`))))),s}function $m(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 Lm(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function ja(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 jm(e){let{icon:t,color:r}=Nm(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," ")} ${Wm(e.status)}`,color:r,muted:!1}}function Om(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${ja(e.createdAt)}`:"",s=Fm(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 Fm(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 Nm(e){switch(e){case"success":return{icon:os,color:"9ece6a"};case"pending":return{icon:ss,color:"e0af68"};case"failed":return{icon:is,color:"f7768e"};case"skipped":return{icon:ns,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function Wm(e){return e==="success"?"passing":e==="failed"?"failing":e}function _m(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=ps(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,u=l.kind==="directory"?e.collapsedFileTreePaths.includes(l.path)?wa:ka:ha(l.label),p=l.kind==="directory"?"7aa2f7":Pa(l.label),f=" ".repeat(l.depth),k=p?{text:u,style:{fg:p}}:{text:u},T=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},A=[{text:f},k,T];return{id:l.path,text:`${f}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:A}})]}function ps(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 cs(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(qm(t))return Um(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=>Oa(o,e,t))))}return r}function qm(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Um(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=>Oa(c,e,t,s.length+1))))}}return r}function Oa(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:h.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:At.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function Km(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Vm(e,t){return{name:h.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function Fa(e,t,r,n){let s=Nn(e,t,{centerOnly:n});return Gm(r,s)?{output:Ki(s.rows,r.rows,s.row,s.column),region:s}:null}function Gm(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}import{appendFile as Hm,mkdir as zm,readFile as Qm}from"node:fs/promises";import Ym from"node:path";var Na=80,ms=async(e,t)=>{await zm(Ym.dirname(e.errorLogFile),{recursive:!0}),await Hm(e.errorLogFile,Jm(t),"utf8")},Wa=async(e,t)=>{try{await ms(e,t)}catch{}},fs=async(e,t=Na)=>{try{let n=(await Qm(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(Xm(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},_a=async(e,t=Na)=>fs(e,t);function Jm(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 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!==`
162
+ `}function Xm(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var rt={appendErrorLog:ms,appendErrorLogBestEffort:Wa,readErrorLog:fs,readRecentErrorLines:_a};var Zm=["tasks","center","inspector"];function ef(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 hs(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return ks({...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 ks(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return mi(t)?w({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):w({state:e});if(e.fileSearchQuery!==null)return ef(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"&&(rr(e.selectedLeftItemId)||nr(e.selectedLeftItemId)))return w({state:{...e,selectedRunner:tr(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return qa(e,1);if(t==="SHIFT_TAB"||t==="[")return qa(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===v?Ce(e,-1,r):hs(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===v?Ce(e,1,r):hs(e,1,r);if(t==="PAGE_UP")return Ce(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Ce(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Ce(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Ce(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??$,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=cf(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"&&bt(e.selectedLeftItemId)&&e.selectedTaskId)return w({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Ti(e.selectedLeftItemId)&&e.selectedWorkspaceId)return w({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Ka(e.activeTab,r.ptyTabIds??[]))return w({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return gs(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return Ua(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return gs(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return Ua(e,1)}if(ne(t)){if(e.focusedRegion==="tasks"&&(rr(e.selectedLeftItemId)||nr(e.selectedLeftItemId))){let n=Dn(e.selectedLeftItemId),s=$n(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"&&bt(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return w({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Ze(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Ka(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return w({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Ze(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===v)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:nf({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return w({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:v,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:v,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 Ce(e,t,r){if(t===0)return w({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?Va(e,t,r):e.inspectionMode==="review"?Ba(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):w({state:e});if(e.focusedRegion==="center"&&e.activeTab===v){if(e.openInspectionKind==="file")return Ba(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return sf(e,t,r)}return w({state:e})}function qa(e,t){return Tr(e,"focusedRegion",Zm,t)}function gs(e,t,r){let n=Tr(e,"activeTab",r&&r.length>0?r:df(e),t);return!n.changed||hi(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Ze(n.state.activeTab)??n.state.preferredPtyTabKind}}}function hs(e,t,r){if(e.focusedRegion==="tasks")return tf(e,t,r.leftItemIds);if(e.focusedRegion==="center")return gs(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Va(e,t,r);if(r.projectTargetIds?.length){let s=ws(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=ws(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:v,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:Tr(e,"selectedActionId",li,t)}return Tr(e,"selectedActionId",En,t)}function tf(e,t,r){let n=ws(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=xn(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=Dn(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=$n(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function rf(e,t){if(e.inspectionMode===t)return w({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?v: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 Ua(e,t){return rf(e,lf(e.inspectionMode,An,t))}function Va(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=he(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?v:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function nf(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 Ba(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=he(e[t]+r,0,o);return i===e[t]?w({state:e}):w({state:{...e,[t]:i,actionMessage:null},changed:!0})}function sf(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return of(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=he(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=he(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:v,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:v,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=he(i,0,o);return c===e.diffScrollOffset?w({state:e}):w({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function of(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=he(e.diffScrollOffset+t,0,o),a=af(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 af(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function Tr(e,t,r,n){let s=r.indexOf(e[t]),o=he(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 ws(e,t,r,n,s=!1){if(r.length===0)return w({state:e});let o=r.indexOf(e[t]??r[0]??""),i=he(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 lf(e,t,r){let n=t.indexOf(e);return t[he(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 Ka(e,t){return t.includes(e)}function cf(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Ze(e.activeTab)??e.preferredPtyTabKind}function df(e){return[e.selectedPtyTabId,e.openInspectionKind?v:null].filter(t=>typeof t=="string")}function he(e,t,r){return Math.min(r,Math.max(t,e))}var Ga=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 X(n.paths,e.selectedTaskId),i=t??uf(o,e.activeTab,e.preferredPtyTabKind),a=Ya(o,i,r??void 0,n.config),l={...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id};return await P(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"}`}}},Ha=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 X(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 P(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}`}}},za=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{let n=await X(t.paths,r);!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab||await P(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 X(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;o&&await P(t.paths,{...s,selectedPtyTabId:o.id})}),{...e,selectedPtyTabId:r.id};let n=Ya(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{let s=await X(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;if(o){await P(t.paths,{...s,selectedPtyTabId:o.id});return}await P(t.paths,{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function uf(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Ya(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 u=new Date().toISOString(),p=r&&r!==e.runner?r:void 0;return{id:d,kind:t,...p?{runner:p}:{},title:c===1?i:`${i} ${c}`,command:t==="agent"?h.runners.buildCommand(s,void 0,n):[],createdAt:u,updatedAt:u}}var nt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Ja=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=Me();await y(Le(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 nt(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}},Xa=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},Za=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 X(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}`}}},el=async(e,t)=>{await t.taskService.prs.discoverOrRefreshMany(t.paths,e)},tl=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await rt.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var rl=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 nl=async(e,t,r)=>{let n=h.runners.setRunnerEnabled(r.config,e,t);return await h.save(r.paths,n),n},sl=async(e,t,r)=>{let n=h.runners.setRunnerPath(r.config,e,t);return await h.save(r.paths,n),n},ol=async(e,t,r)=>{let n=h.previews.setEnabled(r.config,e,t);return await h.save(r.paths,n),n};var pf=250;function we(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function We(e,t){return ge(t,e.ptyRuntime.getViewState(xt(e,t)))}function xt(e,t){let r=we(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 We(e,Ri(t,e.model))}function il(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 al(e,t,r){return il(e,t,r?{tone:"success",message:r}:null)}function j(e,t,r){return il(e,t,{tone:"error",message:r})}function O(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return rt.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function M(e,t){if(!e.uiStateFile)return;e.runtimeState=ui(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Te({uiStateFile:e.uiStateFile},r),()=>Te({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function mf(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function U(e){return{paths:e.paths,config:e.config,taskService:C,workspaceService:z,queueTaskMutation:t=>mf(e,t)}}function Ts(e,t){let r=we(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?ps(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:Fe(e.model),centerTabIds:ki(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:Ma(t,r,s),pageRows:Math.max(5,ee(e.activeTerminal.width,e.activeTerminal.height).height-N.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function ll(e,t){await za(t,U(e))}async function B(e){e.model=await Se(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 Rr(e,t){let r=++e.inspectionRefreshSequence,n=Mn(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 Yo(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await Se(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)},M(e,e.state.shell),e.render())}function cl(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)&&Rr(e,r).catch(n=>{let s=O(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()})},pf))}function dl(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=Ce(e.state.shell,r,Ts(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:g(e,n.state)},M(e,e.state.shell),e.render(),Rr(e,e.state.shell).catch(s=>{let o=O(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)},M(e,e.state.shell),e.render()}},16)))}function Rs(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function ys(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 pl(e){ys(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.render())})}async function ml(e,t){let r=g(e,t),n=we(e.model.tasks,r),s=xt(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 ge(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,Ie(ee(e.activeTerminal.width,e.activeTerminal.height)));return ge({...r,inputMode:"control"},i)}function fl(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=we(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 ul(e,n),await B(e),s=n.selectedPtyTabId)}n&&!s&&(n=await ul(e,n),await B(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:ge({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},M(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,Ie(ee(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ct(s),e.lastTerminalKey=null,e.state={mode:"main",shell:ge({...o,inputMode:"terminal"},i)},M(e,e.state.shell)}catch(r){let n=O(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Ct(t.selectedPtyTabId)&&(await ff(e,t.selectedTaskId,n).catch(()=>{}),await B(e).catch(()=>{})),e.state={mode:"main",shell:j(e,pi(g(e,t),n),n)},M(e,e.state.shell)}e.render()}async function ff(e,t,r){await Xa(t,r,U(e))}async function gl(e,t,r,n){let s=g(e,t),{nextShell:o}=await Ga(s,r,n,U(e));return await B(e),g(e,{...s,...o})}async function hl(e,t){let r=g(e,t),{closedTab:n,nextShell:s}=await Ha(r,U(e));return e.ptyRuntime.disposeSession(n.id),await B(e),g(e,{...r,...s})}async function wl(e,t){let r=g(e,t),n=Fe(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await Za(r,U(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await B(e),g(e,{...r,...i,selectedLeftItemId:gf(n,Fe(e.model),s)})}async function kl(e,t){let r=g(e,t),{nextShell:n}=await rl(r,U(e));return await B(e),g(e,{...r,...n})}async function ul(e,t){return Qa(t,U(e))}function yr(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:We(e,e.state.shell)},e.render())},16))}function gf(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 Tl(e){if(!(e.prPollInFlight||e.state.mode!=="main")){e.prPollInFlight=!0;try{if(await el(e.model.tasks,U(e)),e.lastBackgroundPrPollError=null,e.state.mode!=="main")return;e.model=await Se(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,tl("background PR polling",t,U(e)))}finally{e.prPollInFlight=!1}}}async function Rl(e,t){let r=g(e,t),n=we(e.model.tasks,r),s=null,o=null;if(n?.type==="project"&&n.repoTargets?.length){let i=await C.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await B(e);let a=i.synced+i.discovered+i.notFound;o=`Refreshed ${i.synced}/${a} targets`}else{let{disposition:i,task:a}=await C.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await B(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${D(a)?.requiredChecks.length??0} reported`)}return g(e,{...al(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}import Rf from"node:path";import{readdir as hf,stat as wf}from"node:fs/promises";import yl from"node:path";async function kf(e){let t=await hf(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=yl.join(e,n.name);r.push({name:n.name,path:s,kind:await Tf(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 Pl(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function bl(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 Pr(e,t){let r=await kf(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 Tf(e){let t=yl.join(e,".git");return await wf(t).catch(()=>null)!==null}function Sl(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function Il(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function yf(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 Ja(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,U(e));n=s.task,await B(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??ji(n,"agent"),Ie(ee(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ct(o.selectedPtyTabId),e.state={mode:"main",shell:ge(o,i)},M(e,e.state.shell)}catch(s){s instanceof nt&&(n=s.task);let o=O(e,"create task",s,"Failed to create task.");n&&!(s instanceof nt)?(await P(e.paths,{...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o}).catch(()=>{}),await B(e).catch(()=>{})):n&&(await P(e.paths,{...n,lastFailureReason:o}).catch(()=>{}),await B(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 Pf(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(ne(t)){yf(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:tr(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}fi(t)&&(e.state={mode:"main",shell:g(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function bf(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=Pl(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"){Pr(e,Rf.dirname(r.cwd)).catch(s=>{let o=O(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"||ne(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){Pr(e,s.path).catch(i=>{let a=O(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}=U(e);o.addWorkspace(e.paths,s.path).then(async i=>{await B(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},M(e,e.state.shell),e.render()}).catch(i=>{let a=O(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 Sf(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=ma(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;If(e,n)}}}async function If(e,t){let r;try{r=await rt.readRecentErrorLines(e.paths)}catch(n){let s=O(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 Cf(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=ga(Sl(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"?nl(r.runner,r.enabled,U(e)):sl(r.runner,r.path,U(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=O(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:j(e,g(e,e.state.shell),o),runnerOptions:{...Sl(e),message:o}},e.render()})}function vf(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=fa(Il(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}ol(r.feature,r.enabled,U(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=O(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:j(e,g(e,e.state.shell),s),previewOptions:{...Il(e),message:s}},e.render()})}}function Cl(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){Pf(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){bf(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){Af(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=ks(e.state.shell,r,Ts(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)},M(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)},M(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&ne(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=vt(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(Ef(e,r))return;e.lastTerminalKey=Oi(r)?{key:r,at:Date.now()}:null;let o=Fi(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){yr(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)},M(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){Pr(e,e.workspaceRoot).catch(s=>{let o=O(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){gl(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{Ps(e,s)}).catch(s=>{let o=O(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){hl(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=O(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){Rl(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=O(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=we(e.model.tasks,n.state),o=s?D(s)?.url??null:null;o?bl(o).catch(i=>{let a=O(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){wl(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=O(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){kl(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=O(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)},M(e,e.state.shell),e.render(),e.state.shell.focusedRegion==="tasks"){cl(e,e.state.shell);return}Rr(e,e.state.shell).catch(s=>{let o=O(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)},ll(e,e.state.shell).catch(()=>{}),M(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"){Sf(e,r);return}if(e.state.variant==="runners"){Cf(e,r);return}if(e.state.variant==="previews"){vf(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||ne(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"||ne(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(ne(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;ml(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},M(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=O(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:j(e,g(e,e.state.shell),i)},M(e,e.state.shell),e.render()})}):pl(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 vl(e,t){let r=Ui(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=vt(o);if(i){Al(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(Bn(o)){e.pendingTerminalKeySequence.raw=o,El(e);return}br(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"})},M(e,e.state.shell),e.render();return}let n=Ni(r);if(n!==0){yr(e,n);return}let s=vt(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),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}
164
+ `&&(e.suppressTerminalEnterOnAttach=!1),qi(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function Ef(e,t){if(e.pendingTerminalKeySequence){let r=Wi(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=vt(n);if(s)return Al(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(Bn(n))return e.pendingTerminalKeySequence.raw=n,El(e),!0}return br(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>br(e),30)},!0)}function El(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>br(e),30))}function br(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function Al(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function xl(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){dl(e,Un(t));return}let r=Un(t);r!==0&&yr(e,r)}function Af(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=xf(import.meta.url),$f=Df("terminal-kit"),Mf=$f.terminal;function bs(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function Dl(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}async function $l(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=ce(t),n=await h.load(r),s=h.runners.getEnabled(n),o=e.uiStateFile?await qe({uiStateFile:e.uiStateFile}):null,i=await Se(t,void 0,s),a=Pt(di(o,n),i);i=await Se(t,a,s);let l={current:i},c=()=>{},d={workspaceRoot:t,onUpdate:()=>c(),resolveSessionSpec:(p,f)=>Li(l.current,f,t)},u=e.ptyRuntime??await ea({...d,paths:r,viewUpdateMode:h.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot"});return new Promise(p=>{let f=e.terminal??Mf,k=null,T=null,A=null,m={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Pt(a,i)},get model(){return l.current},set model(R){l.current=R},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:u,resolve:p,render:()=>{},exit:R=>p(R)};c=()=>{m.state.mode==="main"&&(m.ptyRenderTimer||(m.ptyRenderTimer=setTimeout(()=>{if(m.ptyRenderTimer=null,m.state.mode==="main"){let R=We(m,m.state.shell);if(m.state={mode:"main",shell:R},!h.previews.isEnabled(m.config,"incrementalCenterPane")||!A||!T){m.render();return}let ke=ee(f.width,f.height),st={...A,terminal:R.terminal},ve=Fa(ke,st,T,R.centerZoomed);if(!ve){m.render();return}ve.output.length>0&&f.noFormat(ve.output),A=st,T=ve.region,f.hideCursor(!0)}},h.previews.isEnabled(m.config,"incrementalCenterPane")?0:50)))},m.render=()=>{fl(m);let R=m.state;m.ptyRuntime.setViewedTab?.(R.mode==="main"?xt(m,R.shell):null);let te=ee(f.width,f.height),ke;if(R.mode==="main"){let st=Ca(g(m,R.shell),m.model),ve=vi(te,st,{centerOnly:R.shell.centerZoomed,focusFlashActive:m.focusFlashUntil!==null&&Date.now()<m.focusFlashUntil});ke=ve.frame,A=st,T=ve.center}else ke=R.variant==="boot"?bi(te,{menuIndex:R.menuIndex,optionsMessage:R.optionsMessage,versionText:m.versionText,updateText:m.updateText}):R.variant==="pause"?Si(te,{menuIndex:R.menuIndex,optionsMessage:R.optionsMessage,versionText:m.versionText,updateText:m.updateText}):R.variant==="options"?dr(te,{menuIndex:R.menuIndex,optionsMenuItems:es}):R.variant==="runners"?dr(te,{menuIndex:bs(R).menuIndex,optionsMenuItems:ts(m.config,bs(R)),optionsMessage:da(bs(R)),optionsSubtitle:"Runners"}):R.variant==="previews"?dr(te,{menuIndex:Dl(R).menuIndex,optionsMenuItems:ua(m.config),optionsMessage:pa(Dl(R)),optionsSubtitle:"Feature Previews - Experimental"}):R.variant==="error-log"?Ci(te,{errorLogPath:R.errorLog?.path??r.errorLogFile,errorLogLines:R.errorLog?.lines??[]}):Ii(te),A=null,T=null;m.pendingClear&&(f.moveTo(1,1),f.eraseDisplayBelow(),m.pendingClear=!1,k=null),f.noFormat(Bi(ke,k)),k=ke,f.hideCursor(!0)};let ie=R=>Cl(m,R),pe=R=>vl(m,R),b=R=>xl(m,R),ae=()=>{process.stdout.off("resize",Dt),process.off("SIGCONT",$t),f.removeListener("key",ie),f.removeListener("unknown",pe),f.removeListener("mouse",b),m.scrollRenderTimer&&(clearTimeout(m.scrollRenderTimer),m.scrollRenderTimer=null),m.inspectionScrollRenderTimer&&(clearTimeout(m.inspectionScrollRenderTimer),m.inspectionScrollRenderTimer=null),m.leftNavInspectionTimer&&(clearTimeout(m.leftNavInspectionTimer),m.leftNavInspectionTimer=null),m.pendingTerminalKeySequence&&(clearTimeout(m.pendingTerminalKeySequence.timer),m.pendingTerminalKeySequence=null),m.ptyRenderTimer&&(clearTimeout(m.ptyRenderTimer),m.ptyRenderTimer=null),m.footerToastTimer&&(clearTimeout(m.footerToastTimer),m.footerToastTimer=null),m.focusFlashTimer&&(clearTimeout(m.focusFlashTimer),m.focusFlashTimer=null),m.prPollTimer&&(clearInterval(m.prPollTimer),m.prPollTimer=null),m.ptyRuntime.disposeAll(),f.grabInput(!1),f.hideCursor(!1),f.fullscreen(!1)};m.exit=R=>{ae(),p(R)};let Dt=()=>{Rs(m),m.state.mode==="main"&&m.state.shell.inputMode==="terminal"&&(m.ptyRuntime.resize(Ie(ee(f.width,f.height))),m.state={mode:"main",shell:We(m,m.state.shell)}),m.render()},$t=()=>{Rs(m),m.state.mode==="main"&&m.state.shell.inputMode==="terminal"&&(m.ptyRuntime.resize(Ie(ee(f.width,f.height))),m.state={mode:"main",shell:We(m,m.state.shell)}),m.render()};process.stdout.on("resize",Dt),process.on("SIGCONT",$t),f.grabInput(!0),m.inputCaptureMode="control",f.hideCursor(!0),f.fullscreen(!0),f.on("key",ie),f.on("unknown",pe),f.on("mouse",b),m.prPollTimer=setInterval(()=>{Tl(m)},(m.config.github?.watchIntervalSeconds??5)*1e3),h.version.checkForUpdate().then(R=>{R.updateAvailable&&R.latest&&(m.updateText=`Update available: v${R.latest}`,m.render())}),m.bootHydrationReady=ys(m).catch(()=>{}),m.render()})}async function Lf(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??process.cwd(),a=ce(i);return await ta(a),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??process.cwd(),a=ce(i);return await ra(a),0}let e=Fs(process.argv.slice(2)),t=process.cwd(),r=ce(t),n={paths:r};if(e.mode==="interactive")return await $l({uiStateFile:r.uiStateFile,workspaceRoot:r.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await Ho(e.command,n),o=zo(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 Df=await xf();process.exit(Df);
166
+ `),1}}var jf=await Lf();process.exit(jf);