craig-cli 0.7.1 → 0.7.3

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 +40 -16
  2. package/dist/cli.js +53 -53
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,35 +1,35 @@
1
1
  #!/usr/bin/env node
2
- var _a=Object.defineProperty;var ke=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var Ba=(e,t)=>{for(var n in t)_a(e,n,{get:t[n],enumerable:!0})};function Z(e){return Ua[e]}function An(e,t={}){let n=Z(e),r=t.runners?.[e]?.path?.trim();return{...n,executable:r&&r.length>0?r:n.executable}}function Ze(e={}){return N.filter(t=>e.runners?.[t]?.enabled!==!1)}function _e(e={}){let t=Ze(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]}function Dt(e,t={}){if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)}function et(e){return N.includes(e)}function rs(e){if(!e||e.length===0)return"codex";if(!et(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${N.join(", ")}.`);return e}function se(e){return Z(e).displayName}function z(e,t,n={}){let r=[An(e,n).executable];return t&&t.length>0&&r.push(t),r}var N,Ua,ue=ke(()=>{"use strict";N=["codex","cursor","claude"],Ua={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"}}});import{randomUUID as Ya}from"node:crypto";import{open as Ja,readFile as Xp,rename as Qa,rm as Xa}from"node:fs/promises";import $n from"node:path";async function W(e,t){let n=$n.dirname(e),r=$n.join(n,`.${$n.basename(e)}.${process.pid}.${Date.now()}.${Ya()}.tmp`),s=await Ja(r,"w");try{let o=`${JSON.stringify(t,null,2)}
3
- `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Qa(r,e)}catch(o){throw await s.close().catch(()=>{}),await Xa(r,{force:!0}).catch(()=>{}),o}}var ye=ke(()=>{"use strict"});import{readFile as oc}from"node:fs/promises";async function oe(e){let t=await oc(e.indexFile,"utf8"),n=JSON.parse(t);return Mn(n,e.workspaceRoot,e.indexFile)}async function Ue(e,t){let n={...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()};await W(e.indexFile,n)}function Mn(e,t,n){if(!ic(e))throw new Error(`Craig index at ${n} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${n} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e}function ic(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(n=>typeof n=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(n=>typeof n=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(n=>typeof n=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}var qe=ke(()=>{"use strict";ye()});import{readFile as ac}from"node:fs/promises";async function _(e,t){let n=await ac(Ln(e,t),"utf8"),r=JSON.parse(n);return cc(r,Ln(e,t))}async function E(e,t){let n={...t,updatedAt:new Date().toISOString()};await W(Ln(e,t.id),n)}async function On(e,t){let n=await oe(e);n.taskIds.includes(t)||await Ue(e,{...n,taskIds:[...n.taskIds,t]})}function Ln(e,t){return`${e.tasksDir}/${t}.json`}function cc(e,t){let n=lc(e);if(!uc(n))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function lc(e){if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Fn(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[],ptyTabs:mc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:fc(t.repoTargets),runnerSession:t.runnerSession??dc(t),checks:yc(t),lastCommit:t.lastCommit??null,prs:Pc(t),artifacts:Cc(t),cleanup:xc(t)}}function dc(e){if(typeof e.title!="string")return null;let t=Fn(e.runner);return{command:z(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}}function uc(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&et(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(n=>typeof n=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&cs(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||pc(t.repoTargets))&&hc(t.runnerSession)&&wc(t.prompt)&&ls(t.checks)&&ds(t.lastCommit)&&Rc(t.prs)&&Tc(t.artifacts)&&fs(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}function fc(e){if(Array.isArray(e))return e.filter(as)}function pc(e){return Array.isArray(e)&&e.every(as)}function as(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&ls(t.checks)&&ds(t.lastCommit)&&us(t.pullRequest)&&fs(t.cleanup)}function mc(e){if(cs(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return gc(e.id,e.title,t,Fn(e.runner))}function gc(e,t,n,r){let s=Z(r);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:z(r),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function Fn(e){return e&&et(e)?e:"codex"}function cs(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string")}function hc(e){return typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null)}function wc(e){return typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string"}function ls(e){return typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number")}function ds(e){return e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string"}function us(e){return typeof e=="object"&&e!==null&&e.provider==="github"&&kc(e.requiredChecks)}function kc(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null))}function Rc(e){return Array.isArray(e)&&e.every(us)}function Tc(e){return typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null)}function fs(e){return typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null)}function yc(e){return e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]}}function Pc(e){if(Array.isArray(e.prs))return e.prs.map(bc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:ps(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:ms(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]}function bc(e){let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:ps(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Ic(t.reviewDecision),requiredChecks:ms(t.requiredChecks),comments:Sc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}}function ps(e){return e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null}function Ic(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Sc(e){return Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let n=t;return typeof n.body!="string"||!n.body.trim()?[]:[{author:typeof n.author=="string"?n.author:null,body:n.body,createdAt:typeof n.createdAt=="string"?n.createdAt:null,url:typeof n.url=="string"?n.url:null}]}):[]}function ms(e){return Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[]}function Cc(e){let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}}function xc(e){return e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}var ie=ke(()=>{"use strict";ye();qe();ue()});import{readFile as vc}from"node:fs/promises";async function fe(e){try{let t=await vc(e.uiStateFile,"utf8"),n=JSON.parse(t);return Ec(n,e.uiStateFile)}catch(t){if($c(t))return null;throw t}}async function ae(e,t){await W(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Pe(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function Ec(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!nt(e,"inputMode")||!nt(e,"focusedRegion")||!nt(e,"activeTab")||!nt(e,"inspectorSection")||!nt(e,"inspectionMode")||!Mt(e,"openInspectionKind")||!Mt(e,"selectedFileTreePath")||!Mt(e,"selectedFilePath")||!Mt(e,"selectedDiffPath")||!Ac(e,"collapsedFileTreePaths")||!nt(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 nt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Mt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Ac(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(n=>typeof n=="string"))}function $c(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var rt=ke(()=>{"use strict";ye()});import{execFile as Dc}from"node:child_process";import{promisify as Mc}from"node:util";async function x(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr}}catch(r){if(hs(r)){let s=r.stderr?.trim()||r.stdout?.trim()||r.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw r}}async function D(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr,exitCode:0}}catch(r){if(hs(r))return{stdout:r.stdout??"",stderr:r.stderr??"",exitCode:typeof r.code=="number"?r.code:null};throw r}}function hs(e){return e instanceof Error}var gs,ce=ke(()=>{"use strict";gs=Mc(Dc)});import{readFile as Yc,readdir as Jc,rm as Qc}from"node:fs/promises";import Cs from"node:path";async function pe(e,t){let n=await Yc(Ft(e,t),"utf8"),r=JSON.parse(n);return Xc(r,Ft(e,t))}async function jt(e,t){await W(Ft(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function Ge(e){let t=await Jc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>pe(e,Cs.basename(r.name,".json"))))).sort((r,s)=>r.name.localeCompare(s.name)||r.id.localeCompare(s.id))}async function xs(e,t){await Qc(Ft(e,t),{force:!0})}function Ft(e,t){return Cs.join(e.reposDir,`${t}.json`)}function Xc(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}var He=ke(()=>{"use strict";ye()});import{readFile as Zc,readdir as el,rm as tl}from"node:fs/promises";import vs from"node:path";async function ft(e,t){let n=await Zc(Nt(e,t),"utf8"),r=JSON.parse(n);return nl(r,Nt(e,t))}async function st(e,t){await W(Nt(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function me(e){let t=await el(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>ft(e,vs.basename(r.name,".json"))))).sort((r,s)=>r.id.localeCompare(s.id))}async function Es(e,t){await tl(Nt(e,t),{force:!0})}function Nt(e,t){return vs.join(e.workspacesDir,`${t}.json`)}function nl(e,t){let n=rl(e);if(typeof n!="object"||n===null||typeof n.id!="string"||n.kind!=="repo"&&n.kind!=="project"||typeof n.name!="string"||typeof n.rootPath!="string"||typeof n.primaryRepoId!="string"||typeof n.branch!="string"||n.status!=="active"&&n.status!=="archived"||!Array.isArray(n.linkedRepoIds)||!(n.linkedRepoIds??[]).every(r=>typeof r=="string")||!(n.repoId===void 0||typeof n.repoId=="string")||!Array.isArray(n.discoveredRepoIds)||!(n.discoveredRepoIds??[]).every(r=>typeof r=="string")||!(n.archivedAt===null||typeof n.archivedAt=="string")||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function rl(e){if(typeof e!="object"||e===null)return e;let t=e,n=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??n??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??n??"",repoId:t.kind==="project"?t.repoId:n,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(r=>typeof r=="string"):t.kind==="project"?[]:n?[n]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[]}}var pt=ke(()=>{"use strict";ye()});async function be(e,t){let n=await oe(e),r=[],s=[];await Promise.all(n.taskIds.map(async c=>{try{r.push(await _(e,c))}catch(l){if(ul(l)){s.push(c);return}throw l}}));let i=(t?.includeClosed?r:r.filter(c=>c.status!=="closed")).filter(c=>!(t?.workspaceId&&c.workspaceId!==t.workspaceId||t?.repoId&&c.repoId!==t.repoId&&!(c.repoTargets??[]).some(l=>l.repoId===t.repoId)));return i.sort((c,l)=>c.id.localeCompare(l.id)),s.sort(),{kind:"listTasks",tasks:i,missingTaskIds:s,repoId:t?.repoId??null}}function ul(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var ht=ke(()=>{"use strict";qe();ie()});var To={};Ba(To,{addWorkspace:()=>Rt,archiveWorkspace:()=>Tt,listWorkspaces:()=>sr,removeWorkspace:()=>yt,removeWorkspaceRecord:()=>Yt,restoreWorkspace:()=>or});import{readdir as Yl,realpath as fo,stat as Jl}from"node:fs/promises";import Le from"node:path";async function Rt(e,t){let n=Le.resolve(e.workspaceRoot,t);if(!(await Jl(n).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${n}`);return await wo(n)?Ql(e,n):Xl(e,n)}async function sr(e,t){return{kind:"listWorkspaces",workspaces:(await me(e)).filter(r=>r.status===(t.archived?"archived":"active")),archivedOnly:t.archived}}async function Tt(e,t){let r={...await ft(e,t),status:"archived",archivedAt:new Date().toISOString()};return await st(e,r),await Ro(e,t),{kind:"archiveWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function or(e,t){let r={...await ft(e,t),status:"active",archivedAt:null};await st(e,r);let s=await fe({uiStateFile:e.uiStateFile})??null;return await ae({uiStateFile:e.uiStateFile},{...s??Pe(),selectedWorkspaceId:r.id,selectedRepoId:r.kind==="project"?r.discoveredRepoIds?.[0]??null:r.primaryRepoId,selectedTaskId:null}),{kind:"restoreWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function yt(e,t){let n=await ft(e,t),r=await be(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(r.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await Yt(e,t),await Ro(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}}async function Ql(e,t){let n=await ko(t),r=await Ge(e),s=r.find(h=>h.rootPath===t)??null,o=s?mo(s,n):po(r,t,n),i=`workspace_${o.id}`,l=(await me(e)).find(h=>h.id===i)??null,d=new Date().toISOString(),f=l??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:n,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await jt(e,o),l||await st(e,f),await go(e,{repoIds:[o.id],workspaceIds:[f.id]}),await ho(e,f,o.id),{kind:"createWorkspace",workspace:f,repos:[o],created:!l}}async function Xl(e,t){let n=await Zl(e,t);if(n.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let r=await me(e),s=td(r,Le.basename(t)),o=r.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),c=n.map(d=>d.id),l=o?{...o,discoveredRepoIds:c,primaryRepoId:c[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:Le.basename(t),rootPath:t,primaryRepoId:c[0]??"",discoveredRepoIds:c,branch:"project",status:"active",linkedRepoIds:c,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(n.map(d=>jt(e,d))),await st(e,l),await go(e,{repoIds:c,workspaceIds:[l.id]}),await ho(e,l,c[0]??null),{kind:"createWorkspace",workspace:l,repos:n,created:!o}}async function Zl(e,t){let n=await Yl(t,{withFileTypes:!0}),r=await Ge(e),s=[];for(let o of n){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Le.join(t,o.name);if(!await wo(i))continue;let c=r.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await ko(i);s.push(c?mo(c,l):po([...r,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))}function po(e,t,n){let r=new Date().toISOString();return{id:ed(e,Le.basename(t)),name:Le.basename(t),rootPath:t,defaultBranch:n,createdAt:r,updatedAt:r}}function mo(e,t){return e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()}}function ed(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",r=`repo_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`repo_${n}_${s}`,s+=1;return r}function td(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",r=`workspace_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`workspace_${n}_${s}`,s+=1;return r}async function go(e,t){let n=await oe(e);await Ue(e,{...n,repoIds:[...new Set([...n.repoIds,...t.repoIds])],workspaceIds:[...new Set([...n.workspaceIds,...t.workspaceIds])]})}async function ho(e,t,n){await ae({uiStateFile:e.uiStateFile},{...await fe({uiStateFile:e.uiStateFile})??Pe(),selectedRepoId:n,selectedWorkspaceId:t.id,selectedTaskId:null})}async function wo(e){try{let n=(await x("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[r,s]=await Promise.all([fo(n).catch(()=>Le.resolve(n)),fo(e).catch(()=>Le.resolve(e))]);return r===s}catch{return!1}}async function ko(e){let t=await D("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),n=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&n.length>0)return n;for(let o of["main","master","trunk"])if((await D("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await x("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"}async function Yt(e,t){await Es(e,t);let n=await oe(e);await Ue(e,{...n,workspaceIds:n.workspaceIds.filter(r=>r!==t)})}async function Ro(e,t){let n=await fe({uiStateFile:e.uiStateFile});!n||n.selectedWorkspaceId!==t||await ae({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}var Pt=ke(()=>{"use strict";qe();He();pt();rt();ce();ht()});ue();function ss(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Repo path cannot be empty.
2
+ var fc=Object.defineProperty;var $=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var An=(e,t)=>{for(var n in t)fc(e,n,{get:t[n],enumerable:!0})};var F,Ye=$(()=>{"use strict";F=["codex","cursor","claude"]});var ps,ms=$(()=>{"use strict";ps={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 Je,vt=$(()=>{"use strict";ms();Je=e=>ps[e]});var Et,$n=$(()=>{"use strict";vt();Et=(e,t={})=>{let n=Je(e),r=t.runners?.[e]?.path?.trim();return{...n,executable:r&&r.length>0?r:n.executable}}});var At,Dn=$(()=>{"use strict";Ye();At=(e={})=>F.filter(t=>e.runners?.[t]?.enabled!==!1)});var gs,hs=$(()=>{"use strict";Dn();gs=(e={})=>{let t=At(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 ws,ks=$(()=>{"use strict";ws=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)}});var $t,Mn=$(()=>{"use strict";Ye();$t=e=>F.includes(e)});var Rs,Ts=$(()=>{"use strict";Ye();Mn();Rs=e=>{if(!e||e.length===0)return"codex";if(!$t(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${F.join(", ")}.`);return e}});var ys,Ps=$(()=>{"use strict";vt();ys=e=>Je(e).displayName});var bs,Is=$(()=>{"use strict";$n();bs=(e,t,n={})=>{let r=[Et(e,n).executable];return t&&t.length>0&&r.push(t),r}});var Ln={};An(Ln,{RUNNER_IDS:()=>F,assertEnabled:()=>ws,buildCommand:()=>bs,getConfiguredProfile:()=>Et,getDefault:()=>gs,getDisplayName:()=>ys,getEnabled:()=>At,getProfile:()=>Je,isRunnerType:()=>$t,parse:()=>Rs});var On=$(()=>{"use strict";Ye();vt();$n();Dn();hs();ks();Mn();Ts();Ps();Is()});import{mkdir as pc,readFile as mc,writeFile as gc}from"node:fs/promises";import hc from"node:path";var wc,Ss,Cs,Fn=$(()=>{"use strict";wc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Ss=async e=>{try{return await mc(e,"utf8")}catch(t){if(wc(t))return null;throw t}},Cs=async(e,t)=>{await pc(hc.dirname(e),{recursive:!0}),await gc(e,t,"utf8")}});var Dt,jn=$(()=>{"use strict";Ye();Dt=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let n=e;if(n.runners!==void 0){if(typeof n.runners!="object"||n.runners===null||Array.isArray(n.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[r,s]of Object.entries(n.runners)){if(!F.includes(r))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" is not supported. Expected one of: ${F.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${r}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${r}.path" must be a non-empty string.`)}}if(n.checks!==void 0&&(typeof n.checks!="object"||n.checks===null||!Array.isArray(n.checks.commands)||!n.checks.commands.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(n.open!==void 0&&(typeof n.open!="object"||n.open===null||!Array.isArray(n.open.command)||!n.open.command.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(n.github!==void 0){if(typeof n.github!="object"||n.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(n.github.mergeMethod!==void 0&&n.github.mergeMethod!=="merge"&&n.github.mergeMethod!=="rebase"&&n.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(n.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(n.github.watchIntervalSeconds)||n.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return n}});var Nn,xs=$(()=>{"use strict";Fn();jn();Nn=async(e,t={readConfigFile:Ss})=>{let n=await t.readConfigFile(e.configFile);if(!n)return{};if(n.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let r;try{r=JSON.parse(n)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Dt(r,e.configFile)}});var Wn,vs=$(()=>{"use strict";Fn();jn();Wn=async(e,t,n={writeConfigFile:Cs})=>{Dt(t,e.configFile),await n.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
3
+ `)}});var Es=$(()=>{"use strict";xs();vs()});var Mt,_n=$(()=>{"use strict";Mt=()=>{try{return"0.7.3"}catch{return"unknown"}}});var kc,Rc,Tc,yc,As,$s=$(()=>{"use strict";_n();kc="https://registry.npmjs.org/craig-cli/latest",Rc=3600*1e3,Tc={value:null},yc=(e,t)=>{let n=d=>d.split(".").map(Number),[r=0,s=0,o=0]=n(e),[i=0,c=0,l=0]=n(t);return r!==i?r>i:s!==c?s>c:o>l},As=async(e={fetch:globalThis.fetch,getCurrent:Mt,cache:Tc})=>{let t=e.getCurrent(),n=Date.now();if(e.cache.value&&n-e.cache.value.cachedAt<Rc)return e.cache.value.result;let r=null;try{let o=await e.fetch(kc,{signal:AbortSignal.timeout(5e3)});o.ok&&(r=(await o.json()).version??null)}catch{}let s={current:t,latest:r,updateAvailable:r!==null&&r!==t&&yc(r,t)};return e.cache.value={result:s,cachedAt:n},s}});var Bn={};An(Bn,{checkForUpdate:()=>As,getCurrent:()=>Mt});var Ds=$(()=>{"use strict";_n();$s()});var b,ee=$(()=>{"use strict";On();Es();On();Ds();b={load:Nn,save:Wn,runners:Ln,version:Bn}});import{randomUUID as bc}from"node:crypto";import{open as Ic,readFile as wg,rename as Sc,rm as Cc}from"node:fs/promises";import Un from"node:path";async function B(e,t){let n=Un.dirname(e),r=Un.join(n,`.${Un.basename(e)}.${process.pid}.${Date.now()}.${bc()}.tmp`),s=await Ic(r,"w");try{let o=`${JSON.stringify(t,null,2)}
4
+ `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Sc(r,e)}catch(o){throw await s.close().catch(()=>{}),await Cc(r,{force:!0}).catch(()=>{}),o}}var ke=$(()=>{"use strict"});import{readFile as Mc}from"node:fs/promises";async function oe(e){let t=await Mc(e.indexFile,"utf8"),n=JSON.parse(t);return Kn(n,e.workspaceRoot,e.indexFile)}async function Ne(e,t){let n={...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()};await B(e.indexFile,n)}function Kn(e,t,n){if(!Lc(e))throw new Error(`Craig index at ${n} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${n} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e}function Lc(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(n=>typeof n=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(n=>typeof n=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(n=>typeof n=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}var We=$(()=>{"use strict";ke()});import{readFile as Oc}from"node:fs/promises";async function U(e,t){let n=await Oc(Vn(e,t),"utf8"),r=JSON.parse(n);return Fc(r,Vn(e,t))}async function A(e,t){let n={...t,updatedAt:new Date().toISOString()};await B(Vn(e,t.id),n)}async function Gn(e,t){let n=await oe(e);n.taskIds.includes(t)||await Ne(e,{...n,taskIds:[...n.taskIds,t]})}function Vn(e,t){return`${e.tasksDir}/${t}.json`}function Fc(e,t){let n=jc(e);if(!Wc(n))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function jc(e){if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Hn(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[],ptyTabs:Uc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:_c(t.repoTargets),runnerSession:t.runnerSession??Nc(t),checks:Yc(t),lastCommit:t.lastCommit??null,prs:Jc(t),artifacts:el(t),cleanup:tl(t)}}function Nc(e){if(typeof e.title!="string")return null;let t=Hn(e.runner);return{command:b.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}}function Wc(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&b.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(n=>typeof n=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&Os(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||Bc(t.repoTargets))&&Kc(t.runnerSession)&&Vc(t.prompt)&&Fs(t.checks)&&js(t.lastCommit)&&Hc(t.prs)&&zc(t.artifacts)&&Ws(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}function _c(e){if(Array.isArray(e))return e.filter(Ls)}function Bc(e){return Array.isArray(e)&&e.every(Ls)}function Ls(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)&&Fs(t.checks)&&js(t.lastCommit)&&Ns(t.pullRequest)&&Ws(t.cleanup)}function Uc(e){if(Os(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 qc(e.id,e.title,t,Hn(e.runner))}function qc(e,t,n,r){let s=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:b.runners.buildCommand(r),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function Hn(e){return e&&b.runners.isRunnerType(e)?e:"codex"}function Os(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string")}function Kc(e){return typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null)}function Vc(e){return typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string"}function Fs(e){return typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number")}function js(e){return e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string"}function Ns(e){return typeof e=="object"&&e!==null&&e.provider==="github"&&Gc(e.requiredChecks)}function Gc(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null))}function Hc(e){return Array.isArray(e)&&e.every(Ns)}function zc(e){return typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null)}function Ws(e){return typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null)}function Yc(e){return e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]}}function Jc(e){if(Array.isArray(e.prs))return e.prs.map(Qc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:_s(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Bs(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]}function Qc(e){let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:_s(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Xc(t.reviewDecision),requiredChecks:Bs(t.requiredChecks),comments:Zc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}}function _s(e){return e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null}function Xc(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Zc(e){return Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let n=t;return typeof n.body!="string"||!n.body.trim()?[]:[{author:typeof n.author=="string"?n.author:null,body:n.body,createdAt:typeof n.createdAt=="string"?n.createdAt:null,url:typeof n.url=="string"?n.url:null}]}):[]}function Bs(e){return Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[]}function el(e){let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}}function tl(e){return e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}var ie=$(()=>{"use strict";ke();We();ee()});import{readFile as nl}from"node:fs/promises";async function ue(e){try{let t=await nl(e.uiStateFile,"utf8"),n=JSON.parse(t);return rl(n,e.uiStateFile)}catch(t){if(ol(t))return null;throw t}}async function ae(e,t){await B(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Re(){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 rl(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")||!Xe(e,"inputMode")||!Xe(e,"focusedRegion")||!Xe(e,"activeTab")||!Xe(e,"inspectorSection")||!Xe(e,"inspectionMode")||!Lt(e,"openInspectionKind")||!Lt(e,"selectedFileTreePath")||!Lt(e,"selectedFilePath")||!Lt(e,"selectedDiffPath")||!sl(e,"collapsedFileTreePaths")||!Xe(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 Xe(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Lt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function sl(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(n=>typeof n=="string"))}function ol(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Ze=$(()=>{"use strict";ke()});import{execFile as il}from"node:child_process";import{promisify as al}from"node:util";async function v(e,t,n={}){try{let r=await Us(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr}}catch(r){if(qs(r)){let s=r.stderr?.trim()||r.stdout?.trim()||r.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw r}}async function L(e,t,n={}){try{let r=await Us(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr,exitCode:0}}catch(r){if(qs(r))return{stdout:r.stdout??"",stderr:r.stderr??"",exitCode:typeof r.code=="number"?r.code:null};throw r}}function qs(e){return e instanceof Error}var Us,ce=$(()=>{"use strict";Us=al(il)});import{readFile as bl,readdir as Il,rm as Sl}from"node:fs/promises";import Zs from"node:path";async function fe(e,t){let n=await bl(jt(e,t),"utf8"),r=JSON.parse(n);return Cl(r,jt(e,t))}async function Nt(e,t){await B(jt(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function Ue(e){let t=await Il(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>fe(e,Zs.basename(r.name,".json"))))).sort((r,s)=>r.name.localeCompare(s.name)||r.id.localeCompare(s.id))}async function eo(e,t){await Sl(jt(e,t),{force:!0})}function jt(e,t){return Zs.join(e.reposDir,`${t}.json`)}function Cl(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}var qe=$(()=>{"use strict";ke()});import{readFile as xl,readdir as vl,rm as El}from"node:fs/promises";import to from"node:path";async function ct(e,t){let n=await xl(Wt(e,t),"utf8"),r=JSON.parse(n);return Al(r,Wt(e,t))}async function et(e,t){await B(Wt(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function pe(e){let t=await vl(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>ct(e,to.basename(r.name,".json"))))).sort((r,s)=>r.id.localeCompare(s.id))}async function no(e,t){await El(Wt(e,t),{force:!0})}function Wt(e,t){return to.join(e.workspacesDir,`${t}.json`)}function Al(e,t){let n=$l(e);if(typeof n!="object"||n===null||typeof n.id!="string"||n.kind!=="repo"&&n.kind!=="project"||typeof n.name!="string"||typeof n.rootPath!="string"||typeof n.primaryRepoId!="string"||typeof n.branch!="string"||n.status!=="active"&&n.status!=="archived"||!Array.isArray(n.linkedRepoIds)||!(n.linkedRepoIds??[]).every(r=>typeof r=="string")||!(n.repoId===void 0||typeof n.repoId=="string")||!Array.isArray(n.discoveredRepoIds)||!(n.discoveredRepoIds??[]).every(r=>typeof r=="string")||!(n.archivedAt===null||typeof n.archivedAt=="string")||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function $l(e){if(typeof e!="object"||e===null)return e;let t=e,n=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??n??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??n??"",repoId:t.kind==="project"?t.repoId:n,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(r=>typeof r=="string"):t.kind==="project"?[]:n?[n]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[]}}var lt=$(()=>{"use strict";ke()});async function Te(e,t){let n=await oe(e),r=[],s=[];await Promise.all(n.taskIds.map(async c=>{try{r.push(await U(e,c))}catch(l){if(Wl(l)){s.push(c);return}throw l}}));let i=(t?.includeClosed?r:r.filter(c=>c.status!=="closed")).filter(c=>!(t?.workspaceId&&c.workspaceId!==t.workspaceId||t?.repoId&&c.repoId!==t.repoId&&!(c.repoTargets??[]).some(l=>l.repoId===t.repoId)));return i.sort((c,l)=>c.id.localeCompare(l.id)),s.sort(),{kind:"listTasks",tasks:i,missingTaskIds:s,repoId:t?.repoId??null}}function Wl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var ft=$(()=>{"use strict";We();ie()});var Ho={};An(Ho,{addWorkspace:()=>gt,archiveWorkspace:()=>ht,listWorkspaces:()=>gr,removeWorkspace:()=>wt,removeWorkspaceRecord:()=>Jt,restoreWorkspace:()=>hr});import{readdir as bd,realpath as Wo,stat as Id}from"node:fs/promises";import $e from"node:path";async function gt(e,t){let n=$e.resolve(e.workspaceRoot,t);if(!(await Id(n).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${n}`);return await Ko(n)?Sd(e,n):Cd(e,n)}async function gr(e,t){return{kind:"listWorkspaces",workspaces:(await pe(e)).filter(r=>r.status===(t.archived?"archived":"active")),archivedOnly:t.archived}}async function ht(e,t){let r={...await ct(e,t),status:"archived",archivedAt:new Date().toISOString()};return await et(e,r),await Go(e,t),{kind:"archiveWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function hr(e,t){let r={...await ct(e,t),status:"active",archivedAt:null};await et(e,r);let s=await ue({uiStateFile:e.uiStateFile})??null;return await ae({uiStateFile:e.uiStateFile},{...s??Re(),selectedWorkspaceId:r.id,selectedRepoId:r.kind==="project"?r.discoveredRepoIds?.[0]??null:r.primaryRepoId,selectedTaskId:null}),{kind:"restoreWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function wt(e,t){let n=await ct(e,t),r=await Te(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(r.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await Jt(e,t),await Go(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}}async function Sd(e,t){let n=await Vo(t),r=await Ue(e),s=r.find(h=>h.rootPath===t)??null,o=s?Bo(s,n):_o(r,t,n),i=`workspace_${o.id}`,l=(await pe(e)).find(h=>h.id===i)??null,d=new Date().toISOString(),f=l??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:n,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await Nt(e,o),l||await et(e,f),await Uo(e,{repoIds:[o.id],workspaceIds:[f.id]}),await qo(e,f,o.id),{kind:"createWorkspace",workspace:f,repos:[o],created:!l}}async function Cd(e,t){let n=await xd(e,t);if(n.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let r=await pe(e),s=Ed(r,$e.basename(t)),o=r.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),c=n.map(d=>d.id),l=o?{...o,discoveredRepoIds:c,primaryRepoId:c[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:$e.basename(t),rootPath:t,primaryRepoId:c[0]??"",discoveredRepoIds:c,branch:"project",status:"active",linkedRepoIds:c,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(n.map(d=>Nt(e,d))),await et(e,l),await Uo(e,{repoIds:c,workspaceIds:[l.id]}),await qo(e,l,c[0]??null),{kind:"createWorkspace",workspace:l,repos:n,created:!o}}async function xd(e,t){let n=await bd(t,{withFileTypes:!0}),r=await Ue(e),s=[];for(let o of n){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=$e.join(t,o.name);if(!await Ko(i))continue;let c=r.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await Vo(i);s.push(c?Bo(c,l):_o([...r,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))}function _o(e,t,n){let r=new Date().toISOString();return{id:vd(e,$e.basename(t)),name:$e.basename(t),rootPath:t,defaultBranch:n,createdAt:r,updatedAt:r}}function Bo(e,t){return e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()}}function vd(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",r=`repo_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`repo_${n}_${s}`,s+=1;return r}function Ed(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",r=`workspace_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`workspace_${n}_${s}`,s+=1;return r}async function Uo(e,t){let n=await oe(e);await Ne(e,{...n,repoIds:[...new Set([...n.repoIds,...t.repoIds])],workspaceIds:[...new Set([...n.workspaceIds,...t.workspaceIds])]})}async function qo(e,t,n){await ae({uiStateFile:e.uiStateFile},{...await ue({uiStateFile:e.uiStateFile})??Re(),selectedRepoId:n,selectedWorkspaceId:t.id,selectedTaskId:null})}async function Ko(e){try{let n=(await v("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[r,s]=await Promise.all([Wo(n).catch(()=>$e.resolve(n)),Wo(e).catch(()=>$e.resolve(e))]);return r===s}catch{return!1}}async function Vo(e){let t=await L("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),n=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&n.length>0)return n;for(let o of["main","master","trunk"])if((await L("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await v("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"}async function Jt(e,t){await no(e,t);let n=await oe(e);await Ne(e,{...n,workspaceIds:n.workspaceIds.filter(r=>r!==t)})}async function Go(e,t){let n=await ue({uiStateFile:e.uiStateFile});!n||n.selectedWorkspaceId!==t||await ae({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}var kt=$(()=>{"use strict";We();qe();lt();Ze();ce();ft()});ee();function Ms(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Repo path cannot be empty.
4
5
 
5
- `+Y());return{mode:"command",command:{kind:"addRepo",path:n}}}if(t.length>=3&&t[0]==="workspace"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Workspace path cannot be empty.
6
+ `+J());return{mode:"command",command:{kind:"addRepo",path:n}}}if(t.length>=3&&t[0]==="workspace"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Workspace path cannot be empty.
6
7
 
7
- `+Y());return{mode:"command",command:{kind:"addWorkspace",path:n}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let n=t[2]==="--archived";if(t.length===3&&!n)throw new Error(`Unsupported command: ${t.join(" ")}
8
+ `+J());return{mode:"command",command:{kind:"addWorkspace",path:n}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let n=t[2]==="--archived";if(t.length===3&&!n)throw new Error(`Unsupported command: ${t.join(" ")}
8
9
 
9
- ${Y()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:n}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let n=t.indexOf("--repo"),r=t.indexOf("--workspace"),s=t.indexOf("--runner");if(n===-1&&r===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
10
+ ${J()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:n}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let n=t.indexOf("--repo"),r=t.indexOf("--workspace"),s=t.indexOf("--runner");if(n===-1&&r===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
10
11
 
11
- `+Y());if(n!==-1&&r!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
12
+ `+J());if(n!==-1&&r!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
12
13
 
13
- `+Y());let o=n===-1?void 0:t[n+1]?.trim()??"",i=r===-1?void 0:t[r+1]?.trim()??"",c=s===-1?void 0:rs(t[s+1]?.trim()??""),d=t.filter((f,h)=>h>1&&h!==n&&h!==n+1&&h!==r&&h!==r+1&&h!==s&&h!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
14
+ `+J());let o=n===-1?void 0:t[n+1]?.trim()??"",i=r===-1?void 0:t[r+1]?.trim()??"",c=s===-1?void 0:b.runners.parse(t[s+1]?.trim()??""),d=t.filter((f,h)=>h>1&&h!==n&&h!==n+1&&h!==r&&h!==r+1&&h!==s&&h!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
14
15
 
15
- `+Y());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
16
+ `+J());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
16
17
 
17
- `+Y());if(d.length===0)throw new Error(`Task prompt cannot be empty.
18
+ `+J());if(d.length===0)throw new Error(`Task prompt cannot be empty.
18
19
 
19
- `+Y());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:d,...c?{runner:c}:{}}}}if(t.length>=2&&t.length<=4&&t[0]==="task"&&t[1]==="list"){if(t.length===2)return{mode:"command",command:{kind:"listTasks"}};if(t.length===4&&t[2]==="--repo")return{mode:"command",command:{kind:"listTasks",repoId:t[3].trim()}};throw new Error(`Unsupported command: ${t.join(" ")}
20
+ `+J());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:d,...c?{runner:c}:{}}}}if(t.length>=2&&t.length<=4&&t[0]==="task"&&t[1]==="list"){if(t.length===2)return{mode:"command",command:{kind:"listTasks"}};if(t.length===4&&t[2]==="--repo")return{mode:"command",command:{kind:"listTasks",repoId:t[3].trim()}};throw new Error(`Unsupported command: ${t.join(" ")}
20
21
 
21
- ${Y()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:Re(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:Re(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:Re(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:Re(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:Re(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:Re(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:Re(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:Re(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:Re(t[2]),repoId:qa(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:Re(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
22
+ ${J()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:we(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:we(t[2]),repoId:Pc(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:we(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
22
23
 
23
- ${Y()}`)}function Y(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
24
- `)}function Re(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
24
+ ${J()}`)}function J(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
25
+ `)}function we(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
25
26
 
26
- ${Y()}`);return t}function qa(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
27
+ ${J()}`);return t}function Pc(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
27
28
 
28
- ${Y()}`);return t}import Us from"node:path";ue();import{mkdir as Ka,readFile as Va,writeFile as Ga}from"node:fs/promises";import Ha from"node:path";async function Te(e){try{let t=await Va(e.configFile,"utf8"),n=JSON.parse(t);return is(n,e.configFile)}catch(t){if(za(t))return{};throw t instanceof SyntaxError?new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`):t}}async function os(e,t){is(t,e.configFile),await Ka(Ha.dirname(e.configFile),{recursive:!0}),await Ga(e.configFile,`${JSON.stringify(t,null,2)}
29
- `,"utf8")}function is(e,t){if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let n=e;if(n.runners!==void 0){if(typeof n.runners!="object"||n.runners===null||Array.isArray(n.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[r,s]of Object.entries(n.runners)){if(!N.includes(r))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" is not supported. Expected one of: ${N.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${r}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${r}.path" must be a non-empty string.`)}}if(n.checks!==void 0&&(typeof n.checks!="object"||n.checks===null||!Array.isArray(n.checks.commands)||!n.checks.commands.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(n.open!==void 0&&(typeof n.open!="object"||n.open===null||!Array.isArray(n.open.command)||!n.open.command.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(n.github!==void 0){if(typeof n.github!="object"||n.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(n.github.mergeMethod!==void 0&&n.github.mergeMethod!=="merge"&&n.github.mergeMethod!=="rebase"&&n.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(n.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(n.github.watchIntervalSeconds)||n.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return n}function za(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}ye();import{readFile as Za,readdir as nm,rm}from"node:fs/promises";import ec from"node:path";async function tt(e,t){let n=await Za(Dn(e,t),"utf8"),r=JSON.parse(n);return tc(r,Dn(e,t))}async function Be(e,t){await W(Dn(e,t.id),{...t,updatedAt:new Date().toISOString()})}function Dn(e,t){return ec.join(e.sessionsDir,`${t}.json`)}function tc(e,t){let n=sc(e);if(typeof n!="object"||n===null||typeof n.id!="string"||typeof n.taskId!="string"||typeof n.repoId!="string"||typeof n.workspaceId!="string"||n.substrate!=="tmux"||typeof n.sessionName!="string"||typeof n.paneId!="string"||!(n.windowTarget===null||typeof n.windowTarget=="string")||typeof n.worktreePath!="string"||!(n.logPath===null||typeof n.logPath=="string")||!Array.isArray(n.command)||!n.command.every(r=>typeof r=="string")||!["starting","running","exited","failed"].includes(n.status)||!(n.startedAt===null||typeof n.startedAt=="string")||!(n.exitedAt===null||typeof n.exitedAt=="string")||!(n.exitCode===null||typeof n.exitCode=="number")||!(n.lastAttachedAt===null||typeof n.lastAttachedAt=="string")||!rc(n.attach)||!nc(n.snapshot)||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function nc(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function rc(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function sc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(n=>typeof n=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}ie();rt();ce();function Lt(e){return`'${e.replace(/'/g,"'\\''")}'`}import{accessSync as Lc,constants as Oc}from"node:fs";import{homedir as ws}from"node:os";import Me from"node:path";var Fc=[Me.join(ws(),".local","bin"),Me.join(ws(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Rs(e=process.env){return jc([...(e.PATH??"").split(Me.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:Fc])}function Ke(e=process.env){return{...e,PATH:Rs(e).join(Me.delimiter)}}function jn(e,t={}){if(e.includes(Me.sep)){let n=Me.isAbsolute(e)?e:Me.resolve(t.cwd??process.cwd(),e);return ks(n)?n:null}for(let n of Rs(t.env)){let r=Me.join(n,e);if(ks(r))return r}return null}function Ve(e,t={}){let n=jn(e,t);if(n)return n;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function ks(e){try{return Lc(e,Oc.X_OK),!0}catch{return!1}}function jc(e){return[...new Set(e)]}ue();ce();import{spawn as Nc}from"node:child_process";import{createHash as Wc}from"node:crypto";import _c from"node:path";var Bc="craig";async function Ts(e,t,n){let r=Nn(e,t),s=qc(),o=await x("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",r,"-n","runner",...s,"-c",n],{cwd:e}),i=Vc(o.stdout);return await Uc(e,r),i}async function Uc(e,t){let n=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let r of n)await x("tmux",r,{cwd:e})}async function ys(e,t,n){await x("tmux",["resize-window","-t",t,"-x",`${n.columns}`,"-y",`${n.rows}`],{cwd:e})}async function Ps(e,t,n){await x("tmux",["send-keys","-t",e,t,"C-m"],{cwd:n})}async function bs(e,t,n){await x("tmux",["pipe-pane","-o","-t",e,`cat >> ${Lt(t)}`],{cwd:n})}async function Ot(e,t,n,r){let s=r??Is(e);if(n?await x("tmux",["select-window","-t",n],{cwd:e}):await x("tmux",["select-window","-t",t],{cwd:e}),await x("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await x("tmux",["switch-client","-t",s],{cwd:e});return}await Hc(e,["attach-session","-t",s])}function Is(e){let n=_c.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",r=Wc("sha1").update(e).digest("hex").slice(0,8);return`${Bc}-${n}-${r}`}function Nn(e,t){return`${Is(e)}-${t.toLowerCase()}`}function qc(){let e=Kc();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]}function Kc(){let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let n="columns"in t?t.columns:void 0,r="rows"in t?t.rows:void 0;if(typeof n=="number"&&n>0&&typeof r=="number"&&r>0)return{columns:n,rows:r}}return null}function Vc(e){let t=Gc(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}}function Gc(e){return e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0)}async function Hc(e,t){await new Promise((n,r)=>{let s=Nc("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",r),s.on("exit",o=>{if(o===0){n();return}r(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})}var Wn={async prepare(e,t){let n=e.runnerSession.command[0]??z(e.runner)[0],r=Ke();await x(Ve(n,{cwd:t.repoRoot,env:r}),["--help"],{cwd:t.repoRoot,env:r})},async launch(e,t){let n=e.runnerSession.command.length>0?e.runnerSession.command:z(e.runner,e.prompt.value),r=Ve(n[0],{cwd:e.worktreePath,env:Ke()});await Ps(t.session.paneId,[r,...n.slice(1)].map(s=>Lt(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}};ue();ce();var ut={async create(e,t){let n=await Ts(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await bs(n.paneId,t.logPath,t.repoRoot);let r=await Ss({paneId:n.paneId,windowTarget:n.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:n.sessionName||Nn(t.repoRoot,t.taskId),paneId:n.paneId,windowTarget:n.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:r,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await Be(e,s),s},async attach(e,t,n){let r=await ut.snapshot(t,n);if(!r.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Ot(n,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:r};return await Be(e,s),s},async resize(e,t,n,r){await ys(r,t.sessionName,n);let s={...t,attach:{...t.attach,lastSize:n}};return await Be(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,n){let r={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:(n.length>0,t.command)};return await Be(e,r),r},async snapshot(e,t){return zc(e,t)}};async function zc(e,t){let n=await D("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Ss({paneId:e.paneId,windowTarget:e.windowTarget,alive:n.exitCode===0&&n.stdout.split(/\s+/).some(r=>r.trim()===e.paneId)})}async function Ss(e){return{paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()}}He();ie();pt();import{mkdir as mt,rm as ol,writeFile as _t}from"node:fs/promises";import $ from"node:path";ce();async function As(e,t){let n=await D("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(n.exitCode===0)return!0;if(n.exitCode===1)return!1;throw new Error(n.stderr.trim()||n.stdout.trim()||"Unable to check git branch state.")}async function _n(e,t,n,r="main"){let s=r.trim()||"main";if((await D("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 sl(e,s);await x("git",["worktree","add","-b",t,n,i],{cwd:e})}async function sl(e,t){return(await D("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await D("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await D("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t}async function Wt(e){let t=await D("git",["status","--short"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"Unable to inspect git status.");return t.stdout.trim().length>0}async function $s(e){await x("git",["add","-A"],{cwd:e})}async function Ds(e,t){await x("git",["commit","-m",t],{cwd:e})}async function Ms(e){let t=await x("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[n="",r=""]=t.stdout.trim().split(`
30
- `);if(!n||!r)throw new Error("Unable to read git HEAD commit metadata.");return{sha:n,message:r}}ue();qe();async function Ls(e,t){let n=await oe(e),r=Fs(new Date),s=js(n.taskIds,r);for(;;){let o=`task_${r}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await As(t,i))return o;s+=1}}async function Os(e){let t=await oe(e),n=Fs(new Date),r=js(t.taskIds,n);return`task_${n}_${String(r).padStart(2,"0")}`}function Fs(e){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}${n}${r}`}function js(e,t){let n=e.filter(r=>r.startsWith(`task_${t}_`)).map(r=>Number.parseInt(r.slice(-2),10)).filter(r=>Number.isInteger(r));return n.length===0?1:Math.max(...n)+1}var Ws=["AGENTS","md"].join(".");async function gt(e,t,n,r={}){let s=await pe(e,t),o=await dl(e,s.id),i=await Ls(e,s.rootPath),c=r.sessionId??null,l=`craig/${i}`,d=$.join(e.worktreesDir,s.id,i),f=$.join(e.logsDir,`${i}.log`),h=$.join(e.artifactsDir,i);await mt($.dirname(d),{recursive:!0}),await mt(h,{recursive:!0}),await _t(f,"","utf8");let R=il(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:c,repoRoot:s.rootPath,prompt:n,runner:r.runner??"codex",config:r.config??{},branch:l,worktreePath:d});return await E(e,R),await On(e,i),await _n(s.rootPath,l,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:c,workspaceId:o.id,task:R}}async function Ut(e,t,n,r={}){let s=(await me(e)).find(C=>C.id===t&&C.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 C=await gt(e,s.primaryRepoId,n,r);return{...C,bundlePath:C.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await Os(e),c=new Date().toISOString(),l=r.runner??"codex",d=r.sessionId??null,f=`craig/${i}`,h=$.join(e.craigDir,"task-bundles",i),R=$.join(e.logsDir,`${i}.log`),k=$.join(e.artifactsDir,i);await mt(h,{recursive:!0}),await mt(k,{recursive:!0}),await _t(R,"","utf8");let I=await Promise.all(o.map(C=>pe(e,C))),T=cl(I),a=await Promise.all(I.map(C=>al(e,C,i,f,$.join(h,T.get(C.id))))),V=a.find(C=>C.status==="ready")??a[0];if(!a.some(C=>C.status==="ready"))throw await ol(h,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${a.map(C=>`${C.repoId}: ${C.failureReason??"unknown error"}`).join("; ")}`);await _t($.join(h,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:n,repos:a.map(C=>({repoId:C.repoId,repoName:I.find(Ne=>Ne.id===C.repoId)?.name??C.repoId,path:$.relative(h,C.worktreePath),status:C.status,worktreePath:C.worktreePath,failureReason:C.failureReason}))},null,2),"utf8"),await _t($.join(h,Ws),ll({taskId:i,workspaceId:t,prompt:n,repos:I,repoTargets:a,bundlePath:h}),"utf8");let j=_s(i,n,c,l,r.config??{}),te={id:i,title:n,slug:Bs(n),type:"project",status:"draft",runner:l,repoId:V.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:j[0]?.id??null,linkedRepoIds:o.filter(C=>C!==V.repoId),repoRoot:h,worktreePath:h,branch:f,bundlePath:h,selectedRepoTargetId:V.repoId,repoTargets:a,ptyTabs:j,runnerSession:{command:z(l,n,r.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:n},checks:V.checks,lastCommit:null,prs:[],artifacts:{logPath:$.relative(e.workspaceRoot,R),checkSummaryPath:$.relative(e.workspaceRoot,$.join(k,"check-summary.json")),prDraftPath:null,prStatusPath:$.relative(e.workspaceRoot,$.join(k,"pr-status.json"))},cleanup:Bt(),lastFailureReason:a.every(C=>C.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:c,updatedAt:c};return await E(e,te),await On(e,i),{repoId:V.repoId,repoRoot:h,sessionId:d,workspaceId:s.id,task:te,bundlePath:h,repoTargets:a}}function _s(e,t,n,r="codex",s={}){let o=Z(r);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:z(r,void 0,s),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function il(e,t){let n=new Date().toISOString(),r=_s(t.taskId,t.prompt,n,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:Bs(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:r[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:r,runnerSession:{command:z(t.runner,t.prompt,t.config),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:t.prompt},checks:{...Bn($.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:Bt(),lastFailureReason:null,createdAt:n,updatedAt:n}}async function al(e,t,n,r,s){await mt($.dirname(s),{recursive:!0});try{return await _n(t.rootPath,r,s,t.defaultBranch),{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:Bn($.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Ns(),cleanup:Bt()}}catch(o){return{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:o instanceof Error?o.message:"Failed to create worktree.",checks:Bn($.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Ns(),cleanup:Bt()}}}function cl(e){let t=new Set(["manifest.json",Ws]),n=new Map;for(let r of e){let s=t.has(r.name)?`${r.name}-repo`:r.name,o=s,i=2;for(;t.has(o);)o=`${s}-${i}`,i+=1;t.add(o),n.set(r.id,o)}return n}function ll(e){let t=new Map(e.repos.map(r=>[r.id,r.name])),n=e.repoTargets.map(r=>{let s=t.get(r.repoId)??r.repoId,o=$.relative(e.bundlePath,r.worktreePath),i=r.status==="ready"?"ready":`unavailable: ${r.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${r.repoId}, ${i})`}).join(`
29
+ ${J()}`);return t}ee();import ho from"node:path";ke();import{readFile as xc,readdir as yg,rm as Pg}from"node:fs/promises";import vc from"node:path";async function Qe(e,t){let n=await xc(qn(e,t),"utf8"),r=JSON.parse(n);return Ec(r,qn(e,t))}async function je(e,t){await B(qn(e,t.id),{...t,updatedAt:new Date().toISOString()})}function qn(e,t){return vc.join(e.sessionsDir,`${t}.json`)}function Ec(e,t){let n=Dc(e);if(typeof n!="object"||n===null||typeof n.id!="string"||typeof n.taskId!="string"||typeof n.repoId!="string"||typeof n.workspaceId!="string"||n.substrate!=="tmux"||typeof n.sessionName!="string"||typeof n.paneId!="string"||!(n.windowTarget===null||typeof n.windowTarget=="string")||typeof n.worktreePath!="string"||!(n.logPath===null||typeof n.logPath=="string")||!Array.isArray(n.command)||!n.command.every(r=>typeof r=="string")||!["starting","running","exited","failed"].includes(n.status)||!(n.startedAt===null||typeof n.startedAt=="string")||!(n.exitedAt===null||typeof n.exitedAt=="string")||!(n.exitCode===null||typeof n.exitCode=="number")||!(n.lastAttachedAt===null||typeof n.lastAttachedAt=="string")||!$c(n.attach)||!Ac(n.snapshot)||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function Ac(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 $c(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 Dc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(n=>typeof n=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}ie();Ze();ce();function Ot(e){return`'${e.replace(/'/g,"'\\''")}'`}import{accessSync as cl,constants as ll}from"node:fs";import{homedir as Ks}from"node:os";import Ae from"node:path";var dl=[Ae.join(Ks(),".local","bin"),Ae.join(Ks(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Gs(e=process.env){return ul([...(e.PATH??"").split(Ae.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:dl])}function _e(e=process.env){return{...e,PATH:Gs(e).join(Ae.delimiter)}}function zn(e,t={}){if(e.includes(Ae.sep)){let n=Ae.isAbsolute(e)?e:Ae.resolve(t.cwd??process.cwd(),e);return Vs(n)?n:null}for(let n of Gs(t.env)){let r=Ae.join(n,e);if(Vs(r))return r}return null}function Be(e,t={}){let n=zn(e,t);if(n)return n;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function Vs(e){try{return cl(e,ll.X_OK),!0}catch{return!1}}function ul(e){return[...new Set(e)]}ee();ce();import{spawn as fl}from"node:child_process";import{createHash as pl}from"node:crypto";import ml from"node:path";var gl="craig";async function Hs(e,t,n){let r=Yn(e,t),s=wl(),o=await v("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",r,"-n","runner",...s,"-c",n],{cwd:e}),i=Rl(o.stdout);return await hl(e,r),i}async function hl(e,t){let n=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let r of n)await v("tmux",r,{cwd:e})}async function zs(e,t,n){await v("tmux",["resize-window","-t",t,"-x",`${n.columns}`,"-y",`${n.rows}`],{cwd:e})}async function Ys(e,t,n){await v("tmux",["send-keys","-t",e,t,"C-m"],{cwd:n})}async function Js(e,t,n){await v("tmux",["pipe-pane","-o","-t",e,`cat >> ${Ot(t)}`],{cwd:n})}async function Ft(e,t,n,r){let s=r??Qs(e);if(n?await v("tmux",["select-window","-t",n],{cwd:e}):await v("tmux",["select-window","-t",t],{cwd:e}),await v("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await v("tmux",["switch-client","-t",s],{cwd:e});return}await yl(e,["attach-session","-t",s])}function Qs(e){let n=ml.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",r=pl("sha1").update(e).digest("hex").slice(0,8);return`${gl}-${n}-${r}`}function Yn(e,t){return`${Qs(e)}-${t.toLowerCase()}`}function wl(){let e=kl();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]}function kl(){let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let n="columns"in t?t.columns:void 0,r="rows"in t?t.rows:void 0;if(typeof n=="number"&&n>0&&typeof r=="number"&&r>0)return{columns:n,rows:r}}return null}function Rl(e){let t=Tl(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}}function Tl(e){return e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0)}async function yl(e,t){await new Promise((n,r)=>{let s=fl("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",r),s.on("exit",o=>{if(o===0){n();return}r(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})}var Jn={async prepare(e,t){let n=e.runnerSession.command[0]??b.runners.buildCommand(e.runner)[0],r=_e();await v(Be(n,{cwd:t.repoRoot,env:r}),["--help"],{cwd:t.repoRoot,env:r})},async launch(e,t){let n=e.runnerSession.command.length>0?e.runnerSession.command:b.runners.buildCommand(e.runner,e.prompt.value),r=Be(n[0],{cwd:e.worktreePath,env:_e()});await Ys(t.session.paneId,[r,...n.slice(1)].map(s=>Ot(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}};ce();var at={async create(e,t){let n=await Hs(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await Js(n.paneId,t.logPath,t.repoRoot);let r=await Xs({paneId:n.paneId,windowTarget:n.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:n.sessionName||Yn(t.repoRoot,t.taskId),paneId:n.paneId,windowTarget:n.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:r,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await je(e,s),s},async attach(e,t,n){let r=await at.snapshot(t,n);if(!r.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Ft(n,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:r};return await je(e,s),s},async resize(e,t,n,r){await zs(r,t.sessionName,n);let s={...t,attach:{...t.attach,lastSize:n}};return await je(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,n){let r={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:(n.length>0,t.command)};return await je(e,r),r},async snapshot(e,t){return Pl(e,t)}};async function Pl(e,t){let n=await L("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Xs({paneId:e.paneId,windowTarget:e.windowTarget,alive:n.exitCode===0&&n.stdout.split(/\s+/).some(r=>r.trim()===e.paneId)})}async function Xs(e){return{paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()}}qe();ie();ee();lt();import{mkdir as dt,rm as Ml,writeFile as Bt}from"node:fs/promises";import M from"node:path";ce();async function ro(e,t){let n=await L("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(n.exitCode===0)return!0;if(n.exitCode===1)return!1;throw new Error(n.stderr.trim()||n.stdout.trim()||"Unable to check git branch state.")}async function Qn(e,t,n,r="main"){let s=r.trim()||"main";if((await L("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 Dl(e,s);await v("git",["worktree","add","-b",t,n,i],{cwd:e})}async function Dl(e,t){return(await L("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await L("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await L("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t}async function _t(e){let t=await L("git",["status","--short"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"Unable to inspect git status.");return t.stdout.trim().length>0}async function so(e){await v("git",["add","-A"],{cwd:e})}async function oo(e,t){await v("git",["commit","-m",t],{cwd:e})}async function io(e){let t=await v("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[n="",r=""]=t.stdout.trim().split(`
30
+ `);if(!n||!r)throw new Error("Unable to read git HEAD commit metadata.");return{sha:n,message:r}}We();async function ao(e,t){let n=await oe(e),r=lo(new Date),s=uo(n.taskIds,r);for(;;){let o=`task_${r}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await ro(t,i))return o;s+=1}}async function co(e){let t=await oe(e),n=lo(new Date),r=uo(t.taskIds,n);return`task_${n}_${String(r).padStart(2,"0")}`}function lo(e){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}${n}${r}`}function uo(e,t){let n=e.filter(r=>r.startsWith(`task_${t}_`)).map(r=>Number.parseInt(r.slice(-2),10)).filter(r=>Number.isInteger(r));return n.length===0?1:Math.max(...n)+1}var po=["AGENTS","md"].join(".");async function ut(e,t,n,r={}){let s=await fe(e,t),o=await Nl(e,s.id),i=await ao(e,s.rootPath),c=r.sessionId??null,l=`craig/${i}`,d=M.join(e.worktreesDir,s.id,i),f=M.join(e.logsDir,`${i}.log`),h=M.join(e.artifactsDir,i);await dt(M.dirname(d),{recursive:!0}),await dt(h,{recursive:!0}),await Bt(f,"","utf8");let R=Ll(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:c,repoRoot:s.rootPath,prompt:n,runner:r.runner??"codex",config:r.config??{},branch:l,worktreePath:d});return await A(e,R),await Gn(e,i),await Qn(s.rootPath,l,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:c,workspaceId:o.id,task:R}}async function qt(e,t,n,r={}){let s=(await pe(e)).find(x=>x.id===t&&x.status==="active");if(!s)throw new Error(`Workspace ${t} does not exist or is archived.`);if(s.kind!=="project"){if(!s.primaryRepoId)throw new Error(`Workspace ${t} is not task-capable.`);let x=await ut(e,s.primaryRepoId,n,r);return{...x,bundlePath:x.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await co(e),c=new Date().toISOString(),l=r.runner??"codex",d=r.sessionId??null,f=`craig/${i}`,h=M.join(e.craigDir,"task-bundles",i),R=M.join(e.logsDir,`${i}.log`),k=M.join(e.artifactsDir,i);await dt(h,{recursive:!0}),await dt(k,{recursive:!0}),await Bt(R,"","utf8");let S=await Promise.all(o.map(x=>fe(e,x))),T=Fl(S),a=await Promise.all(S.map(x=>Ol(e,x,i,f,M.join(h,T.get(x.id))))),H=a.find(x=>x.status==="ready")??a[0];if(!a.some(x=>x.status==="ready"))throw await Ml(h,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${a.map(x=>`${x.repoId}: ${x.failureReason??"unknown error"}`).join("; ")}`);await Bt(M.join(h,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:n,repos:a.map(x=>({repoId:x.repoId,repoName:S.find(Oe=>Oe.id===x.repoId)?.name??x.repoId,path:M.relative(h,x.worktreePath),status:x.status,worktreePath:x.worktreePath,failureReason:x.failureReason}))},null,2),"utf8"),await Bt(M.join(h,po),jl({taskId:i,workspaceId:t,prompt:n,repos:S,repoTargets:a,bundlePath:h}),"utf8");let _=mo(i,n,c,l,r.config??{}),ne={id:i,title:n,slug:go(n),type:"project",status:"draft",runner:l,repoId:H.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:_[0]?.id??null,linkedRepoIds:o.filter(x=>x!==H.repoId),repoRoot:h,worktreePath:h,branch:f,bundlePath:h,selectedRepoTargetId:H.repoId,repoTargets:a,ptyTabs:_,runnerSession:{command:b.runners.buildCommand(l,n,r.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:n},checks:H.checks,lastCommit:null,prs:[],artifacts:{logPath:M.relative(e.workspaceRoot,R),checkSummaryPath:M.relative(e.workspaceRoot,M.join(k,"check-summary.json")),prDraftPath:null,prStatusPath:M.relative(e.workspaceRoot,M.join(k,"pr-status.json"))},cleanup:Ut(),lastFailureReason:a.every(x=>x.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:c,updatedAt:c};return await A(e,ne),await Gn(e,i),{repoId:H.repoId,repoRoot:h,sessionId:d,workspaceId:s.id,task:ne,bundlePath:h,repoTargets:a}}function mo(e,t,n,r="codex",s={}){let o=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:b.runners.buildCommand(r,void 0,s),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function Ll(e,t){let n=new Date().toISOString(),r=mo(t.taskId,t.prompt,n,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:go(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:r[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:r,runnerSession:{command:b.runners.buildCommand(t.runner,t.prompt,t.config),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:t.prompt},checks:{...Xn(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:Ut(),lastFailureReason:null,createdAt:n,updatedAt:n}}async function Ol(e,t,n,r,s){await dt(M.dirname(s),{recursive:!0});try{return await Qn(t.rootPath,r,s,t.defaultBranch),{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:Xn(M.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:fo(),cleanup:Ut()}}catch(o){return{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:o instanceof Error?o.message:"Failed to create worktree.",checks:Xn(M.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:fo(),cleanup:Ut()}}}function Fl(e){let t=new Set(["manifest.json",po]),n=new Map;for(let r of e){let s=t.has(r.name)?`${r.name}-repo`:r.name,o=s,i=2;for(;t.has(o);)o=`${s}-${i}`,i+=1;t.add(o),n.set(r.id,o)}return n}function jl(e){let t=new Map(e.repos.map(r=>[r.id,r.name])),n=e.repoTargets.map(r=>{let s=t.get(r.repoId)??r.repoId,o=M.relative(e.bundlePath,r.worktreePath),i=r.status==="ready"?"ready":`unavailable: ${r.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${r.repoId}, ${i})`}).join(`
31
31
  `);return["# Craig Project Task Bundle","","This directory is a Craig project task bundle. Repo work must happen inside the child repo worktrees listed below.","","Run repo Git commands from a repo worktree directory, not from the bundle root. Use `manifest.json` as the machine-readable source of truth for this bundle.","",`Task: \`${e.taskId}\``,`Workspace: \`${e.workspaceId}\``,`Prompt: ${e.prompt}`,"","## Repo Worktrees","",n,""].join(`
32
- `)}function Bn(e){return{source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}}function Ns(){return{provider:"github",number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}}function Bt(){return{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}async function dl(e,t){let r=(await me(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!r)throw new Error(`Repo ${t} does not have an active workspace.`);return r}function Bs(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-")}async function qs(e,t,n,r={}){let s=n.trim(),o=await Te(e),i=r.runner??_e(o);if(Dt(i,o),t.trim().length===0)throw new Error(r.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let c=r.workspaceId?await Ut(e,r.workspaceId,s,{runner:i,config:o}):await gt(e,t,s,{runner:i,config:o}),l=c.task,d=z(i,s,o),f=`session_${l.id}`,h=l.artifacts.logPath?Us.resolve(e.workspaceRoot,l.artifacts.logPath):Us.join(e.logsDir,`${l.id}.log`);try{await Wn.prepare(l,{repoRoot:c.repoRoot});let R=await ut.create(e,{sessionId:f,taskId:l.id,repoId:c.repoId,workspaceId:c.workspaceId,repoRoot:c.repoRoot,worktreePath:l.worktreePath,logPath:h,command:d});await Wn.launch(l,{repoRoot:c.repoRoot,session:R});let k=new Date().toISOString();R={...R,status:"running",startedAt:k,command:d};let I={...l,status:"running",runner:i,sessionId:R.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:R.command,pid:null,startedAt:k,lastKnownState:"running",exitCode:null,exitedAt:null}};return await E(e,I),await Be(e,R),await ae({uiStateFile:e.uiStateFile},{...await fe({uiStateFile:e.uiStateFile})??Pe(),selectedRepoId:I.repoId,selectedWorkspaceId:I.workspaceId,selectedTaskId:I.id,selectedPtyTabId:I.selectedPtyTabId}),{kind:"createTask",taskId:I.id,repoId:I.repoId,workspaceId:I.workspaceId,sessionId:R.id,status:I.status,branch:I.branch,worktreePath:I.worktreePath,runner:I.runner}}catch(R){let k={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:R instanceof Error?R.message:"Unknown Craig error"};throw await E(e,k),R}}ht();He();ie();import{access as Ll}from"node:fs/promises";import ro from"node:path";ye();ie();import{mkdir as fl,readFile as Cg,writeFile as xg}from"node:fs/promises";import pl from"node:path";ce();import Ks from"node:path";function qt(e,t){return t?Ks.isAbsolute(t)?t:Ks.join(e.repoRoot,t):null}function K(e){return e.prs.length===0?null:[...e.prs].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e.prs[e.prs.length-1]??null}function Gt(e){return e.status==="merged"||e.status==="closed"}function Vs(e,t){let n=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),r=n>=0?e.prs.map((s,o)=>o===n?t:s):[...e.prs,t];return{...e,prs:r}}var Gs=3,ml=1e3,gl=1e4;async function wt(e){let t=await D("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")}async function Kn(e,t){let n=K(t),r=n?.number?String(n.number):t.branch,s=await x("gh",Vt(r),{cwd:t.worktreePath}),o=JSON.parse(s.stdout);return Gn(e,t,o,n)}async function Vn(e,t){let n=await D("gh",Vt(t.branch),{cwd:t.worktreePath});if(n.exitCode!==0)return{discovered:!1,task:t};let r=JSON.parse(n.stdout);return{discovered:!0,task:await Gn(e,t,r,null)}}async function zs(e){let t=await D("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:bl(t.stdout.trim())}async function Ys(e,t,n){if(n.length===0)return[];let r=Il(n),s=await hl(e,["api","graphql","-f",`query=${r}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return n.map((c,l)=>{let d=i[`item${l}`],f=Sl(d);return{id:c.id,found:f!==null,view:f}})}async function hl(e,t){let n;for(let r=0;r<=Gs;r+=1)try{return await x("gh",t,{cwd:e})}catch(s){if(n=s,r===Gs||!wl(s))throw s;await Rl(kl(r))}throw n}function wl(e){let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")}function kl(e){let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||ml,n=Math.min(t*2**e,gl),r=Math.floor(Math.random()*Math.max(1,Math.floor(n*.25)));return n+r}function Rl(e){return new Promise(t=>setTimeout(t,e))}async function kt(e,t,n){let r=n.pullRequest.number?String(n.pullRequest.number):n.branch;if(n.pullRequest.number){let i=await x("gh",Vt(r),{cwd:n.worktreePath}),c=qn(JSON.parse(i.stdout));return n.pullRequest=c,await Un(e,t,n.repoId,c),"synced"}let s=await D("gh",Vt(r),{cwd:n.worktreePath});if(s.exitCode!==0)return"not_found";let o=qn(JSON.parse(s.stdout));return n.pullRequest=o,await Un(e,t,n.repoId,o),"discovered"}async function Js(e,t,n){return Gn(e,t,n,K(t))}async function Qs(e,t,n,r){return Un(e,t,n,qn(r))}async function Xs(e,t){let n=qt(e,t.artifacts.prStatusPath);n&&(await fl(pl.dirname(n),{recursive:!0}),await W(n,{taskId:t.id,prs:t.prs}))}function Tl(e){return e.mergeable&&!yl(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}function yl(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Pl(e){if(e.length===0)return"checked";let t=[...e].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e[e.length-1];return Tl(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"}function Vt(e){return["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"]}function bl(e){let t=e.replace(/\.git$/,""),n=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let r=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null}function Il(e){return`
32
+ `)}function Xn(e){return{source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}}function fo(){return{provider:"github",number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}}function Ut(){return{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}async function Nl(e,t){let r=(await pe(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!r)throw new Error(`Repo ${t} does not have an active workspace.`);return r}function go(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-")}async function wo(e,t,n,r={}){let s=n.trim(),o=await b.load(e),i=r.runner??b.runners.getDefault(o);if(b.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(r.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let c=r.workspaceId?await qt(e,r.workspaceId,s,{runner:i,config:o}):await ut(e,t,s,{runner:i,config:o}),l=c.task,d=b.runners.buildCommand(i,s,o),f=`session_${l.id}`,h=l.artifacts.logPath?ho.resolve(e.workspaceRoot,l.artifacts.logPath):ho.join(e.logsDir,`${l.id}.log`);try{await Jn.prepare(l,{repoRoot:c.repoRoot});let R=await at.create(e,{sessionId:f,taskId:l.id,repoId:c.repoId,workspaceId:c.workspaceId,repoRoot:c.repoRoot,worktreePath:l.worktreePath,logPath:h,command:d});await Jn.launch(l,{repoRoot:c.repoRoot,session:R});let k=new Date().toISOString();R={...R,status:"running",startedAt:k,command:d};let S={...l,status:"running",runner:i,sessionId:R.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:R.command,pid:null,startedAt:k,lastKnownState:"running",exitCode:null,exitedAt:null}};return await A(e,S),await je(e,R),await ae({uiStateFile:e.uiStateFile},{...await ue({uiStateFile:e.uiStateFile})??Re(),selectedRepoId:S.repoId,selectedWorkspaceId:S.workspaceId,selectedTaskId:S.id,selectedPtyTabId:S.selectedPtyTabId}),{kind:"createTask",taskId:S.id,repoId:S.repoId,workspaceId:S.workspaceId,sessionId:R.id,status:S.status,branch:S.branch,worktreePath:S.worktreePath,runner:S.runner}}catch(R){let k={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:R instanceof Error?R.message:"Unknown Craig error"};throw await A(e,k),R}}ft();qe();ie();import{access as cd}from"node:fs/promises";import $o from"node:path";ke();ie();ee();ce();import{mkdir as _l,readFile as Kh,writeFile as Vh}from"node:fs/promises";import Bl from"node:path";import ko from"node:path";function Kt(e,t){return t?ko.isAbsolute(t)?t:ko.join(e.repoRoot,t):null}function G(e){return e.prs.length===0?null:[...e.prs].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e.prs[e.prs.length-1]??null}function Ht(e){return e.status==="merged"||e.status==="closed"}function Ro(e,t){let n=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),r=n>=0?e.prs.map((s,o)=>o===n?t:s):[...e.prs,t];return{...e,prs:r}}var To=3,Ul=1e3,ql=1e4;async function pt(e){let t=await L("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")}async function tr(e,t){let n=G(t),r=n?.number?String(n.number):t.branch,s=await v("gh",Gt(r),{cwd:t.worktreePath}),o=JSON.parse(s.stdout);return rr(e,t,o,n)}async function nr(e,t){let n=await L("gh",Gt(t.branch),{cwd:t.worktreePath});if(n.exitCode!==0)return{discovered:!1,task:t};let r=JSON.parse(n.stdout);return{discovered:!0,task:await rr(e,t,r,null)}}async function Po(e){let t=await L("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:Ql(t.stdout.trim())}async function bo(e,t,n){if(n.length===0)return[];let r=Xl(n),s=await Kl(e,["api","graphql","-f",`query=${r}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return n.map((c,l)=>{let d=i[`item${l}`],f=Zl(d);return{id:c.id,found:f!==null,view:f}})}async function Kl(e,t){let n;for(let r=0;r<=To;r+=1)try{return await v("gh",t,{cwd:e})}catch(s){if(n=s,r===To||!Vl(s))throw s;await Hl(Gl(r))}throw n}function Vl(e){let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")}function Gl(e){let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||Ul,n=Math.min(t*2**e,ql),r=Math.floor(Math.random()*Math.max(1,Math.floor(n*.25)));return n+r}function Hl(e){return new Promise(t=>setTimeout(t,e))}async function mt(e,t,n){let r=n.pullRequest.number?String(n.pullRequest.number):n.branch;if(n.pullRequest.number){let i=await v("gh",Gt(r),{cwd:n.worktreePath}),c=er(JSON.parse(i.stdout));return n.pullRequest=c,await Zn(e,t,n.repoId,c),"synced"}let s=await L("gh",Gt(r),{cwd:n.worktreePath});if(s.exitCode!==0)return"not_found";let o=er(JSON.parse(s.stdout));return n.pullRequest=o,await Zn(e,t,n.repoId,o),"discovered"}async function Io(e,t,n){return rr(e,t,n,G(t))}async function So(e,t,n,r){return Zn(e,t,n,er(r))}async function Co(e,t){let n=Kt(e,t.artifacts.prStatusPath);n&&(await _l(Bl.dirname(n),{recursive:!0}),await B(n,{taskId:t.id,prs:t.prs}))}function zl(e){return e.mergeable&&!Yl(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}function Yl(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Jl(e){if(e.length===0)return"checked";let t=[...e].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e[e.length-1];return zl(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"}function Gt(e){return["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"]}function Ql(e){let t=e.replace(/\.git$/,""),n=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let r=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null}function Xl(e){return`
33
33
  query CraigPullRequestBatch($owner: String!, $name: String!) {
34
34
  repository(owner: $owner, name: $name) {
35
35
  ${e.map((n,r)=>{let s=`item${r}`;return n.mode==="number"?`${s}: pullRequest(number: ${Number(n.selector)}) { ...PrFields }`:`${s}: pullRequests(headRefName: ${JSON.stringify(n.selector)}, states: OPEN, first: 1, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { ...PrFields } }`}).join(`
@@ -108,58 +108,58 @@ fragment PrFields on PullRequest {
108
108
  }
109
109
  }
110
110
  }
111
- `}function Sl(e){if(!e||typeof e!="object")return null;let t="nodes"in e?e.nodes?.[0]??null:e;if(!t||typeof t!="object")return null;let n=t,r=n.statusCheckRollup?.contexts?.nodes??n.commits?.nodes?.[0]?.commit?.statusCheckRollup?.contexts?.nodes??[];return{number:n.number,url:n.url,baseRefName:n.baseRefName,headRefName:n.headRefName,headRefOid:n.headRefOid??null,state:n.state,isDraft:n.isDraft??!1,title:n.title??null,createdAt:n.createdAt??null,updatedAt:n.updatedAt??null,mergedAt:n.mergedAt??null,mergeable:n.mergeable,mergeStateStatus:n.mergeStateStatus,reviewDecision:n.reviewDecision??null,statusCheckRollup:r,comments:n.comments?.nodes??[]}}async function Gn(e,t,n,r){let s=Cl(n,r),o=Vs(t,s),i=Pl(o.prs),c={...o,status:i};await Xs(e,c);let l=await _(e,t.id),d=l.status==="closed"?l.status:i,f=Vs({...l,status:d},s);return await E(e,f),f}async function Un(e,t,n,r){let s=await _(e,t.id),o=(s.repoTargets??t.repoTargets??[]).map(c=>c.repoId===n?{...c,pullRequest:r}:c),i={...s,repoTargets:o};return await E(e,i),i}function Cl(e,t){let n=e.isDraft??!1,r=xl(e.state,n);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:r,draft:n,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:eo(e.reviewDecision??null),requiredChecks:Zs(e.statusCheckRollup),comments:to(e.comments),createdAt:e.createdAt??t?.createdAt??null,updatedAt:e.updatedAt??t?.updatedAt??null,mergedAt:e.mergedAt??t?.mergedAt??null,lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function qn(e){return{provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:vl(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:eo(e.reviewDecision??null),requiredChecks:Zs(e.statusCheckRollup),comments:to(e.comments),lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function xl(e,t){return t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function vl(e){return e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function Zs(e){let t=e.map(r=>El(r)).filter(r=>r!==null),n=new Map;for(let r of t){let s=n.get(r.name);(!s||Al(s,r))&&n.set(r.name,r)}return[...n.values()].map(r=>({name:r.name,status:r.status,conclusion:r.conclusion}))}function El(e){if(typeof e!="object"||e===null)return null;let t=e,n=t.name??t.context,r=t.state??t.status??t.conclusion;return n?{name:n,status:no(r??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:$l(t)}:null}function Al(e,t){return e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Kt(e)&&!Kt(t)?!0:!Kt(e)&&Kt(t)?!1:Hs(t.status)>=Hs(e.status)}function Kt(e){return e.conclusion?.toUpperCase()==="CANCELLED"}function Hs(e){switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}}function $l(e){let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let n=new Date(t).getTime();return Number.isFinite(n)?n:null}function eo(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function to(e){let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(Dl).filter(n=>n!==null).slice(-4):[]}function Dl(e){if(typeof e!="object"||e===null)return null;let t=e,n=Ml(t.bodyText??t.body??"");return n?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:n,createdAt:t.createdAt??null,url:t.url??null}:null}function Ml(e){return e.replace(/\s+/g," ").trim()}function no(e,t){let n=e?.toUpperCase()??null,r=t?.toUpperCase()??null;return r==="SKIPPED"||n==="SKIPPED"?"skipped":n==="SUCCESS"||r==="SUCCESS"||r==="NEUTRAL"?"success":n==="PENDING"||n==="EXPECTED"||n==="IN_PROGRESS"||n==="QUEUED"||n==="REQUESTED"||n==="WAITING"?"pending":n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"||r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"?"failed":n==="COMPLETED"&&r===null?"unknown":n==="COMPLETED"&&r!==null?no(r,r):"unknown"}async function M(e,t){try{return await _(e,t)}catch(n){throw Wl(n)?new Error(`Craig task "${t}" was not found.`):n}}async function le(e){if(!await Hn(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)}function zn(e,t){return t.artifacts.logPath?ro.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:ro.join(e.workspaceRoot,t.artifacts.logPath):null}async function so(e,t){let n=await Hn(t.worktreePath),r=zn(e,t),s=r?await Hn(r):!1;return{worktreeExists:n,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Ol(t),lastCommitSummary:Fl(t),prSummary:jl(t),cleanupSummary:Nl(t)}}async function Hn(e){try{return await Ll(e),!0}catch{return!1}}function Ol(e){let t=e.checks.commands.length,n=t===1?"command":"commands",r=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${n})${r}`}function Fl(e){return e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed"}function jl(e){if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(l=>l.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),i=s.reduce((l,d)=>{let f=d.pullRequest.status??"unknown";return l[f]=(l[f]??0)+1,l},{}),c=Object.entries(i).map(([l,d])=>`${d} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${c})
111
+ `}function Zl(e){if(!e||typeof e!="object")return null;let t="nodes"in e?e.nodes?.[0]??null:e;if(!t||typeof t!="object")return null;let n=t,r=n.statusCheckRollup?.contexts?.nodes??n.commits?.nodes?.[0]?.commit?.statusCheckRollup?.contexts?.nodes??[];return{number:n.number,url:n.url,baseRefName:n.baseRefName,headRefName:n.headRefName,headRefOid:n.headRefOid??null,state:n.state,isDraft:n.isDraft??!1,title:n.title??null,createdAt:n.createdAt??null,updatedAt:n.updatedAt??null,mergedAt:n.mergedAt??null,mergeable:n.mergeable,mergeStateStatus:n.mergeStateStatus,reviewDecision:n.reviewDecision??null,statusCheckRollup:r,comments:n.comments?.nodes??[]}}async function rr(e,t,n,r){let s=ed(n,r),o=Ro(t,s),i=Jl(o.prs),c={...o,status:i};await Co(e,c);let l=await U(e,t.id),d=l.status==="closed"?l.status:i,f=Ro({...l,status:d},s);return await A(e,f),f}async function Zn(e,t,n,r){let s=await U(e,t.id),o=(s.repoTargets??t.repoTargets??[]).map(c=>c.repoId===n?{...c,pullRequest:r}:c),i={...s,repoTargets:o};return await A(e,i),i}function ed(e,t){let n=e.isDraft??!1,r=td(e.state,n);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:r,draft:n,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:vo(e.reviewDecision??null),requiredChecks:xo(e.statusCheckRollup),comments:Eo(e.comments),createdAt:e.createdAt??t?.createdAt??null,updatedAt:e.updatedAt??t?.updatedAt??null,mergedAt:e.mergedAt??t?.mergedAt??null,lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function er(e){return{provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:nd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:vo(e.reviewDecision??null),requiredChecks:xo(e.statusCheckRollup),comments:Eo(e.comments),lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function td(e,t){return t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function nd(e){return e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function xo(e){let t=e.map(r=>rd(r)).filter(r=>r!==null),n=new Map;for(let r of t){let s=n.get(r.name);(!s||sd(s,r))&&n.set(r.name,r)}return[...n.values()].map(r=>({name:r.name,status:r.status,conclusion:r.conclusion}))}function rd(e){if(typeof e!="object"||e===null)return null;let t=e,n=t.name??t.context,r=t.state??t.status??t.conclusion;return n?{name:n,status:Ao(r??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:od(t)}:null}function sd(e,t){return e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Vt(e)&&!Vt(t)?!0:!Vt(e)&&Vt(t)?!1:yo(t.status)>=yo(e.status)}function Vt(e){return e.conclusion?.toUpperCase()==="CANCELLED"}function yo(e){switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}}function od(e){let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let n=new Date(t).getTime();return Number.isFinite(n)?n:null}function vo(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Eo(e){let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(id).filter(n=>n!==null).slice(-4):[]}function id(e){if(typeof e!="object"||e===null)return null;let t=e,n=ad(t.bodyText??t.body??"");return n?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:n,createdAt:t.createdAt??null,url:t.url??null}:null}function ad(e){return e.replace(/\s+/g," ").trim()}function Ao(e,t){let n=e?.toUpperCase()??null,r=t?.toUpperCase()??null;return r==="SKIPPED"||n==="SKIPPED"?"skipped":n==="SUCCESS"||r==="SUCCESS"||r==="NEUTRAL"?"success":n==="PENDING"||n==="EXPECTED"||n==="IN_PROGRESS"||n==="QUEUED"||n==="REQUESTED"||n==="WAITING"?"pending":n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"||r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"?"failed":n==="COMPLETED"&&r===null?"unknown":n==="COMPLETED"&&r!==null?Ao(r,r):"unknown"}async function O(e,t){try{return await U(e,t)}catch(n){throw pd(n)?new Error(`Craig task "${t}" was not found.`):n}}async function le(e){if(!await sr(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)}function or(e,t){return t.artifacts.logPath?$o.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:$o.join(e.workspaceRoot,t.artifacts.logPath):null}async function Do(e,t){let n=await sr(t.worktreePath),r=or(e,t),s=r?await sr(r):!1;return{worktreeExists:n,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:ld(t),lastCommitSummary:dd(t),prSummary:ud(t),cleanupSummary:fd(t)}}async function sr(e){try{return await cd(e),!0}catch{return!1}}function ld(e){let t=e.checks.commands.length,n=t===1?"command":"commands",r=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${n})${r}`}function dd(e){return e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed"}function ud(e){if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(l=>l.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),i=s.reduce((l,d)=>{let f=d.pullRequest.status??"unknown";return l[f]=(l[f]??0)+1,l},{}),c=Object.entries(i).map(([l,d])=>`${d} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${c})
112
112
  ${o.join(`
113
- `)}`}let t=K(e);if(!t?.number||!t.url)return"not linked";let n=t.requiredChecks.length,r=n===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${n} ${r})`}function Nl(e){return e.status!=="merged"?"not merged":e.cleanup.warning?`warning: ${e.cleanup.warning}`:e.cleanup.preservedWorktree?"preserved worktree":e.cleanup.worktreeRemovedAt?`worktree removed at ${e.cleanup.worktreeRemovedAt}`:"cleanup pending"}function Wl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function oo(e,t){let n=await M(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session to attach.`);let[r,s]=await Promise.all([pe(e,n.repoId),tt(e,n.sessionId)]),o=await ut.attach(e,s,r.rootPath);return{kind:"attachTask",taskId:n.id,sessionId:o.id,disposition:"attached"}}ie();async function ao(e,t){let n=await M(e,t),r=K(n);return r?.number?(await wt(n.worktreePath),Gt(r)?(await Vn(e,n)).task:Kn(e,n)):n}async function zt(e,t){let n=await M(e,t),r=(n.repoTargets??[]).filter(i=>i.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let i of r){await wt(i.worktreePath);let c=i.pullRequest.number?await kt(e,n,i):await kt(e,n,i).catch(()=>"not_found");s[c==="not_found"?"notFound":c]++}let o=await _(e,n.id);return o.status!=="closed"&&(o.status=lo(o),await E(e,o)),s}async function co(e,t){let n=new Map,r=new Map;for(let s of t){let o=Yn(n,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(f=>f.status==="ready")){let f={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head"};await io(r,f).catch(async()=>{try{let h=d.pullRequest.number?await kt(e,s,d):await kt(e,s,d).catch(()=>"not_found");Ht(o,h,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=K(s),c=i?.number&&!Gt(i),l={id:s.id,task:s,worktreePath:s.worktreePath,selector:c?String(i.number):s.branch,mode:c?"number":"head"};await io(r,l).catch(async()=>{try{let{disposition:d,task:f}=await Jn(e,s.id),h=K(f);Ht(o,d,h?.number??null,h?.url??null)}catch{}})}for(let s of r.values())try{await wt(s.worktreePath);let o=await Ys(s.worktreePath,s.repository,s.items),i=new Map(o.map(c=>[c.id,c]));for(let c of s.items){let l=Yn(n,c.task),d=i.get(c.id);if(!d?.found||!d.view){Ht(l,"not_found",null,null);continue}c.targetRepoId?await Qs(e,c.task,c.targetRepoId,d.view):await Js(e,c.task,d.view),Ht(l,c.mode==="number"?"synced":"discovered",d.view.number,d.view.url)}}catch{}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await _(e,s.id);o.status!=="closed"&&(o.status=lo(o),await E(e,o))}return t.map(s=>Yn(n,s))}async function Jn(e,t){let n=await M(e,t);await le(n),await wt(n.worktreePath);let r=K(n);if(r?.number&&!Gt(r))return{disposition:"synced",task:await Kn(e,n)};let s=await Vn(e,n);return{disposition:s.discovered?"discovered":"not_found",task:s.task}}function lo(e){let t=(e.repoTargets??[]).filter(r=>r.status==="ready"),n=t.map(r=>r.pullRequest).filter(r=>!!r.number);return n.length===0?e.status:n.every(r=>r.status==="merged")?"merged":n.length===t.length&&n.every(_l)?"merge_ready":n.some(r=>r.status==="open")?"pr_open":"checked"}async function io(e,t){let n=await zs(t.worktreePath);if(!n)throw new Error("GitHub repository remote could not be parsed.");let r=`${n.owner}/${n.name}`,s=e.get(r);if(s){s.items.push(t);return}e.set(r,{worktreePath:t.worktreePath,repository:n,items:[t]})}function Yn(e,t){let n=e.get(t.id);if(n)return n;let r={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!K(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,r),r}function Ht(e,t,n,r){if(t==="synced"){e.synced+=1;return}if(t==="discovered"){e.discovered+=1,e.firstDiscoveredPrNumber??=n,e.firstDiscoveredPrUrl??=r;return}e.notFound+=1}function _l(e){return e.mergeable&&e.reviewDecision!=="REVIEW_REQUIRED"&&e.reviewDecision!=="CHANGES_REQUESTED"&&e.mergeStateStatus!=="REVIEW_REQUIRED"&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}async function Qn(e,t){let n=await M(e,t);try{n.type==="project"&&n.repoTargets?.length?(await zt(e,t),n=await M(e,t)):n.prs.some(o=>o.number)&&(n=await ao(e,t))}catch{}let r=await so(e,n),s=n.sessionId?await tt(e,n.sessionId).catch(()=>null):null;return{kind:"showTask",task:n,inspection:r,session:s}}import{access as Bl}from"node:fs/promises";async function Xn(e,t){let n=await M(e,t),r=zn(e,n);if(!r)throw new Error(`Task ${n.id} does not have a Craig-managed log path.`);try{await Bl(r)}catch{throw new Error(`Task ${n.id} log file does not exist yet at ${r}.`)}return{kind:"streamTaskLogs",taskId:n.id,logPath:r}}ce();async function Zn(e,t){let n=await M(e,t);if(await le(n),(await x("git",["status","--short"],{cwd:n.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:n.id,diffText:"",isEmpty:!0};let s=await Ul(n.worktreePath);return{kind:"showTaskDiff",taskId:n.id,diffText:s,isEmpty:!1}}async function Ul(e){let t=[],n=await x("git",["diff","--stat","--patch","HEAD"],{cwd:e});n.stdout.trim().length>0&&t.push(n.stdout.trimEnd());let r=await ql(e);for(let s of r){let o=await D("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
113
+ `)}`}let t=G(e);if(!t?.number||!t.url)return"not linked";let n=t.requiredChecks.length,r=n===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${n} ${r})`}function fd(e){return e.status!=="merged"?"not merged":e.cleanup.warning?`warning: ${e.cleanup.warning}`:e.cleanup.preservedWorktree?"preserved worktree":e.cleanup.worktreeRemovedAt?`worktree removed at ${e.cleanup.worktreeRemovedAt}`:"cleanup pending"}function pd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function Mo(e,t){let n=await O(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session to attach.`);let[r,s]=await Promise.all([fe(e,n.repoId),Qe(e,n.sessionId)]),o=await at.attach(e,s,r.rootPath);return{kind:"attachTask",taskId:n.id,sessionId:o.id,disposition:"attached"}}ie();async function Oo(e,t){let n=await O(e,t),r=G(n);return r?.number?(await pt(n.worktreePath),Ht(r)?(await nr(e,n)).task:tr(e,n)):n}async function Yt(e,t){let n=await O(e,t),r=(n.repoTargets??[]).filter(i=>i.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let i of r){await pt(i.worktreePath);let c=i.pullRequest.number?await mt(e,n,i):await mt(e,n,i).catch(()=>"not_found");s[c==="not_found"?"notFound":c]++}let o=await U(e,n.id);return o.status!=="closed"&&(o.status=jo(o),await A(e,o)),s}async function Fo(e,t){let n=new Map,r=new Map;for(let s of t){let o=ir(n,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(f=>f.status==="ready")){let f={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head"};await Lo(r,f).catch(async()=>{try{let h=d.pullRequest.number?await mt(e,s,d):await mt(e,s,d).catch(()=>"not_found");zt(o,h,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=G(s),c=i?.number&&!Ht(i),l={id:s.id,task:s,worktreePath:s.worktreePath,selector:c?String(i.number):s.branch,mode:c?"number":"head"};await Lo(r,l).catch(async()=>{try{let{disposition:d,task:f}=await ar(e,s.id),h=G(f);zt(o,d,h?.number??null,h?.url??null)}catch{}})}for(let s of r.values())try{await pt(s.worktreePath);let o=await bo(s.worktreePath,s.repository,s.items),i=new Map(o.map(c=>[c.id,c]));for(let c of s.items){let l=ir(n,c.task),d=i.get(c.id);if(!d?.found||!d.view){zt(l,"not_found",null,null);continue}c.targetRepoId?await So(e,c.task,c.targetRepoId,d.view):await Io(e,c.task,d.view),zt(l,c.mode==="number"?"synced":"discovered",d.view.number,d.view.url)}}catch{}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await U(e,s.id);o.status!=="closed"&&(o.status=jo(o),await A(e,o))}return t.map(s=>ir(n,s))}async function ar(e,t){let n=await O(e,t);await le(n),await pt(n.worktreePath);let r=G(n);if(r?.number&&!Ht(r))return{disposition:"synced",task:await tr(e,n)};let s=await nr(e,n);return{disposition:s.discovered?"discovered":"not_found",task:s.task}}function jo(e){let t=(e.repoTargets??[]).filter(r=>r.status==="ready"),n=t.map(r=>r.pullRequest).filter(r=>!!r.number);return n.length===0?e.status:n.every(r=>r.status==="merged")?"merged":n.length===t.length&&n.every(md)?"merge_ready":n.some(r=>r.status==="open")?"pr_open":"checked"}async function Lo(e,t){let n=await Po(t.worktreePath);if(!n)throw new Error("GitHub repository remote could not be parsed.");let r=`${n.owner}/${n.name}`,s=e.get(r);if(s){s.items.push(t);return}e.set(r,{worktreePath:t.worktreePath,repository:n,items:[t]})}function ir(e,t){let n=e.get(t.id);if(n)return n;let r={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!G(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,r),r}function zt(e,t,n,r){if(t==="synced"){e.synced+=1;return}if(t==="discovered"){e.discovered+=1,e.firstDiscoveredPrNumber??=n,e.firstDiscoveredPrUrl??=r;return}e.notFound+=1}function md(e){return e.mergeable&&e.reviewDecision!=="REVIEW_REQUIRED"&&e.reviewDecision!=="CHANGES_REQUESTED"&&e.mergeStateStatus!=="REVIEW_REQUIRED"&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}async function cr(e,t){let n=await O(e,t);try{n.type==="project"&&n.repoTargets?.length?(await Yt(e,t),n=await O(e,t)):n.prs.some(o=>o.number)&&(n=await Oo(e,t))}catch{}let r=await Do(e,n),s=n.sessionId?await Qe(e,n.sessionId).catch(()=>null):null;return{kind:"showTask",task:n,inspection:r,session:s}}import{access as gd}from"node:fs/promises";async function lr(e,t){let n=await O(e,t),r=or(e,n);if(!r)throw new Error(`Task ${n.id} does not have a Craig-managed log path.`);try{await gd(r)}catch{throw new Error(`Task ${n.id} log file does not exist yet at ${r}.`)}return{kind:"streamTaskLogs",taskId:n.id,logPath:r}}ce();async function dr(e,t){let n=await O(e,t);if(await le(n),(await v("git",["status","--short"],{cwd:n.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:n.id,diffText:"",isEmpty:!0};let s=await hd(n.worktreePath);return{kind:"showTaskDiff",taskId:n.id,diffText:s,isEmpty:!1}}async function hd(e){let t=[],n=await v("git",["diff","--stat","--patch","HEAD"],{cwd:e});n.stdout.trim().length>0&&t.push(n.stdout.trimEnd());let r=await wd(e);for(let s of r){let o=await L("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
114
114
 
115
- `)}async function ql(e){return(await x("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
- `).map(n=>n.trim()).filter(n=>n.length>0)}async function er(e,t){let n=await M(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session.`);let r=await tt(e,n.sessionId).catch(s=>{throw Kl(s)?new Error(`Task ${n.id} does not have a Craig session.`):s});if(!r.paneId)throw new Error(`Task ${n.id} does not have a tmux target.`);return await Ot(e.repoRoot,r.paneId,r.windowTarget,r.sessionName),{kind:"focusTask",taskId:n.id,tmuxTarget:r.paneId}}function Kl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{spawn as Vl}from"node:child_process";async function tr(e,t){let n=await M(e,t);await le(n);let s=(await Te(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!1,command:null};let o=[...s,n.worktreePath];return await Gl(o,e.repoRoot),{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!0,command:o}}async function Gl(e,t){await new Promise((n,r)=>{let[s,...o]=e,i=Vl(s,o,{cwd:t,stdio:"inherit"});i.on("error",r),i.on("exit",c=>{if(c===0){n();return}r(new Error(`${e.join(" ")} failed with exit code ${c??"unknown"}.`))})})}ye();import{mkdir as Hl}from"node:fs/promises";import zl from"node:path";ie();ce();async function nr(e,t){let n=await M(e,t);if(await le(n),n.status==="draft"||n.status==="merged")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);if(n.status==="running"&&await Wt(n.worktreePath)&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);let s=(await Te(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);n.checks.status="running",n.checks.commands=[...s],n.checks.results=[],await E(e,n);let o=[];for(let i of s){let c=new Date().toISOString(),l=await D("sh",["-lc",i],{cwd:n.worktreePath}),d=new Date().toISOString(),f=l.exitCode??1;if(o.push({command:i,startedAt:c,finishedAt:d,exitCode:f}),f!==0)return n.checks.results=o,n.checks.status="failed",n.checks.lastRunAt=d,n.status="review",n.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await uo(e,n),await E(e,n),{kind:"runChecks",taskId:n.id,status:"failed",commands:s}}return n.checks.results=o,n.checks.status="passed",n.checks.lastRunAt=new Date().toISOString(),n.status="checked",n.lastFailureReason=null,await uo(e,n),await E(e,n),{kind:"runChecks",taskId:n.id,status:"passed",commands:s}}async function uo(e,t){let n=qt(e,t.artifacts.checkSummaryPath);n&&(await Hl(zl.dirname(n),{recursive:!0}),await W(n,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))}ie();async function rr(e,t){let n=await M(e,t);await le(n);let r=await Wt(n.worktreePath);if(n.status==="running"&&r&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot commit from status "${n.status}".`);if(!r)throw new Error(`Task ${n.id} has no uncommitted diff to commit.`);let s=n.prompt.value.trim();await $s(n.worktreePath),await Ds(n.worktreePath,s);let o=await Ms(n.worktreePath);return n.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},n.lastFailureReason=null,await E(e,n),{kind:"commitTask",taskId:n.id,status:n.status,commitSha:o.sha,message:o.message}}qe();He();pt();rt();ht();Pt();ce();import nd from"node:path";import{stat as rd}from"node:fs/promises";async function yo(e,t){let n=nd.resolve(e.workspaceRoot,t);if(!(await rd(n).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${n}`);let s=await Promise.resolve().then(()=>(Pt(),To)).then(({addWorkspace:i})=>i(e,t)),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${n}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}}async function Po(e){return{kind:"listRepos",repos:await Ge(e)}}async function bo(e,t){let n=await pe(e,t),s=(await me(e)).filter(d=>d.primaryRepoId===t),o=s.filter(d=>d.status==="active"),i=await be(e,{repoId:t});if(o.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(i.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(s.map(d=>Yt(e,d.id))),await xs(e,t);let c=await oe(e);await Ue(e,{...c,repoIds:c.repoIds.filter(d=>d!==t)});let l=await fe({uiStateFile:e.uiStateFile});return l?.selectedRepoId===t&&await ae({uiStateFile:e.uiStateFile},{...l,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}}He();ie();async function Io(e,t,n){let[r,s]=await Promise.all([M(e,t),pe(e,n)]);if(r.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${r.id}.`);let o=r.linkedRepoIds.includes(s.id)?r.linkedRepoIds:[...r.linkedRepoIds,s.id];return await E(e,{...r,linkedRepoIds:o}),{kind:"addTaskLink",taskId:r.id,repoId:s.id,linkedRepoIds:o}}async function So(e,t){let n=await M(e,t),r=await Promise.all(n.linkedRepoIds.map(s=>pe(e,s)));return{kind:"listTaskLinks",taskId:n.id,repos:r}}Pt();async function Co(e,t){switch(e.kind){case"addWorkspace":return Rt(t.paths,e.path);case"addRepo":return yo(t.paths,e.path);case"listRepos":return Po(t.paths);case"removeRepo":return bo(t.paths,e.repoId);case"listWorkspaces":return sr(t.paths,{archived:e.archived});case"archiveWorkspace":return Tt(t.paths,e.workspaceId);case"restoreWorkspace":return or(t.paths,e.workspaceId);case"removeWorkspace":return yt(t.paths,e.workspaceId);case"createTask":return qs(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?be(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):be(t.paths);case"attachTask":return oo(t.paths,e.taskId);case"addTaskLink":return Io(t.paths,e.taskId,e.repoId);case"listTaskLinks":return So(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return Qn(t.paths,e.taskId);case"showSelectedTask":return Qn(t.paths,ze(t,"show"));case"streamTaskLogs":return Xn(t.paths,e.taskId);case"streamSelectedTaskLogs":return Xn(t.paths,ze(t,"logs"));case"showTaskDiff":return Zn(t.paths,e.taskId);case"showSelectedTaskDiff":return Zn(t.paths,ze(t,"diff"));case"focusTask":return er(t.paths,e.taskId);case"focusSelectedTask":return er(t.paths,ze(t,"focus"));case"openTask":return tr(t.paths,e.taskId);case"openSelectedTask":return tr(t.paths,ze(t,"open"));case"runChecks":return nr(t.paths,e.taskId);case"runSelectedTaskChecks":return nr(t.paths,ze(t,"check"));case"commitTask":return rr(t.paths,e.taskId);case"commitSelectedTask":return rr(t.paths,ze(t,"commit"));case"help":return{kind:"help",text:Y()};case"exit":return{kind:"exit"};default:return sd(e)}}function sd(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function ze(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>'.`)}ye();import{mkdir as Ie,readFile as od}from"node:fs/promises";import J from"node:path";function Ce(e){let t=J.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:J.join(t,"index.json"),reposDir:J.join(t,"repos"),workspacesDir:J.join(t,"workspaces"),sessionsDir:J.join(t,"sessions"),runtimeDir:J.join(t,"runtime"),uiStateFile:J.join(t,"runtime","ui-state.json"),tasksDir:J.join(t,"tasks"),jobsDir:J.join(t,"jobs"),logsDir:J.join(t,"logs"),errorLogFile:J.join(t,"logs","errors.log"),artifactsDir:J.join(t,"artifacts"),worktreesDir:J.join(t,"worktrees"),configFile:J.join(t,"config.json")}}qe();async function ot(e){let t=Ce(e);await Ie(t.craigDir,{recursive:!0}),await Promise.all([Ie(t.reposDir,{recursive:!0}),Ie(t.workspacesDir,{recursive:!0}),Ie(t.sessionsDir,{recursive:!0}),Ie(t.runtimeDir,{recursive:!0}),Ie(t.tasksDir,{recursive:!0}),Ie(t.jobsDir,{recursive:!0}),Ie(t.logsDir,{recursive:!0}),Ie(t.artifactsDir,{recursive:!0}),Ie(t.worktreesDir,{recursive:!0})]);try{let s=await od(t.indexFile,"utf8"),o=JSON.parse(s);return Mn(o,e,t.indexFile)}catch(s){if(!id(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let n=new Date().toISOString(),r={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:n,updatedAt:n};return await W(t.indexFile,r),r}function id(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}function xo(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
115
+ `)}async function wd(e){return(await v("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
+ `).map(n=>n.trim()).filter(n=>n.length>0)}async function ur(e,t){let n=await O(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session.`);let r=await Qe(e,n.sessionId).catch(s=>{throw kd(s)?new Error(`Task ${n.id} does not have a Craig session.`):s});if(!r.paneId)throw new Error(`Task ${n.id} does not have a tmux target.`);return await Ft(e.repoRoot,r.paneId,r.windowTarget,r.sessionName),{kind:"focusTask",taskId:n.id,tmuxTarget:r.paneId}}function kd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}ee();import{spawn as Rd}from"node:child_process";async function fr(e,t){let n=await O(e,t);await le(n);let s=(await b.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!1,command:null};let o=[...s,n.worktreePath];return await Td(o,e.repoRoot),{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!0,command:o}}async function Td(e,t){await new Promise((n,r)=>{let[s,...o]=e,i=Rd(s,o,{cwd:t,stdio:"inherit"});i.on("error",r),i.on("exit",c=>{if(c===0){n();return}r(new Error(`${e.join(" ")} failed with exit code ${c??"unknown"}.`))})})}ke();ee();ie();import{mkdir as yd}from"node:fs/promises";import Pd from"node:path";ce();async function pr(e,t){let n=await O(e,t);if(await le(n),n.status==="draft"||n.status==="merged")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);if(n.status==="running"&&await _t(n.worktreePath)&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);let s=(await b.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);n.checks.status="running",n.checks.commands=[...s],n.checks.results=[],await A(e,n);let o=[];for(let i of s){let c=new Date().toISOString(),l=await L("sh",["-lc",i],{cwd:n.worktreePath}),d=new Date().toISOString(),f=l.exitCode??1;if(o.push({command:i,startedAt:c,finishedAt:d,exitCode:f}),f!==0)return n.checks.results=o,n.checks.status="failed",n.checks.lastRunAt=d,n.status="review",n.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await No(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"failed",commands:s}}return n.checks.results=o,n.checks.status="passed",n.checks.lastRunAt=new Date().toISOString(),n.status="checked",n.lastFailureReason=null,await No(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"passed",commands:s}}async function No(e,t){let n=Kt(e,t.artifacts.checkSummaryPath);n&&(await yd(Pd.dirname(n),{recursive:!0}),await B(n,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))}ie();async function mr(e,t){let n=await O(e,t);await le(n);let r=await _t(n.worktreePath);if(n.status==="running"&&r&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot commit from status "${n.status}".`);if(!r)throw new Error(`Task ${n.id} has no uncommitted diff to commit.`);let s=n.prompt.value.trim();await so(n.worktreePath),await oo(n.worktreePath,s);let o=await io(n.worktreePath);return n.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},n.lastFailureReason=null,await A(e,n),{kind:"commitTask",taskId:n.id,status:n.status,commitSha:o.sha,message:o.message}}We();qe();lt();Ze();ft();kt();ce();import Ad from"node:path";import{stat as $d}from"node:fs/promises";async function zo(e,t){let n=Ad.resolve(e.workspaceRoot,t);if(!(await $d(n).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${n}`);let s=await Promise.resolve().then(()=>(kt(),Ho)).then(({addWorkspace:i})=>i(e,t)),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${n}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}}async function Yo(e){return{kind:"listRepos",repos:await Ue(e)}}async function Jo(e,t){let n=await fe(e,t),s=(await pe(e)).filter(d=>d.primaryRepoId===t),o=s.filter(d=>d.status==="active"),i=await Te(e,{repoId:t});if(o.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(i.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(s.map(d=>Jt(e,d.id))),await eo(e,t);let c=await oe(e);await Ne(e,{...c,repoIds:c.repoIds.filter(d=>d!==t)});let l=await ue({uiStateFile:e.uiStateFile});return l?.selectedRepoId===t&&await ae({uiStateFile:e.uiStateFile},{...l,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}}qe();ie();async function Qo(e,t,n){let[r,s]=await Promise.all([O(e,t),fe(e,n)]);if(r.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${r.id}.`);let o=r.linkedRepoIds.includes(s.id)?r.linkedRepoIds:[...r.linkedRepoIds,s.id];return await A(e,{...r,linkedRepoIds:o}),{kind:"addTaskLink",taskId:r.id,repoId:s.id,linkedRepoIds:o}}async function Xo(e,t){let n=await O(e,t),r=await Promise.all(n.linkedRepoIds.map(s=>fe(e,s)));return{kind:"listTaskLinks",taskId:n.id,repos:r}}kt();async function Zo(e,t){switch(e.kind){case"addWorkspace":return gt(t.paths,e.path);case"addRepo":return zo(t.paths,e.path);case"listRepos":return Yo(t.paths);case"removeRepo":return Jo(t.paths,e.repoId);case"listWorkspaces":return gr(t.paths,{archived:e.archived});case"archiveWorkspace":return ht(t.paths,e.workspaceId);case"restoreWorkspace":return hr(t.paths,e.workspaceId);case"removeWorkspace":return wt(t.paths,e.workspaceId);case"createTask":return wo(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?Te(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):Te(t.paths);case"attachTask":return Mo(t.paths,e.taskId);case"addTaskLink":return Qo(t.paths,e.taskId,e.repoId);case"listTaskLinks":return Xo(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return cr(t.paths,e.taskId);case"showSelectedTask":return cr(t.paths,Ke(t,"show"));case"streamTaskLogs":return lr(t.paths,e.taskId);case"streamSelectedTaskLogs":return lr(t.paths,Ke(t,"logs"));case"showTaskDiff":return dr(t.paths,e.taskId);case"showSelectedTaskDiff":return dr(t.paths,Ke(t,"diff"));case"focusTask":return ur(t.paths,e.taskId);case"focusSelectedTask":return ur(t.paths,Ke(t,"focus"));case"openTask":return fr(t.paths,e.taskId);case"openSelectedTask":return fr(t.paths,Ke(t,"open"));case"runChecks":return pr(t.paths,e.taskId);case"runSelectedTaskChecks":return pr(t.paths,Ke(t,"check"));case"commitTask":return mr(t.paths,e.taskId);case"commitSelectedTask":return mr(t.paths,Ke(t,"commit"));case"help":return{kind:"help",text:J()};case"exit":return{kind:"exit"};default:return Dd(e)}}function Dd(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Ke(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>'.`)}ke();import{mkdir as ye,readFile as Md}from"node:fs/promises";import Q from"node:path";function be(e){let t=Q.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:Q.join(t,"index.json"),reposDir:Q.join(t,"repos"),workspacesDir:Q.join(t,"workspaces"),sessionsDir:Q.join(t,"sessions"),runtimeDir:Q.join(t,"runtime"),uiStateFile:Q.join(t,"runtime","ui-state.json"),tasksDir:Q.join(t,"tasks"),jobsDir:Q.join(t,"jobs"),logsDir:Q.join(t,"logs"),errorLogFile:Q.join(t,"logs","errors.log"),artifactsDir:Q.join(t,"artifacts"),worktreesDir:Q.join(t,"worktrees"),configFile:Q.join(t,"config.json")}}We();async function tt(e){let t=be(e);await ye(t.craigDir,{recursive:!0}),await Promise.all([ye(t.reposDir,{recursive:!0}),ye(t.workspacesDir,{recursive:!0}),ye(t.sessionsDir,{recursive:!0}),ye(t.runtimeDir,{recursive:!0}),ye(t.tasksDir,{recursive:!0}),ye(t.jobsDir,{recursive:!0}),ye(t.logsDir,{recursive:!0}),ye(t.artifactsDir,{recursive:!0}),ye(t.worktreesDir,{recursive:!0})]);try{let s=await Md(t.indexFile,"utf8"),o=JSON.parse(s);return Kn(o,e,t.indexFile)}catch(s){if(!Ld(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let n=new Date().toISOString(),r={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:n,updatedAt:n};return await B(t.indexFile,r),r}function Ld(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}function ei(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
117
117
  `);case"createRepo":return[`${e.created?"Registered":"Already registered"} repo ${e.repo.id}`,`Path: ${e.repo.rootPath}`,`Branch: ${e.repo.defaultBranch}`,`Workspace: ${e.workspaceId}`].join(`
118
118
  `);case"listRepos":return e.repos.length===0?"No repos registered yet. Use 'craig repo add <path>'.":["ID NAME BRANCH PATH",...e.repos.map(t=>`${t.id} ${t.name} ${t.defaultBranch} ${t.rootPath}`)].join(`
119
119
  `);case"removeRepo":return`Removed repo ${e.repoId} (${e.rootPath})`;case"listWorkspaces":return e.workspaces.length===0?e.archivedOnly?"No archived workspaces.":"No active workspaces yet. Register one with 'craig workspace add <path>'.":["ID KIND STATUS REPOS PATH",...e.workspaces.map(t=>`${t.id} ${t.kind??"repo"} ${t.status} ${(t.discoveredRepoIds??[t.primaryRepoId]).join(",")} ${t.rootPath??""}`)].join(`
120
120
  `);case"archiveWorkspace":return`Archived workspace ${e.workspaceId} on branch ${e.branch}`;case"restoreWorkspace":return`Restored workspace ${e.workspaceId} on branch ${e.branch}`;case"removeWorkspace":return`Removed workspace ${e.workspaceId} (${e.rootPath})`;case"createTask":return[`Created task ${e.taskId}`,`Repo: ${e.repoId}`,`Workspace: ${e.workspaceId}`,`Session: ${e.sessionId}`,`Status: ${e.status}`,`Branch: ${e.branch}`,`Worktree: ${e.worktreePath}`,`Runner: ${e.runner}`].join(`
121
121
  `);case"attachTask":return`Attached to task ${e.taskId} via session ${e.sessionId}`;case"addTaskLink":return`Linked repo ${e.repoId} to task ${e.taskId}: ${e.linkedRepoIds.join(", ")}`;case"listTaskLinks":return e.repos.length===0?`Task ${e.taskId} has no linked repos.`:["ID NAME BRANCH PATH",...e.repos.map(t=>`${t.id} ${t.name} ${t.defaultBranch} ${t.rootPath}`)].join(`
122
- `);case"help":return e.text;case"exit":return"";case"listTasks":return e.tasks.length===0?`No Craig tasks yet. Use 'task new --repo <repo-id> <prompt>' to create one.${e.missingTaskIds.length>0?` (${e.missingTaskIds.length} referenced task file(s) missing from .craig/tasks)`:""}`:["ID REPO STATUS CHECKS PR TITLE",...e.tasks.map(t=>`${t.id} ${t.repoId} ${t.status} ${ld(t)} ${dd(t)} ${t.title}`)].join(`
123
- `);case"showTask":return[`${e.task.id}: ${e.task.title}`,`Status: ${e.task.status}`,`Runner: ${e.task.runner}`,`Repo: ${e.task.repoId}`,`Workspace: ${e.task.workspaceId}`,`Branch: ${e.task.branch}`,`Worktree: ${e.task.worktreePath}`,`Session: ${e.task.sessionId??"<missing>"}`,`tmux: ${e.session?.paneId??"<missing>"}`,`Linked repos: ${e.task.linkedRepoIds.length>0?e.task.linkedRepoIds.join(", "):"none"}`,`Prompt: ${e.task.prompt.source} ${JSON.stringify(e.task.prompt.value)}`,`Runner command: ${e.inspection.runnerCommandText||"<none>"}`,`Runner state: ${e.task.runnerSession.lastKnownState}`,`Started: ${e.task.runnerSession.startedAt??"not started"}`,`Exited: ${e.task.runnerSession.exitedAt??"still running"}`,`Checks: ${e.inspection.checksSummary}`,`Last commit: ${e.inspection.lastCommitSummary}`,`PR: ${e.inspection.prSummary}`,`Cleanup: ${e.inspection.cleanupSummary}`,...ad(e)].join(`
122
+ `);case"help":return e.text;case"exit":return"";case"listTasks":return e.tasks.length===0?`No Craig tasks yet. Use 'task new --repo <repo-id> <prompt>' to create one.${e.missingTaskIds.length>0?` (${e.missingTaskIds.length} referenced task file(s) missing from .craig/tasks)`:""}`:["ID REPO STATUS CHECKS PR TITLE",...e.tasks.map(t=>`${t.id} ${t.repoId} ${t.status} ${jd(t)} ${Nd(t)} ${t.title}`)].join(`
123
+ `);case"showTask":return[`${e.task.id}: ${e.task.title}`,`Status: ${e.task.status}`,`Runner: ${e.task.runner}`,`Repo: ${e.task.repoId}`,`Workspace: ${e.task.workspaceId}`,`Branch: ${e.task.branch}`,`Worktree: ${e.task.worktreePath}`,`Session: ${e.task.sessionId??"<missing>"}`,`tmux: ${e.session?.paneId??"<missing>"}`,`Linked repos: ${e.task.linkedRepoIds.length>0?e.task.linkedRepoIds.join(", "):"none"}`,`Prompt: ${e.task.prompt.source} ${JSON.stringify(e.task.prompt.value)}`,`Runner command: ${e.inspection.runnerCommandText||"<none>"}`,`Runner state: ${e.task.runnerSession.lastKnownState}`,`Started: ${e.task.runnerSession.startedAt??"not started"}`,`Exited: ${e.task.runnerSession.exitedAt??"still running"}`,`Checks: ${e.inspection.checksSummary}`,`Last commit: ${e.inspection.lastCommitSummary}`,`PR: ${e.inspection.prSummary}`,`Cleanup: ${e.inspection.cleanupSummary}`,...Od(e)].join(`
124
124
  `);case"streamTaskLogs":return`Streaming logs for ${e.taskId} from ${e.logPath}`;case"showTaskDiff":return e.isEmpty?`Task ${e.taskId} has no uncommitted diff.`:e.diffText;case"focusTask":return`Focused task ${e.taskId} on ${e.tmuxTarget}`;case"openTask":return e.launched?`Opened task ${e.taskId} at ${e.worktreePath}`:e.worktreePath;case"runChecks":return`Checks ${e.status} for ${e.taskId}: ${e.commands.join(", ")}`;case"commitTask":return[`Committed task ${e.taskId}`,`Status: ${e.status}`,`Commit: ${e.commitSha}`,`Message: ${e.message}`].join(`
125
- `);default:return cd(e)}}function ad(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 cd(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function ld(e){return e.checks.status}function dd(e){if(e.type==="project"&&e.repoTargets?.length){let n=e.repoTargets.filter(s=>s.pullRequest.number);if(n.length===0)return"-";let r=n.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(r).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}He();pt();rt();import{createRequire as hp}from"node:module";import{readdir as wp,stat as kp}from"node:fs/promises";import ct from"node:path";ie();ht();import{appendFile as ud,mkdir as fd,readFile as pd}from"node:fs/promises";import md from"node:path";var gd=80;async function hd(e,t){await fd(md.dirname(e.errorLogFile),{recursive:!0}),await ud(e.errorLogFile,wd(t),"utf8")}async function ir(e,t){try{await hd(e,t)}catch{}}async function vo(e,t=gd){try{let r=(await pd(e.errorLogFile,"utf8")).trimEnd().split(`
126
- `).filter(s=>s.length>0);return{path:e.errorLogFile,lines:r.slice(Math.max(0,r.length-t)),empty:r.length===0}}catch(n){if(kd(n))return{path:e.errorLogFile,lines:[],empty:!0};throw n}}function wd(e){let n=[`[${new Date().toISOString()}] ${e.context}`,`message: ${e.message}`];return e.details&&e.details.trim().length>0&&(n.push("details:"),n.push(...e.details.trimEnd().split(`
125
+ `);default:return Fd(e)}}function Od(e){let t=[];return e.inspection.worktreeExists||e.task.status==="merged"&&!e.task.cleanup.preservedWorktree&&e.task.cleanup.worktreeRemovedAt||t.push(`Warning: worktree is missing at ${e.task.worktreePath}`),e.task.cleanup.warning&&!(e.task.status==="merged"&&!e.task.cleanup.worktreeRemovedAt)&&t.push(`Cleanup warning: ${e.task.cleanup.warning}`),e.task.artifacts.logPath&&!e.inspection.logExists&&t.push(`Warning: log file is missing at ${e.task.artifacts.logPath}`),e.inspection.recentFailureReason&&t.push(`Last failure: ${e.inspection.recentFailureReason}`),t}function Fd(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function jd(e){return e.checks.status}function Nd(e){if(e.type==="project"&&e.repoTargets?.length){let n=e.repoTargets.filter(s=>s.pullRequest.number);if(n.length===0)return"-";let r=n.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(r).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}qe();lt();Ze();ee();ie();import{createRequire as Up}from"node:module";import{readdir as qp,stat as Kp}from"node:fs/promises";import st from"node:path";ft();import{appendFile as Wd,mkdir as _d,readFile as Bd}from"node:fs/promises";import Ud from"node:path";var qd=80;async function Kd(e,t){await _d(Ud.dirname(e.errorLogFile),{recursive:!0}),await Wd(e.errorLogFile,Vd(t),"utf8")}async function wr(e,t){try{await Kd(e,t)}catch{}}async function ti(e,t=qd){try{let r=(await Bd(e.errorLogFile,"utf8")).trimEnd().split(`
126
+ `).filter(s=>s.length>0);return{path:e.errorLogFile,lines:r.slice(Math.max(0,r.length-t)),empty:r.length===0}}catch(n){if(Gd(n))return{path:e.errorLogFile,lines:[],empty:!0};throw n}}function Vd(e){let n=[`[${new Date().toISOString()}] ${e.context}`,`message: ${e.message}`];return e.details&&e.details.trim().length>0&&(n.push("details:"),n.push(...e.details.trimEnd().split(`
127
127
  `).map(r=>` ${r}`))),`${n.join(`
128
128
  `)}
129
129
 
130
- `}function kd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}Pt();ce();import{readFile as Rd,stat as Td}from"node:fs/promises";import ar from"node:path";var yd=200*1024,Pd=500*1024,Jt="100000";async function Ao(e,t,n){if(e.type==="project"&&e.repoTargets?.length)return bd(e,t,n);try{let r=Oe(n.selectedFilePath??null,t.filePaths),s=Oe(n.selectedDiffPath??null,t.diffPaths),o=s?await bt(e.worktreePath):null,[i,c]=await Promise.all([Xt(e.worktreePath,r),s?cr(e.worktreePath,s,t.diffRows,o):Promise.resolve(H("No diff selected","No local changes found.","empty"))]),l=s?{[s]:c}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:l,selectedFile:i,selectedDiff:c,error:null}}catch(r){let s=r instanceof Error?r.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function bd(e,t,n){let r=Oe(n.selectedFilePath??null,t.filePaths),s=Oe(n.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([Do(e,r),(async()=>{if(!s)return H("No diff selected","No local changes found.","empty");let l=Qt(e,s),d=l?await bt(l.target.worktreePath).catch(()=>null):null;return Mo(e,s,t.diffRows,d)})()]),c=s?{[s]:i}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:c,selectedFile:o,selectedDiff:i}}async function $o(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Id(e,t);try{await le(e);let n=await bt(e.worktreePath),[r,s]=await Promise.all([Lo(e.worktreePath),Oo(e.worktreePath,n)]),o=[...new Set(s.map(h=>h.path))],i=Oe(t.selectedFilePath??null,r),c=Oe(t.selectedDiffPath??null,o),[l,d]=await Promise.all([Xt(e.worktreePath,i),c?cr(e.worktreePath,c,s,n):Promise.resolve(H("No diff selected","No local changes found.","empty"))]),f=c?{[c]:d}:{};return{taskId:e.id,fileRows:No(r),filePaths:r,diffRows:s,diffPaths:o,diffContents:f,selectedFilePath:i,selectedDiffPath:c,selectedFile:l,selectedDiff:d,error:null}}catch(n){let r=n instanceof Error?n.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:H("Files unavailable",r,"error"),selectedDiff:H("Diff unavailable",r,"error"),error:r}}}async function Id(e,t){let n=(e.repoTargets??[]).filter(R=>R.status==="ready"),r=await Promise.all(n.map(async R=>{let k=await bt(R.worktreePath).catch(()=>null),[I,T]=await Promise.all([Lo(R.worktreePath).catch(()=>[]),Oo(R.worktreePath,k).catch(()=>[])]);return{target:R,baseRef:k,targetFiles:I,targetDiffRows:T}})),s=[],o=[];for(let{target:R,targetFiles:k,targetDiffRows:I}of r)s.push(...k.map(T=>`${R.repoId}/${T}`)),o.push(...I.map(T=>({...T,path:`${R.repoId}/${T.path}`})));let i=[...new Set(o.map(R=>R.path))].sort(),c=Oe(t.selectedFilePath??null,s),l=Oe(t.selectedDiffPath??null,i),[d,f]=await Promise.all([Do(e,c),(async()=>{if(!l)return H("No diff selected","No local changes found.","empty");let R=Qt(e,l),k=R?r.find(I=>I.target.repoId===R.target.repoId):null;return Mo(e,l,o,k?.baseRef??null)})()]),h=l?{[l]:f}:{};return{taskId:e.id,fileRows:No(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:h,selectedFilePath:c,selectedDiffPath:l,selectedFile:d,selectedDiff:f,error:null}}async function Do(e,t){let n=Qt(e,t);if(!n)return H("No file selected","No Git-visible files found.","empty");let r=await Xt(n.target.worktreePath,n.relativePath);return{...r,path:t,title:t??r.title}}async function Mo(e,t,n,r=null){let s=Qt(e,t);return s?{...await cr(s.target.worktreePath,s.relativePath,n.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),r),path:t,title:t}:H(t,"Repo target is unavailable.","error",t)}function Qt(e,t){if(!t)return null;let[n,...r]=t.split("/"),s=r.join("/"),o=(e.repoTargets??[]).find(i=>i.repoId===n&&i.status==="ready")??null;return!o||s.length===0?null:{target:o,relativePath:s}}async function Lo(e){let t=await x("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return Wo(t.stdout)}async function Oo(e,t){let[n,r,s,o]=await Promise.all([Sd(e,t),Eo(e,"staged"),Eo(e,"unstaged"),Cd(e)]);return[...n,...r,...s,...o]}async function Sd(e,t){if(!t)return[];let[n,r]=await Promise.all([x("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),x("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=Fo(n.stdout),o=jo(r.stdout);return s.map(i=>{let c=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:c.additions,deletions:c.deletions}}).sort((i,c)=>i.path.localeCompare(c.path))}async function Eo(e,t){let n=t==="staged"?["diff","--cached"]:["diff"],[r,s]=await Promise.all([x("git",[...n,"--name-status"],{cwd:e}),x("git",[...n,"--numstat"],{cwd:e})]),o=Fo(r.stdout),i=jo(s.stdout);return o.map(c=>{let l=i.get(c.path)??{additions:null,deletions:null};return{group:t,path:c.path,status:c.status,additions:l.additions,deletions:l.deletions}}).sort((c,l)=>c.path.localeCompare(l.path))}async function Cd(e){let t=await x("git",["ls-files","--others","--exclude-standard"],{cwd:e}),n=Wo(t.stdout);return await Promise.all(n.map(async s=>{let o=await Xt(e,s),i=o.status==="ready"?xd(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function Fo(e){return e.split(`
131
- `).map(t=>t.trim()).filter(t=>t.length>0).map(t=>{let[n="M",...r]=t.split(" ");return{status:n,path:r.at(-1)??""}}).filter(t=>t.path.length>0)}function jo(e){let t=new Map;for(let n of e.split(`
132
- `)){let r=n.trim();if(!r)continue;let[s="-",o="-",...i]=r.split(" "),c=i.join(" ");c&&t.set(c,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function bt(e){return(await D("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await D("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function Xt(e,t){if(!t)return H("No file selected","No Git-visible files found.","empty");let n=vd(e,t);try{let r=await Td(n);if(r.size>yd)return H(t,`File is ${r.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,r.size);let s=await Rd(n);return Ed(s)?H(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
133
- `),byteLength:s.byteLength}}catch(r){let s=r instanceof Error?r.message:"Unable to read file.";return H(t,s,"missing",t,null)}}async function cr(e,t,n,r=null){if(!t)return H("No diff selected","No local changes found.","empty");let s=[],o=n.filter(c=>c.path===t).map(c=>c.group);if(o.includes("branch")){let c=r??await bt(e);if(c){let l=await x("git",["diff","--stat","--patch",`--unified=${Jt}`,`${c}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
134
- ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let c=await x("git",["diff","--cached","--stat","--patch",`--unified=${Jt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`staged
135
- ${c.stdout.trimEnd()}`)}if(o.includes("unstaged")){let c=await x("git",["diff","--stat","--patch",`--unified=${Jt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`unstaged
136
- ${c.stdout.trimEnd()}`)}if(o.includes("untracked")){let c=await D("git",["diff","--no-index","--stat","--patch",`--unified=${Jt}`,"--","/dev/null",t],{cwd:e});c.stdout.trim().length>0&&s.push(`untracked
130
+ `}function Gd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}kt();ce();import{readFile as Hd,stat as zd}from"node:fs/promises";import kr from"node:path";var Yd=200*1024,Jd=500*1024,Qt="100000";async function ri(e,t,n){if(e.type==="project"&&e.repoTargets?.length)return Qd(e,t,n);try{let r=De(n.selectedFilePath??null,t.filePaths),s=De(n.selectedDiffPath??null,t.diffPaths),o=s?await Rt(e.worktreePath):null,[i,c]=await Promise.all([Zt(e.worktreePath,r),s?Rr(e.worktreePath,s,t.diffRows,o):Promise.resolve(Y("No diff selected","No local changes found.","empty"))]),l=s?{[s]:c}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:l,selectedFile:i,selectedDiff:c,error:null}}catch(r){let s=r instanceof Error?r.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function Qd(e,t,n){let r=De(n.selectedFilePath??null,t.filePaths),s=De(n.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([oi(e,r),(async()=>{if(!s)return Y("No diff selected","No local changes found.","empty");let l=Xt(e,s),d=l?await Rt(l.target.worktreePath).catch(()=>null):null;return ii(e,s,t.diffRows,d)})()]),c=s?{[s]:i}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:c,selectedFile:o,selectedDiff:i}}async function si(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Xd(e,t);try{await le(e);let n=await Rt(e.worktreePath),[r,s]=await Promise.all([ai(e.worktreePath),ci(e.worktreePath,n)]),o=[...new Set(s.map(h=>h.path))],i=De(t.selectedFilePath??null,r),c=De(t.selectedDiffPath??null,o),[l,d]=await Promise.all([Zt(e.worktreePath,i),c?Rr(e.worktreePath,c,s,n):Promise.resolve(Y("No diff selected","No local changes found.","empty"))]),f=c?{[c]:d}:{};return{taskId:e.id,fileRows:ui(r),filePaths:r,diffRows:s,diffPaths:o,diffContents:f,selectedFilePath:i,selectedDiffPath:c,selectedFile:l,selectedDiff:d,error:null}}catch(n){let r=n instanceof Error?n.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:Y("Files unavailable",r,"error"),selectedDiff:Y("Diff unavailable",r,"error"),error:r}}}async function Xd(e,t){let n=(e.repoTargets??[]).filter(R=>R.status==="ready"),r=await Promise.all(n.map(async R=>{let k=await Rt(R.worktreePath).catch(()=>null),[S,T]=await Promise.all([ai(R.worktreePath).catch(()=>[]),ci(R.worktreePath,k).catch(()=>[])]);return{target:R,baseRef:k,targetFiles:S,targetDiffRows:T}})),s=[],o=[];for(let{target:R,targetFiles:k,targetDiffRows:S}of r)s.push(...k.map(T=>`${R.repoId}/${T}`)),o.push(...S.map(T=>({...T,path:`${R.repoId}/${T.path}`})));let i=[...new Set(o.map(R=>R.path))].sort(),c=De(t.selectedFilePath??null,s),l=De(t.selectedDiffPath??null,i),[d,f]=await Promise.all([oi(e,c),(async()=>{if(!l)return Y("No diff selected","No local changes found.","empty");let R=Xt(e,l),k=R?r.find(S=>S.target.repoId===R.target.repoId):null;return ii(e,l,o,k?.baseRef??null)})()]),h=l?{[l]:f}:{};return{taskId:e.id,fileRows:ui(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:h,selectedFilePath:c,selectedDiffPath:l,selectedFile:d,selectedDiff:f,error:null}}async function oi(e,t){let n=Xt(e,t);if(!n)return Y("No file selected","No Git-visible files found.","empty");let r=await Zt(n.target.worktreePath,n.relativePath);return{...r,path:t,title:t??r.title}}async function ii(e,t,n,r=null){let s=Xt(e,t);return s?{...await Rr(s.target.worktreePath,s.relativePath,n.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),r),path:t,title:t}:Y(t,"Repo target is unavailable.","error",t)}function Xt(e,t){if(!t)return null;let[n,...r]=t.split("/"),s=r.join("/"),o=(e.repoTargets??[]).find(i=>i.repoId===n&&i.status==="ready")??null;return!o||s.length===0?null:{target:o,relativePath:s}}async function ai(e){let t=await v("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return fi(t.stdout)}async function ci(e,t){let[n,r,s,o]=await Promise.all([Zd(e,t),ni(e,"staged"),ni(e,"unstaged"),eu(e)]);return[...n,...r,...s,...o]}async function Zd(e,t){if(!t)return[];let[n,r]=await Promise.all([v("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),v("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=li(n.stdout),o=di(r.stdout);return s.map(i=>{let c=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:c.additions,deletions:c.deletions}}).sort((i,c)=>i.path.localeCompare(c.path))}async function ni(e,t){let n=t==="staged"?["diff","--cached"]:["diff"],[r,s]=await Promise.all([v("git",[...n,"--name-status"],{cwd:e}),v("git",[...n,"--numstat"],{cwd:e})]),o=li(r.stdout),i=di(s.stdout);return o.map(c=>{let l=i.get(c.path)??{additions:null,deletions:null};return{group:t,path:c.path,status:c.status,additions:l.additions,deletions:l.deletions}}).sort((c,l)=>c.path.localeCompare(l.path))}async function eu(e){let t=await v("git",["ls-files","--others","--exclude-standard"],{cwd:e}),n=fi(t.stdout);return await Promise.all(n.map(async s=>{let o=await Zt(e,s),i=o.status==="ready"?tu(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function li(e){return e.split(`
131
+ `).map(t=>t.trim()).filter(t=>t.length>0).map(t=>{let[n="M",...r]=t.split(" ");return{status:n,path:r.at(-1)??""}}).filter(t=>t.path.length>0)}function di(e){let t=new Map;for(let n of e.split(`
132
+ `)){let r=n.trim();if(!r)continue;let[s="-",o="-",...i]=r.split(" "),c=i.join(" ");c&&t.set(c,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function Rt(e){return(await L("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await L("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function Zt(e,t){if(!t)return Y("No file selected","No Git-visible files found.","empty");let n=nu(e,t);try{let r=await zd(n);if(r.size>Yd)return Y(t,`File is ${r.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,r.size);let s=await Hd(n);return ru(s)?Y(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
133
+ `),byteLength:s.byteLength}}catch(r){let s=r instanceof Error?r.message:"Unable to read file.";return Y(t,s,"missing",t,null)}}async function Rr(e,t,n,r=null){if(!t)return Y("No diff selected","No local changes found.","empty");let s=[],o=n.filter(c=>c.path===t).map(c=>c.group);if(o.includes("branch")){let c=r??await Rt(e);if(c){let l=await v("git",["diff","--stat","--patch",`--unified=${Qt}`,`${c}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
134
+ ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let c=await v("git",["diff","--cached","--stat","--patch",`--unified=${Qt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`staged
135
+ ${c.stdout.trimEnd()}`)}if(o.includes("unstaged")){let c=await v("git",["diff","--stat","--patch",`--unified=${Qt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`unstaged
136
+ ${c.stdout.trimEnd()}`)}if(o.includes("untracked")){let c=await L("git",["diff","--no-index","--stat","--patch",`--unified=${Qt}`,"--","/dev/null",t],{cwd:e});c.stdout.trim().length>0&&s.push(`untracked
137
137
  ${c.stdout.trimEnd()}`)}let i=s.join(`
138
138
 
139
- `);return i.length>Pd?H(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?H(t,"Binary diff preview is not available in Craig.","binary",t,i.length):{path:t,status:i.length>0?"ready":"empty",title:t,lines:i.length>0?i.split(`
140
- `):["No diff for this file."],byteLength:i.length}}function No(e){let t=[],n=new Set;for(let r of e){let s=r.split("/");for(let o=0;o<s.length-1;o+=1){let i=s.slice(0,o+1).join("/");n.has(i)||(n.add(i),t.push({kind:"directory",path:i,depth:o,label:s[o]??i}))}t.push({kind:"file",path:r,depth:s.length-1,label:s.at(-1)??r})}return t}function Oe(e,t){return e&&t.includes(e)?e:t[0]??null}function xd(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function Wo(e){return[...new Set(e.split(`
141
- `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,n)=>t.localeCompare(n))}function vd(e,t){let n=ar.resolve(e,t),r=ar.resolve(e);if(n!==r&&!n.startsWith(`${r}${ar.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return n}function Ed(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function H(e,t,n,r=null,s=null){return{path:r,status:n,title:e,lines:[t],byteLength:s}}ie();import{access as Ad}from"node:fs/promises";async function _o(e,t){let n=await M(e,t),r=await $d(n.worktreePath),s={...n,status:"closed",cleanup:{...n.cleanup,preservedWorktree:r&&n.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await E(e,s),s}async function $d(e){try{return await Ad(e),!0}catch{return!1}}ue();ce();import Ct from"node:path";function Bo(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 Uo="\u{F024B} ",qo="\u{F0DCF} ",Ko="\u25CB",lr="\uEA64",Vo="\uEAFE",Go="\uEBDA",dr="\u25CB",ur="\u25CF",fr="\u2713",pr="\u2715";function Ho(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}}ue();rt();ue();var Dd=["tasks","center","inspector","actions"],Zo=["agent","terminal"],ei=[],A="inspection",Mw=[...Zo,...ei],ti=["commit","push","refresh-checks","close-task"],Md=["refresh-checks","close-task"],ni=["task","checks","pr","setup-run","actions","next-action"],ri=["diff","files","review"];function si(e,t={}){let n=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,r=Yd(e?.openInspectionKind)??n,s=Ze(t);return{inputMode:Qd(e?.inputMode),focusedRegion:Hd(e?.focusedRegion),selectedRepoId:xe(e?.selectedRepoId),selectedWorkspaceId:xe(e?.selectedWorkspaceId),selectedTaskId:xe(e?.selectedTaskId),selectedPtyTabId:xe(e?.selectedPtyTabId),selectedLeftItemId:iu(xe(e?.selectedTaskId)),activeTab:n?A:xe(e?.activeTab)??"agent",preferredPtyTabKind:Jd(e?.preferredPtyTabKind),inspectorSection:It(e?.inspectorSection,ni,"task"),inspectionMode:zd(e?.inspectionMode,n==="diff"?"diff":"files"),openInspectionKind:r,selectedFileTreePath:xe(e?.selectedFileTreePath),selectedFilePath:xe(e?.selectedFilePath),selectedDiffPath:xe(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:It(e?.selectedActionId,ti,"commit"),selectedProjectTargetId:null,selectedRunner:Xd(e?.selectedRunner,s,_e(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:Ld(),centerZoomed:!1}}function Ld(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function oi(e,t){return{...e??Pe(),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 nn(e,t,n={}){let r=su(e,t),s=pi(r),o=(s?.kind==="workspace"?t.workspaces?.find(f=>f.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(f=>f.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,c=((s?.kind==="repo"?t.repos.find(f=>f.id===s.id)??null:s?.kind==="task"?t.repos.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(f=>f.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(f.id))??null:null)??(o?.kind!=="project"?t.repos.find(f=>f.id===o?.primaryRepoId)??null:null)??t.repos.find(f=>f.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(f=>f.workspaceId===o.id):c?t.tasks.filter(f=>f.repoId===c):[],d=(s?.kind==="task"?l.find(f=>f.id===s.id)??null:null)??l.find(f=>f.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:n.resetInputMode?"control":e.inputMode,selectedLeftItemId:r,selectedWorkspaceId:o?.id??null,selectedRepoId:c,selectedTaskId:d?.id??null,...eu(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:Kd(e,t,d?.id??null),...tu(e,t,d?.id??null),selectedDiffPath:qd(e,t,d?.id??null),inspectorSection:It(e.inspectorSection,ni,"task")}}function ii(e,t,n={leftItemIds:[]}){if(e.inputMode==="terminal")return Od(t)?b({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):b({state:e});if(t==="q"||t==="Q")return b({state:e,exit:!0});if(t==="ESCAPE")return b({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return b({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(gr(e.selectedLeftItemId)||hr(e.selectedLeftItemId)))return b({state:{...e,selectedRunner:wr(e.selectedRunner,n.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return zo(e,1);if(t==="SHIFT_TAB"||t==="[")return zo(e,-1);if(t==="z"||t==="Z")return b({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===A?Fe(e,-1,n):Yo(e,-1,n);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===A?Fe(e,1,n):Yo(e,1,n);if(t==="PAGE_UP")return Fe(e,-(n.pageRows??10),n);if(t==="PAGE_DOWN")return Fe(e,n.pageRows??10,n);if(t==="MOUSE_WHEEL_UP")return Fe(e,-3,n);if(t==="MOUSE_WHEEL_DOWN")return Fe(e,3,n);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let r=n.enabledRunnerIds??N,s=e.centerTabRunner?r.indexOf(e.centerTabRunner):-1,o=s===r.length-1?null:r[s+1];return b({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let r=Zd(e,t);return b({state:{...e,preferredPtyTabKind:r,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:r,createPtyTabRunner:r==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return b({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return b({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return b({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&tn(e.selectedLeftItemId)&&e.selectedTaskId)return b({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&au(e.selectedLeftItemId)&&e.selectedWorkspaceId)return b({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Xo(e.activeTab,n.ptyTabIds??[]))return b({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return mr(e,-1,n.centerTabIds);if(e.focusedRegion==="inspector")return Jo(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return mr(e,1,n.centerTabIds);if(e.focusedRegion==="inspector")return Jo(e,1)}if(Ee(t)){if(e.focusedRegion==="tasks"&&(gr(e.selectedLeftItemId)||hr(e.selectedLeftItemId))){let r=mi(e.selectedLeftItemId),s=gi(e.selectedLeftItemId);return b({state:{...e,selectedRepoId:r??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return b({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&tn(e.selectedLeftItemId)&&e.selectedTaskId){let r=e.selectedPtyTabId??e.activeTab;return b({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:r,selectedPtyTabId:r,preferredPtyTabKind:St(r)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Xo(e.activeTab,n.ptyTabIds??[])&&e.selectedTaskId)return b({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:St(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===A)return b({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let r=e.selectedFileTreePath??e.selectedFilePath;if(r&&(n.fileTreeDirectoryIds??[]).includes(r))return b({state:_d({...e,selectedFileTreePath:r}),changed:!0});let s=r&&(n.fileTreeFileIds??[]).includes(r)?r:e.selectedFilePath;return b({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:A,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?b({state:{...e,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!n.projectTargetIds?.length?b({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):b({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?b({state:e}):e.selectedActionId==="refresh-checks"?b({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?b({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):b({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return b({state:e})}function Ye(e,t){return{...e,terminal:t}}function ai(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Od(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Ee(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
142
- `}function ci(e){return e.length===1&&e>=" "&&e!=="\x7F"}function li(e){return di(e)||St(e)!==null}function Fd(e){return ei.includes(e)}function di(e){return Zo.includes(e)}function ui(e,t){return[...e?.ptyTabs.map(n=>n.id)??[],...t?.openInspectionKind?[A]:[]]}var jd=["tasks","center","inspector"];function zo(e,t){return Zt(e,"focusedRegion",jd,t)}function mr(e,t,n){let r=Zt(e,"activeTab",n&&n.length>0?n:ru(e),t);return!r.changed||Fd(r.state.activeTab)?r:{...r,state:{...r.state,selectedPtyTabId:r.state.activeTab,preferredPtyTabKind:St(r.state.activeTab)??r.state.preferredPtyTabKind}}}function Yo(e,t,n){if(e.focusedRegion==="tasks")return Nd(e,t,n.leftItemIds);if(e.focusedRegion==="center")return mr(e,t,n.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return fi(e,t,n);if(e.inspectionMode==="diff"){let r=en(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:r}if(n.projectTargetIds?.length){let r=en(e,"selectedProjectTargetId",n.projectTargetIds,t);return r.changed?{...r,state:{...r.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:r}return Zt(e,"selectedActionId",Md,t)}return Zt(e,"selectedActionId",ti,t)}function Nd(e,t,n){let r=en(e,"selectedLeftItemId",n,t);if(!r.changed)return r;let s=pi(r.state.selectedLeftItemId);if(s?.kind==="workspace")return{...r,state:{...r.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...r,state:{...r.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...r,state:{...r.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=mi(r.state.selectedLeftItemId);if(o)return{...r,state:{...r.state,selectedRepoId:o}};let i=gi(r.state.selectedLeftItemId);return i?{...r,state:{...r.state,selectedWorkspaceId:i}}:r}function Fe(e,t,n){if(t===0)return b({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return fi(e,t,n);if(e.inspectionMode==="diff"){let r=en(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,diffScrollOffset:0}}:r}return e.inspectionMode==="review"?Qo(e,"reviewScrollOffset",t,n.reviewRowCount??100,n.pageRows):b({state:e})}if(e.focusedRegion==="center"&&e.activeTab===A){if(e.openInspectionKind==="file")return Qo(e,"fileScrollOffset",t,n.fileLineCount??0,n.pageRows);if(e.openInspectionKind==="diff")return Bd(e,t,n)}return b({state:e})}function Wd(e,t){if(e.inspectionMode===t)return b({state:e});let n=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,r=t==="diff"||t==="files"?A:e.activeTab;return b({state:{...e,inspectionMode:t,activeTab:r,openInspectionKind:n,fileScrollOffset:t==="files"?0:e.fileScrollOffset,diffScrollOffset:t==="diff"?0:e.diffScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function Jo(e,t){return Wd(e,Gd(e.inspectionMode,ri,t))}function fi(e,t,n){let r=n.fileTreeRowIds&&n.fileTreeRowIds.length>0?n.fileTreeRowIds:n.filePathIds??[];if(r.length===0)return b({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??r[0]??null,o=r.indexOf(s??""),i=ve(o===-1?0:o+t,0,r.length-1),c=r[i]??null;if(c===e.selectedFileTreePath)return b({state:e});let l=c!==null&&(n.fileTreeFileIds??n.filePathIds??[]).includes(c);return b({state:{...e,selectedFileTreePath:c,selectedFilePath:l?c:e.selectedFilePath,activeTab:l?A:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function _d(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((n,r)=>n.localeCompare(r)),actionMessage:null}}function Qo(e,t,n,r,s=10){let o=Math.max(0,r-Math.max(1,s)),i=ve(e[t]+n,0,o);return i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Bd(e,t,n){if(n.diffPathRanges&&n.diffPathRanges.length>0)return Ud(e,t,n);let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=e.diffScrollOffset+t,c=n.diffPathIds??[];if(c.length===0||!e.selectedDiffPath){let f=ve(i,0,o);return f===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}let l=c.indexOf(e.selectedDiffPath);if(l===-1){let f=ve(i,0,o);return f===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}if(t>0&&i>o){let f=c[l+1]??null;return f?b({state:{...e,selectedDiffPath:f,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?b({state:e}):b({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let f=c[l-1]??null;return f?b({state:{...e,selectedDiffPath:f,activeTab:A,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?b({state:e}):b({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=ve(i,0,o);return d===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function Ud(e,t,n){let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=ve(e.diffScrollOffset+t,0,o),c=Vd(n.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&c===e.selectedDiffPath?b({state:e}):b({state:{...e,diffScrollOffset:i,selectedDiffPath:c,actionMessage:null},changed:!0})}function qd(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function Kd(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function Vd(e,t){return e.find(n=>t>=n.start&&t<n.end)?.path??e.at(-1)?.path??null}function Zt(e,t,n,r){let s=n.indexOf(e[t]),o=ve(s+r,0,n.length-1),i=n[o];return!i||i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function en(e,t,n,r,s=!1){if(n.length===0)return b({state:e});let o=n.indexOf(e[t]??n[0]??""),i=ve(o===-1?0:o+r,0,n.length-1),c=n[i]??null;return c===e[t]?b({state:e}):b({state:{...e,[t]:c,actionMessage:null},changed:!0,refreshInspection:s})}function Gd(e,t,n){let r=t.indexOf(e);return t[ve(r+n,0,t.length-1)]??e}function b(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function It(e,t,n){return t.includes(e??"")?e:n}function Hd(e){return e==="tabs"?"center":It(e,Dd,"tasks")}function zd(e,t){return e==="checks"||e==="actions"||e==="review"?"review":It(e,ri,t)}function Yd(e){return e==="file"||e==="diff"?e:null}function Jd(e){return e==="terminal"?"terminal":"agent"}function Qd(e){return e==="terminal"?"terminal":"control"}function Xd(e,t=[...N],n="codex"){return e&&et(e)&&t.includes(e)?e:n}function wr(e,t=N){let n=t.length>0?t:N,r=n.indexOf(e);return n[(r+1)%n.length]??n[0]??"codex"}function St(e){let t=N.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Zd(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":St(e.activeTab)??e.preferredPtyTabKind}function eu(e,t,n){if(!e)return{activeTab:t===A?t:"agent",selectedPtyTabId:null};let r=e.ptyTabs.find(c=>c.id===n)??null,s=e.selectedPtyTabId?e.ptyTabs.find(c=>c.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(c=>c.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(di(t)){let l=e.ptyTabs.find(d=>d.kind===t)??null??s??r??e.ptyTabs[0]??null;return{activeTab:l?.id??A,selectedPtyTabId:l?.id??null}}if(t===A)return{activeTab:A,selectedPtyTabId:r?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??r??e.ptyTabs[0]??null;return{activeTab:i?.id??A,selectedPtyTabId:i?.id??null}}function tu(e,t,n){if(!t.inspection||t.inspection.taskId!==n)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let r=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?nu(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:r,collapsedFileTreePaths:s}}function nu(e,t){let n=new Set;if(t){let r=t.split("/");for(let s=1;s<r.length;s+=1)n.add(r.slice(0,s).join("/"))}return e.filter(r=>r.kind==="directory"&&!r.path.includes("/")&&!n.has(r.path)).map(r=>r.path).sort((r,s)=>r.localeCompare(s))}function ru(e){return[e.selectedPtyTabId,e.openInspectionKind?A:null].filter(t=>typeof t=="string")}function Xo(e,t){return t.includes(e)}function su(e,t){let n=ou(t);return e.selectedLeftItemId&&n.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&n.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&n.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&n.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:n[0]??null}function ou(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function pi(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function xe(e){return typeof e=="string"?e:null}function iu(e){return e?`task:${e}`:null}function tn(e){return typeof e=="string"&&e.startsWith("task:")}function gr(e){return typeof e=="string"&&e.startsWith("new-task:")}function hr(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function au(e){return typeof e=="string"&&e.startsWith("workspace:")}function mi(e){return gr(e)?e.slice(9):null}function gi(e){return hr(e)?e.slice(19):null}function ve(e,t,n){return Math.min(n,Math.max(t,e))}var sn="empty",B={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Ri(e,t){let n=du(t,e),r=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=n?t.tasks.filter(T=>T.workspaceId===n.id):t.tasks,o=n?.kind==="project"?s:r?s.filter(T=>T.repoId===r.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,c=i?.type==="project",l=Gu(t.tasks),d=pu(e,i),f=fu(e,i,d),h=f.find(T=>T.id===d)??f[0]??{id:"agent",label:"CODEX"},R=t.inspection?.taskId===i?.id?t.inspection:null,k=r?.name??"no repo",I=i?se(i.runner):se(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${r?`[${r.name}]`:"[no repo]"} \xB7 ${se(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 [${se(e.selectedRunner)}] Enter create task Esc pause ? help`:tn(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?i===null?"n new task Tab tasks Esc pause ? help":d===A?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${se(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?c?"\u2191\u2193 targets Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?"\u2191\u2193 navigate Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:Ct.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Ct.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:I},leftTree:cu(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>Hu(T,l[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":h.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:k,agent:I},centerTranscript:uu(d,e,r,i,e.workspaceBrowser,R,n),tabs:f,rightContext:Vu(r,i),rightInspection:Cu(e,i,R)}}function cu(e,t){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return lu(n,e,t.repos,t.tasks);let r=t.workspaces;if(r.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of r){let i=e.selectedLeftItemId===`workspace:${o.id}`;n.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:i,focused:i&&e.focusedRegion==="tasks"});let c=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],l=t.tasks.filter(d=>d.workspaceId===o.id);if(l.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of l){let f=e.selectedLeftItemId===`task:${d.id}`,h=f?"\u25B8":"\u2022",R=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,k={id:`task:${d.id}`,taskId:d.id,text:`${h} ${R}`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks"},I=yi(d);I&&(k.prBadge=I),n.push(k)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${se(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${se(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}else{n.push({text:` Repos (${c.length})`,indent:0,muted:!0});for(let d of c.slice(0,6)){let f=t.repos.find(h=>h.id===d);n.push({text:` \xB7 ${f?.name??d}`,indent:0,muted:!0})}c.length>6&&n.push({text:` \xB7 ${c.length-6} more`,indent:0,muted:!0})}}let s=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&e.focusedRegion==="tasks"}),n}function lu(e,t,n,r){if(n.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of n){let i=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:i,focused:i&&t.focusedRegion==="tasks"});let c=r.filter(f=>f.repoId===o.id);if(c.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let f of c){let h=t.selectedLeftItemId===`task:${f.id}`,R=h?"\u25B8":"\u2022",k=f.title.length>28?`${f.title.slice(0,25)}\u2026`:f.title,I={id:`task:${f.id}`,taskId:f.id,text:`${R} ${k}`,indent:2,selected:h,focused:h&&t.focusedRegion==="tasks"},T=yi(f);T&&(I.prBadge=T),e.push(I)}let l=`new-task:${o.id}`,d=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${se(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let s=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&t.focusedRegion==="tasks"}),e}function du(e,t){let n=e.workspaces??[];if(!e.workspaces)return null;let r=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return r?n.find(s=>s.id===r.workspaceId)??null:t.selectedWorkspaceId?n.find(s=>s.id===t.selectedWorkspaceId)??null:n[0]??null}function uu(e,t,n,r,s,o=null,i=null){if(s){let l=s.entries.length===0?["No directories or git repos here."]:s.entries.map((d,f)=>{let h=f===s.selectedIndex?"\u25B8":" ",R=d.kind==="repo"?" [git repo]":"/";return`${h} ${d.name}${R}`});return ge(["Browse for a workspace to register.",s.cwd,"",...l,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!n)return ge(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!r){let l=i?.kind==="project",d=l?i.name??"this workspace":n.name,f=l?"Project Task":"Task";return ge([`No tasks in ${d}.`,"",`Press n or choose + New ${f} to create one with ${se(t.selectedRunner)}.`])}let c=r.ptyTabs.find(l=>l.id===e)??null;return c?c.kind==="agent"?ge([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):ge([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===A&&t.openInspectionKind==="file"?hu(r,o,t.fileScrollOffset):e===A&&t.openInspectionKind==="diff"?wu(r,o,t.diffScrollOffset):r.ptyTabs.length===0&&!t.openInspectionKind?ge(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ge(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function fu(e,t,n){let r=t?.ptyTabs.map(o=>({id:o.id,label:mu(o)}))??[];if(!t)return[{id:sn,label:"EMPTY",active:n===sn,focused:e.focusedRegion==="center"&&n===sn}];let s=e.openInspectionKind||n===A?[{id:A,label:gu(e)}]:[];return[...r,...s].map(o=>({...o,active:o.id===n,focused:e.focusedRegion==="center"&&o.id===n}))}function pu(e,t){return t?t.ptyTabs.some(n=>n.id===e.activeTab)||e.activeTab===A&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(n=>n.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??A:e.selectedPtyTabId&&t.ptyTabs.some(n=>n.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??A:sn}function mu(e){return e.title.toUpperCase()}function gu(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,n=t?Ct.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${n} \u0394`:n}function hu(e,t,n){if(!e)return ge(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ge(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let r=t.selectedFile,s=Ti(r.path??r.title);return[{text:r.title},{text:`${r.byteLength===null?"size unknown":`${r.byteLength} bytes`} \xB7 ${r.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...ku(r.lines,n,s)]}function wu(e,t,n){if(!e)return ge(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ge(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let r=t.selectedDiff,s=Ti(r.path??r.title);return[{text:r.title},{text:`${t.diffPaths.length} changed files \xB7 ${r.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Ru(r.lines,n,s)]}function ge(e){return e.map(t=>({text:t}))}function ku(e,t,n){let r=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let c=s+i+1;return{text:`${`${String(c).padStart(r," ")} \u2502 `}${o}`,segments:[{text:String(c).padStart(r," "),style:{fg:B.lineNumber}},{text:" \u2502 ",style:{fg:B.gutter}},...kr(o,n)],tone:"default"}})}function Ru(e,t,n){let r=Tu(e),s=Math.max(0,Math.min(t,Math.max(0,r.length-1)));return r.slice(s).map(o=>yu(o,n))}function Tu(e){let t=[],n=0,r=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){n=Number.parseInt(o[1]??"0",10),r=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:n,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),n+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:r,marker:"+",text:s.slice(1),kind:"add"}),r+=1;continue}if(s.startsWith(" ")){if(n===0&&r===0)continue;t.push({oldNumber:n,newNumber:r,marker:" ",text:s.slice(1),kind:"context"}),n+=1,r+=1;continue}}}return t}function yu(e,t){let n=hi(e.oldNumber),r=hi(e.newNumber),s=e.kind==="delete"?n:r,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:B.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:B.diffAdd}:null,i=`${s} \u2502 ${e.text}`,c=o?bu(kr(e.text,t),o.bg,o.fallbackFg):kr(e.text,t),l=o?{fg:B.lineNumber,bg:o.bg}:{fg:B.lineNumber},d=o?{fg:B.gutter,bg:o.bg}:{fg:B.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...c],fullBleed:o!==null}}function hi(e){return e===null?" ":String(e).padStart(4," ")}function Ti(e){let t=Ct.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function kr(e,t){return t==="diff"?Pu(e):t==="markdown"?Iu(e):t==="json"?Rr(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Rr(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 Pu(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:B.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:B.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:B.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:B.diffMeta}}]:[{text:e}]}function bu(e,t,n){return e.map(r=>({text:r.text,style:{...r.style??{fg:n},bg:t}}))}function Iu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:B.markup,bold:!0}}]:Rr(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Rr(e,t){let n=[],r=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>r&&n.push({text:e.slice(r,i)}),n.push({text:o,style:Su(o)}),r=i+o.length}return r<e.length&&n.push({text:e.slice(r)}),n.length>0?n:[{text:e}]}function Su(e){return e.startsWith("//")||e.startsWith("/*")?{fg:B.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:B.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:B.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:B.markup}:{fg:B.keyword}}function Cu(e,t,n){let r=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&r?t.repoTargets?.find(c=>c.repoId===r)??null:null,o=t?.type==="project"?Pi(t.repoTargets??[]):s?.pullRequest??(t?K(t):null),i=[xu(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Si(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,..._u(e,n)]}:{title:"",rows:[...i,...Uu(e,n)]}}function xu(e,t){let n=e.inspectionMode,r=[{label:"CHANGES",active:n==="diff"},{label:"FILES",active:n==="files"},{label:"REVIEW",active:n==="review"}],s=[];for(let l=0;l<r.length;l++){let d=r[l];l>0&&s.push({text:" "});let f=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:f}})}let o=Tr(t),i=yr(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function wi(e){return[{text:" "},Tr(e),{text:" "},yr(e)]}function yi(e){if(e.type==="project"&&e.repoTargets?.length){let n=Pi(e.repoTargets);return n?wi(n):null}let t=K(e);return t?.number?wi(t):null}function Pi(e){let t=e.filter(s=>s.status==="ready"),n=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(n.length===0)return null;let r=Eu(n);return{number:-1,status:vu(n),draft:n.some(s=>s.draft),mergeable:n.length===t.length&&n.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:n.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":n.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":n.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:n.flatMap(s=>s.requiredChecks),aggregateReadiness:r}}function vu(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 Eu(e){let t=e.map(n=>bi(n));return t.some(n=>n==="failed")?"failed":t.some(n=>n==="pending")?"pending":t.length>0&&t.every(n=>n==="success")?"success":"none"}function Tr(e){return!e||!e.number?{text:Ko,style:{fg:"565f89"}}:e.status==="merged"?{text:Vo,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Go,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:lr,style:{fg:"565f89"}}:{text:lr,style:{fg:"9ece6a"}}}function yr(e){return e?.aggregateReadiness?ki(e.aggregateReadiness):ki(bi(e))}function ki(e){return e==="failed"?{text:pr,style:{fg:"f7768e"}}:e==="pending"?{text:ur,style:{fg:"e0af68"}}:e==="success"?{text:fr,style:{fg:"9ece6a"}}:{text:dr,style:{fg:"565f89"}}}function bi(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(n=>n.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(n=>n.status==="success"||n.status==="skipped")?Ii(e)?"failed":Au(e)?"success":"pending":"pending"}function Au(e){return!!(e.mergeable&&!e.draft&&!Ii(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Ii(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Si(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return $u(e,t);let n=K(t),r=xi("pr",t.branch,n??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==n&&(o.status==="merged"||o.status==="closed")).length;return s>0&&r.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),Du(r,e)}var rn=32;function $u(e,t){let n=[],r=t.repoTargets??[],s=e.selectedProjectTargetId??r[0]?.repoId??null;for(let i of r){let c=s===i.repoId,l=e.focusedRegion==="inspector"&&c,d=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let h=i.failureReason?i.failureReason.slice(0,14):i.status,R=rn-h.length-1,k=d.length>R?d.slice(0,R-1)+"\u2026":d,I=rn-k.length-h.length;n.push({id:`project-review:${i.repoId}`,text:k+" ".repeat(Math.max(1,I))+h,selected:c,focused:l,muted:!0})}else{let f=Tr(i.pullRequest),h=yr(i.pullRequest),R=`${f.text} ${h.text}`,k=rn-R.length-1,I=d.length>k?d.slice(0,k-1)+"\u2026":d,T=rn-I.length-R.length,a=I+" ".repeat(Math.max(1,T));n.push({id:`project-review:${i.repoId}`,text:a+R,selected:c,focused:l,segments:[{text:a},{...f,text:f.text},{text:" "},{...h,text:h.text}]})}}let o=r.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(n.push({id:"target-detail-spacer",text:""}),n.push(...xi("target",o.branch,o.pullRequest))),n}function Ci(e,t){return Si(e,t).length}function xi(e,t,n){let r=h=>`${e}-${h}`;if(!n.number)return[{id:r("no-pr"),text:t,muted:!0}];let s=[],o=`#${n.number}`;s.push(n.url?{id:r("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:n.url}]}:{id:r("pr-number"),text:o});let i=n.baseBranch??"?",c=n.headBranch??t;s.push({id:r("pr-branches"),text:`${i} \u2192 ${c}`,muted:!0});let l=Mu(n.reviewDecision,n.mergeStateStatus),d=l&&l!=="review approved"?"merge blocked":n.mergeable?"merge ready":n.mergeStateStatus?`merge ${n.mergeStateStatus}`:"merge unknown";l?s.push({id:r("pr-merge"),text:`${d} \xB7 ${l}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:l,style:{fg:Lu(n.reviewDecision,n.mergeStateStatus)}}]}):s.push({id:r("pr-merge"),text:d,muted:!0}),s.push({id:r("pr-synced"),text:`synced ${vi(n.lastSyncedAt)}`,muted:!0}),s.push({id:r("checks-spacer"),text:""}),s.push({id:r("checks-header"),text:"Checks"}),n.requiredChecks.length?s.push(...n.requiredChecks.map(Ou)):s.push({id:r("checks-none"),text:n.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let f=n.comments??[];return f.length>0&&(s.push({id:r("comments-spacer"),text:""}),s.push({id:r("comments-header"),text:`Review comments (${f.length})`}),s.push(...f.slice(-4).flatMap((h,R)=>Fu(h,r(`comment:${R}`))))),s}function Du(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let n=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((r,s)=>({...r,selected:t.reviewScrollOffset===0&&r.selected||s===n,focused:t.reviewScrollOffset===0&&r.focused||s===n}))}function Mu(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Lu(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function vi(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;let r=Math.floor(n/60);if(r<60)return`${r}m ago`;let s=Math.floor(r/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function Ou(e){let{icon:t,color:n}=Nu(e.status),r=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${r.padEnd(16," ")} ${Wu(e.status)}`,color:n,muted:!1}}function Fu(e,t){let n=e.author??"unknown",r=e.createdAt?` \xB7 ${vi(e.createdAt)}`:"",s=ju(e.body,30),o=s.slice(0,4),i=o.length<s.length,c=[{id:`${t}:author`,text:`${n}${r}`,muted:!0},...o.map((l,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return c.push({id:`${t}:spacer`,text:"",muted:!0}),c}function ju(e,t){let n=e.split(/\s+/).filter(Boolean);if(n.length===0)return[];let r=[],s="";for(let o of n){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(r.push(s),s=o)}return s&&r.push(s),r}function Nu(e){switch(e){case"success":return{icon:fr,color:"9ece6a"};case"pending":return{icon:ur,color:"e0af68"};case"failed":return{icon:pr,color:"f7768e"};case"skipped":return{icon:dr,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function Wu(e){return e==="success"?"passing":e==="failed"?"failing":e}function _u(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let n=new Map(t.diffRows.map(o=>[o.path,o.status])),r=Bu(t.fileRows,e.collapsedFileTreePaths),s=e.selectedFileTreePath??t.selectedFilePath;return r.map(o=>{let i=o.kind==="file"?n.get(o.path):void 0,c=i==="A"?"9ece6a":i==="M"?"e0af68":i==="D"?"f7768e":i==="??"?"565f89":void 0,l=o.kind==="directory"?e.collapsedFileTreePaths.includes(o.path)?Uo:qo:Bo(o.label),d=o.kind==="directory"?"7aa2f7":Ho(o.label),f=" ".repeat(o.depth),h=d?{text:l,style:{fg:d}}:{text:l},R=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:c?{text:o.label,style:{fg:c}}:{text:o.label},k=[{text:f},h,R];return{id:o.path,text:`${f}${l}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:k}})}function Bu(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function Uu(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(qu(t))return Ku(e,t);let n=[];for(let r of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===r);s.length!==0&&(n.push({id:r,text:r.toUpperCase(),muted:!0}),n.push(...s.map(o=>Ei(o,e,t))))}return n}function qu(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Ku(e,t){let n=[],r=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of r){let o=t.diffRows.filter(c=>c.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;n.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let c of["branch","staged","unstaged","untracked"]){let l=o.filter(d=>d.group===c);l.length!==0&&(n.push({id:`repo-diff:${s}:${c}`,text:` ${c}`,muted:!0}),n.push(...l.map(d=>Ei(d,e,t,s.length+1))))}}return n}function Ei(e,t,n,r=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",c=r>0?e.path.slice(r):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${c} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??n.selectedDiffPath),focused:e.path===(t.selectedDiffPath??n.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function Vu(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:se(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Ct.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function Gu(e){return e.reduce((t,n)=>(t[n.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Hu(e,t){return{name:se(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var on={width:120,height:36},he={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function je(e,t){return{width:Math.max(e??on.width,on.width),height:Math.max(t??on.height,on.height)}}import{spawn as wf}from"node:child_process";import{createHash as kf}from"node:crypto";import{createServer as Rf,createConnection as Ni}from"node:net";import{openSync as Tf}from"node:fs";import{mkdir as yf,readFile as vr,rm as Je,writeFile as Pf}from"node:fs/promises";import{tmpdir as bf}from"node:os";import it from"node:path";import{createRequire as rf}from"node:module";import zu from"@xterm/headless";var Yu=1e3,Ju=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function $i(e){return new zu.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:Yu,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function Di(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function br(e,t){return new Promise(n=>{e.write(t,n)})}function Mi(e,t=0){let n=e.buffer.active,r=[],s=n.getNullCell(),o=n.baseY+n.cursorY,i=Math.max(0,n.baseY-t);for(let c=0;c<e.rows;c+=1){let l=n.getLine(i+c);if(!l){r.push({segments:[]});continue}let d=[];for(let f=0;f<e.cols;f+=1){let h=l.getCell(f,s);!h||h.getWidth()===0||d.push({text:h.getChars()||" ",style:Zu(h,i+c===o&&f===n.cursorX)})}r.push({segments:Qu(Xu(d))})}return r}function Qu(e){let t=[];for(let n of e){let r=t.at(-1);if(r&&nf(r.style,n.style)){r.text+=n.text;continue}let s={text:n.text};Li(n.style)||(s.style=n.style),t.push(s)}return t}function Xu(e){let t=e.length;for(;t>0;){let n=e[t-1];if(!n||n.text!==" "||!Li(n.style))break;t-=1}return e.slice(0,t)}function Zu(e,t){let n={},r=Ai(e,"fg"),s=Ai(e,"bg");return r&&(n.fg=r),s&&(n.bg=s),e.isBold()&&(n.bold=!0),e.isDim()&&(n.dim=!0),e.isItalic()&&(n.italic=!0),e.isUnderline()&&(n.underline=!0),(e.isInverse()||t)&&(n.inverse=!0),n}function Ai(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let r=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return r?s.toString(16).padStart(6,"0"):Ju[s]??ef(s)}function ef(e){if(e>=16&&e<=231){let t=e-16,n=Math.floor(t/36),r=Math.floor(t%36/6),s=t%6;return[n,r,s].map(tf).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(n=>n.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function tf(e){return e===0?0:55+e*40}function nf(e,t){return Pr(e)===Pr(t)}function Pr(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Li(e){return Pr(e)===""}var sf=rf(import.meta.url),of=/^CTRL_([A-Z])$/,af="\x1B[6n",cf="\x1B[c",lf="\x1B[?u",df={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
143
- `,TAB:" ",SHIFT_TAB:"\x1B[Z",BACK_TAB:"\x1B[Z",BACKSPACE:"\x7F",DELETE:"\x1B[3~",ESCAPE:"\x1B",UP:"\x1B[A",DOWN:"\x1B[B",RIGHT:"\x1B[C",LEFT:"\x1B[D",HOME:"\x1B[H",END:"\x1B[F",PAGE_UP:"\x1B[5~",PAGE_DOWN:"\x1B[6~",CTRL_C:"",CTRL_D:""},an=class{sessions=new Map;shell;env;spawn;onUpdate;resolveSessionSpec;attachedTabId=null;constructor(t){this.shell=t.shell??process.env.SHELL??"/bin/zsh",this.env=t.env??process.env,this.spawn=t.spawn,this.onUpdate=t.onUpdate,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,n,r,s){let o=this.sessions.get(n);if(o)if(o.status!=="running")Ir(o),this.sessions.delete(n);else return this.attachedTabId=n,o.scrollbackLines=0,Oi(o,r),this.getViewState(n);let i=this.createSession(t,n,r,s);return this.sessions.set(n,i),this.attachedTabId=n,this.getViewState(n)}write(t){let n=this.getAttachedSession();!n||n.status!=="running"||n.pty.write(t)}writeKey(t){let n=uf(t);n!==null&&this.write(n)}scrollViewport(t){let n=this.getAttachedSession();if(!n||t===0)return;let r=n.terminal.buffer.active.baseY;n.scrollbackLines=Math.max(0,Math.min(r,n.scrollbackLines-t))}resize(t){let n=this.getAttachedSession();n&&Oi(n,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let n=this.sessions.get(t);n&&(Ir(n),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Ir(t);this.sessions.clear(),this.attachedTabId=null}getViewState(t){if(!t)return{status:"idle",rows:[],error:null,scrolledBack:!1};let n=this.sessions.get(t);return n?{status:n.status,rows:Mi(n.terminal,n.scrollbackLines),error:n.error,scrolledBack:n.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,n,r,s){let o=this.spawn??pf().spawn,i=$i(r),c=s??this.resolveSessionSpec(t,n),l=Ke({...this.env,...c.env??{}}),{executable:d,args:f}=mf(this.shell,c.command,{cwd:c.cwd,env:l}),h=o(d,f,{name:"xterm-256color",cols:r.columns,rows:r.rows,cwd:c.cwd,env:gf(l)}),R={taskId:t,tabId:n,pty:h,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0};return R.disposables.push(h.onData(k=>{hf(h,k),br(R.terminal,k).then(()=>{this.onUpdate?.(R.tabId)})})),R.disposables.push(h.onExit(k=>{R.status="exited",br(R.terminal,`\r
144
- [process exited ${k.exitCode}]`).then(()=>{this.onUpdate?.(R.tabId)})})),R}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function uf(e){if(e.length===1)return e;let t=df[e];if(t!==void 0)return t;let n=of.exec(e);return n?.[1]?String.fromCharCode(n[1].charCodeAt(0)-64):null}function Oi(e,t){ff(e.pty,t),Di(e.terminal,t)}function Ir(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function ff(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function pf(){return sf("node-pty")}function mf(e,t,n){if(t.length===0)return{executable:e,args:[]};let s=`${[Ve(t[0],n),...t.slice(1)].map(Fi).join(" ")}; exec ${Fi(e)} -l`;return{executable:e,args:["-lc",s]}}function Fi(e){return`'${e.replaceAll("'","'\\''")}'`}function gf(e){let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&(t[n]=r);return t.TERM=t.TERM??"xterm-256color",t}function hf(e,t){for(let n=0;n<Sr(t,af);n+=1)e.write("\x1B[1;1R");for(let n=0;n<Sr(t,cf);n+=1)e.write("\x1B[?1;2c");for(let n=0;n<Sr(t,lf);n+=1)e.write("\x1B[?0u")}function Sr(e,t){if(t.length===0)return 0;let n=0,r=e.indexOf(t);for(;r!==-1;)n+=1,r=e.indexOf(t,r+t.length);return n}var Er=3;async function Wi(e){let t=Ar(e.paths);await If(t,e.paths,e.spawnDaemon);let n=await Vi(t.socketPath),r=new Cr(n,e);return await r.ready(),r}async function _i(e,t={}){let n=Ar(e);await yf(e.runtimeDir,{recursive:!0}),await Je(n.socketPath,{force:!0});let r=new xr(e,t),s=Rf(o=>r.handleConnection(o));await Af(s,n.socketPath),await Pf(n.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=()=>{r.closeClients(),s.close(()=>o())};r.onShutdown=i,process.once("SIGTERM",i),process.once("SIGINT",i)}),await Je(n.socketPath,{force:!0}),await Je(n.pidPath,{force:!0}),r.disposeAll()}async function Bi(e){let t=Ar(e);return await ln(t.socketPath)?(await qi(t.socketPath),!0):!1}var Cr=class{constructor(t,n){this.socket=t;this.options=n,t.setEncoding("utf8"),t.on("data",r=>this.handleData(String(r))),t.on("error",r=>this.rejectAll(r instanceof Error?r:new Error(String(r)))),t.on("close",()=>{this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed."))})}socket;nextRequestId=1;pending=new Map;viewCache=new Map;attachedTabId=null;buffer="";closed=!1;options;async ready(){if((await this.send({type:"ping"})).protocolVersion!==Er)throw new Error("Craig PTY daemon protocol mismatch.")}async ensureSession(t,n,r){let s=await this.send({type:"ensureSession",taskId:t,tabId:n,size:r,spec:this.options.resolveSessionSpec?.(t,n)??{cwd:this.options.workspaceRoot,command:[]}});this.attachedTabId=n;let o=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(n,o),o}async hydrateSessions(t){for(let n of t)try{let r=await this.send({type:"hydrateSession",tabId:n});r.view&&this.viewCache.set(n,r.view)}catch(r){let s=r instanceof Error?r.message:String(r);this.viewCache.set(n,{status:"failed",rows:[],error:s})}}async pruneStale(t){await this.send({type:"pruneStale",keepTabIds:t})}write(t){this.send({type:"write",input:t}).catch(()=>{})}writeKey(t){this.send({type:"writeKey",key:t}).catch(()=>{})}scrollViewport(t){this.send({type:"scrollViewport",lines:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}resize(t){this.send({type:"resize",size:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}detach(){this.attachedTabId=null,this.send({type:"detach"}).catch(()=>{})}disposeSession(t){this.viewCache.delete(t),this.attachedTabId===t&&(this.attachedTabId=null),this.send({type:"disposeSession",tabId:t}).catch(()=>{})}disposeAll(){this.attachedTabId=null,!this.closed&&(this.socket.end(),this.closed=!0)}getViewState(t){return t?this.viewCache.get(t)??{status:"idle",rows:[],error:null,scrolledBack:!1}:{status:"idle",rows:[],error:null,scrolledBack:!1}}async requestShutdown(){await this.send({type:"shutdown"})}async send(t){if(this.closed)throw new Error("Craig PTY daemon connection is closed.");let n=this.nextRequestId;this.nextRequestId+=1;let r={...t,id:n},s=new Promise((i,c)=>{this.pending.set(n,{resolve:i,reject:c})});if(this.socket.destroyed)throw this.pending.delete(n),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(r)}
139
+ `);return i.length>Jd?Y(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?Y(t,"Binary diff preview is not available in Craig.","binary",t,i.length):{path:t,status:i.length>0?"ready":"empty",title:t,lines:i.length>0?i.split(`
140
+ `):["No diff for this file."],byteLength:i.length}}function ui(e){let t=[],n=new Set;for(let r of e){let s=r.split("/");for(let o=0;o<s.length-1;o+=1){let i=s.slice(0,o+1).join("/");n.has(i)||(n.add(i),t.push({kind:"directory",path:i,depth:o,label:s[o]??i}))}t.push({kind:"file",path:r,depth:s.length-1,label:s.at(-1)??r})}return t}function De(e,t){return e&&t.includes(e)?e:t[0]??null}function tu(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function fi(e){return[...new Set(e.split(`
141
+ `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,n)=>t.localeCompare(n))}function nu(e,t){let n=kr.resolve(e,t),r=kr.resolve(e);if(n!==r&&!n.startsWith(`${r}${kr.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return n}function ru(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function Y(e,t,n,r=null,s=null){return{path:r,status:n,title:e,lines:[t],byteLength:s}}ie();import{access as su}from"node:fs/promises";async function pi(e,t){let n=await O(e,t),r=await ou(n.worktreePath),s={...n,status:"closed",cleanup:{...n.cleanup,preservedWorktree:r&&n.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await A(e,s),s}async function ou(e){try{return await su(e),!0}catch{return!1}}ce();import Pt from"node:path";function mi(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 gi="\u{F024B} ",hi="\u{F0DCF} ",wi="\u25CB",Tr="\uEA64",ki="\uEAFE",Ri="\uEBDA",yr="\u25CB",Pr="\u25CF",br="\u2713",Ir="\u2715";function Ti(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}}ee();Ze();ee();var iu=["tasks","center","inspector","actions"],Ci=["agent","terminal"],xi=[],D="inspection",Qk=[...Ci,...xi],vi=["commit","push","refresh-checks","close-task"],au=["refresh-checks","close-task"],Ei=["task","checks","pr","setup-run","actions","next-action"],Ai=["diff","files","review"];function $i(e,t={}){let n=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,r=bu(e?.openInspectionKind)??n,s=b.runners.getEnabled(t);return{inputMode:Su(e?.inputMode),focusedRegion:yu(e?.focusedRegion),selectedRepoId:Ie(e?.selectedRepoId),selectedWorkspaceId:Ie(e?.selectedWorkspaceId),selectedTaskId:Ie(e?.selectedTaskId),selectedPtyTabId:Ie(e?.selectedPtyTabId),selectedLeftItemId:Lu(Ie(e?.selectedTaskId)),activeTab:n?D:Ie(e?.activeTab)??"agent",preferredPtyTabKind:Iu(e?.preferredPtyTabKind),inspectorSection:Tt(e?.inspectorSection,Ei,"task"),inspectionMode:Pu(e?.inspectionMode,n==="diff"?"diff":"files"),openInspectionKind:r,selectedFileTreePath:Ie(e?.selectedFileTreePath),selectedFilePath:Ie(e?.selectedFilePath),selectedDiffPath:Ie(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:Tt(e?.selectedActionId,vi,"commit"),selectedProjectTargetId:null,selectedRunner:Cu(e?.selectedRunner,s,b.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:cu(),centerZoomed:!1}}function cu(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function Di(e,t){return{...e??Re(),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 rn(e,t,n={}){let r=Du(e,t),s=_i(r),o=(s?.kind==="workspace"?t.workspaces?.find(f=>f.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(f=>f.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,c=((s?.kind==="repo"?t.repos.find(f=>f.id===s.id)??null:s?.kind==="task"?t.repos.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(f=>f.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(f.id))??null:null)??(o?.kind!=="project"?t.repos.find(f=>f.id===o?.primaryRepoId)??null:null)??t.repos.find(f=>f.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(f=>f.workspaceId===o.id):c?t.tasks.filter(f=>f.repoId===c):[],d=(s?.kind==="task"?l.find(f=>f.id===s.id)??null:null)??l.find(f=>f.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:n.resetInputMode?"control":e.inputMode,selectedLeftItemId:r,selectedWorkspaceId:o?.id??null,selectedRepoId:c,selectedTaskId:d?.id??null,...vu(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:ku(e,t,d?.id??null),...Eu(e,t,d?.id??null),selectedDiffPath:wu(e,t,d?.id??null),inspectorSection:Tt(e.inspectorSection,Ei,"task")}}function Mi(e,t,n={leftItemIds:[]}){if(e.inputMode==="terminal")return lu(t)?I({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):I({state:e});if(t==="q"||t==="Q")return I({state:e,exit:!0});if(t==="ESCAPE")return I({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return I({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(Cr(e.selectedLeftItemId)||xr(e.selectedLeftItemId)))return I({state:{...e,selectedRunner:vr(e.selectedRunner,n.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return yi(e,1);if(t==="SHIFT_TAB"||t==="[")return yi(e,-1);if(t==="z"||t==="Z")return I({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===D?Me(e,-1,n):Pi(e,-1,n);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===D?Me(e,1,n):Pi(e,1,n);if(t==="PAGE_UP")return Me(e,-(n.pageRows??10),n);if(t==="PAGE_DOWN")return Me(e,n.pageRows??10,n);if(t==="MOUSE_WHEEL_UP")return Me(e,-3,n);if(t==="MOUSE_WHEEL_DOWN")return Me(e,3,n);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let r=n.enabledRunnerIds??F,s=e.centerTabRunner?r.indexOf(e.centerTabRunner):-1,o=s===r.length-1?null:r[s+1];return I({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let r=xu(e,t);return I({state:{...e,preferredPtyTabKind:r,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:r,createPtyTabRunner:r==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return I({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return I({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return I({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&nn(e.selectedLeftItemId)&&e.selectedTaskId)return I({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Ou(e.selectedLeftItemId)&&e.selectedWorkspaceId)return I({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Si(e.activeTab,n.ptyTabIds??[]))return I({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Sr(e,-1,n.centerTabIds);if(e.focusedRegion==="inspector")return bi(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Sr(e,1,n.centerTabIds);if(e.focusedRegion==="inspector")return bi(e,1)}if(Ce(t)){if(e.focusedRegion==="tasks"&&(Cr(e.selectedLeftItemId)||xr(e.selectedLeftItemId))){let r=Bi(e.selectedLeftItemId),s=Ui(e.selectedLeftItemId);return I({state:{...e,selectedRepoId:r??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return I({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&nn(e.selectedLeftItemId)&&e.selectedTaskId){let r=e.selectedPtyTabId??e.activeTab;return I({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:r,selectedPtyTabId:r,preferredPtyTabKind:yt(r)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Si(e.activeTab,n.ptyTabIds??[])&&e.selectedTaskId)return I({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:yt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===D)return I({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let r=e.selectedFileTreePath??e.selectedFilePath;if(r&&(n.fileTreeDirectoryIds??[]).includes(r))return I({state:mu({...e,selectedFileTreePath:r}),changed:!0});let s=r&&(n.fileTreeFileIds??[]).includes(r)?r:e.selectedFilePath;return I({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:D,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?I({state:{...e,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!n.projectTargetIds?.length?I({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):I({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?I({state:e}):e.selectedActionId==="refresh-checks"?I({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?I({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):I({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return I({state:e})}function Ve(e,t){return{...e,terminal:t}}function Li(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function lu(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Ce(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
142
+ `}function Oi(e){return e.length===1&&e>=" "&&e!=="\x7F"}function Fi(e){return ji(e)||yt(e)!==null}function du(e){return xi.includes(e)}function ji(e){return Ci.includes(e)}function Ni(e,t){return[...e?.ptyTabs.map(n=>n.id)??[],...t?.openInspectionKind?[D]:[]]}var uu=["tasks","center","inspector"];function yi(e,t){return en(e,"focusedRegion",uu,t)}function Sr(e,t,n){let r=en(e,"activeTab",n&&n.length>0?n:$u(e),t);return!r.changed||du(r.state.activeTab)?r:{...r,state:{...r.state,selectedPtyTabId:r.state.activeTab,preferredPtyTabKind:yt(r.state.activeTab)??r.state.preferredPtyTabKind}}}function Pi(e,t,n){if(e.focusedRegion==="tasks")return fu(e,t,n.leftItemIds);if(e.focusedRegion==="center")return Sr(e,t,n.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Wi(e,t,n);if(e.inspectionMode==="diff"){let r=tn(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:r}if(n.projectTargetIds?.length){let r=tn(e,"selectedProjectTargetId",n.projectTargetIds,t);return r.changed?{...r,state:{...r.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:r}return en(e,"selectedActionId",au,t)}return en(e,"selectedActionId",vi,t)}function fu(e,t,n){let r=tn(e,"selectedLeftItemId",n,t);if(!r.changed)return r;let s=_i(r.state.selectedLeftItemId);if(s?.kind==="workspace")return{...r,state:{...r.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...r,state:{...r.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...r,state:{...r.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=Bi(r.state.selectedLeftItemId);if(o)return{...r,state:{...r.state,selectedRepoId:o}};let i=Ui(r.state.selectedLeftItemId);return i?{...r,state:{...r.state,selectedWorkspaceId:i}}:r}function Me(e,t,n){if(t===0)return I({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Wi(e,t,n);if(e.inspectionMode==="diff"){let r=tn(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,diffScrollOffset:0}}:r}return e.inspectionMode==="review"?Ii(e,"reviewScrollOffset",t,n.reviewRowCount??100,n.pageRows):I({state:e})}if(e.focusedRegion==="center"&&e.activeTab===D){if(e.openInspectionKind==="file")return Ii(e,"fileScrollOffset",t,n.fileLineCount??0,n.pageRows);if(e.openInspectionKind==="diff")return gu(e,t,n)}return I({state:e})}function pu(e,t){if(e.inspectionMode===t)return I({state:e});let n=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,r=t==="diff"||t==="files"?D:e.activeTab;return I({state:{...e,inspectionMode:t,activeTab:r,openInspectionKind:n,fileScrollOffset:t==="files"?0:e.fileScrollOffset,diffScrollOffset:t==="diff"?0:e.diffScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function bi(e,t){return pu(e,Tu(e.inspectionMode,Ai,t))}function Wi(e,t,n){let r=n.fileTreeRowIds&&n.fileTreeRowIds.length>0?n.fileTreeRowIds:n.filePathIds??[];if(r.length===0)return I({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??r[0]??null,o=r.indexOf(s??""),i=Se(o===-1?0:o+t,0,r.length-1),c=r[i]??null;if(c===e.selectedFileTreePath)return I({state:e});let l=c!==null&&(n.fileTreeFileIds??n.filePathIds??[]).includes(c);return I({state:{...e,selectedFileTreePath:c,selectedFilePath:l?c:e.selectedFilePath,activeTab:l?D:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function mu(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((n,r)=>n.localeCompare(r)),actionMessage:null}}function Ii(e,t,n,r,s=10){let o=Math.max(0,r-Math.max(1,s)),i=Se(e[t]+n,0,o);return i===e[t]?I({state:e}):I({state:{...e,[t]:i,actionMessage:null},changed:!0})}function gu(e,t,n){if(n.diffPathRanges&&n.diffPathRanges.length>0)return hu(e,t,n);let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=e.diffScrollOffset+t,c=n.diffPathIds??[];if(c.length===0||!e.selectedDiffPath){let f=Se(i,0,o);return f===e.diffScrollOffset?I({state:e}):I({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}let l=c.indexOf(e.selectedDiffPath);if(l===-1){let f=Se(i,0,o);return f===e.diffScrollOffset?I({state:e}):I({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}if(t>0&&i>o){let f=c[l+1]??null;return f?I({state:{...e,selectedDiffPath:f,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?I({state:e}):I({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let f=c[l-1]??null;return f?I({state:{...e,selectedDiffPath:f,activeTab:D,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?I({state:e}):I({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=Se(i,0,o);return d===e.diffScrollOffset?I({state:e}):I({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function hu(e,t,n){let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=Se(e.diffScrollOffset+t,0,o),c=Ru(n.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&c===e.selectedDiffPath?I({state:e}):I({state:{...e,diffScrollOffset:i,selectedDiffPath:c,actionMessage:null},changed:!0})}function wu(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function ku(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function Ru(e,t){return e.find(n=>t>=n.start&&t<n.end)?.path??e.at(-1)?.path??null}function en(e,t,n,r){let s=n.indexOf(e[t]),o=Se(s+r,0,n.length-1),i=n[o];return!i||i===e[t]?I({state:e}):I({state:{...e,[t]:i,actionMessage:null},changed:!0})}function tn(e,t,n,r,s=!1){if(n.length===0)return I({state:e});let o=n.indexOf(e[t]??n[0]??""),i=Se(o===-1?0:o+r,0,n.length-1),c=n[i]??null;return c===e[t]?I({state:e}):I({state:{...e,[t]:c,actionMessage:null},changed:!0,refreshInspection:s})}function Tu(e,t,n){let r=t.indexOf(e);return t[Se(r+n,0,t.length-1)]??e}function I(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 Tt(e,t,n){return t.includes(e??"")?e:n}function yu(e){return e==="tabs"?"center":Tt(e,iu,"tasks")}function Pu(e,t){return e==="checks"||e==="actions"||e==="review"?"review":Tt(e,Ai,t)}function bu(e){return e==="file"||e==="diff"?e:null}function Iu(e){return e==="terminal"?"terminal":"agent"}function Su(e){return e==="terminal"?"terminal":"control"}function Cu(e,t=[...F],n="codex"){return e&&b.runners.isRunnerType(e)&&t.includes(e)?e:n}function vr(e,t=F){let n=t.length>0?t:F,r=n.indexOf(e);return n[(r+1)%n.length]??n[0]??"codex"}function yt(e){let t=F.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function xu(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":yt(e.activeTab)??e.preferredPtyTabKind}function vu(e,t,n){if(!e)return{activeTab:t===D?t:"agent",selectedPtyTabId:null};let r=e.ptyTabs.find(c=>c.id===n)??null,s=e.selectedPtyTabId?e.ptyTabs.find(c=>c.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(c=>c.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(ji(t)){let l=e.ptyTabs.find(d=>d.kind===t)??null??s??r??e.ptyTabs[0]??null;return{activeTab:l?.id??D,selectedPtyTabId:l?.id??null}}if(t===D)return{activeTab:D,selectedPtyTabId:r?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??r??e.ptyTabs[0]??null;return{activeTab:i?.id??D,selectedPtyTabId:i?.id??null}}function Eu(e,t,n){if(!t.inspection||t.inspection.taskId!==n)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let r=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?Au(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:r,collapsedFileTreePaths:s}}function Au(e,t){let n=new Set;if(t){let r=t.split("/");for(let s=1;s<r.length;s+=1)n.add(r.slice(0,s).join("/"))}return e.filter(r=>r.kind==="directory"&&!r.path.includes("/")&&!n.has(r.path)).map(r=>r.path).sort((r,s)=>r.localeCompare(s))}function $u(e){return[e.selectedPtyTabId,e.openInspectionKind?D:null].filter(t=>typeof t=="string")}function Si(e,t){return t.includes(e)}function Du(e,t){let n=Mu(t);return e.selectedLeftItemId&&n.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&n.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&n.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&n.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:n[0]??null}function Mu(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function _i(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 Ie(e){return typeof e=="string"?e:null}function Lu(e){return e?`task:${e}`:null}function nn(e){return typeof e=="string"&&e.startsWith("task:")}function Cr(e){return typeof e=="string"&&e.startsWith("new-task:")}function xr(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function Ou(e){return typeof e=="string"&&e.startsWith("workspace:")}function Bi(e){return Cr(e)?e.slice(9):null}function Ui(e){return xr(e)?e.slice(19):null}function Se(e,t,n){return Math.min(n,Math.max(t,e))}var on="empty",q={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Gi(e,t){let n=Nu(t,e),r=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=n?t.tasks.filter(T=>T.workspaceId===n.id):t.tasks,o=n?.kind==="project"?s:r?s.filter(T=>T.repoId===r.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,c=i?.type==="project",l=yf(t.tasks),d=Bu(e,i),f=_u(e,i,d),h=f.find(T=>T.id===d)??f[0]??{id:"agent",label:"CODEX"},R=t.inspection?.taskId===i?.id?t.inspection:null,k=r?.name??"no repo",S=i?b.runners.getDisplayName(i.runner):b.runners.getDisplayName(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${r?`[${r.name}]`:"[no repo]"} \xB7 ${b.runners.getDisplayName(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${b.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:nn(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?i===null?"n new task Tab tasks Esc pause ? help":d===D?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${b.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?c?"\u2191\u2193 targets Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?"\u2191\u2193 navigate Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:Pt.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Pt.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:S},leftTree:Fu(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>Pf(T,l[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":h.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:k,agent:S},centerTranscript:Wu(d,e,r,i,e.workspaceBrowser,R,n),tabs:f,rightContext:Tf(r,i),rightInspection:ef(e,i,R)}}function Fu(e,t){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return ju(n,e,t.repos,t.tasks);let r=t.workspaces;if(r.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of r){let i=e.selectedLeftItemId===`workspace:${o.id}`;n.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:i,focused:i&&e.focusedRegion==="tasks"});let c=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],l=t.tasks.filter(d=>d.workspaceId===o.id);if(l.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of l){let f=e.selectedLeftItemId===`task:${d.id}`,h=f?"\u25B8":"\u2022",R=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,k={id:`task:${d.id}`,taskId:d.id,text:`${h} ${R}`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks"},S=zi(d);S&&(k.prBadge=S),n.push(k)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}else{n.push({text:` Repos (${c.length})`,indent:0,muted:!0});for(let d of c.slice(0,6)){let f=t.repos.find(h=>h.id===d);n.push({text:` \xB7 ${f?.name??d}`,indent:0,muted:!0})}c.length>6&&n.push({text:` \xB7 ${c.length-6} more`,indent:0,muted:!0})}}let s=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&e.focusedRegion==="tasks"}),n}function ju(e,t,n,r){if(n.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of n){let i=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:i,focused:i&&t.focusedRegion==="tasks"});let c=r.filter(f=>f.repoId===o.id);if(c.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let f of c){let h=t.selectedLeftItemId===`task:${f.id}`,R=h?"\u25B8":"\u2022",k=f.title.length>28?`${f.title.slice(0,25)}\u2026`:f.title,S={id:`task:${f.id}`,taskId:f.id,text:`${R} ${k}`,indent:2,selected:h,focused:h&&t.focusedRegion==="tasks"},T=zi(f);T&&(S.prBadge=T),e.push(S)}let l=`new-task:${o.id}`,d=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${b.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let s=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&t.focusedRegion==="tasks"}),e}function Nu(e,t){let n=e.workspaces??[];if(!e.workspaces)return null;let r=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return r?n.find(s=>s.id===r.workspaceId)??null:t.selectedWorkspaceId?n.find(s=>s.id===t.selectedWorkspaceId)??null:n[0]??null}function Wu(e,t,n,r,s,o=null,i=null){if(s){let l=s.entries.length===0?["No directories or git repos here."]:s.entries.map((d,f)=>{let h=f===s.selectedIndex?"\u25B8":" ",R=d.kind==="repo"?" [git repo]":"/";return`${h} ${d.name}${R}`});return me(["Browse for a workspace to register.",s.cwd,"",...l,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!n)return me(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!r){let l=i?.kind==="project",d=l?i.name??"this workspace":n.name,f=l?"Project Task":"Task";return me([`No tasks in ${d}.`,"",`Press n or choose + New ${f} to create one with ${b.runners.getDisplayName(t.selectedRunner)}.`])}let c=r.ptyTabs.find(l=>l.id===e)??null;return c?c.kind==="agent"?me([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):me([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===D&&t.openInspectionKind==="file"?Ku(r,o,t.fileScrollOffset):e===D&&t.openInspectionKind==="diff"?Vu(r,o,t.diffScrollOffset):r.ptyTabs.length===0&&!t.openInspectionKind?me(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):me(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function _u(e,t,n){let r=t?.ptyTabs.map(o=>({id:o.id,label:Uu(o)}))??[];if(!t)return[{id:on,label:"EMPTY",active:n===on,focused:e.focusedRegion==="center"&&n===on}];let s=e.openInspectionKind||n===D?[{id:D,label:qu(e)}]:[];return[...r,...s].map(o=>({...o,active:o.id===n,focused:e.focusedRegion==="center"&&o.id===n}))}function Bu(e,t){return t?t.ptyTabs.some(n=>n.id===e.activeTab)||e.activeTab===D&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(n=>n.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??D:e.selectedPtyTabId&&t.ptyTabs.some(n=>n.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??D:on}function Uu(e){return e.title.toUpperCase()}function qu(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,n=t?Pt.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${n} \u0394`:n}function Ku(e,t,n){if(!e)return me(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return me(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let r=t.selectedFile,s=Hi(r.path??r.title);return[{text:r.title},{text:`${r.byteLength===null?"size unknown":`${r.byteLength} bytes`} \xB7 ${r.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Gu(r.lines,n,s)]}function Vu(e,t,n){if(!e)return me(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return me(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let r=t.selectedDiff,s=Hi(r.path??r.title);return[{text:r.title},{text:`${t.diffPaths.length} changed files \xB7 ${r.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Hu(r.lines,n,s)]}function me(e){return e.map(t=>({text:t}))}function Gu(e,t,n){let r=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let c=s+i+1;return{text:`${`${String(c).padStart(r," ")} \u2502 `}${o}`,segments:[{text:String(c).padStart(r," "),style:{fg:q.lineNumber}},{text:" \u2502 ",style:{fg:q.gutter}},...Er(o,n)],tone:"default"}})}function Hu(e,t,n){let r=zu(e),s=Math.max(0,Math.min(t,Math.max(0,r.length-1)));return r.slice(s).map(o=>Yu(o,n))}function zu(e){let t=[],n=0,r=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){n=Number.parseInt(o[1]??"0",10),r=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:n,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),n+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:r,marker:"+",text:s.slice(1),kind:"add"}),r+=1;continue}if(s.startsWith(" ")){if(n===0&&r===0)continue;t.push({oldNumber:n,newNumber:r,marker:" ",text:s.slice(1),kind:"context"}),n+=1,r+=1;continue}}}return t}function Yu(e,t){let n=qi(e.oldNumber),r=qi(e.newNumber),s=e.kind==="delete"?n:r,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:q.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:q.diffAdd}:null,i=`${s} \u2502 ${e.text}`,c=o?Qu(Er(e.text,t),o.bg,o.fallbackFg):Er(e.text,t),l=o?{fg:q.lineNumber,bg:o.bg}:{fg:q.lineNumber},d=o?{fg:q.gutter,bg:o.bg}:{fg:q.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...c],fullBleed:o!==null}}function qi(e){return e===null?" ":String(e).padStart(4," ")}function Hi(e){let t=Pt.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 Er(e,t){return t==="diff"?Ju(e):t==="markdown"?Xu(e):t==="json"?Ar(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Ar(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 Ju(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:q.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:q.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:q.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:q.diffMeta}}]:[{text:e}]}function Qu(e,t,n){return e.map(r=>({text:r.text,style:{...r.style??{fg:n},bg:t}}))}function Xu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:q.markup,bold:!0}}]:Ar(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Ar(e,t){let n=[],r=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>r&&n.push({text:e.slice(r,i)}),n.push({text:o,style:Zu(o)}),r=i+o.length}return r<e.length&&n.push({text:e.slice(r)}),n.length>0?n:[{text:e}]}function Zu(e){return e.startsWith("//")||e.startsWith("/*")?{fg:q.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:q.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:q.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:q.markup}:{fg:q.keyword}}function ef(e,t,n){let r=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&r?t.repoTargets?.find(c=>c.repoId===r)??null:null,o=t?.type==="project"?Yi(t.repoTargets??[]):s?.pullRequest??(t?G(t):null),i=[tf(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Xi(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,...gf(e,n)]}:{title:"",rows:[...i,...wf(e,n)]}}function tf(e,t){let n=e.inspectionMode,r=[{label:"CHANGES",active:n==="diff"},{label:"FILES",active:n==="files"},{label:"REVIEW",active:n==="review"}],s=[];for(let l=0;l<r.length;l++){let d=r[l];l>0&&s.push({text:" "});let f=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:f}})}let o=$r(t),i=Dr(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function Ki(e){return[{text:" "},$r(e),{text:" "},Dr(e)]}function zi(e){if(e.type==="project"&&e.repoTargets?.length){let n=Yi(e.repoTargets);return n?Ki(n):null}let t=G(e);return t?.number?Ki(t):null}function Yi(e){let t=e.filter(s=>s.status==="ready"),n=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(n.length===0)return null;let r=rf(n);return{number:-1,status:nf(n),draft:n.some(s=>s.draft),mergeable:n.length===t.length&&n.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:n.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":n.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":n.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:n.flatMap(s=>s.requiredChecks),aggregateReadiness:r}}function nf(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 rf(e){let t=e.map(n=>Ji(n));return t.some(n=>n==="failed")?"failed":t.some(n=>n==="pending")?"pending":t.length>0&&t.every(n=>n==="success")?"success":"none"}function $r(e){return!e||!e.number?{text:wi,style:{fg:"565f89"}}:e.status==="merged"?{text:ki,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Ri,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Tr,style:{fg:"565f89"}}:{text:Tr,style:{fg:"9ece6a"}}}function Dr(e){return e?.aggregateReadiness?Vi(e.aggregateReadiness):Vi(Ji(e))}function Vi(e){return e==="failed"?{text:Ir,style:{fg:"f7768e"}}:e==="pending"?{text:Pr,style:{fg:"e0af68"}}:e==="success"?{text:br,style:{fg:"9ece6a"}}:{text:yr,style:{fg:"565f89"}}}function Ji(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(n=>n.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(n=>n.status==="success"||n.status==="skipped")?Qi(e)?"failed":sf(e)?"success":"pending":"pending"}function sf(e){return!!(e.mergeable&&!e.draft&&!Qi(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Qi(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Xi(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return of(e,t);let n=G(t),r=ea("pr",t.branch,n??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==n&&(o.status==="merged"||o.status==="closed")).length;return s>0&&r.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),af(r,e)}var sn=32;function of(e,t){let n=[],r=t.repoTargets??[],s=e.selectedProjectTargetId??r[0]?.repoId??null;for(let i of r){let c=s===i.repoId,l=e.focusedRegion==="inspector"&&c,d=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let h=i.failureReason?i.failureReason.slice(0,14):i.status,R=sn-h.length-1,k=d.length>R?d.slice(0,R-1)+"\u2026":d,S=sn-k.length-h.length;n.push({id:`project-review:${i.repoId}`,text:k+" ".repeat(Math.max(1,S))+h,selected:c,focused:l,muted:!0})}else{let f=$r(i.pullRequest),h=Dr(i.pullRequest),R=`${f.text} ${h.text}`,k=sn-R.length-1,S=d.length>k?d.slice(0,k-1)+"\u2026":d,T=sn-S.length-R.length,a=S+" ".repeat(Math.max(1,T));n.push({id:`project-review:${i.repoId}`,text:a+R,selected:c,focused:l,segments:[{text:a},{...f,text:f.text},{text:" "},{...h,text:h.text}]})}}let o=r.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(n.push({id:"target-detail-spacer",text:""}),n.push(...ea("target",o.branch,o.pullRequest))),n}function Zi(e,t){return Xi(e,t).length}function ea(e,t,n){let r=h=>`${e}-${h}`;if(!n.number)return[{id:r("no-pr"),text:t,muted:!0}];let s=[],o=`#${n.number}`;s.push(n.url?{id:r("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:n.url}]}:{id:r("pr-number"),text:o});let i=n.baseBranch??"?",c=n.headBranch??t;s.push({id:r("pr-branches"),text:`${i} \u2192 ${c}`,muted:!0});let l=cf(n.reviewDecision,n.mergeStateStatus),d=l&&l!=="review approved"?"merge blocked":n.mergeable?"merge ready":n.mergeStateStatus?`merge ${n.mergeStateStatus}`:"merge unknown";l?s.push({id:r("pr-merge"),text:`${d} \xB7 ${l}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:l,style:{fg:lf(n.reviewDecision,n.mergeStateStatus)}}]}):s.push({id:r("pr-merge"),text:d,muted:!0}),s.push({id:r("pr-synced"),text:`synced ${ta(n.lastSyncedAt)}`,muted:!0}),s.push({id:r("checks-spacer"),text:""}),s.push({id:r("checks-header"),text:"Checks"}),n.requiredChecks.length?s.push(...n.requiredChecks.map(df)):s.push({id:r("checks-none"),text:n.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let f=n.comments??[];return f.length>0&&(s.push({id:r("comments-spacer"),text:""}),s.push({id:r("comments-header"),text:`Review comments (${f.length})`}),s.push(...f.slice(-4).flatMap((h,R)=>uf(h,r(`comment:${R}`))))),s}function af(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let n=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((r,s)=>({...r,selected:t.reviewScrollOffset===0&&r.selected||s===n,focused:t.reviewScrollOffset===0&&r.focused||s===n}))}function cf(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function lf(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function ta(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;let r=Math.floor(n/60);if(r<60)return`${r}m ago`;let s=Math.floor(r/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function df(e){let{icon:t,color:n}=pf(e.status),r=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${r.padEnd(16," ")} ${mf(e.status)}`,color:n,muted:!1}}function uf(e,t){let n=e.author??"unknown",r=e.createdAt?` \xB7 ${ta(e.createdAt)}`:"",s=ff(e.body,30),o=s.slice(0,4),i=o.length<s.length,c=[{id:`${t}:author`,text:`${n}${r}`,muted:!0},...o.map((l,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return c.push({id:`${t}:spacer`,text:"",muted:!0}),c}function ff(e,t){let n=e.split(/\s+/).filter(Boolean);if(n.length===0)return[];let r=[],s="";for(let o of n){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(r.push(s),s=o)}return s&&r.push(s),r}function pf(e){switch(e){case"success":return{icon:br,color:"9ece6a"};case"pending":return{icon:Pr,color:"e0af68"};case"failed":return{icon:Ir,color:"f7768e"};case"skipped":return{icon:yr,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function mf(e){return e==="success"?"passing":e==="failed"?"failing":e}function gf(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let n=new Map(t.diffRows.map(o=>[o.path,o.status])),r=hf(t.fileRows,e.collapsedFileTreePaths),s=e.selectedFileTreePath??t.selectedFilePath;return r.map(o=>{let i=o.kind==="file"?n.get(o.path):void 0,c=i==="A"?"9ece6a":i==="M"?"e0af68":i==="D"?"f7768e":i==="??"?"565f89":void 0,l=o.kind==="directory"?e.collapsedFileTreePaths.includes(o.path)?gi:hi:mi(o.label),d=o.kind==="directory"?"7aa2f7":Ti(o.label),f=" ".repeat(o.depth),h=d?{text:l,style:{fg:d}}:{text:l},R=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:c?{text:o.label,style:{fg:c}}:{text:o.label},k=[{text:f},h,R];return{id:o.path,text:`${f}${l}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:k}})}function hf(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function wf(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(kf(t))return Rf(e,t);let n=[];for(let r of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===r);s.length!==0&&(n.push({id:r,text:r.toUpperCase(),muted:!0}),n.push(...s.map(o=>na(o,e,t))))}return n}function kf(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Rf(e,t){let n=[],r=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of r){let o=t.diffRows.filter(c=>c.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;n.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let c of["branch","staged","unstaged","untracked"]){let l=o.filter(d=>d.group===c);l.length!==0&&(n.push({id:`repo-diff:${s}:${c}`,text:` ${c}`,muted:!0}),n.push(...l.map(d=>na(d,e,t,s.length+1))))}}return n}function na(e,t,n,r=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",c=r>0?e.path.slice(r):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${c} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??n.selectedDiffPath),focused:e.path===(t.selectedDiffPath??n.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function Tf(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:b.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Pt.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 yf(e){return e.reduce((t,n)=>(t[n.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Pf(e,t){return{name:b.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var an={width:120,height:36},ge={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function Le(e,t){return{width:Math.max(e??an.width,an.width),height:Math.max(t??an.height,an.height)}}import{spawn as Vf}from"node:child_process";import{createHash as Gf}from"node:crypto";import{createServer as Hf,createConnection as ua}from"node:net";import{openSync as zf}from"node:fs";import{mkdir as Yf,readFile as Wr,rm as Ge,writeFile as Jf}from"node:fs/promises";import{tmpdir as Qf}from"node:os";import nt from"node:path";import{createRequire as Df}from"node:module";import bf from"@xterm/headless";var If=1e3,Sf=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function sa(e){return new bf.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:If,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function oa(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Lr(e,t){return new Promise(n=>{e.write(t,n)})}function ia(e,t=0){let n=e.buffer.active,r=[],s=n.getNullCell(),o=n.baseY+n.cursorY,i=Math.max(0,n.baseY-t);for(let c=0;c<e.rows;c+=1){let l=n.getLine(i+c);if(!l){r.push({segments:[]});continue}let d=[];for(let f=0;f<e.cols;f+=1){let h=l.getCell(f,s);!h||h.getWidth()===0||d.push({text:h.getChars()||" ",style:vf(h,i+c===o&&f===n.cursorX)})}r.push({segments:Cf(xf(d))})}return r}function Cf(e){let t=[];for(let n of e){let r=t.at(-1);if(r&&$f(r.style,n.style)){r.text+=n.text;continue}let s={text:n.text};aa(n.style)||(s.style=n.style),t.push(s)}return t}function xf(e){let t=e.length;for(;t>0;){let n=e[t-1];if(!n||n.text!==" "||!aa(n.style))break;t-=1}return e.slice(0,t)}function vf(e,t){let n={},r=ra(e,"fg"),s=ra(e,"bg");return r&&(n.fg=r),s&&(n.bg=s),e.isBold()&&(n.bold=!0),e.isDim()&&(n.dim=!0),e.isItalic()&&(n.italic=!0),e.isUnderline()&&(n.underline=!0),(e.isInverse()||t)&&(n.inverse=!0),n}function ra(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let r=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return r?s.toString(16).padStart(6,"0"):Sf[s]??Ef(s)}function Ef(e){if(e>=16&&e<=231){let t=e-16,n=Math.floor(t/36),r=Math.floor(t%36/6),s=t%6;return[n,r,s].map(Af).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(n=>n.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function Af(e){return e===0?0:55+e*40}function $f(e,t){return Mr(e)===Mr(t)}function Mr(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function aa(e){return Mr(e)===""}var Mf=Df(import.meta.url),Lf=/^CTRL_([A-Z])$/,Of="\x1B[6n",Ff="\x1B[c",jf="\x1B[?u",Nf={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
143
+ `,TAB:" ",SHIFT_TAB:"\x1B[Z",BACK_TAB:"\x1B[Z",BACKSPACE:"\x7F",DELETE:"\x1B[3~",ESCAPE:"\x1B",UP:"\x1B[A",DOWN:"\x1B[B",RIGHT:"\x1B[C",LEFT:"\x1B[D",HOME:"\x1B[H",END:"\x1B[F",PAGE_UP:"\x1B[5~",PAGE_DOWN:"\x1B[6~",CTRL_C:"",CTRL_D:""},cn=class{sessions=new Map;shell;env;spawn;onUpdate;resolveSessionSpec;attachedTabId=null;constructor(t){this.shell=t.shell??process.env.SHELL??"/bin/zsh",this.env=t.env??process.env,this.spawn=t.spawn,this.onUpdate=t.onUpdate,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,n,r,s){let o=this.sessions.get(n);if(o)if(o.status!=="running")Or(o),this.sessions.delete(n);else return this.attachedTabId=n,o.scrollbackLines=0,ca(o,r),this.getViewState(n);let i=this.createSession(t,n,r,s);return this.sessions.set(n,i),this.attachedTabId=n,this.getViewState(n)}write(t){let n=this.getAttachedSession();!n||n.status!=="running"||n.pty.write(t)}writeKey(t){let n=Wf(t);n!==null&&this.write(n)}scrollViewport(t){let n=this.getAttachedSession();if(!n||t===0)return;let r=n.terminal.buffer.active.baseY;n.scrollbackLines=Math.max(0,Math.min(r,n.scrollbackLines-t))}resize(t){let n=this.getAttachedSession();n&&ca(n,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let n=this.sessions.get(t);n&&(Or(n),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Or(t);this.sessions.clear(),this.attachedTabId=null}getViewState(t){if(!t)return{status:"idle",rows:[],error:null,scrolledBack:!1};let n=this.sessions.get(t);return n?{status:n.status,rows:ia(n.terminal,n.scrollbackLines),error:n.error,scrolledBack:n.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,n,r,s){let o=this.spawn??Bf().spawn,i=sa(r),c=s??this.resolveSessionSpec(t,n),l=_e({...this.env,...c.env??{}}),{executable:d,args:f}=Uf(this.shell,c.command,{cwd:c.cwd,env:l}),h=o(d,f,{name:"xterm-256color",cols:r.columns,rows:r.rows,cwd:c.cwd,env:qf(l)}),R={taskId:t,tabId:n,pty:h,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0};return R.disposables.push(h.onData(k=>{Kf(h,k),Lr(R.terminal,k).then(()=>{this.onUpdate?.(R.tabId)})})),R.disposables.push(h.onExit(k=>{R.status="exited",Lr(R.terminal,`\r
144
+ [process exited ${k.exitCode}]`).then(()=>{this.onUpdate?.(R.tabId)})})),R}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function Wf(e){if(e.length===1)return e;let t=Nf[e];if(t!==void 0)return t;let n=Lf.exec(e);return n?.[1]?String.fromCharCode(n[1].charCodeAt(0)-64):null}function ca(e,t){_f(e.pty,t),oa(e.terminal,t)}function Or(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function _f(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Bf(){return Mf("node-pty")}function Uf(e,t,n){if(t.length===0)return{executable:e,args:[]};let s=`${[Be(t[0],n),...t.slice(1)].map(la).join(" ")}; exec ${la(e)} -l`;return{executable:e,args:["-lc",s]}}function la(e){return`'${e.replaceAll("'","'\\''")}'`}function qf(e){let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&(t[n]=r);return t.TERM=t.TERM??"xterm-256color",t}function Kf(e,t){for(let n=0;n<Fr(t,Of);n+=1)e.write("\x1B[1;1R");for(let n=0;n<Fr(t,Ff);n+=1)e.write("\x1B[?1;2c");for(let n=0;n<Fr(t,jf);n+=1)e.write("\x1B[?0u")}function Fr(e,t){if(t.length===0)return 0;let n=0,r=e.indexOf(t);for(;r!==-1;)n+=1,r=e.indexOf(t,r+t.length);return n}var _r=3;async function fa(e){let t=Br(e.paths);await Xf(t,e.paths,e.spawnDaemon);let n=await ka(t.socketPath),r=new jr(n,e);return await r.ready(),r}async function pa(e,t={}){let n=Br(e);await Yf(e.runtimeDir,{recursive:!0}),await Ge(n.socketPath,{force:!0});let r=new Nr(e,t),s=Hf(o=>r.handleConnection(o));await sp(s,n.socketPath),await Jf(n.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=()=>{r.closeClients(),s.close(()=>o())};r.onShutdown=i,process.once("SIGTERM",i),process.once("SIGINT",i)}),await Ge(n.socketPath,{force:!0}),await Ge(n.pidPath,{force:!0}),r.disposeAll()}async function ma(e){let t=Br(e);return await dn(t.socketPath)?(await ha(t.socketPath),!0):!1}var jr=class{constructor(t,n){this.socket=t;this.options=n,t.setEncoding("utf8"),t.on("data",r=>this.handleData(String(r))),t.on("error",r=>this.rejectAll(r instanceof Error?r:new Error(String(r)))),t.on("close",()=>{this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed."))})}socket;nextRequestId=1;pending=new Map;viewCache=new Map;attachedTabId=null;buffer="";closed=!1;options;async ready(){if((await this.send({type:"ping"})).protocolVersion!==_r)throw new Error("Craig PTY daemon protocol mismatch.")}async ensureSession(t,n,r){let s=await this.send({type:"ensureSession",taskId:t,tabId:n,size:r,spec:this.options.resolveSessionSpec?.(t,n)??{cwd:this.options.workspaceRoot,command:[]}});this.attachedTabId=n;let o=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(n,o),o}async hydrateSessions(t){for(let n of t)try{let r=await this.send({type:"hydrateSession",tabId:n});r.view&&this.viewCache.set(n,r.view)}catch(r){let s=r instanceof Error?r.message:String(r);this.viewCache.set(n,{status:"failed",rows:[],error:s})}}async pruneStale(t){await this.send({type:"pruneStale",keepTabIds:t})}write(t){this.send({type:"write",input:t}).catch(()=>{})}writeKey(t){this.send({type:"writeKey",key:t}).catch(()=>{})}scrollViewport(t){this.send({type:"scrollViewport",lines:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}resize(t){this.send({type:"resize",size:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}detach(){this.attachedTabId=null,this.send({type:"detach"}).catch(()=>{})}disposeSession(t){this.viewCache.delete(t),this.attachedTabId===t&&(this.attachedTabId=null),this.send({type:"disposeSession",tabId:t}).catch(()=>{})}disposeAll(){this.attachedTabId=null,!this.closed&&(this.socket.end(),this.closed=!0)}getViewState(t){return t?this.viewCache.get(t)??{status:"idle",rows:[],error:null,scrolledBack:!1}:{status:"idle",rows:[],error:null,scrolledBack:!1}}async requestShutdown(){await this.send({type:"shutdown"})}async send(t){if(this.closed)throw new Error("Craig PTY daemon connection is closed.");let n=this.nextRequestId;this.nextRequestId+=1;let r={...t,id:n},s=new Promise((i,c)=>{this.pending.set(n,{resolve:i,reject:c})});if(this.socket.destroyed)throw this.pending.delete(n),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(r)}
145
145
  `);let o=await s;if(!o.ok)throw new Error(o.error);return o}handleData(t){this.buffer+=t;let n=this.buffer.indexOf(`
146
146
  `);for(;n!==-1;){let r=this.buffer.slice(0,n);this.buffer=this.buffer.slice(n+1),this.handleMessage(r),n=this.buffer.indexOf(`
147
- `)}}handleMessage(t){if(t.trim().length===0)return;let n;try{n=JSON.parse(t)}catch{return}if("id"in n){let r=this.pending.get(n.id);if(!r)return;this.pending.delete(n.id),r.resolve(n);return}n.type==="update"&&(n.tabId&&this.viewCache.set(n.tabId,n.view),this.options.onUpdate?.(n.tabId??""))}rejectAll(t){for(let n of this.pending.values())n.reject(t);this.pending.clear()}},xr=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,n){this.runtime=new an({...n,workspaceRoot:t.workspaceRoot,onUpdate:r=>this.broadcastUpdate(r)})}handleConnection(t){let n="";this.clients.add(t),t.setEncoding("utf8"),t.on("data",r=>{n+=String(r);let s=n.indexOf(`
147
+ `)}}handleMessage(t){if(t.trim().length===0)return;let n;try{n=JSON.parse(t)}catch{return}if("id"in n){let r=this.pending.get(n.id);if(!r)return;this.pending.delete(n.id),r.resolve(n);return}n.type==="update"&&(n.tabId&&this.viewCache.set(n.tabId,n.view),this.options.onUpdate?.(n.tabId??""))}rejectAll(t){for(let n of this.pending.values())n.reject(t);this.pending.clear()}},Nr=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,n){this.runtime=new cn({...n,workspaceRoot:t.workspaceRoot,onUpdate:r=>this.broadcastUpdate(r)})}handleConnection(t){let n="";this.clients.add(t),t.setEncoding("utf8"),t.on("data",r=>{n+=String(r);let s=n.indexOf(`
148
148
  `);for(;s!==-1;){let o=n.slice(0,s);n=n.slice(s+1),this.handleLine(t,o),s=n.indexOf(`
149
- `)}}),t.on("close",()=>this.clients.delete(t)),t.on("error",()=>this.clients.delete(t))}disposeAll(){this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear()}async handleLine(t,n){if(n.trim().length===0)return;let r;try{r=JSON.parse(n)}catch{cn(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(r);cn(t,{id:r.id,ok:!0,...r.type==="ping"?{protocolVersion:Er}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);cn(t,{id:r.id,ok:!1,error:o})}}handleRequest(t){switch(t.type){case"ping":return null;case"ensureSession":return this.attachedTabId=t.tabId,this.runtime.ensureSession(t.taskId,t.tabId,t.size,t.spec);case"hydrateSession":return this.runtime.getViewState(t.tabId);case"write":return this.runtime.write(t.input),null;case"writeKey":return this.runtime.writeKey(t.key),null;case"scrollViewport":return this.runtime.scrollViewport(t.lines),this.runtime.getViewState(this.attachedTabId);case"resize":return this.runtime.resize(t.size),this.runtime.getViewState(this.attachedTabId);case"detach":return this.runtime.detach(),this.attachedTabId=null,null;case"disposeSession":return this.runtime.disposeSession(t.tabId),this.attachedTabId===t.tabId&&(this.attachedTabId=null),null;case"pruneStale":{let n=new Set(t.keepTabIds);for(let r of this.runtime.sessionTabIds())n.has(r)||(this.runtime.disposeSession(r),this.attachedTabId===r&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(t.tabId);case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return $f(t)}}broadcastUpdate(t){let n=this.runtime.getViewState(t);for(let r of this.clients)cn(r,{type:"update",tabId:t,view:n})}};function Ar(e){let t=kf("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:it.join(bf(),`craig-${t}.sock`),pidPath:it.join(e.runtimeDir,"pty-daemon.pid")}}async function If(e,t,n){if(await Sf(e.socketPath,1e3))return;await ln(e.socketPath)&&(await qi(e.socketPath),await ji(e.socketPath,1e3)),await ln(e.socketPath)&&(await vf(e),await ji(e.socketPath,1e3)),await xf(e);let r=t.workspaceRoot;if(n)n(r);else{let{command:i,args:c}=Cf(r),l=Tf(it.join(t.runtimeDir,"pty-daemon.log"),"a");wf(i,c,{cwd:r,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await Ui(e.socketPath))return;await $r(50)}let o=await vr(it.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
150
- ${o.slice(-2e3)}`:""}`)}async function Ui(e){let t=await Ef(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===Er}async function Sf(e,t){let n=Date.now();for(;Date.now()-n<t;){if(await Ui(e))return!0;await $r(50)}return!1}function Cf(e){let t=process.argv[1];if(t?.endsWith(".ts")){let r=it.resolve(it.dirname(t),"..","node_modules",".bin","tsx");return{command:jn("tsx")??r,args:[t,"__craig-daemon",e]}}let n=process.argv.slice(1);return{command:process.execPath,args:[...process.execArgv,...n,"__craig-daemon",e]}}async function xf(e){let t=await vr(e.pidPath,"utf8").catch(()=>null);if(t){let n=Number(t.trim());if(Number.isInteger(n)&&n>0&&Gi(n))return}await Je(e.socketPath,{force:!0}),await Je(e.pidPath,{force:!0})}async function ln(e){let t=await Vi(e).catch(()=>null);return t?(t.end(),!0):!1}async function qi(e){await Ki(e,{id:1,type:"shutdown"}).catch(()=>null)}async function vf(e){let t=await vr(e.pidPath,"utf8").catch(()=>null),n=Number(t?.trim());if(!Number.isInteger(n)||n<=0||!Gi(n)){await Je(e.socketPath,{force:!0});return}try{process.kill(n,"SIGTERM")}catch{await Je(e.socketPath,{force:!0})}}async function Ef(e){return Ki(e,{id:1,type:"ping"})}function Ki(e,t){return new Promise((n,r)=>{let s=Ni(e),o="",i=setTimeout(()=>{s.destroy(),r(new Error("Craig PTY daemon request timed out."))},500),c=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
149
+ `)}}),t.on("close",()=>this.clients.delete(t)),t.on("error",()=>this.clients.delete(t))}disposeAll(){this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear()}async handleLine(t,n){if(n.trim().length===0)return;let r;try{r=JSON.parse(n)}catch{ln(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(r);ln(t,{id:r.id,ok:!0,...r.type==="ping"?{protocolVersion:_r}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);ln(t,{id:r.id,ok:!1,error:o})}}handleRequest(t){switch(t.type){case"ping":return null;case"ensureSession":return this.attachedTabId=t.tabId,this.runtime.ensureSession(t.taskId,t.tabId,t.size,t.spec);case"hydrateSession":return this.runtime.getViewState(t.tabId);case"write":return this.runtime.write(t.input),null;case"writeKey":return this.runtime.writeKey(t.key),null;case"scrollViewport":return this.runtime.scrollViewport(t.lines),this.runtime.getViewState(this.attachedTabId);case"resize":return this.runtime.resize(t.size),this.runtime.getViewState(this.attachedTabId);case"detach":return this.runtime.detach(),this.attachedTabId=null,null;case"disposeSession":return this.runtime.disposeSession(t.tabId),this.attachedTabId===t.tabId&&(this.attachedTabId=null),null;case"pruneStale":{let n=new Set(t.keepTabIds);for(let r of this.runtime.sessionTabIds())n.has(r)||(this.runtime.disposeSession(r),this.attachedTabId===r&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(t.tabId);case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return op(t)}}broadcastUpdate(t){let n=this.runtime.getViewState(t);for(let r of this.clients)ln(r,{type:"update",tabId:t,view:n})}};function Br(e){let t=Gf("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:nt.join(Qf(),`craig-${t}.sock`),pidPath:nt.join(e.runtimeDir,"pty-daemon.pid")}}async function Xf(e,t,n){if(await Zf(e.socketPath,1e3))return;await dn(e.socketPath)&&(await ha(e.socketPath),await da(e.socketPath,1e3)),await dn(e.socketPath)&&(await np(e),await da(e.socketPath,1e3)),await tp(e);let r=t.workspaceRoot;if(n)n(r);else{let{command:i,args:c}=ep(r),l=zf(nt.join(t.runtimeDir,"pty-daemon.log"),"a");Vf(i,c,{cwd:r,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await ga(e.socketPath))return;await Ur(50)}let o=await Wr(nt.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
150
+ ${o.slice(-2e3)}`:""}`)}async function ga(e){let t=await rp(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===_r}async function Zf(e,t){let n=Date.now();for(;Date.now()-n<t;){if(await ga(e))return!0;await Ur(50)}return!1}function ep(e){let t=process.argv[1];if(t?.endsWith(".ts")){let r=nt.resolve(nt.dirname(t),"..","node_modules",".bin","tsx");return{command:zn("tsx")??r,args:[t,"__craig-daemon",e]}}let n=process.argv.slice(1);return{command:process.execPath,args:[...process.execArgv,...n,"__craig-daemon",e]}}async function tp(e){let t=await Wr(e.pidPath,"utf8").catch(()=>null);if(t){let n=Number(t.trim());if(Number.isInteger(n)&&n>0&&Ra(n))return}await Ge(e.socketPath,{force:!0}),await Ge(e.pidPath,{force:!0})}async function dn(e){let t=await ka(e).catch(()=>null);return t?(t.end(),!0):!1}async function ha(e){await wa(e,{id:1,type:"shutdown"}).catch(()=>null)}async function np(e){let t=await Wr(e.pidPath,"utf8").catch(()=>null),n=Number(t?.trim());if(!Number.isInteger(n)||n<=0||!Ra(n)){await Ge(e.socketPath,{force:!0});return}try{process.kill(n,"SIGTERM")}catch{await Ge(e.socketPath,{force:!0})}}async function rp(e){return wa(e,{id:1,type:"ping"})}function wa(e,t){return new Promise((n,r)=>{let s=ua(e),o="",i=setTimeout(()=>{s.destroy(),r(new Error("Craig PTY daemon request timed out."))},500),c=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
151
151
  `)),s.once("error",l=>{c(),r(l)}),s.on("data",l=>{o+=String(l);let d=o.indexOf(`
152
- `);if(d===-1)return;let f=o.slice(0,d);c(),s.end();try{n(JSON.parse(f))}catch(h){r(h instanceof Error?h:new Error(String(h)))}}),s.once("close",()=>c())})}async function ji(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!await ln(e))return;await $r(50)}}function Vi(e){return new Promise((t,n)=>{let r=Ni(e);r.once("connect",()=>t(r)),r.once("error",n)})}function Af(e,t){return new Promise((n,r)=>{e.once("error",r),e.listen(t,n)})}function cn(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
153
- `)}catch{}}function Gi(e){try{return process.kill(e,0),!0}catch{return!1}}function $r(e){return new Promise(t=>setTimeout(t,e))}function $f(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}import ok from"picocolors";var Df=[" \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 Dr(){return[...Df]}var Mf=["Start","Options","Exit"],Lf=["Resume","Options","Exit"],fn=2,pn=2,mn=2,Of=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Ff=new RegExp("\x1B\\[(?:0)?m","g"),jf=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),Nf=/https?:\/\/[^\s<>"']+/g,Mr="\x1B[0m",Lr="\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"}};function Yi(e,t={}){return Fr(e,{subtitle:"crAIg is that you?",menuItems:Mf,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function Ji(e,t={}){return Fr(e,{subtitle:"Control mode is paused.",menuItems:Lf,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var dn=[" 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."],Wf=["Help"];function Or(e,t={}){return Fr(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Wf,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Qi(e,t={}){let n=t.color??!0,r=v.overlay,s=new Array(e.height).fill(O(" ".repeat(e.width),n,r)),o=Dr(),i=Math.max(1,Math.floor((e.height-o.length-2-dn.length)/2));for(let f=0;f<o.length&&!(i+f>=e.height);f+=1)s[i+f]=O(na(o[f]??"",e.width),n,v.overlayLogo);let c=Math.max(...dn.map(f=>f.length)),l=Math.max(0,Math.floor((e.width-c)/2)),d=i+o.length+2;for(let f=0;f<dn.length;f+=1){let h=d+f;if(h>=e.height)break;let R=dn[f]??"";s[h]=O(Se(" ".repeat(l)+R,e.width),n,r)}return s.join(`
154
- `)}function Xi(e,t={}){let n=t.color??!0,r=v.overlay,s=new Array(e.height).fill(O(" ".repeat(e.width),n,r)),o="Error Log",i=t.errorLogPath??"",c=t.errorLogLines??[],l=Math.max(20,e.width-8),d=Math.max(0,Math.floor((e.width-l)/2)),f=[{text:o,tone:"selected"},{text:i,tone:"muted"},ee(),...c.length>0?c.map(k=>({text:k})):[{text:"No Craig errors have been logged.",tone:"muted"}],ee(),{text:"Esc returns to Options.",tone:"muted"}],h=xt(f,e.height-2),R=Math.max(1,Math.floor((e.height-h.length)/2));for(let k=0;k<h.length;k+=1){let I=R+k;if(I>=e.height)break;let T=h[k]??ee(),a=`${" ".repeat(d)}${hn(T.text,l)}`,V=T.tone==="selected"?v.overlayMenuSelected:T.tone==="muted"?v.overlay:v.panelBg;s[I]=O(Se(a,e.width),n,V)}return s.join(`
155
- `)}function Zi(e,t,n={}){let r=n.color??!0,s=he.leftWidth,o=he.rightWidth,i=he.dividerWidth,c=n.centerOnly??!1,l=c?e.width:e.width-s-o-i*2,d=e.height-he.topRailHeight-1,f=n.focusFlashActive??!1,h={bg:v.divider.bg,fg:"9ece6a"},R=f&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?h:v.divider,k=f&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?h:v.divider,I=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=O(Se(I,e.width),r,v.rail),a=Bf(t,s-fn-pn,d,r),V=Uf(t,l,d,r),j=Kf(t,o,d,r),te=t.inputMode==="terminal",C=[];for(let X=0;X<d;X+=1){if(c){C.push(un(V[X]??ee(),l,r,"center"));continue}let $e=un(a[X]??ee(),s,r,"left"),we=O("\u2502",r,R),De=un(V[X]??ee(),l,r,"center"),ne=O("\u2502",r,k),Qe=un(j[X]??ee(),o,r,"right");C.push(`${$e}${we}${De}${ne}${Qe}`)}let Ne=te||t.modalInput?v.panelBg:v.panelMuted,Ae=_f(t.footerText,t.footerToast,e.width,r,Ne);return[T,...C,Ae].join(`
156
- `)}function _f(e,t,n,r,s){let o=` ${e}`;if(!t)return O(Se(o,n),r,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,c=Q(i),l=Q(o),d=Math.max(1,n-l-c-2),f=l+d+c+2>n?hn(o,Math.max(0,n-c-3)):o,h=Math.max(1,n-Q(f)-c-2),R=t.tone==="error"?lp(i,r,s):at(i,r,s),k=`${f}${" ".repeat(h)}${R} `;return O(Se(k,n),r,s)}function Fr(e,t){let n=new Array(e.height).fill(O(" ".repeat(e.width),t.color,v.overlay)),r=Dr(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,f)=>`${f===t.menuIndex?">":" "} ${d.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],c=[...r,"",t.subtitle,"",...o,...i],l=Math.max(1,Math.floor((e.height-c.length)/2));for(let d=0;d<c.length;d+=1){let f=na(c[d]??"",e.width);if(d<r.length){n[l+d]=O(f,t.color,v.overlayLogo);continue}if(d===r.length+1){n[l+d]=O(f,t.color,v.overlaySubtitle);continue}let h=d-(r.length+3),k=h>=0&&h<t.menuItems.length&&h===t.menuIndex?v.overlayMenuSelected:v.overlay;n[l+d]=O(f,t.color,k)}if(t.versionText){let d=t.updateText?" (update available)":"",f=`${t.versionText}${d} `,h=" ".repeat(Math.max(0,e.width-Q(f)));n[e.height-1]=O(`${h}${jr(f,t.color,v.overlay)}`,t.color,v.overlay)}return n.join(`
157
- `)}function Bf(e,t,n,r){let s=Hf(e.runners),o=1,i=e.leftTree.map(l=>Gf(l,t,r));return[...xt(i,n-o),s]}function Uf(e,t,n,r){let s=t-2,o=e.tabs.find(C=>C.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:ip(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?at(l,r,v.panelBg):gn(l,r,v.panelMuted)}`,f=[`${gn(e.centerHeader.tabLabel,r,v.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(C=>C.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!li(h)?e.centerTranscript.map(C=>({...C})):qf(e),k=zf(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?at(`${I}\u25CF `,r,v.panelBg):"",V=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-Q(k)-T)):"",te=[{text:e.inputMode==="terminal"?`${k}${V}${a}`:k},{text:d,tone:"muted"},{text:f},ee(),...R];return xt(te,n)}function qf(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},ee(),{text:e.terminal.error},ee(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(r=>r.active)?.id??"",n=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${n.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(r=>({text:oa(r.segments),segments:r.segments,fullBleed:!0}))}function Kf(e,t,n,r){let s=e.rightInspection?Vf(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,n):xt([{text:"CONTEXT"},ee(),...e.rightContext.map(o=>Yf(o,r)),...e.actionMessage?[ee(),{text:e.actionMessage}]:[]],n);return xt(s,n)}function Vf(e,t){let n=e.slice(0,2),r=e.slice(2),s=Math.max(0,t-n.length),o=r.findIndex(c=>c.focused||c.selected),i=o===-1?0:cp(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Hi(c)),...r.slice(i,i+s).map(c=>Hi(c))]}function Hi(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",n=e.focused||e.selected?"selected":e.muted?"muted":"default",r=`${t}${e.text}`;if(e.segments)return{text:r,segments:[{text:t},...e.segments],tone:n};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:r,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:n}}return e.color?{text:r,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:n}:{text:r,tone:n}}function Gf(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${at("\u25CF",n,e.selected?v.panelSelected:v.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+Q(I.text),0):0,l=t-Q(o)-Q(s)-c,d=e.selected?e.text:e.focused?at(e.text,n,v.panelBg):e.panelHeader?gn(e.text,n,v.panelMuted):e.text,f=Se(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${f}${o}${i}`},...e.prBadge];return{text:`${f}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${f}${o}${i}`,tone:h}}function Hf(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:v.success.fg}}):n.push({text:s.text,style:{fg:v.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function zf(e,t,n){return e.map(r=>r.active?n?at(r.label,t,v.panelBg):gn(r.label,t,v.panelBg):jr(r.label,t,v.panelBg)).join(" ")}function Yf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?jr(e.value,t,v.panelBg):e.value}`}}function un(e,t,n,r){let s=Jf(r,e.tone??"default"),o=Qf(e,n,s);if(r==="left"){if(e.fullBleed)return O(Se(o,t),n,s);let c=t-fn-pn;if(e.rightAlign){let d=Q(o),f=Math.max(0,c-d),h=`${" ".repeat(fn)}${" ".repeat(f)}${o}${" ".repeat(pn)}`;return O(h,n,s)}let l=`${" ".repeat(fn)}${Se(o,c)}${" ".repeat(pn)}`;return O(l,n,s)}return r==="center"&&e.fullBleed?Xf(e,t,n,s):O(Se(` ${o}`,t),n,s)}function Jf(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function xt(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(ee());return n}function ee(){return{text:""}}function Qf(e,t,n){return e.segments?e.segments.map(r=>ea(r,t,n)).join(""):e.text}function Xf(e,t,n,r){let s=" ".repeat(mn),o=Math.max(0,t-mn*2);if(!e.segments)return O(`${s}${Se(e.text,o)}${s}`,n,r);let i=tp(e.segments,o),c=`${s}${i.map(l=>ea(l,n,r)).join("")}${s}${n?Lr:""}`;return O(c,n,r)}function ea(e,t,n){let r=e.href?`${ta(e.href)}${e.text}${Lr}`:Zf(e.text);return!t||!e.style?r:`${vt(sp(e.style,n))}${op(e.style)}${r}${Mr}${vt(n)}`}function Zf(e){return e.replace(Nf,t=>{let[n,r]=ep(t);return`${ta(n)}${n}${Lr}${r}`})}function ep(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ta(e){return`\x1B]8;;${e}\x1B\\`}function tp(e,t){let n=np(e,t);return rp(n,t)}function np(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=Q(s.text);if(o<=r){n.push(s),r-=o;continue}let i=hn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function rp(e,t){let n=Q(oa(e));if(n>=t)return e;let r=e.at(-1)?.style;return r?.bg?[...e,{text:" ".repeat(t-n),style:r}]:[...e,{text:" ".repeat(t-n)}]}function sp(e,t){let n=e.inverse?e.bg??t.bg:e.fg,r=e.inverse?e.fg??t.fg:e.bg,s={},o=n??t.fg,i=r??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function op(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 ip(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function na(e,t){let n=Math.max(0,t-Q(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Se(e,t){let n=Q(e);return n>=t?ap(e,t):e+" ".repeat(t-n)}function ap(e,t){if(t<=0)return"";if(Q(e)<=t)return e;let n=sa(e);return hn(n,Math.max(0,t-1))+"\u2026"}function Q(e){let t=0;for(let n of Array.from(sa(e)))t+=ra(n);return t}function hn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=ra(s);if(r+o>t)break;n+=s,r+=o}return n}function ra(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 cp(e,t,n){return Math.min(Math.max(e,t),n)}function sa(e){return e.replace(jf,"").replace(Of,"")}function oa(e){return e.map(t=>t.text).join("")}function O(e,t,n){if(!t)return e;let r=vt(n),s=e.replace(Ff,`${Mr}${r}`);return`${r}${s}${Mr}`}function vt(e){let t=[];return e.fg&&t.push(`38;2;${zi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${zi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function zi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function at(e,t,n){return wn(e,t,v.success.fg,n)}function lp(e,t,n){return wn(e,t,v.error.fg,n)}function gn(e,t,n){return wn(e,t,v.accent.fg,n)}function jr(e,t,n){return wn(e,t,v.mutedfg.fg,n)}function wn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${vt(s)}${e}${vt(r)}`}var dp="https://registry.npmjs.org/craig-cli/latest";var kn=null;function Nr(){try{return"0.7.1"}catch{return"unknown"}}async function ia(){let e=Nr(),t=Date.now();if(kn&&t-kn.cachedAt<36e5)return kn.result;let n=null;try{let s=await fetch(dp,{signal:AbortSignal.timeout(5e3)});s.ok&&(n=(await s.json()).version??null)}catch{}let r={current:e,latest:n,updateAvailable:n!==null&&n!==e&&up(n,e)};return kn={result:r,cachedAt:t},r}function up(e,t){let n=d=>d.split(".").map(Number),[r=0,s=0,o=0]=n(e),[i=0,c=0,l=0]=n(t);return r!==i?r>i:s!==c?s>c:o>l}ue();var Wr=["Runners","Error Log","Help"];function _r(e,t){return N.map(n=>{let r=Z(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function ca(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function la(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Wr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Br(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function da(e,t,n,r){if(e.pathEdit)return fp({...e,pathEdit:e.pathEdit},t,n);let s=_r(t,e).length;if(n==="UP"||n==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(n==="DOWN"||n==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(n==="ESCAPE")return{kind:"back",state:e};if(n==="e"){let c=N[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!Br(n))return{kind:"noop",state:e};let o=N[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&r.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:pp(t,o,!i),state:{...e,message:`${Z(o).displayName} ${i?"disabled":"enabled"}.`}}}function fp(e,t,n){if(n==="ESCAPE")return{kind:"render",state:aa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Br(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:mp(t,r,s.length>0?s:null),state:aa({...e,message:s.length>0?`${Z(r).displayName} executable saved.`:`${Z(r).displayName} executable reset to default.`})}}return gp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function pp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function mp(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function aa(e){let t={...e};return delete t.pathEdit,t}function Br(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
158
- `}function gp(e){return e.length===1&&e>=" "&&e!=="\x7F"}var Rp=hp(import.meta.url),Tp=Rp("terminal-kit"),yp=Tp.terminal;async function pa(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=Ce(t);await ot(t);let r=await Te(n),s=Ze(r),o=e.uiStateFile?await fe({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await Et(t,void 0,s),d=nn(si(o,r),l);l=await Et(t,d,s);let f=()=>{},h={workspaceRoot:t,onUpdate:()=>f(),resolveSessionSpec:(I,T)=>Sp(l,T,t)},R=e.ptyRuntime??await Wi({...h,paths:n}),k=I=>{if(!e.uiStateFile)return;o=oi(o,I);let T=o;i=i.then(()=>ae({uiStateFile:e.uiStateFile},T),()=>ae({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(I=>{let T=e.terminal??yp,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:nn(d,l)},V=!1,j=!1,te=null,C=0,Ne=0,Ae=null,X=null,$e=null,we=null,De=null,ne=null,Qe=null,yn=!1,Pn=null,qr=`Craig v${Nr()}`,bn=null,In=0,G=!0,Sn=null,y=()=>{},F=R;f=()=>{a.mode==="main"&&(a={mode:"main",shell:lt(a.shell)},$e||($e=setTimeout(()=>{$e=null,a.mode==="main"&&y()},50)))};function lt(m){return Ye(m,F.getViewState(Kr(m)))}function Kr(m){let u=Xe(m);return u?u.ptyTabs.some(p=>p.id===m.activeTab)?m.activeTab:m.activeTab==="agent"||m.activeTab==="terminal"?u.ptyTabs.find(p=>p.kind===m.activeTab)?.id??m.selectedPtyTabId:m.selectedPtyTabId:m.selectedPtyTabId}function P(m){return lt(Pp(m,l))}function Xe(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function Vr(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(p=>p.id));await F.pruneStale?.(m),await F.hydrateSessions?.(m)}function ha(){Vr().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function wa(m){let u=P(m),p=Xe(u),g=Kr(u);if(!p||!g||!p.ptyTabs.some(L=>L.id===g))return u;let w=F.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return Ye(u,w);let S=await F.ensureSession(p.id,g,$t(je(T.width,T.height)));return Ye({...u,inputMode:"control"},S)}function Gr(m,u){return we&&(clearTimeout(we),we=null),u?(we=setTimeout(()=>{we=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...m,footerToast:u}):{...m,footerToast:null}}function ka(m,u){return Gr(m,u?{tone:"success",message:u}:null)}function U(m,u,p){let g=u instanceof Error?u.message:p,w=u instanceof Error?u.stack??u.message:String(u);return ir(n,{context:m,message:g,details:w}),g}function q(m,u){return Gr(m,{tone:"error",message:u})}function We(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function Hr(m){let u=Xe(m),p=l.inspection,g=p&&p.taskId===u?.id?p:null,w=bp(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:Ip(l),centerTabIds:ui(u,m),ptyTabIds:u?.ptyTabs.map(S=>S.id)??[],filePathIds:g?.filePaths??[],fileTreeRowIds:w.map(S=>S.path),fileTreeFileIds:w.filter(S=>S.kind==="file").map(S=>S.path),fileTreeDirectoryIds:w.filter(S=>S.kind==="directory").map(S=>S.path),diffPathIds:g?.diffPaths??[],diffPathRanges:[],fileLineCount:g?.selectedFile.lines.length??0,diffLineCount:g?.selectedDiff.lines.length??0,reviewRowCount:Ci(m,u),pageRows:Math.max(5,je(T.width,T.height).height-he.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(S=>S.repoId)??[]}}async function Ra(m){await os(n,m),r=m,s=Ze(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:_e(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:_e(r)})}}async function Ta(m){let u=m.selectedTaskId;u&&await We(async()=>{let p=await _(n,u);!p.ptyTabs.some(g=>g.id===m.activeTab)||p.selectedPtyTabId===m.activeTab||await E(n,{...p,selectedPtyTabId:m.activeTab})})}async function re(){let m=(a.mode==="main",a.shell);l=await Et(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function zr(m){let u=++In,p=ma(l.tasks,m),g=l.inspection,w;if(p&&g?.taskId===p.id){let S={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},L=await Ao(p,g,S);if(u!==In)return;w={...l,inspection:L}}else if(w=await Et(t,m,s),u!==In)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function Cn(m){let u=await jp(m);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:u,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function Yr(m){try{let u=P(m),p=Xe(u),g=u.selectedPtyTabId;if(p&&u.focusedRegion==="tasks"){let L=p.ptyTabs.find(de=>de.kind==="agent")??null;L?g=L.id:(p=await Jr(p),await re(),g=p.selectedPtyTabId)}p&&!g&&(p=await Jr(p),await re(),g=p.selectedPtyTabId);let w=P({...u,activeTab:g??u.activeTab,selectedPtyTabId:g,focusedRegion:g?"center":u.focusedRegion});if(!w.selectedTaskId||!g){a={mode:"main",shell:w},y();return}a={mode:"main",shell:Ye({...w,inputMode:"terminal"},F.getViewState(g))},k(a.shell);let S=await F.ensureSession(w.selectedTaskId,g,$t(je(T.width,T.height)));j=Ur(g),te=null,a={mode:"main",shell:Ye({...w,inputMode:"terminal"},S)},k(a.shell)}catch(u){let p=U("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Ur(m.selectedPtyTabId)&&(await ya(m.selectedTaskId,p).catch(()=>{}),await re().catch(()=>{})),a={mode:"main",shell:q(ai(P(m),p),p)},k(a.shell)}y()}async function ya(m,u){await We(async()=>{let p=await _(n,m);await E(n,{...p,status:p.status==="running"?"draft":p.status,runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:u})})}async function Pa(m,u,p){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await We(async()=>{let S=await _(n,g.selectedTaskId),L=u??vp(S,g.activeTab,g.preferredPtyTabKind),de=ua(S,L,p??void 0,r),dt={...S,ptyTabs:[...S.ptyTabs,de],selectedPtyTabId:de.id};return await E(n,dt),dt});return await re(),P({...g,activeTab:w.selectedPtyTabId??g.activeTab,selectedPtyTabId:w.selectedPtyTabId,preferredPtyTabKind:w.ptyTabs.at(-1)?.kind??g.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${w.ptyTabs.at(-1)?.title??"tab"}`})}async function ba(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:p,nextSelectedTab:g}=await We(async()=>{let w=await _(n,u.selectedTaskId),S=w.ptyTabs.findIndex(En=>En.id===u.activeTab);if(S===-1)throw new Error("Only PTY tabs can be closed.");let L=w.ptyTabs[S],de=w.ptyTabs.filter(En=>En.id!==L.id),dt=de[Math.min(S,de.length-1)]??de[S-1]??null;return await E(n,{...w,ptyTabs:de,selectedPtyTabId:dt?.id??null}),{closedTab:L,nextSelectedTab:dt}});return F.disposeSession(p.id),await re(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${p.title}`})}async function Ia(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let p=Xe(u),g=null,w=null;if(p?.type==="project"&&p.repoTargets?.length){let S=await zt(n,u.selectedTaskId);await re();let L=S.synced+S.discovered+S.notFound;w=`Refreshed ${S.synced}/${L} targets`}else{let{disposition:S,task:L}=await Jn(n,u.selectedTaskId);await re(),g=S==="not_found"?`No PR found for ${L.branch}`:null,S!=="not_found"&&(w=`Refreshed checks: ${K(L)?.requiredChecks.length??0} reported`)}return P({...ka(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function Sa(){if(yn||a.mode!=="main")return;let m=l.tasks;yn=!0;try{if(await co(n,m),Pn=null,a.mode!=="main")return;l=await Et(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(u){let p=u instanceof Error?u.message:"Background PR discovery failed.";p!==Pn&&(Pn=p,ir(n,{context:"background PR polling",message:p,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{yn=!1}}async function Ca(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:p,task:g}=await We(async()=>{let w=await _(n,u.selectedTaskId),S=await _o(n,u.selectedTaskId);return{taskBeforeClose:w,task:S}});for(let w of p.ptyTabs)F.disposeSession(w.id);return await re(),P({...u,selectedActionId:"close-task",actionMessage:g.cleanup.preservedWorktree?`Archived task ${g.id}; worktree preserved`:`Archived task ${g.id}`})}async function xa(m){let u=P(m);if(!u.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await be(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await Tt(n,u.selectedWorkspaceId);let g=await yt(n,u.selectedWorkspaceId);return await re(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function Jr(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await We(async()=>{let S=await _(n,m.id),L=S.ptyTabs.find(de=>de.kind==="agent")??null;L&&await E(n,{...S,selectedPtyTabId:L.id})}),w}let p=ua(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,p],selectedPtyTabId:p.id};return await We(async()=>{let w=await _(n,m.id),S=w.ptyTabs.find(L=>L.kind==="agent")??null;if(S){await E(n,{...w,selectedPtyTabId:S.id});return}await E(n,{...w,ptyTabs:[...w.ptyTabs,p],selectedPtyTabId:p.id})}),g}y=()=>{va();let m=je(T.width,T.height),u=a.mode==="main"?Zi(m,Ri(P(a.shell),l),{centerOnly:a.shell.centerZoomed,focusFlashActive:De!==null&&Date.now()<De}):a.variant==="boot"?Yi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:qr,updateText:bn}):a.variant==="pause"?Ji(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:qr,updateText:bn}):a.variant==="options"?Or(m,{menuIndex:a.menuIndex,optionsMenuItems:Wr}):a.variant==="runners"?Or(m,{menuIndex:At(a).menuIndex,optionsMenuItems:_r(r,At(a)),optionsMessage:ca(At(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Xi(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Qi(m);G&&(T.moveTo(1,1),T.eraseDisplayBelow(),G=!1),T.noFormat(Ap(u)),T.hideCursor(!0)};function va(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==Sn&&(Sn=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let Ea=()=>{process.stdout.off("resize",ts),process.off("SIGCONT",ns),T.removeListener("key",Qr),T.removeListener("unknown",Xr),T.removeListener("mouse",Zr),Ae&&(clearTimeout(Ae),Ae=null),X&&(clearTimeout(X),X=null),$e&&(clearTimeout($e),$e=null),we&&(clearTimeout(we),we=null),ne&&(clearTimeout(ne),ne=null),Qe&&(clearInterval(Qe),Qe=null),F.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},xn=m=>{Ea(),I(m)},Aa=async()=>{if(a.mode!=="main"||V)return;let m=a.shell,u=m.taskPromptInput?.trim()??"";if(!m.selectedRepoId&&!m.selectedWorkspaceId){a={mode:"main",shell:P({...m,taskPromptError:"Select a workspace first."})},y();return}if(u.length===0){a={mode:"main",shell:P({...m,taskPromptError:"Task prompt cannot be empty."})},y();return}V=!0,a={mode:"main",shell:P({...m,actionMessage:`Creating ${m.selectedRunner} task in ${m.selectedWorkspaceId??m.selectedRepoId}...`})},y();let p=null;try{p=await Ep(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await re();let g=P({...a.shell,selectedRepoId:p.repoId,selectedWorkspaceId:p.workspaceId,selectedTaskId:p.id,selectedPtyTabId:p.selectedPtyTabId,selectedLeftItemId:`task:${p.id}`,activeTab:p.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),w=await F.ensureSession(p.id,g.selectedPtyTabId??ga(p,"agent"),$t(je(T.width,T.height)));j=Ur(g.selectedPtyTabId),a={mode:"main",shell:Ye(g,w)},k(a.shell)}catch(g){g instanceof Rn&&(p=g.task);let w=U("create task",g,"Failed to create task.");p&&(await E(n,{...p,status:"draft",runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:w}).catch(()=>{}),await re().catch(()=>{})),a={mode:"main",shell:q(P({...a.shell,inputMode:"control",selectedTaskId:p?.id??a.shell.selectedTaskId,selectedPtyTabId:p?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:p?`task:${p.id}`:a.shell.selectedLeftItemId,activeTab:p?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:p?null:"",taskPromptError:w,actionMessage:null}),w)}}finally{V=!1,y()}},$a=m=>{if(a.mode!=="main")return;let u=a.shell;if(u.taskPromptInput!==null){if(m==="ESCAPE"){a={mode:"main",shell:P({...u,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Ee(m)){Aa();return}if(m==="BACKSPACE"){a={mode:"main",shell:P({...u,taskPromptInput:u.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(m==="CTRL_R"){a={mode:"main",shell:P({...u,selectedRunner:wr(u.selectedRunner,s),taskPromptError:null})},y();return}ci(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},Da=m=>{if(a.mode!=="main")return;let u=a.shell.workspaceBrowser;if(u){if(m==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(m==="UP"||m==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.max(0,u.selectedIndex-1),error:null}})},y();return}if(m==="DOWN"||m==="j"){let p=Math.max(0,u.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.min(p,u.selectedIndex+1),error:null}})},y();return}if(m==="LEFT"||m==="h"){Cn(ct.dirname(u.cwd)).catch(p=>{let g=U("open parent workspace directory",p,"Failed to open parent directory.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Ee(m)){let p=u.entries[u.selectedIndex]??null;if(!p)return;if((m==="RIGHT"||m==="l")&&(p.kind==="directory"||p.kind==="repo")){Cn(p.path).catch(g=>{let w=U("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}Rt(n,p.path).then(async g=>{await re();let w=g.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${g.workspace.id}`,selectedWorkspaceId:g.workspace.id,selectedRepoId:w?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${g.workspace.name??g.workspace.id}`})},k(a.shell),y()}).catch(g=>{let w=U("add workspace",g,"Failed to add workspace.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},Qr=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){$a(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){Da(u);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(u==="F"){Fa(),y();return}De!==null&&(De=null,ne&&(clearTimeout(ne),ne=null))}if(a.mode==="main"){let p=ii(a.shell,u,Hr(a.shell));if(p.exit){xn(0);return}if(p.detachTerminal){F.detach(),a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(p.changed){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(j&&Ee(u)){j=!1;return}j&&(j=!1),te=Dp(u)?{key:u,at:Date.now()}:null;let g=Mp(u,a.shell.terminal.scrolledBack??!1);if(g!==0){vn(g);return}F.writeKey(u);return}if(u==="CTRL_C"){xn(0);return}if(u==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},G=!0,y();return}if(p.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(p.state)},G=!0,y();return}if(p.beginTaskPrompt){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(p.openWorkspaceBrowser){Cn(t).catch(g=>{let w=U("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:q(P({...p.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(p.createPtyTab){Pa(p.state,p.createPtyTabKind,p.createPtyTabRunner).then(g=>{Yr(g)}).catch(g=>{let w=U("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.closePtyTab){ba(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("close PTY tab",g,"Failed to close tab.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.refreshPullRequestChecks){Ia(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("refresh PR checks",g,"Failed to refresh PR checks.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.openPrUrl){let g=Xe(p.state),w=g?K(g)?.url??null:null;w?Np(w).catch(S=>{let L=U("open PR URL",S,"Failed to open PR in browser.");a={mode:"main",shell:q(P(p.state),L)},y()}):(a={mode:"main",shell:q(P(p.state),"No PR URL available.")},y());return}if(p.closeTask){Ca(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("close task",g,"Failed to close task.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.removeWorkspace){xa(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("remove workspace",g,"Failed to remove workspace.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.attachTerminal){Yr(p.state);return}if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),zr(a.shell).catch(g=>{let w=U("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:q(P({...a.shell,actionMessage:w}),w)},y()});return}p.changed&&(a={mode:"main",shell:P(p.state)},Ta(a.shell).catch(()=>{}),k(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},G=!0,y();return}if(a.variant==="options"){Ma(u);return}if(a.variant==="runners"){Oa(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Ee(u)){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y()}return}if(a.optionsMessage){(u==="ESCAPE"||Ee(u))&&(a={...a,optionsMessage:null},y());return}if(u==="UP"||u==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(u==="DOWN"||u==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(u==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},G=!0,y());return}if(Ee(u)){if(a.menuIndex===0){let p=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},G=!0,y(),p?Wa.then(()=>{if(a.mode!=="main")return;let g=a.shell;wa(g).then(w=>{a.mode!=="main"||a.shell!==g||(a={mode:"main",shell:w},k(a.shell),y())}).catch(w=>{if(a.mode!=="main"||a.shell!==g)return;let S=U("warm selected PTY",w,"Failed to start selected PTY.");a={mode:"main",shell:q(P(a.shell),S)},k(a.shell),y()})}):ha();return}if(a.menuIndex===1){let p=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}xn(0)}};function Ma(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=la(a.menuIndex,m);if(u.kind!=="noop"){if(u.kind==="render"){a={...a,menuIndex:u.menuIndex},y();return}if(u.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},G=!0,y());return}if(u.kind==="help"){let p=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="runners"){let p=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="error-log"){let p=a.parentVariant;La(p)}}}async function La(m){let u;try{u=await vo(n)}catch(p){let g=U("open error log",p,"Failed to read Craig error log.");u={path:n.errorLogFile,lines:[`Unable to read error log: ${g}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:u,...m!==void 0?{parentVariant:m}:{}},G=!0,y())}function Oa(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=da(At(a),r,m,s);if(u.kind!=="noop"){if(u.kind==="back"){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="render"){a={...a,runnerOptions:u.state},y();return}Ra(u.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:u.state},y())}).catch(p=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let g=U("save runner option",p,"Failed to save runner option."),w=q(P(a.shell),g);a={...a,shell:w,runnerOptions:{...At(a),message:g}},y()})}}function Fa(){De=Date.now()+600,ne&&clearTimeout(ne),ne=setTimeout(()=>{De=null,ne=null,y()},600)}let Xr=m=>{let u=$p(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){F.detach(),j=!1,te=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let p=Lp(u);if(p!==0){vn(p);return}let g=Op(u);if(g){j=!1,te={key:g,at:Date.now()},F.writeKey(g);return}if(j&&u!=="\r"&&u!==`
152
+ `);if(d===-1)return;let f=o.slice(0,d);c(),s.end();try{n(JSON.parse(f))}catch(h){r(h instanceof Error?h:new Error(String(h)))}}),s.once("close",()=>c())})}async function da(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!await dn(e))return;await Ur(50)}}function ka(e){return new Promise((t,n)=>{let r=ua(e);r.once("connect",()=>t(r)),r.once("error",n)})}function sp(e,t){return new Promise((n,r)=>{e.once("error",r),e.listen(t,n)})}function ln(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
153
+ `)}catch{}}function Ra(e){try{return process.kill(e,0),!0}catch{return!1}}function Ur(e){return new Promise(t=>setTimeout(t,e))}function op(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}import bR from"picocolors";var ip=[" \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 qr(){return[...ip]}var ap=["Start","Options","Exit"],cp=["Resume","Options","Exit"],pn=2,mn=2,gn=2,lp=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),dp=new RegExp("\x1B\\[(?:0)?m","g"),up=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),fp=/https?:\/\/[^\s<>"']+/g,Kr="\x1B[0m",Vr="\x1B]8;;\x1B\\",E={panelBg:{bg:"0a0a0a",fg:"c0caf5"},panelMuted:{bg:"0a0a0a",fg:"565f89"},panelSelected:{bg:"1a1b26",fg:"c0caf5"},panelFocused:{bg:"1a1b26",fg:"7aa2f7"},divider:{bg:"0a0a0a",fg:"292e42"},rail:{bg:"0a0a0a",fg:"c0caf5"},overlay:{bg:"06060f",fg:"565f89"},overlayTitle:{bg:"06060f",fg:"565f89"},overlayLogo:{bg:"06060f",fg:"9ece6a"},overlaySubtitle:{bg:"06060f",fg:"41a6b5"},overlayMenuSelected:{bg:"06060f",fg:"7aa2f7"},accent:{fg:"7aa2f7"},success:{fg:"9ece6a"},pending:{fg:"e0af68"},error:{fg:"f7768e"},mutedfg:{fg:"565f89"},disabled:{fg:"3b4261"}};function Pa(e,t={}){return Hr(e,{subtitle:"crAIg is that you?",menuItems:ap,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function ba(e,t={}){return Hr(e,{subtitle:"Control mode is paused.",menuItems:cp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var un=[" 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."],pp=["Help"];function Gr(e,t={}){return Hr(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??pp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Ia(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(N(" ".repeat(e.width),n,r)),o=qr(),i=Math.max(1,Math.floor((e.height-o.length-2-un.length)/2));for(let f=0;f<o.length&&!(i+f>=e.height);f+=1)s[i+f]=N(Ea(o[f]??"",e.width),n,E.overlayLogo);let c=Math.max(...un.map(f=>f.length)),l=Math.max(0,Math.floor((e.width-c)/2)),d=i+o.length+2;for(let f=0;f<un.length;f+=1){let h=d+f;if(h>=e.height)break;let R=un[f]??"";s[h]=N(Pe(" ".repeat(l)+R,e.width),n,r)}return s.join(`
154
+ `)}function Sa(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(N(" ".repeat(e.width),n,r)),o="Error Log",i=t.errorLogPath??"",c=t.errorLogLines??[],l=Math.max(20,e.width-8),d=Math.max(0,Math.floor((e.width-l)/2)),f=[{text:o,tone:"selected"},{text:i,tone:"muted"},te(),...c.length>0?c.map(k=>({text:k})):[{text:"No Craig errors have been logged.",tone:"muted"}],te(),{text:"Esc returns to Options.",tone:"muted"}],h=bt(f,e.height-2),R=Math.max(1,Math.floor((e.height-h.length)/2));for(let k=0;k<h.length;k+=1){let S=R+k;if(S>=e.height)break;let T=h[k]??te(),a=`${" ".repeat(d)}${wn(T.text,l)}`,H=T.tone==="selected"?E.overlayMenuSelected:T.tone==="muted"?E.overlay:E.panelBg;s[S]=N(Pe(a,e.width),n,H)}return s.join(`
155
+ `)}function Ca(e,t,n={}){let r=n.color??!0,s=ge.leftWidth,o=ge.rightWidth,i=ge.dividerWidth,c=n.centerOnly??!1,l=c?e.width:e.width-s-o-i*2,d=e.height-ge.topRailHeight-1,f=n.focusFlashActive??!1,h={bg:E.divider.bg,fg:"9ece6a"},R=f&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?h:E.divider,k=f&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?h:E.divider,S=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=N(Pe(S,e.width),r,E.rail),a=gp(t,s-pn-mn,d,r),H=hp(t,l,d,r),_=kp(t,o,d,r),ne=t.inputMode==="terminal",x=[];for(let Z=0;Z<d;Z+=1){if(c){x.push(fn(H[Z]??te(),l,r,"center"));continue}let ve=fn(a[Z]??te(),s,r,"left"),he=N("\u2502",r,R),Ee=fn(H[Z]??te(),l,r,"center"),re=N("\u2502",r,k),He=fn(_[Z]??te(),o,r,"right");x.push(`${ve}${he}${Ee}${re}${He}`)}let Oe=ne||t.modalInput?E.panelBg:E.panelMuted,xe=mp(t.footerText,t.footerToast,e.width,r,Oe);return[T,...x,xe].join(`
156
+ `)}function mp(e,t,n,r,s){let o=` ${e}`;if(!t)return N(Pe(o,n),r,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,c=X(i),l=X(o),d=Math.max(1,n-l-c-2),f=l+d+c+2>n?wn(o,Math.max(0,n-c-3)):o,h=Math.max(1,n-X(f)-c-2),R=t.tone==="error"?jp(i,r,s):rt(i,r,s),k=`${f}${" ".repeat(h)}${R} `;return N(Pe(k,n),r,s)}function Hr(e,t){let n=new Array(e.height).fill(N(" ".repeat(e.width),t.color,E.overlay)),r=qr(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,f)=>`${f===t.menuIndex?">":" "} ${d.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],c=[...r,"",t.subtitle,"",...o,...i],l=Math.max(1,Math.floor((e.height-c.length)/2));for(let d=0;d<c.length;d+=1){let f=Ea(c[d]??"",e.width);if(d<r.length){n[l+d]=N(f,t.color,E.overlayLogo);continue}if(d===r.length+1){n[l+d]=N(f,t.color,E.overlaySubtitle);continue}let h=d-(r.length+3),k=h>=0&&h<t.menuItems.length&&h===t.menuIndex?E.overlayMenuSelected:E.overlay;n[l+d]=N(f,t.color,k)}if(t.versionText){let d=t.updateText?" (update available)":"",f=`${t.versionText}${d} `,h=" ".repeat(Math.max(0,e.width-X(f)));n[e.height-1]=N(`${h}${zr(f,t.color,E.overlay)}`,t.color,E.overlay)}return n.join(`
157
+ `)}function gp(e,t,n,r){let s=yp(e.runners),o=1,i=e.leftTree.map(l=>Tp(l,t,r));return[...bt(i,n-o),s]}function hp(e,t,n,r){let s=t-2,o=e.tabs.find(x=>x.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:Lp(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?rt(l,r,E.panelBg):hn(l,r,E.panelMuted)}`,f=[`${hn(e.centerHeader.tabLabel,r,E.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(x=>x.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!Fi(h)?e.centerTranscript.map(x=>({...x})):wp(e),k=Pp(e.tabs,r,e.focusedRegion==="center"),S=" engaged ",T=S.length+2,a=e.inputMode==="terminal"?rt(`${S}\u25CF `,r,E.panelBg):"",H=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-X(k)-T)):"",ne=[{text:e.inputMode==="terminal"?`${k}${H}${a}`:k},{text:d,tone:"muted"},{text:f},te(),...R];return bt(ne,n)}function wp(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},te(),{text:e.terminal.error},te(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(r=>r.active)?.id??"",n=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${n.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(r=>({text:Da(r.segments),segments:r.segments,fullBleed:!0}))}function kp(e,t,n,r){let s=e.rightInspection?Rp(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,n):bt([{text:"CONTEXT"},te(),...e.rightContext.map(o=>bp(o,r)),...e.actionMessage?[te(),{text:e.actionMessage}]:[]],n);return bt(s,n)}function Rp(e,t){let n=e.slice(0,2),r=e.slice(2),s=Math.max(0,t-n.length),o=r.findIndex(c=>c.focused||c.selected),i=o===-1?0:Fp(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Ta(c)),...r.slice(i,i+s).map(c=>Ta(c))]}function Ta(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",n=e.focused||e.selected?"selected":e.muted?"muted":"default",r=`${t}${e.text}`;if(e.segments)return{text:r,segments:[{text:t},...e.segments],tone:n};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:r,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:n}}return e.color?{text:r,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:n}:{text:r,tone:n}}function Tp(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${rt("\u25CF",n,e.selected?E.panelSelected:E.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,S)=>k+X(S.text),0):0,l=t-X(o)-X(s)-c,d=e.selected?e.text:e.focused?rt(e.text,n,E.panelBg):e.panelHeader?hn(e.text,n,E.panelMuted):e.text,f=Pe(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${f}${o}${i}`},...e.prBadge];return{text:`${f}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${f}${o}${i}`,tone:h}}function yp(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:E.success.fg}}):n.push({text:s.text,style:{fg:E.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function Pp(e,t,n){return e.map(r=>r.active?n?rt(r.label,t,E.panelBg):hn(r.label,t,E.panelBg):zr(r.label,t,E.panelBg)).join(" ")}function bp(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?zr(e.value,t,E.panelBg):e.value}`}}function fn(e,t,n,r){let s=Ip(r,e.tone??"default"),o=Sp(e,n,s);if(r==="left"){if(e.fullBleed)return N(Pe(o,t),n,s);let c=t-pn-mn;if(e.rightAlign){let d=X(o),f=Math.max(0,c-d),h=`${" ".repeat(pn)}${" ".repeat(f)}${o}${" ".repeat(mn)}`;return N(h,n,s)}let l=`${" ".repeat(pn)}${Pe(o,c)}${" ".repeat(mn)}`;return N(l,n,s)}return r==="center"&&e.fullBleed?Cp(e,t,n,s):N(Pe(` ${o}`,t),n,s)}function Ip(e,t){return t==="selected"||t==="focused"?E.panelSelected:t==="muted"?E.panelMuted:E.panelBg}function bt(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(te());return n}function te(){return{text:""}}function Sp(e,t,n){return e.segments?e.segments.map(r=>xa(r,t,n)).join(""):e.text}function Cp(e,t,n,r){let s=" ".repeat(gn),o=Math.max(0,t-gn*2);if(!e.segments)return N(`${s}${Pe(e.text,o)}${s}`,n,r);let i=Ep(e.segments,o),c=`${s}${i.map(l=>xa(l,n,r)).join("")}${s}${n?Vr:""}`;return N(c,n,r)}function xa(e,t,n){let r=e.href?`${va(e.href)}${e.text}${Vr}`:xp(e.text);return!t||!e.style?r:`${It(Dp(e.style,n))}${Mp(e.style)}${r}${Kr}${It(n)}`}function xp(e){return e.replace(fp,t=>{let[n,r]=vp(t);return`${va(n)}${n}${Vr}${r}`})}function vp(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function va(e){return`\x1B]8;;${e}\x1B\\`}function Ep(e,t){let n=Ap(e,t);return $p(n,t)}function Ap(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=X(s.text);if(o<=r){n.push(s),r-=o;continue}let i=wn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function $p(e,t){let n=X(Da(e));if(n>=t)return e;let r=e.at(-1)?.style;return r?.bg?[...e,{text:" ".repeat(t-n),style:r}]:[...e,{text:" ".repeat(t-n)}]}function Dp(e,t){let n=e.inverse?e.bg??t.bg:e.fg,r=e.inverse?e.fg??t.fg:e.bg,s={},o=n??t.fg,i=r??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function Mp(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 Lp(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function Ea(e,t){let n=Math.max(0,t-X(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Pe(e,t){let n=X(e);return n>=t?Op(e,t):e+" ".repeat(t-n)}function Op(e,t){if(t<=0)return"";if(X(e)<=t)return e;let n=$a(e);return wn(n,Math.max(0,t-1))+"\u2026"}function X(e){let t=0;for(let n of Array.from($a(e)))t+=Aa(n);return t}function wn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=Aa(s);if(r+o>t)break;n+=s,r+=o}return n}function Aa(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 Fp(e,t,n){return Math.min(Math.max(e,t),n)}function $a(e){return e.replace(up,"").replace(lp,"")}function Da(e){return e.map(t=>t.text).join("")}function N(e,t,n){if(!t)return e;let r=It(n),s=e.replace(dp,`${Kr}${r}`);return`${r}${s}${Kr}`}function It(e){let t=[];return e.fg&&t.push(`38;2;${ya(e.fg).join(";")}`),e.bg&&t.push(`48;2;${ya(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function ya(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function rt(e,t,n){return kn(e,t,E.success.fg,n)}function jp(e,t,n){return kn(e,t,E.error.fg,n)}function hn(e,t,n){return kn(e,t,E.accent.fg,n)}function zr(e,t,n){return kn(e,t,E.mutedfg.fg,n)}function kn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${It(s)}${e}${It(r)}`}ee();var Yr=["Runners","Error Log","Help"];function Jr(e,t){return F.map(n=>{let r=b.runners.getProfile(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function La(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 Oa(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Yr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Qr(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Fa(e,t,n,r){if(e.pathEdit)return Np({...e,pathEdit:e.pathEdit},t,n);let s=Jr(t,e).length;if(n==="UP"||n==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(n==="DOWN"||n==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(n==="ESCAPE")return{kind:"back",state:e};if(n==="e"){let c=F[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!Qr(n))return{kind:"noop",state:e};let o=F[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&r.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:Wp(t,o,!i),state:{...e,message:`${b.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function Np(e,t,n){if(n==="ESCAPE")return{kind:"render",state:Ma({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Qr(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:_p(t,r,s.length>0?s:null),state:Ma({...e,message:s.length>0?`${b.runners.getProfile(r).displayName} executable saved.`:`${b.runners.getProfile(r).displayName} executable reset to default.`})}}return Bp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function Wp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function _p(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function Ma(e){let t={...e};return delete t.pathEdit,t}function Qr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
158
+ `}function Bp(e){return e.length===1&&e>=" "&&e!=="\x7F"}var Vp=Up(import.meta.url),Gp=Vp("terminal-kit"),Hp=Gp.terminal;async function Wa(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=be(t);await tt(t);let r=await b.load(n),s=b.runners.getEnabled(r),o=e.uiStateFile?await ue({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await St(t,void 0,s),d=rn($i(o,r),l);l=await St(t,d,s);let f=()=>{},h={workspaceRoot:t,onUpdate:()=>f(),resolveSessionSpec:(S,T)=>Qp(l,T,t)},R=e.ptyRuntime??await fa({...h,paths:n}),k=S=>{if(!e.uiStateFile)return;o=Di(o,S);let T=o;i=i.then(()=>ae({uiStateFile:e.uiStateFile},T),()=>ae({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(S=>{let T=e.terminal??Hp,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:rn(d,l)},H=!1,_=!1,ne=null,x=0,Oe=0,xe=null,Z=null,ve=null,he=null,Ee=null,re=null,He=null,yn=!1,Pn=null,Zr=`Craig v${b.version.getCurrent()}`,bn=null,In=0,z=!0,Sn=null,y=()=>{},W=R;f=()=>{a.mode==="main"&&(a={mode:"main",shell:ot(a.shell)},ve||(ve=setTimeout(()=>{ve=null,a.mode==="main"&&y()},50)))};function ot(m){return Ve(m,W.getViewState(es(m)))}function es(m){let u=ze(m);return u?u.ptyTabs.some(p=>p.id===m.activeTab)?m.activeTab:m.activeTab==="agent"||m.activeTab==="terminal"?u.ptyTabs.find(p=>p.kind===m.activeTab)?.id??m.selectedPtyTabId:m.selectedPtyTabId:m.selectedPtyTabId}function P(m){return ot(zp(m,l))}function ze(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function ts(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(p=>p.id));await W.pruneStale?.(m),await W.hydrateSessions?.(m)}function Ua(){ts().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function qa(m){let u=P(m),p=ze(u),g=es(u);if(!p||!g||!p.ptyTabs.some(j=>j.id===g))return u;let w=W.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return Ve(u,w);let C=await W.ensureSession(p.id,g,xt(Le(T.width,T.height)));return Ve({...u,inputMode:"control"},C)}function ns(m,u){return he&&(clearTimeout(he),he=null),u?(he=setTimeout(()=>{he=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...m,footerToast:u}):{...m,footerToast:null}}function Ka(m,u){return ns(m,u?{tone:"success",message:u}:null)}function K(m,u,p){let g=u instanceof Error?u.message:p,w=u instanceof Error?u.stack??u.message:String(u);return wr(n,{context:m,message:g,details:w}),g}function V(m,u){return ns(m,{tone:"error",message:u})}function Fe(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function rs(m){let u=ze(m),p=l.inspection,g=p&&p.taskId===u?.id?p:null,w=Yp(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:Jp(l),centerTabIds:Ni(u,m),ptyTabIds:u?.ptyTabs.map(C=>C.id)??[],filePathIds:g?.filePaths??[],fileTreeRowIds:w.map(C=>C.path),fileTreeFileIds:w.filter(C=>C.kind==="file").map(C=>C.path),fileTreeDirectoryIds:w.filter(C=>C.kind==="directory").map(C=>C.path),diffPathIds:g?.diffPaths??[],diffPathRanges:[],fileLineCount:g?.selectedFile.lines.length??0,diffLineCount:g?.selectedDiff.lines.length??0,reviewRowCount:Zi(m,u),pageRows:Math.max(5,Le(T.width,T.height).height-ge.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(C=>C.repoId)??[]}}async function Va(m){await b.save(n,m),r=m,s=b.runners.getEnabled(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}}async function Ga(m){let u=m.selectedTaskId;u&&await Fe(async()=>{let p=await U(n,u);!p.ptyTabs.some(g=>g.id===m.activeTab)||p.selectedPtyTabId===m.activeTab||await A(n,{...p,selectedPtyTabId:m.activeTab})})}async function se(){let m=(a.mode==="main",a.shell);l=await St(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function ss(m){let u=++In,p=_a(l.tasks,m),g=l.inspection,w;if(p&&g?.taskId===p.id){let C={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},j=await ri(p,g,C);if(u!==In)return;w={...l,inspection:j}}else if(w=await St(t,m,s),u!==In)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function Cn(m){let u=await lm(m);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:u,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function os(m){try{let u=P(m),p=ze(u),g=u.selectedPtyTabId;if(p&&u.focusedRegion==="tasks"){let j=p.ptyTabs.find(de=>de.kind==="agent")??null;j?g=j.id:(p=await is(p),await se(),g=p.selectedPtyTabId)}p&&!g&&(p=await is(p),await se(),g=p.selectedPtyTabId);let w=P({...u,activeTab:g??u.activeTab,selectedPtyTabId:g,focusedRegion:g?"center":u.focusedRegion});if(!w.selectedTaskId||!g){a={mode:"main",shell:w},y();return}a={mode:"main",shell:Ve({...w,inputMode:"terminal"},W.getViewState(g))},k(a.shell);let C=await W.ensureSession(w.selectedTaskId,g,xt(Le(T.width,T.height)));_=Xr(g),ne=null,a={mode:"main",shell:Ve({...w,inputMode:"terminal"},C)},k(a.shell)}catch(u){let p=K("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Xr(m.selectedPtyTabId)&&(await Ha(m.selectedTaskId,p).catch(()=>{}),await se().catch(()=>{})),a={mode:"main",shell:V(Li(P(m),p),p)},k(a.shell)}y()}async function Ha(m,u){await Fe(async()=>{let p=await U(n,m);await A(n,{...p,status:p.status==="running"?"draft":p.status,runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:u})})}async function za(m,u,p){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await Fe(async()=>{let C=await U(n,g.selectedTaskId),j=u??em(C,g.activeTab,g.preferredPtyTabKind),de=ja(C,j,p??void 0,r),it={...C,ptyTabs:[...C.ptyTabs,de],selectedPtyTabId:de.id};return await A(n,it),it});return await se(),P({...g,activeTab:w.selectedPtyTabId??g.activeTab,selectedPtyTabId:w.selectedPtyTabId,preferredPtyTabKind:w.ptyTabs.at(-1)?.kind??g.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${w.ptyTabs.at(-1)?.title??"tab"}`})}async function Ya(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:p,nextSelectedTab:g}=await Fe(async()=>{let w=await U(n,u.selectedTaskId),C=w.ptyTabs.findIndex(En=>En.id===u.activeTab);if(C===-1)throw new Error("Only PTY tabs can be closed.");let j=w.ptyTabs[C],de=w.ptyTabs.filter(En=>En.id!==j.id),it=de[Math.min(C,de.length-1)]??de[C-1]??null;return await A(n,{...w,ptyTabs:de,selectedPtyTabId:it?.id??null}),{closedTab:j,nextSelectedTab:it}});return W.disposeSession(p.id),await se(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${p.title}`})}async function Ja(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let p=ze(u),g=null,w=null;if(p?.type==="project"&&p.repoTargets?.length){let C=await Yt(n,u.selectedTaskId);await se();let j=C.synced+C.discovered+C.notFound;w=`Refreshed ${C.synced}/${j} targets`}else{let{disposition:C,task:j}=await ar(n,u.selectedTaskId);await se(),g=C==="not_found"?`No PR found for ${j.branch}`:null,C!=="not_found"&&(w=`Refreshed checks: ${G(j)?.requiredChecks.length??0} reported`)}return P({...Ka(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function Qa(){if(yn||a.mode!=="main")return;let m=l.tasks;yn=!0;try{if(await Fo(n,m),Pn=null,a.mode!=="main")return;l=await St(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(u){let p=u instanceof Error?u.message:"Background PR discovery failed.";p!==Pn&&(Pn=p,wr(n,{context:"background PR polling",message:p,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{yn=!1}}async function Xa(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:p,task:g}=await Fe(async()=>{let w=await U(n,u.selectedTaskId),C=await pi(n,u.selectedTaskId);return{taskBeforeClose:w,task:C}});for(let w of p.ptyTabs)W.disposeSession(w.id);return await se(),P({...u,selectedActionId:"close-task",actionMessage:g.cleanup.preservedWorktree?`Archived task ${g.id}; worktree preserved`:`Archived task ${g.id}`})}async function Za(m){let u=P(m);if(!u.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await Te(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await ht(n,u.selectedWorkspaceId);let g=await wt(n,u.selectedWorkspaceId);return await se(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function is(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await Fe(async()=>{let C=await U(n,m.id),j=C.ptyTabs.find(de=>de.kind==="agent")??null;j&&await A(n,{...C,selectedPtyTabId:j.id})}),w}let p=ja(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,p],selectedPtyTabId:p.id};return await Fe(async()=>{let w=await U(n,m.id),C=w.ptyTabs.find(j=>j.kind==="agent")??null;if(C){await A(n,{...w,selectedPtyTabId:C.id});return}await A(n,{...w,ptyTabs:[...w.ptyTabs,p],selectedPtyTabId:p.id})}),g}y=()=>{ec();let m=Le(T.width,T.height),u=a.mode==="main"?Ca(m,Gi(P(a.shell),l),{centerOnly:a.shell.centerZoomed,focusFlashActive:Ee!==null&&Date.now()<Ee}):a.variant==="boot"?Pa(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Zr,updateText:bn}):a.variant==="pause"?ba(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Zr,updateText:bn}):a.variant==="options"?Gr(m,{menuIndex:a.menuIndex,optionsMenuItems:Yr}):a.variant==="runners"?Gr(m,{menuIndex:Ct(a).menuIndex,optionsMenuItems:Jr(r,Ct(a)),optionsMessage:La(Ct(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Sa(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Ia(m);z&&(T.moveTo(1,1),T.eraseDisplayBelow(),z=!1),T.noFormat(nm(u)),T.hideCursor(!0)};function ec(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==Sn&&(Sn=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let tc=()=>{process.stdout.off("resize",us),process.off("SIGCONT",fs),T.removeListener("key",as),T.removeListener("unknown",cs),T.removeListener("mouse",ls),xe&&(clearTimeout(xe),xe=null),Z&&(clearTimeout(Z),Z=null),ve&&(clearTimeout(ve),ve=null),he&&(clearTimeout(he),he=null),re&&(clearTimeout(re),re=null),He&&(clearInterval(He),He=null),W.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},xn=m=>{tc(),S(m)},nc=async()=>{if(a.mode!=="main"||H)return;let m=a.shell,u=m.taskPromptInput?.trim()??"";if(!m.selectedRepoId&&!m.selectedWorkspaceId){a={mode:"main",shell:P({...m,taskPromptError:"Select a workspace first."})},y();return}if(u.length===0){a={mode:"main",shell:P({...m,taskPromptError:"Task prompt cannot be empty."})},y();return}H=!0,a={mode:"main",shell:P({...m,actionMessage:`Creating ${m.selectedRunner} task in ${m.selectedWorkspaceId??m.selectedRepoId}...`})},y();let p=null;try{p=await tm(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await se();let g=P({...a.shell,selectedRepoId:p.repoId,selectedWorkspaceId:p.workspaceId,selectedTaskId:p.id,selectedPtyTabId:p.selectedPtyTabId,selectedLeftItemId:`task:${p.id}`,activeTab:p.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),w=await W.ensureSession(p.id,g.selectedPtyTabId??Ba(p,"agent"),xt(Le(T.width,T.height)));_=Xr(g.selectedPtyTabId),a={mode:"main",shell:Ve(g,w)},k(a.shell)}catch(g){g instanceof Rn&&(p=g.task);let w=K("create task",g,"Failed to create task.");p&&(await A(n,{...p,status:"draft",runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:w}).catch(()=>{}),await se().catch(()=>{})),a={mode:"main",shell:V(P({...a.shell,inputMode:"control",selectedTaskId:p?.id??a.shell.selectedTaskId,selectedPtyTabId:p?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:p?`task:${p.id}`:a.shell.selectedLeftItemId,activeTab:p?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:p?null:"",taskPromptError:w,actionMessage:null}),w)}}finally{H=!1,y()}},rc=m=>{if(a.mode!=="main")return;let u=a.shell;if(u.taskPromptInput!==null){if(m==="ESCAPE"){a={mode:"main",shell:P({...u,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Ce(m)){nc();return}if(m==="BACKSPACE"){a={mode:"main",shell:P({...u,taskPromptInput:u.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(m==="CTRL_R"){a={mode:"main",shell:P({...u,selectedRunner:vr(u.selectedRunner,s),taskPromptError:null})},y();return}Oi(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},sc=m=>{if(a.mode!=="main")return;let u=a.shell.workspaceBrowser;if(u){if(m==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(m==="UP"||m==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.max(0,u.selectedIndex-1),error:null}})},y();return}if(m==="DOWN"||m==="j"){let p=Math.max(0,u.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.min(p,u.selectedIndex+1),error:null}})},y();return}if(m==="LEFT"||m==="h"){Cn(st.dirname(u.cwd)).catch(p=>{let g=K("open parent workspace directory",p,"Failed to open parent directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Ce(m)){let p=u.entries[u.selectedIndex]??null;if(!p)return;if((m==="RIGHT"||m==="l")&&(p.kind==="directory"||p.kind==="repo")){Cn(p.path).catch(g=>{let w=K("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}gt(n,p.path).then(async g=>{await se();let w=g.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${g.workspace.id}`,selectedWorkspaceId:g.workspace.id,selectedRepoId:w?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${g.workspace.name??g.workspace.id}`})},k(a.shell),y()}).catch(g=>{let w=K("add workspace",g,"Failed to add workspace.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},as=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){rc(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){sc(u);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(u==="F"){cc(),y();return}Ee!==null&&(Ee=null,re&&(clearTimeout(re),re=null))}if(a.mode==="main"){let p=Mi(a.shell,u,rs(a.shell));if(p.exit){xn(0);return}if(p.detachTerminal){W.detach(),a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(p.changed){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(_&&Ce(u)){_=!1;return}_&&(_=!1),ne=sm(u)?{key:u,at:Date.now()}:null;let g=om(u,a.shell.terminal.scrolledBack??!1);if(g!==0){vn(g);return}W.writeKey(u);return}if(u==="CTRL_C"){xn(0);return}if(u==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},z=!0,y();return}if(p.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(p.state)},z=!0,y();return}if(p.beginTaskPrompt){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(p.openWorkspaceBrowser){Cn(t).catch(g=>{let w=K("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:V(P({...p.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(p.createPtyTab){za(p.state,p.createPtyTabKind,p.createPtyTabRunner).then(g=>{os(g)}).catch(g=>{let w=K("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.closePtyTab){Ya(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("close PTY tab",g,"Failed to close tab.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.refreshPullRequestChecks){Ja(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("refresh PR checks",g,"Failed to refresh PR checks.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.openPrUrl){let g=ze(p.state),w=g?G(g)?.url??null:null;w?dm(w).catch(C=>{let j=K("open PR URL",C,"Failed to open PR in browser.");a={mode:"main",shell:V(P(p.state),j)},y()}):(a={mode:"main",shell:V(P(p.state),"No PR URL available.")},y());return}if(p.closeTask){Xa(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("close task",g,"Failed to close task.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.removeWorkspace){Za(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("remove workspace",g,"Failed to remove workspace.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.attachTerminal){os(p.state);return}if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),ss(a.shell).catch(g=>{let w=K("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:w}),w)},y()});return}p.changed&&(a={mode:"main",shell:P(p.state)},Ga(a.shell).catch(()=>{}),k(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},z=!0,y();return}if(a.variant==="options"){oc(u);return}if(a.variant==="runners"){ac(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Ce(u)){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y()}return}if(a.optionsMessage){(u==="ESCAPE"||Ce(u))&&(a={...a,optionsMessage:null},y());return}if(u==="UP"||u==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(u==="DOWN"||u==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(u==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},z=!0,y());return}if(Ce(u)){if(a.menuIndex===0){let p=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},z=!0,y(),p?uc.then(()=>{if(a.mode!=="main")return;let g=a.shell;qa(g).then(w=>{a.mode!=="main"||a.shell!==g||(a={mode:"main",shell:w},k(a.shell),y())}).catch(w=>{if(a.mode!=="main"||a.shell!==g)return;let C=K("warm selected PTY",w,"Failed to start selected PTY.");a={mode:"main",shell:V(P(a.shell),C)},k(a.shell),y()})}):Ua();return}if(a.menuIndex===1){let p=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}xn(0)}};function oc(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=Oa(a.menuIndex,m);if(u.kind!=="noop"){if(u.kind==="render"){a={...a,menuIndex:u.menuIndex},y();return}if(u.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},z=!0,y());return}if(u.kind==="help"){let p=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}if(u.kind==="runners"){let p=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}if(u.kind==="error-log"){let p=a.parentVariant;ic(p)}}}async function ic(m){let u;try{u=await ti(n)}catch(p){let g=K("open error log",p,"Failed to read Craig error log.");u={path:n.errorLogFile,lines:[`Unable to read error log: ${g}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:u,...m!==void 0?{parentVariant:m}:{}},z=!0,y())}function ac(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=Fa(Ct(a),r,m,s);if(u.kind!=="noop"){if(u.kind==="back"){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}if(u.kind==="render"){a={...a,runnerOptions:u.state},y();return}Va(u.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:u.state},y())}).catch(p=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let g=K("save runner option",p,"Failed to save runner option."),w=V(P(a.shell),g);a={...a,shell:w,runnerOptions:{...Ct(a),message:g}},y()})}}function cc(){Ee=Date.now()+600,re&&clearTimeout(re),re=setTimeout(()=>{Ee=null,re=null,y()},600)}let cs=m=>{let u=rm(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){W.detach(),_=!1,ne=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let p=im(u);if(p!==0){vn(p);return}let g=am(u);if(g){_=!1,ne={key:g,at:Date.now()},W.writeKey(g);return}if(_&&u!=="\r"&&u!==`
159
159
  `&&u!==`\r
160
- `&&(j=!1),Fp(j,te,u)){j=!1;return}F.write(u)},Zr=m=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){Na(fa(m));return}let u=fa(m);u!==0&&vn(u)};function vn(m){C+=m,!Ae&&(Ae=setTimeout(()=>{Ae=null;let u=C;C=0,u!==0&&(ja(u),y())},16))}function ja(m){F.scrollViewport(m),a={mode:"main",shell:lt(a.shell)}}function es(){G=!0,T.fullscreen(!0)}function Na(m){m!==0&&(Ne+=m,!X&&(X=setTimeout(()=>{X=null;let u=Ne;if(Ne=0,u===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let p=Fe(a.shell,u,Hr(a.shell));if(p.changed){if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),zr(a.shell).catch(g=>{let w=U("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:q(P({...a.shell,actionMessage:w}),w)},y()});return}a={mode:"main",shell:P(p.state)},k(a.shell),y()}},16)))}let ts=()=>{es(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(F.resize($t(je(T.width,T.height))),a={mode:"main",shell:lt(a.shell)}),y()},ns=()=>{es(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(F.resize($t(je(T.width,T.height))),a={mode:"main",shell:lt(a.shell)}),y()};process.stdout.on("resize",ts),process.on("SIGCONT",ns),T.grabInput(!0),Sn="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",Qr),T.on("unknown",Xr),T.on("mouse",Zr),Qe=setInterval(()=>{Sa()},(r.github?.watchIntervalSeconds??5)*1e3),ia().then(m=>{m.updateAvailable&&m.latest&&(bn=`Update available: v${m.latest}`,y())});let Wa=Vr().catch(()=>{});y()})}async function Et(e,t,n){let r=Ce(e),[s,o,i]=await Promise.all([Ge(r),me(r),be(r)]),c=ma(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=c?await $o(c,l):null;return{workspaceRoot:e,workspaces:o.filter(f=>f.status==="active"),repos:s,tasks:i.tasks,inspection:d,...n?{enabledRunnerIds:n}:{}}}function ma(e,t){return t?.selectedTaskId?e.find(n=>n.id===t.selectedTaskId)??null:null}function Pp(e,t){return nn(e,t)}function bp(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function Ip(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function Sp(e,t,n){let r=e.tasks.find(c=>c.ptyTabs.some(l=>l.id===t))??null,s=r?.ptyTabs.find(c=>c.id===t)??null,o=r?.worktreePath??n,i=s?.kind==="agent"?xp(s):[];return r?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:Cp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function Cp(e,t){let n=(e??"").split(ct.delimiter).filter(r=>r.length>0);return n.includes(t)?n.join(ct.delimiter):[...n,t].join(ct.delimiter)}function xp(e){return e.command.length>0?e.command:["codex"]}function At(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function vp(e,t,n){return e.ptyTabs.find(r=>r.id===t)?.kind??n}function ua(e,t,n,r={}){let s=n??e.runner,o=Z(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",c=t==="agent"&&n&&n!==e.runner?`${e.id}:${n}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(k=>k.id)),d=1,f=c;for(;l.has(f);)d+=1,f=`${c}-${d}`;let h=new Date().toISOString(),R=n&&n!==e.runner?n:void 0;return{id:f,kind:t,...R?{runner:R}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?z(s,void 0,r):[],createdAt:h,updatedAt:h}}async function Ep(e,t,n,r,s){let o=await Te(e);Dt(s,o);let i=n?await Ut(e,n,r,{runner:s,config:o}):await gt(e,t??"",r,{runner:s,config:o});try{let d=Ke();await x(Ve(An(s,o).executable,{cwd:i.repoRoot,env:d}),["--help"],{cwd:i.repoRoot,env:d})}catch(d){let f=d instanceof Error?d.message:"Failed to start runner.",h={...i.task,status:"draft",runnerSession:{...i.task.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:f};throw await E(e,h),new Rn(f,h)}let c=ga(i.task,"agent"),l={...i.task,status:"running",selectedPtyTabId:c,runnerSession:{...i.task.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await E(e,l),await ae({uiStateFile:e.uiStateFile},{...await fe({uiStateFile:e.uiStateFile})??Pe(),version:1,selectedRepoId:l.repoId,selectedWorkspaceId:l.workspaceId,selectedTaskId:l.id,selectedPtyTabId:l.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:l.selectedPtyTabId??"agent",selectedActionId:"commit",updatedAt:new Date().toISOString()}),l}var Rn=class extends Error{task;constructor(t,n){super(t),this.name="InteractiveTaskStartupError",this.task=n}};function ga(e,t){let n=e.ptyTabs.find(r=>r.kind===t);if(!n)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return n.id}function $t(e){return{columns:Math.max(20,e.width-he.leftWidth-he.rightWidth-he.dividerWidth-mn*2),rows:Math.max(5,e.height-he.topRailHeight-5)}}function Ap(e){return e.split(`
161
- `).map((t,n)=>`\x1B[${n+1};1H${t}`).join("")}function $p(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Dp(e){return e.length===1||Ee(e)||e==="BACKSPACE"||e==="TAB"}function Ur(e){return typeof e=="string"&&new RegExp(`:(?:agent|${N.join("|")})(?:-\\d+)?$`).test(e)}function Mp(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 fa(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Lp(e){let t=new RegExp("\x1B\\[<(\\d+);\\d+;\\d+[mM]").exec(e);if(!t?.[1])return 0;let n=Number.parseInt(t[1],10);return n===64?-3:n===65?3:0}function Op(e){return e==="\x1B[13;2u"?"SHIFT_ENTER":null}function Fp(e,t,n){return n.length===0?!1:e&&(n==="\r"||n===`
160
+ `&&(_=!1),cm(_,ne,u)){_=!1;return}W.write(u)},ls=m=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){dc(Na(m));return}let u=Na(m);u!==0&&vn(u)};function vn(m){x+=m,!xe&&(xe=setTimeout(()=>{xe=null;let u=x;x=0,u!==0&&(lc(u),y())},16))}function lc(m){W.scrollViewport(m),a={mode:"main",shell:ot(a.shell)}}function ds(){z=!0,T.fullscreen(!0)}function dc(m){m!==0&&(Oe+=m,!Z&&(Z=setTimeout(()=>{Z=null;let u=Oe;if(Oe=0,u===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let p=Me(a.shell,u,rs(a.shell));if(p.changed){if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),ss(a.shell).catch(g=>{let w=K("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:w}),w)},y()});return}a={mode:"main",shell:P(p.state)},k(a.shell),y()}},16)))}let us=()=>{ds(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(W.resize(xt(Le(T.width,T.height))),a={mode:"main",shell:ot(a.shell)}),y()},fs=()=>{ds(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(W.resize(xt(Le(T.width,T.height))),a={mode:"main",shell:ot(a.shell)}),y()};process.stdout.on("resize",us),process.on("SIGCONT",fs),T.grabInput(!0),Sn="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",as),T.on("unknown",cs),T.on("mouse",ls),He=setInterval(()=>{Qa()},(r.github?.watchIntervalSeconds??5)*1e3),b.version.checkForUpdate().then(m=>{m.updateAvailable&&m.latest&&(bn=`Update available: v${m.latest}`,y())});let uc=ts().catch(()=>{});y()})}async function St(e,t,n){let r=be(e),[s,o,i]=await Promise.all([Ue(r),pe(r),Te(r)]),c=_a(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=c?await si(c,l):null;return{workspaceRoot:e,workspaces:o.filter(f=>f.status==="active"),repos:s,tasks:i.tasks,inspection:d,...n?{enabledRunnerIds:n}:{}}}function _a(e,t){return t?.selectedTaskId?e.find(n=>n.id===t.selectedTaskId)??null:null}function zp(e,t){return rn(e,t)}function Yp(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function Jp(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function Qp(e,t,n){let r=e.tasks.find(c=>c.ptyTabs.some(l=>l.id===t))??null,s=r?.ptyTabs.find(c=>c.id===t)??null,o=r?.worktreePath??n,i=s?.kind==="agent"?Zp(s):[];return r?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:Xp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function Xp(e,t){let n=(e??"").split(st.delimiter).filter(r=>r.length>0);return n.includes(t)?n.join(st.delimiter):[...n,t].join(st.delimiter)}function Zp(e){return e.command.length>0?e.command:["codex"]}function Ct(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function em(e,t,n){return e.ptyTabs.find(r=>r.id===t)?.kind??n}function ja(e,t,n,r={}){let s=n??e.runner,o=b.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",c=t==="agent"&&n&&n!==e.runner?`${e.id}:${n}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(k=>k.id)),d=1,f=c;for(;l.has(f);)d+=1,f=`${c}-${d}`;let h=new Date().toISOString(),R=n&&n!==e.runner?n:void 0;return{id:f,kind:t,...R?{runner:R}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?b.runners.buildCommand(s,void 0,r):[],createdAt:h,updatedAt:h}}async function tm(e,t,n,r,s){let o=await b.load(e);b.runners.assertEnabled(s,o);let i=n?await qt(e,n,r,{runner:s,config:o}):await ut(e,t??"",r,{runner:s,config:o});try{let d=_e();await v(Be(b.runners.getConfiguredProfile(s,o).executable,{cwd:i.repoRoot,env:d}),["--help"],{cwd:i.repoRoot,env:d})}catch(d){let f=d instanceof Error?d.message:"Failed to start runner.",h={...i.task,status:"draft",runnerSession:{...i.task.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:f};throw await A(e,h),new Rn(f,h)}let c=Ba(i.task,"agent"),l={...i.task,status:"running",selectedPtyTabId:c,runnerSession:{...i.task.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await A(e,l),await ae({uiStateFile:e.uiStateFile},{...await ue({uiStateFile:e.uiStateFile})??Re(),version:1,selectedRepoId:l.repoId,selectedWorkspaceId:l.workspaceId,selectedTaskId:l.id,selectedPtyTabId:l.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:l.selectedPtyTabId??"agent",selectedActionId:"commit",updatedAt:new Date().toISOString()}),l}var Rn=class extends Error{task;constructor(t,n){super(t),this.name="InteractiveTaskStartupError",this.task=n}};function Ba(e,t){let n=e.ptyTabs.find(r=>r.kind===t);if(!n)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return n.id}function xt(e){return{columns:Math.max(20,e.width-ge.leftWidth-ge.rightWidth-ge.dividerWidth-gn*2),rows:Math.max(5,e.height-ge.topRailHeight-5)}}function nm(e){return e.split(`
161
+ `).map((t,n)=>`\x1B[${n+1};1H${t}`).join("")}function rm(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function sm(e){return e.length===1||Ce(e)||e==="BACKSPACE"||e==="TAB"}function Xr(e){return typeof e=="string"&&new RegExp(`:(?:agent|${F.join("|")})(?:-\\d+)?$`).test(e)}function om(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 Na(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function im(e){let t=new RegExp("\x1B\\[<(\\d+);\\d+;\\d+[mM]").exec(e);if(!t?.[1])return 0;let n=Number.parseInt(t[1],10);return n===64?-3:n===65?3:0}function am(e){return e==="\x1B[13;2u"?"SHIFT_ENTER":null}function cm(e,t,n){return n.length===0?!1:e&&(n==="\r"||n===`
162
162
  `||n===`\r
163
- `)?!0:!t||Date.now()-t.at>=30?!1:n===t.key?!0:n.length<=4&&n.split("").every(r=>r===t.key)}async function jp(e){let t=await wp(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory())continue;let s=ct.join(e,r.name);n.push({name:r.name,path:s,kind:await Wp(s)?"repo":"directory"})}return n.sort((r,s)=>r.kind!==s.kind?r.kind==="repo"?-1:1:r.name.localeCompare(s.name)),{cwd:e,entries:n,selectedIndex:0,error:null}}async function Np(e){let{spawn:t}=await import("node:child_process"),n=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((r,s)=>{let o=t(n,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",r)})}async function Wp(e){let t=ct.join(e,".git");return await kp(t).catch(()=>null)!==null}function Tn(){return process.cwd()}async function _p(){try{if(process.argv[2]==="__craig-daemon"){let c=process.argv[3]??Tn(),l=Ce(c);return await ot(c),await _i(l),0}if(process.argv[2]==="__craig-daemon-shutdown"){let c=process.argv[3]??Tn(),l=Ce(c);return await ot(c),await Bi(l),0}let e=ss(process.argv.slice(2)),t=Tn(),n=Ce(t),r=await ot(t),s={paths:n};if(e.mode==="interactive")return await pa({uiStateFile:n.uiStateFile,workspaceRoot:n.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let o=await Co(e.command,s),i=xo(o);return i.length>0&&process.stdout.write(`${i}
163
+ `)?!0:!t||Date.now()-t.at>=30?!1:n===t.key?!0:n.length<=4&&n.split("").every(r=>r===t.key)}async function lm(e){let t=await qp(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory())continue;let s=st.join(e,r.name);n.push({name:r.name,path:s,kind:await um(s)?"repo":"directory"})}return n.sort((r,s)=>r.kind!==s.kind?r.kind==="repo"?-1:1:r.name.localeCompare(s.name)),{cwd:e,entries:n,selectedIndex:0,error:null}}async function dm(e){let{spawn:t}=await import("node:child_process"),n=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((r,s)=>{let o=t(n,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",r)})}async function um(e){let t=st.join(e,".git");return await Kp(t).catch(()=>null)!==null}function Tn(){return process.cwd()}async function fm(){try{if(process.argv[2]==="__craig-daemon"){let c=process.argv[3]??Tn(),l=be(c);return await tt(c),await pa(l),0}if(process.argv[2]==="__craig-daemon-shutdown"){let c=process.argv[3]??Tn(),l=be(c);return await tt(c),await ma(l),0}let e=Ms(process.argv.slice(2)),t=Tn(),n=be(t),r=await tt(t),s={paths:n};if(e.mode==="interactive")return await Wa({uiStateFile:n.uiStateFile,workspaceRoot:n.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let o=await Zo(e.command,s),i=ei(o);return i.length>0&&process.stdout.write(`${i}
164
164
  `),0}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
165
- `),1}}var Bp=await _p();process.exit(Bp);
165
+ `),1}}var pm=await fm();process.exit(pm);