craig-cli 0.12.2 → 0.12.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +4 -2
  2. package/dist/cli.js +63 -63
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- var pp=Object.defineProperty;var Ar=(e,t)=>{for(var r in t)pp(e,r,{get:t[r],enumerable:!0})};import H from"node:path";function re(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"),commandsDir:H.join(t,"commands"),eventsDir:H.join(t,"events"),orchestrationDir:H.join(t,"orchestration"),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")}}import{readFile as yp}from"node:fs/promises";import{randomUUID as mp}from"node:crypto";import{open as fp,readFile as gp,rename as hp,rm as wp}from"node:fs/promises";import Hn from"node:path";async function M(e,t){let r=Hn.dirname(e),n=Hn.join(r,`.${Hn.basename(e)}.${process.pid}.${Date.now()}.${mp()}.tmp`),s=await fp(n,"w");try{let o=`${JSON.stringify(t,null,2)}
3
- `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await hp(n,e)}catch(o){throw await s.close().catch(()=>{}),await wp(n,{force:!0}).catch(()=>{}),o}}async function Er(e){try{let t=await gp(e,"utf8");return JSON.parse(t)}catch(t){if(kp(t))return null;throw t}}function kp(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function yt(e){try{let t=await yp(e.uiStateFile,"utf8"),r=JSON.parse(t);return Tp(r,e.uiStateFile)}catch(t){if(bp(t))return null;throw t}}async function Me(e,t){await M(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Dr(){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 Tp(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")||!kt(e,"inputMode")||!kt(e,"focusedRegion")||!kt(e,"activeTab")||!kt(e,"inspectorSection")||!kt(e,"inspectionMode")||!xr(e,"openInspectionKind")||!xr(e,"selectedFileTreePath")||!xr(e,"selectedFilePath")||!xr(e,"selectedDiffPath")||!Rp(e,"collapsedFileTreePaths")||!kt(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 kt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function xr(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Rp(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function bp(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var zn={};Ar(zn,{RUNNER_IDS:()=>L,assertEnabled:()=>zi,buildCommand:()=>Xi,getConfiguredProfile:()=>Or,getDefault:()=>Hi,getDisplayName:()=>Ji,getEnabled:()=>$r,getProfile:()=>Tt,isRunnerType:()=>Nr,parse:()=>Yi,setRunnerEnabled:()=>Qi,setRunnerPath:()=>Zi});var L=["codex","cursor","claude"];var Gi={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 Tt=e=>Gi[e];var Or=(e,t={})=>{let r=Tt(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var $r=(e={})=>L.filter(t=>e.runners?.[t]?.enabled!==!1);var Hi=(e={})=>{let t=$r(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 zi=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var Nr=e=>L.includes(e);var Yi=e=>{if(!e||e.length===0)return"codex";if(!Nr(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${L.join(", ")}.`);return e};var Ji=e=>Tt(e).displayName;var Xi=(e,t,r={})=>{let n=[Or(e,r).executable];return t&&t.length>0&&n.push(t),n};var Qi=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var Zi=(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 Yn={};Ar(Yn,{PREVIEW_FEATURE_IDS:()=>ge,isEnabled:()=>ea,setEnabled:()=>ta});var ge=["incrementalCenterPane","agentActivityIndicators","agentOrchestration"];function ea(e,t){return e.previews?.[t]===!0}function ta(e,t,r){return{...e,previews:{...e.previews,[t]:r}}}import{mkdir as Pp,readFile as Sp,writeFile as vp}from"node:fs/promises";import Ip from"node:path";var Cp=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",ra=async e=>{try{return await Sp(e,"utf8")}catch(t){if(Cp(t))return null;throw t}},na=async(e,t)=>{await Pp(Ip.dirname(e),{recursive:!0}),await vp(e,t,"utf8")};var Mr=(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(!L.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${L.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(!ge.includes(n))throw new Error(`Craig config at ${t} is invalid. "previews.${n}" is not supported. Expected one of: ${ge.join(", ")}.`);if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${n}" must be a boolean.`)}}return r};var Jn=async(e,t={readConfigFile:ra})=>{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 Mr(n,e.configFile)};var Xn=async(e,t,r={writeConfigFile:na})=>{Mr(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
4
- `)};var Qn={};Ar(Qn,{checkForUpdate:()=>sa,getCurrent:()=>Lr});var Lr=()=>{try{return"0.12.2"}catch{return"unknown"}};var Ap="https://registry.npmjs.org/craig-cli/latest",Ep=3600*1e3,xp={value:null},Dp=(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},sa=async(e={fetch:globalThis.fetch,getCurrent:Lr,cache:xp})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<Ep)return e.cache.value.result;let n=null;try{let o=await e.fetch(Ap,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&Dp(n,t)};return e.cache.value={result:s,cachedAt:r},s};var h={load:Jn,save:Xn,previews:Yn,runners:zn,version:Qn};var oa={CLI_USAGE:2,INPUT_REQUIRED:2,WORKSPACE_CONTEXT_NOT_FOUND:3,WORKSPACE_CONTEXT_INVALID:4,WORKSPACE_NOT_FOUND:3,WORKSPACE_RECORD_INVALID:2,TASK_CONTEXT_NOT_FOUND:3,TASK_CONTEXT_AMBIGUOUS:4,TASK_CONTEXT_CONFLICT:4,TASK_NOT_FOUND:3,TASK_RECORD_INVALID:2,REPO_NOT_FOUND:3,REPO_RECORD_INVALID:2,PR_REPOSITORY_MISMATCH:4,PR_BRANCH_MISMATCH:4,EXTERNAL_DEPENDENCY_FAILED:5,OPERATION_TIMEOUT:6,OPERATION_CANCELLED:6,EVENT_CURSOR_INVALID:2,EVENT_CURSOR_EXPIRED:4,EVENT_JOURNAL_CORRUPT:2,COMMAND_NOT_FOUND:3,COMMAND_RECORD_INVALID:2,COMMAND_STATE_CONFLICT:4,PARTIAL_RESULT:7,INTERNAL_ERROR:1},f=class extends Error{code;exitCode;retryable;details;constructor(t,r,n){super(r,n.cause===void 0?void 0:{cause:n.cause}),this.name="CraigError",this.code=t,this.exitCode=oa[t],this.retryable=n.retryable??!1,this.details=n.details??{}}};function Zn(e){return e instanceof f?e:new f("INTERNAL_ERROR",e instanceof Error?e.message:"Unknown Craig error",{cause:e})}import{appendFile as Op,mkdir as $p,readFile as Np}from"node:fs/promises";import Mp from"node:path";var ia=80,es=async(e,t)=>{await $p(Mp.dirname(e.errorLogFile),{recursive:!0}),await Op(e.errorLogFile,Lp(t),"utf8")},aa=async(e,t)=>{try{await es(e,t)}catch{}},ts=async(e,t=ia)=>{try{let n=(await Np(e.errorLogFile,"utf8")).trimEnd().split(`
5
- `).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(_p(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},la=async(e,t=ia)=>ts(e,t);function Lp(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(`
2
+ var Tp=Object.defineProperty;var Dr=(e,t)=>{for(var r in t)Tp(e,r,{get:t[r],enumerable:!0})};import Y from"node:path";function ne(e){let t=Y.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:Y.join(t,"index.json"),reposDir:Y.join(t,"repos"),workspacesDir:Y.join(t,"workspaces"),sessionsDir:Y.join(t,"sessions"),runtimeDir:Y.join(t,"runtime"),uiStateFile:Y.join(t,"runtime","ui-state.json"),tasksDir:Y.join(t,"tasks"),jobsDir:Y.join(t,"jobs"),commandsDir:Y.join(t,"commands"),eventsDir:Y.join(t,"events"),orchestrationDir:Y.join(t,"orchestration"),logsDir:Y.join(t,"logs"),errorLogFile:Y.join(t,"logs","errors.log"),artifactsDir:Y.join(t,"artifacts"),worktreesDir:Y.join(t,"worktrees"),configFile:Y.join(t,"config.json")}}import{readFile as Cp}from"node:fs/promises";import{randomUUID as Rp}from"node:crypto";import{open as bp,readFile as Pp,rename as Sp,rm as vp}from"node:fs/promises";import Yn from"node:path";async function L(e,t){let r=Yn.dirname(e),n=Yn.join(r,`.${Yn.basename(e)}.${process.pid}.${Date.now()}.${Rp()}.tmp`),s=await bp(n,"w");try{let i=`${JSON.stringify(t,null,2)}
3
+ `;await s.writeFile(i,"utf8"),await s.sync(),await s.close(),await Sp(n,e)}catch(i){throw await s.close().catch(()=>{}),await vp(n,{force:!0}).catch(()=>{}),i}}async function Or(e){try{let t=await Pp(e,"utf8");return JSON.parse(t)}catch(t){if(Ip(t))return null;throw t}}function Ip(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function Rt(e){try{let t=await Cp(e.uiStateFile,"utf8"),r=JSON.parse(t);return Ap(r,e.uiStateFile)}catch(t){if(xp(t))return null;throw t}}async function Fe(e,t){await L(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Mr(){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 Ap(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")||!Tt(e,"inputMode")||!Tt(e,"focusedRegion")||!Tt(e,"activeTab")||!Tt(e,"inspectorSection")||!Tt(e,"inspectionMode")||!$r(e,"openInspectionKind")||!$r(e,"selectedFileTreePath")||!$r(e,"selectedFilePath")||!$r(e,"selectedDiffPath")||!Ep(e,"collapsedFileTreePaths")||!Tt(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 Tt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function $r(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Ep(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function xp(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Jn={};Dr(Jn,{RUNNER_IDS:()=>_,assertEnabled:()=>Zo,buildCommand:()=>ra,getConfiguredProfile:()=>Nr,getDefault:()=>Qo,getDisplayName:()=>ta,getEnabled:()=>Lr,getProfile:()=>bt,isRunnerType:()=>_r,parse:()=>ea,setRunnerEnabled:()=>na,setRunnerPath:()=>sa});var _=["codex","cursor","claude"];var Xo={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 bt=e=>Xo[e];var Nr=(e,t={})=>{let r=bt(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var Lr=(e={})=>_.filter(t=>e.runners?.[t]?.enabled!==!1);var Qo=(e={})=>{let t=Lr(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 Zo=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var _r=e=>_.includes(e);var ea=e=>{if(!e||e.length===0)return"codex";if(!_r(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${_.join(", ")}.`);return e};var ta=e=>bt(e).displayName;var ra=(e,t,r={})=>{let n=[Nr(e,r).executable];return t&&t.length>0&&n.push(t),n};var na=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var sa=(e,t,r)=>{let n=e.runners?.[t]??{},{path:s,...i}=n;return{...e,runners:{...e.runners??{},[t]:r!=null?{...n,path:r}:i}}};var Xn={};Dr(Xn,{PREVIEW_FEATURE_IDS:()=>ge,isEnabled:()=>ia,setEnabled:()=>oa});var ge=["incrementalCenterPane","agentActivityIndicators","agentOrchestration"];function ia(e,t){return e.previews?.[t]===!0}function oa(e,t,r){return{...e,previews:{...e.previews,[t]:r}}}import{mkdir as Dp,readFile as Op,writeFile as $p}from"node:fs/promises";import Mp from"node:path";var Np=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",aa=async e=>{try{return await Op(e,"utf8")}catch(t){if(Np(t))return null;throw t}},la=async(e,t)=>{await Dp(Mp.dirname(e),{recursive:!0}),await $p(e,t,"utf8")};var jr=(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 i=s;if(i.enabled!==void 0&&typeof i.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${n}.enabled" must be a boolean.`);if(i.path!==void 0&&(typeof i.path!="string"||i.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(!ge.includes(n))throw new Error(`Craig config at ${t} is invalid. "previews.${n}" is not supported. Expected one of: ${ge.join(", ")}.`);if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${n}" must be a boolean.`)}}return r};var Qn=async(e,t={readConfigFile:aa})=>{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 jr(n,e.configFile)};var Zn=async(e,t,r={writeConfigFile:la})=>{jr(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
4
+ `)};var es={};Dr(es,{checkForUpdate:()=>ca,getCurrent:()=>Fr});var Fr=()=>{try{return"0.12.5"}catch{return"unknown"}};var Lp="https://registry.npmjs.org/craig-cli/latest",_p=3600*1e3,jp={value:null},Fp=(e,t)=>{let r=c=>c.split(".").map(Number),[n=0,s=0,i=0]=r(e),[o=0,a=0,l=0]=r(t);return n!==o?n>o:s!==a?s>a:i>l},ca=async(e={fetch:globalThis.fetch,getCurrent:Fr,cache:jp})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<_p)return e.cache.value.result;let n=null;try{let i=await e.fetch(Lp,{signal:AbortSignal.timeout(5e3)});i.ok&&(n=(await i.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&Fp(n,t)};return e.cache.value={result:s,cachedAt:r},s};var w={load:Qn,save:Zn,previews:Xn,runners:Jn,version:es};var da={CLI_USAGE:2,INPUT_REQUIRED:2,WORKSPACE_CONTEXT_NOT_FOUND:3,WORKSPACE_CONTEXT_INVALID:4,WORKSPACE_NOT_FOUND:3,WORKSPACE_RECORD_INVALID:2,TASK_CONTEXT_NOT_FOUND:3,TASK_CONTEXT_AMBIGUOUS:4,TASK_CONTEXT_CONFLICT:4,TASK_NOT_FOUND:3,TASK_RECORD_INVALID:2,REPO_NOT_FOUND:3,REPO_RECORD_INVALID:2,PR_REPOSITORY_MISMATCH:4,PR_BRANCH_MISMATCH:4,EXTERNAL_DEPENDENCY_FAILED:5,OPERATION_TIMEOUT:6,OPERATION_CANCELLED:6,EVENT_CURSOR_INVALID:2,EVENT_CURSOR_EXPIRED:4,EVENT_JOURNAL_CORRUPT:2,COMMAND_NOT_FOUND:3,COMMAND_RECORD_INVALID:2,COMMAND_STATE_CONFLICT:4,PARTIAL_RESULT:7,INTERNAL_ERROR:1},g=class extends Error{code;exitCode;retryable;details;constructor(t,r,n){super(r,n.cause===void 0?void 0:{cause:n.cause}),this.name="CraigError",this.code=t,this.exitCode=da[t],this.retryable=n.retryable??!1,this.details=n.details??{}}};function ts(e){return e instanceof g?e:new g("INTERNAL_ERROR",e instanceof Error?e.message:"Unknown Craig error",{cause:e})}import{appendFile as Wp,mkdir as qp,readFile as Up}from"node:fs/promises";import Vp from"node:path";var ua=80,rs=async(e,t)=>{await qp(Vp.dirname(e.errorLogFile),{recursive:!0}),await Wp(e.errorLogFile,Bp(t),"utf8")},pa=async(e,t)=>{try{await rs(e,t)}catch{}},ns=async(e,t=ua)=>{try{let n=(await Up(e.errorLogFile,"utf8")).trimEnd().split(`
5
+ `).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(Kp(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},ma=async(e,t=ua)=>ns(e,t);function Bp(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(`
6
6
  `).map(n=>` ${n}`))),`${r.join(`
7
7
  `)}
8
8
 
9
- `}function _p(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Le={appendErrorLog:es,appendErrorLogBestEffort:aa,readErrorLog:ts,readRecentErrorLines:la};function fa(e){let{commandTokens:t,options:r,help:n}=Fp(e);if(n)return da({kind:"help"},r);if(t.length===0)return{mode:"interactive",options:r};let[s,o,...i]=t,a;switch(`${s??""}:${o??""}`){case"context:show":Ht(i,"context show"),a={kind:"showContext"};break;case"repo:add":a={kind:"addRepo",path:pa(i,"Repo path")};break;case"repo:list":Ht(i,"repo list"),a={kind:"listRepos"};break;case"repo:remove":a={kind:"removeRepo",repoId:X(i,"Repo id")};break;case"workspace:add":a={kind:"addWorkspace",path:pa(i,"Workspace path")};break;case"workspace:list":a=Wp(i);break;case"workspace:archive":a={kind:"archiveWorkspace",workspaceId:X(i,"Workspace id")};break;case"workspace:restore":a={kind:"restoreWorkspace",workspaceId:X(i,"Workspace id")};break;case"workspace:remove":a={kind:"removeWorkspace",workspaceId:X(i,"Workspace id")};break;case"task:new":a=Up(i);break;case"task:list":a=qp(i);break;case"task:current":Ht(i,"task current"),a={kind:"currentTask"};break;case"task:show":a=i.length===0?{kind:"showCurrentTask"}:{kind:"showTask",taskId:X(i,"Task id")};break;case"task:pr":a=Bp(i);break;case"task:wait":a=Jp(i);break;case"agent:list":Ht(i,"agent list"),a={kind:"listAgents"};break;case"agent:status":a=Gp(i);break;case"agent:send":a=Hp(i);break;case"command:show":a={kind:"showPromptCommand",commandId:X(i,"Command id")};break;case"command:list":Ht(i,"command list"),a={kind:"listPromptCommands"};break;case"command:cancel":a={kind:"cancelPromptCommand",commandId:X(i,"Command id")};break;case"command:wait":a=zp(i);break;case"events:list":a=ca(i,!1);break;case"events:watch":a=ca(i,!0);break;case"task:attach":a={kind:"attachTask",taskId:X(i,"Task id")};break;case"task:logs":a={kind:"streamTaskLogs",taskId:X(i,"Task id")};break;case"task:diff":a={kind:"showTaskDiff",taskId:X(i,"Task id")};break;case"task:focus":a={kind:"focusTask",taskId:X(i,"Task id")};break;case"task:open":a={kind:"openTask",taskId:X(i,"Task id")};break;case"task:check":a={kind:"runChecks",taskId:X(i,"Task id")};break;case"task:commit":a={kind:"commitTask",taskId:X(i,"Task id")};break;case"link:add":a={kind:"addTaskLink",taskId:ma(i,0,"Task id"),repoId:ma(i,1,"Repo id")},ha(i,2,"link add");break;case"link:list":a={kind:"listTaskLinks",taskId:X(i,"Task id")};break;default:if(t.length===1&&(s==="help"||s==="--help"||s==="-h")){a={kind:"help"};break}throw P(`Unsupported command: ${t.join(" ")}`)}return da(a,r)}function ga(e){let t=e[0]==="--"?e.slice(1):e,r=!0;for(let n of t){if(n==="--"){r=!1;continue}if(r&&n==="--json")return!0}return!1}function jp(e){return{addWorkspace:"workspace.add",addRepo:"repo.add",listRepos:"repo.list",removeRepo:"repo.remove",listWorkspaces:"workspace.list",archiveWorkspace:"workspace.archive",restoreWorkspace:"workspace.restore",removeWorkspace:"workspace.remove",createTask:"task.new",listTasks:"task.list",currentTask:"task.current",showTask:"task.show",showCurrentTask:"task.show",showTaskPr:"task.pr.show",discoverTaskPr:"task.pr.discover",linkTaskPr:"task.pr.link",refreshTaskPr:"task.pr.refresh",unlinkTaskPr:"task.pr.unlink",listAgents:"agent.list",showAgentStatus:"agent.status",sendAgentPrompt:"agent.send",showPromptCommand:"command.show",listPromptCommands:"command.list",cancelPromptCommand:"command.cancel",waitPromptCommand:"command.wait",waitTask:"task.wait",listEvents:"events.list",watchEvents:"events.watch",attachTask:"task.attach",addTaskLink:"link.add",listTaskLinks:"link.list",refreshInteractiveState:"interactive.refresh",showSelectedTask:"task.show",streamTaskLogs:"task.logs",streamSelectedTaskLogs:"task.logs",showTaskDiff:"task.diff",showSelectedTaskDiff:"task.diff",focusTask:"task.focus",focusSelectedTask:"task.focus",openTask:"task.open",openSelectedTask:"task.open",runChecks:"task.check",runSelectedTaskChecks:"task.check",commitTask:"task.commit",commitSelectedTask:"task.commit",showContext:"context.show",help:"help",exit:"exit"}[e.kind]}function rs(){return["Craig commands:"," craig [--workspace-root <path>] [--task <id>] [--json] [--no-input] <command>"," craig context show Show resolved workspace, task, and agent-tab context"," craig repo add <path> 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 <id> Remove a registered repo"," craig workspace list [--archived] List workspaces"," craig workspace archive <id> Archive a workspace"," craig workspace restore <id> Restore an archived workspace"," craig workspace remove <id> Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt>"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt>"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task current Show the task resolved from flags, environment, or cwd"," craig task show [<id>] Show task details; omit id to use resolved context"," craig task pr show [<id>] [--repo <repo-id>]"," craig task pr discover [<id>] [--repo <repo-id>]"," craig task pr link [<id>] --pr <url|number> [--repo <repo-id>]"," craig task pr refresh [<id>] [--repo <repo-id>]"," craig task pr unlink [<id>] --pr <url|number> [--repo <repo-id>]"," craig agent list [--task <task-id>] List agent-tab and task roll-up states"," craig agent status [--task <task-id>] [--tab <tab-id>] Show agent state details"," craig agent send --task <task-id> [--tab <tab-id>] (--prompt <text> | --prompt-file <path> | --stdin)"," [--delivery when-ready|immediate] [--timeout <duration>] [--idempotency-key <key>]"," craig command show <command-id> Show a durable prompt command"," craig command list [--task <task-id>] List durable prompt commands"," craig command cancel <command-id> Cancel a queued prompt command"," craig command wait <command-id> [--state <states>] [--timeout <duration>]"," craig task wait [<id>] --state <states> [--tab <tab-id>] [--timeout <duration>]"," craig events list [--task <task-id>] [--type <glob>] [--after <cursor>] --json"," craig events watch [--task <task-id>] [--type <glob>] [--after <cursor>] [--format jsonl]"," craig task logs <id> Stream Craig-managed logs for a task"," craig task diff <id> Show the current worktree diff for a task"," craig task attach <id> Attach to a live task session"," craig task focus <id> Focus the tmux pane for a task"," craig task open <id> Open the task worktree or print its path"," craig task check <id> Run configured checks for a task"," craig task commit <id> Commit all task worktree changes"," craig link add <task-id> <repo-id> Add a linked repo to a task"," craig link list <task-id> List linked repos for a task"].join(`
10
- `)}function Fp(e){let t=[...e];t[0]==="--"&&t.shift();let r=[],n={json:!1,noInput:!1},s=new Set,o=!1,i=!0;for(let a=0;a<t.length;a+=1){let l=t[a];if(l==="--"){i=!1,r.push(l);continue}if(!i||!ua(l)){r.push(l);continue}if(s.has(l))throw P(`Global option ${l} may only be provided once.`);if(s.add(l),l==="--json"){n.json=!0;continue}if(l==="--no-input"){n.noInput=!0;continue}if(l==="--help"||l==="-h"){o=!0;continue}let c=t[a+1];if(c===void 0||c==="--"||ua(c))throw P(`Global option ${l} requires a value.`);a+=1,l==="--workspace-root"?n.workspaceRoot=F(c,"Workspace root"):n.taskId=F(c,"Task id")}return{commandTokens:r,options:n,help:o}}function Wp(e){if(e.length===0)return{kind:"listWorkspaces",archived:!1};if(e.length===1&&e[0]==="--archived")return{kind:"listWorkspaces",archived:!0};throw P(`Unsupported command: workspace list ${e.join(" ")}`)}function qp(e){if(e.length===0)return{kind:"listTasks"};if(e.length===2&&e[0]==="--repo")return{kind:"listTasks",repoId:F(e[1],"Repo id")};throw P(`Unsupported command: task list ${e.join(" ")}`)}function Up(e){let t,r,n,s=[],o=!0;for(let a=0;a<e.length;a+=1){let l=e[a];if(l==="--"){o=!1;continue}if(!o||!["--repo","--workspace","--runner"].includes(l)){if(o&&l.startsWith("--"))throw P(`Unsupported task new option: ${l}`);s.push(l);continue}let c=e[a+1];if(c===void 0||c==="--")throw P(`Task option ${l} requires a value.`);if(a+=1,l==="--repo"){if(t!==void 0)throw P("Task option --repo may only be provided once.");t=F(c,"Repo id")}else if(l==="--workspace"){if(r!==void 0)throw P("Task option --workspace may only be provided once.");r=F(c,"Workspace id")}else{if(n!==void 0)throw P("Task option --runner may only be provided once.");try{n=h.runners.parse(c)}catch(d){throw P(d instanceof Error?d.message:"Unsupported runner.")}}}if(!t&&!r)throw P("Task creation requires '--repo <repo-id>' or '--workspace <workspace-id>'.");if(t&&r)throw P("Task creation accepts either '--repo' or '--workspace', not both.");let i=F(s.join(" "),"Task prompt");return{kind:"createTask",...t?{repoId:t}:{},...r?{workspaceId:r}:{},...n?{runner:n}:{},prompt:i}}function Bp(e){let[t,...r]=e;if(!["show","discover","link","refresh","unlink"].includes(t??""))throw P(`Unsupported command: task pr ${e.join(" ")}`);let n,s,o;for(let a=0;a<r.length;a+=1){let l=r[a];if(l!=="--repo"&&l!=="--pr"){if(l.startsWith("--"))throw P(`Unsupported task pr ${t} option: ${l}`);if(n!==void 0)throw P(`task pr ${t} accepts at most one task id.`);n=F(l,"Task id");continue}let c=r[a+1];if(c===void 0||c==="--")throw P(`Task PR option ${l} requires a value.`);if(a+=1,l==="--repo"){if(s!==void 0)throw P("Task PR option --repo may only be provided once.");s=F(c,"Repo id")}else{if(o!==void 0)throw P("Task PR option --pr may only be provided once.");o=F(c,"Pull request selector")}}if((t==="link"||t==="unlink")&&o===void 0)throw P(`task pr ${t} requires --pr <url|number>.`);if(t!=="link"&&t!=="unlink"&&o!==void 0)throw P(`task pr ${t} does not accept --pr.`);let i={...n?{taskId:n}:{},...s?{repoId:s}:{}};switch(t){case"show":return{kind:"showTaskPr",...i};case"discover":return{kind:"discoverTaskPr",...i};case"link":return{kind:"linkTaskPr",...i,pullRequest:o};case"refresh":return{kind:"refreshTaskPr",...i};case"unlink":return{kind:"unlinkTaskPr",...i,pullRequest:o};default:throw P(`Unsupported command: task pr ${e.join(" ")}`)}}var ns=300*1e3,Vp=new Set(["idle","working","ready","error"]),Kp=new Set(["queued","delivering","delivered","failed","cancelled"]);function Gp(e){if(e.length===0)return{kind:"showAgentStatus"};if(e.length===2&&e[0]==="--tab")return{kind:"showAgentStatus",tabId:F(e[1],"Agent tab id")};throw P(`Unsupported command: agent status ${e.join(" ")}`)}function Hp(e){let t,r,n="when-ready",s=ns,o,i=new Set;for(let a=0;a<e.length;a+=1){let l=e[a];if(!["--prompt","--prompt-file","--stdin","--tab","--delivery","--timeout","--idempotency-key"].includes(l))throw P(`Unsupported agent send option: ${l}`);if(i.has(l))throw P(`Agent send option ${l} may only be provided once.`);if(i.add(l),l==="--stdin"){if(t)throw P("Agent send accepts exactly one prompt source.");t={source:"stdin"};continue}let c=e[a+1];if(c===void 0||c.startsWith("--"))throw P(`Agent send option ${l} requires a value.`);if(a+=1,l==="--prompt"||l==="--prompt-file"){if(t)throw P("Agent send accepts exactly one prompt source.");t=l==="--prompt"?{source:"inline",text:F(c,"Prompt")}:{source:"file",path:F(c,"Prompt file")}}else if(l==="--tab")r=F(c,"Agent tab id");else if(l==="--delivery"){if(c!=="when-ready"&&c!=="immediate")throw P('Agent send delivery must be "when-ready" or "immediate".');n=c}else l==="--timeout"?s=ss(c):o=F(c,"Idempotency key")}if(!t)throw P("Agent send requires --prompt, --prompt-file, or --stdin.");return{kind:"sendAgentPrompt",prompt:t,delivery:n,timeoutMs:s,...r?{tabId:r}:{},...o?{idempotencyKey:o}:{}}}function zp(e){let t=F(e[0]??"","Command id"),r,n=ns,s=new Set;for(let o=1;o<e.length;o+=1){let i=e[o];if(i!=="--state"&&i!=="--timeout")throw P(`Unsupported command wait option: ${i}`);if(s.has(i))throw P(`Command wait option ${i} may only be provided once.`);s.add(i);let a=e[o+1];if(a===void 0||a.startsWith("--"))throw P(`Command wait option ${i} requires a value.`);o+=1,i==="--state"?r=Yp(a):n=ss(a)}return{kind:"waitPromptCommand",commandId:t,...r?{states:r}:{},timeoutMs:n}}function Yp(e){let t=e.split(",").map(r=>r.trim()).filter(Boolean);if(t.length===0||t.some(r=>!Kp.has(r)))throw P(`Invalid command state list "${e}". Use queued, delivering, delivered, failed, or cancelled.`);return[...new Set(t)]}function ca(e,t){let r,n,s="human",o=new Set;for(let a=0;a<e.length;a+=1){let l=e[a];if(!["--type","--after","--format"].includes(l))throw P(`Unsupported events ${t?"watch":"list"} option: ${l}`);if(!t&&l==="--format")throw P("--format is supported only by events watch.");if(o.has(l))throw P(`Events option ${l} may only be provided once.`);o.add(l);let c=e[a+1];if(c===void 0||c.startsWith("--"))throw P(`Events option ${l} requires a value.`);if(a+=1,l==="--type")r=F(c,"Event type glob");else if(l==="--after")n=F(c,"Event cursor");else if(c==="jsonl")s="jsonl";else throw P('Events watch format must be "jsonl".')}let i={...r?{typeGlob:r}:{},...n?{after:n}:{}};return t?{kind:"watchEvents",...i,format:s}:{kind:"listEvents",...i}}function Jp(e){let t,r,n,s=ns,o=new Set;for(let i=0;i<e.length;i+=1){let a=e[i];if(!["--state","--tab","--timeout"].includes(a)){if(a.startsWith("--"))throw P(`Unsupported task wait option: ${a}`);if(t!==void 0)throw P("task wait accepts at most one task id.");t=F(a,"Task id");continue}if(o.has(a))throw P(`Task wait option ${a} may only be provided once.`);o.add(a);let l=e[i+1];if(l===void 0||l.startsWith("--"))throw P(`Task wait option ${a} requires a value.`);i+=1,a==="--state"?r=Xp(l):a==="--tab"?n=F(l,"Agent tab id"):s=ss(l)}if(!r)throw P("task wait requires --state <idle|working|ready|error>[,...].");return{kind:"waitTask",...t?{taskId:t}:{},states:r,...n?{tabId:n}:{},timeoutMs:s}}function Xp(e){let t=e.split(",").map(r=>r.trim()).filter(Boolean);if(t.length===0||t.some(r=>!Vp.has(r)))throw P(`Invalid agent state list "${e}". Use idle, working, ready, or error.`);return[...new Set(t)]}function ss(e){let t=/^(\d+)(ms|s|m|h)$/.exec(e.trim());if(!t)throw P(`Invalid duration "${e}". Use values such as 500ms, 30s, 5m, or 1h.`);let r=Number(t[1]),n={ms:1,s:1e3,m:6e4,h:36e5}[t[2]],s=r*n;if(!Number.isSafeInteger(s))throw P(`Duration "${e}" is too large.`);return s}function da(e,t){return{mode:"command",command:e,commandName:jp(e),options:t}}function ua(e){return["--json","--no-input","--workspace-root","--task","--help","-h"].includes(e)}function Ht(e,t){ha(e,0,t)}function ha(e,t,r){if(e.length!==t)throw P(`Command ${r} received an unexpected number of arguments.`)}function X(e,t){if(e.length!==1)throw P(`${t} is required and must be provided once.`);return F(e[0],t)}function pa(e,t){return F(e.join(" "),t)}function ma(e,t,r){return F(e[t]??"",r)}function F(e,t){let r=e.trim();if(r.length===0)throw P(`${t} cannot be empty.`);return r}function P(e){return new f("CLI_USAGE",`${e}
9
+ `}function Kp(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Se={appendErrorLog:rs,appendErrorLogBestEffort:pa,readErrorLog:ns,readRecentErrorLines:ma};function ya(e){let{commandTokens:t,options:r,help:n}=Hp(e);if(n)return ga({kind:"help"},r);if(t.length===0)return{mode:"interactive",options:r};let[s,i,...o]=t,a;switch(`${s??""}:${i??""}`){case"context:show":Yt(o,"context show"),a={kind:"showContext"};break;case"repo:add":a={kind:"addRepo",path:wa(o,"Repo path")};break;case"repo:list":Yt(o,"repo list"),a={kind:"listRepos"};break;case"repo:remove":a={kind:"removeRepo",repoId:Q(o,"Repo id")};break;case"workspace:add":a={kind:"addWorkspace",path:wa(o,"Workspace path")};break;case"workspace:list":a=zp(o);break;case"workspace:archive":a={kind:"archiveWorkspace",workspaceId:Q(o,"Workspace id")};break;case"workspace:restore":a={kind:"restoreWorkspace",workspaceId:Q(o,"Workspace id")};break;case"workspace:remove":a={kind:"removeWorkspace",workspaceId:Q(o,"Workspace id")};break;case"task:new":a=Jp(o);break;case"task:list":a=Yp(o);break;case"task:current":Yt(o,"task current"),a={kind:"currentTask"};break;case"task:show":a=o.length===0?{kind:"showCurrentTask"}:{kind:"showTask",taskId:Q(o,"Task id")};break;case"task:pr":a=Xp(o);break;case"task:wait":a=sm(o);break;case"agent:list":Yt(o,"agent list"),a={kind:"listAgents"};break;case"agent:status":a=em(o);break;case"agent:send":a=tm(o);break;case"command:show":a={kind:"showPromptCommand",commandId:Q(o,"Command id")};break;case"command:list":Yt(o,"command list"),a={kind:"listPromptCommands"};break;case"command:cancel":a={kind:"cancelPromptCommand",commandId:Q(o,"Command id")};break;case"command:wait":a=rm(o);break;case"events:list":a=fa(o,!1);break;case"events:watch":a=fa(o,!0);break;case"task:attach":a={kind:"attachTask",taskId:Q(o,"Task id")};break;case"task:logs":a={kind:"streamTaskLogs",taskId:Q(o,"Task id")};break;case"task:diff":a={kind:"showTaskDiff",taskId:Q(o,"Task id")};break;case"task:focus":a={kind:"focusTask",taskId:Q(o,"Task id")};break;case"task:open":a={kind:"openTask",taskId:Q(o,"Task id")};break;case"task:check":a={kind:"runChecks",taskId:Q(o,"Task id")};break;case"task:commit":a={kind:"commitTask",taskId:Q(o,"Task id")};break;case"link:add":a={kind:"addTaskLink",taskId:ka(o,0,"Task id"),repoId:ka(o,1,"Repo id")},Ra(o,2,"link add");break;case"link:list":a={kind:"listTaskLinks",taskId:Q(o,"Task id")};break;default:if(t.length===1&&(s==="help"||s==="--help"||s==="-h")){a={kind:"help"};break}throw S(`Unsupported command: ${t.join(" ")}`)}return ga(a,r)}function Ta(e){let t=e[0]==="--"?e.slice(1):e,r=!0;for(let n of t){if(n==="--"){r=!1;continue}if(r&&n==="--json")return!0}return!1}function Gp(e){return{addWorkspace:"workspace.add",addRepo:"repo.add",listRepos:"repo.list",removeRepo:"repo.remove",listWorkspaces:"workspace.list",archiveWorkspace:"workspace.archive",restoreWorkspace:"workspace.restore",removeWorkspace:"workspace.remove",createTask:"task.new",listTasks:"task.list",currentTask:"task.current",showTask:"task.show",showCurrentTask:"task.show",showTaskPr:"task.pr.show",discoverTaskPr:"task.pr.discover",linkTaskPr:"task.pr.link",refreshTaskPr:"task.pr.refresh",unlinkTaskPr:"task.pr.unlink",listAgents:"agent.list",showAgentStatus:"agent.status",sendAgentPrompt:"agent.send",showPromptCommand:"command.show",listPromptCommands:"command.list",cancelPromptCommand:"command.cancel",waitPromptCommand:"command.wait",waitTask:"task.wait",listEvents:"events.list",watchEvents:"events.watch",attachTask:"task.attach",addTaskLink:"link.add",listTaskLinks:"link.list",refreshInteractiveState:"interactive.refresh",showSelectedTask:"task.show",streamTaskLogs:"task.logs",streamSelectedTaskLogs:"task.logs",showTaskDiff:"task.diff",showSelectedTaskDiff:"task.diff",focusTask:"task.focus",focusSelectedTask:"task.focus",openTask:"task.open",openSelectedTask:"task.open",runChecks:"task.check",runSelectedTaskChecks:"task.check",commitTask:"task.commit",commitSelectedTask:"task.commit",showContext:"context.show",help:"help",exit:"exit"}[e.kind]}function ss(){return["Craig commands:"," craig [--workspace-root <path>] [--task <id>] [--json] [--no-input] <command>"," craig context show Show resolved workspace, task, and agent-tab context"," craig repo add <path> 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 <id> Remove a registered repo"," craig workspace list [--archived] List workspaces"," craig workspace archive <id> Archive a workspace"," craig workspace restore <id> Restore an archived workspace"," craig workspace remove <id> Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt>"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt>"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task current Show the task resolved from flags, environment, or cwd"," craig task show [<id>] Show task details; omit id to use resolved context"," craig task pr show [<id>] [--repo <repo-id>]"," craig task pr discover [<id>] [--repo <repo-id>]"," craig task pr link [<id>] --pr <url|number> [--repo <repo-id>]"," craig task pr refresh [<id>] [--repo <repo-id>]"," craig task pr unlink [<id>] --pr <url|number> [--repo <repo-id>]"," craig agent list [--task <task-id>] List agent-tab and task roll-up states"," craig agent status [--task <task-id>] [--tab <tab-id>] Show agent state details"," craig agent send --task <task-id> [--tab <tab-id>] (--prompt <text> | --prompt-file <path> | --stdin)"," [--delivery when-ready|immediate] [--timeout <duration>] [--idempotency-key <key>]"," craig command show <command-id> Show a durable prompt command"," craig command list [--task <task-id>] List durable prompt commands"," craig command cancel <command-id> Cancel a queued prompt command"," craig command wait <command-id> [--state <states>] [--timeout <duration>]"," craig task wait [<id>] --state <states> [--tab <tab-id>] [--timeout <duration>]"," craig events list [--task <task-id>] [--type <glob>] [--after <cursor>] --json"," craig events watch [--task <task-id>] [--type <glob>] [--after <cursor>] [--format jsonl]"," craig task logs <id> Stream Craig-managed logs for a task"," craig task diff <id> Show the current worktree diff for a task"," craig task attach <id> Attach to a live task session"," craig task focus <id> Focus the tmux pane for a task"," craig task open <id> Open the task worktree or print its path"," craig task check <id> Run configured checks for a task"," craig task commit <id> Commit all task worktree changes"," craig link add <task-id> <repo-id> Add a linked repo to a task"," craig link list <task-id> List linked repos for a task"].join(`
10
+ `)}function Hp(e){let t=[...e];t[0]==="--"&&t.shift();let r=[],n={json:!1,noInput:!1},s=new Set,i=!1,o=!0;for(let a=0;a<t.length;a+=1){let l=t[a];if(l==="--"){o=!1,r.push(l);continue}if(!o||!ha(l)){r.push(l);continue}if(s.has(l))throw S(`Global option ${l} may only be provided once.`);if(s.add(l),l==="--json"){n.json=!0;continue}if(l==="--no-input"){n.noInput=!0;continue}if(l==="--help"||l==="-h"){i=!0;continue}let c=t[a+1];if(c===void 0||c==="--"||ha(c))throw S(`Global option ${l} requires a value.`);a+=1,l==="--workspace-root"?n.workspaceRoot=j(c,"Workspace root"):n.taskId=j(c,"Task id")}return{commandTokens:r,options:n,help:i}}function zp(e){if(e.length===0)return{kind:"listWorkspaces",archived:!1};if(e.length===1&&e[0]==="--archived")return{kind:"listWorkspaces",archived:!0};throw S(`Unsupported command: workspace list ${e.join(" ")}`)}function Yp(e){if(e.length===0)return{kind:"listTasks"};if(e.length===2&&e[0]==="--repo")return{kind:"listTasks",repoId:j(e[1],"Repo id")};throw S(`Unsupported command: task list ${e.join(" ")}`)}function Jp(e){let t,r,n,s=[],i=!0;for(let a=0;a<e.length;a+=1){let l=e[a];if(l==="--"){i=!1;continue}if(!i||!["--repo","--workspace","--runner"].includes(l)){if(i&&l.startsWith("--"))throw S(`Unsupported task new option: ${l}`);s.push(l);continue}let c=e[a+1];if(c===void 0||c==="--")throw S(`Task option ${l} requires a value.`);if(a+=1,l==="--repo"){if(t!==void 0)throw S("Task option --repo may only be provided once.");t=j(c,"Repo id")}else if(l==="--workspace"){if(r!==void 0)throw S("Task option --workspace may only be provided once.");r=j(c,"Workspace id")}else{if(n!==void 0)throw S("Task option --runner may only be provided once.");try{n=w.runners.parse(c)}catch(d){throw S(d instanceof Error?d.message:"Unsupported runner.")}}}if(!t&&!r)throw S("Task creation requires '--repo <repo-id>' or '--workspace <workspace-id>'.");if(t&&r)throw S("Task creation accepts either '--repo' or '--workspace', not both.");let o=j(s.join(" "),"Task prompt");return{kind:"createTask",...t?{repoId:t}:{},...r?{workspaceId:r}:{},...n?{runner:n}:{},prompt:o}}function Xp(e){let[t,...r]=e;if(!["show","discover","link","refresh","unlink"].includes(t??""))throw S(`Unsupported command: task pr ${e.join(" ")}`);let n,s,i;for(let a=0;a<r.length;a+=1){let l=r[a];if(l!=="--repo"&&l!=="--pr"){if(l.startsWith("--"))throw S(`Unsupported task pr ${t} option: ${l}`);if(n!==void 0)throw S(`task pr ${t} accepts at most one task id.`);n=j(l,"Task id");continue}let c=r[a+1];if(c===void 0||c==="--")throw S(`Task PR option ${l} requires a value.`);if(a+=1,l==="--repo"){if(s!==void 0)throw S("Task PR option --repo may only be provided once.");s=j(c,"Repo id")}else{if(i!==void 0)throw S("Task PR option --pr may only be provided once.");i=j(c,"Pull request selector")}}if((t==="link"||t==="unlink")&&i===void 0)throw S(`task pr ${t} requires --pr <url|number>.`);if(t!=="link"&&t!=="unlink"&&i!==void 0)throw S(`task pr ${t} does not accept --pr.`);let o={...n?{taskId:n}:{},...s?{repoId:s}:{}};switch(t){case"show":return{kind:"showTaskPr",...o};case"discover":return{kind:"discoverTaskPr",...o};case"link":return{kind:"linkTaskPr",...o,pullRequest:i};case"refresh":return{kind:"refreshTaskPr",...o};case"unlink":return{kind:"unlinkTaskPr",...o,pullRequest:i};default:throw S(`Unsupported command: task pr ${e.join(" ")}`)}}var is=300*1e3,Qp=new Set(["idle","working","ready","error"]),Zp=new Set(["queued","delivering","delivered","failed","cancelled"]);function em(e){if(e.length===0)return{kind:"showAgentStatus"};if(e.length===2&&e[0]==="--tab")return{kind:"showAgentStatus",tabId:j(e[1],"Agent tab id")};throw S(`Unsupported command: agent status ${e.join(" ")}`)}function tm(e){let t,r,n="when-ready",s=is,i,o=new Set;for(let a=0;a<e.length;a+=1){let l=e[a];if(!["--prompt","--prompt-file","--stdin","--tab","--delivery","--timeout","--idempotency-key"].includes(l))throw S(`Unsupported agent send option: ${l}`);if(o.has(l))throw S(`Agent send option ${l} may only be provided once.`);if(o.add(l),l==="--stdin"){if(t)throw S("Agent send accepts exactly one prompt source.");t={source:"stdin"};continue}let c=e[a+1];if(c===void 0||c.startsWith("--"))throw S(`Agent send option ${l} requires a value.`);if(a+=1,l==="--prompt"||l==="--prompt-file"){if(t)throw S("Agent send accepts exactly one prompt source.");t=l==="--prompt"?{source:"inline",text:j(c,"Prompt")}:{source:"file",path:j(c,"Prompt file")}}else if(l==="--tab")r=j(c,"Agent tab id");else if(l==="--delivery"){if(c!=="when-ready"&&c!=="immediate")throw S('Agent send delivery must be "when-ready" or "immediate".');n=c}else l==="--timeout"?s=os(c):i=j(c,"Idempotency key")}if(!t)throw S("Agent send requires --prompt, --prompt-file, or --stdin.");return{kind:"sendAgentPrompt",prompt:t,delivery:n,timeoutMs:s,...r?{tabId:r}:{},...i?{idempotencyKey:i}:{}}}function rm(e){let t=j(e[0]??"","Command id"),r,n=is,s=new Set;for(let i=1;i<e.length;i+=1){let o=e[i];if(o!=="--state"&&o!=="--timeout")throw S(`Unsupported command wait option: ${o}`);if(s.has(o))throw S(`Command wait option ${o} may only be provided once.`);s.add(o);let a=e[i+1];if(a===void 0||a.startsWith("--"))throw S(`Command wait option ${o} requires a value.`);i+=1,o==="--state"?r=nm(a):n=os(a)}return{kind:"waitPromptCommand",commandId:t,...r?{states:r}:{},timeoutMs:n}}function nm(e){let t=e.split(",").map(r=>r.trim()).filter(Boolean);if(t.length===0||t.some(r=>!Zp.has(r)))throw S(`Invalid command state list "${e}". Use queued, delivering, delivered, failed, or cancelled.`);return[...new Set(t)]}function fa(e,t){let r,n,s="human",i=new Set;for(let a=0;a<e.length;a+=1){let l=e[a];if(!["--type","--after","--format"].includes(l))throw S(`Unsupported events ${t?"watch":"list"} option: ${l}`);if(!t&&l==="--format")throw S("--format is supported only by events watch.");if(i.has(l))throw S(`Events option ${l} may only be provided once.`);i.add(l);let c=e[a+1];if(c===void 0||c.startsWith("--"))throw S(`Events option ${l} requires a value.`);if(a+=1,l==="--type")r=j(c,"Event type glob");else if(l==="--after")n=j(c,"Event cursor");else if(c==="jsonl")s="jsonl";else throw S('Events watch format must be "jsonl".')}let o={...r?{typeGlob:r}:{},...n?{after:n}:{}};return t?{kind:"watchEvents",...o,format:s}:{kind:"listEvents",...o}}function sm(e){let t,r,n,s=is,i=new Set;for(let o=0;o<e.length;o+=1){let a=e[o];if(!["--state","--tab","--timeout"].includes(a)){if(a.startsWith("--"))throw S(`Unsupported task wait option: ${a}`);if(t!==void 0)throw S("task wait accepts at most one task id.");t=j(a,"Task id");continue}if(i.has(a))throw S(`Task wait option ${a} may only be provided once.`);i.add(a);let l=e[o+1];if(l===void 0||l.startsWith("--"))throw S(`Task wait option ${a} requires a value.`);o+=1,a==="--state"?r=im(l):a==="--tab"?n=j(l,"Agent tab id"):s=os(l)}if(!r)throw S("task wait requires --state <idle|working|ready|error>[,...].");return{kind:"waitTask",...t?{taskId:t}:{},states:r,...n?{tabId:n}:{},timeoutMs:s}}function im(e){let t=e.split(",").map(r=>r.trim()).filter(Boolean);if(t.length===0||t.some(r=>!Qp.has(r)))throw S(`Invalid agent state list "${e}". Use idle, working, ready, or error.`);return[...new Set(t)]}function os(e){let t=/^(\d+)(ms|s|m|h)$/.exec(e.trim());if(!t)throw S(`Invalid duration "${e}". Use values such as 500ms, 30s, 5m, or 1h.`);let r=Number(t[1]),n={ms:1,s:1e3,m:6e4,h:36e5}[t[2]],s=r*n;if(!Number.isSafeInteger(s))throw S(`Duration "${e}" is too large.`);return s}function ga(e,t){return{mode:"command",command:e,commandName:Gp(e),options:t}}function ha(e){return["--json","--no-input","--workspace-root","--task","--help","-h"].includes(e)}function Yt(e,t){Ra(e,0,t)}function Ra(e,t,r){if(e.length!==t)throw S(`Command ${r} received an unexpected number of arguments.`)}function Q(e,t){if(e.length!==1)throw S(`${t} is required and must be provided once.`);return j(e[0],t)}function wa(e,t){return j(e.join(" "),t)}function ka(e,t,r){return j(e[t]??"",r)}function j(e,t){let r=e.trim();if(r.length===0)throw S(`${t} cannot be empty.`);return r}function S(e){return new g("CLI_USAGE",`${e}
11
11
 
12
- ${rs()}`,{})}var ue=(e,t)=>{let r=os(e);if(!Zp(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},os=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:is(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:rm(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:em(t.repoTargets),runnerSession:t.runnerSession??Qp(t),checks:cm(t),lastCommit:t.lastCommit??null,prs:dm(t),artifacts:fm(t),cleanup:gm(t)}},Qp=e=>{if(typeof e.title!="string")return null;let t=is(e.runner);return{command:h.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},Zp=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"&&ka(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||tm(t.repoTargets))&&sm(t.runnerSession)&&om(t.prompt)&&ya(t.checks)&&Ta(t.lastCommit)&&am(t.prs)&&lm(t.artifacts)&&ba(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},em=e=>{if(Array.isArray(e))return e.filter(wa)},tm=e=>Array.isArray(e)&&e.every(wa),wa=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)&&ya(t.checks)&&Ta(t.lastCommit)&&Ra(t.pullRequest)&&ba(t.cleanup)},rm=e=>{if(ka(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 nm(e.id,e.title,t,is(e.runner))},nm=(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}]},is=e=>e&&h.runners.isRunnerType(e)?e:"codex",ka=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"),sm=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),om=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",ya=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"),Ta=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",Ra=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&im(e.requiredChecks),im=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)),am=e=>Array.isArray(e)&&e.every(Ra),lm=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),ba=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),cm=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},dm=e=>{if(Array.isArray(e.prs))return e.prs.map(um);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:Pa(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Sa(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},um=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:Pa(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:pm(t.reviewDecision),requiredChecks:Sa(t.requiredChecks),comments:mm(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},Pa=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,pm=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,mm=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}]}):[],Sa=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})):[],fm=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},gm=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as Zm}from"node:fs/promises";import{readFile as hm,readdir as wm,rm as km}from"node:fs/promises";import va from"node:path";var as=(e,t)=>va.join(e.workspacesDir,`${t}.json`),ym=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"):[]}},Ia=(e,t)=>{let r=ym(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},et=async(e,t)=>{let r=as(e,t);try{let n=await hm(r,"utf8");return Ia(JSON.parse(n),r)}catch(n){throw Tm(n)?new f("WORKSPACE_NOT_FOUND",`Craig workspace "${t}" was not found.`,{details:{workspaceId:t}}):n instanceof SyntaxError||n instanceof Error&&n.message.startsWith("Craig workspace record at ")?new f("WORKSPACE_RECORD_INVALID",n instanceof Error?n.message:`Craig workspace "${t}" is invalid.`,{details:{workspaceId:t},cause:n}):n}},tt=async(e,t)=>{await M(as(e,t.id),{...t,updatedAt:new Date().toISOString()})},ie=async e=>{let t=await wm(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>et(e,va.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},Ca=async(e,t)=>{await km(as(e,t),{force:!0})},Tm=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";import{readFile as Rm,readdir as bm,rm as Pm}from"node:fs/promises";import Aa from"node:path";var ls=(e,t)=>Aa.join(e.reposDir,`${t}.json`),Ea=(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},pe=async(e,t)=>{let r=ls(e,t);try{let n=await Rm(r,"utf8");return Ea(JSON.parse(n),r)}catch(n){throw Sm(n)?new f("REPO_NOT_FOUND",`Craig repo "${t}" was not found.`,{details:{repoId:t}}):n instanceof SyntaxError||n instanceof Error&&n.message.startsWith("Craig repo record at ")?new f("REPO_RECORD_INVALID",n instanceof Error?n.message:`Craig repo "${t}" is invalid.`,{details:{repoId:t},cause:n}):n}},cs=async(e,t)=>{await M(ls(e,t.id),{...t,updatedAt:new Date().toISOString()})},zt=async e=>{let t=await bm(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>pe(e,Aa.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},xa=async(e,t)=>{await Pm(ls(e,t),{force:!0})},Sm=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";import{readFile as vm}from"node:fs/promises";var Im=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"},Rt=(e,t,r)=>{if(!Im(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},ne=async e=>{let t=await vm(e.indexFile,"utf8");return Rt(JSON.parse(t),e.workspaceRoot,e.indexFile)},Se=async(e,t)=>{await M(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as Dm,stat as Om}from"node:fs/promises";import Pt from"node:path";import{realpath as $a}from"node:fs/promises";import _r from"node:path";import{execFile as Cm}from"node:child_process";import{promisify as Am}from"node:util";var Da=Am(Cm);async function C(e,t,r={}){try{let n=await Da(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(Oa(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function O(e,t,r={}){try{let n=await Da(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(Oa(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function Oa(e){return e instanceof Error}var ds=async e=>{try{let r=(await C("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([$a(r).catch(()=>_r.resolve(r)),$a(e).catch(()=>_r.resolve(e))]);return n===s}catch{return!1}},us=async e=>{let t=await O("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 O("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await C("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"},Na=async e=>{let t=await O("git",["rev-parse","--path-format=absolute","--git-common-dir"],{cwd:e}),r=t.stdout.trim();if(t.exitCode!==0||r.length===0)return null;let n=_r.resolve(e,r);return _r.dirname(n)};import{mkdir as ae,readFile as Em}from"node:fs/promises";var xm=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",bt=async e=>{let t=re(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.commandsDir,{recursive:!0}),ae(t.eventsDir,{recursive:!0}),ae(t.orchestrationDir,{recursive:!0}),ae(t.logsDir,{recursive:!0}),ae(t.artifactsDir,{recursive:!0}),ae(t.worktreesDir,{recursive:!0})]);try{let s=await Em(t.indexFile,"utf8"),o=JSON.parse(s);return Rt(o,e,t.indexFile)}catch(s){if(!xm(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 M(t.indexFile,n),n};var Ma=(e,t,r)=>{let n=new Date().toISOString();return{id:$m(e,Pt.basename(t)),name:Pt.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},La=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},$m=(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},Nm=(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},_a=async(e,t)=>{let r=await ne(e);await Se(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},Mm=async(e,t)=>{let r=await Dm(t,{withFileTypes:!0}),n=await zt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Pt.join(t,o.name);if(!await ds(i))continue;let a=n.find(c=>c.rootPath===i)??s.find(c=>c.rootPath===i),l=await us(i);s.push(a?La(a,l):Ma([...n,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},Lm=async(e,t)=>{let r=await us(t),n=await zt(e),s=n.find(u=>u.rootPath===t)??null,o=s?La(s,r):Ma(n,t,r),i=`workspace_${o.id}`,l=(await ie(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 cs(e,o),l||await tt(e,d),await _a(e,{repoIds:[o.id],workspaceIds:[d.id]}),{kind:"createWorkspace",workspace:d,repos:[o],created:!l}},_m=async(e,t)=>{let r=await Mm(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await ie(e),s=Nm(n,Pt.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:Pt.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=>cs(e,c))),await tt(e,l),await _a(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!o}},Yt=async(e,t)=>{await bt(e.workspaceRoot);let r=Pt.resolve(e.workspaceRoot,t);if(!(await Om(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await ds(r)?Lm(e,r):_m(e,r)};var ps=async(e,t,r={listWorkspaceRecords:ie,ensureCraigState:bt})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var ms=async(e,t,r={readWorkspace:et,writeWorkspace:tt})=>{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 fs=async(e,t)=>{let n={...await et(e,t),status:"active",archivedAt:null};await tt(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 rt=async(e,t,r={deleteWorkspace:Ca,readCraigIndex:ne,writeCraigIndex:Se})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var gs=async(e,t,r)=>{let n=await et(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 rt(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};import{readFile as jm,realpath as Wa,stat as Fm}from"node:fs/promises";import jr from"node:path";async function hs(e){let t=await Ua(e.cwd,"Current working directory");if(e.explicitWorkspaceRoot!==void 0)return ja(e.explicitWorkspaceRoot,"explicit",t,e.allowUninitializedCwd??!1);if(e.environmentWorkspaceRoot!==void 0)return ja(e.environmentWorkspaceRoot,"environment",t,e.allowUninitializedCwd??!1);let r=await Fa(t);if(r)return{workspaceRoot:r,source:"ancestor",initialized:!0};let n=await Na(t);if(n){let s=await Fa(n);if(s)return{workspaceRoot:s,source:"git_common_dir",initialized:!0}}if(e.allowUninitializedCwd)return{workspaceRoot:t,source:"cwd",initialized:!1};throw new f("WORKSPACE_CONTEXT_NOT_FOUND",`No Craig workspace was found from ${t}. Use --workspace-root <path> or run Craig inside an initialized workspace.`,{details:{cwd:t}})}async function ja(e,t,r,n){let s=t==="explicit"?"Workspace root":"CRAIG_WORKSPACE_ROOT",o=await Ua(jr.resolve(r,e),s),i=await qa(o);if(i)return{workspaceRoot:i,source:t,initialized:!0};if(n)return{workspaceRoot:o,source:t,initialized:!1};throw new f("WORKSPACE_CONTEXT_NOT_FOUND",`${s} ${o} is not an initialized Craig workspace.`,{details:{workspaceRoot:o,source:t}})}async function Fa(e){let t=e;for(;;){let r=await qa(t);if(r)return r;let n=jr.dirname(t);if(n===t)return null;t=n}}async function qa(e){let t=re(e);try{let r=await jm(t.indexFile,"utf8"),n=JSON.parse(r),s=typeof n=="object"&&n!==null&&"workspaceRoot"in n&&typeof n.workspaceRoot=="string"?n.workspaceRoot:e,o=Rt(n,s,t.indexFile);if(await Wa(o.workspaceRoot).catch(()=>jr.resolve(o.workspaceRoot))!==e)throw new Error(`Craig index at ${t.indexFile} belongs to ${o.workspaceRoot}, not ${e}. Remove or repair the file before rerunning Craig.`);return o.workspaceRoot}catch(r){if(Wm(r))return null;throw r instanceof f?r:new f("WORKSPACE_CONTEXT_INVALID",r instanceof Error?r.message:`Craig workspace at ${e} is invalid.`,{details:{workspaceRoot:e},cause:r})}}async function Ua(e,t){let r=jr.resolve(e);try{if(!(await Fm(r)).isDirectory())throw new f("WORKSPACE_CONTEXT_INVALID",`${t} ${r} is not a directory.`,{details:{path:r}});return await Wa(r)}catch(n){throw n instanceof f?n:new f("WORKSPACE_CONTEXT_NOT_FOUND",`${t} ${r} does not exist or cannot be read.`,{details:{path:r},cause:n})}}function Wm(e){return typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT"}var ws={};Ar(ws,{addRepo:()=>Ba,listRegisteredRepos:()=>Va,removeRepo:()=>Ka});import qm from"node:path";import{stat as Um}from"node:fs/promises";var Ba=async(e,t)=>{let r=qm.resolve(e.workspaceRoot,t);if(!(await Um(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await Yt(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 Va=async(e,t={listRepos:zt,ensureCraigState:bt})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var Ka=async(e,t,r)=>{let n=await pe(e,t),o=(await ie(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=>rt(e,c.id))),await xa(e,t);let l=await ne(e);return await Se(e,{...l,repoIds:l.repoIds.filter(c=>c!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var J={addWorkspace:Yt,listWorkspaces:ps,archiveWorkspace:ms,restoreWorkspace:fs,removeWorkspace:gs,removeWorkspaceRecord:rt,resolveContext:hs,repos:ws};import{mkdir as Ga,readFile as Bm,rm as Wr,stat as Vm,writeFile as Km}from"node:fs/promises";import Fr from"node:path";var Gm=25,Hm=3e4,zm=5e3;async function _e(e,t,r){let n=Fr.join(e.runtimeDir,"task-locks"),s=Fr.join(n,`${t}.lock`);await Ga(n,{recursive:!0});let o=Date.now();for(;;)try{await Ga(s);try{await Km(Fr.join(s,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(i){throw await Wr(s,{recursive:!0,force:!0}),i}break}catch(i){if(!Xm(i))throw i;if(await Ym(s))continue;if(Date.now()-o>=Hm)throw new f("OPERATION_TIMEOUT",`Timed out waiting to update task ${t}.`,{retryable:!0,details:{taskId:t}});await Qm(Gm)}try{return await r()}finally{await Wr(s,{recursive:!0,force:!0})}}async function Ym(e){let t=await Bm(Fr.join(e,"owner.json"),"utf8").then(n=>JSON.parse(n)).catch(()=>null);if(t&&typeof t.pid=="number")return Jm(t.pid)?!1:(await Wr(e,{recursive:!0,force:!0}),!0);let r=await Vm(e).catch(()=>null);return!r||Date.now()-r.mtimeMs<zm?!1:(await Wr(e,{recursive:!0,force:!0}),!0)}function Jm(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var Xm=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST",Qm=e=>new Promise(t=>setTimeout(t,e));var ve=async(e,t)=>{let r=await Zm(qr(e,t),"utf8");return JSON.parse(r)},Jt=async(e,t)=>{let r=await ve(e,t);return ue(r,qr(e,t))},Ie=async(e,t)=>{let r=Ha(t);await M(qr(e,t.id),r)},x=async(e,t,r)=>_e(e,t,async()=>{let n=await Jt(e,t),s=await r(n);if(s.id!==t)throw new Error(`Task mutation cannot change task id ${t} to ${s.id}.`);let o=Ha(s);return await M(qr(e,t),o),o}),ks=async(e,t)=>{let r=await ne(e);r.taskIds.includes(t)||await Se(e,{...r,taskIds:[...r.taskIds,t]})},qr=(e,t)=>`${e.tasksDir}/${t}.json`,Ha=e=>({...e,updatedAt:new Date().toISOString()});var E=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,je=e=>e.status==="merged"||e.status==="closed",Ce=(e,t)=>{let r=e.prs.findIndex(s=>St(s,t)),n=r>=0?e.prs.map((s,o)=>o===r?t:s):[...e.prs,t];return{...e,prs:n}},St=(e,t)=>e.number===null||t.number===null||e.number!==t.number?!1:!e.owner||!e.repo||!t.owner||!t.repo?!0:e.owner.toLowerCase()===t.owner.toLowerCase()&&e.repo.toLowerCase()===t.repo.toLowerCase(),nt=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return Br(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},Br=e=>e.mergeable&&!ef(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),ef=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",ys=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),Ae=(e,t,r)=>{let n=e.isDraft??!1,s=tf(e.state,n);return{provider:"github",owner:r?.owner??t?.owner??null,repo:r?.name??t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:s,draft:n,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:rf(e.reviewDecision??null),requiredChecks:Ts(e.statusCheckRollup),comments:e.comments===void 0?t?.comments??[]:af(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}},tf=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,rf=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Ts=e=>{let t=e.map(n=>nf(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||sf(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},nf=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:Ya(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:of(t)}:null},sf=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Ur(e)&&!Ur(t)?!0:!Ur(e)&&Ur(t)?!1:za(t.status)>=za(e.status),Ur=e=>e.conclusion?.toUpperCase()==="CANCELLED",za=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},of=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},af=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(lf).filter(r=>r!==null).slice(-4):[]},lf=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=cf(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},cf=e=>e.replace(/\s+/g," ").trim(),Ya=(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?Ya(n,n):"unknown"};var ye=class extends Error{constructor(t){super(t),this.name="GitHubRateLimitError"}};import{access as df}from"node:fs/promises";import Ja from"node:path";var A=async(e,t,r={readRawTask:ve,validateTaskRecord:ue})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw gf(n)?new f("TASK_NOT_FOUND",`Craig task "${t}" was not found.`,{details:{taskId:t}}):hf(n)?new f("TASK_RECORD_INVALID",n instanceof Error?n.message:`Craig task "${t}" is invalid.`,{details:{taskId:t},cause:n}):n}},z=async e=>{if(!await Rs(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},vt=(e,t)=>t.artifacts.logPath?Ja.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:Ja.join(e.workspaceRoot,t.artifacts.logPath):null,Xt=async(e,t)=>{let r=await Rs(t.worktreePath),n=vt(e,t),s=n?await Rs(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:uf(t),lastCommitSummary:pf(t),prSummary:mf(t),cleanupSummary:ff(t)}},Rs=async e=>{try{return await df(e),!0}catch{return!1}},uf=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}`},pf=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",mf=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})
13
- ${o.join(`
14
- `)}`}let t=E(e);if(!t?.number||!t.url)return"not linked";let r=t.requiredChecks.length,n=r===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${r} ${n})`},ff=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",gf=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",hf=e=>e instanceof SyntaxError||e instanceof Error&&e.message.startsWith("Craig task record at ");var Xa=async(e,t)=>{let r=await O("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.")},bs=async(e,t,r,n="main")=>{let s=n.trim()||"main";if((await O("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 wf(e,s);await C("git",["worktree","add","-b",t,r,i],{cwd:e})},wf=async(e,t)=>(await O("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await O("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await O("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t,Vr=async e=>{let t=await O("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},Qa=async e=>{await C("git",["add","-A"],{cwd:e})},Za=async(e,t)=>{await C("git",["commit","-m",t],{cwd:e})},el=async e=>{let t=await C("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[r="",n=""]=t.stdout.trim().split(`
15
- `);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}},tl=async e=>{let t=await O("git",["branch","--show-current"],{cwd:e});if(t.exitCode!==0)return null;let r=t.stdout.trim();return r.length>0?r:null};var rl=async(e,t)=>{await C("git",["worktree","remove","--force",t],{cwd:e})};var Ps=async e=>It(e,e.repoRoot),It=async(e,t)=>{let r=await ne(e),n=nl(new Date),s=sl(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await Xa(t,i))return o;s+=1}},Qt=async e=>{let t=await ne(e),r=nl(new Date),n=sl(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},nl=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},sl=(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 Zt=async(e,t,r={readRawTask:ve,validateTaskRecord:ue})=>{let n=await ne(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(kf(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}},kf=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var ol=["merge_ready","pr_open","checked","review","running","draft"],Ss=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),vs=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(yf)[0]?.id??null,yf=(e,t)=>{let r=il(e.status),n=il(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},il=e=>{let t=ol.indexOf(e);return t>=0?t:ol.length};import al from"node:path";var st=(e,t)=>t?al.isAbsolute(t)?t:al.join(e.repoRoot,t):null;import{mkdir as er,rm as Tf,writeFile as Kr}from"node:fs/promises";import $ from"node:path";var cl=["AGENTS","md"].join("."),Ct=async(e,t,r,n={})=>{let s=await pe(e,t),[o,i]=await Promise.all([vf(e,s.id),It(e,s.rootPath)]),a=n.sessionId??null,l=`craig/${i}`,c=$.join(e.worktreesDir,s.id,i),d=$.join(e.logsDir,`${i}.log`),u=$.join(e.artifactsDir,i);await Promise.all([er($.dirname(c),{recursive:!0}),er(u,{recursive:!0}),Kr(d,"","utf8")]);let m=Rf(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 Ie(e,m),await ks(e,i),await bs(s.rootPath,l,c,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:a,workspaceId:o.id,task:m}},tr=async(e,t,r,n={})=>{let s=(await ie(e)).find(I=>I.id===t&&I.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 I=await Ct(e,s.primaryRepoId,r,n);return{...I,bundlePath:I.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await Qt(e),a=new Date().toISOString(),l=n.runner??"codex",c=n.sessionId??null,d=`craig/${i}`,u=$.join(e.craigDir,"task-bundles",i),m=$.join(e.logsDir,`${i}.log`),p=$.join(e.artifactsDir,i);await er(u,{recursive:!0}),await er(p,{recursive:!0}),await Kr(m,"","utf8");let k=await Promise.all(o.map(I=>pe(e,I))),w=Pf(k),b=await Promise.all(k.map(I=>bf(e,I,i,d,$.join(u,w.get(I.id))))),N=b.find(I=>I.status==="ready")??b[0];if(!b.some(I=>I.status==="ready"))throw await Tf(u,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${b.map(I=>`${I.repoId}: ${I.failureReason??"unknown error"}`).join("; ")}`);await Kr($.join(u,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:b.map(I=>({repoId:I.repoId,repoName:k.find(ce=>ce.id===I.repoId)?.name??I.repoId,path:$.relative(u,I.worktreePath),status:I.status,worktreePath:I.worktreePath,failureReason:I.failureReason}))},null,2),"utf8"),await Kr($.join(u,cl),Sf({taskId:i,workspaceId:t,prompt:r,repos:k,repoTargets:b,bundlePath:u}),"utf8");let _=rr(i,r,a,l,n.config??{}),Y={id:i,title:r,slug:dl(r),type:"project",status:"draft",runner:l,repoId:N.repoId,workspaceId:s.id,sessionId:c,selectedPtyTabId:_[0]?.id??null,linkedRepoIds:o.filter(I=>I!==N.repoId),repoRoot:u,worktreePath:u,branch:d,bundlePath:u,selectedRepoTargetId:N.repoId,repoTargets:b,ptyTabs:_,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:N.checks,lastCommit:null,prs:[],artifacts:{logPath:$.relative(e.workspaceRoot,m),checkSummaryPath:$.relative(e.workspaceRoot,$.join(p,"check-summary.json")),prDraftPath:null,prStatusPath:$.relative(e.workspaceRoot,$.join(p,"pr-status.json"))},cleanup:Gr(),lastFailureReason:b.every(I=>I.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:a,updatedAt:a};return await Ie(e,Y),await ks(e,i),{repoId:N.repoId,repoRoot:u,sessionId:c,workspaceId:s.id,task:Y,bundlePath:u,repoTargets:b}},rr=(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}]},Rf=(e,t)=>{let r=new Date().toISOString(),n=rr(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:dl(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:{...Is($.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:$.relative(e.workspaceRoot,$.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:$.relative(e.workspaceRoot,$.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:$.relative(e.workspaceRoot,$.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:Gr(),lastFailureReason:null,createdAt:r,updatedAt:r}},bf=async(e,t,r,n,s)=>{await er($.dirname(s),{recursive:!0});try{return await bs(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:Is($.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:ll(),cleanup:Gr()}}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:Is($.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:ll(),cleanup:Gr()}}},Pf=e=>{let t=new Set(["manifest.json",cl]),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},Sf=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=$.relative(e.bundlePath,n.worktreePath),i=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${n.repoId}, ${i})`}).join(`
12
+ ${ss()}`,{})}var ue=(e,t)=>{let r=as(e);if(!am(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},as=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:ls(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:dm(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:lm(t.repoTargets),runnerSession:t.runnerSession??om(t),checks:wm(t),lastCommit:t.lastCommit??null,prs:km(t),artifacts:bm(t),cleanup:Pm(t)}},om=e=>{if(typeof e.title!="string")return null;let t=ls(e.runner);return{command:w.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},am=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"&&w.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"&&Pa(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||cm(t.repoTargets))&&pm(t.runnerSession)&&mm(t.prompt)&&Sa(t.checks)&&va(t.lastCommit)&&gm(t.prs)&&hm(t.artifacts)&&Ca(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},lm=e=>{if(Array.isArray(e))return e.filter(ba)},cm=e=>Array.isArray(e)&&e.every(ba),ba=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)&&Sa(t.checks)&&va(t.lastCommit)&&Ia(t.pullRequest)&&Ca(t.cleanup)},dm=e=>{if(Pa(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 um(e.id,e.title,t,ls(e.runner))},um=(e,t,r,n)=>{let s=w.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:w.runners.buildCommand(n),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},ls=e=>e&&w.runners.isRunnerType(e)?e:"codex",Pa=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"),pm=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),mm=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",Sa=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"),va=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",Ia=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&fm(e.requiredChecks),fm=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)),gm=e=>Array.isArray(e)&&e.every(Ia),hm=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),Ca=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),wm=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},km=e=>{if(Array.isArray(e.prs))return e.prs.map(ym);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:Aa(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Ea(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},ym=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:Aa(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Tm(t.reviewDecision),requiredChecks:Ea(t.requiredChecks),comments:Rm(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},Aa=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,Tm=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Rm=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}]}):[],Ea=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})):[],bm=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},Pm=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as lf}from"node:fs/promises";import{readFile as Sm,readdir as vm,rm as Im}from"node:fs/promises";import xa from"node:path";var cs=(e,t)=>xa.join(e.workspacesDir,`${t}.json`),Cm=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"):[]}},Da=(e,t)=>{let r=Cm(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},st=async(e,t)=>{let r=cs(e,t);try{let n=await Sm(r,"utf8");return Da(JSON.parse(n),r)}catch(n){throw Am(n)?new g("WORKSPACE_NOT_FOUND",`Craig workspace "${t}" was not found.`,{details:{workspaceId:t}}):n instanceof SyntaxError||n instanceof Error&&n.message.startsWith("Craig workspace record at ")?new g("WORKSPACE_RECORD_INVALID",n instanceof Error?n.message:`Craig workspace "${t}" is invalid.`,{details:{workspaceId:t},cause:n}):n}},it=async(e,t)=>{await L(cs(e,t.id),{...t,updatedAt:new Date().toISOString()})},ae=async e=>{let t=await vm(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>st(e,xa.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},Oa=async(e,t)=>{await Im(cs(e,t),{force:!0})},Am=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";import{readFile as Em,readdir as xm,rm as Dm}from"node:fs/promises";import $a from"node:path";var ds=(e,t)=>$a.join(e.reposDir,`${t}.json`),Ma=(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},pe=async(e,t)=>{let r=ds(e,t);try{let n=await Em(r,"utf8");return Ma(JSON.parse(n),r)}catch(n){throw Om(n)?new g("REPO_NOT_FOUND",`Craig repo "${t}" was not found.`,{details:{repoId:t}}):n instanceof SyntaxError||n instanceof Error&&n.message.startsWith("Craig repo record at ")?new g("REPO_RECORD_INVALID",n instanceof Error?n.message:`Craig repo "${t}" is invalid.`,{details:{repoId:t},cause:n}):n}},us=async(e,t)=>{await L(ds(e,t.id),{...t,updatedAt:new Date().toISOString()})},Jt=async e=>{let t=await xm(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>pe(e,$a.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Na=async(e,t)=>{await Dm(ds(e,t),{force:!0})},Om=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";import{readFile as $m}from"node:fs/promises";var Mm=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"},Pt=(e,t,r)=>{if(!Mm(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},se=async e=>{let t=await $m(e.indexFile,"utf8");return Pt(JSON.parse(t),e.workspaceRoot,e.indexFile)},ve=async(e,t)=>{await L(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as Fm,stat as Wm}from"node:fs/promises";import vt from"node:path";import{realpath as ja}from"node:fs/promises";import Wr from"node:path";import{execFile as Nm}from"node:child_process";import{promisify as Lm}from"node:util";var La=Lm(Nm);async function C(e,t,r={}){try{let n=await La(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(_a(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function $(e,t,r={}){try{let n=await La(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(_a(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function _a(e){return e instanceof Error}var ps=async e=>{try{let r=(await C("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([ja(r).catch(()=>Wr.resolve(r)),ja(e).catch(()=>Wr.resolve(e))]);return n===s}catch{return!1}},ms=async e=>{let t=await $("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 i of["main","master","trunk"])if((await $("git",["show-ref","--verify","--quiet",`refs/heads/${i}`],{cwd:e})).exitCode===0)return i;let s=(await C("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"},Fa=async e=>{let t=await $("git",["rev-parse","--path-format=absolute","--git-common-dir"],{cwd:e}),r=t.stdout.trim();if(t.exitCode!==0||r.length===0)return null;let n=Wr.resolve(e,r);return Wr.dirname(n)};import{mkdir as le,readFile as _m}from"node:fs/promises";var jm=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",St=async e=>{let t=ne(e);await le(t.craigDir,{recursive:!0}),await Promise.all([le(t.reposDir,{recursive:!0}),le(t.workspacesDir,{recursive:!0}),le(t.sessionsDir,{recursive:!0}),le(t.runtimeDir,{recursive:!0}),le(t.tasksDir,{recursive:!0}),le(t.jobsDir,{recursive:!0}),le(t.commandsDir,{recursive:!0}),le(t.eventsDir,{recursive:!0}),le(t.orchestrationDir,{recursive:!0}),le(t.logsDir,{recursive:!0}),le(t.artifactsDir,{recursive:!0}),le(t.worktreesDir,{recursive:!0})]);try{let s=await _m(t.indexFile,"utf8"),i=JSON.parse(s);return Pt(i,e,t.indexFile)}catch(s){if(!jm(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 L(t.indexFile,n),n};var Wa=(e,t,r)=>{let n=new Date().toISOString();return{id:qm(e,vt.basename(t)),name:vt.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},qa=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},qm=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",n=`repo_${r}`,s=2;for(;e.some(i=>i.id===n);)n=`repo_${r}_${s}`,s+=1;return n},Um=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",n=`workspace_${r}`,s=2;for(;e.some(i=>i.id===n);)n=`workspace_${r}_${s}`,s+=1;return n},Ua=async(e,t)=>{let r=await se(e);await ve(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},Vm=async(e,t)=>{let r=await Fm(t,{withFileTypes:!0}),n=await Jt(e),s=[];for(let i of r){if(!i.isDirectory()||i.name.startsWith("."))continue;let o=vt.join(t,i.name);if(!await ps(o))continue;let a=n.find(c=>c.rootPath===o)??s.find(c=>c.rootPath===o),l=await ms(o);s.push(a?qa(a,l):Wa([...n,...s],o,l))}return s.sort((i,o)=>i.name.localeCompare(o.name)||i.id.localeCompare(o.id))},Bm=async(e,t)=>{let r=await ms(t),n=await Jt(e),s=n.find(u=>u.rootPath===t)??null,i=s?qa(s,r):Wa(n,t,r),o=`workspace_${i.id}`,l=(await ae(e)).find(u=>u.id===o)??null,c=new Date().toISOString(),d=l??{id:o,kind:"repo",name:i.name,rootPath:t,primaryRepoId:i.id,repoId:i.id,discoveredRepoIds:[i.id],branch:r,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:c,updatedAt:c};return await us(e,i),l||await it(e,d),await Ua(e,{repoIds:[i.id],workspaceIds:[d.id]}),{kind:"createWorkspace",workspace:d,repos:[i],created:!l}},Km=async(e,t)=>{let r=await Vm(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await ae(e),s=Um(n,vt.basename(t)),i=n.find(c=>c.kind==="project"&&c.rootPath===t)??null,o=new Date().toISOString(),a=r.map(c=>c.id),l=i?{...i,discoveredRepoIds:a,primaryRepoId:a[0]??i.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:vt.basename(t),rootPath:t,primaryRepoId:a[0]??"",discoveredRepoIds:a,branch:"project",status:"active",linkedRepoIds:a,archivedAt:null,createdAt:o,updatedAt:o};return await Promise.all(r.map(c=>us(e,c))),await it(e,l),await Ua(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!i}},Xt=async(e,t)=>{await St(e.workspaceRoot);let r=vt.resolve(e.workspaceRoot,t);if(!(await Wm(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await ps(r)?Bm(e,r):Km(e,r)};var fs=async(e,t,r={listWorkspaceRecords:ae,ensureCraigState:St})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var gs=async(e,t,r={readWorkspace:st,writeWorkspace:it})=>{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 hs=async(e,t)=>{let n={...await st(e,t),status:"active",archivedAt:null};await it(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 ot=async(e,t,r={deleteWorkspace:Oa,readCraigIndex:se,writeCraigIndex:ve})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var ws=async(e,t,r)=>{let n=await st(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 ot(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};import{readFile as Gm,realpath as Ka,stat as Hm}from"node:fs/promises";import qr from"node:path";async function ks(e){let t=await Ha(e.cwd,"Current working directory");if(e.explicitWorkspaceRoot!==void 0)return Va(e.explicitWorkspaceRoot,"explicit",t,e.allowUninitializedCwd??!1);if(e.environmentWorkspaceRoot!==void 0)return Va(e.environmentWorkspaceRoot,"environment",t,e.allowUninitializedCwd??!1);let r=await Ba(t);if(r)return{workspaceRoot:r,source:"ancestor",initialized:!0};let n=await Fa(t);if(n){let s=await Ba(n);if(s)return{workspaceRoot:s,source:"git_common_dir",initialized:!0}}if(e.allowUninitializedCwd)return{workspaceRoot:t,source:"cwd",initialized:!1};throw new g("WORKSPACE_CONTEXT_NOT_FOUND",`No Craig workspace was found from ${t}. Use --workspace-root <path> or run Craig inside an initialized workspace.`,{details:{cwd:t}})}async function Va(e,t,r,n){let s=t==="explicit"?"Workspace root":"CRAIG_WORKSPACE_ROOT",i=await Ha(qr.resolve(r,e),s),o=await Ga(i);if(o)return{workspaceRoot:o,source:t,initialized:!0};if(n)return{workspaceRoot:i,source:t,initialized:!1};throw new g("WORKSPACE_CONTEXT_NOT_FOUND",`${s} ${i} is not an initialized Craig workspace.`,{details:{workspaceRoot:i,source:t}})}async function Ba(e){let t=e;for(;;){let r=await Ga(t);if(r)return r;let n=qr.dirname(t);if(n===t)return null;t=n}}async function Ga(e){let t=ne(e);try{let r=await Gm(t.indexFile,"utf8"),n=JSON.parse(r),s=typeof n=="object"&&n!==null&&"workspaceRoot"in n&&typeof n.workspaceRoot=="string"?n.workspaceRoot:e,i=Pt(n,s,t.indexFile);if(await Ka(i.workspaceRoot).catch(()=>qr.resolve(i.workspaceRoot))!==e)throw new Error(`Craig index at ${t.indexFile} belongs to ${i.workspaceRoot}, not ${e}. Remove or repair the file before rerunning Craig.`);return i.workspaceRoot}catch(r){if(zm(r))return null;throw r instanceof g?r:new g("WORKSPACE_CONTEXT_INVALID",r instanceof Error?r.message:`Craig workspace at ${e} is invalid.`,{details:{workspaceRoot:e},cause:r})}}async function Ha(e,t){let r=qr.resolve(e);try{if(!(await Hm(r)).isDirectory())throw new g("WORKSPACE_CONTEXT_INVALID",`${t} ${r} is not a directory.`,{details:{path:r}});return await Ka(r)}catch(n){throw n instanceof g?n:new g("WORKSPACE_CONTEXT_NOT_FOUND",`${t} ${r} does not exist or cannot be read.`,{details:{path:r},cause:n})}}function zm(e){return typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT"}var ys={};Dr(ys,{addRepo:()=>za,listRegisteredRepos:()=>Ya,removeRepo:()=>Ja});import Ym from"node:path";import{stat as Jm}from"node:fs/promises";var za=async(e,t)=>{let r=Ym.resolve(e.workspaceRoot,t);if(!(await Jm(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await Xt(e,t),i=s.repos[0];if(!i||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${r}`);return{kind:"createRepo",repo:i,workspaceId:s.workspace.id,created:s.created}};var Ya=async(e,t={listRepos:Jt,ensureCraigState:St})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var Ja=async(e,t,r)=>{let n=await pe(e,t),i=(await ae(e)).filter(c=>c.primaryRepoId===t),o=i.filter(c=>c.status==="active"),a=await r.listTasks(e,{repoId:t});if(o.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(i.map(c=>ot(e,c.id))),await Na(e,t);let l=await se(e);return await ve(e,{...l,repoIds:l.repoIds.filter(c=>c!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var X={addWorkspace:Xt,listWorkspaces:fs,archiveWorkspace:gs,restoreWorkspace:hs,removeWorkspace:ws,removeWorkspaceRecord:ot,resolveContext:ks,repos:ys};import{mkdir as Xa,readFile as Xm,rm as Vr,stat as Qm,writeFile as Zm}from"node:fs/promises";import Ur from"node:path";var ef=25,tf=3e4,rf=5e3;async function We(e,t,r){let n=Ur.join(e.runtimeDir,"task-locks"),s=Ur.join(n,`${t}.lock`);await Xa(n,{recursive:!0});let i=Date.now();for(;;)try{await Xa(s);try{await Zm(Ur.join(s,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(o){throw await Vr(s,{recursive:!0,force:!0}),o}break}catch(o){if(!of(o))throw o;if(await nf(s))continue;if(Date.now()-i>=tf)throw new g("OPERATION_TIMEOUT",`Timed out waiting to update task ${t}.`,{retryable:!0,details:{taskId:t}});await af(ef)}try{return await r()}finally{await Vr(s,{recursive:!0,force:!0})}}async function nf(e){let t=await Xm(Ur.join(e,"owner.json"),"utf8").then(n=>JSON.parse(n)).catch(()=>null);if(t&&typeof t.pid=="number")return sf(t.pid)?!1:(await Vr(e,{recursive:!0,force:!0}),!0);let r=await Qm(e).catch(()=>null);return!r||Date.now()-r.mtimeMs<rf?!1:(await Vr(e,{recursive:!0,force:!0}),!0)}function sf(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var of=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST",af=e=>new Promise(t=>setTimeout(t,e));var Ie=async(e,t)=>{let r=await lf(Br(e,t),"utf8");return JSON.parse(r)},Qt=async(e,t)=>{let r=await Ie(e,t);return ue(r,Br(e,t))},Ce=async(e,t)=>{let r=Qa(t);await L(Br(e,t.id),r)},x=async(e,t,r)=>We(e,t,async()=>{let n=await Qt(e,t),s=await r(n);if(s.id!==t)throw new Error(`Task mutation cannot change task id ${t} to ${s.id}.`);let i=Qa(s);return await L(Br(e,t),i),i}),Ts=async(e,t)=>{let r=await se(e);r.taskIds.includes(t)||await ve(e,{...r,taskIds:[...r.taskIds,t]})},Br=(e,t)=>`${e.tasksDir}/${t}.json`,Qa=e=>({...e,updatedAt:new Date().toISOString()});var E=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,qe=e=>e.status==="merged"||e.status==="closed",Ae=(e,t)=>{let r=e.prs.findIndex(s=>It(s,t)),n=r>=0?e.prs.map((s,i)=>i===r?t:s):[...e.prs,t];return{...e,prs:n}},It=(e,t)=>e.number===null||t.number===null||e.number!==t.number?!1:!e.owner||!e.repo||!t.owner||!t.repo?!0:e.owner.toLowerCase()===t.owner.toLowerCase()&&e.repo.toLowerCase()===t.repo.toLowerCase(),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 Gr(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},Gr=e=>e.mergeable&&!cf(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),cf=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",Rs=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),Ee=(e,t,r)=>{let n=e.isDraft??!1,s=df(e.state,n);return{provider:"github",owner:r?.owner??t?.owner??null,repo:r?.name??t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:s,draft:n,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:uf(e.reviewDecision??null),requiredChecks:bs(e.statusCheckRollup),comments:e.comments===void 0?t?.comments??[]:gf(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}},df=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,uf=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,bs=e=>{let t=e.map(n=>pf(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||mf(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},pf=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:el(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:ff(t)}:null},mf=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Kr(e)&&!Kr(t)?!0:!Kr(e)&&Kr(t)?!1:Za(t.status)>=Za(e.status),Kr=e=>e.conclusion?.toUpperCase()==="CANCELLED",Za=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},ff=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},gf=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(hf).filter(r=>r!==null).slice(-4):[]},hf=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=wf(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},wf=e=>e.replace(/\s+/g," ").trim(),el=(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?el(n,n):"unknown"};var me=class extends Error{constructor(t){super(t),this.name="GitHubRateLimitError"}};import{access as kf}from"node:fs/promises";import tl from"node:path";var A=async(e,t,r={readRawTask:Ie,validateTaskRecord:ue})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Pf(n)?new g("TASK_NOT_FOUND",`Craig task "${t}" was not found.`,{details:{taskId:t}}):Sf(n)?new g("TASK_RECORD_INVALID",n instanceof Error?n.message:`Craig task "${t}" is invalid.`,{details:{taskId:t},cause:n}):n}},J=async e=>{if(!await Ps(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},Ct=(e,t)=>t.artifacts.logPath?tl.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:tl.join(e.workspaceRoot,t.artifacts.logPath):null,Zt=async(e,t)=>{let r=await Ps(t.worktreePath),n=Ct(e,t),s=n?await Ps(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:yf(t),lastCommitSummary:Tf(t),prSummary:Rf(t),cleanupSummary:bf(t)}},Ps=async e=>{try{return await kf(e),!0}catch{return!1}},yf=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}`},Tf=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",Rf=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 i=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),o=s.reduce((l,c)=>{let d=c.pullRequest.status??"unknown";return l[d]=(l[d]??0)+1,l},{}),a=Object.entries(o).map(([l,c])=>`${c} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${a})
13
+ ${i.join(`
14
+ `)}`}let t=E(e);if(!t?.number||!t.url)return"not linked";let r=t.requiredChecks.length,n=r===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${r} ${n})`},bf=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",Pf=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Sf=e=>e instanceof SyntaxError||e instanceof Error&&e.message.startsWith("Craig task record at ");var rl=async(e,t)=>{let r=await $("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.")},Ss=async(e,t,r,n="main")=>{let s=n.trim()||"main";if((await $("git",["show-ref","--verify","--quiet",`refs/heads/${s}`],{cwd:e})).exitCode!==0)throw new Error(`Base branch '${s}' does not exist locally.`);let o=await vf(e,s);await C("git",["worktree","add","-b",t,r,o],{cwd:e})},vf=async(e,t)=>(await $("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await $("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await $("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t,Hr=async e=>{let t=await $("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},nl=async e=>{await C("git",["add","-A"],{cwd:e})},sl=async(e,t)=>{await C("git",["commit","-m",t],{cwd:e})},il=async e=>{let t=await C("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[r="",n=""]=t.stdout.trim().split(`
15
+ `);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}},ol=async e=>{let t=await $("git",["branch","--show-current"],{cwd:e});if(t.exitCode!==0)return null;let r=t.stdout.trim();return r.length>0?r:null};var al=async(e,t)=>{await C("git",["worktree","remove","--force",t],{cwd:e})};var vs=async e=>At(e,e.repoRoot),At=async(e,t)=>{let r=await se(e),n=ll(new Date),s=cl(r.taskIds,n);for(;;){let i=`task_${n}_${String(s).padStart(2,"0")}`,o=`craig/${i}`;if(!await rl(t,o))return i;s+=1}},er=async e=>{let t=await se(e),r=ll(new Date),n=cl(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},ll=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},cl=(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 tr=async(e,t,r={readRawTask:Ie,validateTaskRecord:ue})=>{let n=await se(e),s=[],i=[];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(If(c)){i.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)),i.sort(),{kind:"listTasks",tasks:a,missingTaskIds:i,repoId:t?.repoId??null}},If=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var dl=["merge_ready","pr_open","checked","review","running","draft"],Is=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),Cs=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(Cf)[0]?.id??null,Cf=(e,t)=>{let r=ul(e.status),n=ul(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},ul=e=>{let t=dl.indexOf(e);return t>=0?t:dl.length};import pl from"node:path";var lt=(e,t)=>t?pl.isAbsolute(t)?t:pl.join(e.repoRoot,t):null;import{mkdir as rr,rm as Af,writeFile as zr}from"node:fs/promises";import M from"node:path";var fl=["AGENTS","md"].join("."),Et=async(e,t,r,n={})=>{let s=await pe(e,t),[i,o]=await Promise.all([$f(e,s.id),At(e,s.rootPath)]),a=n.sessionId??null,l=`craig/${o}`,c=M.join(e.worktreesDir,s.id,o),d=M.join(e.logsDir,`${o}.log`),u=M.join(e.artifactsDir,o);await Promise.all([rr(M.dirname(c),{recursive:!0}),rr(u,{recursive:!0}),zr(d,"","utf8")]);let f=Ef(e,{taskId:o,repoId:s.id,workspaceId:i.id,sessionId:a,repoRoot:s.rootPath,prompt:r,runner:n.runner??"codex",config:n.config??{},branch:l,worktreePath:c});return await Ce(e,f),await Ts(e,o),await Ss(s.rootPath,l,c,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:a,workspaceId:i.id,task:f}},nr=async(e,t,r,n={})=>{let s=(await ae(e)).find(I=>I.id===t&&I.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 I=await Et(e,s.primaryRepoId,r,n);return{...I,bundlePath:I.task.worktreePath,repoTargets:[]}}let i=s.discoveredRepoIds??[];if(i.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let o=await er(e),a=new Date().toISOString(),l=n.runner??"codex",c=n.sessionId??null,d=`craig/${o}`,u=M.join(e.craigDir,"task-bundles",o),f=M.join(e.logsDir,`${o}.log`),h=M.join(e.artifactsDir,o);await rr(u,{recursive:!0}),await rr(h,{recursive:!0}),await zr(f,"","utf8");let m=await Promise.all(i.map(I=>pe(e,I))),k=Df(m),b=await Promise.all(m.map(I=>xf(e,I,o,d,M.join(u,k.get(I.id))))),O=b.find(I=>I.status==="ready")??b[0];if(!b.some(I=>I.status==="ready"))throw await Af(u,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${b.map(I=>`${I.repoId}: ${I.failureReason??"unknown error"}`).join("; ")}`);await zr(M.join(u,"manifest.json"),JSON.stringify({taskId:o,workspaceId:t,prompt:r,repos:b.map(I=>({repoId:I.repoId,repoName:m.find(te=>te.id===I.repoId)?.name??I.repoId,path:M.relative(u,I.worktreePath),status:I.status,worktreePath:I.worktreePath,failureReason:I.failureReason}))},null,2),"utf8"),await zr(M.join(u,fl),Of({taskId:o,workspaceId:t,prompt:r,repos:m,repoTargets:b,bundlePath:u}),"utf8");let q=sr(o,r,a,l,n.config??{}),U={id:o,title:r,slug:gl(r),type:"project",status:"draft",runner:l,repoId:O.repoId,workspaceId:s.id,sessionId:c,selectedPtyTabId:q[0]?.id??null,linkedRepoIds:i.filter(I=>I!==O.repoId),repoRoot:u,worktreePath:u,branch:d,bundlePath:u,selectedRepoTargetId:O.repoId,repoTargets:b,ptyTabs:q,runnerSession:{command:w.runners.buildCommand(l,r,n.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:r},checks:O.checks,lastCommit:null,prs:[],artifacts:{logPath:M.relative(e.workspaceRoot,f),checkSummaryPath:M.relative(e.workspaceRoot,M.join(h,"check-summary.json")),prDraftPath:null,prStatusPath:M.relative(e.workspaceRoot,M.join(h,"pr-status.json"))},cleanup:Yr(),lastFailureReason:b.every(I=>I.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:a,updatedAt:a};return await Ce(e,U),await Ts(e,o),{repoId:O.repoId,repoRoot:u,sessionId:c,workspaceId:s.id,task:U,bundlePath:u,repoTargets:b}},sr=(e,t,r,n="codex",s={})=>{let i=w.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:i.defaultAgentTitle,command:w.runners.buildCommand(n,void 0,s),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Ef=(e,t)=>{let r=new Date().toISOString(),n=sr(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:gl(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:w.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:{...As(M.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:M.relative(e.workspaceRoot,M.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:M.relative(e.workspaceRoot,M.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:M.relative(e.workspaceRoot,M.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:Yr(),lastFailureReason:null,createdAt:r,updatedAt:r}},xf=async(e,t,r,n,s)=>{await rr(M.dirname(s),{recursive:!0});try{return await Ss(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:As(M.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:ml(),cleanup:Yr()}}catch(i){return{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:i instanceof Error?i.message:"Failed to create worktree.",checks:As(M.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:ml(),cleanup:Yr()}}},Df=e=>{let t=new Set(["manifest.json",fl]),r=new Map;for(let n of e){let s=t.has(n.name)?`${n.name}-repo`:n.name,i=s,o=2;for(;t.has(i);)i=`${s}-${o}`,o+=1;t.add(i),r.set(n.id,i)}return r},Of=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,i=M.relative(e.bundlePath,n.worktreePath),o=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${i}/\` - ${s} (${n.repoId}, ${o})`}).join(`
16
16
  `);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(`
17
- `)},Is=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),ll=()=>({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}),Gr=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),vf=async(e,t)=>{let n=(await ie(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!n)throw new Error(`Repo ${t} does not have an active workspace.`);return n},dl=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import Rl from"node:path";import{readFile as If,rm as GS}from"node:fs/promises";import Cf from"node:path";var Fe=async(e,t)=>{let r=await If(Cs(e,t),"utf8"),n=JSON.parse(r);return Af(n,Cs(e,t))},ot=async(e,t)=>{await M(Cs(e,t.id),{...t,updatedAt:new Date().toISOString()})};var Cs=(e,t)=>Cf.join(e.sessionsDir,`${t}.json`);function Af(e,t){let r=Df(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")||!xf(r.attach)||!Ef(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 Ef(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 xf(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 Df(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 Of}from"node:child_process";import{createHash as $f}from"node:crypto";import Nf from"node:path";function Hr(e){return`'${e.replace(/'/g,"'\\''")}'`}var Mf="craig",ul=async(e,t,r)=>{let n=As(e,t),s=_f(),o=await C("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=Ff(o.stdout);return await Lf(e,n),i};var Lf=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 C("tmux",n,{cwd:e})},pl=async(e,t,r)=>{await C("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},ml=async(e,t,r)=>{await C("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var fl=async(e,t,r)=>{await C("tmux",["pipe-pane","-o","-t",e,`cat >> ${Hr(t)}`],{cwd:r})},zr=async(e,t,r,n)=>{let s=n??hl(e);if(r?await C("tmux",["select-window","-t",r],{cwd:e}):await C("tmux",["select-window","-t",t],{cwd:e}),await C("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await C("tmux",["switch-client","-t",s],{cwd:e});return}await qf(e,["attach-session","-t",s])};var gl=async(e,t)=>{await C("tmux",["kill-session","-t",t],{cwd:e})};var hl=e=>{let r=Nf.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=$f("sha1").update(e).digest("hex").slice(0,8);return`${Mf}-${r}-${n}`},As=(e,t)=>`${hl(e)}-${t.toLowerCase()}`,_f=()=>{let e=jf();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},jf=()=>{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},Ff=e=>{let t=Wf(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]}},Wf=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),qf=async(e,t)=>{await new Promise((r,n)=>{let s=Of("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 Uf,constants as Bf}from"node:fs";import{homedir as wl}from"node:os";import We from"node:path";var Vf=[We.join(wl(),".local","bin"),We.join(wl(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function yl(e=process.env){return Kf([...(e.PATH??"").split(We.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:Vf])}function it(e=process.env){return{...e,PATH:yl(e).join(We.delimiter)}}function Es(e,t={}){if(e.includes(We.sep)){let r=We.isAbsolute(e)?e:We.resolve(t.cwd??process.cwd(),e);return kl(r)?r:null}for(let r of yl(t.env)){let n=We.join(r,e);if(kl(n))return n}return null}function at(e,t={}){let r=Es(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 kl(e){try{return Uf(e,Bf.X_OK),!0}catch{return!1}}function Kf(e){return[...new Set(e)]}var nr={async create(e,t){let r=await ul(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await fl(r.paneId,t.logPath,t.repoRoot);let n=await Tl({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||As(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 ot(e,s),s},async attach(e,t,r){let n=await nr.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await zr(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await ot(e,s),s},async resize(e,t,r,n){await pl(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await ot(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 ot(e,n),n},async snapshot(e,t){return Gf(e,t)}},xs={async prepare(e,t){let n=e.runnerSession.command[0],s=it();at(n,{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=at(r[0],{cwd:e.worktreePath,env:it()});await ml(t.session.paneId,[n,...r.slice(1)].map(s=>Hr(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},Gf=async(e,t)=>{let r=await O("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Tl({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},Tl=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var Ds=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 tr(e,n.workspaceId,s,{runner:i,config:o}):await Ct(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?Rl.resolve(e.workspaceRoot,l.artifacts.logPath):Rl.join(e.logsDir,`${l.id}.log`);try{await xs.prepare(l,{repoRoot:a.repoRoot});let m=await nr.create(e,{sessionId:d,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:u,command:c});await xs.launch(l,{repoRoot:a.repoRoot,session:m});let p=new Date().toISOString();m={...m,status:"running",startedAt:p,command:c};let k=await x(e,l.id,w=>({...w,status:"running",runner:i,sessionId:m.id,selectedPtyTabId:w.selectedPtyTabId,runnerSession:{command:m.command,pid:null,startedAt:p,lastKnownState:"running",exitCode:null,exitedAt:null}}));return await ot(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){throw await x(e,l.id,p=>({...p,sessionId:null,status:"draft",runnerSession:{...p.runnerSession,lastKnownState:"failed"},lastFailureReason:m instanceof Error?m.message:"Unknown Craig error"})),m}};import{mkdir as Qf}from"node:fs/promises";import Zf from"node:path";var qe=async e=>{let t=await O("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var bl=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await C("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},At=async(e,t)=>{let r=await C("gh",Os(e),{cwd:t});return JSON.parse(r.stdout)},Et=async(e,t)=>{let r=await O("gh",Os(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},Pl=async(e,t)=>{let r=await O("gh",Os(e),{cwd:t});if(r.exitCode===0)return JSON.parse(r.stdout);let n=r.stderr.trim()||r.stdout.trim();if(zf(n))return null;throw new Error(n||`GitHub CLI failed while discovering a pull request for ${e}.`)},Sl=async(e,t,r)=>{if(r.length===0)return[];let n=Jf(r),s;try{s=await C("gh",["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`])}catch(a){throw Hf(a)?new ye(a instanceof Error?a.message:String(a)):a}let i=JSON.parse(s.stdout).data?.repository??{};return r.map((a,l)=>{let c=i[`item${l}`],d=Xf(c);return{id:a.id,found:d!==null,view:d}})},Yr=async e=>{let t=await O("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:Yf(t.stdout.trim())},Ue=e=>{let t=e.trim().match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/([1-9]\d*)(?:[/?#].*)?$/);return!t?.[1]||!t[2]||!t[3]?null:{owner:t[1],name:t[2],number:Number(t[3])}},Hf=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")},zf=e=>{let t=e.toLowerCase();return t.includes("no pull requests found")||t.includes("could not resolve to a pullrequest")},Os=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],Yf=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},Jf=e=>`
17
+ `)},As=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),ml=()=>({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}),Yr=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),$f=async(e,t)=>{let n=(await ae(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},gl=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import Il from"node:path";import{readFile as Mf,rm as av}from"node:fs/promises";import Nf from"node:path";var Ue=async(e,t)=>{let r=await Mf(Es(e,t),"utf8"),n=JSON.parse(r);return Lf(n,Es(e,t))},ct=async(e,t)=>{await L(Es(e,t.id),{...t,updatedAt:new Date().toISOString()})};var Es=(e,t)=>Nf.join(e.sessionsDir,`${t}.json`);function Lf(e,t){let r=Ff(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")||!jf(r.attach)||!_f(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 _f(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 jf(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 Ff(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 Wf}from"node:child_process";import{createHash as qf}from"node:crypto";import Uf from"node:path";function Jr(e){return`'${e.replace(/'/g,"'\\''")}'`}var Vf="craig",hl=async(e,t,r)=>{let n=xs(e,t),s=Kf(),i=await C("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),o=Hf(i.stdout);return await Bf(e,n),o};var Bf=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 C("tmux",n,{cwd:e})},wl=async(e,t,r)=>{await C("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},kl=async(e,t,r)=>{await C("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var yl=async(e,t,r)=>{await C("tmux",["pipe-pane","-o","-t",e,`cat >> ${Jr(t)}`],{cwd:r})},Xr=async(e,t,r,n)=>{let s=n??Rl(e);if(r?await C("tmux",["select-window","-t",r],{cwd:e}):await C("tmux",["select-window","-t",t],{cwd:e}),await C("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await C("tmux",["switch-client","-t",s],{cwd:e});return}await Yf(e,["attach-session","-t",s])};var Tl=async(e,t)=>{await C("tmux",["kill-session","-t",t],{cwd:e})};var Rl=e=>{let r=Uf.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=qf("sha1").update(e).digest("hex").slice(0,8);return`${Vf}-${r}-${n}`},xs=(e,t)=>`${Rl(e)}-${t.toLowerCase()}`,Kf=()=>{let e=Gf();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},Gf=()=>{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},Hf=e=>{let t=zf(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]}},zf=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),Yf=async(e,t)=>{await new Promise((r,n)=>{let s=Wf("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",n),s.on("exit",i=>{if(i===0){r();return}n(new Error(`tmux ${t.join(" ")} failed with exit code ${i??"unknown"}.`))})})};import{accessSync as Jf,constants as Xf}from"node:fs";import{homedir as bl}from"node:os";import Ve from"node:path";var Qf=[Ve.join(bl(),".local","bin"),Ve.join(bl(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Sl(e=process.env){return Zf([...(e.PATH??"").split(Ve.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:Qf])}function dt(e=process.env){return{...e,PATH:Sl(e).join(Ve.delimiter)}}function Ds(e,t={}){if(e.includes(Ve.sep)){let r=Ve.isAbsolute(e)?e:Ve.resolve(t.cwd??process.cwd(),e);return Pl(r)?r:null}for(let r of Sl(t.env)){let n=Ve.join(r,e);if(Pl(n))return n}return null}function ut(e,t={}){let r=Ds(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 Pl(e){try{return Jf(e,Xf.X_OK),!0}catch{return!1}}function Zf(e){return[...new Set(e)]}var ir={async create(e,t){let r=await hl(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await yl(r.paneId,t.logPath,t.repoRoot);let n=await vl({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||xs(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 ct(e,s),s},async attach(e,t,r){let n=await ir.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Xr(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await ct(e,s),s},async resize(e,t,r,n){await wl(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await ct(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 ct(e,n),n},async snapshot(e,t){return eg(e,t)}},Os={async prepare(e,t){let n=e.runnerSession.command[0],s=dt();ut(n,{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=ut(r[0],{cwd:e.worktreePath,env:dt()});await kl(t.session.paneId,[n,...r.slice(1)].map(s=>Jr(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},eg=async(e,t)=>{let r=await $("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return vl({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},vl=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var $s=async(e,t,r,n={})=>{let s=r.trim(),i=await w.load(e),o=n.runner??w.runners.getDefault(i);if(w.runners.assertEnabled(o,i),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 nr(e,n.workspaceId,s,{runner:o,config:i}):await Et(e,t,s,{runner:o,config:i}),l=a.task,c=w.runners.buildCommand(o,s,i),d=`session_${l.id}`,u=l.artifacts.logPath?Il.resolve(e.workspaceRoot,l.artifacts.logPath):Il.join(e.logsDir,`${l.id}.log`);try{await Os.prepare(l,{repoRoot:a.repoRoot});let f=await ir.create(e,{sessionId:d,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:u,command:c});await Os.launch(l,{repoRoot:a.repoRoot,session:f});let h=new Date().toISOString();f={...f,status:"running",startedAt:h,command:c};let m=await x(e,l.id,k=>({...k,status:"running",runner:o,sessionId:f.id,selectedPtyTabId:k.selectedPtyTabId,runnerSession:{command:f.command,pid:null,startedAt:h,lastKnownState:"running",exitCode:null,exitedAt:null}}));return await ct(e,f),{kind:"createTask",taskId:m.id,repoId:m.repoId,workspaceId:m.workspaceId,sessionId:f.id,status:m.status,branch:m.branch,worktreePath:m.worktreePath,runner:m.runner}}catch(f){throw await x(e,l.id,h=>({...h,sessionId:null,status:"draft",runnerSession:{...h.runnerSession,lastKnownState:"failed"},lastFailureReason:f instanceof Error?f.message:"Unknown Craig error"})),f}};import{mkdir as ig}from"node:fs/promises";import og from"node:path";var xe=async e=>{let t=await $("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var Cl=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await C("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},xt=async(e,t)=>{let r=await C("gh",Ms(e),{cwd:t});return JSON.parse(r.stdout)},Dt=async(e,t)=>{let r=await $("gh",Ms(e),{cwd:t});if(r.exitCode===0)return JSON.parse(r.stdout);let n=r.stderr.trim()||r.stdout.trim();if(xl(n))return null;throw new Error(n||`GitHub CLI failed while discovering a pull request for ${e}.`)},Al=async(e,t)=>{let r=await $("gh",Ms(e),{cwd:t});if(r.exitCode===0)return JSON.parse(r.stdout);let n=r.stderr.trim()||r.stdout.trim();if(xl(n))return null;throw new Error(n||`GitHub CLI failed while discovering a pull request for ${e}.`)},El=async(e,t,r)=>{if(r.length===0)return[];let n=ng(r),s;try{s=await C("gh",["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`])}catch(a){throw tg(a)?new me(a instanceof Error?a.message:String(a)):a}let o=JSON.parse(s.stdout).data?.repository??{};return r.map((a,l)=>{let c=o[`item${l}`],d=sg(c);return{id:a.id,found:d!==null,view:d}})},Qr=async e=>{let t=await $("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:rg(t.stdout.trim())},Be=e=>{let t=e.trim().match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/([1-9]\d*)(?:[/?#].*)?$/);return!t?.[1]||!t[2]||!t[3]?null:{owner:t[1],name:t[2],number:Number(t[3])}},tg=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")},xl=e=>{let t=e.toLowerCase();return t.includes("no pull requests found")||t.includes("could not resolve to a pullrequest")},Ms=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],rg=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},ng=e=>`
18
18
  query CraigPullRequestBatch($owner: String!, $name: String!) {
19
19
  repository(owner: $owner, name: $name) {
20
20
  ${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(`
@@ -68,71 +68,71 @@ fragment PrFields on PullRequest {
68
68
  }
69
69
  }
70
70
  }
71
- `,Xf=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??[];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 lt=async(e,t)=>{let r=st(e,t.artifacts.prStatusPath);r&&(await Qf(Zf.dirname(r),{recursive:!0}),await M(r,{taskId:t.id,prs:t.prs}))},sr=async(e,t,r={writeTask:Ie,writePrStatusArtifact:lt})=>{await r.writeTask(e,t);try{await r.writePrStatusArtifact(e,t)}catch(n){throw new f("PARTIAL_RESULT",`Task ${t.id} was updated, but its PR status artifact could not be written.`,{retryable:!0,details:{taskId:t.id},cause:n})}return t},or=async(e,t,r,n,s={readRawTask:ve,validateTaskRecord:ue,writeTask:Ie,writePrStatusArtifact:lt,withTaskLock:_e})=>s.withTaskLock(e,t.id,async()=>{let o=await s.readRawTask(e,t.id),i=s.validateTaskRecord(o,`${e.tasksDir}/${t.id}.json`),a=i.prs.find(m=>n?.number!==null&&m.number===n?.number)??n,l=Ae(r,a),c=Ce(i,l),d=i.status==="closed"?i.status:nt(c.prs),u={...c,status:d};return sr(e,u,s)}),ir=async(e,t)=>{let r=E(t),n=r?.number?String(r.number):t.branch,s=await At(n,t.worktreePath);return or(e,t,s,r)},ar=async(e,t)=>{for(let r of await $s(t)){let n=await Et(r,t.worktreePath);if(!n)continue;return{discovered:!0,task:await or(e,t,n,null)}}return{discovered:!1,task:t}},$s=async e=>{let t=await tl(e.worktreePath).catch(()=>null);return[...new Set([t,e.branch].filter(r=>!!r))]};async function lr(e,t,r,n){return _e(e,t,async()=>{let s=await A(e,t);if(!s.repoTargets?.find(p=>p.repoId===r))throw new Error(`Project task ${t} has no repo target ${r}.`);let i=Ue(n.url),a=s.prs.find(p=>i?St(p,{owner:i.owner,repo:i.name,number:n.number}):p.number===n.number)??null,l=Ae(n,a,i??void 0),c=eg(n),d=Ce(s,l),u={...d,repoTargets:(d.repoTargets??[]).map(p=>p.repoId===r?{...p,pullRequest:c}:p)},m={...u,status:u.status==="closed"?u.status:Ns(u)};return sr(e,m)})}function eg(e){let t=Ue(e.url);return{provider:"github",owner:t?.owner??null,repo:t?.name??null,number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:tg(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:rg(e.reviewDecision??null),requiredChecks:Ts(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function Ns(e){let t=(e.repoTargets??[]).filter(n=>n.status==="ready"),r=t.map(n=>n.pullRequest).filter(n=>n.number!==null);return r.length===0?"checked":r.every(n=>n.status==="merged")?"merged":r.length===t.length&&r.every(n=>n.mergeable&&n.reviewDecision!=="REVIEW_REQUIRED"&&n.reviewDecision!=="CHANGES_REQUESTED"&&n.mergeStateStatus!=="REVIEW_REQUIRED"&&n.requiredChecks.length>0&&n.requiredChecks.every(s=>s.status==="success"||s.status==="skipped"))?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"}var tg=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,rg=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var xt=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let o=await At(n,r.worktreePath);return await lr(e,t.id,r.repoId,o),"synced"}let s=await Et(n,r.worktreePath);return s?(await lr(e,t.id,r.repoId,s),"discovered"):"not_found"};var cr=async(e,t)=>{let r=await A(e,t),n=E(r);return n?.number?(await qe(r.worktreePath),je(n)?(await ar(e,r)).task:ir(e,r)):r},Ls=async(e,t)=>{let r=await A(e,t);if(r.type==="project"&&r.repoTargets?.length)return await Dt(e,t),A(e,t);let n=E(r);if(await z(r),await qe(r.worktreePath),!n?.number||je(n)){let o=await ar(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return o.task}return await ir(e,r)},Dt=async(e,t)=>{let r=await A(e,t),n=(r.repoTargets??[]).filter(o=>o.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let o of n){await qe(o.worktreePath);let i=o.pullRequest.number?await xt(e,r,o):await xt(e,r,o).catch(()=>"not_found");s[i==="not_found"?"notFound":i]++}return s},_s=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=Ms(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 vl(n,u).catch(async()=>{try{let m=d.pullRequest.number?await xt(e,s,d):await xt(e,s,d).catch(()=>"not_found");Jr(o,m,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=E(s),a=i?.number&&!je(i),l=a?[]:await $s(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 vl(n,c).catch(async()=>{try{let{disposition:d,task:u}=await Xr(e,s.id),m=E(u);Jr(o,d,m?.number??null,m?.url??null)}catch{}})}for(let s of n.values())try{await qe(s.worktreePath);let o=await Sl(s.worktreePath,s.repository,s.items),i=new Map(o.map(a=>[a.id,a]));for(let a of s.items){let l=Ms(r,a.task),d=i.get(a.id)?.view??await ng(s.worktreePath,a);if(!d){Jr(l,"not_found",null,null);continue}if(a.targetRepoId)await lr(e,a.task.id,a.targetRepoId,d);else{let u=await ve(e,a.task.id),m=ue(u,`${e.tasksDir}/${a.task.id}.json`);await or(e,m,d,a.mode==="number"?E(m):null)}Jr(l,a.mode==="number"?"synced":"discovered",d.number,d.url)}}catch(o){if(o instanceof ye)throw o}return t.map(s=>Ms(r,s))},Xr=async(e,t)=>{let r=await A(e,t);await z(r),await qe(r.worktreePath);let n=E(r);if(n?.number&&!je(n))return{disposition:"synced",task:await ir(e,r)};let s=await ar(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},ng=async(e,t)=>{if(t.mode!=="head")return null;for(let r of t.fallbackSelectors){let n=await Et(r,e);if(n)return n}return null},vl=async(e,t)=>{let r=await Yr(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]})},Ms=(e,t)=>{let r=e.get(t.id);if(r)return r;let n={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!E(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},Jr=(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};var js=async(e,t)=>{let r=await A(e,t);try{r.type==="project"&&r.repoTargets?.length?(await Dt(e,t),r=await A(e,t)):r.prs.some(o=>o.number)&&(r=await cr(e,t))}catch{}let n=await Xt(e,r),s=r.sessionId?await Fe(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var Fs=async(e,t)=>{let r=await A(e,t);if(await z(r),(await C("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await sg(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},sg=async e=>{let t=[],r=await C("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await og(e);for(let s of n){let o=await O("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
71
+ `,sg=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??[];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 pt=async(e,t)=>{let r=lt(e,t.artifacts.prStatusPath);r&&(await ig(og.dirname(r),{recursive:!0}),await L(r,{taskId:t.id,prs:t.prs}))},or=async(e,t,r={writeTask:Ce,writePrStatusArtifact:pt})=>{await r.writeTask(e,t);try{await r.writePrStatusArtifact(e,t)}catch(n){throw new g("PARTIAL_RESULT",`Task ${t.id} was updated, but its PR status artifact could not be written.`,{retryable:!0,details:{taskId:t.id},cause:n})}return t},ar=async(e,t,r,n,s={readRawTask:Ie,validateTaskRecord:ue,writeTask:Ce,writePrStatusArtifact:pt,withTaskLock:We})=>s.withTaskLock(e,t.id,async()=>{let i=await s.readRawTask(e,t.id),o=s.validateTaskRecord(i,`${e.tasksDir}/${t.id}.json`),a=o.prs.find(f=>n?.number!==null&&f.number===n?.number)??n,l=Ee(r,a),c=Ae(o,l),d=o.status==="closed"?o.status:at(c.prs),u={...c,status:d};return or(e,u,s)}),lr=async(e,t)=>{let r=E(t),n=r?.number?String(r.number):t.branch,s=await xt(n,t.worktreePath);return ar(e,t,s,r)},cr=async(e,t)=>{for(let r of await Ns(t)){let n=await Dt(r,t.worktreePath);if(!n)continue;return{discovered:!0,task:await ar(e,t,n,null)}}return{discovered:!1,task:t}},Ns=async e=>{let t=await ol(e.worktreePath).catch(()=>null);return[...new Set([t,e.branch].filter(r=>!!r))]};async function dr(e,t,r,n){return We(e,t,async()=>{let s=await A(e,t);if(!s.repoTargets?.find(h=>h.repoId===r))throw new Error(`Project task ${t} has no repo target ${r}.`);let o=Be(n.url),a=s.prs.find(h=>o?It(h,{owner:o.owner,repo:o.name,number:n.number}):h.number===n.number)??null,l=Ee(n,a,o??void 0),c=ag(n),d=Ae(s,l),u={...d,repoTargets:(d.repoTargets??[]).map(h=>h.repoId===r?{...h,pullRequest:c}:h)},f={...u,status:u.status==="closed"?u.status:Ls(u)};return or(e,f)})}function ag(e){let t=Be(e.url);return{provider:"github",owner:t?.owner??null,repo:t?.name??null,number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:lg(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:cg(e.reviewDecision??null),requiredChecks:bs(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function Ls(e){let t=(e.repoTargets??[]).filter(n=>n.status==="ready"),r=t.map(n=>n.pullRequest).filter(n=>n.number!==null);return r.length===0?"checked":r.every(n=>n.status==="merged")?"merged":r.length===t.length&&r.every(n=>n.mergeable&&n.reviewDecision!=="REVIEW_REQUIRED"&&n.reviewDecision!=="CHANGES_REQUESTED"&&n.mergeStateStatus!=="REVIEW_REQUIRED"&&n.requiredChecks.length>0&&n.requiredChecks.every(s=>s.status==="success"||s.status==="skipped"))?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"}var lg=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,cg=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var Ot=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await xt(n,r.worktreePath);return await dr(e,t.id,r.repoId,i),"synced"}let s=await Dt(n,r.worktreePath);return s?(await dr(e,t.id,r.repoId,s),"discovered"):"not_found"};var ur=async(e,t)=>{let r=await A(e,t),n=E(r);return n?.number?(await xe(r.worktreePath),qe(n)?(await cr(e,r)).task:lr(e,r)):r},js=async(e,t)=>{let r=await A(e,t);if(r.type==="project"&&r.repoTargets?.length)return await $t(e,t),A(e,t);let n=E(r);if(await J(r),await xe(r.worktreePath),!n?.number||qe(n)){let i=await cr(e,r);if(!i.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return i.task}return await lr(e,r)},$t=async(e,t)=>{let r=await A(e,t),n=(r.repoTargets??[]).filter(i=>i.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let i of n){await xe(i.worktreePath);let o=i.pullRequest.number?await Ot(e,r,i):await Ot(e,r,i).catch(()=>"not_found");s[o==="not_found"?"notFound":o]++}return s},Fs=async(e,t)=>{let r=new Map,n=new Map,s=[];for(let i of t){let o=_s(r,i);if(i.type==="project"&&i.repoTargets?.length){for(let u of i.repoTargets.filter(f=>f.status==="ready")){let f={id:`${i.id}:${u.repoId}`,task:i,targetRepoId:u.repoId,worktreePath:u.worktreePath,selector:u.pullRequest.number?String(u.pullRequest.number):u.branch,mode:u.pullRequest.number?"number":"head",fallbackSelectors:[]};await Dl(n,f).catch(async()=>{try{await xe(u.worktreePath);let h=u.pullRequest.number?await Ot(e,i,u):await Ot(e,i,u);Zr(o,h,u.pullRequest.number??null,u.pullRequest.url??null)}catch(h){if(h instanceof me)throw h;s.push(h)}})}continue}let a=E(i),l=a?.number&&!qe(a),c=l?[]:await Ns(i),d={id:i.id,task:i,worktreePath:i.worktreePath,selector:l?String(a.number):c[0]??i.branch,mode:l?"number":"head",fallbackSelectors:l?[]:c.slice(1)};await Dl(n,d).catch(async()=>{try{let{disposition:u,task:f}=await en(e,i.id),h=E(f);Zr(o,u,h?.number??null,h?.url??null)}catch(u){if(u instanceof me)throw u;s.push(u)}})}for(let i of n.values())try{await xe(i.worktreePath);let o=await El(i.worktreePath,i.repository,i.items),a=new Map(o.map(l=>[l.id,l]));for(let l of i.items){let c=_s(r,l.task),u=a.get(l.id)?.view??await dg(i.worktreePath,l);if(!u){Zr(c,"not_found",null,null);continue}if(l.targetRepoId)await dr(e,l.task.id,l.targetRepoId,u);else{let f=await Ie(e,l.task.id),h=ue(f,`${e.tasksDir}/${l.task.id}.json`);await ar(e,h,u,l.mode==="number"?E(h):null)}Zr(c,l.mode==="number"?"synced":"discovered",u.number,u.url)}}catch(o){if(o instanceof me)throw o;s.push(o)}return ug(s),t.map(i=>_s(r,i))},en=async(e,t)=>{let r=await A(e,t);await J(r),await xe(r.worktreePath);let n=E(r);if(n?.number&&!qe(n))return{disposition:"synced",task:await lr(e,r)};let s=await cr(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},dg=async(e,t)=>{if(t.mode!=="head")return null;for(let r of t.fallbackSelectors){let n=await Dt(r,e);if(n)return n}return null},Dl=async(e,t)=>{let r=await Qr(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]})},_s=(e,t)=>{let r=e.get(t.id);if(r)return r;let n={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!E(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},Zr=(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},ug=e=>{if(e.length!==0)throw e.length===1?e[0]:new AggregateError(e,`${e.length} pull request polling operations failed.`)};var Ws=async(e,t)=>{let r=await A(e,t);try{r.type==="project"&&r.repoTargets?.length?(await $t(e,t),r=await A(e,t)):r.prs.some(i=>i.number)&&(r=await ur(e,t))}catch{}let n=await Zt(e,r),s=r.sessionId?await Ue(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var qs=async(e,t)=>{let r=await A(e,t);if(await J(r),(await C("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await pg(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},pg=async e=>{let t=[],r=await C("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await mg(e);for(let s of n){let i=await $("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(i.stdout.trimEnd())}return t.join(`
72
72
 
73
- `)},og=async e=>(await C("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
74
- `).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as ig}from"node:child_process";import{access as ag}from"node:fs/promises";var Ws=async(e,t)=>{let r=await A(e,t),n=vt(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await ag(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},qs=async e=>{await new Promise((t,r)=>{let n=!1,s=ig("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 lg}from"node:fs/promises";import cg from"node:path";var Us=async(e,t)=>{let r=await A(e,t);if(await z(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 Vr(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".`);await x(e,r.id,a=>({...a,status:a.status==="running"?r.status:a.status,checks:{...a.checks,status:"running",commands:[...s],results:[]}}));let o=[];for(let a of s){let l=new Date().toISOString(),c=await O("sh",["-lc",a],{cwd:r.worktreePath}),d=new Date().toISOString(),u=c.exitCode??1;if(o.push({command:a,startedAt:l,finishedAt:d,exitCode:u}),u!==0){let m=c.stderr.trim()||c.stdout.trim()||`Check command failed: ${a}`,p=await x(e,r.id,k=>({...k,status:"review",checks:{...k.checks,results:o,status:"failed",lastRunAt:d},lastFailureReason:m}));return await Il(e,p),{kind:"runChecks",taskId:r.id,status:"failed",commands:s}}}let i=await x(e,r.id,a=>({...a,status:a.status==="review"||a.status==="checked"?"checked":a.status,checks:{...a.checks,results:o,status:"passed",lastRunAt:new Date().toISOString()},lastFailureReason:null}));return await Il(e,i),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},Il=async(e,t)=>{let r=st(e,t.artifacts.checkSummaryPath);r&&(await lg(cg.dirname(r),{recursive:!0}),await M(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var Bs=async(e,t)=>{let r=await A(e,t);await z(r);let n=await Vr(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 Qa(r.worktreePath),await Za(r.worktreePath,s);let o=await el(r.worktreePath),i=new Date().toISOString(),a=await x(e,r.id,l=>({...l,status:l.status==="running"?r.status:l.status,lastCommit:{sha:o.sha,message:o.message,committedAt:i},lastFailureReason:null}));return{kind:"commitTask",taskId:r.id,status:a.status,commitSha:o.sha,message:o.message}};import{access as dg}from"node:fs/promises";var Vs=async(e,t)=>{let r=await A(e,t),n=await ug(r.worktreePath);return x(e,t,s=>({...s,status:"closed",cleanup:{...s.cleanup,preservedWorktree:n&&s.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null}))},ug=async e=>{try{return await dg(e),!0}catch{return!1}};var Ks=async(e,t,r)=>{let n=[],s=null,o=null;try{if(t.sessionId){let i=await Fe(e,t.sessionId);await gl(e.repoRoot,i.sessionName),s=new Date().toISOString()}}catch(i){n.push(i instanceof Error?i.message:"Failed to close tmux session.")}if(!r.preserveWorktree)try{await rl(e.repoRoot,t.worktreePath),o=new Date().toISOString()}catch(i){n.push(i instanceof Error?i.message:"Failed to remove worktree.")}await x(e,t.id,i=>({...i,cleanup:{...i.cleanup,paneClosedAt:s??i.cleanup.paneClosedAt,worktreeRemovedAt:o??i.cleanup.worktreeRemovedAt,preservedWorktree:r.preserveWorktree,warning:n.length>0?n.join(" "):null}}))};var Gs=async(e,t,r)=>{let n=await pe(e,r),s=await x(e,t,o=>{if(o.repoId===n.id)throw new Error(`Repo ${n.id} is already the primary repo for task ${o.id}.`);return{...o,linkedRepoIds:o.linkedRepoIds.includes(n.id)?o.linkedRepoIds:[...o.linkedRepoIds,n.id]}});return{kind:"addTaskLink",taskId:s.id,repoId:n.id,linkedRepoIds:s.linkedRepoIds}},Hs=async(e,t)=>{let r=await A(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>pe(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var zs=async(e,t)=>{let r=await A(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([pe(e,r.repoId),Fe(e,r.sessionId)]),o=await nr.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var Ys=async(e,t)=>{let r=await A(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await Fe(e,r.sessionId).catch(s=>{throw pg(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 zr(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},pg=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as mg}from"node:child_process";var Js=async(e,t)=>{let r=await A(e,t);await z(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 fg(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},fg=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=mg(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 Xs=async(e,t,r)=>{await x(e,t,n=>({...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r}))},Qs=async(e,t,r)=>x(e,t,n=>({...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})),Zs=async(e,t)=>x(e,t,r=>{let n=r.ptyTabs.find(s=>s.kind==="agent");if(!n)throw new Error(`Task ${t} is missing its agent PTY tab.`);return{...r,status:"running",selectedPtyTabId:n.id,runnerSession:{...r.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}}});import{realpath as Al}from"node:fs/promises";import dr from"node:path";async function to(e,t){if(t.explicitTaskId!==void 0){let l=await Cl(e,t.explicitTaskId,"explicit");return eo(l,"explicit",t.environmentAgentTabId)}if(t.environmentTaskId!==void 0){let l=await Cl(e,t.environmentTaskId,"environment");return eo(l,"environment",t.environmentAgentTabId)}let r=await Al(t.cwd).catch(()=>dr.resolve(t.cwd)),n=await Zt(e,{includeClosed:!0}),o=(await Promise.all(n.tasks.map(async l=>({task:l,matches:await hg(l,r)})))).filter(l=>l.matches).map(l=>l.task),i=[...new Map(o.map(l=>[l.id,l])).values()];if(i.length>1)throw new f("TASK_CONTEXT_AMBIGUOUS",`Multiple Craig tasks match ${r}: ${i.map(l=>l.id).join(", ")}. Use --task <id>.`,{details:{cwd:r,taskIds:i.map(l=>l.id)}});let a=i[0];if(a)return eo(a,"cwd",t.environmentAgentTabId);if(t.environmentAgentTabId!==void 0)throw new f("TASK_CONTEXT_CONFLICT",`CRAIG_AGENT_TAB_ID is set to ${t.environmentAgentTabId}, but no task context could be resolved.`,{details:{agentTabId:t.environmentAgentTabId}});if(t.required)throw new f("TASK_CONTEXT_NOT_FOUND",`No Craig task was found from ${r}. Use --task <id> or run the command inside a task worktree.`,{details:{cwd:r}});return null}async function Cl(e,t,r){try{return await A(e,t)}catch(n){throw!(n instanceof f)||n.code!=="TASK_NOT_FOUND"?n:new f("TASK_CONTEXT_NOT_FOUND",`Craig task "${t}" from ${r==="explicit"?"--task":"CRAIG_TASK_ID"} was not found.`,{details:{taskId:t,source:r},cause:n})}}function eo(e,t,r){let n=r??null;if(n!==null){let s=e.ptyTabs.find(o=>o.id===n);if(!s||s.kind!=="agent")throw new f("TASK_CONTEXT_CONFLICT",`Agent tab ${n} does not belong to Craig task ${e.id}.`,{details:{taskId:e.id,agentTabId:n}})}return{task:e,source:t,agentTabId:n}}function gg(e){return[e.worktreePath,...e.bundlePath?[e.bundlePath]:[],...(e.repoTargets??[]).map(t=>t.worktreePath)]}async function hg(e,t){return(await Promise.all(gg(e).map(n=>Al(n).catch(()=>dr.resolve(n))))).some(n=>wg(n,t))}function wg(e,t){let r=dr.relative(dr.resolve(e),t);return r===""||!r.startsWith("..")&&!dr.isAbsolute(r)}var ro=async(e,t,r="merge",n)=>{let s=await A(e,t),o=n??E(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await bl(s.worktreePath,o,r)};var ur={readTask:A,writeTask:Ie,withTaskLock:_e,ensureGhAuthenticated:qe,fetchPrView:At,discoverPrView:Pl,getGitHubRepositoryLocator:Yr,writePrStatusArtifact:lt};async function so(e,t,r,n=ur){let s=await n.readTask(e,t),o=await yg(s,r,n);return Be(s,o,"showTaskPr","shown",[])}async function oo(e,t,r,n=ur){return n.withTaskLock(e,t,async()=>{let s=await n.readTask(e,t),o=await uo(s,r,null,n);await po(o,n);let i=await Zr(`discover a pull request for ${o.branch}`,()=>n.discoverPrView(o.branch,o.worktreePath));if(!i)return Be(s,o,"discoverTaskPr","not_found",[]);mo(i,o);let a=en(s,o,i.number),l=await fo(e,s,o,i,n);return Be(l,o,"discoverTaskPr",a?"synced":"discovered",[])})}async function io(e,t,r,n,s=ur){let o=co(r);return s.withTaskLock(e,t,async()=>{let i=await s.readTask(e,t),a=await uo(i,n,o.repository,s);xl(o.repository,a),await po(a,s);let l=await Zr(`fetch pull request ${r}`,()=>s.fetchPrView(r,a.worktreePath));Tg(l,o),mo(l,a);let c=en(i,a,l.number),d=go(i,a),u=d&&!St(d,{owner:a.repository.owner,repo:a.repository.name,number:l.number})&&d.status!=="closed"&&d.status!=="merged"?[`Pull request #${l.number} becomes active; #${d.number} remains in task history.`]:[],m=await fo(e,i,a,l,s);return Be(m,a,"linkTaskPr",c?"unchanged":"linked",u)})}async function kg(e,t,r,n){if(e.type==="repo"){if(t&&t!==e.repoId)throw Ot(e,t);let i=e.prs.find(a=>a.number===r.number)??E(e);return{repoId:e.repoId,branch:e.branch,worktreePath:e.worktreePath,repository:await Qr(i,e.worktreePath,e.repoId,n),projectTarget:null}}if(t){let i=e.repoTargets?.find(c=>c.repoId===t);if(!i)throw Ot(e,t);let a=El(i.pullRequest),l=e.prs.find(c=>c.number===r.number&&(!c.headBranch||c.headBranch===i.branch)&&(!a||!!(c.owner&&c.repo&&Te({owner:c.owner,name:c.repo},a))))??i.pullRequest;return{repoId:t,branch:i.branch,worktreePath:i.worktreePath,repository:await Qr(l,i.worktreePath,t,n),projectTarget:i}}if(!r.repository)throw new f("CLI_USAGE",`Project task ${e.id} requires --repo <repo-id> for a numeric pull request selector.`,{details:{taskId:e.id,pullRequestNumber:r.number}});let s=r.repository,o=[];for(let i of e.repoTargets??[]){let a=i.pullRequest.owner&&i.pullRequest.repo&&Te({owner:i.pullRequest.owner,name:i.pullRequest.repo},s),l=e.prs.some(c=>c.number===r.number&&c.owner&&c.repo&&Te({owner:c.owner,name:c.repo},s)&&(!c.headBranch||c.headBranch===i.branch));(a||l)&&o.push({repoId:i.repoId,branch:i.branch,worktreePath:i.worktreePath,repository:s,projectTarget:i})}if(o.length!==1)throw new f("TASK_CONTEXT_AMBIGUOUS",`Pull request repository ${r.repository.owner}/${r.repository.name} does not map to exactly one target in project task ${e.id}.`,{details:{taskId:e.id,owner:r.repository.owner,repo:r.repository.name,matchingRepoIds:o.map(i=>i.repoId)}});return o[0]}async function ao(e,t,r,n=ur){return n.withTaskLock(e,t,async()=>{let s=await n.readTask(e,t),o=await uo(s,r,null,n),i=go(s,o);if(!i?.number)return Be(s,o,"refreshTaskPr","not_found",[]);await po(o,n);let a=await Zr(`refresh pull request #${i.number}`,()=>n.fetchPrView(String(i.number),o.worktreePath));mo(a,o);let l=await fo(e,s,o,a,n);return Be(l,o,"refreshTaskPr","synced",[])})}async function lo(e,t,r,n,s=ur){let o=co(r);return s.withTaskLock(e,t,async()=>{let i=await s.readTask(e,t),a=await kg(i,n,o,s);if(xl(o.repository,a),!en(i,a,o.number))return Be(i,a,"unlinkTaskPr","unchanged",[]);let c=Rg(i,a,o.number),d=await Ol(e,c,s);return Be(d,a,"unlinkTaskPr","unlinked",[])})}function co(e){let t=e.trim(),r=Ue(t);if(r)return{number:r.number,repository:r};if(/^[1-9]\d*$/.test(t))return{number:Number(t),repository:null};throw new f("CLI_USAGE",`Invalid pull request selector "${e}". Use a GitHub pull request URL or positive number.`,{details:{selector:e}})}async function uo(e,t,r,n){if(e.type==="repo"){if(t&&t!==e.repoId)throw Ot(e,t);return no(e.repoId,e.branch,e.worktreePath,null,n)}let s=e.repoTargets??[];if(t){let i=s.find(a=>a.repoId===t);if(!i)throw Ot(e,t);return no(i.repoId,i.branch,i.worktreePath,i,n)}if(!r)throw new f("CLI_USAGE",`Project task ${e.id} requires --repo <repo-id> for pull request commands.`,{details:{taskId:e.id,repoIds:s.map(i=>i.repoId)}});let o=[];for(let i of s){let a=await no(i.repoId,i.branch,i.worktreePath,i,n).catch(l=>{if(l instanceof f&&l.code==="EXTERNAL_DEPENDENCY_FAILED"&&l.message.includes("does not have a supported GitHub origin remote"))return null;throw l});a&&Te(a.repository,r)&&o.push(a)}if(o.length!==1)throw new f("TASK_CONTEXT_AMBIGUOUS",`Pull request repository ${r.owner}/${r.name} does not map to exactly one target in project task ${e.id}.`,{details:{taskId:e.id,owner:r.owner,repo:r.name,matchingRepoIds:o.map(i=>i.repoId)}});return o[0]}async function yg(e,t,r){if(e.type==="repo"){if(t&&t!==e.repoId)throw Ot(e,t);let s=E(e);return{repoId:e.repoId,branch:e.branch,worktreePath:e.worktreePath,repository:await Qr(s,e.worktreePath,e.repoId,r),projectTarget:null}}if(!t)throw new f("CLI_USAGE",`Project task ${e.id} requires --repo <repo-id> for pull request commands.`,{details:{taskId:e.id,repoIds:(e.repoTargets??[]).map(s=>s.repoId)}});let n=e.repoTargets?.find(s=>s.repoId===t);if(!n)throw Ot(e,t);return{repoId:t,branch:n.branch,worktreePath:n.worktreePath,repository:await Qr(n.pullRequest,n.worktreePath,t,r),projectTarget:n}}async function Qr(e,t,r,n){let s=El(e);return s||(await n.getGitHubRepositoryLocator(t).catch(()=>null)??{owner:"",name:r})}function El(e){return e?.owner&&e.repo?{owner:e.owner,name:e.repo}:e?.url?Ue(e.url):null}async function no(e,t,r,n,s){let o=await s.getGitHubRepositoryLocator(r);if(!o)throw new f("EXTERNAL_DEPENDENCY_FAILED",`Repo ${e} does not have a supported GitHub origin remote.`,{details:{repoId:e,worktreePath:r}});return{repoId:e,branch:t,worktreePath:r,repository:o,projectTarget:n}}async function po(e,t){await Zr("verify GitHub CLI authentication",()=>t.ensureGhAuthenticated(e.worktreePath))}async function Zr(e,t){try{return await t()}catch(r){throw r instanceof f?r:new f("EXTERNAL_DEPENDENCY_FAILED",`Failed to ${e}: ${r instanceof Error?r.message:String(r)}`,{retryable:!0,cause:r})}}function xl(e,t){if(e&&!Te(e,t.repository))throw Dl(e,t)}function Tg(e,t){let r=Ue(e.url);if(!r||r.number!==t.number)throw new f("TASK_CONTEXT_CONFLICT",`GitHub returned ${e.url} for pull request selector #${t.number}.`,{details:{selectorNumber:t.number,returnedUrl:e.url}});if(t.repository&&!Te(t.repository,r))throw new f("PR_REPOSITORY_MISMATCH",`GitHub returned a pull request from ${r.owner}/${r.name}, not ${t.repository.owner}/${t.repository.name}.`,{details:{selectorRepository:t.repository,returnedRepository:r}})}function mo(e,t){let r=Ue(e.url);if(!r||!Te(r,t.repository))throw Dl(r,t);if(e.headRefName!==t.branch)throw new f("PR_BRANCH_MISMATCH",`Pull request #${e.number} uses head branch ${e.headRefName}, not task branch ${t.branch}.`,{details:{repoId:t.repoId,pullRequestNumber:e.number,expectedBranch:t.branch,actualBranch:e.headRefName}})}function Dl(e,t){return new f("PR_REPOSITORY_MISMATCH",`Pull request repository ${e?`${e.owner}/${e.name}`:"is invalid"} does not match task repo ${t.repository.owner}/${t.repository.name}.`,{details:{repoId:t.repoId,expectedOwner:t.repository.owner,expectedRepo:t.repository.name,actualOwner:e?.owner??null,actualRepo:e?.name??null}})}function Ot(e,t){return new f("TASK_CONTEXT_CONFLICT",`Repo ${t} is not a target of task ${e.id}.`,{details:{taskId:e.id,repoId:t}})}function Te(e,t){return e.owner.toLowerCase()===t.owner.toLowerCase()&&e.name.toLowerCase()===t.name.toLowerCase()}async function fo(e,t,r,n,s){let o=en(t,r,n.number),i=Ae(n,o,r.repository),a=Ce(t,i);return r.projectTarget&&(a={...a,repoTargets:(a.repoTargets??[]).map(l=>l.repoId===r.repoId?{...l,pullRequest:Ml(i)}:l)}),Ol(e,a,s)}function Rg(e,t,r){let n=e.prs.filter(o=>!Nl(o,t,r)),s={...e,prs:n};if(t.projectTarget?.pullRequest.number===r){let o=$l(n.filter(i=>i.owner&&i.repo&&Te({owner:i.owner,name:i.repo},t.repository)));s={...s,repoTargets:(s.repoTargets??[]).map(i=>i.repoId===t.repoId?{...i,pullRequest:o?Ml(o):Pg(t.repository)}:i)}}return s}async function Ol(e,t,r){let n=t.status==="closed"?t.status:t.type==="project"?Ns(t):nt(t.prs),s={...t,status:n};return sr(e,s,r)}function en(e,t,r){return ho(e,t).find(n=>Nl(n,t,r))??null}function go(e,t){if(!t.projectTarget)return E(e);let r=ho(e,t);return $l(r)}function $l(e){return[...e].reverse().find(t=>t.status!=="merged"&&t.status!=="closed")??e[e.length-1]??null}function ho(e,t){if(!t.projectTarget)return e.prs;let r=e.prs.filter(o=>o.owner&&o.repo&&Te({owner:o.owner,name:o.repo},t.repository)),n=e.repoTargets?.find(o=>o.repoId===t.repoId),s=n?.pullRequest.number?bg(n.pullRequest,t.repository):null;return s&&!r.some(o=>St(o,s))?[...r,s]:r}function Nl(e,t,r){return e.number!==r?!1:!e.owner||!e.repo||Te({owner:e.owner,name:e.repo},t.repository)}function Be(e,t,r,n,s){let o=ho(e,t);return{kind:r,taskId:e.id,repoId:t.repoId,disposition:n,pullRequests:o,primaryPullRequest:go(e,t),warnings:s}}function Ml(e){return{provider:"github",owner:e.owner,repo:e.repo,number:e.number,url:e.url,baseBranch:e.baseBranch,headBranch:e.headBranch,status:e.status==="draft"?"open":e.status,draft:e.draft,mergeable:e.mergeable,mergeStateStatus:e.mergeStateStatus,reviewDecision:e.reviewDecision??null,requiredChecks:e.requiredChecks,comments:e.comments??[],lastSyncedAt:e.lastSyncedAt,lastSyncedHeadSha:e.lastSyncedHeadSha}}function bg(e,t){return{provider:"github",owner:e.owner??t.owner,repo:e.repo??t.name,number:e.number,url:e.url,title:null,status:e.draft?"draft":e.status,draft:e.draft??!1,baseBranch:e.baseBranch,headBranch:e.headBranch,mergeable:e.mergeable,mergeStateStatus:e.mergeStateStatus,reviewDecision:e.reviewDecision??null,requiredChecks:e.requiredChecks,comments:e.comments??[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:e.lastSyncedAt,lastSyncedHeadSha:e.lastSyncedHeadSha}}function Pg(e){return{provider:"github",owner:e.owner,repo:e.name,number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}}var S={listTasks:Zt,getTask:A,provisionTask:Ct,provisionProjectTask:tr,createTask:Ds,showTask:js,showTaskDiff:Fs,prepareTaskLogs:Ws,streamTaskLogs:qs,runChecks:Us,commitTask:Bs,closeTask:Vs,cleanupTask:Ks,addTaskLink:Gs,listTaskLinks:Hs,sortTasksForDisplay:Ss,resolveSelectedTaskId:vs,allocateTaskId:Ps,allocateTaskIdForRepo:It,allocateProjectTaskId:Qt,createDefaultTaskPtyTabs:rr,assertTaskWorktreeExists:z,resolveTaskLogPath:vt,buildTaskInspection:Xt,resolveArtifactPath:st,attachTask:zs,focusTask:Ys,openTask:Js,markRunnerFailed:Xs,recordStartupFailure:Qs,markTaskStarted:Zs,resolveContext:to,prs:{refresh:cr,refreshChecks:Ls,discoverOrRefresh:Xr,discoverOrRefreshAll:Dt,discoverOrRefreshMany:_s,show:so,discover:oo,link:io,refreshAssociation:ao,unlink:lo,merge:ro,getPrimaryPr:E,isPrTerminal:je,isMergeReady:Br,deriveTaskStatus:nt,upsertPr:Ce,normalizePr:Ae,summarizeRequiredChecks:ys,writePrStatusArtifact:lt}};var Ll={idle:0,working:1,ready:2,error:3};function ct(e,t,r,n="idle"){let s=t.find(o=>o.tabId===e);return s?s.sessionState==="failed"||s.sessionState==="exited"&&s.exitCode!==0?"error":s.sessionState==="exited"?"ready":r-s.lastActivityAt<5e3?"working":"ready":n}function Ve(e,t,r,n){let s=e.ptyTabs.find(i=>i.kind==="agent")?.id,o=t===s&&e.runnerSession?.lastKnownState==="failed"?"error":"idle";return ct(t,r,n,o)}function $t(e,t,r){let n="idle";for(let s of e.ptyTabs){if(s.kind!=="agent")continue;let o=Ve(e,s.id,t,r);Ll[o]>Ll[n]&&(n=o)}return n}function tn(e,t,r){return e.some(n=>n.ptyTabs.some(s=>s.kind==="agent"&&ct(s.id,t,r)==="working"))}function Re(e,t,r){let n=e.flatMap(o=>o.ptyTabs.filter(i=>i.kind==="agent").map(i=>{let a=t.find(c=>c.tabId===i.id),l=Ve(o,i.id,t,r);return{taskId:o.id,tabId:i.id,title:i.title,runner:i.runner??o.runner,state:l,sessionState:a?.sessionState??null,lastActivityAt:a?.lastActivityAt??null,exitCode:a?.exitCode??null,error:a?.error??(l==="error"?o.lastFailureReason??null:null)}})),s=e.map(o=>({taskId:o.id,state:$t(o,t,r),agentTabIds:n.filter(i=>i.taskId===o.id).map(i=>i.tabId)}));return{agents:n,tasks:s}}async function wo(e,t,r){let n=r.now??Date.now;if(r.tabId&&!e.ptyTabs.some(l=>l.kind==="agent"&&l.id===r.tabId))throw new f("TASK_CONTEXT_CONFLICT",`Agent tab ${r.tabId} does not belong to task ${e.id}.`,{details:{taskId:e.id,tabId:r.tabId}});let s=0,o=null,i=t.subscribe(()=>{s+=1,o?.()}),a=n()+r.timeoutMs;try{for(;;){let l=n(),c=Re([e],t.getSnapshots(),l),d=r.tabId?c.agents.find(p=>p.tabId===r.tabId)?.state??"idle":c.tasks[0]?.state??"idle";if(r.states.includes(d))return{kind:"waitTask",taskId:e.id,tabId:r.tabId??null,state:d,matchedStates:[...r.states],observedAt:new Date(l).toISOString()};if(r.signal?.aborted)throw _l(e.id);let u=a-n();if(u<=0)throw Sg(e.id,r.states,r.timeoutMs);let m=s;await new Promise((p,k)=>{let w=()=>{clearTimeout(N),r.signal?.removeEventListener("abort",b),p()},b=()=>{clearTimeout(N),k(_l(e.id))},N=setTimeout(w,u);o=w,r.signal?.addEventListener("abort",b,{once:!0}),s!==m&&o()}),o=null}}finally{i()}}var Sg=(e,t,r)=>new f("OPERATION_TIMEOUT",`Timed out after ${r}ms waiting for task ${e} agent state ${t.join(",")}.`,{retryable:!0,details:{taskId:e,states:t,timeoutMs:r}}),_l=e=>new f("OPERATION_CANCELLED",`Cancelled while waiting for task ${e} agent state.`,{retryable:!0,details:{taskId:e,cancelled:!0}});import{createConnection as Ag}from"node:net";import{createHash as Ig}from"node:crypto";import{tmpdir as Cg}from"node:os";import jl from"node:path";var Nt=7;function Ke(e){let t=Ig("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:jl.join(Cg(),`craig-${t}.sock`),pidPath:jl.join(e.runtimeDir,"pty-daemon.pid")}}async function Fl(e){let t=null;try{let r=await Eg(Ke(e.paths).socketPath);return t=new ko(r,e),await t.ready(),t}catch{return t?.close(),null}}var ko=class{constructor(t,r){this.socket=t;this.options=r;t.setEncoding("utf8"),t.on("data",n=>this.handleData(String(n))),t.on("error",n=>this.rejectAll(n instanceof Error?n:new Error(String(n)))),t.on("close",()=>this.handleClose())}socket;options;pending=new Map;snapshots=new Map;revisionByTabId=new Map;nextRequestId=1;revision=0;buffer="";closed=!1;async ready(){if((await this.send({type:"ping"})).protocolVersion!==Nt)throw new Error("Craig PTY daemon protocol mismatch.");await this.send({type:"setActivityEnabled",enabled:!0});let r=this.revision,n=await this.send({type:"getActivitySnapshots"});this.replaceSnapshots(n.activities??[],r)}getSnapshots(){return[...this.snapshots.values()]}close(){this.closed||(this.closed=!0,this.socket.end(),this.rejectAll(new Error("Craig PTY daemon activity connection closed.")))}async send(t){if(this.closed||this.socket.destroyed)throw new Error("Craig PTY daemon activity connection is closed.");let r=this.nextRequestId++,n=new Promise((o,i)=>{this.pending.set(r,{resolve:o,reject:i})});this.socket.write(`${JSON.stringify({...t,id:r})}
73
+ `)},mg=async e=>(await C("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
74
+ `).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as fg}from"node:child_process";import{access as gg}from"node:fs/promises";var Us=async(e,t)=>{let r=await A(e,t),n=Ct(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await gg(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},Vs=async e=>{await new Promise((t,r)=>{let n=!1,s=fg("tail",["-n","+1","-f",e],{stdio:"inherit"}),i=()=>{n=!0,s.kill("SIGINT")};process.on("SIGINT",i),s.on("error",a=>{o(),r(a)}),s.on("exit",(a,l)=>{if(o(),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 o(){process.off("SIGINT",i)}})};import{mkdir as hg}from"node:fs/promises";import wg from"node:path";var Bs=async(e,t)=>{let r=await A(e,t);if(await J(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 Hr(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 w.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);await x(e,r.id,a=>({...a,status:a.status==="running"?r.status:a.status,checks:{...a.checks,status:"running",commands:[...s],results:[]}}));let i=[];for(let a of s){let l=new Date().toISOString(),c=await $("sh",["-lc",a],{cwd:r.worktreePath}),d=new Date().toISOString(),u=c.exitCode??1;if(i.push({command:a,startedAt:l,finishedAt:d,exitCode:u}),u!==0){let f=c.stderr.trim()||c.stdout.trim()||`Check command failed: ${a}`,h=await x(e,r.id,m=>({...m,status:"review",checks:{...m.checks,results:i,status:"failed",lastRunAt:d},lastFailureReason:f}));return await Ol(e,h),{kind:"runChecks",taskId:r.id,status:"failed",commands:s}}}let o=await x(e,r.id,a=>({...a,status:a.status==="review"||a.status==="checked"?"checked":a.status,checks:{...a.checks,results:i,status:"passed",lastRunAt:new Date().toISOString()},lastFailureReason:null}));return await Ol(e,o),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},Ol=async(e,t)=>{let r=lt(e,t.artifacts.checkSummaryPath);r&&(await hg(wg.dirname(r),{recursive:!0}),await L(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var Ks=async(e,t)=>{let r=await A(e,t);await J(r);let n=await Hr(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 nl(r.worktreePath),await sl(r.worktreePath,s);let i=await il(r.worktreePath),o=new Date().toISOString(),a=await x(e,r.id,l=>({...l,status:l.status==="running"?r.status:l.status,lastCommit:{sha:i.sha,message:i.message,committedAt:o},lastFailureReason:null}));return{kind:"commitTask",taskId:r.id,status:a.status,commitSha:i.sha,message:i.message}};import{access as kg}from"node:fs/promises";var Gs=async(e,t)=>{let r=await A(e,t),n=await yg(r.worktreePath);return x(e,t,s=>({...s,status:"closed",cleanup:{...s.cleanup,preservedWorktree:n&&s.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null}))},yg=async e=>{try{return await kg(e),!0}catch{return!1}};var Hs=async(e,t,r)=>{let n=[],s=null,i=null;try{if(t.sessionId){let o=await Ue(e,t.sessionId);await Tl(e.repoRoot,o.sessionName),s=new Date().toISOString()}}catch(o){n.push(o instanceof Error?o.message:"Failed to close tmux session.")}if(!r.preserveWorktree)try{await al(e.repoRoot,t.worktreePath),i=new Date().toISOString()}catch(o){n.push(o instanceof Error?o.message:"Failed to remove worktree.")}await x(e,t.id,o=>({...o,cleanup:{...o.cleanup,paneClosedAt:s??o.cleanup.paneClosedAt,worktreeRemovedAt:i??o.cleanup.worktreeRemovedAt,preservedWorktree:r.preserveWorktree,warning:n.length>0?n.join(" "):null}}))};var zs=async(e,t,r)=>{let n=await pe(e,r),s=await x(e,t,i=>{if(i.repoId===n.id)throw new Error(`Repo ${n.id} is already the primary repo for task ${i.id}.`);return{...i,linkedRepoIds:i.linkedRepoIds.includes(n.id)?i.linkedRepoIds:[...i.linkedRepoIds,n.id]}});return{kind:"addTaskLink",taskId:s.id,repoId:n.id,linkedRepoIds:s.linkedRepoIds}},Ys=async(e,t)=>{let r=await A(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>pe(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var Js=async(e,t)=>{let r=await A(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([pe(e,r.repoId),Ue(e,r.sessionId)]),i=await ir.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:i.id,disposition:"attached"}};var Xs=async(e,t)=>{let r=await A(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await Ue(e,r.sessionId).catch(s=>{throw Tg(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 Xr(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},Tg=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as Rg}from"node:child_process";var Qs=async(e,t)=>{let r=await A(e,t);await J(r);let s=(await w.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!1,command:null};let i=[...s,r.worktreePath];return await bg(i,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:i}},bg=async(e,t)=>{await new Promise((r,n)=>{let[s,...i]=e,o=Rg(s,i,{cwd:t,stdio:"inherit"});o.on("error",n),o.on("exit",a=>{if(a===0){r();return}n(new Error(`${e.join(" ")} failed with exit code ${a??"unknown"}.`))})})};var Zs=async(e,t,r)=>{await x(e,t,n=>({...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r}))},ei=async(e,t,r)=>x(e,t,n=>({...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})),ti=async(e,t)=>x(e,t,r=>{let n=r.ptyTabs.find(s=>s.kind==="agent");if(!n)throw new Error(`Task ${t} is missing its agent PTY tab.`);return{...r,status:"running",selectedPtyTabId:n.id,runnerSession:{...r.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}}});import{realpath as Ml}from"node:fs/promises";import pr from"node:path";async function ni(e,t){if(t.explicitTaskId!==void 0){let l=await $l(e,t.explicitTaskId,"explicit");return ri(l,"explicit",t.environmentAgentTabId)}if(t.environmentTaskId!==void 0){let l=await $l(e,t.environmentTaskId,"environment");return ri(l,"environment",t.environmentAgentTabId)}let r=await Ml(t.cwd).catch(()=>pr.resolve(t.cwd)),n=await tr(e,{includeClosed:!0}),i=(await Promise.all(n.tasks.map(async l=>({task:l,matches:await Sg(l,r)})))).filter(l=>l.matches).map(l=>l.task),o=[...new Map(i.map(l=>[l.id,l])).values()];if(o.length>1)throw new g("TASK_CONTEXT_AMBIGUOUS",`Multiple Craig tasks match ${r}: ${o.map(l=>l.id).join(", ")}. Use --task <id>.`,{details:{cwd:r,taskIds:o.map(l=>l.id)}});let a=o[0];if(a)return ri(a,"cwd",t.environmentAgentTabId);if(t.environmentAgentTabId!==void 0)throw new g("TASK_CONTEXT_CONFLICT",`CRAIG_AGENT_TAB_ID is set to ${t.environmentAgentTabId}, but no task context could be resolved.`,{details:{agentTabId:t.environmentAgentTabId}});if(t.required)throw new g("TASK_CONTEXT_NOT_FOUND",`No Craig task was found from ${r}. Use --task <id> or run the command inside a task worktree.`,{details:{cwd:r}});return null}async function $l(e,t,r){try{return await A(e,t)}catch(n){throw!(n instanceof g)||n.code!=="TASK_NOT_FOUND"?n:new g("TASK_CONTEXT_NOT_FOUND",`Craig task "${t}" from ${r==="explicit"?"--task":"CRAIG_TASK_ID"} was not found.`,{details:{taskId:t,source:r},cause:n})}}function ri(e,t,r){let n=r??null;if(n!==null){let s=e.ptyTabs.find(i=>i.id===n);if(!s||s.kind!=="agent")throw new g("TASK_CONTEXT_CONFLICT",`Agent tab ${n} does not belong to Craig task ${e.id}.`,{details:{taskId:e.id,agentTabId:n}})}return{task:e,source:t,agentTabId:n}}function Pg(e){return[e.worktreePath,...e.bundlePath?[e.bundlePath]:[],...(e.repoTargets??[]).map(t=>t.worktreePath)]}async function Sg(e,t){return(await Promise.all(Pg(e).map(n=>Ml(n).catch(()=>pr.resolve(n))))).some(n=>vg(n,t))}function vg(e,t){let r=pr.relative(pr.resolve(e),t);return r===""||!r.startsWith("..")&&!pr.isAbsolute(r)}var si=async(e,t,r="merge",n)=>{let s=await A(e,t),i=n??E(s)?.number;if(!i)throw new Error(`Task ${s.id} has no pull request to merge.`);await Cl(s.worktreePath,i,r)};var mr={readTask:A,writeTask:Ce,withTaskLock:We,ensureGhAuthenticated:xe,fetchPrView:xt,discoverPrView:Al,getGitHubRepositoryLocator:Qr,writePrStatusArtifact:pt};async function oi(e,t,r,n=mr){let s=await n.readTask(e,t),i=await Cg(s,r,n);return Ke(s,i,"showTaskPr","shown",[])}async function ai(e,t,r,n=mr){return n.withTaskLock(e,t,async()=>{let s=await n.readTask(e,t),i=await pi(s,r,null,n);await mi(i,n);let o=await rn(`discover a pull request for ${i.branch}`,()=>n.discoverPrView(i.branch,i.worktreePath));if(!o)return Ke(s,i,"discoverTaskPr","not_found",[]);fi(o,i);let a=nn(s,i,o.number),l=await gi(e,s,i,o,n);return Ke(l,i,"discoverTaskPr",a?"synced":"discovered",[])})}async function li(e,t,r,n,s=mr){let i=ui(r);return s.withTaskLock(e,t,async()=>{let o=await s.readTask(e,t),a=await pi(o,n,i.repository,s);Ll(i.repository,a),await mi(a,s);let l=await rn(`fetch pull request ${r}`,()=>s.fetchPrView(r,a.worktreePath));Ag(l,i),fi(l,a);let c=nn(o,a,l.number),d=hi(o,a),u=d&&!It(d,{owner:a.repository.owner,repo:a.repository.name,number:l.number})&&d.status!=="closed"&&d.status!=="merged"?[`Pull request #${l.number} becomes active; #${d.number} remains in task history.`]:[],f=await gi(e,o,a,l,s);return Ke(f,a,"linkTaskPr",c?"unchanged":"linked",u)})}async function Ig(e,t,r,n){if(e.type==="repo"){if(t&&t!==e.repoId)throw Mt(e,t);let o=e.prs.find(a=>a.number===r.number)??E(e);return{repoId:e.repoId,branch:e.branch,worktreePath:e.worktreePath,repository:await tn(o,e.worktreePath,e.repoId,n),projectTarget:null}}if(t){let o=e.repoTargets?.find(c=>c.repoId===t);if(!o)throw Mt(e,t);let a=Nl(o.pullRequest),l=e.prs.find(c=>c.number===r.number&&(!c.headBranch||c.headBranch===o.branch)&&(!a||!!(c.owner&&c.repo&&Te({owner:c.owner,name:c.repo},a))))??o.pullRequest;return{repoId:t,branch:o.branch,worktreePath:o.worktreePath,repository:await tn(l,o.worktreePath,t,n),projectTarget:o}}if(!r.repository)throw new g("CLI_USAGE",`Project task ${e.id} requires --repo <repo-id> for a numeric pull request selector.`,{details:{taskId:e.id,pullRequestNumber:r.number}});let s=r.repository,i=[];for(let o of e.repoTargets??[]){let a=o.pullRequest.owner&&o.pullRequest.repo&&Te({owner:o.pullRequest.owner,name:o.pullRequest.repo},s),l=e.prs.some(c=>c.number===r.number&&c.owner&&c.repo&&Te({owner:c.owner,name:c.repo},s)&&(!c.headBranch||c.headBranch===o.branch));(a||l)&&i.push({repoId:o.repoId,branch:o.branch,worktreePath:o.worktreePath,repository:s,projectTarget:o})}if(i.length!==1)throw new g("TASK_CONTEXT_AMBIGUOUS",`Pull request repository ${r.repository.owner}/${r.repository.name} does not map to exactly one target in project task ${e.id}.`,{details:{taskId:e.id,owner:r.repository.owner,repo:r.repository.name,matchingRepoIds:i.map(o=>o.repoId)}});return i[0]}async function ci(e,t,r,n=mr){return n.withTaskLock(e,t,async()=>{let s=await n.readTask(e,t),i=await pi(s,r,null,n),o=hi(s,i);if(!o?.number)return Ke(s,i,"refreshTaskPr","not_found",[]);await mi(i,n);let a=await rn(`refresh pull request #${o.number}`,()=>n.fetchPrView(String(o.number),i.worktreePath));fi(a,i);let l=await gi(e,s,i,a,n);return Ke(l,i,"refreshTaskPr","synced",[])})}async function di(e,t,r,n,s=mr){let i=ui(r);return s.withTaskLock(e,t,async()=>{let o=await s.readTask(e,t),a=await Ig(o,n,i,s);if(Ll(i.repository,a),!nn(o,a,i.number))return Ke(o,a,"unlinkTaskPr","unchanged",[]);let c=Eg(o,a,i.number),d=await jl(e,c,s);return Ke(d,a,"unlinkTaskPr","unlinked",[])})}function ui(e){let t=e.trim(),r=Be(t);if(r)return{number:r.number,repository:r};if(/^[1-9]\d*$/.test(t))return{number:Number(t),repository:null};throw new g("CLI_USAGE",`Invalid pull request selector "${e}". Use a GitHub pull request URL or positive number.`,{details:{selector:e}})}async function pi(e,t,r,n){if(e.type==="repo"){if(t&&t!==e.repoId)throw Mt(e,t);return ii(e.repoId,e.branch,e.worktreePath,null,n)}let s=e.repoTargets??[];if(t){let o=s.find(a=>a.repoId===t);if(!o)throw Mt(e,t);return ii(o.repoId,o.branch,o.worktreePath,o,n)}if(!r)throw new g("CLI_USAGE",`Project task ${e.id} requires --repo <repo-id> for pull request commands.`,{details:{taskId:e.id,repoIds:s.map(o=>o.repoId)}});let i=[];for(let o of s){let a=await ii(o.repoId,o.branch,o.worktreePath,o,n).catch(l=>{if(l instanceof g&&l.code==="EXTERNAL_DEPENDENCY_FAILED"&&l.message.includes("does not have a supported GitHub origin remote"))return null;throw l});a&&Te(a.repository,r)&&i.push(a)}if(i.length!==1)throw new g("TASK_CONTEXT_AMBIGUOUS",`Pull request repository ${r.owner}/${r.name} does not map to exactly one target in project task ${e.id}.`,{details:{taskId:e.id,owner:r.owner,repo:r.name,matchingRepoIds:i.map(o=>o.repoId)}});return i[0]}async function Cg(e,t,r){if(e.type==="repo"){if(t&&t!==e.repoId)throw Mt(e,t);let s=E(e);return{repoId:e.repoId,branch:e.branch,worktreePath:e.worktreePath,repository:await tn(s,e.worktreePath,e.repoId,r),projectTarget:null}}if(!t)throw new g("CLI_USAGE",`Project task ${e.id} requires --repo <repo-id> for pull request commands.`,{details:{taskId:e.id,repoIds:(e.repoTargets??[]).map(s=>s.repoId)}});let n=e.repoTargets?.find(s=>s.repoId===t);if(!n)throw Mt(e,t);return{repoId:t,branch:n.branch,worktreePath:n.worktreePath,repository:await tn(n.pullRequest,n.worktreePath,t,r),projectTarget:n}}async function tn(e,t,r,n){let s=Nl(e);return s||(await n.getGitHubRepositoryLocator(t).catch(()=>null)??{owner:"",name:r})}function Nl(e){return e?.owner&&e.repo?{owner:e.owner,name:e.repo}:e?.url?Be(e.url):null}async function ii(e,t,r,n,s){let i=await s.getGitHubRepositoryLocator(r);if(!i)throw new g("EXTERNAL_DEPENDENCY_FAILED",`Repo ${e} does not have a supported GitHub origin remote.`,{details:{repoId:e,worktreePath:r}});return{repoId:e,branch:t,worktreePath:r,repository:i,projectTarget:n}}async function mi(e,t){await rn("verify GitHub CLI authentication",()=>t.ensureGhAuthenticated(e.worktreePath))}async function rn(e,t){try{return await t()}catch(r){throw r instanceof g?r:new g("EXTERNAL_DEPENDENCY_FAILED",`Failed to ${e}: ${r instanceof Error?r.message:String(r)}`,{retryable:!0,cause:r})}}function Ll(e,t){if(e&&!Te(e,t.repository))throw _l(e,t)}function Ag(e,t){let r=Be(e.url);if(!r||r.number!==t.number)throw new g("TASK_CONTEXT_CONFLICT",`GitHub returned ${e.url} for pull request selector #${t.number}.`,{details:{selectorNumber:t.number,returnedUrl:e.url}});if(t.repository&&!Te(t.repository,r))throw new g("PR_REPOSITORY_MISMATCH",`GitHub returned a pull request from ${r.owner}/${r.name}, not ${t.repository.owner}/${t.repository.name}.`,{details:{selectorRepository:t.repository,returnedRepository:r}})}function fi(e,t){let r=Be(e.url);if(!r||!Te(r,t.repository))throw _l(r,t);if(e.headRefName!==t.branch)throw new g("PR_BRANCH_MISMATCH",`Pull request #${e.number} uses head branch ${e.headRefName}, not task branch ${t.branch}.`,{details:{repoId:t.repoId,pullRequestNumber:e.number,expectedBranch:t.branch,actualBranch:e.headRefName}})}function _l(e,t){return new g("PR_REPOSITORY_MISMATCH",`Pull request repository ${e?`${e.owner}/${e.name}`:"is invalid"} does not match task repo ${t.repository.owner}/${t.repository.name}.`,{details:{repoId:t.repoId,expectedOwner:t.repository.owner,expectedRepo:t.repository.name,actualOwner:e?.owner??null,actualRepo:e?.name??null}})}function Mt(e,t){return new g("TASK_CONTEXT_CONFLICT",`Repo ${t} is not a target of task ${e.id}.`,{details:{taskId:e.id,repoId:t}})}function Te(e,t){return e.owner.toLowerCase()===t.owner.toLowerCase()&&e.name.toLowerCase()===t.name.toLowerCase()}async function gi(e,t,r,n,s){let i=nn(t,r,n.number),o=Ee(n,i,r.repository),a=Ae(t,o);return r.projectTarget&&(a={...a,repoTargets:(a.repoTargets??[]).map(l=>l.repoId===r.repoId?{...l,pullRequest:ql(o)}:l)}),jl(e,a,s)}function Eg(e,t,r){let n=e.prs.filter(i=>!Wl(i,t,r)),s={...e,prs:n};if(t.projectTarget?.pullRequest.number===r){let i=Fl(n.filter(o=>o.owner&&o.repo&&Te({owner:o.owner,name:o.repo},t.repository)));s={...s,repoTargets:(s.repoTargets??[]).map(o=>o.repoId===t.repoId?{...o,pullRequest:i?ql(i):Dg(t.repository)}:o)}}return s}async function jl(e,t,r){let n=t.status==="closed"?t.status:t.type==="project"?Ls(t):at(t.prs),s={...t,status:n};return or(e,s,r)}function nn(e,t,r){return wi(e,t).find(n=>Wl(n,t,r))??null}function hi(e,t){if(!t.projectTarget)return E(e);let r=wi(e,t);return Fl(r)}function Fl(e){return[...e].reverse().find(t=>t.status!=="merged"&&t.status!=="closed")??e[e.length-1]??null}function wi(e,t){if(!t.projectTarget)return e.prs;let r=e.prs.filter(i=>i.owner&&i.repo&&Te({owner:i.owner,name:i.repo},t.repository)),n=e.repoTargets?.find(i=>i.repoId===t.repoId),s=n?.pullRequest.number?xg(n.pullRequest,t.repository):null;return s&&!r.some(i=>It(i,s))?[...r,s]:r}function Wl(e,t,r){return e.number!==r?!1:!e.owner||!e.repo||Te({owner:e.owner,name:e.repo},t.repository)}function Ke(e,t,r,n,s){let i=wi(e,t);return{kind:r,taskId:e.id,repoId:t.repoId,disposition:n,pullRequests:i,primaryPullRequest:hi(e,t),warnings:s}}function ql(e){return{provider:"github",owner:e.owner,repo:e.repo,number:e.number,url:e.url,baseBranch:e.baseBranch,headBranch:e.headBranch,status:e.status==="draft"?"open":e.status,draft:e.draft,mergeable:e.mergeable,mergeStateStatus:e.mergeStateStatus,reviewDecision:e.reviewDecision??null,requiredChecks:e.requiredChecks,comments:e.comments??[],lastSyncedAt:e.lastSyncedAt,lastSyncedHeadSha:e.lastSyncedHeadSha}}function xg(e,t){return{provider:"github",owner:e.owner??t.owner,repo:e.repo??t.name,number:e.number,url:e.url,title:null,status:e.draft?"draft":e.status,draft:e.draft??!1,baseBranch:e.baseBranch,headBranch:e.headBranch,mergeable:e.mergeable,mergeStateStatus:e.mergeStateStatus,reviewDecision:e.reviewDecision??null,requiredChecks:e.requiredChecks,comments:e.comments??[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:e.lastSyncedAt,lastSyncedHeadSha:e.lastSyncedHeadSha}}function Dg(e){return{provider:"github",owner:e.owner,repo:e.name,number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}}var P={listTasks:tr,getTask:A,provisionTask:Et,provisionProjectTask:nr,createTask:$s,showTask:Ws,showTaskDiff:qs,prepareTaskLogs:Us,streamTaskLogs:Vs,runChecks:Bs,commitTask:Ks,closeTask:Gs,cleanupTask:Hs,addTaskLink:zs,listTaskLinks:Ys,sortTasksForDisplay:Is,resolveSelectedTaskId:Cs,allocateTaskId:vs,allocateTaskIdForRepo:At,allocateProjectTaskId:er,createDefaultTaskPtyTabs:sr,assertTaskWorktreeExists:J,resolveTaskLogPath:Ct,buildTaskInspection:Zt,resolveArtifactPath:lt,attachTask:Js,focusTask:Xs,openTask:Qs,markRunnerFailed:Zs,recordStartupFailure:ei,markTaskStarted:ti,resolveContext:ni,prs:{refresh:ur,refreshChecks:js,discoverOrRefresh:en,discoverOrRefreshAll:$t,discoverOrRefreshMany:Fs,show:oi,discover:ai,link:li,refreshAssociation:ci,unlink:di,merge:si,getPrimaryPr:E,isPrTerminal:qe,isMergeReady:Gr,deriveTaskStatus:at,upsertPr:Ae,normalizePr:Ee,summarizeRequiredChecks:Rs,writePrStatusArtifact:pt}};var Ul={idle:0,working:1,ready:2,error:3};function De(e,t,r,n="idle"){let s=t.find(i=>i.tabId===e);return s?s.sessionState==="failed"||s.sessionState==="exited"&&s.exitCode!==0?"error":s.sessionState==="exited"?"ready":r-s.lastActivityAt<5e3?"working":"ready":n}function Ge(e,t,r,n){let s=e.ptyTabs.find(o=>o.kind==="agent")?.id,i=t===s&&e.runnerSession?.lastKnownState==="failed"?"error":"idle";return De(t,r,n,i)}function Nt(e,t,r){let n="idle";for(let s of e.ptyTabs){if(s.kind!=="agent")continue;let i=Ge(e,s.id,t,r);Ul[i]>Ul[n]&&(n=i)}return n}function sn(e,t,r){return e.some(n=>n.ptyTabs.some(s=>s.kind==="agent"&&De(s.id,t,r)==="working"))}function Re(e,t,r){let n=e.flatMap(i=>i.ptyTabs.filter(o=>o.kind==="agent").map(o=>{let a=t.find(c=>c.tabId===o.id),l=Ge(i,o.id,t,r);return{taskId:i.id,tabId:o.id,title:o.title,runner:o.runner??i.runner,state:l,sessionState:a?.sessionState??null,lastActivityAt:a?.lastActivityAt??null,exitCode:a?.exitCode??null,error:a?.error??(l==="error"?i.lastFailureReason??null:null)}})),s=e.map(i=>({taskId:i.id,state:Nt(i,t,r),agentTabIds:n.filter(o=>o.taskId===i.id).map(o=>o.tabId)}));return{agents:n,tasks:s}}async function ki(e,t,r){let n=r.now??Date.now;if(r.tabId&&!e.ptyTabs.some(l=>l.kind==="agent"&&l.id===r.tabId))throw new g("TASK_CONTEXT_CONFLICT",`Agent tab ${r.tabId} does not belong to task ${e.id}.`,{details:{taskId:e.id,tabId:r.tabId}});let s=0,i=null,o=t.subscribe(()=>{s+=1,i?.()}),a=n()+r.timeoutMs;try{for(;;){let l=n(),c=Re([e],t.getSnapshots(),l),d=r.tabId?c.agents.find(h=>h.tabId===r.tabId)?.state??"idle":c.tasks[0]?.state??"idle";if(r.states.includes(d))return{kind:"waitTask",taskId:e.id,tabId:r.tabId??null,state:d,matchedStates:[...r.states],observedAt:new Date(l).toISOString()};if(r.signal?.aborted)throw Vl(e.id);let u=a-n();if(u<=0)throw Og(e.id,r.states,r.timeoutMs);let f=s;await new Promise((h,m)=>{let k=()=>{clearTimeout(O),r.signal?.removeEventListener("abort",b),h()},b=()=>{clearTimeout(O),m(Vl(e.id))},O=setTimeout(k,u);i=k,r.signal?.addEventListener("abort",b,{once:!0}),s!==f&&i()}),i=null}}finally{o()}}var Og=(e,t,r)=>new g("OPERATION_TIMEOUT",`Timed out after ${r}ms waiting for task ${e} agent state ${t.join(",")}.`,{retryable:!0,details:{taskId:e,states:t,timeoutMs:r}}),Vl=e=>new g("OPERATION_CANCELLED",`Cancelled while waiting for task ${e} agent state.`,{retryable:!0,details:{taskId:e,cancelled:!0}});import{createConnection as Ng}from"node:net";import{createHash as $g}from"node:crypto";import{tmpdir as Mg}from"node:os";import Bl from"node:path";var Lt=8;function He(e){let t=$g("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:Bl.join(Mg(),`craig-${t}.sock`),pidPath:Bl.join(e.runtimeDir,"pty-daemon.pid")}}async function Kl(e){let t=null;try{let r=await Lg(He(e.paths).socketPath);return t=new Ti(r,e),await t.ready(),t}catch{return t?.close(),null}}var Ti=class{constructor(t,r){this.socket=t;this.options=r;t.setEncoding("utf8"),t.on("data",n=>this.handleData(String(n))),t.on("error",n=>this.rejectAll(n instanceof Error?n:new Error(String(n)))),t.on("close",()=>this.handleClose())}socket;options;pending=new Map;snapshots=new Map;revisionByTabId=new Map;nextRequestId=1;revision=0;buffer="";closed=!1;async ready(){if((await this.send({type:"ping"})).protocolVersion!==Lt)throw new Error("Craig PTY daemon protocol mismatch.");await this.send({type:"setActivityEnabled",enabled:!0});let r=this.revision,n=await this.send({type:"getActivitySnapshots"});this.replaceSnapshots(n.activities??[],r)}getSnapshots(){return[...this.snapshots.values()]}close(){this.closed||(this.closed=!0,this.socket.end(),this.rejectAll(new Error("Craig PTY daemon activity connection closed.")))}async send(t){if(this.closed||this.socket.destroyed)throw new Error("Craig PTY daemon activity connection is closed.");let r=this.nextRequestId++,n=new Promise((i,o)=>{this.pending.set(r,{resolve:i,reject:o})});this.socket.write(`${JSON.stringify({...t,id:r})}
75
75
  `);let s=await n;if(!s.ok)throw new Error(s.error);return s}handleData(t){this.buffer+=t;let r=this.buffer.indexOf(`
76
76
  `);for(;r!==-1;){let n=this.buffer.slice(0,r);this.buffer=this.buffer.slice(r+1),this.handleMessage(n),r=this.buffer.indexOf(`
77
- `)}}handleMessage(t){if(t.trim().length===0)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r){let n=this.pending.get(r.id);if(!n)return;this.pending.delete(r.id),n.resolve(r);return}r.type==="activity"?(this.recordSnapshot(r.snapshot),this.options.onActivity?.(r.snapshot)):r.type==="activityRemoved"&&(this.removeSnapshot(r.tabId),this.options.onActivityRemoved?.(r.tabId))}replaceSnapshots(t,r){let n=new Map;for(let[s,o]of this.revisionByTabId)o>r&&n.set(s,this.snapshots.get(s)??null);this.snapshots.clear();for(let s of t)this.snapshots.set(s.tabId,s);for(let[s,o]of n)o?this.snapshots.set(s,o):this.snapshots.delete(s)}recordSnapshot(t){this.revision+=1,this.revisionByTabId.set(t.tabId,this.revision),this.snapshots.set(t.tabId,t)}removeSnapshot(t){this.revision+=1,this.revisionByTabId.set(t,this.revision),this.snapshots.delete(t)}handleClose(){if(this.closed)return;this.closed=!0;let t=new Error("Craig PTY daemon connection closed.");this.rejectAll(t);for(let r of this.snapshots.values()){if(r.sessionState!=="running")continue;let n={...r,sessionState:"failed",lastActivityAt:Date.now(),error:t.message};this.recordSnapshot(n),this.options.onActivity?.(n)}this.options.onDaemonClose?.()}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}};function Eg(e){return new Promise((t,r)=>{let n=Ag(e);n.once("connect",()=>t(n)),n.once("error",r)})}var To={openObserver:ql,listTasks:e=>S.listTasks(e),getTask:(e,t)=>S.getTask(e,t),now:Date.now};async function xg(e,t,r=To){let n=await Wl(e,t,r),s=await r.openObserver(e);try{return{kind:"listAgents",...Re(n,s.getSnapshots(),r.now()),daemonAvailable:s.daemonAvailable}}finally{s.close()}}async function Dg(e,t,r=To){let n=await Wl(e,t.taskId,r),s=await r.openObserver(e);try{let o=Re(n,s.getSnapshots(),r.now()),i=t.tabId?o.agents.filter(l=>l.tabId===t.tabId):o.agents;if(t.tabId&&i.length===0)throw new f("TASK_CONTEXT_NOT_FOUND",`Agent tab ${t.tabId} was not found${t.taskId?` in task ${t.taskId}`:""}.`,{details:{taskId:t.taskId??null,tabId:t.tabId}});let a=new Set(i.map(l=>l.taskId));return{kind:"showAgentStatus",agents:i,tasks:t.tabId?o.tasks.filter(l=>a.has(l.taskId)):o.tasks,daemonAvailable:s.daemonAvailable}}finally{s.close()}}async function Og(e,t,r,n=To){let s=await n.getTask(e,t),o=await n.openObserver(e);try{return await wo(s,o,{...r,now:n.now})}finally{o.close()}}async function Wl(e,t,r){return t?[await r.getTask(e,t)]:(await r.listTasks(e)).tasks}async function ql(e){return yo.open(e)}async function $g(e){return ql(e)}var yo=class e{listeners=new Set;snapshots=new Map;client=null;reconnectTimer=null;reconnectDelayMs=250;closed=!1;paths;constructor(t){this.paths=t}static async open(t){let r=new e(t);return await r.connect(),r}get daemonAvailable(){return this.client!==null}getSnapshots(){return[...this.snapshots.values()]}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}close(){this.closed=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.client?.close(),this.client=null}async connect(){if(this.closed)return;let t=await Fl({paths:this.paths,onActivity:r=>{this.snapshots.set(r.tabId,r),this.notify()},onActivityRemoved:r=>{this.snapshots.delete(r),this.notify()},onDaemonClose:()=>{this.client=null,this.notify(),this.scheduleReconnect()}});if(this.closed){t?.close();return}if(this.client=t,t){this.reconnectDelayMs=250,this.snapshots.clear();for(let r of t.getSnapshots())this.snapshots.set(r.tabId,r);this.notify()}else this.scheduleReconnect()}scheduleReconnect(){if(this.closed||this.reconnectTimer)return;let t=this.reconnectDelayMs;this.reconnectDelayMs=Math.min(this.reconnectDelayMs*2,1e3),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},t)}notify(){for(let t of this.listeners)t()}},Ee={listAgents:xg,showAgentStatus:Dg,waitForTask:Og,openObserver:$g};import{randomUUID as Vg}from"node:crypto";import{mkdir as Gl,open as So,readdir as Hl,readFile as nn,rm as Kg,stat as Gg}from"node:fs/promises";import vo from"node:path";import{mkdir as Ul,readFile as Ng,rm as rn,stat as Mg,writeFile as Lg}from"node:fs/promises";import Ro from"node:path";var _g=20,jg=3e4,Fg=5e3;async function Bl(e,t){let r=Ro.join(e.runtimeDir,"event-journal.lock");await Ul(e.runtimeDir,{recursive:!0});let n=Date.now();for(;;)try{await Ul(r);try{await Lg(Ro.join(r,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(s){throw await rn(r,{recursive:!0,force:!0}),s}break}catch(s){if(!Ug(s))throw s;if(await Wg(r))continue;if(Date.now()-n>=jg)throw new f("OPERATION_TIMEOUT","Timed out waiting for the event journal lock.",{retryable:!0});await Bg(_g)}try{return await t()}finally{await rn(r,{recursive:!0,force:!0})}}async function Wg(e){let t=await Ng(Ro.join(e,"owner.json"),"utf8").then(n=>JSON.parse(n)).catch(()=>null);if(t&&typeof t.pid=="number")return qg(t.pid)?!1:(await rn(e,{recursive:!0,force:!0}),!0);let r=await Mg(e).catch(()=>null);return!r||Date.now()-r.mtimeMs<Fg?!1:(await rn(e,{recursive:!0,force:!0}),!0)}function qg(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var Ug=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST",Bg=e=>new Promise(t=>setTimeout(t,e));var Hg=256*1024,zg=16,Yg=64*1024;async function Lt(e,t,r={}){let n=Po(r.maxSegmentBytes??Hg,"Event journal segment size"),s=Po(r.maxSegments??zg,"Event journal retention"),o=Po(r.maxRecordBytes??Yg,"Event record size");return Bl(e,async()=>{await Gl(e.eventsDir,{recursive:!0}),await eh(e);let i=await Io(e),a=t.id??Vg(),l=i.events.find(b=>b.id===a);if(l)return l;let c=(i.events.at(-1)?.sequence??0)+1,d={schemaVersion:1,id:a,sequence:c,workspaceId:t.workspaceId??null,taskId:t.taskId??null,agentTabId:t.agentTabId??null,commandId:t.commandId??null,swarmRunId:t.swarmRunId??null,swarmStepId:t.swarmStepId??null,type:t.type,occurredAt:t.occurredAt??new Date().toISOString(),actor:t.actor,data:nh(t.data)},u=`${JSON.stringify(d)}
78
- `;if(Buffer.byteLength(u)>o)throw new f("CLI_USAGE",`Event record exceeds the ${o}-byte limit.`,{details:{eventType:t.type,maxRecordBytes:o}});let p=(await sn(e)).at(-1),k=!p||await Jg(p.path,u,n);if(k&&(p={name:Kl(c),path:vo.join(e.eventsDir,Kl(c)),startSequence:c}),!p)throw new f("INTERNAL_ERROR","Failed to select an event journal segment.",{});let w=await So(p.path,"a");try{await w.writeFile(u,"utf8"),await w.sync()}finally{await w.close()}return k&&await Jl(e.eventsDir),await Xg(e,s),d})}async function pr(e,t={}){let r=await Io(e),n=th(r.events,t.after,r.earliestSequence,r.events.at(-1)?.sequence??null),s=t.typeGlob?rh(t.typeGlob):null,o=r.events.filter(l=>l.sequence>n&&(!t.taskId||l.taskId===t.taskId)&&(!s||s.test(l.type))),i=r.events.at(-1)?.sequence??null,a=r.events.filter(l=>l.sequence>n).at(-1);return{kind:"listEvents",events:o,cursor:{after:a?.id??t.after??null,sequence:a?.sequence??n,earliestAvailableSequence:r.earliestSequence,latestSequence:i}}}async function zl(e){return(await Io(e)).events}async function Io(e){await Gl(e.eventsDir,{recursive:!0});let t=await sn(e),r=[],n=new Set;for(let s=0;s<t.length;s+=1){let o=t[s],i=await nn(o.path,"utf8"),a=s===t.length-1,l=i.split(`
79
- `);if(i.endsWith(`
80
- `))l.pop();else{if(!a)throw Ge(o.name,"segment has a truncated tail");l.pop()}for(let c=0;c<l.length;c+=1){let d=l[c];if(d.length===0)throw Ge(o.name,`empty record at line ${c+1}`);let u;try{u=JSON.parse(d)}catch{throw Ge(o.name,`invalid JSON at line ${c+1}`)}let m=sh(u,o.name,c+1);if(c===0&&m.sequence!==o.startSequence)throw Ge(o.name,`first record sequence ${m.sequence} does not match segment name`);if(n.has(m.id))throw Ge(o.name,`duplicate event id ${m.id}`);n.add(m.id);let p=r.at(-1);if(p&&m.sequence!==p.sequence+1)throw Ge(o.name,`non-monotonic sequence ${m.sequence} after ${p.sequence}`);r.push(m)}}return{events:r,earliestSequence:r[0]?.sequence??null}}async function sn(e){return(await Hl(e.eventsDir).catch(r=>{if(Yl(r))return[];throw r})).flatMap(r=>{let n=/^segment-(\d{16})\.jsonl$/.exec(r);return n?[{name:r,path:vo.join(e.eventsDir,r),startSequence:Number(n[1])}]:[]}).sort((r,n)=>r.startSequence-n.startSequence)}async function Jg(e,t,r){let n=await Gg(e).catch(()=>null);return n!==null&&n.size>0&&n.size+Buffer.byteLength(t)>r}async function Xg(e,t){let r=await sn(e),n=Math.max(0,r.length-t),s=await Qg(e);if(s===null)return;for(let i=0;i<n;i+=1)if(await Zg(r[i].path,s)){n=i;break}let o=r.slice(0,n);for(let i of o)await Kg(i.path,{force:!0});o.length>0&&await Jl(e.eventsDir)}async function Qg(e){let t=await Hl(e.commandsDir).catch(n=>{if(Yl(n))return[];throw n}),r=new Set;for(let n of t.filter(s=>s.endsWith(".json")))try{let s=JSON.parse(await nn(vo.join(e.commandsDir,n),"utf8"));typeof s.id=="string"&&(s.state==="queued"||s.state==="delivering")&&r.add(s.id)}catch{return null}return r}async function Zg(e,t){if(t.size===0)return!1;let r=await nn(e,"utf8");for(let n of r.split(`
81
- `))if(n)try{let s=JSON.parse(n);if(typeof s.commandId=="string"&&t.has(s.commandId))return!0}catch{return!0}return!1}async function eh(e){let t=(await sn(e)).at(-1);if(!t)return;let r=await nn(t.path);if(r.length===0||r[r.length-1]===10)return;let n=r.lastIndexOf(10),s=await So(t.path,"r+");try{await s.truncate(n+1),await s.sync()}finally{await s.close()}}function th(e,t,r,n){if(t===void 0)return 0;if(/^\d+$/.test(t)){let o=Number(t);if(!Number.isSafeInteger(o)||n===null&&o!==0||n!==null&&o>n)throw bo(t);return Vl(t,o,r),o}let s=e.find(o=>o.id===t);if(!s)throw r!==null&&r>1?new f("EVENT_CURSOR_EXPIRED",`Event cursor ${t} has expired.`,{details:{cursor:t,earliestAvailableSequence:r,resumeAfter:r-1}}):bo(t);return Vl(t,s.sequence,r),s.sequence}function Vl(e,t,r){if(r!==null&&t<r-1)throw new f("EVENT_CURSOR_EXPIRED",`Event cursor ${e} has expired.`,{details:{cursor:e,earliestAvailableSequence:r,resumeAfter:r-1}})}function rh(e){if(e.length===0||e.length>256)throw new f("CLI_USAGE","Event type glob must contain between 1 and 256 characters.",{});let t=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replaceAll("*",".*");return new RegExp(`^${t}$`)}function nh(e){let t=JSON.stringify(e,(r,n)=>/prompt|token|secret|password|authorization|capability/i.test(r)?"[REDACTED]":n);return t===void 0?null:JSON.parse(t)}function sh(e,t,r){if(typeof e!="object"||e===null||Array.isArray(e))throw Ge(t,`record at line ${r} is not an object`);let n=e;if(n.schemaVersion!==1||typeof n.id!="string"||n.id.length===0||n.id.length>256||!Number.isSafeInteger(n.sequence)||(n.sequence??0)<1||typeof n.type!="string"||n.type.length===0||n.type.length>256||typeof n.occurredAt!="string"||!Number.isFinite(Date.parse(n.occurredAt))||!Mt(n.workspaceId)||!Mt(n.taskId)||!Mt(n.agentTabId)||!Mt(n.commandId)||!Mt(n.swarmRunId)||!Mt(n.swarmStepId)||!oh(n.actor)||!("data"in n))throw Ge(t,`record at line ${r} has an invalid schema`);return n}function oh(e){if(typeof e!="object"||e===null||Array.isArray(e)||!("type"in e))return!1;let t=e;return t.type==="human"?(t.source==="cli"||t.source==="tui")&&Number.isInteger(t.processId):t.type==="agent"?typeof t.taskId=="string"&&typeof t.agentTabId=="string"&&typeof t.capabilityId=="string":t.type==="system"&&(t.component==="orchestration-supervisor"||t.component==="heartbeat")}var Mt=e=>e===null||typeof e=="string",Kl=e=>`segment-${String(e).padStart(16,"0")}.jsonl`,Ge=(e,t)=>new f("EVENT_JOURNAL_CORRUPT",`Event journal segment ${e} is corrupt: ${t}.`,{details:{segment:e,reason:t}}),bo=e=>new f("EVENT_CURSOR_INVALID",`Event cursor ${e} was not found.`,{details:{cursor:e}}),Yl=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";function Po(e,t){if(!Number.isSafeInteger(e)||e<1)throw new f("CLI_USAGE",`${t} must be a positive integer.`,{details:{value:e}});return e}async function Jl(e){let t=await So(e,"r");try{await t.sync()}finally{await t.close()}}import{mkdir as Zl,readdir as hh,readFile as ec}from"node:fs/promises";import tc from"node:path";import{mkdir as Xl,readFile as ih,rm as on,stat as ah,writeFile as lh}from"node:fs/promises";import Co from"node:path";var ch=20,dh=3e4,uh=5e3;async function Ao(e,t){let r=Co.join(e.runtimeDir,"command-store.lock");await Xl(e.runtimeDir,{recursive:!0});let n=Date.now();for(;;)try{await Xl(r);try{await lh(Co.join(r,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(s){throw await on(r,{recursive:!0,force:!0}),s}break}catch(s){if(!fh(s))throw s;if(await ph(r))continue;if(Date.now()-n>=dh)throw new f("OPERATION_TIMEOUT","Timed out waiting for the command store lock.",{retryable:!0});await gh(ch)}try{return await t()}finally{await on(r,{recursive:!0,force:!0})}}async function ph(e){let t=await ih(Co.join(e,"owner.json"),"utf8").then(n=>JSON.parse(n)).catch(()=>null);if(t&&typeof t.pid=="number")return mh(t.pid)?!1:(await on(e,{recursive:!0,force:!0}),!0);let r=await ah(e).catch(()=>null);return!r||Date.now()-r.mtimeMs<uh?!1:(await on(e,{recursive:!0,force:!0}),!0)}function mh(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var fh=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST",gh=e=>new Promise(t=>setTimeout(t,e));async function cn(e,t){Eo(t);try{let r=JSON.parse(await ec(mr(e,t),"utf8"));return nc(r,mr(e,t),t)}catch(r){throw Th(r)?new f("COMMAND_NOT_FOUND",`Craig command "${t}" was not found.`,{details:{commandId:t}}):r instanceof SyntaxError?ln(t,mr(e,t),r):r}}async function xe(e){await Zl(e.commandsDir,{recursive:!0});let t=await hh(e.commandsDir),r=[];for(let n of t.filter(s=>s.endsWith(".json")).sort()){let s=tc.join(e.commandsDir,n);try{r.push(nc(JSON.parse(await ec(s,"utf8")),s,n.slice(0,-5)))}catch(o){throw o instanceof f?o:ln(n.slice(0,-5),s,o)}}return r.sort((n,s)=>n.createdAt.localeCompare(s.createdAt)||n.id.localeCompare(s.id))}async function rc(e,t){return Eo(t.id),Ao(e,async()=>{await Zl(e.commandsDir,{recursive:!0});let r=await xe(e);if(t.idempotencyKey){let n=r.find(s=>s.idempotencyKey===t.idempotencyKey);if(n){if(!wh(n,t))throw new f("COMMAND_STATE_CONFLICT",`Idempotency key "${t.idempotencyKey}" is already used by command ${n.id}.`,{details:{commandId:n.id,idempotencyKey:t.idempotencyKey}});return{command:n,created:!1}}}return await M(mr(e,t.id),t),{command:t,created:!0}})}async function fr(e,t,r){return Eo(t),Ao(e,async()=>{let n=await cn(e,t),s=r(n);if(s.id!==n.id)throw new f("INTERNAL_ERROR","Command mutation cannot change its id.",{});return await M(mr(e,t),s),s})}function wh(e,t){return e.taskId===t.taskId&&e.agentTabId===t.agentTabId&&e.prompt.source===t.prompt.source&&e.prompt.text===t.prompt.text&&e.delivery===t.delivery&&e.timeoutMs===t.timeoutMs}function nc(e,t,r){if(!an(e)||e.schemaVersion!==1||typeof e.id!="string"||e.id.length===0)throw ln("unknown",t);let n=e.id,s=["queued","delivering","delivered","failed","cancelled"];if(n!==r||e.idempotencyKey!==null&&(typeof e.idempotencyKey!="string"||e.idempotencyKey.length>256)||typeof e.taskId!="string"||e.taskId.length===0||typeof e.agentTabId!="string"||e.agentTabId.length===0||!an(e.prompt)||!["inline","file","stdin"].includes(String(e.prompt.source))||typeof e.prompt.text!="string"||!yh(e.prompt.text)||!["when-ready","immediate"].includes(String(e.delivery))||!s.includes(e.state)||!Number.isInteger(e.attempts)||Number(e.attempts)<0||!Number.isInteger(e.timeoutMs)||Number(e.timeoutMs)<=0||Number(e.timeoutMs)>864e5||!_t(e.expiresAt)||!_t(e.createdAt)||!_t(e.updatedAt)||e.deliveryStartedAt!==null&&!_t(e.deliveryStartedAt)||e.deliveredAt!==null&&!_t(e.deliveredAt)||e.cancelledAt!==null&&!_t(e.cancelledAt)||e.cancelledBy!==null&&!Ql(e.cancelledBy)||!Ql(e.actor)||!kh(e.lastError)||e.state==="delivered"!=(e.deliveredAt!==null)||e.state==="failed"!=(e.lastError!==null)||Number(e.attempts)>0!=(e.deliveryStartedAt!==null)||e.state==="cancelled"!=(e.cancelledAt!==null&&e.cancelledBy!==null))throw ln(n,t);return e}function Ql(e){return!an(e)||typeof e.type!="string"?!1:e.type==="human"?["cli","tui"].includes(String(e.source))&&Number.isInteger(e.processId):e.type==="agent"?typeof e.taskId=="string"&&typeof e.agentTabId=="string"&&typeof e.capabilityId=="string":e.type==="system"&&["orchestration-supervisor","heartbeat"].includes(String(e.component))}function kh(e){return e===null||an(e)&&typeof e.code=="string"&&typeof e.message=="string"&&typeof e.retryable=="boolean"&&typeof e.deliveryUncertain=="boolean"}var mr=(e,t)=>tc.join(e.commandsDir,`${t}.json`),Eo=e=>{if(!/^command_[A-Za-z0-9_-]+$/.test(e))throw new f("CLI_USAGE",`Invalid command id "${e}".`,{details:{commandId:e}})},_t=e=>typeof e=="string"&&e.length>0&&Number.isFinite(Date.parse(e)),yh=e=>e.trim().length>0&&Buffer.byteLength(e)<=32*1024&&![...e].some(t=>{let r=t.charCodeAt(0);return r<=8||r>=11&&r<=31||r>=127&&r<=159}),an=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Th=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT",ln=(e,t,r)=>new f("COMMAND_RECORD_INVALID",`Craig command record at ${t} is invalid.`,{details:{commandId:e,filePath:t},...r?{cause:r}:{}});function sc(e,t=new Date){return dn(e,["queued"],"begin delivery"),{...e,state:"delivering",attempts:e.attempts+1,lastError:null,deliveryStartedAt:t.toISOString(),updatedAt:t.toISOString()}}function oc(e,t=new Date){return e.state==="delivered"?e:(dn(e,["delivering"],"complete delivery"),{...e,state:"delivered",deliveredAt:t.toISOString(),lastError:null,updatedAt:t.toISOString()})}function ic(e,t,r=new Date){return e.state==="failed"?e:(dn(e,["queued","delivering"],"fail"),{...e,state:"failed",lastError:t,updatedAt:r.toISOString()})}function ac(e,t,r=new Date){return e.state==="cancelled"?e:(dn(e,["queued"],"cancel"),{...e,state:"cancelled",cancelledAt:r.toISOString(),cancelledBy:t,updatedAt:r.toISOString()})}function dn(e,t,r){if(!t.includes(e.state))throw new f("COMMAND_STATE_CONFLICT",`Cannot ${r} command ${e.id} while it is ${e.state}.`,{details:{commandId:e.id,state:e.state,allowedStates:t}})}import{randomUUID as Rh}from"node:crypto";var xo=32*1024,lc=1440*60*1e3,Do=256,bh=["delivered","failed","cancelled"],Oo={type:"system",component:"orchestration-supervisor"};async function Ph(e,t){if(Dh(t.prompt.text),!Number.isSafeInteger(t.timeoutMs)||t.timeoutMs<=0||t.timeoutMs>lc)throw new f("CLI_USAGE","Prompt command timeout must be between 1ms and 24h.",{details:{maxTimeoutMs:lc}});if(t.idempotencyKey!==void 0&&t.idempotencyKey!==null&&t.idempotencyKey.trim().length===0)throw new f("CLI_USAGE","Idempotency key cannot be empty.",{});if((t.idempotencyKey?.length??0)>Do)throw new f("CLI_USAGE",`Idempotency key exceeds ${Do} characters.`,{details:{maxIdempotencyKeyLength:Do}});let r=t.now??new Date,n={schemaVersion:1,id:t.id??`command_${Rh()}`,idempotencyKey:t.idempotencyKey?.trim()||null,taskId:t.taskId,agentTabId:t.agentTabId,prompt:t.prompt,delivery:t.delivery,state:"queued",attempts:0,timeoutMs:t.timeoutMs,expiresAt:new Date(r.getTime()+t.timeoutMs).toISOString(),lastError:null,actor:t.actor,createdAt:r.toISOString(),updatedAt:r.toISOString(),deliveryStartedAt:null,deliveredAt:null,cancelledAt:null,cancelledBy:null},s=await rc(e,n);if(s.created)try{await dt(e,s.command,"command.queued")}catch(o){throw cc(s.command,o)}return{kind:"sendAgentPrompt",...s}}async function Sh(e,t){return{kind:"showPromptCommand",command:await cn(e,t)}}async function vh(e,t){let r=await xe(e);return{kind:"listPromptCommands",commands:t?r.filter(n=>n.taskId===t):r}}async function Ih(e,t,r){let n=!1,s=await fr(e,t,o=>{if(o.state==="cancelled")return o;let i=ac(o,r??o.actor);return n=!0,i});if(n)try{await dt(e,s,"command.cancelled",s.cancelledBy??s.actor)}catch(o){throw cc(s,o)}return{kind:"cancelPromptCommand",command:s,changed:n}}async function Ch(e,t){let r=await fr(e,t,n=>sc(n));return await dt(e,r,"command.delivering",Oo),r}async function Ah(e,t){let r=await fr(e,t,n=>oc(n));return await dt(e,r,"command.delivered",Oo),r}async function Eh(e,t,r){let n=await fr(e,t,s=>ic(s,r));return await dt(e,n,"command.failed",Oo),n}async function xh(e,t,r){let n=[...r.states??bh],s=Date.now()+r.timeoutMs;for(;;){let o=await cn(e,t);if(n.includes(o.state))return{kind:"waitPromptCommand",command:o,matchedStates:n};if(r.signal?.aborted)throw new f("OPERATION_CANCELLED",`Cancelled while waiting for command ${t}.`,{retryable:!0,details:{commandId:t,cancelled:!0}});let i=s-Date.now();if(i<=0)throw new f("OPERATION_TIMEOUT",`Timed out after ${r.timeoutMs}ms waiting for command ${t}.`,{retryable:!0,details:{commandId:t,states:n,timeoutMs:r.timeoutMs}});await Oh(Math.min(r.pollIntervalMs??100,i),r.signal)}}function Dh(e){if(e.trim().length===0)throw new f("CLI_USAGE","Prompt cannot be empty.",{});let t=Buffer.byteLength(e);if(t>xo)throw new f("CLI_USAGE",`Prompt exceeds the ${xo}-byte limit.`,{details:{maxPromptBytes:xo,promptBytes:t}});if([...e].some(r=>{let n=r.charCodeAt(0);return n<=8||n>=11&&n<=31||n>=127&&n<=159}))throw new f("CLI_USAGE","Prompt contains unsupported control characters.",{})}async function dt(e,t,r,n=t.actor){await Lt(e,{id:`${t.id}:${r}`,taskId:t.taskId,agentTabId:t.agentTabId,commandId:t.id,type:r,occurredAt:r==="command.queued"?t.createdAt:r==="command.delivering"?t.deliveryStartedAt??t.updatedAt:r==="command.delivered"?t.deliveredAt??t.updatedAt:r==="command.cancelled"?t.cancelledAt??t.updatedAt:t.updatedAt,actor:n,data:{state:t.state,delivery:t.delivery,attempts:t.attempts,errorCode:t.lastError?.code??null,deliveryUncertain:t.lastError?.deliveryUncertain??!1}})}function Oh(e,t){return t?.aborted?Promise.resolve():new Promise(r=>{let n=()=>{clearTimeout(s),t?.removeEventListener("abort",n),r()},s=setTimeout(n,e);t?.addEventListener("abort",n,{once:!0})})}var cc=(e,t)=>new f("PARTIAL_RESULT",`Command ${e.id} was persisted as ${e.state}, but its event could not be appended.`,{retryable:!0,details:{commandId:e.id,durableState:e.state},cause:t}),se={create:Ph,show:Sh,list:vh,cancel:Ih,wait:xh,beginDelivery:Ch,completeDelivery:Ah,fail:Eh};import{createHash as dc}from"node:crypto";import $h from"node:path";import{mkdir as Nh}from"node:fs/promises";var $o={type:"system",component:"heartbeat"};async function jt(e,t={}){await Nh(e.orchestrationDir,{recursive:!0});let[r,n,s,o]=await Promise.all([S.listTasks(e,{includeClosed:!0}),t.agentObserver?Promise.resolve(null):Ee.listAgents(e),zl(e),Fh(e)]),i=n??Re(r.tasks.filter(p=>p.status!=="closed"),t.agentObserver?.getSnapshots()??[],Date.now()),a=jh(o),l=[],c=No(s.filter(_h),p=>p.taskId),d=No(s.filter(p=>p.type.startsWith("task.pr.")),p=>p.taskId),u=No(s.filter(p=>p.type==="agent.state.changed"),p=>p.agentTabId);for(let p of r.tasks){let k=Mh(p),w=c.get(p.id),b=Lo(w?.data)??a.tasks[p.id]??null,N=w?.id??a.tasks[p.id]?.eventId??null;if(b?.signature!==k.signature){let me=b?p.status==="closed"&&b?.status!=="closed"?"task.closed":"task.updated":"task.created",de=await Lt(e,{id:Mo(me,p.id,k.signature),type:me,taskId:p.id,workspaceId:p.workspaceId||null,occurredAt:p.updatedAt,actor:$o,data:k});l.push(de),N=de.id}a.tasks[p.id]={...k,eventId:N};let _=Lh(p.prs),Y=d.get(p.id),I=Lo(Y?.data)??a.pullRequests[p.id]??null,ce=Y?.id??a.pullRequests[p.id]?.eventId??null;if((I||_.associations.length>0)&&I?.signature!==_.signature){let me=Array.isArray(I?.associations)?I.associations.length:0,de=_.associations.length>me?"task.pr.linked":_.associations.length<me?"task.pr.unlinked":"task.pr.refreshed",wt=await Lt(e,{id:Mo(de,p.id,_.signature),type:de,taskId:p.id,workspaceId:p.workspaceId||null,occurredAt:p.updatedAt,actor:$o,data:_});l.push(wt),ce=wt.id}a.pullRequests[p.id]={..._,eventId:ce}}let m=new Map(i.tasks.map(p=>[p.taskId,p.state]));for(let p of i.agents){let k=u.get(p.tabId),w=Lo(k?.data)??a.agents[p.tabId]??null;if(w?.state===p.state){a.agents[p.tabId]={state:p.state,eventId:k?.id??a.agents[p.tabId]?.eventId??null};continue}let b=[k?.id??a.agents[p.tabId]?.eventId??"initial",p.state,p.sessionState??"none",p.lastActivityAt??"none",p.exitCode??"none",p.error??"none"].join(":"),N=await Lt(e,{id:Mo("agent.state.changed",p.tabId,b),type:"agent.state.changed",taskId:p.taskId,agentTabId:p.tabId,actor:$o,data:{previousState:typeof w?.state=="string"?w.state:null,state:p.state,taskState:m.get(p.taskId)??"idle",sessionState:p.sessionState,lastActivityAt:p.lastActivityAt,exitCode:p.exitCode,error:p.error}});l.push(N),a.agents[p.tabId]={state:p.state,eventId:N.id}}return await M(pc(e),a),l}function Mh(e){let t={status:e.status,title:e.title,runner:e.runner,branch:e.branch,sourceUpdatedAt:e.updatedAt,agentTabIds:e.ptyTabs.filter(r=>r.kind==="agent").map(r=>r.id)};return{...t,signature:uc(t)}}function Lh(e){let t=e.map(r=>({provider:r.provider,owner:r.owner,repo:r.repo,number:r.number,url:r.url,status:r.status,draft:r.draft,headBranch:r.headBranch,lastSyncedAt:r.lastSyncedAt,lastSyncedHeadSha:r.lastSyncedHeadSha}));return{associations:t,signature:uc(t)}}function No(e,t){let r=new Map;for(let n of e){let s=t(n);s&&r.set(s,n)}return r}var _h=e=>e.type==="task.created"||e.type==="task.updated"||e.type==="task.closed",uc=e=>dc("sha256").update(JSON.stringify(e)).digest("hex"),Mo=(...e)=>dc("sha256").update(e.join("\0")).digest("hex"),Lo=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:null,pc=e=>$h.join(e.orchestrationDir,"event-reconciliation.json");function jh(e){return e?.schemaVersion===1&&typeof e.tasks=="object"&&e.tasks!==null&&typeof e.pullRequests=="object"&&e.pullRequests!==null&&typeof e.agents=="object"&&e.agents!==null?e:{schemaVersion:1,tasks:{},pullRequests:{},agents:{}}}async function Fh(e){try{return await Er(pc(e))}catch(t){if(t instanceof SyntaxError)return null;throw t}}async function Wh(e,t){return await _o(e),await jt(e),pr(e,t)}async function qh(e,t,r){await _o(e);let n=await Ee.openObserver(e);try{let s=t.after,o=0,i=0;for(;!r.signal?.aborted;){await jt(e,{agentObserver:n});let a=await pr(e,{...t,...s?{after:s}:{}});for(let l of a.events)r.onEvent(l),o+=1;if(s=a.cursor.after??s,i=a.cursor.sequence,r.signal?.aborted)break;await mc(r.pollIntervalMs??250,r.signal)}return{kind:"watchEvents",eventCount:o,lastSequence:i,cancelled:r.signal?.aborted??!1}}finally{n.close()}}async function Uh(e,t,r){await _o(e);let n=await S.getTask(e,t);if(r.tabId&&!n.ptyTabs.some(o=>o.kind==="agent"&&o.id===r.tabId))throw new f("TASK_CONTEXT_CONFLICT",`Agent tab ${r.tabId} does not belong to task ${t}.`,{details:{taskId:t,tabId:r.tabId}});let s=await Ee.openObserver(e);try{await jt(e,{agentObserver:s});let i=(await pr(e,{taskId:t,typeGlob:"agent.state.changed"})).cursor.after??void 0,a=Date.now()+r.timeoutMs;for(;;){let l=Date.now(),c=Re([n],s.getSnapshots(),l),d=r.tabId?c.agents.find(p=>p.tabId===r.tabId)?.state??"idle":c.tasks[0]?.state??"idle";if(r.states.includes(d))return{kind:"waitTask",taskId:t,tabId:r.tabId??null,state:d,matchedStates:[...r.states],observedAt:new Date(l).toISOString()};if(r.signal?.aborted)throw Vh(t);let u=a-Date.now();if(u<=0)throw Bh(t,r.states,r.timeoutMs);await jt(e,{agentObserver:s}),i=(await pr(e,{taskId:t,typeGlob:"agent.state.changed",...i?{after:i}:{}})).cursor.after??i,await mc(Math.min(250,u),r.signal)}}finally{s.close()}}async function _o(e){let t=await h.load(e);if(!h.previews.isEnabled(t,"agentOrchestration"))throw new f("CLI_USAGE","Event orchestration is a feature preview. Enable agentOrchestration before using events commands.",{details:{preview:"agentOrchestration"}})}function mc(e,t){return t?.aborted?Promise.resolve():new Promise(r=>{let n=()=>{clearTimeout(s),t?.removeEventListener("abort",n),r()},s=setTimeout(n,e);t?.addEventListener("abort",n,{once:!0})})}var Bh=(e,t,r)=>new f("OPERATION_TIMEOUT",`Timed out after ${r}ms waiting for task ${e} agent state ${t.join(",")}.`,{retryable:!0,details:{taskId:e,states:t,timeoutMs:r}}),Vh=e=>new f("OPERATION_CANCELLED",`Cancelled while waiting for task ${e} agent state.`,{retryable:!0,details:{taskId:e,cancelled:!0}}),un={list:Wh,watch:qh,waitForTaskState:Uh,reconcile:jt};import{readFile as zh}from"node:fs/promises";import{createConnection as Kh}from"node:net";async function gr(e){let t=await Hh(Ke(e).socketPath).catch(()=>null);if(!t)return!1;try{return(await fc(t,{type:"ping"})).protocolVersion!==Nt?!1:(await fc(t,{type:"wakeOrchestration"}),!0)}catch{return!1}finally{t.end()}}var Gh=1;function fc(e,t){let r=Gh++;return new Promise((n,s)=>{let o="",i=setTimeout(()=>s(new Error("Craig PTY daemon request timed out.")),1e3),a=c=>{o+=String(c);let d=o.indexOf(`
82
- `);if(d===-1)return;l();let u=JSON.parse(o.slice(0,d));u.ok?n(u):s(new Error(u.error??"Craig PTY daemon request failed."))},l=()=>{clearTimeout(i),e.off("data",a)};e.on("data",a),e.write(`${JSON.stringify({...t,id:r})}
83
- `)})}function Hh(e){return new Promise((t,r)=>{let n=Kh(e);n.once("connect",()=>t(n)),n.once("error",r)})}async function Yh(e,t){await tw(e);let r=await S.getTask(e,t.taskId);if(r.status==="closed")throw new f("COMMAND_STATE_CONFLICT",`Task ${r.id} is ${r.status} and cannot receive prompts.`,{details:{taskId:r.id,taskStatus:r.status}});let n=r.ptyTabs.filter(a=>a.kind==="agent"),s=t.tabId?n.find(a=>a.id===t.tabId):n[0];if(!s)throw new f("TASK_CONTEXT_CONFLICT",t.tabId?`Agent tab ${t.tabId} does not belong to task ${r.id}.`:`Task ${r.id} has no agent tab.`,{details:{taskId:r.id,tabId:t.tabId??null}});let o=await ew(t.prompt,t.readStdin),i;try{i=await se.create(e,{taskId:r.id,agentTabId:s.id,prompt:o,delivery:t.delivery,timeoutMs:t.timeoutMs,idempotencyKey:t.idempotencyKey??null,actor:{type:"human",source:"cli",processId:process.pid}})}catch(a){throw await gr(e),a}return await gr(e),i}async function Jh(e,t){return se.show(e,t)}async function Xh(e,t){return se.list(e,t)}async function Qh(e,t){let r;try{r=await se.cancel(e,t,{type:"human",source:"cli",processId:process.pid})}catch(n){throw await gr(e),n}return await gr(e),r}async function Zh(e,t,r){return se.wait(e,t,r)}async function ew(e,t){if(e.source==="inline")return e;if(e.source==="file")try{return{source:"file",text:await zh(e.path,"utf8")}}catch(r){throw new f("CLI_USAGE",`Unable to read prompt file ${e.path}.`,{details:{promptFile:e.path},cause:r})}if(!t)throw new f("INPUT_REQUIRED","Prompt input from stdin is unavailable.",{});return{source:"stdin",text:await t()}}async function tw(e){let t=await h.load(e);if(!h.previews.isEnabled(t,"agentOrchestration"))throw new f("CLI_USAGE","Prompt dispatch is a feature preview. Enable agentOrchestration before sending prompts.",{details:{preview:"agentOrchestration"}})}var Ft={send:Yh,show:Jh,list:Xh,cancel:Qh,wait:Zh};async function gc(e,t){switch(e.kind){case"addWorkspace":{let r=await J.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await jo(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await J.repos.addRepo(t.paths,e.path);return await jo(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return J.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await yt({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await ie(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await J.repos.removeRepo(t.paths,e.repoId,{listTasks:S.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await Me({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await Me({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return J.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await J.archiveWorkspace(t.paths,e.workspaceId);return await rw(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await J.restoreWorkspace(t.paths,e.workspaceId);return await jo(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return J.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"currentTask":{let r=Fo(t);return{kind:"currentTask",task:r.task,context:{source:r.source,agentTabId:r.agentTabId}}}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"showCurrentTask":return S.showTask(t.paths,Fo(t).task.id);case"showTaskPr":return S.prs.show(t.paths,pt(e.taskId,t),e.repoId);case"discoverTaskPr":return S.prs.discover(t.paths,pt(e.taskId,t),e.repoId);case"linkTaskPr":return S.prs.link(t.paths,pt(e.taskId,t),e.pullRequest,e.repoId);case"refreshTaskPr":return S.prs.refreshAssociation(t.paths,pt(e.taskId,t),e.repoId);case"unlinkTaskPr":return S.prs.unlink(t.paths,pt(e.taskId,t),e.pullRequest,e.repoId);case"listAgents":return Ee.listAgents(t.paths,e.taskId);case"showAgentStatus":return Ee.showAgentStatus(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.tabId?{tabId:e.tabId}:{}});case"waitTask":{let r={states:e.states,timeoutMs:e.timeoutMs,...e.tabId?{tabId:e.tabId}:{},...t.signal?{signal:t.signal}:{}},n=pt(e.taskId,t),s=await h.load(t.paths);return h.previews.isEnabled(s,"agentOrchestration")?un.waitForTaskState(t.paths,n,r):Ee.waitForTask(t.paths,n,r)}case"listEvents":return un.list(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}});case"watchEvents":return un.watch(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}},{onEvent:t.emitEvent??(()=>{}),...t.signal?{signal:t.signal}:{}});case"sendAgentPrompt":return Ft.send(t.paths,{taskId:pt(e.taskId,t),...e.tabId?{tabId:e.tabId}:t.taskContext?.agentTabId?{tabId:t.taskContext.agentTabId}:{},prompt:e.prompt,delivery:e.delivery,timeoutMs:e.timeoutMs,...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{},...t.readStdin?{readStdin:t.readStdin}:{}});case"showPromptCommand":return Ft.show(t.paths,e.commandId);case"listPromptCommands":return Ft.list(t.paths,e.taskId);case"cancelPromptCommand":return Ft.cancel(t.paths,e.commandId);case"waitPromptCommand":return Ft.wait(t.paths,e.commandId,{...e.states?{states:e.states}:{},timeoutMs:e.timeoutMs,...t.signal?{signal:t.signal}:{}});case"showSelectedTask":return S.showTask(t.paths,ut(t,"show"));case"streamTaskLogs":return S.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return S.prepareTaskLogs(t.paths,ut(t,"logs"));case"showTaskDiff":return S.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return S.showTaskDiff(t.paths,ut(t,"diff"));case"focusTask":return S.focusTask(t.paths,e.taskId);case"focusSelectedTask":return S.focusTask(t.paths,ut(t,"focus"));case"openTask":return S.openTask(t.paths,e.taskId);case"openSelectedTask":return S.openTask(t.paths,ut(t,"open"));case"runChecks":return S.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return S.runChecks(t.paths,ut(t,"check"));case"commitTask":return S.commitTask(t.paths,e.taskId);case"commitSelectedTask":return S.commitTask(t.paths,ut(t,"commit"));case"showContext":{let r=sw(t);return{kind:"showContext",workspace:{root:r.workspaceRoot,source:r.source,initialized:r.initialized},task:t.taskContext?{id:t.taskContext.task.id,source:t.taskContext.source,agentTabId:t.taskContext.agentTabId}:null}}case"help":return{kind:"help",text:rs()};case"exit":return{kind:"exit"};default:return nw(e)}}async function jo(e,t,r){let n=await yt({uiStateFile:e.uiStateFile})??Dr();await Me({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function rw(e,t){let r=await yt({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Me({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function nw(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function ut(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 Fo(e){if(e.taskContext)return e.taskContext;throw new Error("Command requires resolved task context.")}function pt(e,t){return e??Fo(t).task.id}function sw(e){if(e.workspaceContext)return e.workspaceContext;throw new Error("Command requires resolved workspace context.")}function hc(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(`
77
+ `)}}handleMessage(t){if(t.trim().length===0)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r){let n=this.pending.get(r.id);if(!n)return;this.pending.delete(r.id),n.resolve(r);return}r.type==="activity"?(this.recordSnapshot(r.snapshot),this.options.onActivity?.(r.snapshot)):r.type==="activityRemoved"&&(this.removeSnapshot(r.tabId),this.options.onActivityRemoved?.(r.tabId))}replaceSnapshots(t,r){let n=new Map;for(let[s,i]of this.revisionByTabId)i>r&&n.set(s,this.snapshots.get(s)??null);this.snapshots.clear();for(let s of t)this.snapshots.set(s.tabId,s);for(let[s,i]of n)i?this.snapshots.set(s,i):this.snapshots.delete(s)}recordSnapshot(t){this.revision+=1,this.revisionByTabId.set(t.tabId,this.revision),this.snapshots.set(t.tabId,t)}removeSnapshot(t){this.revision+=1,this.revisionByTabId.set(t,this.revision),this.snapshots.delete(t)}handleClose(){if(this.closed)return;this.closed=!0;let t=new Error("Craig PTY daemon connection closed.");this.rejectAll(t);for(let r of this.snapshots.values()){if(r.sessionState!=="running")continue;let n={...r,sessionState:"failed",lastActivityAt:Date.now(),error:t.message};this.recordSnapshot(n),this.options.onActivity?.(n)}this.options.onDaemonClose?.()}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}};function Lg(e){return new Promise((t,r)=>{let n=Ng(e);n.once("connect",()=>t(n)),n.once("error",r)})}var bi={openObserver:Hl,listTasks:e=>P.listTasks(e),getTask:(e,t)=>P.getTask(e,t),now:Date.now};async function _g(e,t,r=bi){let n=await Gl(e,t,r),s=await r.openObserver(e);try{return{kind:"listAgents",...Re(n,s.getSnapshots(),r.now()),daemonAvailable:s.daemonAvailable}}finally{s.close()}}async function jg(e,t,r=bi){let n=await Gl(e,t.taskId,r),s=await r.openObserver(e);try{let i=Re(n,s.getSnapshots(),r.now()),o=t.tabId?i.agents.filter(l=>l.tabId===t.tabId):i.agents;if(t.tabId&&o.length===0)throw new g("TASK_CONTEXT_NOT_FOUND",`Agent tab ${t.tabId} was not found${t.taskId?` in task ${t.taskId}`:""}.`,{details:{taskId:t.taskId??null,tabId:t.tabId}});let a=new Set(o.map(l=>l.taskId));return{kind:"showAgentStatus",agents:o,tasks:t.tabId?i.tasks.filter(l=>a.has(l.taskId)):i.tasks,daemonAvailable:s.daemonAvailable}}finally{s.close()}}async function Fg(e,t,r,n=bi){let s=await n.getTask(e,t),i=await n.openObserver(e);try{return await ki(s,i,{...r,now:n.now})}finally{i.close()}}async function Gl(e,t,r){return t?[await r.getTask(e,t)]:(await r.listTasks(e)).tasks}async function Hl(e){return Ri.open(e)}async function Wg(e){return Hl(e)}var Ri=class e{listeners=new Set;snapshots=new Map;client=null;reconnectTimer=null;reconnectDelayMs=250;closed=!1;paths;constructor(t){this.paths=t}static async open(t){let r=new e(t);return await r.connect(),r}get daemonAvailable(){return this.client!==null}getSnapshots(){return[...this.snapshots.values()]}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}close(){this.closed=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.client?.close(),this.client=null}async connect(){if(this.closed)return;let t=await Kl({paths:this.paths,onActivity:r=>{this.snapshots.set(r.tabId,r),this.notify()},onActivityRemoved:r=>{this.snapshots.delete(r),this.notify()},onDaemonClose:()=>{this.client=null,this.notify(),this.scheduleReconnect()}});if(this.closed){t?.close();return}if(this.client=t,t){this.reconnectDelayMs=250,this.snapshots.clear();for(let r of t.getSnapshots())this.snapshots.set(r.tabId,r);this.notify()}else this.scheduleReconnect()}scheduleReconnect(){if(this.closed||this.reconnectTimer)return;let t=this.reconnectDelayMs;this.reconnectDelayMs=Math.min(this.reconnectDelayMs*2,1e3),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},t)}notify(){for(let t of this.listeners)t()}},Oe={listAgents:_g,showAgentStatus:jg,waitForTask:Fg,openObserver:Wg};import{randomUUID as Xg}from"node:crypto";import{mkdir as Ql,open as Ii,readdir as Zl,readFile as an,rm as Qg,stat as Zg}from"node:fs/promises";import Ci from"node:path";import{mkdir as zl,readFile as qg,rm as on,stat as Ug,writeFile as Vg}from"node:fs/promises";import Pi from"node:path";var Bg=20,Kg=3e4,Gg=5e3;async function Yl(e,t){let r=Pi.join(e.runtimeDir,"event-journal.lock");await zl(e.runtimeDir,{recursive:!0});let n=Date.now();for(;;)try{await zl(r);try{await Vg(Pi.join(r,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(s){throw await on(r,{recursive:!0,force:!0}),s}break}catch(s){if(!Yg(s))throw s;if(await Hg(r))continue;if(Date.now()-n>=Kg)throw new g("OPERATION_TIMEOUT","Timed out waiting for the event journal lock.",{retryable:!0});await Jg(Bg)}try{return await t()}finally{await on(r,{recursive:!0,force:!0})}}async function Hg(e){let t=await qg(Pi.join(e,"owner.json"),"utf8").then(n=>JSON.parse(n)).catch(()=>null);if(t&&typeof t.pid=="number")return zg(t.pid)?!1:(await on(e,{recursive:!0,force:!0}),!0);let r=await Ug(e).catch(()=>null);return!r||Date.now()-r.mtimeMs<Gg?!1:(await on(e,{recursive:!0,force:!0}),!0)}function zg(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var Yg=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST",Jg=e=>new Promise(t=>setTimeout(t,e));var eh=256*1024,th=16,rh=64*1024;async function jt(e,t,r={}){let n=vi(r.maxSegmentBytes??eh,"Event journal segment size"),s=vi(r.maxSegments??th,"Event journal retention"),i=vi(r.maxRecordBytes??rh,"Event record size");return Yl(e,async()=>{await Ql(e.eventsDir,{recursive:!0}),await ah(e);let o=await Ai(e),a=t.id??Xg(),l=o.events.find(b=>b.id===a);if(l)return l;let c=(o.events.at(-1)?.sequence??0)+1,d={schemaVersion:1,id:a,sequence:c,workspaceId:t.workspaceId??null,taskId:t.taskId??null,agentTabId:t.agentTabId??null,commandId:t.commandId??null,swarmRunId:t.swarmRunId??null,swarmStepId:t.swarmStepId??null,type:t.type,occurredAt:t.occurredAt??new Date().toISOString(),actor:t.actor,data:dh(t.data)},u=`${JSON.stringify(d)}
78
+ `;if(Buffer.byteLength(u)>i)throw new g("CLI_USAGE",`Event record exceeds the ${i}-byte limit.`,{details:{eventType:t.type,maxRecordBytes:i}});let h=(await ln(e)).at(-1),m=!h||await nh(h.path,u,n);if(m&&(h={name:Xl(c),path:Ci.join(e.eventsDir,Xl(c)),startSequence:c}),!h)throw new g("INTERNAL_ERROR","Failed to select an event journal segment.",{});let k=await Ii(h.path,"a");try{await k.writeFile(u,"utf8"),await k.sync()}finally{await k.close()}return m&&await rc(e.eventsDir),await sh(e,s),d})}async function fr(e,t={}){let r=await Ai(e),n=lh(r.events,t.after,r.earliestSequence,r.events.at(-1)?.sequence??null),s=t.typeGlob?ch(t.typeGlob):null,i=r.events.filter(l=>l.sequence>n&&(!t.taskId||l.taskId===t.taskId)&&(!s||s.test(l.type))),o=r.events.at(-1)?.sequence??null,a=r.events.filter(l=>l.sequence>n).at(-1);return{kind:"listEvents",events:i,cursor:{after:a?.id??t.after??null,sequence:a?.sequence??n,earliestAvailableSequence:r.earliestSequence,latestSequence:o}}}async function ec(e){return(await Ai(e)).events}async function Ai(e){await Ql(e.eventsDir,{recursive:!0});let t=await ln(e),r=[],n=new Set;for(let s=0;s<t.length;s+=1){let i=t[s],o=await an(i.path,"utf8"),a=s===t.length-1,l=o.split(`
79
+ `);if(o.endsWith(`
80
+ `))l.pop();else{if(!a)throw ze(i.name,"segment has a truncated tail");l.pop()}for(let c=0;c<l.length;c+=1){let d=l[c];if(d.length===0)throw ze(i.name,`empty record at line ${c+1}`);let u;try{u=JSON.parse(d)}catch{throw ze(i.name,`invalid JSON at line ${c+1}`)}let f=uh(u,i.name,c+1);if(c===0&&f.sequence!==i.startSequence)throw ze(i.name,`first record sequence ${f.sequence} does not match segment name`);if(n.has(f.id))throw ze(i.name,`duplicate event id ${f.id}`);n.add(f.id);let h=r.at(-1);if(h&&f.sequence!==h.sequence+1)throw ze(i.name,`non-monotonic sequence ${f.sequence} after ${h.sequence}`);r.push(f)}}return{events:r,earliestSequence:r[0]?.sequence??null}}async function ln(e){return(await Zl(e.eventsDir).catch(r=>{if(tc(r))return[];throw r})).flatMap(r=>{let n=/^segment-(\d{16})\.jsonl$/.exec(r);return n?[{name:r,path:Ci.join(e.eventsDir,r),startSequence:Number(n[1])}]:[]}).sort((r,n)=>r.startSequence-n.startSequence)}async function nh(e,t,r){let n=await Zg(e).catch(()=>null);return n!==null&&n.size>0&&n.size+Buffer.byteLength(t)>r}async function sh(e,t){let r=await ln(e),n=Math.max(0,r.length-t),s=await ih(e);if(s===null)return;for(let o=0;o<n;o+=1)if(await oh(r[o].path,s)){n=o;break}let i=r.slice(0,n);for(let o of i)await Qg(o.path,{force:!0});i.length>0&&await rc(e.eventsDir)}async function ih(e){let t=await Zl(e.commandsDir).catch(n=>{if(tc(n))return[];throw n}),r=new Set;for(let n of t.filter(s=>s.endsWith(".json")))try{let s=JSON.parse(await an(Ci.join(e.commandsDir,n),"utf8"));typeof s.id=="string"&&(s.state==="queued"||s.state==="delivering")&&r.add(s.id)}catch{return null}return r}async function oh(e,t){if(t.size===0)return!1;let r=await an(e,"utf8");for(let n of r.split(`
81
+ `))if(n)try{let s=JSON.parse(n);if(typeof s.commandId=="string"&&t.has(s.commandId))return!0}catch{return!0}return!1}async function ah(e){let t=(await ln(e)).at(-1);if(!t)return;let r=await an(t.path);if(r.length===0||r[r.length-1]===10)return;let n=r.lastIndexOf(10),s=await Ii(t.path,"r+");try{await s.truncate(n+1),await s.sync()}finally{await s.close()}}function lh(e,t,r,n){if(t===void 0)return 0;if(/^\d+$/.test(t)){let i=Number(t);if(!Number.isSafeInteger(i)||n===null&&i!==0||n!==null&&i>n)throw Si(t);return Jl(t,i,r),i}let s=e.find(i=>i.id===t);if(!s)throw r!==null&&r>1?new g("EVENT_CURSOR_EXPIRED",`Event cursor ${t} has expired.`,{details:{cursor:t,earliestAvailableSequence:r,resumeAfter:r-1}}):Si(t);return Jl(t,s.sequence,r),s.sequence}function Jl(e,t,r){if(r!==null&&t<r-1)throw new g("EVENT_CURSOR_EXPIRED",`Event cursor ${e} has expired.`,{details:{cursor:e,earliestAvailableSequence:r,resumeAfter:r-1}})}function ch(e){if(e.length===0||e.length>256)throw new g("CLI_USAGE","Event type glob must contain between 1 and 256 characters.",{});let t=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replaceAll("*",".*");return new RegExp(`^${t}$`)}function dh(e){let t=JSON.stringify(e,(r,n)=>/prompt|token|secret|password|authorization|capability/i.test(r)?"[REDACTED]":n);return t===void 0?null:JSON.parse(t)}function uh(e,t,r){if(typeof e!="object"||e===null||Array.isArray(e))throw ze(t,`record at line ${r} is not an object`);let n=e;if(n.schemaVersion!==1||typeof n.id!="string"||n.id.length===0||n.id.length>256||!Number.isSafeInteger(n.sequence)||(n.sequence??0)<1||typeof n.type!="string"||n.type.length===0||n.type.length>256||typeof n.occurredAt!="string"||!Number.isFinite(Date.parse(n.occurredAt))||!_t(n.workspaceId)||!_t(n.taskId)||!_t(n.agentTabId)||!_t(n.commandId)||!_t(n.swarmRunId)||!_t(n.swarmStepId)||!ph(n.actor)||!("data"in n))throw ze(t,`record at line ${r} has an invalid schema`);return n}function ph(e){if(typeof e!="object"||e===null||Array.isArray(e)||!("type"in e))return!1;let t=e;return t.type==="human"?(t.source==="cli"||t.source==="tui")&&Number.isInteger(t.processId):t.type==="agent"?typeof t.taskId=="string"&&typeof t.agentTabId=="string"&&typeof t.capabilityId=="string":t.type==="system"&&(t.component==="orchestration-supervisor"||t.component==="heartbeat")}var _t=e=>e===null||typeof e=="string",Xl=e=>`segment-${String(e).padStart(16,"0")}.jsonl`,ze=(e,t)=>new g("EVENT_JOURNAL_CORRUPT",`Event journal segment ${e} is corrupt: ${t}.`,{details:{segment:e,reason:t}}),Si=e=>new g("EVENT_CURSOR_INVALID",`Event cursor ${e} was not found.`,{details:{cursor:e}}),tc=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";function vi(e,t){if(!Number.isSafeInteger(e)||e<1)throw new g("CLI_USAGE",`${t} must be a positive integer.`,{details:{value:e}});return e}async function rc(e){let t=await Ii(e,"r");try{await t.sync()}finally{await t.close()}}import{mkdir as ic,readdir as Ph,readFile as oc}from"node:fs/promises";import ac from"node:path";import{mkdir as nc,readFile as mh,rm as cn,stat as fh,writeFile as gh}from"node:fs/promises";import Ei from"node:path";var hh=20,wh=3e4,kh=5e3;async function xi(e,t){let r=Ei.join(e.runtimeDir,"command-store.lock");await nc(e.runtimeDir,{recursive:!0});let n=Date.now();for(;;)try{await nc(r);try{await gh(Ei.join(r,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(s){throw await cn(r,{recursive:!0,force:!0}),s}break}catch(s){if(!Rh(s))throw s;if(await yh(r))continue;if(Date.now()-n>=wh)throw new g("OPERATION_TIMEOUT","Timed out waiting for the command store lock.",{retryable:!0});await bh(hh)}try{return await t()}finally{await cn(r,{recursive:!0,force:!0})}}async function yh(e){let t=await mh(Ei.join(e,"owner.json"),"utf8").then(n=>JSON.parse(n)).catch(()=>null);if(t&&typeof t.pid=="number")return Th(t.pid)?!1:(await cn(e,{recursive:!0,force:!0}),!0);let r=await fh(e).catch(()=>null);return!r||Date.now()-r.mtimeMs<kh?!1:(await cn(e,{recursive:!0,force:!0}),!0)}function Th(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var Rh=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST",bh=e=>new Promise(t=>setTimeout(t,e));async function pn(e,t){Di(t);try{let r=JSON.parse(await oc(gr(e,t),"utf8"));return cc(r,gr(e,t),t)}catch(r){throw Ch(r)?new g("COMMAND_NOT_FOUND",`Craig command "${t}" was not found.`,{details:{commandId:t}}):r instanceof SyntaxError?un(t,gr(e,t),r):r}}async function $e(e){await ic(e.commandsDir,{recursive:!0});let t=await Ph(e.commandsDir),r=[];for(let n of t.filter(s=>s.endsWith(".json")).sort()){let s=ac.join(e.commandsDir,n);try{r.push(cc(JSON.parse(await oc(s,"utf8")),s,n.slice(0,-5)))}catch(i){throw i instanceof g?i:un(n.slice(0,-5),s,i)}}return r.sort((n,s)=>n.createdAt.localeCompare(s.createdAt)||n.id.localeCompare(s.id))}async function lc(e,t){return Di(t.id),xi(e,async()=>{await ic(e.commandsDir,{recursive:!0});let r=await $e(e);if(t.idempotencyKey){let n=r.find(s=>s.idempotencyKey===t.idempotencyKey);if(n){if(!Sh(n,t))throw new g("COMMAND_STATE_CONFLICT",`Idempotency key "${t.idempotencyKey}" is already used by command ${n.id}.`,{details:{commandId:n.id,idempotencyKey:t.idempotencyKey}});return{command:n,created:!1}}}return await L(gr(e,t.id),t),{command:t,created:!0}})}async function hr(e,t,r){return Di(t),xi(e,async()=>{let n=await pn(e,t),s=r(n);if(s.id!==n.id)throw new g("INTERNAL_ERROR","Command mutation cannot change its id.",{});return await L(gr(e,t),s),s})}function Sh(e,t){return e.taskId===t.taskId&&e.agentTabId===t.agentTabId&&e.prompt.source===t.prompt.source&&e.prompt.text===t.prompt.text&&e.delivery===t.delivery&&e.timeoutMs===t.timeoutMs}function cc(e,t,r){if(!dn(e)||e.schemaVersion!==1||typeof e.id!="string"||e.id.length===0)throw un("unknown",t);let n=e.id,s=["queued","delivering","delivered","failed","cancelled"];if(n!==r||e.idempotencyKey!==null&&(typeof e.idempotencyKey!="string"||e.idempotencyKey.length>256)||typeof e.taskId!="string"||e.taskId.length===0||typeof e.agentTabId!="string"||e.agentTabId.length===0||!dn(e.prompt)||!["inline","file","stdin"].includes(String(e.prompt.source))||typeof e.prompt.text!="string"||!Ih(e.prompt.text)||!["when-ready","immediate"].includes(String(e.delivery))||!s.includes(e.state)||!Number.isInteger(e.attempts)||Number(e.attempts)<0||!Number.isInteger(e.timeoutMs)||Number(e.timeoutMs)<=0||Number(e.timeoutMs)>864e5||!Ft(e.expiresAt)||!Ft(e.createdAt)||!Ft(e.updatedAt)||e.deliveryStartedAt!==null&&!Ft(e.deliveryStartedAt)||e.deliveredAt!==null&&!Ft(e.deliveredAt)||e.cancelledAt!==null&&!Ft(e.cancelledAt)||e.cancelledBy!==null&&!sc(e.cancelledBy)||!sc(e.actor)||!vh(e.lastError)||e.state==="delivered"!=(e.deliveredAt!==null)||e.state==="failed"!=(e.lastError!==null)||Number(e.attempts)>0!=(e.deliveryStartedAt!==null)||e.state==="cancelled"!=(e.cancelledAt!==null&&e.cancelledBy!==null))throw un(n,t);return e}function sc(e){return!dn(e)||typeof e.type!="string"?!1:e.type==="human"?["cli","tui"].includes(String(e.source))&&Number.isInteger(e.processId):e.type==="agent"?typeof e.taskId=="string"&&typeof e.agentTabId=="string"&&typeof e.capabilityId=="string":e.type==="system"&&["orchestration-supervisor","heartbeat"].includes(String(e.component))}function vh(e){return e===null||dn(e)&&typeof e.code=="string"&&typeof e.message=="string"&&typeof e.retryable=="boolean"&&typeof e.deliveryUncertain=="boolean"}var gr=(e,t)=>ac.join(e.commandsDir,`${t}.json`),Di=e=>{if(!/^command_[A-Za-z0-9_-]+$/.test(e))throw new g("CLI_USAGE",`Invalid command id "${e}".`,{details:{commandId:e}})},Ft=e=>typeof e=="string"&&e.length>0&&Number.isFinite(Date.parse(e)),Ih=e=>e.trim().length>0&&Buffer.byteLength(e)<=32*1024&&![...e].some(t=>{let r=t.charCodeAt(0);return r<=8||r>=11&&r<=31||r>=127&&r<=159}),dn=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Ch=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT",un=(e,t,r)=>new g("COMMAND_RECORD_INVALID",`Craig command record at ${t} is invalid.`,{details:{commandId:e,filePath:t},...r?{cause:r}:{}});function dc(e,t=new Date){return mn(e,["queued"],"begin delivery"),{...e,state:"delivering",attempts:e.attempts+1,lastError:null,deliveryStartedAt:t.toISOString(),updatedAt:t.toISOString()}}function uc(e,t=new Date){return e.state==="delivered"?e:(mn(e,["delivering"],"complete delivery"),{...e,state:"delivered",deliveredAt:t.toISOString(),lastError:null,updatedAt:t.toISOString()})}function pc(e,t,r=new Date){return e.state==="failed"?e:(mn(e,["queued","delivering"],"fail"),{...e,state:"failed",lastError:t,updatedAt:r.toISOString()})}function mc(e,t,r=new Date){return e.state==="cancelled"?e:(mn(e,["queued"],"cancel"),{...e,state:"cancelled",cancelledAt:r.toISOString(),cancelledBy:t,updatedAt:r.toISOString()})}function mn(e,t,r){if(!t.includes(e.state))throw new g("COMMAND_STATE_CONFLICT",`Cannot ${r} command ${e.id} while it is ${e.state}.`,{details:{commandId:e.id,state:e.state,allowedStates:t}})}import{randomUUID as Ah}from"node:crypto";var Oi=32*1024,fc=1440*60*1e3,$i=256,Eh=["delivered","failed","cancelled"],Mi={type:"system",component:"orchestration-supervisor"};async function xh(e,t){if(jh(t.prompt.text),!Number.isSafeInteger(t.timeoutMs)||t.timeoutMs<=0||t.timeoutMs>fc)throw new g("CLI_USAGE","Prompt command timeout must be between 1ms and 24h.",{details:{maxTimeoutMs:fc}});if(t.idempotencyKey!==void 0&&t.idempotencyKey!==null&&t.idempotencyKey.trim().length===0)throw new g("CLI_USAGE","Idempotency key cannot be empty.",{});if((t.idempotencyKey?.length??0)>$i)throw new g("CLI_USAGE",`Idempotency key exceeds ${$i} characters.`,{details:{maxIdempotencyKeyLength:$i}});let r=t.now??new Date,n={schemaVersion:1,id:t.id??`command_${Ah()}`,idempotencyKey:t.idempotencyKey?.trim()||null,taskId:t.taskId,agentTabId:t.agentTabId,prompt:t.prompt,delivery:t.delivery,state:"queued",attempts:0,timeoutMs:t.timeoutMs,expiresAt:new Date(r.getTime()+t.timeoutMs).toISOString(),lastError:null,actor:t.actor,createdAt:r.toISOString(),updatedAt:r.toISOString(),deliveryStartedAt:null,deliveredAt:null,cancelledAt:null,cancelledBy:null},s=await lc(e,n);if(s.created)try{await mt(e,s.command,"command.queued")}catch(i){throw gc(s.command,i)}return{kind:"sendAgentPrompt",...s}}async function Dh(e,t){return{kind:"showPromptCommand",command:await pn(e,t)}}async function Oh(e,t){let r=await $e(e);return{kind:"listPromptCommands",commands:t?r.filter(n=>n.taskId===t):r}}async function $h(e,t,r){let n=!1,s=await hr(e,t,i=>{if(i.state==="cancelled")return i;let o=mc(i,r??i.actor);return n=!0,o});if(n)try{await mt(e,s,"command.cancelled",s.cancelledBy??s.actor)}catch(i){throw gc(s,i)}return{kind:"cancelPromptCommand",command:s,changed:n}}async function Mh(e,t){let r=await hr(e,t,n=>dc(n));return await mt(e,r,"command.delivering",Mi),r}async function Nh(e,t){let r=await hr(e,t,n=>uc(n));return await mt(e,r,"command.delivered",Mi),r}async function Lh(e,t,r){let n=await hr(e,t,s=>pc(s,r));return await mt(e,n,"command.failed",Mi),n}async function _h(e,t,r){let n=[...r.states??Eh],s=Date.now()+r.timeoutMs;for(;;){let i=await pn(e,t);if(n.includes(i.state))return{kind:"waitPromptCommand",command:i,matchedStates:n};if(r.signal?.aborted)throw new g("OPERATION_CANCELLED",`Cancelled while waiting for command ${t}.`,{retryable:!0,details:{commandId:t,cancelled:!0}});let o=s-Date.now();if(o<=0)throw new g("OPERATION_TIMEOUT",`Timed out after ${r.timeoutMs}ms waiting for command ${t}.`,{retryable:!0,details:{commandId:t,states:n,timeoutMs:r.timeoutMs}});await Fh(Math.min(r.pollIntervalMs??100,o),r.signal)}}function jh(e){if(e.trim().length===0)throw new g("CLI_USAGE","Prompt cannot be empty.",{});let t=Buffer.byteLength(e);if(t>Oi)throw new g("CLI_USAGE",`Prompt exceeds the ${Oi}-byte limit.`,{details:{maxPromptBytes:Oi,promptBytes:t}});if([...e].some(r=>{let n=r.charCodeAt(0);return n<=8||n>=11&&n<=31||n>=127&&n<=159}))throw new g("CLI_USAGE","Prompt contains unsupported control characters.",{})}async function mt(e,t,r,n=t.actor){await jt(e,{id:`${t.id}:${r}`,taskId:t.taskId,agentTabId:t.agentTabId,commandId:t.id,type:r,occurredAt:r==="command.queued"?t.createdAt:r==="command.delivering"?t.deliveryStartedAt??t.updatedAt:r==="command.delivered"?t.deliveredAt??t.updatedAt:r==="command.cancelled"?t.cancelledAt??t.updatedAt:t.updatedAt,actor:n,data:{state:t.state,delivery:t.delivery,attempts:t.attempts,errorCode:t.lastError?.code??null,deliveryUncertain:t.lastError?.deliveryUncertain??!1}})}function Fh(e,t){return t?.aborted?Promise.resolve():new Promise(r=>{let n=()=>{clearTimeout(s),t?.removeEventListener("abort",n),r()},s=setTimeout(n,e);t?.addEventListener("abort",n,{once:!0})})}var gc=(e,t)=>new g("PARTIAL_RESULT",`Command ${e.id} was persisted as ${e.state}, but its event could not be appended.`,{retryable:!0,details:{commandId:e.id,durableState:e.state},cause:t}),ie={create:xh,show:Dh,list:Oh,cancel:$h,wait:_h,beginDelivery:Mh,completeDelivery:Nh,fail:Lh};import{createHash as hc}from"node:crypto";import Wh from"node:path";import{mkdir as qh}from"node:fs/promises";var Ni={type:"system",component:"heartbeat"};async function Ye(e,t={}){await qh(e.orchestrationDir,{recursive:!0});let[r,n,s,i]=await Promise.all([P.listTasks(e,{includeClosed:!0}),t.agentObserver?Promise.resolve(null):Oe.listAgents(e),ec(e),zh(e)]),o=n??Re(r.tasks.filter(m=>m.status!=="closed"),t.agentObserver?.getSnapshots()??[],Date.now()),a=Hh(i),l=a!==i,c=[],d=Li(s.filter(Gh),m=>m.taskId),u=Li(s.filter(m=>m.type.startsWith("task.pr.")),m=>m.taskId),f=Li(s.filter(m=>m.type==="agent.state.changed"),m=>m.agentTabId);for(let m of r.tasks){let k=Uh(m),b=d.get(m.id),O=ji(b?.data)??a.tasks[m.id]??null,q=b?.id??a.tasks[m.id]?.eventId??null;if(O?.signature!==k.signature){let de=O?m.status==="closed"&&O?.status!=="closed"?"task.closed":"task.updated":"task.created",ye=await jt(e,{id:_i(de,m.id,k.signature),type:de,taskId:m.id,workspaceId:m.workspaceId||null,occurredAt:m.updatedAt,actor:Ni,data:{...k,changedFields:O?Bh(O,k):[]}});c.push(ye),q=ye.id}a.tasks[m.id]={...k,eventId:q};let U=Kh(m.prs),I=u.get(m.id),te=ji(I?.data)??a.pullRequests[m.id]??null,je=I?.id??a.pullRequests[m.id]?.eventId??null;if((te||U.associations.length>0)&&te?.signature!==U.signature){let de=Array.isArray(te?.associations)?te.associations.length:0,ye=U.associations.length>de?"task.pr.linked":U.associations.length<de?"task.pr.unlinked":"task.pr.refreshed",p=await jt(e,{id:_i(ye,m.id,U.signature),type:ye,taskId:m.id,workspaceId:m.workspaceId||null,occurredAt:m.updatedAt,actor:Ni,data:U});c.push(p),je=p.id}a.pullRequests[m.id]={...U,eventId:je}}let h=new Map(o.tasks.map(m=>[m.taskId,m.state]));for(let m of o.agents){let k=f.get(m.tabId),b=ji(k?.data)??a.agents[m.tabId]??null;if(b?.state===m.state){a.agents[m.tabId]={state:m.state,eventId:k?.id??a.agents[m.tabId]?.eventId??null};continue}let O=[k?.id??a.agents[m.tabId]?.eventId??"initial",m.state,m.sessionState??"none",m.lastActivityAt??"none",m.exitCode??"none",m.error??"none"].join(":"),q=await jt(e,{id:_i("agent.state.changed",m.tabId,O),type:"agent.state.changed",taskId:m.taskId,agentTabId:m.tabId,actor:Ni,data:{previousState:typeof b?.state=="string"?b.state:null,state:m.state,taskState:h.get(m.taskId)??"idle",sessionState:m.sessionState,lastActivityAt:m.lastActivityAt,exitCode:m.exitCode,error:m.error}});c.push(q),a.agents[m.tabId]={state:m.state,eventId:q.id}}return(c.length>0||l)&&await L(kc(e),a),c}function Uh(e){let t={status:e.status,title:e.title,runner:e.runner,branch:e.branch,lastCommitSha:e.lastCommit?.sha??null,checksStatus:e.checks.status,checksLastRunAt:e.checks.lastRunAt,sourceUpdatedAt:e.updatedAt,agentTabIds:e.ptyTabs.filter(r=>r.kind==="agent").map(r=>r.id)};return{...t,signature:wc(t)}}var Vh=["status","title","runner","branch","lastCommitSha","checksStatus","checksLastRunAt","agentTabIds"];function Bh(e,t){return Vh.filter(r=>JSON.stringify(e[r])!==JSON.stringify(t[r]))}function Kh(e){let t=e.map(r=>({provider:r.provider,owner:r.owner,repo:r.repo,number:r.number,url:r.url,status:r.status,draft:r.draft,headBranch:r.headBranch,lastSyncedAt:r.lastSyncedAt,lastSyncedHeadSha:r.lastSyncedHeadSha}));return{associations:t,signature:wc(t)}}function Li(e,t){let r=new Map;for(let n of e){let s=t(n);s&&r.set(s,n)}return r}var Gh=e=>e.type==="task.created"||e.type==="task.updated"||e.type==="task.closed",wc=e=>hc("sha256").update(JSON.stringify(e)).digest("hex"),_i=(...e)=>hc("sha256").update(e.join("\0")).digest("hex"),ji=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:null,kc=e=>Wh.join(e.orchestrationDir,"event-reconciliation.json");function Hh(e){return e?.schemaVersion===1&&typeof e.tasks=="object"&&e.tasks!==null&&typeof e.pullRequests=="object"&&e.pullRequests!==null&&typeof e.agents=="object"&&e.agents!==null?e:{schemaVersion:1,tasks:{},pullRequests:{},agents:{}}}async function zh(e){try{return await Or(kc(e))}catch(t){if(t instanceof SyntaxError)return null;throw t}}async function Yh(e,t){return await Fi(e),await Ye(e),fr(e,t)}async function Jh(e,t,r){await Fi(e);let n=await Oe.openObserver(e);try{let s=t.after,i=0,o=0;for(;!r.signal?.aborted;){await Ye(e,{agentObserver:n});let a=await fr(e,{...t,...s?{after:s}:{}});for(let l of a.events)r.onEvent(l),i+=1;if(s=a.cursor.after??s,o=a.cursor.sequence,r.signal?.aborted)break;await yc(r.pollIntervalMs??250,r.signal)}return{kind:"watchEvents",eventCount:i,lastSequence:o,cancelled:r.signal?.aborted??!1}}finally{n.close()}}async function Xh(e,t,r){await Fi(e);let n=await P.getTask(e,t);if(r.tabId&&!n.ptyTabs.some(i=>i.kind==="agent"&&i.id===r.tabId))throw new g("TASK_CONTEXT_CONFLICT",`Agent tab ${r.tabId} does not belong to task ${t}.`,{details:{taskId:t,tabId:r.tabId}});let s=await Oe.openObserver(e);try{await Ye(e,{agentObserver:s});let o=(await fr(e,{taskId:t,typeGlob:"agent.state.changed"})).cursor.after??void 0,a=Date.now()+r.timeoutMs;for(;;){let l=Date.now(),c=Re([n],s.getSnapshots(),l),d=r.tabId?c.agents.find(h=>h.tabId===r.tabId)?.state??"idle":c.tasks[0]?.state??"idle";if(r.states.includes(d))return{kind:"waitTask",taskId:t,tabId:r.tabId??null,state:d,matchedStates:[...r.states],observedAt:new Date(l).toISOString()};if(r.signal?.aborted)throw Zh(t);let u=a-Date.now();if(u<=0)throw Qh(t,r.states,r.timeoutMs);await Ye(e,{agentObserver:s}),o=(await fr(e,{taskId:t,typeGlob:"agent.state.changed",...o?{after:o}:{}})).cursor.after??o,await yc(Math.min(250,u),r.signal)}}finally{s.close()}}async function Fi(e){let t=await w.load(e);if(!w.previews.isEnabled(t,"agentOrchestration"))throw new g("CLI_USAGE","Event orchestration is a feature preview. Enable agentOrchestration before using events commands.",{details:{preview:"agentOrchestration"}})}function yc(e,t){return t?.aborted?Promise.resolve():new Promise(r=>{let n=()=>{clearTimeout(s),t?.removeEventListener("abort",n),r()},s=setTimeout(n,e);t?.addEventListener("abort",n,{once:!0})})}var Qh=(e,t,r)=>new g("OPERATION_TIMEOUT",`Timed out after ${r}ms waiting for task ${e} agent state ${t.join(",")}.`,{retryable:!0,details:{taskId:e,states:t,timeoutMs:r}}),Zh=e=>new g("OPERATION_CANCELLED",`Cancelled while waiting for task ${e} agent state.`,{retryable:!0,details:{taskId:e,cancelled:!0}}),fn={list:Yh,watch:Jh,waitForTaskState:Xh,reconcile:Ye};import{readFile as nw}from"node:fs/promises";import{createConnection as ew}from"node:net";async function wr(e){let t=await rw(He(e).socketPath).catch(()=>null);if(!t)return!1;try{return(await Tc(t,{type:"ping"})).protocolVersion!==Lt?!1:(await Tc(t,{type:"wakeOrchestration"}),!0)}catch{return!1}finally{t.end()}}var tw=1;function Tc(e,t){let r=tw++;return new Promise((n,s)=>{let i="",o=setTimeout(()=>s(new Error("Craig PTY daemon request timed out.")),1e3),a=c=>{i+=String(c);let d=i.indexOf(`
82
+ `);if(d===-1)return;l();let u=JSON.parse(i.slice(0,d));u.ok?n(u):s(new Error(u.error??"Craig PTY daemon request failed."))},l=()=>{clearTimeout(o),e.off("data",a)};e.on("data",a),e.write(`${JSON.stringify({...t,id:r})}
83
+ `)})}function rw(e){return new Promise((t,r)=>{let n=ew(e);n.once("connect",()=>t(n)),n.once("error",r)})}async function sw(e,t){await dw(e);let r=await P.getTask(e,t.taskId);if(r.status==="closed")throw new g("COMMAND_STATE_CONFLICT",`Task ${r.id} is ${r.status} and cannot receive prompts.`,{details:{taskId:r.id,taskStatus:r.status}});let n=r.ptyTabs.filter(a=>a.kind==="agent"),s=t.tabId?n.find(a=>a.id===t.tabId):n[0];if(!s)throw new g("TASK_CONTEXT_CONFLICT",t.tabId?`Agent tab ${t.tabId} does not belong to task ${r.id}.`:`Task ${r.id} has no agent tab.`,{details:{taskId:r.id,tabId:t.tabId??null}});let i=await cw(t.prompt,t.readStdin),o;try{o=await ie.create(e,{taskId:r.id,agentTabId:s.id,prompt:i,delivery:t.delivery,timeoutMs:t.timeoutMs,idempotencyKey:t.idempotencyKey??null,actor:{type:"human",source:"cli",processId:process.pid}})}catch(a){throw await wr(e),a}return await wr(e),o}async function iw(e,t){return ie.show(e,t)}async function ow(e,t){return ie.list(e,t)}async function aw(e,t){let r;try{r=await ie.cancel(e,t,{type:"human",source:"cli",processId:process.pid})}catch(n){throw await wr(e),n}return await wr(e),r}async function lw(e,t,r){return ie.wait(e,t,r)}async function cw(e,t){if(e.source==="inline")return e;if(e.source==="file")try{return{source:"file",text:await nw(e.path,"utf8")}}catch(r){throw new g("CLI_USAGE",`Unable to read prompt file ${e.path}.`,{details:{promptFile:e.path},cause:r})}if(!t)throw new g("INPUT_REQUIRED","Prompt input from stdin is unavailable.",{});return{source:"stdin",text:await t()}}async function dw(e){let t=await w.load(e);if(!w.previews.isEnabled(t,"agentOrchestration"))throw new g("CLI_USAGE","Prompt dispatch is a feature preview. Enable agentOrchestration before sending prompts.",{details:{preview:"agentOrchestration"}})}var Wt={send:sw,show:iw,list:ow,cancel:aw,wait:lw};async function Rc(e,t){switch(e.kind){case"addWorkspace":{let r=await X.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await Wi(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await X.repos.addRepo(t.paths,e.path);return await Wi(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return X.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await Rt({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await ae(t.paths)).filter(i=>i.primaryRepoId===e.repoId).map(i=>i.id):[],s=await X.repos.removeRepo(t.paths,e.repoId,{listTasks:P.listTasks});if(r){let i=n.includes(r.selectedWorkspaceId??""),o=r.selectedRepoId===e.repoId;i?await Fe({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):o&&await Fe({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return X.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await X.archiveWorkspace(t.paths,e.workspaceId);return await uw(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await X.restoreWorkspace(t.paths,e.workspaceId);return await Wi(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return X.removeWorkspace(t.paths,e.workspaceId,{listTasks:P.listTasks});case"createTask":return P.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?P.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):P.listTasks(t.paths);case"currentTask":{let r=qi(t);return{kind:"currentTask",task:r.task,context:{source:r.source,agentTabId:r.agentTabId}}}case"attachTask":return P.attachTask(t.paths,e.taskId);case"addTaskLink":return P.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return P.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return P.showTask(t.paths,e.taskId);case"showCurrentTask":return P.showTask(t.paths,qi(t).task.id);case"showTaskPr":return P.prs.show(t.paths,gt(e.taskId,t),e.repoId);case"discoverTaskPr":return P.prs.discover(t.paths,gt(e.taskId,t),e.repoId);case"linkTaskPr":return P.prs.link(t.paths,gt(e.taskId,t),e.pullRequest,e.repoId);case"refreshTaskPr":return P.prs.refreshAssociation(t.paths,gt(e.taskId,t),e.repoId);case"unlinkTaskPr":return P.prs.unlink(t.paths,gt(e.taskId,t),e.pullRequest,e.repoId);case"listAgents":return Oe.listAgents(t.paths,e.taskId);case"showAgentStatus":return Oe.showAgentStatus(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.tabId?{tabId:e.tabId}:{}});case"waitTask":{let r={states:e.states,timeoutMs:e.timeoutMs,...e.tabId?{tabId:e.tabId}:{},...t.signal?{signal:t.signal}:{}},n=gt(e.taskId,t),s=await w.load(t.paths);return w.previews.isEnabled(s,"agentOrchestration")?fn.waitForTaskState(t.paths,n,r):Oe.waitForTask(t.paths,n,r)}case"listEvents":return fn.list(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}});case"watchEvents":return fn.watch(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}},{onEvent:t.emitEvent??(()=>{}),...t.signal?{signal:t.signal}:{}});case"sendAgentPrompt":return Wt.send(t.paths,{taskId:gt(e.taskId,t),...e.tabId?{tabId:e.tabId}:t.taskContext?.agentTabId?{tabId:t.taskContext.agentTabId}:{},prompt:e.prompt,delivery:e.delivery,timeoutMs:e.timeoutMs,...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{},...t.readStdin?{readStdin:t.readStdin}:{}});case"showPromptCommand":return Wt.show(t.paths,e.commandId);case"listPromptCommands":return Wt.list(t.paths,e.taskId);case"cancelPromptCommand":return Wt.cancel(t.paths,e.commandId);case"waitPromptCommand":return Wt.wait(t.paths,e.commandId,{...e.states?{states:e.states}:{},timeoutMs:e.timeoutMs,...t.signal?{signal:t.signal}:{}});case"showSelectedTask":return P.showTask(t.paths,ft(t,"show"));case"streamTaskLogs":return P.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return P.prepareTaskLogs(t.paths,ft(t,"logs"));case"showTaskDiff":return P.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return P.showTaskDiff(t.paths,ft(t,"diff"));case"focusTask":return P.focusTask(t.paths,e.taskId);case"focusSelectedTask":return P.focusTask(t.paths,ft(t,"focus"));case"openTask":return P.openTask(t.paths,e.taskId);case"openSelectedTask":return P.openTask(t.paths,ft(t,"open"));case"runChecks":return P.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return P.runChecks(t.paths,ft(t,"check"));case"commitTask":return P.commitTask(t.paths,e.taskId);case"commitSelectedTask":return P.commitTask(t.paths,ft(t,"commit"));case"showContext":{let r=mw(t);return{kind:"showContext",workspace:{root:r.workspaceRoot,source:r.source,initialized:r.initialized},task:t.taskContext?{id:t.taskContext.task.id,source:t.taskContext.source,agentTabId:t.taskContext.agentTabId}:null}}case"help":return{kind:"help",text:ss()};case"exit":return{kind:"exit"};default:return pw(e)}}async function Wi(e,t,r){let n=await Rt({uiStateFile:e.uiStateFile})??Mr();await Fe({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function uw(e,t){let r=await Rt({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Fe({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function pw(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function ft(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 qi(e){if(e.taskContext)return e.taskContext;throw new Error("Command requires resolved task context.")}function gt(e,t){return e??qi(t).task.id}function mw(e){if(e.workspaceContext)return e.workspaceContext;throw new Error("Command requires resolved workspace context.")}function bc(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(`
84
84
  `);case"createRepo":return[`${e.created?"Registered":"Already registered"} repo ${e.repo.id}`,`Path: ${e.repo.rootPath}`,`Branch: ${e.repo.defaultBranch}`,`Workspace: ${e.workspaceId}`].join(`
85
85
  `);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(`
86
86
  `);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(`
87
87
  `);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(`
88
88
  `);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(`
89
- `);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} ${dw(t)} ${uw(t)} ${t.title}`)].join(`
90
- `);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}`,...lw(e)].join(`
89
+ `);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} ${yw(t)} ${Tw(t)} ${t.title}`)].join(`
90
+ `);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}`,...ww(e)].join(`
91
91
  `);case"currentTask":return[`${e.task.id}: ${e.task.title}`,`Workspace: ${e.task.workspaceId}`,`Repo: ${e.task.repoId}`,`Worktree: ${e.task.worktreePath}`,`Context source: ${e.context.source}`,`Agent tab: ${e.context.agentTabId??"none"}`].join(`
92
- `);case"showTaskPr":case"discoverTaskPr":case"linkTaskPr":case"refreshTaskPr":case"unlinkTaskPr":return aw(e);case"listAgents":case"showAgentStatus":return iw(e);case"waitTask":return`Task ${e.taskId}${e.tabId?` tab ${e.tabId}`:""} reached ${e.state}.`;case"listEvents":return e.events.length===0?"No events found.":e.events.map(Wo).join(`
93
- `);case"watchEvents":return"";case"sendAgentPrompt":return`${e.created?"Queued":"Found"} command ${e.command.id} for task ${e.command.taskId} tab ${e.command.agentTabId}.`;case"showPromptCommand":return ow(e.command);case"listPromptCommands":return e.commands.length===0?"No prompt commands found.":["ID TASK TAB STATE DELIVERY ATTEMPTS",...e.commands.map(t=>`${t.id} ${t.taskId} ${t.agentTabId} ${t.state} ${t.delivery} ${t.attempts}`)].join(`
92
+ `);case"showTaskPr":case"discoverTaskPr":case"linkTaskPr":case"refreshTaskPr":case"unlinkTaskPr":return hw(e);case"listAgents":case"showAgentStatus":return gw(e);case"waitTask":return`Task ${e.taskId}${e.tabId?` tab ${e.tabId}`:""} reached ${e.state}.`;case"listEvents":return e.events.length===0?"No events found.":e.events.map(Ui).join(`
93
+ `);case"watchEvents":return"";case"sendAgentPrompt":return`${e.created?"Queued":"Found"} command ${e.command.id} for task ${e.command.taskId} tab ${e.command.agentTabId}.`;case"showPromptCommand":return fw(e.command);case"listPromptCommands":return e.commands.length===0?"No prompt commands found.":["ID TASK TAB STATE DELIVERY ATTEMPTS",...e.commands.map(t=>`${t.id} ${t.taskId} ${t.agentTabId} ${t.state} ${t.delivery} ${t.attempts}`)].join(`
94
94
  `);case"cancelPromptCommand":return`${e.changed?"Cancelled":"Command already cancelled:"} ${e.command.id}`;case"waitPromptCommand":return`Command ${e.command.id} reached ${e.command.state}.`;case"showContext":return[`Workspace: ${e.workspace.root}`,`Workspace source: ${e.workspace.source}`,`Initialized: ${e.workspace.initialized?"yes":"no"}`,`Task: ${e.task?.id??"none"}`,`Task source: ${e.task?.source??"none"}`,`Agent tab: ${e.task?.agentTabId??"none"}`].join(`
95
95
  `);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(`
96
- `);default:return cw(e)}}function ow(e){return[`${e.id}: ${e.state}`,`Task: ${e.taskId}`,`Agent tab: ${e.agentTabId}`,`Delivery: ${e.delivery}`,`Attempts: ${e.attempts}`,`Prompt source: ${e.prompt.source}`,`Prompt bytes: ${Buffer.byteLength(e.prompt.text)}`,`Created: ${e.createdAt}`,`Updated: ${e.updatedAt}`,`Error: ${e.lastError?.message??"none"}`].join(`
97
- `)}function Wo(e){return`${e.sequence} ${e.occurredAt} ${e.type} ${e.taskId??"-"}`}function iw(e){return e.agents.length===0?"No agent tabs found.":["TASK TAB RUNNER STATE SESSION ERROR",...e.agents.map(t=>`${t.taskId} ${t.tabId} ${t.runner} ${t.state} ${t.sessionState??"none"} ${t.error??""}`),...e.daemonAvailable?[]:["Warning: PTY daemon unavailable; live agent tabs report idle unless a durable startup failure exists."]].join(`
98
- `)}function aw(e){let t=`${e.taskId} (${e.repoId}): ${e.disposition}`,r=e.pullRequests.length===0?["No pull requests associated."]:["PR STATUS HEAD URL",...e.pullRequests.map(n=>`#${n.number??"-"} ${n.status??"unknown"} ${n.headBranch??"-"} ${n.url??"-"}`)];return[t,...r,...e.warnings.map(n=>`Warning: ${n}`)].join(`
99
- `)}function lw(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 cw(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function dw(e){return e.checks.status}function uw(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"}`:"-"}function wc(e,t){let{data:r,warnings:n}=pw(t);return JSON.stringify({schemaVersion:1,command:e,ok:!0,data:r,warnings:n})}function pw(e){if("warnings"in e&&Array.isArray(e.warnings)){let{warnings:t,...r}=e;return{data:r,warnings:t}}return{data:e,warnings:[]}}function kc(e,t){let r={schemaVersion:1,command:e,ok:!1,error:{code:t.code,message:t.message,retryable:t.retryable,details:t.details}};return JSON.stringify(r)}async function qo(e){let t=await J.resolveContext({cwd:e.cwd,...e.explicitWorkspaceRoot!==void 0?{explicitWorkspaceRoot:e.explicitWorkspaceRoot}:{},...e.environmentWorkspaceRoot!==void 0?{environmentWorkspaceRoot:e.environmentWorkspaceRoot}:{},...e.allowUninitializedWorkspace!==void 0?{allowUninitializedCwd:e.allowUninitializedWorkspace}:{}}),r=re(t.workspaceRoot),n=e.resolveTask===!0||e.requireTask===!0||e.explicitTaskId!==void 0||e.environmentTaskId!==void 0||e.environmentAgentTabId!==void 0;if(n&&!t.initialized)throw new f("TASK_CONTEXT_NOT_FOUND",`Task context cannot be resolved because ${t.workspaceRoot} is not an initialized Craig workspace.`,{details:{workspaceRoot:t.workspaceRoot}});let s=n&&t.initialized?await S.resolveContext(r,{cwd:e.cwd,...e.explicitTaskId!==void 0?{explicitTaskId:e.explicitTaskId}:{},...e.environmentTaskId!==void 0?{environmentTaskId:e.environmentTaskId}:{},...e.environmentAgentTabId!==void 0?{environmentAgentTabId:e.environmentAgentTabId}:{},...e.requireTask!==void 0?{required:e.requireTask}:{}}):null;return{paths:r,workspace:t,task:s}}async function yc(e){let t="cli",r=ga(e.argv);try{let n=fa(e.argv);if(r=n.options.json,n.mode==="interactive"){if(n.options.noInput||n.options.json||Tw(e.env)||!e.isInputTty||!e.isOutputTty)throw new f("INPUT_REQUIRED","Interactive Craig requires a TTY. Provide a command instead of starting the terminal application.",{});let u=await qo({cwd:e.cwd,...n.options.workspaceRoot!==void 0?{explicitWorkspaceRoot:n.options.workspaceRoot}:{},...e.env.CRAIG_WORKSPACE_ROOT!==void 0?{environmentWorkspaceRoot:e.env.CRAIG_WORKSPACE_ROOT}:{},allowUninitializedWorkspace:!0});return e.runInteractive(u.workspace.workspaceRoot)}if(!n.command||!n.commandName)throw new f("CLI_USAGE","Command mode requires a command.",{});if(t=n.commandName,n.command.kind==="watchEvents"&&n.options.json)throw new f("CLI_USAGE","events watch streams output; use --format jsonl instead of --json.",{});gw(n.command,n.options.taskId);let s=ww(n.command,n.options.taskId),o=fw(s);hw(s,n.options.taskId,o);let i=o!=="none",a=await qo({cwd:e.cwd,...n.options.workspaceRoot!==void 0?{explicitWorkspaceRoot:n.options.workspaceRoot}:{},...e.env.CRAIG_WORKSPACE_ROOT!==void 0?{environmentWorkspaceRoot:e.env.CRAIG_WORKSPACE_ROOT}:{},...i&&n.options.taskId!==void 0?{explicitTaskId:n.options.taskId}:{},...i&&e.env.CRAIG_TASK_ID!==void 0?{environmentTaskId:e.env.CRAIG_TASK_ID}:{},...i&&e.env.CRAIG_AGENT_TAB_ID!==void 0?{environmentAgentTabId:e.env.CRAIG_AGENT_TAB_ID}:{},allowUninitializedWorkspace:mw(s),resolveTask:o!=="none",requireTask:o==="required"}),l=kw(s,e.signal),c;try{c=await gc(s,{paths:a.paths,workspaceContext:a.workspace,taskContext:a.task,...l.signal?{signal:l.signal}:{},...s.kind==="watchEvents"?{emitEvent:u=>e.writeStdout(`${s.format==="jsonl"?JSON.stringify(u):Wo(u)}
100
- `)}:{},...e.readStdin?{readStdin:e.readStdin}:{}})}finally{l.dispose()}let d=r?wc(t,c):hc(c);return d.length>0&&e.writeStdout(`${d}
101
- `),0}catch(n){let s=Zn(n),o=r?kc(t,s):s.message;return e.writeStderr(`${o}
102
- `),s.exitCode}}function mw(e){return["addWorkspace","addRepo","listRepos","listWorkspaces","help"].includes(e.kind)}function fw(e){return e.kind==="showContext"?"optional":e.kind==="currentTask"||e.kind==="showCurrentTask"?"required":yw(e)?e.taskId?"none":"required":e.kind==="listAgents"||e.kind==="showAgentStatus"||e.kind==="listEvents"||e.kind==="watchEvents"?"none":e.kind==="sendAgentPrompt"?e.taskId?"none":"required":e.kind==="listPromptCommands"?"none":e.kind==="waitTask"?e.taskId?"none":"required":"none"}function gw(e,t){let r=Tc(e);if(!(r===void 0||t===void 0||t===r))throw new f("CLI_USAGE",`Task ${r} conflicts with --task ${t}. Provide only one task target.`,{details:{positionalTaskId:r,globalTaskId:t}})}function hw(e,t,r){if(!(t===void 0||r!=="none"||Tc(e)===t))throw new f("CLI_USAGE",`--task is not supported by ${e.kind}. Use it with context show, task current, or task show without an id.`,{details:{commandKind:e.kind,globalTaskId:t}})}function Tc(e){switch(e.kind){case"showTask":case"attachTask":case"listTaskLinks":case"streamTaskLogs":case"showTaskDiff":case"focusTask":case"openTask":case"runChecks":case"commitTask":case"waitTask":case"listAgents":case"showAgentStatus":case"listEvents":case"watchEvents":case"sendAgentPrompt":case"listPromptCommands":return e.taskId;case"showTaskPr":case"discoverTaskPr":case"linkTaskPr":case"refreshTaskPr":case"unlinkTaskPr":return e.taskId;case"addTaskLink":return e.taskId;default:return}}function ww(e,t){return t&&(e.kind==="listAgents"||e.kind==="showAgentStatus"||e.kind==="waitTask"||e.kind==="listEvents"||e.kind==="watchEvents"||e.kind==="sendAgentPrompt"||e.kind==="listPromptCommands")?{...e,taskId:e.taskId??t}:e}function kw(e,t){if(e.kind!=="waitTask"&&e.kind!=="watchEvents"&&e.kind!=="waitPromptCommand")return{dispose:()=>{}};if(t)return{signal:t,dispose:()=>{}};let r=new AbortController,n=()=>r.abort();return process.once("SIGINT",n),{signal:r.signal,dispose:()=>process.removeListener("SIGINT",n)}}function yw(e){return["showTaskPr","discoverTaskPr","linkTaskPr","refreshTaskPr","unlinkTaskPr"].includes(e.kind)}function Tw(e){let t=e.CI?.trim().toLowerCase();return t!==void 0&&t!==""&&t!=="0"&&t!=="false"}import{createRequire as zT}from"node:module";import{readFile as Rw,stat as bw}from"node:fs/promises";import Uo from"node:path";var Pw=200*1024,Sw=500*1024,pn="100000";async function bc(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return vw(e,t,r);try{let n=He(r.selectedFilePath??null,t.filePaths),s=He(r.selectedDiffPath??null,t.diffPaths),o=s?await hr(e.worktreePath):null,[i,a]=await Promise.all([fn(e.worktreePath,n),s?Bo(e.worktreePath,s,t.diffRows,o):Promise.resolve(Q("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 vw(e,t,r){let n=He(r.selectedFilePath??null,t.filePaths),s=He(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([Sc(e,n),(async()=>{if(!s)return Q("No diff selected","No local changes found.","empty");let l=mn(e,s),c=l?await hr(l.target.worktreePath).catch(()=>null):null;return vc(e,s,t.diffRows,c)})()]),a=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:a,selectedFile:o,selectedDiff:i}}async function Pc(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Iw(e,t);try{await z(e);let r=await hr(e.worktreePath),[n,s]=await Promise.all([Ic(e.worktreePath),Cc(e.worktreePath,r)]),o=[...new Set(s.map(u=>u.path))],i=He(t.selectedFilePath??null,n),a=He(t.selectedDiffPath??null,o),[l,c]=await Promise.all([fn(e.worktreePath,i),a?Bo(e.worktreePath,a,s,r):Promise.resolve(Q("No diff selected","No local changes found.","empty"))]),d=a?{[a]:c}:{};return{taskId:e.id,fileRows:xc(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:Q("Files unavailable",n,"error"),selectedDiff:Q("Diff unavailable",n,"error"),error:n}}}async function Iw(e,t){let r=(e.repoTargets??[]).filter(m=>m.status==="ready"),n=await Promise.all(r.map(async m=>{let p=await hr(m.worktreePath).catch(()=>null),[k,w]=await Promise.all([Ic(m.worktreePath).catch(()=>[]),Cc(m.worktreePath,p).catch(()=>[])]);return{target:m,baseRef:p,targetFiles:k,targetDiffRows:w}})),s=[],o=[];for(let{target:m,targetFiles:p,targetDiffRows:k}of n)s.push(...p.map(w=>`${m.repoId}/${w}`)),o.push(...k.map(w=>({...w,path:`${m.repoId}/${w.path}`})));let i=[...new Set(o.map(m=>m.path))].sort(),a=He(t.selectedFilePath??null,s),l=He(t.selectedDiffPath??null,i),[c,d]=await Promise.all([Sc(e,a),(async()=>{if(!l)return Q("No diff selected","No local changes found.","empty");let m=mn(e,l),p=m?n.find(k=>k.target.repoId===m.target.repoId):null;return vc(e,l,o,p?.baseRef??null)})()]),u=l?{[l]:d}:{};return{taskId:e.id,fileRows:xc(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:u,selectedFilePath:a,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}async function Sc(e,t){let r=mn(e,t);if(!r)return Q("No file selected","No Git-visible files found.","empty");let n=await fn(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function vc(e,t,r,n=null){let s=mn(e,t);return s?{...await Bo(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}:Q(t,"Repo target is unavailable.","error",t)}function mn(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 Ic(e){let t=await C("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return Dc(t.stdout)}async function Cc(e,t){let[r,n,s,o]=await Promise.all([Cw(e,t),Rc(e,"staged"),Rc(e,"unstaged"),Aw(e)]);return[...r,...n,...s,...o]}async function Cw(e,t){if(!t)return[];let[r,n]=await Promise.all([C("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),C("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=Ac(r.stdout),o=Ec(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 Rc(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([C("git",[...r,"--name-status"],{cwd:e}),C("git",[...r,"--numstat"],{cwd:e})]),o=Ac(n.stdout),i=Ec(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 Aw(e){let t=await C("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=Dc(t.stdout);return await Promise.all(r.map(async s=>{let o=await fn(e,s),i=o.status==="ready"?Ew(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function Ac(e){return e.split(`
103
- `).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 Ec(e){let t=new Map;for(let r of e.split(`
104
- `)){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 hr(e){return(await O("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await O("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function fn(e,t){if(!t)return Q("No file selected","No Git-visible files found.","empty");let r=xw(e,t);try{let n=await bw(r);if(n.size>Pw)return Q(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await Rw(r);return Dw(s)?Q(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
105
- `),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return Q(t,s,"missing",t,null)}}async function Bo(e,t,r,n=null){if(!t)return Q("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 hr(e);if(a){let l=await C("git",["diff","--stat","--patch",`--unified=${pn}`,`${a}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
106
- ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let a=await C("git",["diff","--cached","--stat","--patch",`--unified=${pn}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`staged
107
- ${a.stdout.trimEnd()}`)}if(o.includes("unstaged")){let a=await C("git",["diff","--stat","--patch",`--unified=${pn}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`unstaged
108
- ${a.stdout.trimEnd()}`)}if(o.includes("untracked")){let a=await O("git",["diff","--no-index","--stat","--patch",`--unified=${pn}`,"--","/dev/null",t],{cwd:e});a.stdout.trim().length>0&&s.push(`untracked
109
- ${a.stdout.trimEnd()}`)}let i=s.join(`
96
+ `);default:return kw(e)}}function fw(e){return[`${e.id}: ${e.state}`,`Task: ${e.taskId}`,`Agent tab: ${e.agentTabId}`,`Delivery: ${e.delivery}`,`Attempts: ${e.attempts}`,`Prompt source: ${e.prompt.source}`,`Prompt bytes: ${Buffer.byteLength(e.prompt.text)}`,`Created: ${e.createdAt}`,`Updated: ${e.updatedAt}`,`Error: ${e.lastError?.message??"none"}`].join(`
97
+ `)}function Ui(e){return`${e.sequence} ${e.occurredAt} ${e.type} ${e.taskId??"-"}`}function gw(e){return e.agents.length===0?"No agent tabs found.":["TASK TAB RUNNER STATE SESSION ERROR",...e.agents.map(t=>`${t.taskId} ${t.tabId} ${t.runner} ${t.state} ${t.sessionState??"none"} ${t.error??""}`),...e.daemonAvailable?[]:["Warning: PTY daemon unavailable; live agent tabs report idle unless a durable startup failure exists."]].join(`
98
+ `)}function hw(e){let t=`${e.taskId} (${e.repoId}): ${e.disposition}`,r=e.pullRequests.length===0?["No pull requests associated."]:["PR STATUS HEAD URL",...e.pullRequests.map(n=>`#${n.number??"-"} ${n.status??"unknown"} ${n.headBranch??"-"} ${n.url??"-"}`)];return[t,...r,...e.warnings.map(n=>`Warning: ${n}`)].join(`
99
+ `)}function ww(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 kw(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function yw(e){return e.checks.status}function Tw(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,i)=>{let o=i.pullRequest.status??"unknown";return s[o]=(s[o]??0)+1,s},{});return Object.entries(n).map(([s,i])=>`${i} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}function Pc(e,t){let{data:r,warnings:n}=Rw(t);return JSON.stringify({schemaVersion:1,command:e,ok:!0,data:r,warnings:n})}function Rw(e){if("warnings"in e&&Array.isArray(e.warnings)){let{warnings:t,...r}=e;return{data:r,warnings:t}}return{data:e,warnings:[]}}function Sc(e,t){let r={schemaVersion:1,command:e,ok:!1,error:{code:t.code,message:t.message,retryable:t.retryable,details:t.details}};return JSON.stringify(r)}async function Vi(e){let t=await X.resolveContext({cwd:e.cwd,...e.explicitWorkspaceRoot!==void 0?{explicitWorkspaceRoot:e.explicitWorkspaceRoot}:{},...e.environmentWorkspaceRoot!==void 0?{environmentWorkspaceRoot:e.environmentWorkspaceRoot}:{},...e.allowUninitializedWorkspace!==void 0?{allowUninitializedCwd:e.allowUninitializedWorkspace}:{}}),r=ne(t.workspaceRoot),n=e.resolveTask===!0||e.requireTask===!0||e.explicitTaskId!==void 0||e.environmentTaskId!==void 0||e.environmentAgentTabId!==void 0;if(n&&!t.initialized)throw new g("TASK_CONTEXT_NOT_FOUND",`Task context cannot be resolved because ${t.workspaceRoot} is not an initialized Craig workspace.`,{details:{workspaceRoot:t.workspaceRoot}});let s=n&&t.initialized?await P.resolveContext(r,{cwd:e.cwd,...e.explicitTaskId!==void 0?{explicitTaskId:e.explicitTaskId}:{},...e.environmentTaskId!==void 0?{environmentTaskId:e.environmentTaskId}:{},...e.environmentAgentTabId!==void 0?{environmentAgentTabId:e.environmentAgentTabId}:{},...e.requireTask!==void 0?{required:e.requireTask}:{}}):null;return{paths:r,workspace:t,task:s}}async function vc(e){let t="cli",r=Ta(e.argv);try{let n=ya(e.argv);if(r=n.options.json,n.mode==="interactive"){if(n.options.noInput||n.options.json||Ew(e.env)||!e.isInputTty||!e.isOutputTty)throw new g("INPUT_REQUIRED","Interactive Craig requires a TTY. Provide a command instead of starting the terminal application.",{});let u=await Vi({cwd:e.cwd,...n.options.workspaceRoot!==void 0?{explicitWorkspaceRoot:n.options.workspaceRoot}:{},...e.env.CRAIG_WORKSPACE_ROOT!==void 0?{environmentWorkspaceRoot:e.env.CRAIG_WORKSPACE_ROOT}:{},allowUninitializedWorkspace:!0});return e.runInteractive(u.workspace.workspaceRoot)}if(!n.command||!n.commandName)throw new g("CLI_USAGE","Command mode requires a command.",{});if(t=n.commandName,n.command.kind==="watchEvents"&&n.options.json)throw new g("CLI_USAGE","events watch streams output; use --format jsonl instead of --json.",{});Sw(n.command,n.options.taskId);let s=Iw(n.command,n.options.taskId),i=Pw(s);vw(s,n.options.taskId,i);let o=i!=="none",a=await Vi({cwd:e.cwd,...n.options.workspaceRoot!==void 0?{explicitWorkspaceRoot:n.options.workspaceRoot}:{},...e.env.CRAIG_WORKSPACE_ROOT!==void 0?{environmentWorkspaceRoot:e.env.CRAIG_WORKSPACE_ROOT}:{},...o&&n.options.taskId!==void 0?{explicitTaskId:n.options.taskId}:{},...o&&e.env.CRAIG_TASK_ID!==void 0?{environmentTaskId:e.env.CRAIG_TASK_ID}:{},...o&&e.env.CRAIG_AGENT_TAB_ID!==void 0?{environmentAgentTabId:e.env.CRAIG_AGENT_TAB_ID}:{},allowUninitializedWorkspace:bw(s),resolveTask:i!=="none",requireTask:i==="required"}),l=Cw(s,e.signal),c;try{c=await Rc(s,{paths:a.paths,workspaceContext:a.workspace,taskContext:a.task,...l.signal?{signal:l.signal}:{},...s.kind==="watchEvents"?{emitEvent:u=>e.writeStdout(`${s.format==="jsonl"?JSON.stringify(u):Ui(u)}
100
+ `)}:{},...e.readStdin?{readStdin:e.readStdin}:{}})}finally{l.dispose()}let d=r?Pc(t,c):bc(c);return d.length>0&&e.writeStdout(`${d}
101
+ `),0}catch(n){let s=ts(n),i=r?Sc(t,s):s.message;return e.writeStderr(`${i}
102
+ `),s.exitCode}}function bw(e){return["addWorkspace","addRepo","listRepos","listWorkspaces","help"].includes(e.kind)}function Pw(e){return e.kind==="showContext"?"optional":e.kind==="currentTask"||e.kind==="showCurrentTask"?"required":Aw(e)?e.taskId?"none":"required":e.kind==="listAgents"||e.kind==="showAgentStatus"||e.kind==="listEvents"||e.kind==="watchEvents"?"none":e.kind==="sendAgentPrompt"?e.taskId?"none":"required":e.kind==="listPromptCommands"?"none":e.kind==="waitTask"?e.taskId?"none":"required":"none"}function Sw(e,t){let r=Ic(e);if(!(r===void 0||t===void 0||t===r))throw new g("CLI_USAGE",`Task ${r} conflicts with --task ${t}. Provide only one task target.`,{details:{positionalTaskId:r,globalTaskId:t}})}function vw(e,t,r){if(!(t===void 0||r!=="none"||Ic(e)===t))throw new g("CLI_USAGE",`--task is not supported by ${e.kind}. Use it with context show, task current, or task show without an id.`,{details:{commandKind:e.kind,globalTaskId:t}})}function Ic(e){switch(e.kind){case"showTask":case"attachTask":case"listTaskLinks":case"streamTaskLogs":case"showTaskDiff":case"focusTask":case"openTask":case"runChecks":case"commitTask":case"waitTask":case"listAgents":case"showAgentStatus":case"listEvents":case"watchEvents":case"sendAgentPrompt":case"listPromptCommands":return e.taskId;case"showTaskPr":case"discoverTaskPr":case"linkTaskPr":case"refreshTaskPr":case"unlinkTaskPr":return e.taskId;case"addTaskLink":return e.taskId;default:return}}function Iw(e,t){return t&&(e.kind==="listAgents"||e.kind==="showAgentStatus"||e.kind==="waitTask"||e.kind==="listEvents"||e.kind==="watchEvents"||e.kind==="sendAgentPrompt"||e.kind==="listPromptCommands")?{...e,taskId:e.taskId??t}:e}function Cw(e,t){if(e.kind!=="waitTask"&&e.kind!=="watchEvents"&&e.kind!=="waitPromptCommand")return{dispose:()=>{}};if(t)return{signal:t,dispose:()=>{}};let r=new AbortController,n=()=>r.abort();return process.once("SIGINT",n),{signal:r.signal,dispose:()=>process.removeListener("SIGINT",n)}}function Aw(e){return["showTaskPr","discoverTaskPr","linkTaskPr","refreshTaskPr","unlinkTaskPr"].includes(e.kind)}function Ew(e){let t=e.CI?.trim().toLowerCase();return t!==void 0&&t!==""&&t!=="0"&&t!=="false"}import{createRequire as cR}from"node:module";import{readFile as xw,stat as Dw}from"node:fs/promises";import Bi from"node:path";var Ow=200*1024,$w=500*1024,gn="100000";async function Ac(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return Mw(e,t,r);try{let n=Je(r.selectedFilePath??null,t.filePaths),s=Je(r.selectedDiffPath??null,t.diffPaths),i=s?await kr(e.worktreePath):null,[o,a]=await Promise.all([wn(e.worktreePath,n),s?Ki(e.worktreePath,s,t.diffRows,i):Promise.resolve(Z("No diff selected","No local changes found.","empty"))]),l=s?{[s]:a}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:l,selectedFile:o,selectedDiff:a,error:null}}catch(n){let s=n instanceof Error?n.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function Mw(e,t,r){let n=Je(r.selectedFilePath??null,t.filePaths),s=Je(r.selectedDiffPath??null,t.diffPaths),[i,o]=await Promise.all([xc(e,n),(async()=>{if(!s)return Z("No diff selected","No local changes found.","empty");let l=hn(e,s),c=l?await kr(l.target.worktreePath).catch(()=>null):null;return Dc(e,s,t.diffRows,c)})()]),a=s?{[s]:o}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:a,selectedFile:i,selectedDiff:o}}async function Ec(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Nw(e,t);try{await J(e);let r=await kr(e.worktreePath),[n,s]=await Promise.all([Oc(e.worktreePath),$c(e.worktreePath,r)]),i=[...new Set(s.map(u=>u.path))],o=Je(t.selectedFilePath??null,n),a=Je(t.selectedDiffPath??null,i),[l,c]=await Promise.all([wn(e.worktreePath,o),a?Ki(e.worktreePath,a,s,r):Promise.resolve(Z("No diff selected","No local changes found.","empty"))]),d=a?{[a]:c}:{};return{taskId:e.id,fileRows:Lc(n),filePaths:n,diffRows:s,diffPaths:i,diffContents:d,selectedFilePath:o,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:Z("Files unavailable",n,"error"),selectedDiff:Z("Diff unavailable",n,"error"),error:n}}}async function Nw(e,t){let r=(e.repoTargets??[]).filter(f=>f.status==="ready"),n=await Promise.all(r.map(async f=>{let h=await kr(f.worktreePath).catch(()=>null),[m,k]=await Promise.all([Oc(f.worktreePath).catch(()=>[]),$c(f.worktreePath,h).catch(()=>[])]);return{target:f,baseRef:h,targetFiles:m,targetDiffRows:k}})),s=[],i=[];for(let{target:f,targetFiles:h,targetDiffRows:m}of n)s.push(...h.map(k=>`${f.repoId}/${k}`)),i.push(...m.map(k=>({...k,path:`${f.repoId}/${k.path}`})));let o=[...new Set(i.map(f=>f.path))].sort(),a=Je(t.selectedFilePath??null,s),l=Je(t.selectedDiffPath??null,o),[c,d]=await Promise.all([xc(e,a),(async()=>{if(!l)return Z("No diff selected","No local changes found.","empty");let f=hn(e,l),h=f?n.find(m=>m.target.repoId===f.target.repoId):null;return Dc(e,l,i,h?.baseRef??null)})()]),u=l?{[l]:d}:{};return{taskId:e.id,fileRows:Lc(s),filePaths:s,diffRows:i,diffPaths:o,diffContents:u,selectedFilePath:a,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}async function xc(e,t){let r=hn(e,t);if(!r)return Z("No file selected","No Git-visible files found.","empty");let n=await wn(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function Dc(e,t,r,n=null){let s=hn(e,t);return s?{...await Ki(s.target.worktreePath,s.relativePath,r.filter(o=>o.path.startsWith(`${s.target.repoId}/`)).map(o=>({...o,path:o.path.slice(s.target.repoId.length+1)})),n),path:t,title:t}:Z(t,"Repo target is unavailable.","error",t)}function hn(e,t){if(!t)return null;let[r,...n]=t.split("/"),s=n.join("/"),i=(e.repoTargets??[]).find(o=>o.repoId===r&&o.status==="ready")??null;return!i||s.length===0?null:{target:i,relativePath:s}}async function Oc(e){let t=await C("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return _c(t.stdout)}async function $c(e,t){let[r,n,s,i]=await Promise.all([Lw(e,t),Cc(e,"staged"),Cc(e,"unstaged"),_w(e)]);return[...r,...n,...s,...i]}async function Lw(e,t){if(!t)return[];let[r,n]=await Promise.all([C("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),C("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=Mc(r.stdout),i=Nc(n.stdout);return s.map(o=>{let a=i.get(o.path)??{additions:null,deletions:null};return{group:"branch",path:o.path,status:o.status,additions:a.additions,deletions:a.deletions}}).sort((o,a)=>o.path.localeCompare(a.path))}async function Cc(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([C("git",[...r,"--name-status"],{cwd:e}),C("git",[...r,"--numstat"],{cwd:e})]),i=Mc(n.stdout),o=Nc(s.stdout);return i.map(a=>{let l=o.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 _w(e){let t=await C("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=_c(t.stdout);return await Promise.all(r.map(async s=>{let i=await wn(e,s),o=i.status==="ready"?jw(i.lines):null;return{group:"untracked",path:s,status:"A",additions:o,deletions:0}}))}function Mc(e){return e.split(`
103
+ `).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 Nc(e){let t=new Map;for(let r of e.split(`
104
+ `)){let n=r.trim();if(!n)continue;let[s="-",i="-",...o]=n.split(" "),a=o.join(" ");a&&t.set(a,{additions:s==="-"?null:Number(s),deletions:i==="-"?null:Number(i)})}return t}async function kr(e){return(await $("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await $("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function wn(e,t){if(!t)return Z("No file selected","No Git-visible files found.","empty");let r=Fw(e,t);try{let n=await Dw(r);if(n.size>Ow)return Z(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await xw(r);return Ww(s)?Z(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
105
+ `),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return Z(t,s,"missing",t,null)}}async function Ki(e,t,r,n=null){if(!t)return Z("No diff selected","No local changes found.","empty");let s=[],i=r.filter(a=>a.path===t).map(a=>a.group);if(i.includes("branch")){let a=n??await kr(e);if(a){let l=await C("git",["diff","--stat","--patch",`--unified=${gn}`,`${a}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
106
+ ${l.stdout.trimEnd()}`)}}if(i.includes("staged")){let a=await C("git",["diff","--cached","--stat","--patch",`--unified=${gn}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`staged
107
+ ${a.stdout.trimEnd()}`)}if(i.includes("unstaged")){let a=await C("git",["diff","--stat","--patch",`--unified=${gn}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`unstaged
108
+ ${a.stdout.trimEnd()}`)}if(i.includes("untracked")){let a=await $("git",["diff","--no-index","--stat","--patch",`--unified=${gn}`,"--","/dev/null",t],{cwd:e});a.stdout.trim().length>0&&s.push(`untracked
109
+ ${a.stdout.trimEnd()}`)}let o=s.join(`
110
110
 
111
- `);return i.length>Sw?Q(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?Q(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(`
112
- `):["No diff for this file."],byteLength:i.length}}function xc(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 He(e,t){return e&&t.includes(e)?e:t[0]??null}function Ew(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function Dc(e){return[...new Set(e.split(`
113
- `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function xw(e,t){let r=Uo.resolve(e,t),n=Uo.resolve(e);if(r!==n&&!r.startsWith(`${n}${Uo.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function Dw(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function Q(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}var Ow=["tasks","center","inspector","actions"],Oc=["agent","terminal"],$c=[],D="inspection",lx=[...Oc,...$c],Vo=["commit","push","refresh-checks","close-task"],Nc=["refresh-checks","close-task"],Mc=["task","checks","pr","setup-run","actions","next-action"],Ko=["files","review"];function Lc(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=jw(e?.openInspectionKind)??r,s=h.runners.getEnabled(t);return{inputMode:Ww(e?.inputMode),focusedRegion:Lw(e?.focusedRegion),selectedRepoId:De(e?.selectedRepoId),selectedWorkspaceId:De(e?.selectedWorkspaceId),selectedTaskId:De(e?.selectedTaskId),selectedPtyTabId:De(e?.selectedPtyTabId),selectedLeftItemId:Gw(De(e?.selectedTaskId)),activeTab:r?D:De(e?.activeTab)??"agent",preferredPtyTabKind:Fw(e?.preferredPtyTabKind),inspectorSection:wr(e?.inspectorSection,Mc,"task"),inspectionMode:_w(e?.inspectionMode,r==="diff"?"review":"files"),openInspectionKind:n,selectedFileTreePath:De(e?.selectedFileTreePath),selectedFilePath:De(e?.selectedFilePath),selectedDiffPath:De(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:wr(e?.selectedActionId,Vo,"commit"),selectedProjectTargetId:null,selectedRunner:qw(e?.selectedRunner,s,h.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,fileSearchQuery:null,workspaceBrowser:null,terminal:$w(),centerZoomed:!1}}function $w(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function _c(e,t){return{...e??Dr(),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 kr(e,t,r={}){let n=Kw(e,t),s=Ho(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,...Uw(c,e.activeTab,e.selectedPtyTabId),selectedFilePath:Mw(e,t,c?.id??null),...Bw(e,t,c?.id??null),selectedDiffPath:Nw(e,t,c?.id??null),inspectorSection:wr(e.inspectorSection,Mc,"task")}}function Oe(e,t){return{...e,terminal:t}}function jc(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Fc(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function he(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
114
- `}function Wc(e){return e.length===1&&e>=" "&&e!=="\x7F"}function Go(e){return Uc(e)||Wt(e)!==null}function qc(e){return $c.includes(e)}function Uc(e){return Oc.includes(e)}function Bc(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[D]:[]]}function Nw(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function Mw(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function wr(e,t,r){return t.includes(e??"")?e:r}function Lw(e){return e==="tabs"?"center":wr(e,Ow,"tasks")}function _w(e,t){return e==="checks"||e==="actions"||e==="diff"||e==="review"?"review":wr(e,Ko,t)}function jw(e){return e==="file"||e==="diff"?e:null}function Fw(e){return e==="terminal"?"terminal":"agent"}function Ww(e){return e==="terminal"?"terminal":"control"}function qw(e,t=[...L],r="codex"){return e&&h.runners.isRunnerType(e)&&t.includes(e)?e:r}function gn(e,t=L){let r=t.length>0?t:L,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function Wt(e){let t=L.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Uw(e,t,r){if(!e)return{activeTab:t===D?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(Uc(t)){let l=e.ptyTabs.find(c=>c.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:l?.id??D,selectedPtyTabId:l?.id??null}}if(t===D)return{activeTab:D,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??D,selectedPtyTabId:i?.id??null}}function Bw(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?Vw(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function Vw(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 Kw(e,t){let r=mt(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 mt(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 Ho(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function De(e){return typeof e=="string"?e:null}function Gw(e){return e?`task:${e}`:null}function yr(e){return typeof e=="string"&&e.startsWith("task:")}function hn(e){return typeof e=="string"&&e.startsWith("new-task:")}function wn(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function Vc(e){return typeof e=="string"&&e.startsWith("workspace:")}function zo(e){return hn(e)?e.slice(9):null}function Yo(e){return wn(e)?e.slice(19):null}async function qt(e,t,r){let n=re(e),[s,o]=await Promise.all([J.repos.listRegisteredRepos(n),J.listWorkspaces(n,{archived:!1})]),i=await S.listTasks(n),a=Jo(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},c=a?await Pc(a,l):null;return{workspaceRoot:e,workspaces:o.workspaces,repos:s.repos,tasks:i.tasks,inspection:c,...r?{enabledRunnerIds:r}:{}}}function Jo(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function Kc(e,t){return kr(e,t)}import ii from"node:path";import wx from"picocolors";var Hw=[" \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 Xo(){return[...Hw]}var kn={width:120,height:36},W={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function le(e,t){return{width:Math.max(e??kn.width,kn.width),height:Math.max(t??kn.height,kn.height)}}var zw=["Start","Options","Exit"],Yw=["Resume","Options","Exit"],Tn=2,Rn=2,bn=2,Jw=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Xw=new RegExp("\x1B\\[(?:0)?m","g"),Qw=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),Zw=/https?:\/\/[^\s<>"']+/g,Zo="\x1B[0m",ei="\x1B]8;;\x1B\\",v={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"}},Qo=["3d59a1","506eb8","6386d0","7aa2f7","6386d0","506eb8"];function zc(e,t={}){return ri(e,{subtitle:"crAIg is that you?",menuItems:zw,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function Yc(e,t={}){return ri(e,{subtitle:"Control mode is paused.",menuItems:Yw,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var yn=[" 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."],ek=["Help"],tk=5;function vn(e,t={}){return ri(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??ek,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Jc(e,t={}){let r=t.color??!0,n=v.overlay,s=new Array(e.height).fill(U(" ".repeat(e.width),r,n)),o=Xo(),i=Math.max(1,Math.floor((e.height-o.length-2-yn.length)/2));for(let d=0;d<o.length&&!(i+d>=e.height);d+=1)s[i+d]=U(od(o[d]??"",e.width),r,v.overlayLogo);let a=Math.max(...yn.map(d=>d.length)),l=Math.max(0,Math.floor((e.width-a)/2)),c=i+o.length+2;for(let d=0;d<yn.length;d+=1){let u=c+d;if(u>=e.height)break;let m=yn[d]??"";s[u]=U(be(" ".repeat(l)+m,e.width),r,n)}return s.join(`
115
- `)}function Xc(e,t={}){let r=t.color??!0,n=v.overlay,s=new Array(e.height).fill(U(" ".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"},we(),...a.length>0?a.map(p=>({text:p})):[{text:"No Craig errors have been logged.",tone:"muted"}],we(),{text:"Esc returns to Options.",tone:"muted"}],u=Tr(d,e.height-2),m=Math.max(1,Math.floor((e.height-u.length)/2));for(let p=0;p<u.length;p+=1){let k=m+p;if(k>=e.height)break;let w=u[p]??we(),b=`${" ".repeat(c)}${In(w.text,l)}`,N=w.tone==="selected"?v.overlayMenuSelected:w.tone==="muted"?v.overlay:v.panelBg;s[k]=U(be(b,e.width),r,N)}return s.join(`
116
- `)}function Qc(e,t,r={}){let n=r.color??!0,s=W.leftWidth,o=W.rightWidth,i=r.centerOnly??!1,a=e.height-W.topRailHeight-1,l=r.focusFlashActive??!1,c={bg:v.divider.bg,fg:"9ece6a"},d=l&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?c:v.divider,u=l&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?c:v.divider,m=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,p=U(be(m,e.width),n,v.rail),k=nk(t,s-Tn-Rn,a,n),w=ti(e,t,{color:n,centerOnly:i}),b=ik(t,o,a,n),N=t.inputMode==="terminal",_=[],Y=[];for(let Pe=0;Pe<a;Pe+=1)if(!i){let Qe=Pn(k[Pe]??we(),s,n,"left"),vr=U("\u2502",n,d),Ir=U("\u2502",n,u),Cr=Pn(b[Pe]??we(),o,n,"right");_.push(`${Qe}${vr}`),Y.push(`${Ir}${Cr}`)}let I=N||t.modalInput?v.panelBg:v.panelMuted,ce=rk(t.footerText,t.footerToast,e.width,n,I),me={row:1,column:1,width:e.width,rows:[p]},de=i?null:{row:W.topRailHeight+1,column:1,width:s+W.dividerWidth,rows:_},wt=i?null:{row:W.topRailHeight+1,column:w.column+w.width,width:W.dividerWidth+o,rows:Y},g={row:e.height,column:1,width:e.width,rows:[ce]},Xe=i?w.rows:w.rows.map((Pe,Qe)=>`${_[Qe]??""}${Pe}${Y[Qe]??""}`);return{frame:[p,...Xe,ce].join(`
117
- `),center:w,regions:{rail:me,left:de,center:w,right:wt,footer:g}}}function ti(e,t,r={}){let n=r.color??!0,s=ed(e,r.centerOnly??!1),o=sk(t,s.width,s.rowCount,n);return{row:s.row,column:s.column,width:s.width,rows:o.map(i=>Pn(i,s.width,n,"center"))}}function Zc(e,t,r,n={}){let s=t.tabs.find(c=>c.active)?.id??"";if(!Go(s)||t.centerHeader.tabLabel==="BROWSER"||t.terminal.error||t.terminal.rows.length===0||r.some(c=>c<0||c>=t.terminal.rows.length))return null;let o=n.color??!0,i=ed(e,n.centerOnly??!1),a=td(t,i.width,o).length,l=[...new Set(r)].map(c=>({terminalIndex:c,index:a+c})).filter(({index:c})=>c<i.rowCount).map(({terminalIndex:c,index:d})=>({index:d,row:Pn(rd(t.terminal.rows[c]),i.width,o,"center")}));return{...i,rows:l}}function ed(e,t){return{row:W.topRailHeight+1,column:t?1:W.leftWidth+W.dividerWidth+1,width:t?e.width:e.width-W.leftWidth-W.rightWidth-W.dividerWidth*2,rowCount:e.height-W.topRailHeight-1}}function rk(e,t,r,n,s){let o=` ${e}`;if(!t)return U(be(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,a=oe(i),l=oe(o),c=Math.max(1,r-l-a-2),d=l+c+a+2>r?In(o,Math.max(0,r-a-3)):o,u=Math.max(1,r-oe(d)-a-2),m=t.tone==="error"?vk(i,n,s):Ut(i,n,s),p=`${d}${" ".repeat(u)}${m} `;return U(be(p,r),n,s)}function ri(e,t){let r=new Array(e.height).fill(U(" ".repeat(e.width),t.color,v.overlay)),n=Xo(),s=t.menuItems.map((c,d)=>`${d===t.menuIndex?">":" "} ${c}`),o=t.optionsMessage?["",t.optionsMessage]:[],i=[...s,...o];for(;i.length<tk;)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=od(a[c]??"",e.width);if(c<n.length){r[l+c]=U(d,t.color,v.overlayLogo);continue}if(c===n.length+1){r[l+c]=U(d,t.color,v.overlaySubtitle);continue}let u=c-(n.length+3),p=u>=0&&u<t.menuItems.length&&u===t.menuIndex?v.overlayMenuSelected:v.overlay;r[l+c]=U(d,t.color,p)}if(t.versionText){let c=t.updateText?" (update available)":"",d=`${t.versionText}${c} `,u=" ".repeat(Math.max(0,e.width-oe(d)));r[e.height-1]=U(`${u}${oi(d,t.color,v.overlay)}`,t.color,v.overlay)}return r.join(`
118
- `)}function nk(e,t,r,n){let s=ck(e.runners),o=1,i=e.leftTree.map(l=>lk(l,t,n));return[...Tr(i,r-o),s]}function sk(e,t,r,n){let s=e.tabs.find(i=>i.active)?.id??"agent",o=e.centerHeader.tabLabel==="BROWSER"||!Go(s)?e.centerTranscript.map(i=>({...i})):ok(e);return Tr([...td(e,t,n),...o],r)}function td(e,t,r){let n=t-2,s=e.tabs.find(b=>b.active)?.label??"AGENT",o=e.inputMode==="terminal"?0:bk(e.tabs),i=e.inputMode==="terminal"?n:s.length+1,a="\u2500".repeat(Math.max(0,i)),l=`${" ".repeat(o)}${e.inputMode==="terminal"?Ut(a,r,v.panelBg):Sn(a,r,v.panelMuted)}`,c=[`${Sn(e.centerHeader.tabLabel,r,v.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),d=dk(e.tabs,r,e.focusedRegion==="center"),u=" engaged ",m=u.length+2,p=e.inputMode==="terminal"?Ut(`${u}\u25CF `,r,v.panelBg):"",k=e.inputMode==="terminal"?" ".repeat(Math.max(0,n-oe(d)-m)):"";return[{text:e.inputMode==="terminal"?`${d}${k}${p}`:d},{text:l,tone:"muted"},{text:c},we()]}function ok(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},we(),{text:e.terminal.error},we(),{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(rd)}function rd(e){return{text:si(e.segments),segments:e.segments,fullBleed:!0}}function ik(e,t,r,n){let s=e.rightInspection?ak(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):Tr([{text:"CONTEXT"},we(),...e.rightContext.map(o=>uk(o,n)),...e.actionMessage?[we(),{text:e.actionMessage}]:[]],r);return Tr(s,r)}function ak(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:Sk(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(a=>Gc(a)),...n.slice(i,i+s).map(a=>Gc(a))]}function Gc(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 lk(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${Ut("\u25CF",r,e.selected?v.panelSelected:v.panelBg)}`:"",a=e.prBadge?e.prBadge.reduce((k,w)=>k+oe(w.text),0):0,l=t-oe(o)-oe(s)-a,c=e.activity?`${e.selected?"\u25B8":" "} \u25CF `:"",d=e.selected?e.text:e.focused?Ut(e.text,r,v.panelBg):e.panelHeader?Sn(e.text,r,v.panelMuted):e.text,u=be(`${n}${c}${d}`,Math.max(0,l)),m=e.selected?"selected":e.muted?"muted":"default";if(e.activity){let k=`${n}${e.selected?"\u25B8":" "} `,w=u.slice(k.length+2),b=[{text:k},nd(e.activity,e.activityAnimationFrame??0),{text:` ${w}${o}${i}`},...e.prBadge??[]];return{text:si(b),segments:b,tone:m}}if(e.prBadge){let k=[{text:`${u}${o}${i}`},...e.prBadge];return{text:`${u}${o}${e.prBadge.map(b=>b.text).join("")}`,segments:k,tone:m}}return{text:`${u}${o}${i}`,tone:m}}function ck(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:v.success.fg}}):r.push({text:s.text,style:{fg:v.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function dk(e,t,r){return e.map(n=>{let s=n.active?r?Ut(n.label,t,v.panelBg):Sn(n.label,t,v.panelBg):oi(n.label,t,v.panelBg),o=n.activity?ni(nd(n.activity,n.activityAnimationFrame??0),t,v.panelBg):"";return`${s}${o?` ${o}`:""}`}).join(" ")}function nd(e,t){return{text:"\u25CF",style:{fg:e==="working"?Qo[t%Qo.length]??Qo[0]:e==="ready"?v.success.fg:e==="error"?v.error.fg:v.panelMuted.fg}}}function uk(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?oi(e.value,t,v.panelBg):e.value}`}}function Pn(e,t,r,n){let s=pk(n,e.tone??"default"),o=mk(e,r,s);if(n==="left"){if(e.fullBleed)return U(be(o,t),r,s);let a=t-Tn-Rn;if(e.rightAlign){let c=oe(o),d=Math.max(0,a-c),u=`${" ".repeat(Tn)}${" ".repeat(d)}${o}${" ".repeat(Rn)}`;return U(u,r,s)}let l=`${" ".repeat(Tn)}${be(o,a)}${" ".repeat(Rn)}`;return U(l,r,s)}return n==="center"&&e.fullBleed?fk(e,t,r,s):U(be(` ${o}`,t),r,s)}function pk(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function Tr(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(we());return r}function we(){return{text:""}}function mk(e,t,r){return e.segments?e.segments.map(n=>ni(n,t,r)).join(""):e.text}function fk(e,t,r,n){let s=" ".repeat(bn),o=Math.max(0,t-bn*2);if(!e.segments)return U(`${s}${be(e.text,o)}${s}`,r,n);let i=wk(e.segments,o),a=`${s}${i.map(l=>ni(l,r,n)).join("")}${s}${r?ei:""}`;return U(a,r,n)}function ni(e,t,r){let n=e.href?`${sd(e.href)}${e.text}${ei}`:gk(e.text);return!t||!e.style?n:`${Rr(Tk(e.style,r))}${Rk(e.style)}${n}${Zo}${Rr(r)}`}function gk(e){return e.replace(Zw,t=>{let[r,n]=hk(t);return`${sd(r)}${r}${ei}${n}`})}function hk(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function sd(e){return`\x1B]8;;${e}\x1B\\`}function wk(e,t){let r=kk(e,t);return yk(r,t)}function kk(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=oe(s.text);if(o<=n){r.push(s),n-=o;continue}let i=In(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function yk(e,t){let r=oe(si(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 Tk(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 Rk(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 bk(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+(r.activity?2:0)+3}return 0}function od(e,t){let r=Math.max(0,t-oe(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function be(e,t){let r=oe(e);return r>=t?Pk(e,t):e+" ".repeat(t-r)}function Pk(e,t){if(t<=0)return"";if(oe(e)<=t)return e;let r=ad(e);return In(r,Math.max(0,t-1))+"\u2026"}function oe(e){let t=0;for(let r of Array.from(ad(e)))t+=id(r);return t}function In(e,t){let r="",n=0;for(let s of Array.from(e)){let o=id(s);if(n+o>t)break;r+=s,n+=o}return r}function id(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 Sk(e,t,r){return Math.min(Math.max(e,t),r)}function ad(e){return e.replace(Qw,"").replace(Jw,"")}function si(e){return e.map(t=>t.text).join("")}function U(e,t,r){if(!t)return e;let n=Rr(r),s=e.replace(Xw,`${Zo}${n}`);return`${n}${s}${Zo}`}function Rr(e){let t=[];return e.fg&&t.push(`38;2;${Hc(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Hc(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Hc(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function Ut(e,t,r){return Cn(e,t,v.success.fg,r)}function vk(e,t,r){return Cn(e,t,v.error.fg,r)}function Sn(e,t,r){return Cn(e,t,v.accent.fg,r)}function oi(e,t,r){return Cn(e,t,v.mutedfg.fg,r)}function Cn(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${Rr(s)}${e}${Rr(n)}`}function ld(e,t,r){let n=e.tasks.find(l=>l.ptyTabs.some(c=>c.id===t))??null,s=n?.ptyTabs.find(l=>l.id===t)??null,o=n?.worktreePath??r,i=s?.kind==="agent"?Ck(s):[],a=n?{CRAIG_WORKSPACE_ROOT:r,CRAIG_TASK_ID:n.id,...s?.kind==="agent"?{CRAIG_AGENT_TAB_ID:s.id}:{}}:{};return n?.type==="project"?{cwd:o,command:i,env:{...a,GIT_CEILING_DIRECTORIES:Ik(process.env.GIT_CEILING_DIRECTORIES,o)}}:n?{cwd:o,command:i,env:a}:{cwd:o,command:i}}function Ik(e,t){let r=(e??"").split(ii.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(ii.delimiter):[...r,t].join(ii.delimiter)}function Ck(e){return e.command.length>0?e.command:["codex"]}function cd(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 ze(e){return{columns:Math.max(20,e.width-W.leftWidth-W.rightWidth-W.dividerWidth-bn*2),rows:Math.max(5,e.height-W.topRailHeight-5)}}function dd(e){return e.length===1||he(e)||e==="BACKSPACE"||e==="TAB"}function Ye(e){return typeof e=="string"&&new RegExp(`:(?:agent|${L.join("|")})(?:-\\d+)?$`).test(e)}function ud(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 ai(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function pd(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 br(e){return fd.includes(e)?"SHIFT_ENTER":null}function li(e){return fd.some(t=>t.startsWith(e))}function md(e){return e==="ESCAPE"?"\x1B":e.length===1?e:null}var fd=["\x1B[13;2u","\x1B[13;2~","\x1B[27;2;13~","\x1B[27;2;10~"];function gd(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
111
+ `);return o.length>$w?Z(t,"Diff is above the 500 KB inline preview limit.","too_large",t,o.length):o.includes("\0")?Z(t,"Binary diff preview is not available in Craig.","binary",t,o.length):{path:t,status:o.length>0?"ready":"empty",title:t,lines:o.length>0?o.split(`
112
+ `):["No diff for this file."],byteLength:o.length}}function Lc(e){let t=[],r=new Set;for(let n of e){let s=n.split("/");for(let i=0;i<s.length-1;i+=1){let o=s.slice(0,i+1).join("/");r.has(o)||(r.add(o),t.push({kind:"directory",path:o,depth:i,label:s[i]??o}))}t.push({kind:"file",path:n,depth:s.length-1,label:s.at(-1)??n})}return t}function Je(e,t){return e&&t.includes(e)?e:t[0]??null}function jw(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function _c(e){return[...new Set(e.split(`
113
+ `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function Fw(e,t){let r=Bi.resolve(e,t),n=Bi.resolve(e);if(r!==n&&!r.startsWith(`${n}${Bi.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function Ww(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function Z(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}var qw=["tasks","center","inspector","actions"],jc=["agent","terminal"],Fc=[],D="inspection",Px=[...jc,...Fc],Gi=["commit","push","refresh-checks","close-task"],Wc=["refresh-checks","close-task"],qc=["task","checks","pr","setup-run","actions","next-action"],Hi=["files","review"];function Uc(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=Hw(e?.openInspectionKind)??r,s=w.runners.getEnabled(t);return{inputMode:Yw(e?.inputMode),focusedRegion:Kw(e?.focusedRegion),selectedRepoId:Me(e?.selectedRepoId),selectedWorkspaceId:Me(e?.selectedWorkspaceId),selectedTaskId:Me(e?.selectedTaskId),selectedPtyTabId:Me(e?.selectedPtyTabId),selectedLeftItemId:tk(Me(e?.selectedTaskId)),activeTab:r?D:Me(e?.activeTab)??"agent",preferredPtyTabKind:zw(e?.preferredPtyTabKind),inspectorSection:yr(e?.inspectorSection,qc,"task"),inspectionMode:Gw(e?.inspectionMode,r==="diff"?"review":"files"),openInspectionKind:n,selectedFileTreePath:Me(e?.selectedFileTreePath),selectedFilePath:Me(e?.selectedFilePath),selectedDiffPath:Me(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:yr(e?.selectedActionId,Gi,"commit"),selectedProjectTargetId:null,selectedRunner:Jw(e?.selectedRunner,s,w.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,fileSearchQuery:null,workspaceBrowser:null,terminal:Uw(),centerZoomed:!1}}function Uw(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function Vc(e,t){return{...e??Mr(),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 Tr(e,t,r={}){let n=ek(e,t),s=Yi(n),i=(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)??(i?.kind==="project"?t.repos.find(d=>d.id===e.selectedRepoId&&i.discoveredRepoIds?.includes(d.id))??null:null)??(i?.kind!=="project"?t.repos.find(d=>d.id===i?.primaryRepoId)??null:null)??t.repos.find(d=>d.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=i?t.tasks.filter(d=>d.workspaceId===i.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:i?.id??null,selectedRepoId:a,selectedTaskId:c?.id??null,...Xw(c,e.activeTab,e.selectedPtyTabId),selectedFilePath:Bw(e,t,c?.id??null),...Qw(e,t,c?.id??null),selectedDiffPath:Vw(e,t,c?.id??null),inspectorSection:yr(e.inspectorSection,qc,"task")}}function Ne(e,t){return{...e,terminal:t}}function Bc(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Kc(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function he(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
114
+ `}function Gc(e){return e.length===1&&e>=" "&&e!=="\x7F"}function zi(e){return zc(e)||qt(e)!==null}function Hc(e){return Fc.includes(e)}function zc(e){return jc.includes(e)}function Yc(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[D]:[]]}function Vw(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function Bw(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function yr(e,t,r){return t.includes(e??"")?e:r}function Kw(e){return e==="tabs"?"center":yr(e,qw,"tasks")}function Gw(e,t){return e==="checks"||e==="actions"||e==="diff"||e==="review"?"review":yr(e,Hi,t)}function Hw(e){return e==="file"||e==="diff"?e:null}function zw(e){return e==="terminal"?"terminal":"agent"}function Yw(e){return e==="terminal"?"terminal":"control"}function Jw(e,t=[..._],r="codex"){return e&&w.runners.isRunnerType(e)&&t.includes(e)?e:r}function kn(e,t=_){let r=t.length>0?t:_,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function qt(e){let t=_.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Xw(e,t,r){if(!e)return{activeTab:t===D?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,i=e.ptyTabs.find(a=>a.id===t)??null;if(i)return{activeTab:i.id,selectedPtyTabId:i.id};if(zc(t)){let l=e.ptyTabs.find(c=>c.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:l?.id??D,selectedPtyTabId:l?.id??null}}if(t===D)return{activeTab:D,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let o=s??n??e.ptyTabs[0]??null;return{activeTab:o?.id??D,selectedPtyTabId:o?.id??null}}function Qw(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?Zw(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function Zw(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 ek(e,t){let r=ht(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 ht(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 Yi(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 Me(e){return typeof e=="string"?e:null}function tk(e){return e?`task:${e}`:null}function Rr(e){return typeof e=="string"&&e.startsWith("task:")}function yn(e){return typeof e=="string"&&e.startsWith("new-task:")}function Tn(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function Jc(e){return typeof e=="string"&&e.startsWith("workspace:")}function Ji(e){return yn(e)?e.slice(9):null}function Xi(e){return Tn(e)?e.slice(19):null}async function Ut(e,t,r){let n=ne(e),[s,i]=await Promise.all([X.repos.listRegisteredRepos(n),X.listWorkspaces(n,{archived:!1})]),o=await P.listTasks(n),a=Qi(o.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},c=a?await Ec(a,l):null;return{workspaceRoot:e,workspaces:i.workspaces,repos:s.repos,tasks:o.tasks,inspection:c,...r?{enabledRunnerIds:r}:{}}}function Qi(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function Xc(e,t){return Tr(e,t)}import lo from"node:path";import Ox from"picocolors";var rk=[" \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 Zi(){return[...rk]}var Rn={width:120,height:36},F={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function ce(e,t){return{width:Math.max(e??Rn.width,Rn.width),height:Math.max(t??Rn.height,Rn.height)}}var nk=["Start","Options","Exit"],sk=["Resume","Options","Exit"],Pn=2,Sn=2,vn=2,ik=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),ok=new RegExp("\x1B\\[(?:0)?m","g"),ak=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),lk=/https?:\/\/[^\s<>"']+/g,to="\x1B[0m",ro="\x1B]8;;\x1B\\",v={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"}},eo=["3d59a1","506eb8","6386d0","7aa2f7","6386d0","506eb8"];function ed(e,t={}){return so(e,{subtitle:"crAIg is that you?",menuItems:nk,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function td(e,t={}){return so(e,{subtitle:"Control mode is paused.",menuItems:sk,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var bn=[" 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."],ck=["Help"],dk=5;function An(e,t={}){return so(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??ck,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function rd(e,t={}){let r=t.color??!0,n=v.overlay,s=new Array(e.height).fill(V(" ".repeat(e.width),r,n)),i=Zi(),o=Math.max(1,Math.floor((e.height-i.length-2-bn.length)/2));for(let d=0;d<i.length&&!(o+d>=e.height);d+=1)s[o+d]=V(ud(i[d]??"",e.width),r,v.overlayLogo);let a=Math.max(...bn.map(d=>d.length)),l=Math.max(0,Math.floor((e.width-a)/2)),c=o+i.length+2;for(let d=0;d<bn.length;d+=1){let u=c+d;if(u>=e.height)break;let f=bn[d]??"";s[u]=V(be(" ".repeat(l)+f,e.width),r,n)}return s.join(`
115
+ `)}function nd(e,t={}){let r=t.color??!0,n=v.overlay,s=new Array(e.height).fill(V(" ".repeat(e.width),r,n)),i="Error Log",o=t.errorLogPath??"",a=t.errorLogLines??[],l=Math.max(20,e.width-8),c=Math.max(0,Math.floor((e.width-l)/2)),d=[{text:i,tone:"selected"},{text:o,tone:"muted"},we(),...a.length>0?a.map(h=>({text:h})):[{text:"No Craig errors have been logged.",tone:"muted"}],we(),{text:"Esc returns to Options.",tone:"muted"}],u=br(d,e.height-2),f=Math.max(1,Math.floor((e.height-u.length)/2));for(let h=0;h<u.length;h+=1){let m=f+h;if(m>=e.height)break;let k=u[h]??we(),b=`${" ".repeat(c)}${En(k.text,l)}`,O=k.tone==="selected"?v.overlayMenuSelected:k.tone==="muted"?v.overlay:v.panelBg;s[m]=V(be(b,e.width),r,O)}return s.join(`
116
+ `)}function sd(e,t,r={}){let n=r.color??!0,s=F.leftWidth,i=F.rightWidth,o=r.centerOnly??!1,a=e.height-F.topRailHeight-1,l=r.focusFlashActive??!1,c={bg:v.divider.bg,fg:"9ece6a"},d=l&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?c:v.divider,u=l&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?c:v.divider,f=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,h=V(be(f,e.width),n,v.rail),m=pk(t,s-Pn-Sn,a,n),k=no(e,t,{color:n,centerOnly:o}),b=gk(t,i,a,n),O=t.inputMode==="terminal",q=[],U=[];for(let Pe=0;Pe<a;Pe+=1)if(!o){let yt=In(m[Pe]??we(),s,n,"left"),Ar=V("\u2502",n,d),Er=V("\u2502",n,u),xr=In(b[Pe]??we(),i,n,"right");q.push(`${yt}${Ar}`),U.push(`${Er}${xr}`)}let I=O||t.modalInput?v.panelBg:v.panelMuted,te=uk(t.footerText,t.footerToast,e.width,n,I),je={row:1,column:1,width:e.width,rows:[h]},de=o?null:{row:F.topRailHeight+1,column:1,width:s+F.dividerWidth,rows:q},ye=o?null:{row:F.topRailHeight+1,column:k.column+k.width,width:F.dividerWidth+i,rows:U},p={row:e.height,column:1,width:e.width,rows:[te]},rt=o?k.rows:k.rows.map((Pe,yt)=>`${q[yt]??""}${Pe}${U[yt]??""}`);return{frame:[h,...rt,te].join(`
117
+ `),center:k,regions:{rail:je,left:de,center:k,right:ye,footer:p}}}function no(e,t,r={}){let n=r.color??!0,s=od(e,r.centerOnly??!1),i=mk(t,s.width,s.rowCount,n);return{row:s.row,column:s.column,width:s.width,rows:i.map(o=>In(o,s.width,n,"center"))}}function id(e,t,r,n={}){let s=t.tabs.find(c=>c.active)?.id??"";if(!zi(s)||t.centerHeader.tabLabel==="BROWSER"||t.terminal.error||t.terminal.rows.length===0||r.some(c=>c<0||c>=t.terminal.rows.length))return null;let i=n.color??!0,o=od(e,n.centerOnly??!1),a=ad(t,o.width,i).length,l=[...new Set(r)].map(c=>({terminalIndex:c,index:a+c})).filter(({index:c})=>c<o.rowCount).map(({terminalIndex:c,index:d})=>({index:d,row:In(ld(t.terminal.rows[c]),o.width,i,"center")}));return{...o,rows:l}}function od(e,t){return{row:F.topRailHeight+1,column:t?1:F.leftWidth+F.dividerWidth+1,width:t?e.width:e.width-F.leftWidth-F.rightWidth-F.dividerWidth*2,rowCount:e.height-F.topRailHeight-1}}function uk(e,t,r,n,s){let i=` ${e}`;if(!t)return V(be(i,r),n,s);let o=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,a=oe(o),l=oe(i),c=Math.max(1,r-l-a-2),d=l+c+a+2>r?En(i,Math.max(0,r-a-3)):i,u=Math.max(1,r-oe(d)-a-2),f=t.tone==="error"?Mk(o,n,s):Vt(o,n,s),h=`${d}${" ".repeat(u)}${f} `;return V(be(h,r),n,s)}function so(e,t){let r=new Array(e.height).fill(V(" ".repeat(e.width),t.color,v.overlay)),n=Zi(),s=t.menuItems.map((c,d)=>`${d===t.menuIndex?">":" "} ${c}`),i=t.optionsMessage?["",t.optionsMessage]:[],o=[...s,...i];for(;o.length<dk;)o.push("");let a=[...n,"",t.subtitle,"",...o],l=Math.max(1,Math.floor((e.height-a.length)/2));for(let c=0;c<a.length;c+=1){let d=ud(a[c]??"",e.width);if(c<n.length){r[l+c]=V(d,t.color,v.overlayLogo);continue}if(c===n.length+1){r[l+c]=V(d,t.color,v.overlaySubtitle);continue}let u=c-(n.length+3),h=u>=0&&u<t.menuItems.length&&u===t.menuIndex?v.overlayMenuSelected:v.overlay;r[l+c]=V(d,t.color,h)}if(t.versionText){let c=t.updateText?" (update available)":"",d=`${t.versionText}${c} `,u=" ".repeat(Math.max(0,e.width-oe(d)));r[e.height-1]=V(`${u}${ao(d,t.color,v.overlay)}`,t.color,v.overlay)}return r.join(`
118
+ `)}function pk(e,t,r,n){let s=kk(e.runners),i=1,o=e.leftTree.map(l=>wk(l,t,n));return[...br(o,r-i),s]}function mk(e,t,r,n){let s=e.tabs.find(o=>o.active)?.id??"agent",i=e.centerHeader.tabLabel==="BROWSER"||!zi(s)?e.centerTranscript.map(o=>({...o})):fk(e);return br([...ad(e,t,n),...i],r)}function ad(e,t,r){let n=t-2,s=e.tabs.find(b=>b.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:Dk(e.tabs),o=e.inputMode==="terminal"?n:s.length+1,a="\u2500".repeat(Math.max(0,o)),l=`${" ".repeat(i)}${e.inputMode==="terminal"?Vt(a,r,v.panelBg):Cn(a,r,v.panelMuted)}`,c=[`${Cn(e.centerHeader.tabLabel,r,v.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),d=yk(e.tabs,r,e.focusedRegion==="center"),u=" engaged ",f=u.length+2,h=e.inputMode==="terminal"?Vt(`${u}\u25CF `,r,v.panelBg):"",m=e.inputMode==="terminal"?" ".repeat(Math.max(0,n-oe(d)-f)):"";return[{text:e.inputMode==="terminal"?`${d}${m}${h}`:d},{text:l,tone:"muted"},{text:c},we()]}function fk(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},we(),{text:e.terminal.error},we(),{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(ld)}function ld(e){return{text:oo(e.segments),segments:e.segments,fullBleed:!0}}function gk(e,t,r,n){let s=e.rightInspection?hk(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):br([{text:"CONTEXT"},we(),...e.rightContext.map(i=>Tk(i,n)),...e.actionMessage?[we(),{text:e.actionMessage}]:[]],r);return br(s,r)}function hk(e,t){let r=e.slice(0,2),n=e.slice(2),s=Math.max(0,t-r.length),i=n.findIndex(a=>a.focused||a.selected),o=i===-1?0:$k(i-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(a=>Qc(a)),...n.slice(o,o+s).map(a=>Qc(a))]}function Qc(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(" "),i=s===-1?e.text:e.text.slice(0,s),o=s===-1?"":e.text.slice(s);return{text:n,segments:[{text:t},{text:i,style:{fg:"7aa2f7"}},{text:o}],tone:r}}return e.color?{text:n,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:r}:{text:n,tone:r}}function wk(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",i=e.status?` ${e.status}`:"",o=e.accentDot?` ${Vt("\u25CF",r,e.selected?v.panelSelected:v.panelBg)}`:"",a=e.prBadge?e.prBadge.reduce((m,k)=>m+oe(k.text),0):0,l=t-oe(i)-oe(s)-a,c=e.activity?`${e.selected?"\u25B8":" "} \u25CF `:"",d=e.selected?e.text:e.focused?Vt(e.text,r,v.panelBg):e.panelHeader?Cn(e.text,r,v.panelMuted):e.text,u=be(`${n}${c}${d}`,Math.max(0,l)),f=e.selected?"selected":e.muted?"muted":"default";if(e.activity){let m=`${n}${e.selected?"\u25B8":" "} `,k=u.slice(m.length+2),b=[{text:m},cd(e.activity,e.activityAnimationFrame??0),{text:` ${k}${i}${o}`},...e.prBadge??[]];return{text:oo(b),segments:b,tone:f}}if(e.prBadge){let m=[{text:`${u}${i}${o}`},...e.prBadge];return{text:`${u}${i}${e.prBadge.map(b=>b.text).join("")}`,segments:m,tone:f}}return{text:`${u}${i}${o}`,tone:f}}function kk(e){let t=e.map(n=>{let s=n.health>=1,i=parseInt(n.count,10),o=i>1?` (${i})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${n.name}${o}`,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:v.success.fg}}):r.push({text:s.text,style:{fg:v.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function yk(e,t,r){return e.map(n=>{let s=n.active?r?Vt(n.label,t,v.panelBg):Cn(n.label,t,v.panelBg):ao(n.label,t,v.panelBg),i=n.activity?io(cd(n.activity,n.activityAnimationFrame??0),t,v.panelBg):"";return`${s}${i?` ${i}`:""}`}).join(" ")}function cd(e,t){return{text:"\u25CF",style:{fg:e==="working"?eo[t%eo.length]??eo[0]:e==="ready"?v.success.fg:e==="error"?v.error.fg:v.panelMuted.fg}}}function Tk(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?ao(e.value,t,v.panelBg):e.value}`}}function In(e,t,r,n){let s=Rk(n,e.tone??"default"),i=bk(e,r,s);if(n==="left"){if(e.fullBleed)return V(be(i,t),r,s);let a=t-Pn-Sn;if(e.rightAlign){let c=oe(i),d=Math.max(0,a-c),u=`${" ".repeat(Pn)}${" ".repeat(d)}${i}${" ".repeat(Sn)}`;return V(u,r,s)}let l=`${" ".repeat(Pn)}${be(i,a)}${" ".repeat(Sn)}`;return V(l,r,s)}return n==="center"&&e.fullBleed?Pk(e,t,r,s):V(be(` ${i}`,t),r,s)}function Rk(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function br(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(we());return r}function we(){return{text:""}}function bk(e,t,r){return e.segments?e.segments.map(n=>io(n,t,r)).join(""):e.text}function Pk(e,t,r,n){let s=" ".repeat(vn),i=Math.max(0,t-vn*2);if(!e.segments)return V(`${s}${be(e.text,i)}${s}`,r,n);let o=Ik(e.segments,i),a=`${s}${o.map(l=>io(l,r,n)).join("")}${s}${r?ro:""}`;return V(a,r,n)}function io(e,t,r){let n=e.href?`${dd(e.href)}${e.text}${ro}`:Sk(e.text);return!t||!e.style?n:`${Pr(Ek(e.style,r))}${xk(e.style)}${n}${to}${Pr(r)}`}function Sk(e){return e.replace(lk,t=>{let[r,n]=vk(t);return`${dd(r)}${r}${ro}${n}`})}function vk(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function dd(e){return`\x1B]8;;${e}\x1B\\`}function Ik(e,t){let r=Ck(e,t);return Ak(r,t)}function Ck(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let i=oe(s.text);if(i<=n){r.push(s),n-=i;continue}let o=En(s.text,n);o.length>0&&r.push({...s,text:o}),n=0}return r}function Ak(e,t){let r=oe(oo(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 Ek(e,t){let r=e.inverse?e.bg??t.bg:e.fg,n=e.inverse?e.fg??t.fg:e.bg,s={},i=r??t.fg,o=n??t.bg;return i&&(s.fg=i),o&&(s.bg=o),s}function xk(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 Dk(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+(r.activity?2:0)+3}return 0}function ud(e,t){let r=Math.max(0,t-oe(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function be(e,t){let r=oe(e);return r>=t?Ok(e,t):e+" ".repeat(t-r)}function Ok(e,t){if(t<=0)return"";if(oe(e)<=t)return e;let r=md(e);return En(r,Math.max(0,t-1))+"\u2026"}function oe(e){let t=0;for(let r of Array.from(md(e)))t+=pd(r);return t}function En(e,t){let r="",n=0;for(let s of Array.from(e)){let i=pd(s);if(n+i>t)break;r+=s,n+=i}return r}function pd(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 $k(e,t,r){return Math.min(Math.max(e,t),r)}function md(e){return e.replace(ak,"").replace(ik,"")}function oo(e){return e.map(t=>t.text).join("")}function V(e,t,r){if(!t)return e;let n=Pr(r),s=e.replace(ok,`${to}${n}`);return`${n}${s}${to}`}function Pr(e){let t=[];return e.fg&&t.push(`38;2;${Zc(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Zc(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Zc(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function Vt(e,t,r){return xn(e,t,v.success.fg,r)}function Mk(e,t,r){return xn(e,t,v.error.fg,r)}function Cn(e,t,r){return xn(e,t,v.accent.fg,r)}function ao(e,t,r){return xn(e,t,v.mutedfg.fg,r)}function xn(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${Pr(s)}${e}${Pr(n)}`}function fd(e,t,r){let n=e.tasks.find(l=>l.ptyTabs.some(c=>c.id===t))??null,s=n?.ptyTabs.find(l=>l.id===t)??null,i=n?.worktreePath??r,o=s?.kind==="agent"?Lk(s):[],a=n?{CRAIG_WORKSPACE_ROOT:r,CRAIG_TASK_ID:n.id,...s?.kind==="agent"?{CRAIG_AGENT_TAB_ID:s.id}:{}}:{};return n?.type==="project"?{cwd:i,command:o,env:{...a,GIT_CEILING_DIRECTORIES:Nk(process.env.GIT_CEILING_DIRECTORIES,i)}}:n?{cwd:i,command:o,env:a}:{cwd:i,command:o}}function Nk(e,t){let r=(e??"").split(lo.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(lo.delimiter):[...r,t].join(lo.delimiter)}function Lk(e){return e.command.length>0?e.command:["codex"]}function gd(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 Xe(e){return{columns:Math.max(20,e.width-F.leftWidth-F.rightWidth-F.dividerWidth-vn*2),rows:Math.max(5,e.height-F.topRailHeight-5)}}function hd(e){return e.length===1||he(e)||e==="BACKSPACE"||e==="TAB"}function Qe(e){return typeof e=="string"&&new RegExp(`:(?:agent|${_.join("|")})(?:-\\d+)?$`).test(e)}function wd(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 co(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function kd(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 Sr(e){return Td.includes(e)?"SHIFT_ENTER":null}function uo(e){return Td.some(t=>t.startsWith(e))}function yd(e){return e==="ESCAPE"?"\x1B":e.length===1?e:null}var Td=["\x1B[13;2u","\x1B[13;2~","\x1B[27;2;13~","\x1B[27;2;10~"];function Rd(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
119
119
  `||r===`\r
120
- `)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function hd(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function wd(e,t=null){let r=t?.split(`
120
+ `)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function bd(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Pd(e,t=null){let r=t?.split(`
121
121
  `)??[];return e.split(`
122
- `).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function An(e,t,r,n){return e.map((s,o)=>t?.[o]===s?"":`\x1B[${r+o};${n}H${s}`).join("")}import{spawn as iy}from"node:child_process";import{createServer as ay,createConnection as Ed}from"node:net";import{openSync as ly}from"node:fs";import{mkdir as cy,readFile as yi,rm as gt,writeFile as dy}from"node:fs/promises";import On from"node:path";var Bt=class{jobs=new Map;resolutionMs;now;onError;timer=null;abortController=null;constructor(t){this.resolutionMs=ci(t.resolutionMs??1e3,"Heartbeat resolution"),this.now=t.now??Date.now,this.onError=t.onError}register(t){if(this.jobs.has(t.id))throw new Error(`Heartbeat job "${t.id}" is already registered.`);let r={...t,intervalMs:ci(t.intervalMs,`Heartbeat job "${t.id}" interval`),inFlight:!1,nextRunAt:this.timer?this.now()+t.intervalMs:null};this.jobs.set(t.id,r)}start(){if(this.timer)return;let t=this.now();for(let r of this.jobs.values())r.nextRunAt=t+r.intervalMs;this.abortController=new AbortController,this.timer=setInterval(()=>this.tick(),this.resolutionMs)}stop(){this.abortController?.abort(),this.abortController=null,this.timer&&clearInterval(this.timer),this.timer=null;for(let t of this.jobs.values())t.nextRunAt=null}setResolutionMs(t){let r=ci(t,"Heartbeat resolution");r!==this.resolutionMs&&(this.resolutionMs=r,this.timer&&(clearInterval(this.timer),this.timer=setInterval(()=>this.tick(),this.resolutionMs)))}tick(){let t=this.abortController?.signal;if(!t)return;let r=this.now();for(let n of this.jobs.values())n.inFlight||n.nextRunAt===null||r<n.nextRunAt||(n.inFlight=!0,n.nextRunAt=r+n.intervalMs,Promise.resolve().then(()=>n.run(t)).catch(s=>{if(!t.aborted)return Promise.resolve(this.onError(n.id,s)).catch(()=>{})}).finally(()=>{n.inFlight=!1}))}};function ci(e,t){if(!Number.isFinite(e)||e<=0)throw new Error(`${t} must be a positive number.`);return e}import{mkdir as kd,readFile as Ak,rm as di,stat as Ek,writeFile as xk}from"node:fs/promises";import ui from"node:path";async function pi(e){let t=ui.join(e.runtimeDir,"orchestration-supervisor.lock");await kd(e.runtimeDir,{recursive:!0});try{await kd(t)}catch(n){if(!Ok(n))throw n;let s=await Ak(ui.join(t,"owner.json"),"utf8").then(i=>JSON.parse(i)).catch(()=>null),o=await Ek(t).catch(()=>null);if(typeof s?.pid=="number"&&!Dk(s.pid)||!s&&o&&Date.now()-o.mtimeMs>=5e3)return await di(t,{recursive:!0,force:!0}),pi(e);throw new f("COMMAND_STATE_CONFLICT","Another orchestration supervisor already leads this workspace.",{details:{ownerPid:s?.pid??null}})}try{await xk(ui.join(t,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(n){throw await di(t,{recursive:!0,force:!0}),n}let r=!1;return{async release(){r||(r=!0,await di(t,{recursive:!0,force:!0}))}}}function Dk(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var Ok=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST";function yd(e,t){switch(e){case"codex":case"cursor":case"claude":return`\x1B[200~${t}\x1B[201~\r`;default:return $k(e)}}function $k(e){throw new Error(`Unsupported prompt-delivery runner: ${String(e)}`)}import Nk from"node:path";var Mk={type:"system",component:"orchestration-supervisor"};async function Td(e){let t=Nk.join(e.orchestrationDir,"command-event-reconciliation.json"),r=await Er(t)??{version:1,commands:{}},n=await xe(e),s=!1;for(let o of n){let i=new Set(r.commands[o.id]??[]);for(let a of Lk(o))i.has(a)||(await dt(e,o,a,a==="command.queued"?o.actor:a==="command.cancelled"?o.cancelledBy??o.actor:Mk),i.add(a),s=!0);r.commands[o.id]=[...i]}s&&await M(t,r)}function Lk(e){let t=["command.queued"];return e.attempts>0&&t.push("command.delivering"),e.state==="delivered"?t.push("command.delivered"):e.state==="failed"?t.push("command.failed"):e.state==="cancelled"&&t.push("command.cancelled"),t}var En=class{constructor(t,r,n={}){this.paths=t;this.runtime=r;let s=n.intervalMs??250;this.heartbeat=new Bt({resolutionMs:s,onError:(o,i)=>n.onError?.(i)}),this.heartbeat.register({id:"orchestration.commands",intervalMs:s,run:()=>this.reconcile()})}paths;runtime;heartbeat;lease=null;reconciliation=null;async start(){if(!this.lease){this.lease=await pi(this.paths);try{await this.reconcile(),this.heartbeat.start()}catch(t){throw await this.lease.release(),this.lease=null,t}}}async wake(){await this.reconcile()}async stop(){this.heartbeat.stop(),await this.reconciliation?.catch(()=>{}),await this.lease?.release(),this.lease=null}reconcile(){return this.reconciliation?this.reconciliation:(this.reconciliation=this.reconcileCommands().finally(()=>{this.reconciliation=null}),this.reconciliation)}async reconcileCommands(){await Td(this.paths);let t=await xe(this.paths);for(let r of t){if(r.state==="delivering"){await se.fail(this.paths,r.id,Pr("PROMPT_DELIVERY_UNCERTAIN","Craig resumed after prompt delivery began; the prompt was not replayed.",!1,!0));continue}r.state==="queued"&&await this.reconcileCommand(r)}}async reconcileCommand(t){if(Date.now()>=Date.parse(t.expiresAt)){await se.fail(this.paths,t.id,Pr("PROMPT_DELIVERY_TIMEOUT",`Prompt delivery timed out after ${t.timeoutMs}ms.`,!1,!1));return}let r=await S.getTask(this.paths,t.taskId).catch(o=>{if(o instanceof f&&o.code==="TASK_NOT_FOUND")return null;throw o}),n=r?.ptyTabs.find(o=>o.id===t.agentTabId);if(!r||!n||n.kind!=="agent"||r.status==="closed"){await se.fail(this.paths,t.id,Pr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer available in task ${t.taskId}.`,!1,!1));return}let s=this.runtime.getActivitySnapshots().find(o=>o.tabId===t.agentTabId);if(s&&s.sessionState!=="running"){await se.fail(this.paths,t.id,Pr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer running.`,!1,!1));return}if(this.runtime.hasRunningSession(t.agentTabId)&&!(t.delivery==="when-ready"&&Ve(r,t.agentTabId,this.runtime.getActivitySnapshots(),Date.now())!=="ready")){await se.beginDelivery(this.paths,t.id);try{this.runtime.writeToSession(t.agentTabId,yd(n.runner??r.runner,t.prompt.text))}catch(o){await se.fail(this.paths,t.id,Pr("PROMPT_DELIVERY_UNCERTAIN",o instanceof Error?o.message:"Prompt delivery failed after it began.",!1,!0));return}await se.completeDelivery(this.paths,t.id)}}},Pr=(e,t,r,n)=>({code:e,message:t,retryable:r,deliveryUncertain:n});import{createRequire as Gk}from"node:module";import _k from"@xterm/headless";var jk=1e3,Fk=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function bd(e){return new _k.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:jk,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function Pd(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function fi(e,t){return new Promise(r=>{e.write(t,r)})}function Sd(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:Uk(u,i+a===o&&d===r.cursorX)})}n.push({segments:Wk(qk(c))})}return n}function Wk(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&Kk(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};vd(r.style)||(s.style=r.style),t.push(s)}return t}function qk(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!vd(r.style))break;t-=1}return e.slice(0,t)}function Uk(e,t){let r={},n=Rd(e,"fg"),s=Rd(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 Rd(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"):Fk[s]??Bk(s)}function Bk(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(Vk).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 Vk(e){return e===0?0:55+e*40}function Kk(e,t){return mi(e)===mi(t)}function mi(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function vd(e){return mi(e)===""}var Hk=Gk(import.meta.url),zk=/^CTRL_([A-Z])$/,Yk="\x1B[6n",Jk="\x1B[c",Xk="\x1B[?u",Qk={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
123
- `,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:""},xn=class{sessions=new Map;activitySnapshots=new Map;shell;env;spawn;onUpdate;onActivity;onActivityRemoved;activityEnabled;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.onActivity=t.onActivity,this.onActivityRemoved=t.onActivityRemoved,this.activityEnabled=t.activityEnabled??!0,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")gi(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,Id(o,n),this.getViewState(r);let i;try{i=this.createSession(t,r,n,s)}catch(a){throw this.recordActivity({taskId:t,tabId:r,sessionState:"failed",lastActivityAt:Date.now(),exitCode:null,error:a instanceof Error?a.message:String(a)}),a}return this.sessions.set(r,i),this.notifyActivity(i),this.attachedTabId=r,this.getViewState(r)}write(t){let r=this.getAttachedSession();!r||r.status!=="running"||(r.pty.write(t),(t.includes("\r")||t.includes(`
124
- `))&&this.touchActivity(r))}writeKey(t){let r=Zk(t);r!==null&&this.write(r)}hasRunningSession(t){return this.sessions.get(t)?.status==="running"}writeToSession(t,r){let n=this.sessions.get(t);if(!n||n.status!=="running")throw new Error(`Agent tab ${t} is not running.`);n.pty.write(r),this.touchActivity(n)}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&&Id(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}getActivitySnapshots(){return[...this.activitySnapshots.values()]}setActivityEnabled(t){if(this.activityEnabled!==t&&(this.activityEnabled=t,!!t))for(let r of this.sessions.values())this.notifyActivity(r)}disposeSession(t){let r=this.sessions.get(t);r&&(gi(r),this.sessions.delete(t)),this.removeActivity(t),this.attachedTabId===t&&(this.attachedTabId=null)}disposeAll(){for(let t of this.sessions.values())gi(t);this.sessions.clear();for(let t of this.activitySnapshots.keys())this.onActivityRemoved?.(t);this.activitySnapshots.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:ey(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??ry().spawn,i=bd(n),a=s??this.resolveSessionSpec(t,r),l=it({...this.env,...a.env??{}}),{executable:c,args:d}=ny(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:sy(l)}),m={taskId:t,tabId:r,pty:u,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0,rows:[],renderedScrollbackLines:null,screenDirty:!0,lastActivityAt:Date.now(),exitCode:null};return m.disposables.push(u.onData(p=>{this.touchActivity(m),oy(u,p),fi(m.terminal,p).then(()=>{m.screenDirty=!0,this.onUpdate?.({tabId:m.tabId,kind:"full"})})})),m.disposables.push(u.onExit(p=>{m.status="exited",m.exitCode=p.exitCode,m.lastActivityAt=Date.now(),this.notifyActivity(m),fi(m.terminal,`\r
125
- [process exited ${p.exitCode}]`).then(()=>{m.screenDirty=!0,this.onUpdate?.({tabId:m.tabId,kind:"full"})})})),m}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}touchActivity(t){t.lastActivityAt=Date.now(),this.activityEnabled&&this.notifyActivity(t)}notifyActivity(t){this.activityEnabled&&this.recordActivity(this.buildActivitySnapshot(t))}recordActivity(t){this.activityEnabled&&(this.activitySnapshots.set(t.tabId,t),this.onActivity?.(t))}removeActivity(t){this.activitySnapshots.delete(t)&&this.onActivityRemoved?.(t)}buildActivitySnapshot(t){return{taskId:t.taskId,tabId:t.tabId,sessionState:t.status==="failed"?"failed":t.status==="exited"?"exited":"running",lastActivityAt:t.lastActivityAt,exitCode:t.exitCode,error:t.error}}};function Zk(e){if(e.length===1)return e;let t=Qk[e];if(t!==void 0)return t;let r=zk.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function Id(e,t){ty(e.pty,t),Pd(e.terminal,t),e.screenDirty=!0}function ey(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=Sd(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function gi(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function ty(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function ry(){return Hk("node-pty")}function ny(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[at(t[0],r),...t.slice(1)].map(Cd).join(" ")}; exec ${Cd(e)} -l`;return{executable:e,args:["-lc",s]}}function Cd(e){return`'${e.replaceAll("'","'\\''")}'`}function sy(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 oy(e,t){for(let r=0;r<hi(t,Yk);r+=1)e.write("\x1B[1;1R");for(let r=0;r<hi(t,Jk);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<hi(t,Xk);r+=1)e.write("\x1B[?0u")}function hi(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 xd=Nt,uy=new Set([xd]),py=16,my=250;async function Dd(e){let t=Ke(e.paths);await wy(t,e.paths,e.spawnDaemon);let r=await jd(t.socketPath),n=new wi(r,e);return await n.ready(),n}async function Od(e,t={}){let r=Ke(e);await cy(e.runtimeDir,{recursive:!0}),await gt(r.socketPath,{force:!0});let n=new ki(e,t),s=ay(o=>n.handleConnection(o));try{await n.start(),await Py(s,r.socketPath),await dy(r.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,n.closeClients(),s.close(()=>{process.removeListener("SIGTERM",a),process.removeListener("SIGINT",a),o()}))};n.onShutdown=a,process.once("SIGTERM",a),process.once("SIGINT",a)})}finally{n.onShutdown=null,await gt(r.socketPath,{force:!0}),await gt(r.pidPath,{force:!0}),await n.stop(),n.disposeAll()}}async function $d(e){let t=Ke(e);return await $n(t.socketPath)?(await Ld(t.socketPath),!0):!1}var wi=class{constructor(t,r){this.socket=t;this.options=r,this.viewUpdateMode=r.viewUpdateMode??"snapshot",this.activityEnabled=r.activityEnabled??!1,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||(this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed.")),this.failRunningActivities("Craig PTY daemon connection closed."))})}socket;nextRequestId=1;pending=new Map;viewCache=new Map;activityCache=new Map;activityRevisionByTabId=new Map;activityRevision=0;attachedTabId=null;viewedTabId=null;subscribedTabId=null;viewUpdateMode;activityEnabled;buffer="";closed=!1;options;async ready(){let t=await this.send({type:"ping"});if(!Md(t.protocolVersion))throw new Error("Craig PTY daemon protocol mismatch.");await this.send({type:"setViewUpdateMode",mode:this.viewUpdateMode}),await this.send({type:"setActivityEnabled",enabled:this.activityEnabled}),this.activityEnabled&&await this.refreshActivitySnapshots()}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})}this.activityEnabled&&await this.refreshActivitySnapshots()}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){let r=this.attachedTabId;this.send({type:"scrollViewport",lines:t}).then(n=>{r&&n.view&&(this.viewCache.set(r,n.view),this.notifyFullUpdate(r))}).catch(()=>{})}resize(t){let r=this.attachedTabId;this.send({type:"resize",size:t}).then(n=>{r&&n.view&&(this.viewCache.set(r,n.view),this.notifyFullUpdate(r))}).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.notifyFullUpdate(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)})}setActivityEnabled(t){if(!(this.closed||this.activityEnabled===t)){if(this.activityEnabled=t,!t){for(let r of[...this.activityCache.keys()])this.removeCachedActivity(r);this.send({type:"setActivityEnabled",enabled:t}).catch(()=>{});return}this.send({type:"setActivityEnabled",enabled:t}).then(()=>this.refreshActivitySnapshots(!0)).catch(()=>{})}}disposeSession(t){this.viewCache.delete(t),this.removeCachedActivity(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}}getActivitySnapshots(){return[...this.activityCache.values()]}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)}
126
- `);let o=await s;if(!o.ok)throw new Error(o.error);return o}handleData(t){this.buffer+=t;let r=this.buffer.indexOf(`
122
+ `).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function Dn(e,t,r,n){return e.map((s,i)=>t?.[i]===s?"":`\x1B[${r+i};${n}H${s}`).join("")}import{spawn as Sy}from"node:child_process";import{createServer as vy,createConnection as Ld}from"node:net";import{openSync as Iy}from"node:fs";import{mkdir as Cy,readFile as bo,rm as wt,writeFile as Ay}from"node:fs/promises";import _n from"node:path";var Ze=class{jobs=new Map;resolutionMs;now;onError;timer=null;abortController=null;constructor(t){this.resolutionMs=po(t.resolutionMs??1e3,"Heartbeat resolution"),this.now=t.now??Date.now,this.onError=t.onError}register(t){if(this.jobs.has(t.id))throw new Error(`Heartbeat job "${t.id}" is already registered.`);let r={...t,intervalMs:po(t.intervalMs,`Heartbeat job "${t.id}" interval`),inFlight:!1,nextRunAt:this.timer?this.now()+t.intervalMs:null};this.jobs.set(t.id,r)}start(){if(this.timer)return;let t=this.now();for(let r of this.jobs.values())r.nextRunAt=t+r.intervalMs;this.abortController=new AbortController,this.timer=setInterval(()=>this.tick(),this.resolutionMs)}stop(){this.abortController?.abort(),this.abortController=null,this.timer&&clearInterval(this.timer),this.timer=null;for(let t of this.jobs.values())t.nextRunAt=null}setResolutionMs(t){let r=po(t,"Heartbeat resolution");r!==this.resolutionMs&&(this.resolutionMs=r,this.timer&&(clearInterval(this.timer),this.timer=setInterval(()=>this.tick(),this.resolutionMs)))}tick(){let t=this.abortController?.signal;if(!t)return;let r=this.now();for(let n of this.jobs.values())n.inFlight||n.nextRunAt===null||r<n.nextRunAt||(n.inFlight=!0,n.nextRunAt=r+n.intervalMs,Promise.resolve().then(()=>n.run(t)).catch(s=>{if(!t.aborted)return Promise.resolve(this.onError(n.id,s)).catch(()=>{})}).finally(()=>{n.inFlight=!1}))}};function po(e,t){if(!Number.isFinite(e)||e<=0)throw new Error(`${t} must be a positive number.`);return e}import{mkdir as Sd,readFile as _k,rm as mo,stat as jk,writeFile as Fk}from"node:fs/promises";import fo from"node:path";async function go(e){let t=fo.join(e.runtimeDir,"orchestration-supervisor.lock");await Sd(e.runtimeDir,{recursive:!0});try{await Sd(t)}catch(n){if(!qk(n))throw n;let s=await _k(fo.join(t,"owner.json"),"utf8").then(o=>JSON.parse(o)).catch(()=>null),i=await jk(t).catch(()=>null);if(typeof s?.pid=="number"&&!Wk(s.pid)||!s&&i&&Date.now()-i.mtimeMs>=5e3)return await mo(t,{recursive:!0,force:!0}),go(e);throw new g("COMMAND_STATE_CONFLICT","Another orchestration supervisor already leads this workspace.",{details:{ownerPid:s?.pid??null}})}try{await Fk(fo.join(t,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(n){throw await mo(t,{recursive:!0,force:!0}),n}let r=!1;return{async release(){r||(r=!0,await mo(t,{recursive:!0,force:!0}))}}}function Wk(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var qk=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST";function vd(e,t){switch(e){case"codex":case"cursor":case"claude":return`\x1B[200~${t}\x1B[201~\r`;default:return Uk(e)}}function Uk(e){throw new Error(`Unsupported prompt-delivery runner: ${String(e)}`)}import Vk from"node:path";var Bk={type:"system",component:"orchestration-supervisor"};async function Id(e){let t=Vk.join(e.orchestrationDir,"command-event-reconciliation.json"),r=await Or(t)??{version:1,commands:{}},n=await $e(e),s=!1;for(let i of n){let o=new Set(r.commands[i.id]??[]);for(let a of Kk(i))o.has(a)||(await mt(e,i,a,a==="command.queued"?i.actor:a==="command.cancelled"?i.cancelledBy??i.actor:Bk),o.add(a),s=!0);r.commands[i.id]=[...o]}s&&await L(t,r)}function Kk(e){let t=["command.queued"];return e.attempts>0&&t.push("command.delivering"),e.state==="delivered"?t.push("command.delivered"):e.state==="failed"?t.push("command.failed"):e.state==="cancelled"&&t.push("command.cancelled"),t}var On=class{constructor(t,r,n={}){this.paths=t;this.runtime=r;let s=n.intervalMs??250;this.heartbeat=new Ze({resolutionMs:s,onError:(i,o)=>n.onError?.(o)}),this.heartbeat.register({id:"orchestration.commands",intervalMs:s,run:()=>this.reconcile()})}paths;runtime;heartbeat;lease=null;reconciliation=null;async start(){if(!this.lease){this.lease=await go(this.paths);try{await this.reconcile(),this.heartbeat.start()}catch(t){throw await this.lease.release(),this.lease=null,t}}}async wake(){await this.reconcile()}async stop(){this.heartbeat.stop(),await this.reconciliation?.catch(()=>{}),await this.lease?.release(),this.lease=null}reconcile(){return this.reconciliation?this.reconciliation:(this.reconciliation=this.reconcileCommands().finally(()=>{this.reconciliation=null}),this.reconciliation)}async reconcileCommands(){await Id(this.paths);let t=await $e(this.paths);for(let r of t){if(r.state==="delivering"){await ie.fail(this.paths,r.id,vr("PROMPT_DELIVERY_UNCERTAIN","Craig resumed after prompt delivery began; the prompt was not replayed.",!1,!0));continue}r.state==="queued"&&await this.reconcileCommand(r)}}async reconcileCommand(t){if(Date.now()>=Date.parse(t.expiresAt)){await ie.fail(this.paths,t.id,vr("PROMPT_DELIVERY_TIMEOUT",`Prompt delivery timed out after ${t.timeoutMs}ms.`,!1,!1));return}let r=await P.getTask(this.paths,t.taskId).catch(i=>{if(i instanceof g&&i.code==="TASK_NOT_FOUND")return null;throw i}),n=r?.ptyTabs.find(i=>i.id===t.agentTabId);if(!r||!n||n.kind!=="agent"||r.status==="closed"){await ie.fail(this.paths,t.id,vr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer available in task ${t.taskId}.`,!1,!1));return}let s=this.runtime.getActivitySnapshots().find(i=>i.tabId===t.agentTabId);if(s&&s.sessionState!=="running"){await ie.fail(this.paths,t.id,vr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer running.`,!1,!1));return}if(this.runtime.hasRunningSession(t.agentTabId)&&!(t.delivery==="when-ready"&&Ge(r,t.agentTabId,this.runtime.getActivitySnapshots(),Date.now())!=="ready")){await ie.beginDelivery(this.paths,t.id);try{this.runtime.writeToSession(t.agentTabId,vd(n.runner??r.runner,t.prompt.text))}catch(i){await ie.fail(this.paths,t.id,vr("PROMPT_DELIVERY_UNCERTAIN",i instanceof Error?i.message:"Prompt delivery failed after it began.",!1,!0));return}await ie.completeDelivery(this.paths,t.id)}}},vr=(e,t,r,n)=>({code:e,message:t,retryable:r,deliveryUncertain:n});var Gk={pendingForegroundMs:5e3,pendingBackgroundMs:15e3,stableForegroundMs:3e4,stableBackgroundMs:6e4,discoveryForegroundMs:6e4,discoveryBackgroundMs:18e4,rateLimitBaseMs:6e4,rateLimitMaxMs:15*6e4},Bt=class{scheduledTasks=new Map;now;intervals;minimumIntervalMs;rateLimitFailures=0;notBefore=0;constructor(t={}){this.minimumIntervalMs=Math.max(1e3,t.minimumIntervalMs??5e3),this.intervals={...Gk,...t.intervals},this.now=t.now??Date.now}takeDueTasks(t,r){let n=this.now(),s=new Set(t.map(o=>o.id));for(let o of this.scheduledTasks.keys())s.has(o)||this.scheduledTasks.delete(o);let i=[];for(let o of t){let a=this.getTaskIntervalMs(o,r);if(a===null){this.scheduledTasks.delete(o.id);continue}let l=this.scheduledTasks.get(o.id);if(!l){this.scheduledTasks.set(o.id,{intervalMs:a,nextPollAt:n,lastPollAt:null}),n>=this.notBefore&&i.push(o);continue}a<l.intervalMs&&(l.nextPollAt=Math.min(l.nextPollAt,n+a)),l.intervalMs=a,n>=this.notBefore&&n>=l.nextPollAt&&i.push(o)}return i}requestImmediate(t){let r=this.now();for(let n of t){let s=this.scheduledTasks.get(n);if(!s)continue;let i=s.lastPollAt===null?r:Math.max(r,s.lastPollAt+this.minimumIntervalMs);s.nextPollAt=Math.min(s.nextPollAt,i)}}recordSuccess(t,r){let n=this.now();this.rateLimitFailures=0,this.notBefore=0;for(let s of t){let i=this.getTaskIntervalMs(s,r);i===null?this.scheduledTasks.delete(s.id):this.scheduledTasks.set(s.id,{intervalMs:i,nextPollAt:n+i,lastPollAt:n})}}recordFailure(t,r){let n=this.now(),s=r instanceof me,i=s?Math.min(this.intervals.rateLimitBaseMs*2**this.rateLimitFailures,this.intervals.rateLimitMaxMs):Math.max(this.minimumIntervalMs,this.intervals.pendingBackgroundMs);s&&(this.rateLimitFailures+=1,this.notBefore=n+i);for(let o of t){let a=this.scheduledTasks.get(o.id);a&&(a.nextPollAt=n+i,a.lastPollAt=n)}}getTaskIntervalMs(t,r){let n=Hk(t),s=t.id===r.selectedTaskId&&r.reviewVisible;if(n.length>0){let i=n.some(zk);return this.withMinimum(i?s?this.intervals.pendingForegroundMs:this.intervals.pendingBackgroundMs:s?this.intervals.stableForegroundMs:this.intervals.stableBackgroundMs)}return t.status!=="closed"?this.withMinimum(s?this.intervals.discoveryForegroundMs:this.intervals.discoveryBackgroundMs):null}withMinimum(t){return Math.max(t,this.minimumIntervalMs)}};function Hk(e){return e.type==="project"&&e.repoTargets?.length?e.repoTargets.map(t=>t.pullRequest).filter(t=>t.status==="open"):e.prs.filter(t=>t.status==="open")}function zk(e){return e.requiredChecks.some(t=>t.status==="pending"||t.status==="unknown")}import{watch as Yk}from"node:fs";var $n=class{constructor(t,r){this.paths=t;this.options=r;this.now=r.now??Date.now,this.taskDebounceMs=r.taskDebounceMs??50,this.readyAfterMs=r.readyAfterMs??5e3}paths;options;now;taskDebounceMs;readyAfterMs;agentStates=new Map;readinessTimers=new Map;watcher=null;debounceTimer=null;reconciliation=null;dirty=!1;running=!1;baselineComplete=!1;start(){if(!this.running){this.running=!0,this.baselineComplete=!1;try{this.watcher=Yk(this.paths.tasksDir,{persistent:!1},()=>{this.schedule(this.taskDebounceMs)}),this.watcher.on("error",t=>{this.reportError(t)})}catch(t){this.reportError(t)}this.schedule(0)}}notifyActivity(t){if(!this.running)return;let r=De(t.tabId,[t],this.now());this.agentStates.get(t.tabId)!==r&&(this.agentStates.set(t.tabId,r),this.schedule(0)),this.scheduleReadiness(t)}notifyActivityRemoved(t){this.running&&(this.clearReadinessTimer(t),this.agentStates.delete(t)&&this.schedule(0))}async stop(){if(this.running){this.running=!1,this.watcher?.close(),this.watcher=null,this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=null;for(let t of this.readinessTimers.values())clearTimeout(t);this.readinessTimers.clear(),await this.reconciliation?.catch(()=>{})}}scheduleReadiness(t){if(this.clearReadinessTimer(t.tabId),t.sessionState!=="running")return;let r=Math.max(0,t.lastActivityAt+this.readyAfterMs-this.now());this.readinessTimers.set(t.tabId,setTimeout(()=>{this.readinessTimers.delete(t.tabId),!(!this.running||this.agentStates.get(t.tabId)!=="working")&&(this.agentStates.set(t.tabId,"ready"),this.schedule(0))},r+1))}clearReadinessTimer(t){let r=this.readinessTimers.get(t);r&&clearTimeout(r),this.readinessTimers.delete(t)}schedule(t){if(this.running){if(this.reconciliation){this.dirty=!0;return}this.debounceTimer||(this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.requestReconciliation()},t))}}requestReconciliation(){if(!this.running||this.reconciliation){this.dirty=!0;return}this.reconciliation=this.drainReconciliations().catch(t=>this.reportError(t)).finally(()=>{this.reconciliation=null,this.running&&this.dirty&&this.requestReconciliation()})}async drainReconciliations(){do{this.dirty=!1;let t=await this.options.reconcileEvents();this.baselineComplete&&t.length>0&&await this.options.onEvents(t),this.baselineComplete=!0}while(this.running&&this.dirty)}async reportError(t){await this.options.onError(t)}};var Jk={selectedTaskId:null,reviewVisible:!1},Xk={listTasks:async e=>(await P.listTasks(e)).tasks,syncTasks:async(e,t)=>(await P.prs.discoverOrRefreshMany(e,t),Promise.all(t.map(r=>P.getTask(e,r.id))))},Mn=class{constructor(t,r={}){this.paths=t;let n=r.heartbeatIntervalMs??1e3;this.dependencies=r.dependencies??Xk,this.onTasksChanged=r.onTasksChanged??(()=>{}),this.onError=r.onError??(()=>{}),this.coordinator=new Bt({...r.minimumIntervalMs!==void 0?{minimumIntervalMs:r.minimumIntervalMs}:{},...r.intervals?{intervals:r.intervals}:{},...r.now?{now:r.now}:{}}),this.eventMonitor=r.reconcileEvents?new $n(t,{reconcileEvents:r.reconcileEvents,onEvents:async s=>{let i=Qk(s);i.length>0&&await this.wake(i)},onError:s=>this.reportError(s),...r.now?{now:r.now}:{}}):null,this.heartbeat=new Ze({resolutionMs:n,...r.now?{now:r.now}:{},onError:(s,i)=>this.reportError(i)}),this.heartbeat.register({id:"github.pull-requests",intervalMs:n,run:()=>this.reconcile()})}paths;heartbeat;coordinator;dependencies;onTasksChanged;onError;eventMonitor;pendingWakeTaskIds=new Set;reconciliation=null;reconciliationVersion=0;view=Jk;running=!1;lastErrorMessage=null;start(){this.running||(this.running=!0,this.eventMonitor?.start(),this.heartbeat.start())}async stop(){this.running&&(this.running=!1,this.heartbeat.stop(),await this.eventMonitor?.stop(),await this.reconciliation?.catch(()=>{}))}setView(t){this.view=t}notifyActivity(t){this.eventMonitor?.notifyActivity(t)}notifyActivityRemoved(t){this.eventMonitor?.notifyActivityRemoved(t)}async wake(t){if(t?.length){for(let r of t)this.pendingWakeTaskIds.add(r);this.reconciliationVersion+=1}await this.reconcile()}reconcile(){return this.reconciliation?this.reconciliation:(this.reconciliation=this.drainReconciliations(),this.reconciliation)}async drainReconciliations(){try{for(;;){let t=this.reconciliationVersion,r=[...this.pendingWakeTaskIds];if(this.pendingWakeTaskIds.clear(),this.coordinator.requestImmediate(r),await this.reconcilePullRequests(),t===this.reconciliationVersion)return}}finally{this.reconciliation=null}}async reconcilePullRequests(){let t=await this.dependencies.listTasks(this.paths),r=this.view,n=this.coordinator.takeDueTasks(t,r);if(n.length===0)return;let s=new Map(n.map(o=>[o.id,Cd(o)])),i;try{i=await this.dependencies.syncTasks(this.paths,n)}catch(o){this.coordinator.recordFailure(n,o),await this.reportPersistedChangesAfterFailure(s),await this.reportError(o);return}this.coordinator.recordSuccess(i,this.view),this.lastErrorMessage=null,await this.reportChangedTasks(s,i)}async reportPersistedChangesAfterFailure(t){try{let r=await this.dependencies.listTasks(this.paths);await this.reportChangedTasks(t,r.filter(n=>t.has(n.id)))}catch(r){await this.reportError(r)}}async reportChangedTasks(t,r){let n=r.filter(s=>t.get(s.id)!==Cd(s)).map(s=>s.id);n.length>0&&await this.onTasksChanged(n)}async reportError(t){let r=t instanceof Error?t.message:String(t);r!==this.lastErrorMessage&&(this.lastErrorMessage=r,await this.onError(t))}};function Qk(e){let t=new Set;for(let r of e){if(!r.taskId)continue;if(r.type==="task.created"||r.type==="task.pr.unlinked"){t.add(r.taskId);continue}let n=ey(r.data);if(r.type==="task.updated"){(Array.isArray(n?.changedFields)?n.changedFields:[]).some(i=>typeof i=="string"&&Zk.has(i))&&t.add(r.taskId);continue}r.type==="agent.state.changed"&&n?.previousState==="working"&&(n.state==="ready"||n.state==="idle"||n.state==="error")&&t.add(r.taskId)}return[...t]}var Zk=new Set(["branch","lastCommitSha","checksStatus","checksLastRunAt"]),ey=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:null;function Cd(e){return JSON.stringify({status:e.status,prs:e.prs,repoTargets:e.repoTargets??null})}import{createRequire as dy}from"node:module";import ty from"@xterm/headless";var ry=1e3,ny=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function Ed(e){return new ty.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:ry,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function xd(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function wo(e,t){return new Promise(r=>{e.write(t,r)})}function Dd(e,t=0){let r=e.buffer.active,n=[],s=r.getNullCell(),i=r.baseY+r.cursorY,o=Math.max(0,r.baseY-t);for(let a=0;a<e.rows;a+=1){let l=r.getLine(o+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:oy(u,o+a===i&&d===r.cursorX)})}n.push({segments:sy(iy(c))})}return n}function sy(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&cy(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};Od(r.style)||(s.style=r.style),t.push(s)}return t}function iy(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!Od(r.style))break;t-=1}return e.slice(0,t)}function oy(e,t){let r={},n=Ad(e,"fg"),s=Ad(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 Ad(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"):ny[s]??ay(s)}function ay(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(ly).map(i=>i.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 ly(e){return e===0?0:55+e*40}function cy(e,t){return ho(e)===ho(t)}function ho(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Od(e){return ho(e)===""}var uy=dy(import.meta.url),py=/^CTRL_([A-Z])$/,my="\x1B[6n",fy="\x1B[c",gy="\x1B[?u",hy={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
123
+ `,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:""},Nn=class{sessions=new Map;activitySnapshots=new Map;shell;env;spawn;onUpdate;onActivity;onActivityRemoved;activityEnabled;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.onActivity=t.onActivity,this.onActivityRemoved=t.onActivityRemoved,this.activityEnabled=t.activityEnabled??!0,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,r,n,s){let i=this.sessions.get(r);if(i)if(i.status!=="running")ko(i),this.sessions.delete(r);else return this.attachedTabId=r,i.scrollbackLines=0,$d(i,n),this.getViewState(r);let o;try{o=this.createSession(t,r,n,s)}catch(a){throw this.recordActivity({taskId:t,tabId:r,sessionState:"failed",lastActivityAt:Date.now(),exitCode:null,error:a instanceof Error?a.message:String(a)}),a}return this.sessions.set(r,o),this.notifyActivity(o),this.attachedTabId=r,this.getViewState(r)}write(t){let r=this.getAttachedSession();!r||r.status!=="running"||(r.pty.write(t),(t.includes("\r")||t.includes(`
124
+ `))&&this.touchActivity(r))}writeKey(t){let r=wy(t);r!==null&&this.write(r)}hasRunningSession(t){return this.sessions.get(t)?.status==="running"}writeToSession(t,r){let n=this.sessions.get(t);if(!n||n.status!=="running")throw new Error(`Agent tab ${t} is not running.`);n.pty.write(r),this.touchActivity(n)}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&&$d(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}getActivitySnapshots(){return[...this.activitySnapshots.values()]}setActivityEnabled(t){if(this.activityEnabled!==t&&(this.activityEnabled=t,!!t))for(let r of this.sessions.values())this.notifyActivity(r)}disposeSession(t){let r=this.sessions.get(t);r&&(ko(r),this.sessions.delete(t)),this.removeActivity(t),this.attachedTabId===t&&(this.attachedTabId=null)}disposeAll(){for(let t of this.sessions.values())ko(t);this.sessions.clear();for(let t of this.activitySnapshots.keys())this.onActivityRemoved?.(t);this.activitySnapshots.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:ky(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let i=this.spawn??Ty().spawn,o=Ed(n),a=s??this.resolveSessionSpec(t,r),l=dt({...this.env,...a.env??{}}),{executable:c,args:d}=Ry(this.shell,a.command,{cwd:a.cwd,env:l}),u=i(c,d,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:a.cwd,env:by(l)}),f={taskId:t,tabId:r,pty:u,terminal:o,status:"running",error:null,disposables:[],scrollbackLines:0,rows:[],renderedScrollbackLines:null,screenDirty:!0,lastActivityAt:Date.now(),exitCode:null};return f.disposables.push(u.onData(h=>{this.touchActivity(f),Py(u,h),wo(f.terminal,h).then(()=>{f.screenDirty=!0,this.onUpdate?.({tabId:f.tabId,kind:"full"})})})),f.disposables.push(u.onExit(h=>{f.status="exited",f.exitCode=h.exitCode,f.lastActivityAt=Date.now(),this.notifyActivity(f),wo(f.terminal,`\r
125
+ [process exited ${h.exitCode}]`).then(()=>{f.screenDirty=!0,this.onUpdate?.({tabId:f.tabId,kind:"full"})})})),f}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}touchActivity(t){t.lastActivityAt=Date.now(),this.activityEnabled&&this.notifyActivity(t)}notifyActivity(t){this.activityEnabled&&this.recordActivity(this.buildActivitySnapshot(t))}recordActivity(t){this.activityEnabled&&(this.activitySnapshots.set(t.tabId,t),this.onActivity?.(t))}removeActivity(t){this.activitySnapshots.delete(t)&&this.onActivityRemoved?.(t)}buildActivitySnapshot(t){return{taskId:t.taskId,tabId:t.tabId,sessionState:t.status==="failed"?"failed":t.status==="exited"?"exited":"running",lastActivityAt:t.lastActivityAt,exitCode:t.exitCode,error:t.error}}};function wy(e){if(e.length===1)return e;let t=hy[e];if(t!==void 0)return t;let r=py.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function $d(e,t){yy(e.pty,t),xd(e.terminal,t),e.screenDirty=!0}function ky(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=Dd(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function ko(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function yy(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Ty(){return uy("node-pty")}function Ry(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[ut(t[0],r),...t.slice(1)].map(Md).join(" ")}; exec ${Md(e)} -l`;return{executable:e,args:["-lc",s]}}function Md(e){return`'${e.replaceAll("'","'\\''")}'`}function by(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 Py(e,t){for(let r=0;r<yo(t,my);r+=1)e.write("\x1B[1;1R");for(let r=0;r<yo(t,fy);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<yo(t,gy);r+=1)e.write("\x1B[?0u")}function yo(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 _d=Lt,Ey=new Set([_d]),xy=16,Dy=250;async function jd(e){let t=He(e.paths);await Ny(t,e.paths,e.spawnDaemon);let r=await Kd(t.socketPath),n=new To(r,e);return await n.ready(),n}async function Fd(e,t={}){let r=He(e);await Cy(e.runtimeDir,{recursive:!0}),await wt(r.socketPath,{force:!0});let n=new Ro(e,t),s=vy(i=>n.handleConnection(i));try{await n.start(),await qy(s,r.socketPath),await Ay(r.pidPath,String(process.pid),"utf8"),await new Promise(i=>{let o=!1,a=()=>{o||(o=!0,n.closeClients(),s.close(()=>{process.removeListener("SIGTERM",a),process.removeListener("SIGINT",a),i()}))};n.onShutdown=a,process.once("SIGTERM",a),process.once("SIGINT",a)})}finally{n.onShutdown=null,await wt(r.socketPath,{force:!0}),await wt(r.pidPath,{force:!0}),await n.stop(),n.disposeAll()}}async function Wd(e){let t=He(e);return await jn(t.socketPath)?(await Vd(t.socketPath),!0):!1}var To=class{constructor(t,r){this.socket=t;this.options=r,this.viewUpdateMode=r.viewUpdateMode??"snapshot",this.activityEnabled=r.activityEnabled??!1,this.tasksChangedHandler=r.onTasksChanged,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||(this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed.")),this.failRunningActivities("Craig PTY daemon connection closed."))})}socket;managesPullRequestSync=!0;nextRequestId=1;pending=new Map;viewCache=new Map;activityCache=new Map;activityRevisionByTabId=new Map;activityRevision=0;attachedTabId=null;viewedTabId=null;subscribedTabId=null;viewUpdateMode;activityEnabled;pullRequestPollView={selectedTaskId:null,reviewVisible:!1};tasksChangedHandler;buffer="";closed=!1;options;async ready(){let t=await this.send({type:"ping"});if(!Ud(t.protocolVersion))throw new Error("Craig PTY daemon protocol mismatch.");await this.send({type:"setViewUpdateMode",mode:this.viewUpdateMode}),await this.send({type:"setActivityEnabled",enabled:this.activityEnabled}),this.activityEnabled&&await this.refreshActivitySnapshots()}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 i=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(r,i),i}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})}this.activityEnabled&&await this.refreshActivitySnapshots()}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){let r=this.attachedTabId;this.send({type:"scrollViewport",lines:t}).then(n=>{r&&n.view&&(this.viewCache.set(r,n.view),this.notifyFullUpdate(r))}).catch(()=>{})}resize(t){let r=this.attachedTabId;this.send({type:"resize",size:t}).then(n=>{r&&n.view&&(this.viewCache.set(r,n.view),this.notifyFullUpdate(r))}).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.notifyFullUpdate(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)})}setActivityEnabled(t){if(!(this.closed||this.activityEnabled===t)){if(this.activityEnabled=t,!t){for(let r of[...this.activityCache.keys()])this.removeCachedActivity(r);this.send({type:"setActivityEnabled",enabled:t}).catch(()=>{});return}this.send({type:"setActivityEnabled",enabled:t}).then(()=>this.refreshActivitySnapshots(!0)).catch(()=>{})}}setPullRequestPollView(t){this.closed||this.pullRequestPollView.selectedTaskId===t.selectedTaskId&&this.pullRequestPollView.reviewVisible===t.reviewVisible||(this.pullRequestPollView=t,this.send({type:"setPullRequestPollView",view:t}).catch(()=>{}))}setTasksChangedHandler(t){this.tasksChangedHandler=t}disposeSession(t){this.viewCache.delete(t),this.removeCachedActivity(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}}getActivitySnapshots(){return[...this.activityCache.values()]}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((o,a)=>{this.pending.set(r,{resolve:o,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)}
126
+ `);let i=await s;if(!i.ok)throw new Error(i.error);return i}handleData(t){this.buffer+=t;let r=this.buffer.indexOf(`
127
127
  `);for(;r!==-1;){let n=this.buffer.slice(0,r);this.buffer=this.buffer.slice(r+1),this.handleMessage(n),r=this.buffer.indexOf(`
128
- `)}}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.notifyFullUpdate(r.tabId);return}let n=this.viewCache.get(r.tabId)??{status:"idle",rows:[],error:null,scrolledBack:!1},s=hy(n,r.patch),o=n.rows.slice(0,r.patch.rowCount);for(let i of r.patch.rows)o[i.index]=i.row;this.viewCache.set(r.tabId,{status:r.patch.status,rows:o,error:r.patch.error,scrolledBack:r.patch.scrolledBack}),this.viewUpdateMode==="incremental"&&this.viewedTabId===r.tabId&&this.options.onUpdate?.(s?{tabId:r.tabId,kind:"full"}:{tabId:r.tabId,kind:"rows",rowIndices:r.patch.rows.map(i=>i.index)})}r.type==="activity"&&(this.recordCachedActivity(r.snapshot),this.options.onActivity?.(r.snapshot)),r.type==="activityRemoved"&&this.removeCachedActivity(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.notifyFullUpdate(t)}).catch(()=>{this.subscribedTabId===t&&(this.subscribedTabId=null)}))}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}notifyFullUpdate(t){t&&this.options.onUpdate?.({tabId:t,kind:"full"})}replaceActivityCache(t,r){let n=new Map;for(let[s,o]of this.activityRevisionByTabId)o>r&&n.set(s,this.activityCache.get(s)??null);this.activityCache.clear();for(let s of t)this.activityCache.set(s.tabId,s);for(let[s,o]of n)o?this.activityCache.set(s,o):this.activityCache.delete(s)}async refreshActivitySnapshots(t=!1){let r=this.activityRevision,n=await this.send({type:"getActivitySnapshots"});if(this.replaceActivityCache(n.activities??[],r),t)for(let s of this.activityCache.values())this.options.onActivity?.(s)}recordCachedActivity(t){this.activityRevision+=1,this.activityRevisionByTabId.set(t.tabId,this.activityRevision),this.activityCache.set(t.tabId,t)}removeCachedActivity(t){this.activityRevision+=1,this.activityRevisionByTabId.set(t,this.activityRevision),this.activityCache.delete(t),this.options.onActivityRemoved?.(t)}failRunningActivities(t){for(let r of this.activityCache.values()){if(r.sessionState!=="running")continue;let n={...r,sessionState:"failed",lastActivityAt:Date.now(),error:t};this.recordCachedActivity(n),this.options.onActivity?.(n)}}},ki=class{onShutdown=null;clients=new Set;subscriptions=new Map;updateTimers=new Map;activityTimers=new Map;pendingActivities=new Map;runtime;paths;orchestrationSupervisor=null;attachedTabId=null;constructor(t,r){this.paths=t,this.runtime=new xn({...r,workspaceRoot:t.workspaceRoot,activityEnabled:!1,onUpdate:n=>this.handleRuntimeUpdate(n.tabId),onActivity:n=>this.handleActivityUpdate(n),onActivityRemoved:n=>this.handleActivityRemoved(n)})}async start(){let t=await h.load(this.paths),r=(await xe(this.paths)).some(n=>n.state==="queued"||n.state==="delivering");(h.previews.isEnabled(t,"agentOrchestration")||r)&&await this.ensureOrchestrationSupervisor()}async stop(){await this.orchestrationSupervisor?.stop(),this.orchestrationSupervisor=null}handleConnection(t){let r="";this.clients.add(t),this.subscriptions.set(t,{mode:"snapshot",activityEnabled:!1,tabId:null,view:null,rowKeys:[]}),t.setEncoding("utf8"),t.on("data",s=>{r+=String(s);let o=r.indexOf(`
129
- `);for(;o!==-1;){let i=r.slice(0,o);r=r.slice(o+1),this.handleLine(t,i),o=r.indexOf(`
130
- `)}});let n=()=>{this.clients.delete(t),this.subscriptions.delete(t),this.hasActivitySubscribers()||(this.updateRuntimeActivityEnabled(),this.clearPendingActivityBroadcasts())};t.on("close",n),t.on("error",n)}disposeAll(){for(let t of this.updateTimers.values())clearTimeout(t);this.updateTimers.clear();for(let t of this.activityTimers.values())clearTimeout(t);this.activityTimers.clear(),this.pendingActivities.clear(),this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear(),this.subscriptions.clear(),this.updateRuntimeActivityEnabled()}async handleLine(t,r){if(r.trim().length===0)return;let n;try{n=JSON.parse(r)}catch{ft(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=await this.handleRequest(t,n);ft(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:xd}:{},...n.type==="getActivitySnapshots"?{activities:this.runtime.getActivitySnapshots()}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);ft(t,{id:n.id,ok:!1,error:o})}}async 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"setActivityEnabled":return this.setActivityEnabled(t,r.enabled),null;case"subscribeView":return this.subscribe(t,r.tabId,this.runtime.getViewState(r.tabId));case"pruneStale":{let n=new Set(r.keepTabIds),s=new Set([...this.runtime.sessionTabIds(),...this.runtime.getActivitySnapshots().map(o=>o.tabId)]);for(let o of s)n.has(o)||(this.runtime.disposeSession(o),this.attachedTabId===o&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(r.tabId);case"getActivitySnapshots":return null;case"wakeOrchestration":return await this.ensureOrchestrationSupervisor(),await this.orchestrationSupervisor.wake(),null;case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return Sy(r)}}subscribe(t,r,n){let s=this.subscriptions.get(t),o=s?.mode??"snapshot";return this.subscriptions.set(t,{mode:o,activityEnabled:s?.activityEnabled??!1,tabId:r,view:n,rowKeys:n.rows.map(Dn)}),n}setViewUpdateMode(t,r){let n=this.subscriptions.get(t),s=n?.tabId??null,o=this.runtime.getViewState(s);return this.subscriptions.set(t,{mode:r,activityEnabled:n?.activityEnabled??!1,tabId:s,view:o,rowKeys:o.rows.map(Dn)}),o}setActivityEnabled(t,r){let n=this.subscriptions.get(t);if(!n)return;this.subscriptions.set(t,{...n,activityEnabled:r});let s=this.hasActivitySubscribers();this.updateRuntimeActivityEnabled(),s||this.clearPendingActivityBroadcasts()}handleRuntimeUpdate(t){let r=null;for(let n of this.clients)this.subscriptions.get(n)?.mode==="snapshot"&&(r??=this.runtime.getViewState(t),ft(n,{type:"update",tabId:t,view:r}));this.scheduleBroadcastUpdate(t)}handleActivityUpdate(t){if(this.hasActivitySubscribers()){if(this.pendingActivities.set(t.tabId,t),t.sessionState!=="running"){let r=this.activityTimers.get(t.tabId);r&&(clearTimeout(r),this.activityTimers.delete(t.tabId)),this.broadcastActivity(t.tabId);return}this.activityTimers.has(t.tabId)||this.activityTimers.set(t.tabId,setTimeout(()=>{this.activityTimers.delete(t.tabId),this.broadcastActivity(t.tabId)},my))}}handleActivityRemoved(t){let r=this.activityTimers.get(t);r&&(clearTimeout(r),this.activityTimers.delete(t)),this.pendingActivities.delete(t);for(let[n,s]of this.subscriptions)s.activityEnabled&&ft(n,{type:"activityRemoved",tabId:t})}broadcastActivity(t){let r=this.pendingActivities.get(t);if(r){this.pendingActivities.delete(t);for(let[n,s]of this.subscriptions)s.activityEnabled&&ft(n,{type:"activity",snapshot:r})}}hasActivitySubscribers(){return[...this.subscriptions.values()].some(t=>t.activityEnabled)}clearPendingActivityBroadcasts(){for(let t of this.activityTimers.values())clearTimeout(t);this.activityTimers.clear(),this.pendingActivities.clear()}async ensureOrchestrationSupervisor(){if(this.orchestrationSupervisor)return;let t=new En(this.paths,this.runtime,{onError:r=>Le.appendErrorLogBestEffort(this.paths,{context:"orchestration supervisor",message:r instanceof Error?r.message:String(r)})});await t.start(),this.orchestrationSupervisor=t,this.updateRuntimeActivityEnabled()}updateRuntimeActivityEnabled(){this.runtime.setActivityEnabled(this.orchestrationSupervisor!==null||this.hasActivitySubscribers())}scheduleBroadcastUpdate(t){this.updateTimers.has(t)||!this.hasViewSubscriber(t)||this.updateTimers.set(t,setTimeout(()=>{this.updateTimers.delete(t),this.broadcastUpdate(t)},py))}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=fy(s,r),i=gy(s.view,r);s.view=r,s.rowKeys=r.rows.map(Dn),(o.rows.length>0||i)&&ft(n,{type:"update",tabId:t,patch:o})}}};function fy(e,t){let r=[];for(let n=0;n<t.rows.length;n+=1){let s=t.rows[n];e.rowKeys[n]!==Dn(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 gy(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 hy(e,t){return e.status!==t.status||e.error!==t.error||(e.scrolledBack??!1)!==t.scrolledBack||e.rows.length!==t.rowCount}function Dn(e){return JSON.stringify(e)}async function wy(e,t,r){if(await ky(e.socketPath,1e3))return;await $n(e.socketPath)&&(await Ld(e.socketPath),await Ad(e.socketPath,1e3)),await $n(e.socketPath)&&(await Ry(e),await Ad(e.socketPath,1e3)),await Ty(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:a}=yy(n),l=ly(On.join(t.runtimeDir,"pty-daemon.log"),"a");iy(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 Nd(e.socketPath))return;await Ti(50)}let o=await yi(On.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
131
- ${o.slice(-2e3)}`:""}`)}async function Nd(e){let t=await by(e).catch(()=>null);return t?.ok===!0&&Md(t.protocolVersion)}function Md(e){return e!==void 0&&uy.has(e)}async function ky(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await Nd(e))return!0;await Ti(50)}return!1}function yy(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=On.resolve(On.dirname(t),"..","node_modules",".bin","tsx");return{command:Es("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 Ty(e){let t=await yi(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&Fd(r))return}await gt(e.socketPath,{force:!0}),await gt(e.pidPath,{force:!0})}async function $n(e){let t=await jd(e).catch(()=>null);return t?(t.end(),!0):!1}async function Ld(e){await _d(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Ry(e){let t=await yi(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!Fd(r)){await gt(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await gt(e.socketPath,{force:!0})}}async function by(e){return _d(e,{id:1,type:"ping"})}function _d(e,t){return new Promise((r,n)=>{let s=Ed(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)}
132
- `)),s.once("error",l=>{a(),n(l)}),s.on("data",l=>{o+=String(l);let c=o.indexOf(`
133
- `);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 Ad(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await $n(e))return;await Ti(50)}}function jd(e){return new Promise((t,r)=>{let n=Ed(e);n.once("connect",()=>t(n)),n.once("error",r)})}function Py(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function ft(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
134
- `)}catch{}}function Fd(e){try{return process.kill(e,0),!0}catch{return!1}}function Ti(e){return new Promise(t=>setTimeout(t,e))}function Sy(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var Ri=["Runners","Feature Previews","Error Log","Help"],qd={incrementalCenterPane:"Incremental center pane",agentActivityIndicators:"Agent activity indicators",agentOrchestration:"Agent orchestration"};function bi(e,t){return L.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 Ud(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 Bd(e){return ge.map(t=>`${h.previews.isEnabled(e,t)?"[x]":"[ ]"} ${qd[t]}`)}function Vd(e){return e.message??"Experimental features may change or be removed. Enter toggles."}function Kd(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Ri.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Nn(t)?e===0?{kind:"runners"}:e===1?{kind:"previews"}:e===2?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Gd(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(ge.length-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(!Nn(r))return{kind:"noop",state:e};let n=ge[e.menuIndex]??ge[0],s=!h.previews.isEnabled(t,n);return{kind:"save-enabled",feature:n,enabled:s,state:{...e,message:`${qd[n]} ${s?"enabled":"disabled"}.`}}}function Hd(e,t,r,n){if(e.pathEdit)return vy({...e,pathEdit:e.pathEdit},t,r);let s=bi(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=L[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:a,value:t.runners?.[a]?.path??""}}}}if(!Nn(r))return{kind:"noop",state:e};let o=L[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 vy(e,t,r){if(r==="ESCAPE")return{kind:"render",state:Wd({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Nn(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:Wd({...e,message:s.length>0?`${h.runners.getProfile(n).displayName} executable saved.`:`${h.runners.getProfile(n).displayName} executable reset to default.`})}}return Iy(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function Wd(e){let t={...e};return delete t.pathEdit,t}function Nn(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
135
- `}function Iy(e){return e.length===1&&e>=" "&&e!==""}import Sr from"node:path";function zd(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 Yd="\u{F024B} ",Jd="\u{F0DCF} ",Xd="\u25CB",Pi="\uEA64",Qd="\uEAFE",Zd="\uEBDA",Si="\u25CB",vi="\u25CF",Ii="\u2713",Ci="\u2715";function eu(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 Mn=150,tu=6;var _n="empty",G={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function ou(e,t,r){let n=Ey(t,e),s=t.repos.find(b=>b.id===e.selectedRepoId)??t.repos[0]??null,o=n?t.tasks.filter(b=>b.workspaceId===n.id):t.tasks,i=n?.kind==="project"?o:s?o.filter(b=>b.repoId===s.id):[],a=i.find(b=>b.id===e.selectedTaskId)??i[0]??null,l=a?.type==="project",c=cT(t.tasks),d=Oy(e,a),u=Dy(e,a,d,r),m=u.find(b=>b.id===d)??u[0]??{id:"agent",label:"CODEX"},p=t.inspection?.taskId===a?.id?t.inspection:null,k=s?.name??"no repo",w=a?h.runners.getDisplayName(a.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 ${s?`[${s.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`:yr(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"?a===null?"n new task Tab tasks Esc pause ? help":d===D?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${h.runners.getDisplayName(e.centerTabRunner??a?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?l?"\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:Sr.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Sr.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:w},leftTree:Cy(e,t,r),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(b=>dT(b,c[b])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":m.label,taskId:e.workspaceBrowser?"new workspace":a?.id??"no task",repo:k,agent:w},centerTranscript:xy(d,e,s,a,e.workspaceBrowser,p,n),tabs:u,rightContext:lT(s,a),rightInspection:Ky(e,a,p)}}function Cy(e,t,r){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return Ay(n,e,t.repos,t.tasks,r);let s=t.workspaces;if(s.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let i of s){let a=e.selectedLeftItemId===`workspace:${i.id}`;n.push({id:`workspace:${i.id}`,text:`${i.kind==="project"?"\u2261":"\u2013"} ${i.name??i.id}`,selected:a,focused:a&&e.focusedRegion==="tasks"});let l=i.kind==="project"?i.discoveredRepoIds??[]:[i.primaryRepoId],c=t.tasks.filter(d=>d.workspaceId===i.id);if(c.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of c){let u=e.selectedLeftItemId===`task:${d.id}`,m=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,p={id:`task:${d.id}`,taskId:d.id,text:r?m:`${u?"\u25B8":"\u2022"} ${m}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",...r?{activity:$t(d,r.snapshots,r.now),activityAnimationFrame:r.animationFrame}:{}},k=au(d);k&&(p.prBadge=k),n.push(p)}if(i.kind==="project"){let d=`new-task-workspace:${i.id}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}if(i.kind==="repo"){let d=`new-task:${i.primaryRepoId}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}else{n.push({text:` Repos (${l.length})`,indent:0,muted:!0});for(let d of l.slice(0,6)){let u=t.repos.find(m=>m.id===d);n.push({text:` \xB7 ${u?.name??d}`,indent:0,muted:!0})}l.length>6&&n.push({text:` \xB7 ${l.length-6} more`,indent:0,muted:!0})}}let o=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:o,focused:o&&e.focusedRegion==="tasks"}),n}function Ay(e,t,r,n,s){if(r.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let i of r){let a=t.selectedLeftItemId===`repo:${i.id}`;e.push({id:`repo:${i.id}`,text:`\u2013 ${i.name}`,selected:a,focused:a&&t.focusedRegion==="tasks"});let l=n.filter(u=>u.repoId===i.id);if(l.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let u of l){let m=t.selectedLeftItemId===`task:${u.id}`,p=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,k={id:`task:${u.id}`,taskId:u.id,text:s?p:`${m?"\u25B8":"\u2022"} ${p}`,indent:2,selected:m,focused:m&&t.focusedRegion==="tasks",...s?{activity:$t(u,s.snapshots,s.now),activityAnimationFrame:s.animationFrame}:{}},w=au(u);w&&(k.prBadge=w),e.push(k)}let c=`new-task:${i.id}`,d=t.selectedLeftItemId===c;e.push({id:c,text:`+ New Task [${h.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let o=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:o,focused:o&&t.focusedRegion==="tasks"}),e}function Ey(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 xy(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,m)=>{let p=m===s.selectedIndex?"\u25B8":" ",k=u.kind==="repo"?" [git repo]":"/";return`${p} ${u.name}${k}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return ke(["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 ke(["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 ke([`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"?ke([`${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."]):ke([`${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===D&&t.openInspectionKind==="file"?My(n,o,t.fileScrollOffset):e===D&&t.openInspectionKind==="diff"?Ly(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?ke(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ke(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Dy(e,t,r,n){let s=t?.ptyTabs.map(i=>({id:i.id,label:$y(i),...i.kind==="agent"&&n&&t?{activity:Ve(t,i.id,n.snapshots,n.now),activityAnimationFrame:n.animationFrame}:{}}))??[];if(!t)return[{id:_n,label:"EMPTY",active:r===_n,focused:e.focusedRegion==="center"&&r===_n}];let o=e.openInspectionKind||r===D?[{id:D,label:Ny(e)}]:[];return[...s,...o].map(i=>({...i,active:i.id===r,focused:e.focusedRegion==="center"&&i.id===r}))}function Oy(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===D&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??D:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??D:_n}function $y(e){return e.title.toUpperCase()}function Ny(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?Sr.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function My(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ke(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=iu(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:""},..._y(n.lines,r,s)]}function Ly(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ke(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=iu(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:""},...jy(n.lines,r,s)]}function ke(e){return e.map(t=>({text:t}))}function _y(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:G.lineNumber}},{text:" \u2502 ",style:{fg:G.gutter}},...Ai(o,r)],tone:"default"}})}function jy(e,t,r){let n=Fy(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>Wy(o,r))}function Fy(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 Wy(e,t){let r=ru(e.oldNumber),n=ru(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:G.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:G.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?Uy(Ai(e.text,t),o.bg,o.fallbackFg):Ai(e.text,t),l=o?{fg:G.lineNumber,bg:o.bg}:{fg:G.lineNumber},c=o?{fg:G.gutter,bg:o.bg}:{fg:G.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:o!==null}}function ru(e){return e===null?" ":String(e).padStart(4," ")}function iu(e){let t=Sr.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 Ai(e,t){return t==="diff"?qy(e):t==="markdown"?By(e):t==="json"?Ei(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Ei(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 qy(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:G.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:G.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:G.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:G.diffMeta}}]:[{text:e}]}function Uy(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function By(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:G.markup,bold:!0}}]:Ei(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Ei(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:Vy(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function Vy(e){return e.startsWith("//")||e.startsWith("/*")?{fg:G.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:G.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:G.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:G.markup}:{fg:G.keyword}}function Ky(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"?lu(t.repoTargets??[]):s?.pullRequest??(t?E(t):null),i=[Gy(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=uu(e,t),l=xi(e,r),c=Xy([{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,...oT(e,r)]}:{title:"",rows:[...i,...xi(e,r)]}}function Gy(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=Di(t),i=Oi(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function nu(e){return[{text:" "},Di(e),{text:" "},Oi(e)]}function au(e){if(e.type==="project"&&e.repoTargets?.length){let r=lu(e.repoTargets);return r?nu(r):null}let t=E(e);return t?.number?nu(t):null}function lu(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=zy(r);return{number:-1,status:Hy(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 Hy(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 zy(e){let t=e.map(r=>cu(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 Di(e){return!e||!e.number?{text:Xd,style:{fg:"565f89"}}:e.status==="merged"?{text:Qd,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Zd,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Pi,style:{fg:"565f89"}}:{text:Pi,style:{fg:"9ece6a"}}}function Oi(e){return e?.aggregateReadiness?su(e.aggregateReadiness):su(cu(e))}function su(e){return e==="failed"?{text:Ci,style:{fg:"f7768e"}}:e==="pending"?{text:vi,style:{fg:"e0af68"}}:e==="success"?{text:Ii,style:{fg:"9ece6a"}}:{text:Si,style:{fg:"565f89"}}}function cu(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")?du(e)?"failed":Yy(e)?"success":"pending":"pending"}function Yy(e){return!!(e.mergeable&&!e.draft&&!du(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function du(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function uu(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return Jy(e,t);let r=E(t),n=mu("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 Ln=32;function Jy(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,m=Ln-u.length-1,p=c.length>m?c.slice(0,m-1)+"\u2026":c,k=Ln-p.length-u.length;r.push({id:`project-review:${i.repoId}`,text:p+" ".repeat(Math.max(1,k))+u,selected:a,focused:l,muted:!0})}else{let d=Di(i.pullRequest),u=Oi(i.pullRequest),m=`${d.text} ${u.text}`,p=Ln-m.length-1,k=c.length>p?c.slice(0,p-1)+"\u2026":c,w=Ln-k.length-m.length,b=k+" ".repeat(Math.max(1,w));r.push({id:`project-review:${i.repoId}`,text:b+m,selected:a,focused:l,segments:[{text:b},{...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(...mu("target",o.branch,o.pullRequest))),r}function pu(e,t,r=null){return 3+uu(e,t).length+xi(e,r).length}function mu(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=Qy(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:Zy(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${fu(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(eT)):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,m)=>tT(u,n(`comment:${m}`))))),s}function Xy(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 Qy(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Zy(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function fu(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 eT(e){let{icon:t,color:r}=nT(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," ")} ${sT(e.status)}`,color:r,muted:!1}}function tT(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${fu(e.createdAt)}`:"",s=rT(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 rT(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 nT(e){switch(e){case"success":return{icon:Ii,color:"9ece6a"};case"pending":return{icon:vi,color:"e0af68"};case"failed":return{icon:Ci,color:"f7768e"};case"skipped":return{icon:Si,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function sT(e){return e==="success"?"passing":e==="failed"?"failing":e}function oT(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=$i(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)?Yd:Jd:zd(l.label),m=l.kind==="directory"?"7aa2f7":eu(l.label),p=" ".repeat(l.depth),k=m?{text:u,style:{fg:m}}:{text:u},w=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},b=[{text:p},k,w];return{id:l.path,text:`${p}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:b}})]}function $i(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 xi(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(iT(t))return aT(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=>gu(o,e,t))))}return r}function iT(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function aT(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=>gu(c,e,t,s.length+1))))}}return r}function gu(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 lT(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:Sr.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 cT(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function dT(e,t){return{name:h.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function hu(e,t,r,n,s=null){if(s)return uT(e,t,r,n,s);let o=ti(e,t,{centerOnly:n});return pT(r,o)?{output:An(o.rows,r.rows,o.row,o.column),region:o}:null}function uT(e,t,r,n,s){let o=Zc(e,t,s,{centerOnly:n});if(!o||!mT(r,o))return null;let i=r.rows.slice();return{output:o.rows.map(({index:l,row:c})=>i[l]===c?"":(i[l]=c,`\x1B[${o.row+l};${o.column}H${c}`)).join(""),region:{row:o.row,column:o.column,width:o.width,rows:i}}}function pT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}function mT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rowCount}function wu(e,t,r){let n={...e},s="";for(let o of r){let i=e[o],a=t[o];if(!fT(i,a))return null;!i||!a||(s+=An(a.rows,i.rows,a.row,a.column),n[o]=a)}return{output:s,regions:n}}function fT(e,t){return!e||!t?e===t:e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}var gT=["tasks","center","inspector"];function hT(e,t,r){if(t==="ESCAPE")return R({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return R({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return Mi(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return _i({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return R({state:{...e,fileSearchQuery:n},changed:!0})}return R({state:e})}function _i(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return Fc(t)?R({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):R({state:e});if(e.fileSearchQuery!==null)return hT(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return R({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return R({state:e,exit:!0});if(t==="ESCAPE")return R({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return R({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(hn(e.selectedLeftItemId)||wn(e.selectedLeftItemId)))return R({state:{...e,selectedRunner:gn(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return ku(e,1);if(t==="SHIFT_TAB"||t==="[")return ku(e,-1);if(t==="z"||t==="Z")return R({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===D?Je(e,-1,r):Mi(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===D?Je(e,1,r):Mi(e,1,r);if(t==="PAGE_UP")return Je(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Je(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Je(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Je(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??L,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return R({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=ST(e,t);return R({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 R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return R({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&yr(e.selectedLeftItemId)&&e.selectedTaskId)return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Vc(e.selectedLeftItemId)&&e.selectedWorkspaceId)return R({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Ru(e.activeTab,r.ptyTabIds??[]))return R({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Ni(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return yu(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Ni(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return yu(e,1)}if(he(t)){if(e.focusedRegion==="tasks"&&(hn(e.selectedLeftItemId)||wn(e.selectedLeftItemId))){let n=zo(e.selectedLeftItemId),s=Yo(e.selectedLeftItemId);return R({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 R({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&yr(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return R({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Wt(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Ru(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return R({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Wt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===D)return R({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 R({state:yT({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return R({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:D,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?R({state:{...e,selectedDiffPath:n,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?R({state:e}):e.selectedActionId==="refresh-checks"?R({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return R({state:e})}function Je(e,t,r){if(t===0)return R({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?bu(e,t,r):e.inspectionMode==="review"?Tu(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):R({state:e});if(e.focusedRegion==="center"&&e.activeTab===D){if(e.openInspectionKind==="file")return Tu(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return TT(e,t,r)}return R({state:e})}function ku(e,t){return jn(e,"focusedRegion",gT,t)}function Ni(e,t,r){let n=jn(e,"activeTab",r&&r.length>0?r:vT(e),t);return!n.changed||qc(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Wt(n.state.activeTab)??n.state.preferredPtyTabKind}}}function Mi(e,t,r){if(e.focusedRegion==="tasks")return wT(e,t,r.leftItemIds);if(e.focusedRegion==="center")return Ni(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return bu(e,t,r);if(r.projectTargetIds?.length){let s=Li(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=Li(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:jn(e,"selectedActionId",Nc,t)}return jn(e,"selectedActionId",Vo,t)}function wT(e,t,r){let n=Li(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Ho(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=zo(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=Yo(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function kT(e,t){if(e.inspectionMode===t)return R({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?D:e.activeTab;return R({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 yu(e,t){return kT(e,PT(e.inspectionMode,Ko,t))}function bu(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return R({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=$e(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return R({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return R({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?D:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function yT(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 Tu(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=$e(e[t]+r,0,o);return i===e[t]?R({state:e}):R({state:{...e,[t]:i,actionMessage:null},changed:!0})}function TT(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return RT(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=$e(i,0,o);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let d=$e(i,0,o);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}if(t>0&&i>o){let d=a[l+1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?R({state:e}):R({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let d=a[l-1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?R({state:e}):R({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let c=$e(i,0,o);return c===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function RT(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=$e(e.diffScrollOffset+t,0,o),a=bT(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?R({state:e}):R({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function bT(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function jn(e,t,r,n){let s=r.indexOf(e[t]),o=$e(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?R({state:e}):R({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Li(e,t,r,n,s=!1){if(r.length===0)return R({state:e});let o=r.indexOf(e[t]??r[0]??""),i=$e(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?R({state:e}):R({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function PT(e,t,r){let n=t.indexOf(e);return t[$e(n+r,0,t.length-1)]??e}function R(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 Ru(e,t){return t.includes(e)}function ST(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Wt(e.activeTab)??e.preferredPtyTabKind}function vT(e){return[e.selectedPtyTabId,e.openInspectionKind?D:null].filter(t=>typeof t=="string")}function $e(e,t,r){return Math.min(r,Math.max(t,e))}var Pu=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>x(n.paths,e.selectedTaskId,o=>{let i=t??IT(o,e.activeTab,e.preferredPtyTabKind),a=Cu(o,i,r??void 0,n.config);return{...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id}}));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"}`}}},Su=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={closedTab:null,nextSelectedTab:null};if(await x(t.paths,e.selectedTaskId,o=>{let i=o.ptyTabs.findIndex(l=>l.id===e.activeTab);if(i===-1)throw new Error("Only PTY tabs can be closed.");s.closedTab=o.ptyTabs[i];let a=o.ptyTabs.filter(l=>l.id!==s.closedTab.id);return s.nextSelectedTab=a[Math.min(i,a.length-1)]??null,{...o,ptyTabs:a,selectedPtyTabId:s.nextSelectedTab?.id??null}}),!s.closedTab)throw new Error("Only PTY tabs can be closed.");return{closedTab:s.closedTab,nextSelectedTab:s.nextSelectedTab}});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}`}}},vu=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{await x(t.paths,r,n=>!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab?n:{...n,selectedPtyTabId:e.activeTab})})},Iu=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let o=s.ptyTabs.find(i=>i.kind==="agent")??null;return o?{...s,selectedPtyTabId:o.id}:s})}),{...e,selectedPtyTabId:r.id};let n=Cu(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let o=s.ptyTabs.find(i=>i.kind==="agent")??null;return o?{...s,selectedPtyTabId:o.id}:{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id}})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function IT(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Cu(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(p=>p.id)),c=1,d=a;for(;l.has(d);)c+=1,d=`${a}-${c}`;let u=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:u,updatedAt:u}}var Vt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Au=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=it();at(h.runners.getConfiguredProfile(n,s.config).executable,{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 Vt(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}},Eu=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},xu=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 Jt(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}`}}},Du=async(e,t)=>(await t.taskService.prs.discoverOrRefreshMany(t.paths,e),Promise.all(e.map(r=>Jt(t.paths,r.id)))),Fn=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await Le.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var Ou=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 $u=async(e,t,r)=>{let n=h.runners.setRunnerEnabled(r.config,e,t);return await h.save(r.paths,n),n},Nu=async(e,t,r)=>{let n=h.runners.setRunnerPath(r.config,e,t);return await h.save(r.paths,n),n},Mu=async(e,t,r)=>{let n=h.previews.setEnabled(r.config,e,t);return await h.save(r.paths,n),n};var CT=250;function Ne(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function ht(e,t){return Oe(t,e.ptyRuntime.getViewState(Kt(e,t)))}function Kt(e,t){let r=Ne(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 y(e,t){return ht(e,Kc(t,e.model))}function Lu(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:y(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function _u(e,t,r){return Lu(e,t,r?{tone:"success",message:r}:null)}function B(e,t,r){return Lu(e,t,{tone:"error",message:r})}function V(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return Le.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function q(e,t){if(!e.uiStateFile)return;e.runtimeState=_c(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Me({uiStateFile:e.uiStateFile},r),()=>Me({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function AT(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function K(e){return{paths:e.paths,config:e.config,taskService:S,workspaceService:J,queueTaskMutation:t=>AT(e,t)}}function ji(e,t){let r=Ne(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?$i(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:mt(e.model),centerTabIds:Bc(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:pu(t,r,s),pageRows:Math.max(5,le(e.activeTerminal.width,e.activeTerminal.height).height-W.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function ju(e,t){await vu(t,K(e))}async function Z(e){e.model=await qt(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:y(e,e.state.shell)}:e.state={...e.state,shell:y(e,e.state.shell)}}function Wn(e,t){e.model={...e.model,tasks:[...e.model.tasks.filter(r=>r.id!==t.id),t].sort((r,n)=>r.id.localeCompare(n.id))}}async function qn(e,t){let r=++e.inspectionRefreshSequence,n=Jo(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 bc(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await qt(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=i,e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},q(e,e.state.shell),e.render())}function Fu(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)&&qn(e,r).catch(n=>{let s=V(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},CT))}function Wu(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=Je(e.state.shell,r,ji(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render(),qn(e,e.state.shell).catch(s=>{let o=V(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render()}},16)))}function Fi(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function Wi(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 Uu(e){Wi(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},e.render())})}async function Bu(e,t){let r=y(e,t),n=Ne(e.model.tasks,r),s=Kt(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 Oe(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,ze(le(e.activeTerminal.width,e.activeTerminal.height)));return Oe({...r,inputMode:"control"},i)}function qi(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 Ui(e,t){try{let r=y(e,t),n=Ne(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 qu(e,n),await Z(e),s=n.selectedPtyTabId)}n&&!s&&(n=await qu(e,n),await Z(e),s=n.selectedPtyTabId);let o=y(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:Oe({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},q(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,ze(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ye(s),e.lastTerminalKey=null,e.state={mode:"main",shell:Oe({...o,inputMode:"terminal"},i)},q(e,e.state.shell)}catch(r){let n=V(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Ye(t.selectedPtyTabId)&&(await ET(e,t.selectedTaskId,n).catch(()=>{}),await Z(e).catch(()=>{})),e.state={mode:"main",shell:B(e,jc(y(e,t),n),n)},q(e,e.state.shell)}e.render()}async function ET(e,t,r){await Eu(t,r,K(e))}async function Vu(e,t,r,n){let s=y(e,t),{nextShell:o}=await Pu(s,r,n,K(e));return await Z(e),y(e,{...s,...o})}async function Ku(e,t){let r=y(e,t),{closedTab:n,nextShell:s}=await Su(r,K(e));return e.ptyRuntime.disposeSession(n.id),await Z(e),y(e,{...r,...s})}async function Gu(e,t){let r=y(e,t),n=mt(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await xu(r,K(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await Z(e),y(e,{...r,...i,selectedLeftItemId:xT(n,mt(e.model),s)})}async function Hu(e,t){let r=y(e,t),{nextShell:n}=await Ou(r,K(e));return await Z(e),y(e,{...r,...n})}async function qu(e,t){return Iu(t,K(e))}function Un(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:ht(e,e.state.shell)},e.render())},16))}function xT(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 Yu(e,t,r){if(r?.aborted||e.state.mode!=="main")return;let n=zu(e),s=t.takeDueTasks(e.model.tasks,n);if(s.length!==0)try{let o=await Du(s,K(e));if(r?.aborted||(e.lastBackgroundPrPollError=null,e.state.mode!=="main"))return;for(let i of o)Wn(e,i);t.recordSuccess(o,zu(e)),e.state={mode:"main",shell:y(e,e.state.shell)},e.render()}catch(o){if(r?.aborted)return;t.recordFailure(s,o);let i=o instanceof Error?o.message:"Background PR discovery failed.";i!==e.lastBackgroundPrPollError&&(e.lastBackgroundPrPollError=i,Fn("background PR polling",o,K(e)))}}function zu(e){return e.state.mode!=="main"?{selectedTaskId:null,reviewVisible:!1}:{selectedTaskId:e.state.shell.selectedTaskId,reviewVisible:e.state.shell.inspectionMode==="review"}}async function Ju(e,t){let r=y(e,t),n=Ne(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 Z(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 Z(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${E(a)?.requiredChecks.length??0} reported`)}return y(e,{..._u(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}var DT={pendingForegroundMs:5e3,pendingBackgroundMs:15e3,stableForegroundMs:3e4,stableBackgroundMs:6e4,discoveryForegroundMs:6e4,discoveryBackgroundMs:18e4,rateLimitBaseMs:6e4,rateLimitMaxMs:15*6e4},Bn=class{scheduledTasks=new Map;now;intervals;minimumIntervalMs;rateLimitFailures=0;notBefore=0;constructor(t={}){this.minimumIntervalMs=Math.max(1e3,t.minimumIntervalMs??5e3),this.intervals={...DT,...t.intervals},this.now=t.now??Date.now}takeDueTasks(t,r){let n=this.now(),s=new Set(t.map(i=>i.id));for(let i of this.scheduledTasks.keys())s.has(i)||this.scheduledTasks.delete(i);let o=[];for(let i of t){let a=this.getTaskIntervalMs(i,r);if(a===null){this.scheduledTasks.delete(i.id);continue}let l=this.scheduledTasks.get(i.id);if(!l){this.scheduledTasks.set(i.id,{intervalMs:a,nextPollAt:n}),n>=this.notBefore&&o.push(i);continue}a<l.intervalMs&&(l.nextPollAt=Math.min(l.nextPollAt,n+a)),l.intervalMs=a,n>=this.notBefore&&n>=l.nextPollAt&&o.push(i)}return o}recordSuccess(t,r){let n=this.now();this.rateLimitFailures=0,this.notBefore=0;for(let s of t){let o=this.getTaskIntervalMs(s,r);o===null?this.scheduledTasks.delete(s.id):this.scheduledTasks.set(s.id,{intervalMs:o,nextPollAt:n+o})}}recordFailure(t,r){let n=this.now(),s=r instanceof ye,o=s?Math.min(this.intervals.rateLimitBaseMs*2**this.rateLimitFailures,this.intervals.rateLimitMaxMs):Math.max(this.minimumIntervalMs,this.intervals.pendingBackgroundMs);s&&(this.rateLimitFailures+=1,this.notBefore=n+o);for(let i of t){let a=this.scheduledTasks.get(i.id);a&&(a.nextPollAt=n+o)}}getTaskIntervalMs(t,r){let n=OT(t),s=t.id===r.selectedTaskId&&r.reviewVisible;if(n.length>0){let o=n.some($T);return this.withMinimum(o?s?this.intervals.pendingForegroundMs:this.intervals.pendingBackgroundMs:s?this.intervals.stableForegroundMs:this.intervals.stableBackgroundMs)}return t.status==="checked"?this.withMinimum(s?this.intervals.discoveryForegroundMs:this.intervals.discoveryBackgroundMs):null}withMinimum(t){return Math.max(t,this.minimumIntervalMs)}};function OT(e){return e.type==="project"&&e.repoTargets?.length?e.repoTargets.map(t=>t.pullRequest).filter(t=>t.status==="open"):e.prs.filter(t=>t.status==="open")}function $T(e){return e.requiredChecks.some(t=>t.status==="pending"||t.status==="unknown")}import jT from"node:path";import{readdir as NT,stat as MT}from"node:fs/promises";import Xu from"node:path";async function LT(e){let t=await NT(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=Xu.join(e,n.name);r.push({name:n.name,path:s,kind:await _T(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 Qu(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function Zu(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 Vn(e,t){let r=await LT(t);e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function _T(e){let t=Xu.join(e,".git");return await MT(t).catch(()=>null)!==null}function ep(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function tp(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function FT(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:y(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:y(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:y(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await Au(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,K(e));n=s.task,Wn(e,n);let o=y(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??cd(n,"agent"),ze(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ye(o.selectedPtyTabId),e.state={mode:"main",shell:Oe(o,i)},q(e,e.state.shell)}catch(s){s instanceof Vt&&(n=s.task);let o=V(e,"create task",s,"Failed to create task.");n&&!(s instanceof Vt)?(await x(e.paths,n.id,i=>({...i,status:"draft",runnerSession:{...i.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o})).catch(()=>{}),await Z(e).catch(()=>{})):n&&(await x(e.paths,n.id,i=>({...i,lastFailureReason:o})).catch(()=>{}),await Z(e).catch(()=>{})),e.state={mode:"main",shell:B(e,y(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 WT(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:y(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(he(t)){FT(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:y(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:y(e,{...r,selectedRunner:gn(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}Wc(t)&&(e.state={mode:"main",shell:y(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function qT(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:y(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:y(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:y(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:y(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=Qu(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:y(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:y(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"){Vn(e,jT.dirname(r.cwd)).catch(s=>{let o=V(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:o}}),o)},e.render()});return}if(t==="RIGHT"||t==="l"||he(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){Vn(e,s.path).catch(i=>{let a=V(e,"open workspace directory",i,"Failed to open directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:o}=K(e);o.addWorkspace(e.paths,s.path).then(async i=>{await Z(e);let a=i.repos[0]??null,l=y(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},q(e,e.state.shell),e.render()}).catch(i=>{let a=V(e,"add workspace",i,"Failed to add workspace.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function UT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=Kd(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;BT(e,n)}}}async function BT(e,t){let r;try{r=await Le.readRecentErrorLines(e.paths)}catch(n){let s=V(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 VT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=Hd(ep(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"?$u(r.runner,r.enabled,K(e)):Nu(r.runner,r.path,K(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:y(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=V(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:B(e,y(e,e.state.shell),o),runnerOptions:{...ep(e),message:o}},e.render()})}function KT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=Gd(tp(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}Mu(r.feature,r.enabled,K(e)).then(n=>{e.state.mode!=="overlay"||e.state.variant!=="previews"||(e.config=n,r.feature==="incrementalCenterPane"&&e.ptyRuntime.setViewUpdateMode?.(r.enabled?"incremental":"snapshot"),r.feature==="agentActivityIndicators"&&e.setAgentActivityEnabled(r.enabled),e.state={...e.state,previewOptions:r.state},e.render())}).catch(n=>{if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let s=V(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:B(e,y(e,e.state.shell),s),previewOptions:{...tp(e),message:s}},e.render()})}}function rp(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){WT(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){qT(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){HT(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=_i(e.state.shell,r,ji(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&he(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=br(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(GT(e,r))return;e.lastTerminalKey=dd(r)?{key:r,at:Date.now()}:null;let o=ud(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){Un(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:y(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){Vn(e,e.workspaceRoot).catch(s=>{let o=V(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:B(e,y(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:o}}),o)},e.render()});return}if(n.createPtyTab){Vu(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{Ui(e,s)}).catch(s=>{let o=V(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.closePtyTab){Ku(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.refreshPullRequestChecks){Ju(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.openPrUrl){let s=Ne(e.model.tasks,n.state),o=s?E(s)?.url??null:null;o?Zu(o).catch(i=>{let a=V(e,"open PR URL",i,"Failed to open PR in browser.");e.state={mode:"main",shell:B(e,y(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:B(e,y(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){Gu(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.removeWorkspace){Hu(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.attachTerminal){Ui(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),(e.state.shell.focusedRegion!=="tasks"||!e.renderTaskNavigation())&&e.render(),e.state.shell.focusedRegion==="tasks"){Fu(e,e.state.shell);return}qn(e,e.state.shell).catch(s=>{let o=V(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}n.changed&&(e.state={mode:"main",shell:y(e,n.state)},ju(e,e.state.shell).catch(()=>{}),q(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:y(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){UT(e,r);return}if(e.state.variant==="runners"){VT(e,r);return}if(e.state.variant==="previews"){KT(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||he(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"||he(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:y(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(he(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:y(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;Bu(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},q(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=V(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:B(e,y(e,e.state.shell),i)},q(e,e.state.shell),e.render()})}):Uu(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 np(e,t){let r=hd(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=br(o);if(i){op(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(li(o)){e.pendingTerminalKeySequence.raw=o,sp(e);return}Kn(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:y(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},q(e,e.state.shell),e.render();return}let n=pd(r);if(n!==0){Un(e,n);return}let s=br(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
128
+ `)}}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.notifyFullUpdate(r.tabId);return}let n=this.viewCache.get(r.tabId)??{status:"idle",rows:[],error:null,scrolledBack:!1},s=My(n,r.patch),i=n.rows.slice(0,r.patch.rowCount);for(let o of r.patch.rows)i[o.index]=o.row;this.viewCache.set(r.tabId,{status:r.patch.status,rows:i,error:r.patch.error,scrolledBack:r.patch.scrolledBack}),this.viewUpdateMode==="incremental"&&this.viewedTabId===r.tabId&&this.options.onUpdate?.(s?{tabId:r.tabId,kind:"full"}:{tabId:r.tabId,kind:"rows",rowIndices:r.patch.rows.map(o=>o.index)})}r.type==="activity"&&(this.recordCachedActivity(r.snapshot),this.options.onActivity?.(r.snapshot)),r.type==="activityRemoved"&&this.removeCachedActivity(r.tabId),r.type==="tasksChanged"&&this.tasksChangedHandler?.(r.taskIds)}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.notifyFullUpdate(t)}).catch(()=>{this.subscribedTabId===t&&(this.subscribedTabId=null)}))}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}notifyFullUpdate(t){t&&this.options.onUpdate?.({tabId:t,kind:"full"})}replaceActivityCache(t,r){let n=new Map;for(let[s,i]of this.activityRevisionByTabId)i>r&&n.set(s,this.activityCache.get(s)??null);this.activityCache.clear();for(let s of t)this.activityCache.set(s.tabId,s);for(let[s,i]of n)i?this.activityCache.set(s,i):this.activityCache.delete(s)}async refreshActivitySnapshots(t=!1){let r=this.activityRevision,n=await this.send({type:"getActivitySnapshots"});if(this.replaceActivityCache(n.activities??[],r),t)for(let s of this.activityCache.values())this.options.onActivity?.(s)}recordCachedActivity(t){this.activityRevision+=1,this.activityRevisionByTabId.set(t.tabId,this.activityRevision),this.activityCache.set(t.tabId,t)}removeCachedActivity(t){this.activityRevision+=1,this.activityRevisionByTabId.set(t,this.activityRevision),this.activityCache.delete(t),this.options.onActivityRemoved?.(t)}failRunningActivities(t){for(let r of this.activityCache.values()){if(r.sessionState!=="running")continue;let n={...r,sessionState:"failed",lastActivityAt:Date.now(),error:t};this.recordCachedActivity(n),this.options.onActivity?.(n)}}},Ro=class{onShutdown=null;clients=new Set;subscriptions=new Map;updateTimers=new Map;activityTimers=new Map;pendingActivities=new Map;runtime;paths;orchestrationSupervisor=null;pullRequestSyncSupervisor=null;pullRequestEventReconciliationEnabled=!1;pullRequestSyncOptions;attachedTabId=null;constructor(t,r){this.paths=t,this.pullRequestSyncOptions=r.pullRequestSync;let n={...r};delete n.pullRequestSync,this.runtime=new Nn({...n,workspaceRoot:t.workspaceRoot,activityEnabled:!1,onUpdate:s=>this.handleRuntimeUpdate(s.tabId),onActivity:s=>this.handleActivityUpdate(s),onActivityRemoved:s=>this.handleActivityRemoved(s)})}async start(){let t=await w.load(this.paths);if(this.pullRequestSyncOptions!==!1){let n=this.pullRequestSyncOptions??{},s=n.reconcileEvents===!1?!1:n.reconcileEvents??(()=>Ye(this.paths,{agentObserver:{daemonAvailable:!0,getSnapshots:()=>this.runtime.getActivitySnapshots(),subscribe:()=>()=>{},close:()=>{}}}));this.pullRequestEventReconciliationEnabled=!!s,this.pullRequestSyncSupervisor=new Mn(this.paths,{...n,reconcileEvents:s,minimumIntervalMs:n.minimumIntervalMs??(t.github?.watchIntervalSeconds??5)*1e3,onTasksChanged:async i=>{this.broadcastTasksChanged(i),await n.onTasksChanged?.(i)},onError:async i=>{await Se.appendErrorLogBestEffort(this.paths,{context:"pull request sync supervisor",message:i instanceof Error?i.message:String(i)}),await n.onError?.(i)}}),this.pullRequestSyncSupervisor.start(),this.updateRuntimeActivityEnabled()}let r=(await $e(this.paths)).some(n=>n.state==="queued"||n.state==="delivering");(w.previews.isEnabled(t,"agentOrchestration")||r)&&await this.ensureOrchestrationSupervisor()}async stop(){await this.pullRequestSyncSupervisor?.stop(),this.pullRequestSyncSupervisor=null,this.pullRequestEventReconciliationEnabled=!1,this.updateRuntimeActivityEnabled(),await this.orchestrationSupervisor?.stop(),this.orchestrationSupervisor=null}handleConnection(t){let r="";this.clients.add(t),this.subscriptions.set(t,{mode:"snapshot",activityEnabled:!1,tabId:null,view:null,rowKeys:[],pullRequestPollView:{selectedTaskId:null,reviewVisible:!1}}),t.setEncoding("utf8"),t.on("data",s=>{r+=String(s);let i=r.indexOf(`
129
+ `);for(;i!==-1;){let o=r.slice(0,i);r=r.slice(i+1),this.handleLine(t,o),i=r.indexOf(`
130
+ `)}});let n=()=>{this.clients.delete(t),this.subscriptions.delete(t),this.pullRequestSyncSupervisor?.setView(this.getPullRequestPollView()),this.hasActivitySubscribers()||(this.updateRuntimeActivityEnabled(),this.clearPendingActivityBroadcasts())};t.on("close",n),t.on("error",n)}disposeAll(){for(let t of this.updateTimers.values())clearTimeout(t);this.updateTimers.clear();for(let t of this.activityTimers.values())clearTimeout(t);this.activityTimers.clear(),this.pendingActivities.clear(),this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear(),this.subscriptions.clear(),this.updateRuntimeActivityEnabled()}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=await this.handleRequest(t,n);et(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:_d}:{},...n.type==="getActivitySnapshots"?{activities:this.runtime.getActivitySnapshots()}:{},...s?{view:s}:{}})}catch(s){let i=s instanceof Error?s.message:String(s);et(t,{id:n.id,ok:!1,error:i})}}async 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"setActivityEnabled":return this.setActivityEnabled(t,r.enabled),null;case"subscribeView":return this.subscribe(t,r.tabId,this.runtime.getViewState(r.tabId));case"pruneStale":{let n=new Set(r.keepTabIds),s=new Set([...this.runtime.sessionTabIds(),...this.runtime.getActivitySnapshots().map(i=>i.tabId)]);for(let i of s)n.has(i)||(this.runtime.disposeSession(i),this.attachedTabId===i&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(r.tabId);case"getActivitySnapshots":return null;case"setPullRequestPollView":return this.setPullRequestPollView(t,r.view),null;case"wakeOrchestration":return await this.ensureOrchestrationSupervisor(),await this.orchestrationSupervisor.wake(),null;case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return Uy(r)}}subscribe(t,r,n){let s=this.subscriptions.get(t),i=s?.mode??"snapshot";return this.subscriptions.set(t,{mode:i,activityEnabled:s?.activityEnabled??!1,tabId:r,view:n,rowKeys:n.rows.map(Ln),pullRequestPollView:s?.pullRequestPollView??{selectedTaskId:null,reviewVisible:!1}}),n}setViewUpdateMode(t,r){let n=this.subscriptions.get(t),s=n?.tabId??null,i=this.runtime.getViewState(s);return this.subscriptions.set(t,{mode:r,activityEnabled:n?.activityEnabled??!1,tabId:s,view:i,rowKeys:i.rows.map(Ln),pullRequestPollView:n?.pullRequestPollView??{selectedTaskId:null,reviewVisible:!1}}),i}setActivityEnabled(t,r){let n=this.subscriptions.get(t);if(!n)return;this.subscriptions.set(t,{...n,activityEnabled:r});let s=this.hasActivitySubscribers();this.updateRuntimeActivityEnabled(),s||this.clearPendingActivityBroadcasts()}setPullRequestPollView(t,r){let n=this.subscriptions.get(t);n&&(this.subscriptions.set(t,{...n,pullRequestPollView:r}),this.pullRequestSyncSupervisor?.setView(this.getPullRequestPollView()))}getPullRequestPollView(){let t=[...this.subscriptions.values()].map(r=>r.pullRequestPollView);return t.find(r=>r.selectedTaskId&&r.reviewVisible)??t.find(r=>r.selectedTaskId)??{selectedTaskId:null,reviewVisible:!1}}broadcastTasksChanged(t){for(let r of this.clients)et(r,{type:"tasksChanged",taskIds:t})}handleRuntimeUpdate(t){let r=null;for(let n of this.clients)this.subscriptions.get(n)?.mode==="snapshot"&&(r??=this.runtime.getViewState(t),et(n,{type:"update",tabId:t,view:r}));this.scheduleBroadcastUpdate(t)}handleActivityUpdate(t){if(this.pullRequestSyncSupervisor?.notifyActivity(t),!!this.hasActivitySubscribers()){if(this.pendingActivities.set(t.tabId,t),t.sessionState!=="running"){let r=this.activityTimers.get(t.tabId);r&&(clearTimeout(r),this.activityTimers.delete(t.tabId)),this.broadcastActivity(t.tabId);return}this.activityTimers.has(t.tabId)||this.activityTimers.set(t.tabId,setTimeout(()=>{this.activityTimers.delete(t.tabId),this.broadcastActivity(t.tabId)},Dy))}}handleActivityRemoved(t){this.pullRequestSyncSupervisor?.notifyActivityRemoved(t);let r=this.activityTimers.get(t);r&&(clearTimeout(r),this.activityTimers.delete(t)),this.pendingActivities.delete(t);for(let[n,s]of this.subscriptions)s.activityEnabled&&et(n,{type:"activityRemoved",tabId:t})}broadcastActivity(t){let r=this.pendingActivities.get(t);if(r){this.pendingActivities.delete(t);for(let[n,s]of this.subscriptions)s.activityEnabled&&et(n,{type:"activity",snapshot:r})}}hasActivitySubscribers(){return[...this.subscriptions.values()].some(t=>t.activityEnabled)}clearPendingActivityBroadcasts(){for(let t of this.activityTimers.values())clearTimeout(t);this.activityTimers.clear(),this.pendingActivities.clear()}async ensureOrchestrationSupervisor(){if(this.orchestrationSupervisor)return;let t=new On(this.paths,this.runtime,{onError:r=>Se.appendErrorLogBestEffort(this.paths,{context:"orchestration supervisor",message:r instanceof Error?r.message:String(r)})});await t.start(),this.orchestrationSupervisor=t,this.updateRuntimeActivityEnabled()}updateRuntimeActivityEnabled(){this.runtime.setActivityEnabled(this.orchestrationSupervisor!==null||this.pullRequestEventReconciliationEnabled||this.hasActivitySubscribers())}scheduleBroadcastUpdate(t){this.updateTimers.has(t)||!this.hasViewSubscriber(t)||this.updateTimers.set(t,setTimeout(()=>{this.updateTimers.delete(t),this.broadcastUpdate(t)},xy))}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 i=Oy(s,r),o=$y(s.view,r);s.view=r,s.rowKeys=r.rows.map(Ln),(i.rows.length>0||o)&&et(n,{type:"update",tabId:t,patch:i})}}};function Oy(e,t){let r=[];for(let n=0;n<t.rows.length;n+=1){let s=t.rows[n];e.rowKeys[n]!==Ln(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 $y(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 My(e,t){return e.status!==t.status||e.error!==t.error||(e.scrolledBack??!1)!==t.scrolledBack||e.rows.length!==t.rowCount}function Ln(e){return JSON.stringify(e)}async function Ny(e,t,r){if(await Ly(e.socketPath,1e3))return;await jn(e.socketPath)&&(await Vd(e.socketPath),await Nd(e.socketPath,1e3)),await jn(e.socketPath)&&(await Fy(e),await Nd(e.socketPath,1e3)),await jy(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:o,args:a}=_y(n),l=Iy(_n.join(t.runtimeDir,"pty-daemon.log"),"a");Sy(o,a,{cwd:n,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await qd(e.socketPath))return;await Po(50)}let i=await bo(_n.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${i?`
131
+ ${i.slice(-2e3)}`:""}`)}async function qd(e){let t=await Wy(e).catch(()=>null);return t?.ok===!0&&Ud(t.protocolVersion)}function Ud(e){return e!==void 0&&Ey.has(e)}async function Ly(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await qd(e))return!0;await Po(50)}return!1}function _y(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=_n.resolve(_n.dirname(t),"..","node_modules",".bin","tsx");return{command:Ds("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 jy(e){let t=await bo(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&Gd(r))return}await wt(e.socketPath,{force:!0}),await wt(e.pidPath,{force:!0})}async function jn(e){let t=await Kd(e).catch(()=>null);return t?(t.end(),!0):!1}async function Vd(e){await Bd(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Fy(e){let t=await bo(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!Gd(r)){await wt(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await wt(e.socketPath,{force:!0})}}async function Wy(e){return Bd(e,{id:1,type:"ping"})}function Bd(e,t){return new Promise((r,n)=>{let s=Ld(e),i="",o=setTimeout(()=>{s.destroy(),n(new Error("Craig PTY daemon request timed out."))},500),a=()=>clearTimeout(o);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
132
+ `)),s.once("error",l=>{a(),n(l)}),s.on("data",l=>{i+=String(l);let c=i.indexOf(`
133
+ `);if(c===-1)return;let d=i.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 Nd(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await jn(e))return;await Po(50)}}function Kd(e){return new Promise((t,r)=>{let n=Ld(e);n.once("connect",()=>t(n)),n.once("error",r)})}function qy(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)}
134
+ `)}catch{}}function Gd(e){try{return process.kill(e,0),!0}catch{return!1}}function Po(e){return new Promise(t=>setTimeout(t,e))}function Uy(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var So=["Runners","Feature Previews","Error Log","Help"],zd={incrementalCenterPane:"Incremental center pane",agentActivityIndicators:"Agent activity indicators",agentOrchestration:"Agent orchestration"};function vo(e,t){return _.map(r=>{let n=w.runners.getProfile(r),s=e.runners?.[r]?.enabled!==!1,i=e.runners?.[r]?.path?.trim(),o=t.pathEdit?.runner===r?`${t.pathEdit.value}_`:i&&i.length>0?i:`default (${n.executable})`;return`${n.displayName} ${s?"enabled":"disabled"} ${o}`})}function Yd(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 Jd(e){return ge.map(t=>`${w.previews.isEnabled(e,t)?"[x]":"[ ]"} ${zd[t]}`)}function Xd(e){return e.message??"Experimental features may change or be removed. Enter toggles."}function Qd(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(So.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Fn(t)?e===0?{kind:"runners"}:e===1?{kind:"previews"}:e===2?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Zd(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(ge.length-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(!Fn(r))return{kind:"noop",state:e};let n=ge[e.menuIndex]??ge[0],s=!w.previews.isEnabled(t,n);return{kind:"save-enabled",feature:n,enabled:s,state:{...e,message:`${zd[n]} ${s?"enabled":"disabled"}.`}}}function eu(e,t,r,n){if(e.pathEdit)return Vy({...e,pathEdit:e.pathEdit},t,r);let s=vo(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(!Fn(r))return{kind:"noop",state:e};let i=_[e.menuIndex]??"codex",o=t.runners?.[i]?.enabled!==!1;return o&&n.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save-enabled",runner:i,enabled:!o,state:{...e,message:`${w.runners.getProfile(i).displayName} ${o?"disabled":"enabled"}.`}}}function Vy(e,t,r){if(r==="ESCAPE")return{kind:"render",state:Hd({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Fn(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:Hd({...e,message:s.length>0?`${w.runners.getProfile(n).displayName} executable saved.`:`${w.runners.getProfile(n).displayName} executable reset to default.`})}}return By(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function Hd(e){let t={...e};return delete t.pathEdit,t}function Fn(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
135
+ `}function By(e){return e.length===1&&e>=" "&&e!==""}import Ir from"node:path";function tu(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 ru="\u{F024B} ",nu="\u{F0DCF} ",su="\u25CB",Io="\uEA64",iu="\uEAFE",ou="\uEBDA",Co="\u25CB",Ao="\u25CF",Eo="\u2713",xo="\u2715";function au(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 Wn=150,lu=6;var Un="empty",z={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function pu(e,t,r){let n=Hy(t,e),s=t.repos.find(b=>b.id===e.selectedRepoId)??t.repos[0]??null,i=n?t.tasks.filter(b=>b.workspaceId===n.id):t.tasks,o=n?.kind==="project"?i:s?i.filter(b=>b.repoId===s.id):[],a=o.find(b=>b.id===e.selectedTaskId)??o[0]??null,l=a?.type==="project",c=CT(t.tasks),d=Jy(e,a),u=Yy(e,a,d,r),f=u.find(b=>b.id===d)??u[0]??{id:"agent",label:"CODEX"},h=t.inspection?.taskId===a?.id?t.inspection:null,m=s?.name??"no repo",k=a?w.runners.getDisplayName(a.runner):w.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 ${s?`[${s.name}]`:"[no repo]"} \xB7 ${w.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 [${w.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:Rr(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"?a===null?"n new task Tab tasks Esc pause ? help":d===D?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${w.runners.getDisplayName(e.centerTabRunner??a?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?l?"\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:Ir.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Ir.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:k},leftTree:Ky(e,t,r),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(b=>AT(b,c[b])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":f.label,taskId:e.workspaceBrowser?"new workspace":a?.id??"no task",repo:m,agent:k},centerTranscript:zy(d,e,s,a,e.workspaceBrowser,h,n),tabs:u,rightContext:IT(s,a),rightInspection:cT(e,a,h)}}function Ky(e,t,r){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return Gy(n,e,t.repos,t.tasks,r);let s=t.workspaces;if(s.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of s){let a=e.selectedLeftItemId===`workspace:${o.id}`;n.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:a,focused:a&&e.focusedRegion==="tasks"});let l=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],c=t.tasks.filter(d=>d.workspaceId===o.id);if(c.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of c){let u=e.selectedLeftItemId===`task:${d.id}`,f=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,h={id:`task:${d.id}`,taskId:d.id,text:r?f:`${u?"\u25B8":"\u2022"} ${f}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",...r?{activity:Nt(d,r.snapshots,r.now),activityAnimationFrame:r.animationFrame}:{}},m=fu(d);m&&(h.prBadge=m),n.push(h)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${w.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${w.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}else{n.push({text:` Repos (${l.length})`,indent:0,muted:!0});for(let d of l.slice(0,6)){let u=t.repos.find(f=>f.id===d);n.push({text:` \xB7 ${u?.name??d}`,indent:0,muted:!0})}l.length>6&&n.push({text:` \xB7 ${l.length-6} more`,indent:0,muted:!0})}}let i=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:i,focused:i&&e.focusedRegion==="tasks"}),n}function Gy(e,t,r,n,s){if(r.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of r){let a=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:a,focused:a&&t.focusedRegion==="tasks"});let l=n.filter(u=>u.repoId===o.id);if(l.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let u of l){let f=t.selectedLeftItemId===`task:${u.id}`,h=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,m={id:`task:${u.id}`,taskId:u.id,text:s?h:`${f?"\u25B8":"\u2022"} ${h}`,indent:2,selected:f,focused:f&&t.focusedRegion==="tasks",...s?{activity:Nt(u,s.snapshots,s.now),activityAnimationFrame:s.animationFrame}:{}},k=fu(u);k&&(m.prBadge=k),e.push(m)}let c=`new-task:${o.id}`,d=t.selectedLeftItemId===c;e.push({id:c,text:`+ New Task [${w.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let i=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:i,focused:i&&t.focusedRegion==="tasks"}),e}function Hy(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 zy(e,t,r,n,s,i=null,o=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,f)=>{let h=f===s.selectedIndex?"\u25B8":" ",m=u.kind==="repo"?" [git repo]":"/";return`${h} ${u.name}${m}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return ke(["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 ke(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let l=o?.kind==="project",c=l?o.name??"this workspace":r.name,d=l?"Project Task":"Task";return ke([`No tasks in ${c}.`,"",`Press n or choose + New ${d} to create one with ${w.runners.getDisplayName(t.selectedRunner)}.`])}let a=n.ptyTabs.find(l=>l.id===e)??null;return a?a.kind==="agent"?ke([`${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."]):ke([`${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===D&&t.openInspectionKind==="file"?Zy(n,i,t.fileScrollOffset):e===D&&t.openInspectionKind==="diff"?eT(n,i,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?ke(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ke(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Yy(e,t,r,n){let s=t?.ptyTabs.map(o=>({id:o.id,label:Xy(o),...o.kind==="agent"&&n&&t?{activity:Ge(t,o.id,n.snapshots,n.now),activityAnimationFrame:n.animationFrame}:{}}))??[];if(!t)return[{id:Un,label:"EMPTY",active:r===Un,focused:e.focusedRegion==="center"&&r===Un}];let i=e.openInspectionKind||r===D?[{id:D,label:Qy(e)}]:[];return[...s,...i].map(o=>({...o,active:o.id===r,focused:e.focusedRegion==="center"&&o.id===r}))}function Jy(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===D&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??D:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??D:Un}function Xy(e){return e.title.toUpperCase()}function Qy(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?Ir.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function Zy(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ke(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=mu(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:""},...tT(n.lines,r,s)]}function eT(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ke(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=mu(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:""},...rT(n.lines,r,s)]}function ke(e){return e.map(t=>({text:t}))}function tT(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((i,o)=>{let a=s+o+1;return{text:`${`${String(a).padStart(n," ")} \u2502 `}${i}`,segments:[{text:String(a).padStart(n," "),style:{fg:z.lineNumber}},{text:" \u2502 ",style:{fg:z.gutter}},...Do(i,r)],tone:"default"}})}function rT(e,t,r){let n=nT(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(i=>sT(i,r))}function nT(e){let t=[],r=0,n=0;for(let s of e){let i=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(i){r=Number.parseInt(i[1]??"0",10),n=Number.parseInt(i[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 sT(e,t){let r=cu(e.oldNumber),n=cu(e.newNumber),s=e.kind==="delete"?r:n,i=e.kind==="delete"?{bg:"2a1111",fallbackFg:z.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:z.diffAdd}:null,o=`${s} \u2502 ${e.text}`,a=i?oT(Do(e.text,t),i.bg,i.fallbackFg):Do(e.text,t),l=i?{fg:z.lineNumber,bg:i.bg}:{fg:z.lineNumber},c=i?{fg:z.gutter,bg:i.bg}:{fg:z.gutter};return{text:o,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:i!==null}}function cu(e){return e===null?" ":String(e).padStart(4," ")}function mu(e){let t=Ir.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 Do(e,t){return t==="diff"?iT(e):t==="markdown"?aT(e):t==="json"?Oo(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Oo(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 iT(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:z.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:z.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:z.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:z.diffMeta}}]:[{text:e}]}function oT(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function aT(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:z.markup,bold:!0}}]:Oo(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Oo(e,t){let r=[],n=0;for(let s of e.matchAll(t)){let i=s[0],o=s.index??0;o>n&&r.push({text:e.slice(n,o)}),r.push({text:i,style:lT(i)}),n=o+i.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function lT(e){return e.startsWith("//")||e.startsWith("/*")?{fg:z.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:z.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:z.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:z.markup}:{fg:z.keyword}}function cT(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,i=t?.type==="project"?gu(t.repoTargets??[]):s?.pullRequest??(t?E(t):null),o=[dT(e,i),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=ku(e,t),l=$o(e,r),c=gT([{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:[...o,...c]}}return e.inspectionMode==="files"?{title:"",rows:[...o,...PT(e,r)]}:{title:"",rows:[...o,...$o(e,r)]}}function dT(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 i=Mo(t),o=No(t);return s.push({text:" "},i,{text:" "},o),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function du(e){return[{text:" "},Mo(e),{text:" "},No(e)]}function fu(e){if(e.type==="project"&&e.repoTargets?.length){let r=gu(e.repoTargets);return r?du(r):null}let t=E(e);return t?.number?du(t):null}function gu(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=pT(r);return{number:-1,status:uT(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 uT(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 pT(e){let t=e.map(r=>hu(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 Mo(e){return!e||!e.number?{text:su,style:{fg:"565f89"}}:e.status==="merged"?{text:iu,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:ou,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Io,style:{fg:"565f89"}}:{text:Io,style:{fg:"9ece6a"}}}function No(e){return e?.aggregateReadiness?uu(e.aggregateReadiness):uu(hu(e))}function uu(e){return e==="failed"?{text:xo,style:{fg:"f7768e"}}:e==="pending"?{text:Ao,style:{fg:"e0af68"}}:e==="success"?{text:Eo,style:{fg:"9ece6a"}}:{text:Co,style:{fg:"565f89"}}}function hu(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")?wu(e)?"failed":mT(e)?"success":"pending":"pending"}function mT(e){return!!(e.mergeable&&!e.draft&&!wu(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function wu(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function ku(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return fT(e,t);let r=E(t),n=Tu("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(i=>i!==r&&(i.status==="merged"||i.status==="closed")).length;return s>0&&n.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),n}var qn=32;function fT(e,t){let r=[],n=t.repoTargets??[],s=e.selectedProjectTargetId??n[0]?.repoId??null;for(let o of n){let a=s===o.repoId,l=e.focusedRegion==="inspector"&&a,c=o.repoId.startsWith("repo_")?o.repoId.slice(5):o.repoId;if(o.status!=="ready"){let u=o.failureReason?o.failureReason.slice(0,14):o.status,f=qn-u.length-1,h=c.length>f?c.slice(0,f-1)+"\u2026":c,m=qn-h.length-u.length;r.push({id:`project-review:${o.repoId}`,text:h+" ".repeat(Math.max(1,m))+u,selected:a,focused:l,muted:!0})}else{let d=Mo(o.pullRequest),u=No(o.pullRequest),f=`${d.text} ${u.text}`,h=qn-f.length-1,m=c.length>h?c.slice(0,h-1)+"\u2026":c,k=qn-m.length-f.length,b=m+" ".repeat(Math.max(1,k));r.push({id:`project-review:${o.repoId}`,text:b+f,selected:a,focused:l,segments:[{text:b},{...d,text:d.text},{text:" "},{...u,text:u.text}]})}}let i=n.find(o=>o.repoId===s)??null;return i?.status==="ready"&&i.pullRequest.number&&(r.push({id:"target-detail-spacer",text:""}),r.push(...Tu("target",i.branch,i.pullRequest))),r}function yu(e,t,r=null){return 3+ku(e,t).length+$o(e,r).length}function Tu(e,t,r){let n=u=>`${e}-${u}`;if(!r.number)return[{id:n("no-pr"),text:t,muted:!0}];let s=[],i=`#${r.number}`;s.push(r.url?{id:n("pr-number"),text:`${i} Open in GitHub \u2197`,segments:[{text:i},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:r.url}]}:{id:n("pr-number"),text:i});let o=r.baseBranch??"?",a=r.headBranch??t;s.push({id:n("pr-branches"),text:`${o} \u2192 ${a}`,muted:!0});let l=hT(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:wT(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${Ru(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(kT)):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,f)=>yT(u,n(`comment:${f}`))))),s}function gT(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 hT(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function wT(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function Ru(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 kT(e){let{icon:t,color:r}=RT(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," ")} ${bT(e.status)}`,color:r,muted:!1}}function yT(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${Ru(e.createdAt)}`:"",s=TT(e.body,30),i=s.slice(0,4),o=i.length<s.length,a=[{id:`${t}:author`,text:`${r}${n}`,muted:!0},...i.map((l,c)=>({id:`${t}:body:${c}`,text:` ${o&&c===i.length-1?`${l}\u2026`:l}`,muted:!0}))];return a.push({id:`${t}:spacer`,text:"",muted:!0}),a}function TT(e,t){let r=e.split(/\s+/).filter(Boolean);if(r.length===0)return[];let n=[],s="";for(let i of r){if(!s){s=i;continue}`${s} ${i}`.length<=t?s=`${s} ${i}`:(n.push(s),s=i)}return s&&n.push(s),n}function RT(e){switch(e){case"success":return{icon:Eo,color:"9ece6a"};case"pending":return{icon:Ao,color:"e0af68"};case"failed":return{icon:xo,color:"f7768e"};case"skipped":return{icon:Co,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function bT(e){return e==="success"?"passing":e==="failed"?"failing":e}function PT(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=Lo(t.fileRows,e.collapsedFileTreePaths),s=e.fileSearchQuery,i=s?n.filter(l=>l.path.toLowerCase().includes(s.toLowerCase())):n,o=s!==null?[{id:"file-search",text:`Search: ${s}\u2588`,muted:!1}]:[],a=e.selectedFileTreePath??t.selectedFilePath;return[...o,...i.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)?ru:nu:tu(l.label),f=l.kind==="directory"?"7aa2f7":au(l.label),h=" ".repeat(l.depth),m=f?{text:u,style:{fg:f}}:{text:u},k=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},b=[{text:h},m,k];return{id:l.path,text:`${h}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:b}})]}function Lo(e,t){let r=new Set(t);return e.filter(n=>{let s=n.path.split("/");for(let i=1;i<s.length;i+=1)if(r.has(s.slice(0,i).join("/")))return!1;return!0})}function $o(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(ST(t))return vT(e,t);let r=[];for(let n of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(i=>i.group===n);s.length!==0&&(r.push({id:n,text:n.toUpperCase(),muted:!0}),r.push(...s.map(i=>bu(i,e,t))))}return r}function ST(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function vT(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 i=t.diffRows.filter(a=>a.path.startsWith(`${s}/`)),o=s.startsWith("repo_")?s.slice(5):s;r.push({id:`repo-diff:${s}`,text:o,muted:!0});for(let a of["branch","staged","unstaged","untracked"]){let l=i.filter(c=>c.group===a);l.length!==0&&(r.push({id:`repo-diff:${s}:${a}`,text:` ${a}`,muted:!0}),r.push(...l.map(c=>bu(c,e,t,s.length+1))))}}return r}function bu(e,t,r,n=0){let s=e.additions===null?"-":`+${e.additions}`,i=e.deletions===null?"-":`-${e.deletions}`,o=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}/${i}`,selected:e.path===(t.selectedDiffPath??r.selectedDiffPath),focused:e.path===(t.selectedDiffPath??r.selectedDiffPath)&&t.focusedRegion==="inspector",color:o}}function IT(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:w.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Ir.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 CT(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function AT(e,t){return{name:w.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function Pu(e,t,r,n,s=null){if(s)return ET(e,t,r,n,s);let i=no(e,t,{centerOnly:n});return xT(r,i)?{output:Dn(i.rows,r.rows,i.row,i.column),region:i}:null}function ET(e,t,r,n,s){let i=id(e,t,s,{centerOnly:n});if(!i||!DT(r,i))return null;let o=r.rows.slice();return{output:i.rows.map(({index:l,row:c})=>o[l]===c?"":(o[l]=c,`\x1B[${i.row+l};${i.column}H${c}`)).join(""),region:{row:i.row,column:i.column,width:i.width,rows:o}}}function xT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}function DT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rowCount}function Su(e,t,r){let n={...e},s="";for(let i of r){let o=e[i],a=t[i];if(!OT(o,a))return null;!o||!a||(s+=Dn(a.rows,o.rows,a.row,a.column),n[i]=a)}return{output:s,regions:n}}function OT(e,t){return!e||!t?e===t:e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}var $T=["tasks","center","inspector"];function MT(e,t,r){if(t==="ESCAPE")return R({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return R({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return jo(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return Wo({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return R({state:{...e,fileSearchQuery:n},changed:!0})}return R({state:e})}function Wo(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return Kc(t)?R({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):R({state:e});if(e.fileSearchQuery!==null)return MT(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return R({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return R({state:e,exit:!0});if(t==="ESCAPE")return R({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return R({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(yn(e.selectedLeftItemId)||Tn(e.selectedLeftItemId)))return R({state:{...e,selectedRunner:kn(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return vu(e,1);if(t==="SHIFT_TAB"||t==="[")return vu(e,-1);if(t==="z"||t==="Z")return R({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===D?tt(e,-1,r):jo(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===D?tt(e,1,r):jo(e,1,r);if(t==="PAGE_UP")return tt(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return tt(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return tt(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return tt(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??_,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,i=s===n.length-1?null:n[s+1];return R({state:{...e,centerTabRunner:i,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let n=UT(e,t);return R({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 R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return R({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Rr(e.selectedLeftItemId)&&e.selectedTaskId)return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Jc(e.selectedLeftItemId)&&e.selectedWorkspaceId)return R({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Au(e.activeTab,r.ptyTabIds??[]))return R({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return _o(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return Iu(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return _o(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return Iu(e,1)}if(he(t)){if(e.focusedRegion==="tasks"&&(yn(e.selectedLeftItemId)||Tn(e.selectedLeftItemId))){let n=Ji(e.selectedLeftItemId),s=Xi(e.selectedLeftItemId);return R({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 R({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&Rr(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return R({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:qt(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Au(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return R({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:qt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===D)return R({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 R({state:_T({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return R({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:D,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?R({state:{...e,selectedDiffPath:n,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?R({state:e}):e.selectedActionId==="refresh-checks"?R({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return R({state:e})}function tt(e,t,r){if(t===0)return R({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?Eu(e,t,r):e.inspectionMode==="review"?Cu(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):R({state:e});if(e.focusedRegion==="center"&&e.activeTab===D){if(e.openInspectionKind==="file")return Cu(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return jT(e,t,r)}return R({state:e})}function vu(e,t){return Vn(e,"focusedRegion",$T,t)}function _o(e,t,r){let n=Vn(e,"activeTab",r&&r.length>0?r:VT(e),t);return!n.changed||Hc(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:qt(n.state.activeTab)??n.state.preferredPtyTabKind}}}function jo(e,t,r){if(e.focusedRegion==="tasks")return NT(e,t,r.leftItemIds);if(e.focusedRegion==="center")return _o(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Eu(e,t,r);if(r.projectTargetIds?.length){let s=Fo(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=Fo(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:Vn(e,"selectedActionId",Wc,t)}return Vn(e,"selectedActionId",Gi,t)}function NT(e,t,r){let n=Fo(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Yi(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 i=Ji(n.state.selectedLeftItemId);if(i)return{...n,state:{...n.state,selectedRepoId:i}};let o=Xi(n.state.selectedLeftItemId);return o?{...n,state:{...n.state,selectedWorkspaceId:o}}:n}function LT(e,t){if(e.inspectionMode===t)return R({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?D:e.activeTab;return R({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 Iu(e,t){return LT(e,qT(e.inspectionMode,Hi,t))}function Eu(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return R({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,i=n.indexOf(s??""),o=Le(i===-1?0:i+t,0,n.length-1),a=n[o]??null;if(a===e.selectedFileTreePath)return R({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return R({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?D:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function _T(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 Cu(e,t,r,n,s=10){let i=Math.max(0,n-Math.max(1,s)),o=Le(e[t]+r,0,i);return o===e[t]?R({state:e}):R({state:{...e,[t]:o,actionMessage:null},changed:!0})}function jT(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return FT(e,t,r);let n=r.diffLineCount??0,s=r.pageRows??10,i=Math.max(0,n-Math.max(1,s)),o=e.diffScrollOffset+t,a=r.diffPathIds??[];if(a.length===0||!e.selectedDiffPath){let d=Le(o,0,i);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let d=Le(o,0,i);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}if(t>0&&o>i){let d=a[l+1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===i?R({state:e}):R({state:{...e,diffScrollOffset:i,actionMessage:null},changed:!0})}if(t<0&&o<0){let d=a[l-1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?R({state:e}):R({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let c=Le(o,0,i);return c===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function FT(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,i=Math.max(0,n-Math.max(1,s)),o=Le(e.diffScrollOffset+t,0,i),a=WT(r.diffPathRanges??[],o)??e.selectedDiffPath;return o===e.diffScrollOffset&&a===e.selectedDiffPath?R({state:e}):R({state:{...e,diffScrollOffset:o,selectedDiffPath:a,actionMessage:null},changed:!0})}function WT(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function Vn(e,t,r,n){let s=r.indexOf(e[t]),i=Le(s+n,0,r.length-1),o=r[i];return!o||o===e[t]?R({state:e}):R({state:{...e,[t]:o,actionMessage:null},changed:!0})}function Fo(e,t,r,n,s=!1){if(r.length===0)return R({state:e});let i=r.indexOf(e[t]??r[0]??""),o=Le(i===-1?0:i+n,0,r.length-1),a=r[o]??null;return a===e[t]?R({state:e}):R({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function qT(e,t,r){let n=t.indexOf(e);return t[Le(n+r,0,t.length-1)]??e}function R(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 Au(e,t){return t.includes(e)}function UT(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":qt(e.activeTab)??e.preferredPtyTabKind}function VT(e){return[e.selectedPtyTabId,e.openInspectionKind?D:null].filter(t=>typeof t=="string")}function Le(e,t,r){return Math.min(r,Math.max(t,e))}var xu=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>x(n.paths,e.selectedTaskId,i=>{let o=t??BT(i,e.activeTab,e.preferredPtyTabKind),a=Mu(i,o,r??void 0,n.config);return{...i,ptyTabs:[...i.ptyTabs,a],selectedPtyTabId:a.id}}));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"}`}}},Du=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={closedTab:null,nextSelectedTab:null};if(await x(t.paths,e.selectedTaskId,i=>{let o=i.ptyTabs.findIndex(l=>l.id===e.activeTab);if(o===-1)throw new Error("Only PTY tabs can be closed.");s.closedTab=i.ptyTabs[o];let a=i.ptyTabs.filter(l=>l.id!==s.closedTab.id);return s.nextSelectedTab=a[Math.min(o,a.length-1)]??null,{...i,ptyTabs:a,selectedPtyTabId:s.nextSelectedTab?.id??null}}),!s.closedTab)throw new Error("Only PTY tabs can be closed.");return{closedTab:s.closedTab,nextSelectedTab:s.nextSelectedTab}});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}`}}},Ou=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{await x(t.paths,r,n=>!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab?n:{...n,selectedPtyTabId:e.activeTab})})},$u=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let i=s.ptyTabs.find(o=>o.kind==="agent")??null;return i?{...s,selectedPtyTabId:i.id}:s})}),{...e,selectedPtyTabId:r.id};let n=Mu(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let i=s.ptyTabs.find(o=>o.kind==="agent")??null;return i?{...s,selectedPtyTabId:i.id}:{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id}})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function BT(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Mu(e,t,r,n={}){let s=r??e.runner,i=w.runners.getProfile(s),o=t==="agent"?i.defaultAgentTitle:"Terminal",a=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(h=>h.id)),c=1,d=a;for(;l.has(d);)c+=1,d=`${a}-${c}`;let u=new Date().toISOString(),f=r&&r!==e.runner?r:void 0;return{id:d,kind:t,...f?{runner:f}:{},title:c===1?o:`${o} ${c}`,command:t==="agent"?w.runners.buildCommand(s,void 0,n):[],createdAt:u,updatedAt:u}}var Kt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Nu=async(e,t,r,n,s)=>{w.runners.assertEnabled(n,s.config);let i=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=dt();ut(w.runners.getConfiguredProfile(n,s.config).executable,{cwd:i.repoRoot,env:l})}catch(l){let c=l instanceof Error?l.message:"Failed to start runner.",d=await s.taskService.recordStartupFailure(s.paths,i.task.id,c);throw new Kt(c,d)}let o=await s.taskService.markTaskStarted(s.paths,i.task.id),a={selectedRepoId:o.repoId,selectedWorkspaceId:o.workspaceId,selectedTaskId:o.id,selectedPtyTabId:o.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:o.selectedPtyTabId??"agent",selectedActionId:"commit"};return{task:o,nextShell:a}},Lu=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},_u=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 Qt(t.paths,e.selectedTaskId),i=await t.taskService.closeTask(t.paths,e.selectedTaskId);return{taskBeforeClose:s,task:i}});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}`}}},ju=async(e,t)=>(await t.taskService.prs.discoverOrRefreshMany(t.paths,e),Promise.all(e.map(r=>Qt(t.paths,r.id)))),Cr=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await Se.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var Fu=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 Wu=async(e,t,r)=>{let n=w.runners.setRunnerEnabled(r.config,e,t);return await w.save(r.paths,n),n},qu=async(e,t,r)=>{let n=w.runners.setRunnerPath(r.config,e,t);return await w.save(r.paths,n),n},Uu=async(e,t,r)=>{let n=w.previews.setEnabled(r.config,e,t);return await w.save(r.paths,n),n};var KT=250;function _e(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function kt(e,t){return Ne(t,e.ptyRuntime.getViewState(Gt(e,t)))}function Gt(e,t){let r=_e(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 y(e,t){return kt(e,Xc(t,e.model))}function Vu(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:y(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function Bu(e,t,r){return Vu(e,t,r?{tone:"success",message:r}:null)}function B(e,t,r){return Vu(e,t,{tone:"error",message:r})}function K(e,t,r,n){let s=r instanceof Error?r.message:n,i=r instanceof Error?r.stack??r.message:String(r);return Se.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:i}),s}function W(e,t){if(!e.uiStateFile)return;e.runtimeState=Vc(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Fe({uiStateFile:e.uiStateFile},r),()=>Fe({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function GT(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function G(e){return{paths:e.paths,config:e.config,taskService:P,workspaceService:X,queueTaskMutation:t=>GT(e,t)}}function qo(e,t){let r=_e(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,o=t.focusedRegion==="inspector"||t.activeTab==="inspection"?Lo(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:ht(e.model),centerTabIds:Yc(r,t),ptyTabIds:r?.ptyTabs.map(a=>a.id)??[],filePathIds:s?.filePaths??[],fileTreeRowIds:o.map(a=>a.path),fileTreeFileIds:o.filter(a=>a.kind==="file").map(a=>a.path),fileTreeDirectoryIds:o.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:yu(t,r,s),pageRows:Math.max(5,ce(e.activeTerminal.width,e.activeTerminal.height).height-F.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function Ku(e,t){await Ou(t,G(e))}async function ee(e){e.model=await Ut(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:y(e,e.state.shell)}:e.state={...e.state,shell:y(e,e.state.shell)}}function Ht(e,t){e.model={...e.model,tasks:[...e.model.tasks.filter(r=>r.id!==t.id),t].sort((r,n)=>r.id.localeCompare(n.id))}}async function Bn(e,t){let r=++e.inspectionRefreshSequence,n=Qi(e.model.tasks,t),s=e.model.inspection,i=t.focusedRegion==="inspector"&&t.inspectionMode==="review"&&t.openInspectionKind!=="diff",o;if(n&&s?.taskId===n.id&&!i){let a={selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath},l=await Ac(n,s,a);if(r!==e.inspectionRefreshSequence)return;o={...e.model,inspection:l}}else if(o=await Ut(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=o,e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},W(e,e.state.shell),e.render())}function Gu(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)&&Bn(e,r).catch(n=>{let s=K(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},KT))}function Hu(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=tt(e.state.shell,r,qo(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:y(e,n.state)},W(e,e.state.shell),e.render(),Bn(e,e.state.shell).catch(s=>{let i=K(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:i}),i)},e.render()});return}e.state={mode:"main",shell:y(e,n.state)},W(e,e.state.shell),e.render()}},16)))}function Uo(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function Vo(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 Yu(e){Vo(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},e.render())})}async function Ju(e,t){let r=y(e,t),n=_e(e.model.tasks,r),s=Gt(e,r);if(!n||!s||!n.ptyTabs.some(a=>a.id===s))return r;let i=e.ptyRuntime.getViewState(s);if(i.status!=="idle"||i.rows.length>0||i.error)return Ne(r,i);let o=await e.ptyRuntime.ensureSession(n.id,s,Xe(ce(e.activeTerminal.width,e.activeTerminal.height)));return Ne({...r,inputMode:"control"},o)}function Bo(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 Ko(e,t){try{let r=y(e,t),n=_e(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 zu(e,n),await ee(e),s=n.selectedPtyTabId)}n&&!s&&(n=await zu(e,n),await ee(e),s=n.selectedPtyTabId);let i=y(e,{...r,activeTab:s??r.activeTab,selectedPtyTabId:s,focusedRegion:s?"center":r.focusedRegion});if(!i.selectedTaskId||!s){e.state={mode:"main",shell:i},e.render();return}e.state={mode:"main",shell:Ne({...i,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},W(e,e.state.shell);let o=await e.ptyRuntime.ensureSession(i.selectedTaskId,s,Xe(ce(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Qe(s),e.lastTerminalKey=null,e.state={mode:"main",shell:Ne({...i,inputMode:"terminal"},o)},W(e,e.state.shell)}catch(r){let n=K(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Qe(t.selectedPtyTabId)&&(await HT(e,t.selectedTaskId,n).catch(()=>{}),await ee(e).catch(()=>{})),e.state={mode:"main",shell:B(e,Bc(y(e,t),n),n)},W(e,e.state.shell)}e.render()}async function HT(e,t,r){await Lu(t,r,G(e))}async function Xu(e,t,r,n){let s=y(e,t),{nextShell:i}=await xu(s,r,n,G(e));return await ee(e),y(e,{...s,...i})}async function Qu(e,t){let r=y(e,t),{closedTab:n,nextShell:s}=await Du(r,G(e));return e.ptyRuntime.disposeSession(n.id),await ee(e),y(e,{...r,...s})}async function Zu(e,t){let r=y(e,t),n=ht(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:i,nextShell:o}=await _u(r,G(e));for(let a of i)e.ptyRuntime.disposeSession(a);return await ee(e),y(e,{...r,...o,selectedLeftItemId:zT(n,ht(e.model),s)})}async function ep(e,t){let r=y(e,t),{nextShell:n}=await Fu(r,G(e));return await ee(e),y(e,{...r,...n})}async function zu(e,t){return $u(t,G(e))}function Kn(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:kt(e,e.state.shell)},e.render())},16))}function zT(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 rp(e,t,r){if(r?.aborted||e.state.mode!=="main")return;let n=tp(e),s=t.takeDueTasks(e.model.tasks,n);if(s.length!==0)try{let i=await ju(s,G(e));if(r?.aborted||(e.lastBackgroundPrPollError=null,e.state.mode!=="main"))return;for(let o of i)Ht(e,o);t.recordSuccess(i,tp(e)),e.state={mode:"main",shell:y(e,e.state.shell)},e.render()}catch(i){if(r?.aborted)return;t.recordFailure(s,i);let o=i instanceof Error?i.message:"Background PR discovery failed.";o!==e.lastBackgroundPrPollError&&(e.lastBackgroundPrPollError=o,Cr("background PR polling",i,G(e)))}}function tp(e){return e.state.mode!=="main"?{selectedTaskId:null,reviewVisible:!1}:{selectedTaskId:e.state.shell.selectedTaskId,reviewVisible:e.state.shell.inspectionMode==="review"}}async function np(e,t){let r=y(e,t),n=_e(e.model.tasks,r),s=null,i=null;if(n?.type==="project"&&n.repoTargets?.length){let o=await P.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await ee(e);let a=o.synced+o.discovered+o.notFound;i=`Refreshed ${o.synced}/${a} targets`}else{let{disposition:o,task:a}=await P.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await ee(e),s=o==="not_found"?`No PR found for ${a.branch}`:null,o!=="not_found"&&(i=`Refreshed checks: ${E(a)?.requiredChecks.length??0} reported`)}return y(e,{...Bu(e,r,i),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}import ZT from"node:path";import{readdir as YT,stat as JT}from"node:fs/promises";import sp from"node:path";async function XT(e){let t=await YT(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=sp.join(e,n.name);r.push({name:n.name,path:s,kind:await QT(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 ip(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function op(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 i=t(r,[e],{stdio:"ignore",detached:!0});i.unref(),i.on("error",s),i.on("spawn",n)})}async function Gn(e,t){let r=await XT(t);e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function QT(e){let t=sp.join(e,".git");return await JT(t).catch(()=>null)!==null}function ap(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function lp(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function eR(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:y(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:y(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:y(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await Nu(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,G(e));n=s.task,Ht(e,n);let i=y(e,{...e.state.shell,...s.nextShell,selectedLeftItemId:`task:${n.id}`,inputMode:"terminal",taskPromptInput:null,taskPromptError:null,actionMessage:null}),o=await e.ptyRuntime.ensureSession(n.id,i.selectedPtyTabId??gd(n,"agent"),Xe(ce(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Qe(i.selectedPtyTabId),e.state={mode:"main",shell:Ne(i,o)},W(e,e.state.shell)}catch(s){s instanceof Kt&&(n=s.task);let i=K(e,"create task",s,"Failed to create task.");n&&!(s instanceof Kt)?(await x(e.paths,n.id,o=>({...o,status:"draft",runnerSession:{...o.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:i})).catch(()=>{}),await ee(e).catch(()=>{})):n&&(await x(e.paths,n.id,o=>({...o,lastFailureReason:i})).catch(()=>{}),await ee(e).catch(()=>{})),e.state={mode:"main",shell:B(e,y(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:i,actionMessage:null}),i)}}finally{e.creatingTask=!1,e.render()}}function tR(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:y(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(he(t)){eR(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:y(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:y(e,{...r,selectedRunner:kn(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}Gc(t)&&(e.state={mode:"main",shell:y(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function rR(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:y(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:y(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:y(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:y(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=ip(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:y(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:y(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"){Gn(e,ZT.dirname(r.cwd)).catch(s=>{let i=K(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:i}}),i)},e.render()});return}if(t==="RIGHT"||t==="l"||he(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){Gn(e,s.path).catch(o=>{let a=K(e,"open workspace directory",o,"Failed to open directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:i}=G(e);i.addWorkspace(e.paths,s.path).then(async o=>{await ee(e);let a=o.repos[0]??null,l=y(e,{...e.state.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${o.workspace.id}`,selectedWorkspaceId:o.workspace.id,selectedRepoId:a?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${o.workspace.name??o.workspace.id}`});e.state={mode:"main",shell:l},W(e,e.state.shell),e.render()}).catch(o=>{let a=K(e,"add workspace",o,"Failed to add workspace.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function nR(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=Qd(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;sR(e,n)}}}async function sR(e,t){let r;try{r=await Se.readRecentErrorLines(e.paths)}catch(n){let s=K(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 iR(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=eu(ap(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"?Wu(r.runner,r.enabled,G(e)):qu(r.runner,r.path,G(e))).then(s=>{e.state.mode!=="overlay"||e.state.variant!=="runners"||(e.config=s,e.enabledRunnerIds=w.runners.getEnabled(e.config),e.model={...e.model,enabledRunnerIds:e.enabledRunnerIds},e.state={...e.state,shell:y(e,{...e.state.shell,selectedRunner:e.enabledRunnerIds.includes(e.state.shell.selectedRunner)?e.state.shell.selectedRunner:w.runners.getDefault(e.config)}),runnerOptions:r.state},e.render())}).catch(s=>{if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let i=K(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:B(e,y(e,e.state.shell),i),runnerOptions:{...ap(e),message:i}},e.render()})}function oR(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=Zd(lp(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}Uu(r.feature,r.enabled,G(e)).then(n=>{e.state.mode!=="overlay"||e.state.variant!=="previews"||(e.config=n,r.feature==="incrementalCenterPane"&&e.ptyRuntime.setViewUpdateMode?.(r.enabled?"incremental":"snapshot"),r.feature==="agentActivityIndicators"&&e.setAgentActivityEnabled(r.enabled),e.state={...e.state,previewOptions:r.state},e.render())}).catch(n=>{if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let s=K(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:B(e,y(e,e.state.shell),s),previewOptions:{...lp(e),message:s}},e.render()})}}function cp(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){tR(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){rR(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){lR(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=Wo(e.state.shell,r,qo(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:y(e,n.state)},W(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:y(e,n.state)},W(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&he(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=Sr(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(aR(e,r))return;e.lastTerminalKey=hd(r)?{key:r,at:Date.now()}:null;let i=wd(r,e.state.shell.terminal.scrolledBack??!1);if(i!==0){Kn(e,i);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:y(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:y(e,n.state)},W(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){Gn(e,e.workspaceRoot).catch(s=>{let i=K(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:B(e,y(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:i}}),i)},e.render()});return}if(n.createPtyTab){Xu(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{Ko(e,s)}).catch(s=>{let i=K(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:i}),i)},e.render()});return}if(n.closePtyTab){Qu(e,n.state).then(s=>{e.state={mode:"main",shell:s},W(e,e.state.shell),e.render()}).catch(s=>{let i=K(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:i}),i)},e.render()});return}if(n.refreshPullRequestChecks){np(e,n.state).then(s=>{e.state={mode:"main",shell:s},W(e,e.state.shell),e.render()}).catch(s=>{let i=K(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:i}),i)},e.render()});return}if(n.openPrUrl){let s=_e(e.model.tasks,n.state),i=s?E(s)?.url??null:null;i?op(i).catch(o=>{let a=K(e,"open PR URL",o,"Failed to open PR in browser.");e.state={mode:"main",shell:B(e,y(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:B(e,y(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){Zu(e,n.state).then(s=>{e.state={mode:"main",shell:s},W(e,e.state.shell),e.render()}).catch(s=>{let i=K(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:i}),i)},e.render()});return}if(n.removeWorkspace){ep(e,n.state).then(s=>{e.state={mode:"main",shell:s},W(e,e.state.shell),e.render()}).catch(s=>{let i=K(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:i}),i)},e.render()});return}if(n.attachTerminal){Ko(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:y(e,n.state)},W(e,e.state.shell),(e.state.shell.focusedRegion!=="tasks"||!e.renderTaskNavigation())&&e.render(),e.state.shell.focusedRegion==="tasks"){Gu(e,e.state.shell);return}Bn(e,e.state.shell).catch(s=>{let i=K(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:i}),i)},e.render()});return}n.changed&&(e.state={mode:"main",shell:y(e,n.state)},Ku(e,e.state.shell).catch(()=>{}),W(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:y(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){nR(e,r);return}if(e.state.variant==="runners"){iR(e,r);return}if(e.state.variant==="previews"){oR(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||he(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"||he(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:y(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(he(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:y(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;Ju(e,s).then(i=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:i},W(e,e.state.shell),e.render())}).catch(i=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let o=K(e,"warm selected PTY",i,"Failed to start selected PTY.");e.state={mode:"main",shell:B(e,y(e,e.state.shell),o)},W(e,e.state.shell),e.render()})}):Yu(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 dp(e,t){let r=bd(t);if(e.state.mode!=="main"||e.state.shell.inputMode!=="terminal"||r.length===0)return;if(e.pendingTerminalKeySequence){let i=`${e.pendingTerminalKeySequence.raw}${r}`,o=Sr(i);if(o){pp(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:o,at:Date.now()},e.ptyRuntime.writeKey(o);return}if(uo(i)){e.pendingTerminalKeySequence.raw=i,up(e);return}Hn(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:y(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},W(e,e.state.shell),e.render();return}let n=kd(r);if(n!==0){Kn(e,n);return}let s=Sr(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
136
136
  `&&r!==`\r
137
- `&&(e.suppressTerminalEnterOnAttach=!1),gd(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function GT(e,t){if(e.pendingTerminalKeySequence){let r=md(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=br(n);if(s)return op(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(li(n))return e.pendingTerminalKeySequence.raw=n,sp(e),!0}return Kn(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>Kn(e),30)},!0)}function sp(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>Kn(e),30))}function Kn(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function op(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function ip(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){Wu(e,ai(t));return}let r=ai(t);r!==0&&Un(e,r)}function HT(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var ap=1e3,YT=zT(import.meta.url),JT=YT("terminal-kit"),XT=JT.terminal;function Bi(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function lp(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function QT(e,t){return e?e.tabId!==t.tabId?{tabId:t.tabId,kind:"full"}:e.kind==="full"||t.kind==="full"?{tabId:t.tabId,kind:"full"}:{tabId:t.tabId,kind:"rows",rowIndices:[...new Set([...e.rowIndices,...t.rowIndices])]}:t}async function cp(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=re(t),n=await h.load(r),s=h.runners.getEnabled(n),o=e.uiStateFile?await yt({uiStateFile:e.uiStateFile}):null,i=await qt(t,void 0,s),a=kr(Lc(o,n),i);i=await qt(t,a,s);let l={current:i},c=()=>{},d=()=>{},u=()=>{},m={workspaceRoot:t,onUpdate:k=>c(k),onActivity:k=>d(k),onActivityRemoved:k=>u(k),resolveSessionSpec:(k,w)=>ld(l.current,w,t)},p=e.ptyRuntime??await Dd({...m,paths:r,viewUpdateMode:h.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot",activityEnabled:h.previews.isEnabled(n,"agentActivityIndicators")});return new Promise(k=>{let w=e.terminal??XT,b=null,N=null,_=null,Y=null,I=null,ce=0,me=!1,de=new Map,wt=new Bn({minimumIntervalMs:(n.github?.watchIntervalSeconds??5)*1e3}),g,Xe=new Bt({resolutionMs:h.previews.isEnabled(n,"agentActivityIndicators")?Mn:ap,onError:(T,j)=>Fn(`heartbeat job "${T}"`,j,K(g))});g={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:kr(a,i)},get model(){return l.current},set model(T){l.current=T},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,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:w,ptyRuntime:p,resolve:k,render:()=>{},renderTaskNavigation:()=>!1,exit:T=>k(T),setAgentActivityEnabled:T=>{Xe.setResolutionMs(T?Mn:ap),g.ptyRuntime.setActivityEnabled?.(T)}},g.setAgentActivityEnabled(h.previews.isEnabled(n,"agentActivityIndicators")),c=T=>{g.state.mode==="main"&&(I=QT(I,T),g.ptyRenderTimer||(g.ptyRenderTimer=setTimeout(()=>{g.ptyRenderTimer=null;let j=I;if(I=null,g.state.mode==="main"){let ee=ht(g,g.state.shell);if(g.state={mode:"main",shell:ee},!h.previews.isEnabled(g.config,"incrementalCenterPane")||!Y||!N){g.render();return}let te=le(w.width,w.height),Gt={...Y,terminal:ee.terminal},Ze=hu(te,Gt,N,ee.centerZoomed,j?.kind==="rows"?j.rowIndices:null);if(!Ze){g.render();return}Ze.output.length>0&&w.noFormat(Ze.output),Y=Gt,N=Ze.region,_&&(_={..._,center:Ze.region}),b=null,w.hideCursor(!0)}},h.previews.isEnabled(g.config,"incrementalCenterPane")?0:50)))},d=T=>{g.state.mode==="main"&&h.previews.isEnabled(g.config,"agentActivityIndicators")&&Ye(T.tabId)&&de.get(T.tabId)!==ct(T.tabId,[T],Date.now())&&g.render()},u=T=>{g.state.mode==="main"&&h.previews.isEnabled(g.config,"agentActivityIndicators")&&Ye(T)&&de.get(T)!=="idle"&&g.render()};let Pe=T=>{let j=le(w.width,w.height),ee=h.previews.isEnabled(g.config,"agentActivityIndicators"),fe=ee?g.ptyRuntime.getActivitySnapshots?.()??[]:[],te=Date.now(),Gt=ou(y(g,T.shell),g.model,ee?{snapshots:fe,now:te,animationFrame:ce}:void 0);if(de.clear(),ee)for(let up of g.model.tasks)for(let Gn of up.ptyTabs)Gn.kind==="agent"&&de.set(Gn.id,ct(Gn.id,fe,te));let Ze=Qc(j,Gt,{centerOnly:T.shell.centerZoomed,focusFlashActive:g.focusFlashUntil!==null&&Date.now()<g.focusFlashUntil});return{data:Gt,presentation:Ze}},Qe=(T,j,ee,fe)=>{if(!_)return!1;let te=wu(_,j.regions,ee);return te?(te.output.length>0&&w.noFormat(te.output),Y=T,_=te.regions,N=te.regions.center,b=fe?j.frame:null,w.hideCursor(!0),!0):!1};g.renderTaskNavigation=()=>{if(g.state.mode!=="main"||g.pendingClear||!h.previews.isEnabled(g.config,"incrementalCenterPane"))return!1;qi(g),g.ptyRuntime.setViewedTab?.(Kt(g,g.state.shell));let{data:T,presentation:j}=Pe(g.state);return Qe(T,j,["rail","left","center","footer"],!1)},g.render=()=>{qi(g);let T=g.state;g.ptyRuntime.setViewedTab?.(T.mode==="main"?Kt(g,T.shell):null);let j=le(w.width,w.height),ee,fe=null;if(T.mode==="main"){let te=Pe(T);if(fe=te.presentation,ee=fe.frame,h.previews.isEnabled(g.config,"incrementalCenterPane")&&!g.pendingClear&&Qe(te.data,fe,["rail","left","center","right","footer"],!0))return;Y=te.data,N=fe.center}else ee=T.variant==="boot"?zc(j,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:g.versionText,updateText:g.updateText}):T.variant==="pause"?Yc(j,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:g.versionText,updateText:g.updateText}):T.variant==="options"?vn(j,{menuIndex:T.menuIndex,optionsMenuItems:Ri}):T.variant==="runners"?vn(j,{menuIndex:Bi(T).menuIndex,optionsMenuItems:bi(g.config,Bi(T)),optionsMessage:Ud(Bi(T)),optionsSubtitle:"Runners"}):T.variant==="previews"?vn(j,{menuIndex:lp(T).menuIndex,optionsMenuItems:Bd(g.config),optionsMessage:Vd(lp(T)),optionsSubtitle:"Feature Previews - Experimental"}):T.variant==="error-log"?Xc(j,{errorLogPath:T.errorLog?.path??r.errorLogFile,errorLogLines:T.errorLog?.lines??[]}):Jc(j),Y=null,N=null,_=null;g.pendingClear&&(w.moveTo(1,1),w.eraseDisplayBelow(),g.pendingClear=!1,b=null),w.noFormat(wd(ee,b)),b=ee,_=fe?.regions??null,w.hideCursor(!0)};let vr=T=>rp(g,T),Ir=T=>np(g,T),Cr=T=>ip(g,T),dp=()=>{process.stdout.off("resize",Vi),process.off("SIGCONT",Ki),w.removeListener("key",vr),w.removeListener("unknown",Ir),w.removeListener("mouse",Cr),g.scrollRenderTimer&&(clearTimeout(g.scrollRenderTimer),g.scrollRenderTimer=null),g.inspectionScrollRenderTimer&&(clearTimeout(g.inspectionScrollRenderTimer),g.inspectionScrollRenderTimer=null),g.leftNavInspectionTimer&&(clearTimeout(g.leftNavInspectionTimer),g.leftNavInspectionTimer=null),g.pendingTerminalKeySequence&&(clearTimeout(g.pendingTerminalKeySequence.timer),g.pendingTerminalKeySequence=null),g.ptyRenderTimer&&(clearTimeout(g.ptyRenderTimer),g.ptyRenderTimer=null),g.footerToastTimer&&(clearTimeout(g.footerToastTimer),g.footerToastTimer=null),g.focusFlashTimer&&(clearTimeout(g.focusFlashTimer),g.focusFlashTimer=null),Xe.stop(),g.ptyRuntime.disposeAll(),w.grabInput(!1),w.hideCursor(!1),w.fullscreen(!1)};g.exit=T=>{dp(),k(T)};let Vi=()=>{Fi(g),g.state.mode==="main"&&g.state.shell.inputMode==="terminal"&&(g.ptyRuntime.resize(ze(le(w.width,w.height))),g.state={mode:"main",shell:ht(g,g.state.shell)}),g.render()},Ki=()=>{Fi(g),g.state.mode==="main"&&g.state.shell.inputMode==="terminal"&&(g.ptyRuntime.resize(ze(le(w.width,w.height))),g.state={mode:"main",shell:ht(g,g.state.shell)}),g.render()};process.stdout.on("resize",Vi),process.on("SIGCONT",Ki),w.grabInput(!0),g.inputCaptureMode="control",w.hideCursor(!0),w.fullscreen(!0),w.on("key",vr),w.on("unknown",Ir),w.on("mouse",Cr),Xe.register({id:"github.pull-requests",intervalMs:1e3,run:T=>Yu(g,wt,T)}),Xe.register({id:"agent.activity-indicators",intervalMs:Mn,run:()=>{if(!h.previews.isEnabled(g.config,"agentActivityIndicators")){ce=0,me=!1;return}let T=Date.now(),j=tn(g.model.tasks,g.ptyRuntime.getActivitySnapshots?.()??[],T);(j||me)&&(ce=(ce+1)%tu,g.state.mode==="main"&&g.render()),me=j}}),Xe.start(),h.version.checkForUpdate().then(T=>{T.updateAvailable&&T.latest&&(g.updateText=`Update available: v${T.latest}`,g.render())}),g.bootHydrationReady=Wi(g).catch(()=>{}),g.render()})}async function ZT(){try{if(process.argv[2]==="__craig-daemon"){let e=process.argv[3]??process.cwd(),t=re(e);return await Od(t),0}if(process.argv[2]==="__craig-daemon-shutdown"){let e=process.argv[3]??process.cwd(),t=re(e);return await $d(t),0}}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
138
- `),1}return yc({argv:process.argv.slice(2),cwd:process.cwd(),env:process.env,isInputTty:process.stdin.isTTY===!0,isOutputTty:process.stdout.isTTY===!0,writeStdout:e=>process.stdout.write(e),writeStderr:e=>process.stderr.write(e),readStdin:async()=>{let e="";process.stdin.setEncoding("utf8");for await(let t of process.stdin)e+=t;return e},runInteractive:e=>cp({uiStateFile:re(e).uiStateFile,workspaceRoot:e})})}var eR=await ZT();process.exit(eR);
137
+ `&&(e.suppressTerminalEnterOnAttach=!1),Rd(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function aR(e,t){if(e.pendingTerminalKeySequence){let r=yd(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=Sr(n);if(s)return pp(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(uo(n))return e.pendingTerminalKeySequence.raw=n,up(e),!0}return Hn(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>Hn(e),30)},!0)}function up(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>Hn(e),30))}function Hn(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function pp(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function mp(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){Hu(e,co(t));return}let r=co(t);r!==0&&Kn(e,r)}function lR(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var fp=1e3,dR=cR(import.meta.url),uR=dR("terminal-kit"),pR=uR.terminal;function Go(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function gp(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function hp(e){return e.mode!=="main"?{selectedTaskId:null,reviewVisible:!1}:{selectedTaskId:e.shell.selectedTaskId,reviewVisible:e.shell.inspectionMode==="review"}}function mR(e,t){return e?e.tabId!==t.tabId?{tabId:t.tabId,kind:"full"}:e.kind==="full"||t.kind==="full"?{tabId:t.tabId,kind:"full"}:{tabId:t.tabId,kind:"rows",rowIndices:[...new Set([...e.rowIndices,...t.rowIndices])]}:t}async function wp(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=ne(t),n=await w.load(r),s=w.runners.getEnabled(n),i=e.uiStateFile?await Rt({uiStateFile:e.uiStateFile}):null,o=await Ut(t,void 0,s),a=Tr(Uc(i,n),o);o=await Ut(t,a,s);let l={current:o},c=()=>{},d=()=>{},u=()=>{},f={workspaceRoot:t,onUpdate:m=>c(m),onActivity:m=>d(m),onActivityRemoved:m=>u(m),resolveSessionSpec:(m,k)=>fd(l.current,k,t)},h=e.ptyRuntime??await jd({...f,paths:r,viewUpdateMode:w.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot",activityEnabled:w.previews.isEnabled(n,"agentActivityIndicators")});return new Promise(m=>{let k=e.terminal??pR,b=null,O=null,q=null,U=null,I=null,te=0,je=!1,de=new Map,ye=h.managesPullRequestSync?null:new Bt({minimumIntervalMs:(n.github?.watchIntervalSeconds??5)*1e3}),p,rt=new Ze({resolutionMs:w.previews.isEnabled(n,"agentActivityIndicators")?Wn:fp,onError:(T,N)=>Cr(`heartbeat job "${T}"`,N,G(p))});p={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Tr(a,o)},get model(){return l.current},set model(T){l.current=T},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,lastBackgroundPrPollError:null,versionText:`Craig v${w.version.getCurrent()}`,updateText:null,inspectionRefreshSequence:0,pendingClear:!0,inputCaptureMode:null,runtimeState:i,persistQueue:Promise.resolve(),taskMutationQueue:Promise.resolve(),bootHydrationReady:Promise.resolve(),paths:r,workspaceRoot:t,uiStateFile:e.uiStateFile,activeTerminal:k,ptyRuntime:h,resolve:m,render:()=>{},renderTaskNavigation:()=>!1,exit:T=>m(T),setAgentActivityEnabled:T=>{rt.setResolutionMs(T?Wn:fp),p.ptyRuntime.setActivityEnabled?.(T)}},p.setAgentActivityEnabled(w.previews.isEnabled(n,"agentActivityIndicators")),c=T=>{p.state.mode==="main"&&(I=mR(I,T),p.ptyRenderTimer||(p.ptyRenderTimer=setTimeout(()=>{p.ptyRenderTimer=null;let N=I;if(I=null,p.state.mode==="main"){let H=kt(p,p.state.shell);if(p.state={mode:"main",shell:H},!w.previews.isEnabled(p.config,"incrementalCenterPane")||!U||!O){p.render();return}let re=ce(k.width,k.height),zt={...U,terminal:H.terminal},nt=Pu(re,zt,O,H.centerZoomed,N?.kind==="rows"?N.rowIndices:null);if(!nt){p.render();return}nt.output.length>0&&k.noFormat(nt.output),U=zt,O=nt.region,q&&(q={...q,center:nt.region}),b=null,k.hideCursor(!0)}},w.previews.isEnabled(p.config,"incrementalCenterPane")?0:50)))},d=T=>{p.state.mode==="main"&&w.previews.isEnabled(p.config,"agentActivityIndicators")&&Qe(T.tabId)&&de.get(T.tabId)!==De(T.tabId,[T],Date.now())&&p.render()},u=T=>{p.state.mode==="main"&&w.previews.isEnabled(p.config,"agentActivityIndicators")&&Qe(T)&&de.get(T)!=="idle"&&p.render()};let Pe=Promise.resolve(),yt=T=>{Pe=Pe.then(async()=>{let N=await Promise.all([...new Set(T)].map(H=>P.getTask(p.paths,H)));for(let H of N)Ht(p,H);p.state.mode==="main"?p.state={mode:"main",shell:y(p,p.state.shell)}:p.state={...p.state,shell:y(p,p.state.shell)},p.render()}).catch(N=>Cr("daemon task-state refresh",N,G(p)))};p.ptyRuntime.setTasksChangedHandler?.(yt);let Ar=T=>{let N=ce(k.width,k.height),H=w.previews.isEnabled(p.config,"agentActivityIndicators"),fe=H?p.ptyRuntime.getActivitySnapshots?.()??[]:[],re=Date.now(),zt=pu(y(p,T.shell),p.model,H?{snapshots:fe,now:re,animationFrame:te}:void 0);if(de.clear(),H)for(let yp of p.model.tasks)for(let zn of yp.ptyTabs)zn.kind==="agent"&&de.set(zn.id,De(zn.id,fe,re));let nt=sd(N,zt,{centerOnly:T.shell.centerZoomed,focusFlashActive:p.focusFlashUntil!==null&&Date.now()<p.focusFlashUntil});return{data:zt,presentation:nt}},Er=(T,N,H,fe)=>{if(!q)return!1;let re=Su(q,N.regions,H);return re?(re.output.length>0&&k.noFormat(re.output),U=T,q=re.regions,O=re.regions.center,b=fe?N.frame:null,k.hideCursor(!0),!0):!1};p.renderTaskNavigation=()=>{if(p.state.mode!=="main"||p.pendingClear||!w.previews.isEnabled(p.config,"incrementalCenterPane"))return!1;Bo(p),p.ptyRuntime.setPullRequestPollView?.(hp(p.state)),p.ptyRuntime.setViewedTab?.(Gt(p,p.state.shell));let{data:T,presentation:N}=Ar(p.state);return Er(T,N,["rail","left","center","footer"],!1)},p.render=()=>{Bo(p);let T=p.state;p.ptyRuntime.setPullRequestPollView?.(hp(T)),p.ptyRuntime.setViewedTab?.(T.mode==="main"?Gt(p,T.shell):null);let N=ce(k.width,k.height),H,fe=null;if(T.mode==="main"){let re=Ar(T);if(fe=re.presentation,H=fe.frame,w.previews.isEnabled(p.config,"incrementalCenterPane")&&!p.pendingClear&&Er(re.data,fe,["rail","left","center","right","footer"],!0))return;U=re.data,O=fe.center}else H=T.variant==="boot"?ed(N,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:p.versionText,updateText:p.updateText}):T.variant==="pause"?td(N,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:p.versionText,updateText:p.updateText}):T.variant==="options"?An(N,{menuIndex:T.menuIndex,optionsMenuItems:So}):T.variant==="runners"?An(N,{menuIndex:Go(T).menuIndex,optionsMenuItems:vo(p.config,Go(T)),optionsMessage:Yd(Go(T)),optionsSubtitle:"Runners"}):T.variant==="previews"?An(N,{menuIndex:gp(T).menuIndex,optionsMenuItems:Jd(p.config),optionsMessage:Xd(gp(T)),optionsSubtitle:"Feature Previews - Experimental"}):T.variant==="error-log"?nd(N,{errorLogPath:T.errorLog?.path??r.errorLogFile,errorLogLines:T.errorLog?.lines??[]}):rd(N),U=null,O=null,q=null;p.pendingClear&&(k.moveTo(1,1),k.eraseDisplayBelow(),p.pendingClear=!1,b=null),k.noFormat(Pd(H,b)),b=H,q=fe?.regions??null,k.hideCursor(!0)};let xr=T=>cp(p,T),Ho=T=>dp(p,T),zo=T=>mp(p,T),kp=()=>{process.stdout.off("resize",Yo),process.off("SIGCONT",Jo),k.removeListener("key",xr),k.removeListener("unknown",Ho),k.removeListener("mouse",zo),p.scrollRenderTimer&&(clearTimeout(p.scrollRenderTimer),p.scrollRenderTimer=null),p.inspectionScrollRenderTimer&&(clearTimeout(p.inspectionScrollRenderTimer),p.inspectionScrollRenderTimer=null),p.leftNavInspectionTimer&&(clearTimeout(p.leftNavInspectionTimer),p.leftNavInspectionTimer=null),p.pendingTerminalKeySequence&&(clearTimeout(p.pendingTerminalKeySequence.timer),p.pendingTerminalKeySequence=null),p.ptyRenderTimer&&(clearTimeout(p.ptyRenderTimer),p.ptyRenderTimer=null),p.footerToastTimer&&(clearTimeout(p.footerToastTimer),p.footerToastTimer=null),p.focusFlashTimer&&(clearTimeout(p.focusFlashTimer),p.focusFlashTimer=null),rt.stop(),p.ptyRuntime.disposeAll(),k.grabInput(!1),k.hideCursor(!1),k.fullscreen(!1)};p.exit=T=>{kp(),m(T)};let Yo=()=>{Uo(p),p.state.mode==="main"&&p.state.shell.inputMode==="terminal"&&(p.ptyRuntime.resize(Xe(ce(k.width,k.height))),p.state={mode:"main",shell:kt(p,p.state.shell)}),p.render()},Jo=()=>{Uo(p),p.state.mode==="main"&&p.state.shell.inputMode==="terminal"&&(p.ptyRuntime.resize(Xe(ce(k.width,k.height))),p.state={mode:"main",shell:kt(p,p.state.shell)}),p.render()};process.stdout.on("resize",Yo),process.on("SIGCONT",Jo),k.grabInput(!0),p.inputCaptureMode="control",k.hideCursor(!0),k.fullscreen(!0),k.on("key",xr),k.on("unknown",Ho),k.on("mouse",zo),ye&&rt.register({id:"github.pull-requests",intervalMs:1e3,run:T=>rp(p,ye,T)}),rt.register({id:"agent.activity-indicators",intervalMs:Wn,run:()=>{if(!w.previews.isEnabled(p.config,"agentActivityIndicators")){te=0,je=!1;return}let T=Date.now(),N=sn(p.model.tasks,p.ptyRuntime.getActivitySnapshots?.()??[],T);(N||je)&&(te=(te+1)%lu,p.state.mode==="main"&&p.render()),je=N}}),rt.start(),w.version.checkForUpdate().then(T=>{T.updateAvailable&&T.latest&&(p.updateText=`Update available: v${T.latest}`,p.render())}),p.bootHydrationReady=Vo(p).catch(()=>{}),p.render()})}async function fR(){try{if(process.argv[2]==="__craig-daemon"){let e=process.argv[3]??process.cwd(),t=ne(e);return await Fd(t),0}if(process.argv[2]==="__craig-daemon-shutdown"){let e=process.argv[3]??process.cwd(),t=ne(e);return await Wd(t),0}}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
138
+ `),1}return vc({argv:process.argv.slice(2),cwd:process.cwd(),env:process.env,isInputTty:process.stdin.isTTY===!0,isOutputTty:process.stdout.isTTY===!0,writeStdout:e=>process.stdout.write(e),writeStderr:e=>process.stderr.write(e),readStdin:async()=>{let e="";process.stdin.setEncoding("utf8");for await(let t of process.stdin)e+=t;return e},runInteractive:e=>wp({uiStateFile:ne(e).uiStateFile,workspaceRoot:e})})}var gR=await fR();process.exit(gR);