craig-cli 0.6.8 → 0.6.10

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