craig-cli 0.7.2 → 0.7.4
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.
- package/dist/cli.js +53 -53
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Qa(r,e)}catch(o){throw await s.close().catch(()=>{}),await Xa(r,{force:!0}).catch(()=>{}),o}}var ye=ke(()=>{"use strict"});import{readFile as oc}from"node:fs/promises";async function oe(e){let t=await oc(e.indexFile,"utf8"),n=JSON.parse(t);return Mn(n,e.workspaceRoot,e.indexFile)}async function Ue(e,t){let n={...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()};await W(e.indexFile,n)}function Mn(e,t,n){if(!ic(e))throw new Error(`Craig index at ${n} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${n} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e}function ic(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(n=>typeof n=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(n=>typeof n=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(n=>typeof n=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}var qe=ke(()=>{"use strict";ye()});import{readFile as ac}from"node:fs/promises";async function _(e,t){let n=await ac(Ln(e,t),"utf8"),r=JSON.parse(n);return cc(r,Ln(e,t))}async function E(e,t){let n={...t,updatedAt:new Date().toISOString()};await W(Ln(e,t.id),n)}async function On(e,t){let n=await oe(e);n.taskIds.includes(t)||await Ue(e,{...n,taskIds:[...n.taskIds,t]})}function Ln(e,t){return`${e.tasksDir}/${t}.json`}function cc(e,t){let n=lc(e);if(!uc(n))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function lc(e){if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Fn(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[],ptyTabs:mc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:fc(t.repoTargets),runnerSession:t.runnerSession??dc(t),checks:yc(t),lastCommit:t.lastCommit??null,prs:Pc(t),artifacts:Cc(t),cleanup:xc(t)}}function dc(e){if(typeof e.title!="string")return null;let t=Fn(e.runner);return{command:z(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}}function uc(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&et(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(n=>typeof n=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&cs(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||pc(t.repoTargets))&&hc(t.runnerSession)&&wc(t.prompt)&&ls(t.checks)&&ds(t.lastCommit)&&Rc(t.prs)&&Tc(t.artifacts)&&fs(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}function fc(e){if(Array.isArray(e))return e.filter(as)}function pc(e){return Array.isArray(e)&&e.every(as)}function as(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&ls(t.checks)&&ds(t.lastCommit)&&us(t.pullRequest)&&fs(t.cleanup)}function mc(e){if(cs(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return gc(e.id,e.title,t,Fn(e.runner))}function gc(e,t,n,r){let s=Z(r);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:z(r),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function Fn(e){return e&&et(e)?e:"codex"}function cs(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string")}function hc(e){return typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null)}function wc(e){return typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string"}function ls(e){return typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number")}function ds(e){return e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string"}function us(e){return typeof e=="object"&&e!==null&&e.provider==="github"&&kc(e.requiredChecks)}function kc(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null))}function Rc(e){return Array.isArray(e)&&e.every(us)}function Tc(e){return typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null)}function fs(e){return typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null)}function yc(e){return e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]}}function Pc(e){if(Array.isArray(e.prs))return e.prs.map(bc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:ps(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:ms(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]}function bc(e){let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:ps(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Ic(t.reviewDecision),requiredChecks:ms(t.requiredChecks),comments:Sc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}}function ps(e){return e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null}function Ic(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Sc(e){return Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let n=t;return typeof n.body!="string"||!n.body.trim()?[]:[{author:typeof n.author=="string"?n.author:null,body:n.body,createdAt:typeof n.createdAt=="string"?n.createdAt:null,url:typeof n.url=="string"?n.url:null}]}):[]}function ms(e){return Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[]}function Cc(e){let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}}function xc(e){return e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}var ie=ke(()=>{"use strict";ye();qe();ue()});import{readFile as vc}from"node:fs/promises";async function fe(e){try{let t=await vc(e.uiStateFile,"utf8"),n=JSON.parse(t);return Ec(n,e.uiStateFile)}catch(t){if($c(t))return null;throw t}}async function ae(e,t){await W(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Pe(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function Ec(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!nt(e,"inputMode")||!nt(e,"focusedRegion")||!nt(e,"activeTab")||!nt(e,"inspectorSection")||!nt(e,"inspectionMode")||!Mt(e,"openInspectionKind")||!Mt(e,"selectedFileTreePath")||!Mt(e,"selectedFilePath")||!Mt(e,"selectedDiffPath")||!Ac(e,"collapsedFileTreePaths")||!nt(e,"selectedActionId")||typeof e.updatedAt!="string")throw new Error(`Craig UI state at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}function nt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Mt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Ac(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(n=>typeof n=="string"))}function $c(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var rt=ke(()=>{"use strict";ye()});import{execFile as Dc}from"node:child_process";import{promisify as Mc}from"node:util";async function x(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr}}catch(r){if(hs(r)){let s=r.stderr?.trim()||r.stdout?.trim()||r.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw r}}async function D(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr,exitCode:0}}catch(r){if(hs(r))return{stdout:r.stdout??"",stderr:r.stderr??"",exitCode:typeof r.code=="number"?r.code:null};throw r}}function hs(e){return e instanceof Error}var gs,ce=ke(()=>{"use strict";gs=Mc(Dc)});import{readFile as Yc,readdir as Jc,rm as Qc}from"node:fs/promises";import Cs from"node:path";async function pe(e,t){let n=await Yc(Ft(e,t),"utf8"),r=JSON.parse(n);return Xc(r,Ft(e,t))}async function jt(e,t){await W(Ft(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function Ge(e){let t=await Jc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>pe(e,Cs.basename(r.name,".json"))))).sort((r,s)=>r.name.localeCompare(s.name)||r.id.localeCompare(s.id))}async function xs(e,t){await Qc(Ft(e,t),{force:!0})}function Ft(e,t){return Cs.join(e.reposDir,`${t}.json`)}function Xc(e,t){if(typeof e!="object"||e===null||typeof e.id!="string"||typeof e.name!="string"||typeof e.rootPath!="string"||typeof e.defaultBranch!="string"||typeof e.createdAt!="string"||typeof e.updatedAt!="string")throw new Error(`Craig repo record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}var He=ke(()=>{"use strict";ye()});import{readFile as Zc,readdir as el,rm as tl}from"node:fs/promises";import vs from"node:path";async function ft(e,t){let n=await Zc(Nt(e,t),"utf8"),r=JSON.parse(n);return nl(r,Nt(e,t))}async function st(e,t){await W(Nt(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function me(e){let t=await el(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>ft(e,vs.basename(r.name,".json"))))).sort((r,s)=>r.id.localeCompare(s.id))}async function Es(e,t){await tl(Nt(e,t),{force:!0})}function Nt(e,t){return vs.join(e.workspacesDir,`${t}.json`)}function nl(e,t){let n=rl(e);if(typeof n!="object"||n===null||typeof n.id!="string"||n.kind!=="repo"&&n.kind!=="project"||typeof n.name!="string"||typeof n.rootPath!="string"||typeof n.primaryRepoId!="string"||typeof n.branch!="string"||n.status!=="active"&&n.status!=="archived"||!Array.isArray(n.linkedRepoIds)||!(n.linkedRepoIds??[]).every(r=>typeof r=="string")||!(n.repoId===void 0||typeof n.repoId=="string")||!Array.isArray(n.discoveredRepoIds)||!(n.discoveredRepoIds??[]).every(r=>typeof r=="string")||!(n.archivedAt===null||typeof n.archivedAt=="string")||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function rl(e){if(typeof e!="object"||e===null)return e;let t=e,n=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??n??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??n??"",repoId:t.kind==="project"?t.repoId:n,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(r=>typeof r=="string"):t.kind==="project"?[]:n?[n]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[]}}var pt=ke(()=>{"use strict";ye()});async function be(e,t){let n=await oe(e),r=[],s=[];await Promise.all(n.taskIds.map(async c=>{try{r.push(await _(e,c))}catch(l){if(ul(l)){s.push(c);return}throw l}}));let i=(t?.includeClosed?r:r.filter(c=>c.status!=="closed")).filter(c=>!(t?.workspaceId&&c.workspaceId!==t.workspaceId||t?.repoId&&c.repoId!==t.repoId&&!(c.repoTargets??[]).some(l=>l.repoId===t.repoId)));return i.sort((c,l)=>c.id.localeCompare(l.id)),s.sort(),{kind:"listTasks",tasks:i,missingTaskIds:s,repoId:t?.repoId??null}}function ul(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var ht=ke(()=>{"use strict";qe();ie()});var To={};Ba(To,{addWorkspace:()=>Rt,archiveWorkspace:()=>Tt,listWorkspaces:()=>sr,removeWorkspace:()=>yt,removeWorkspaceRecord:()=>Yt,restoreWorkspace:()=>or});import{readdir as Yl,realpath as fo,stat as Jl}from"node:fs/promises";import Le from"node:path";async function Rt(e,t){let n=Le.resolve(e.workspaceRoot,t);if(!(await Jl(n).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${n}`);return await wo(n)?Ql(e,n):Xl(e,n)}async function sr(e,t){return{kind:"listWorkspaces",workspaces:(await me(e)).filter(r=>r.status===(t.archived?"archived":"active")),archivedOnly:t.archived}}async function Tt(e,t){let r={...await ft(e,t),status:"archived",archivedAt:new Date().toISOString()};return await st(e,r),await Ro(e,t),{kind:"archiveWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function or(e,t){let r={...await ft(e,t),status:"active",archivedAt:null};await st(e,r);let s=await fe({uiStateFile:e.uiStateFile})??null;return await ae({uiStateFile:e.uiStateFile},{...s??Pe(),selectedWorkspaceId:r.id,selectedRepoId:r.kind==="project"?r.discoveredRepoIds?.[0]??null:r.primaryRepoId,selectedTaskId:null}),{kind:"restoreWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function yt(e,t){let n=await ft(e,t),r=await be(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(r.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await Yt(e,t),await Ro(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}}async function Ql(e,t){let n=await ko(t),r=await Ge(e),s=r.find(h=>h.rootPath===t)??null,o=s?mo(s,n):po(r,t,n),i=`workspace_${o.id}`,l=(await me(e)).find(h=>h.id===i)??null,d=new Date().toISOString(),f=l??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:n,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await jt(e,o),l||await st(e,f),await go(e,{repoIds:[o.id],workspaceIds:[f.id]}),await ho(e,f,o.id),{kind:"createWorkspace",workspace:f,repos:[o],created:!l}}async function Xl(e,t){let n=await Zl(e,t);if(n.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let r=await me(e),s=td(r,Le.basename(t)),o=r.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),c=n.map(d=>d.id),l=o?{...o,discoveredRepoIds:c,primaryRepoId:c[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:Le.basename(t),rootPath:t,primaryRepoId:c[0]??"",discoveredRepoIds:c,branch:"project",status:"active",linkedRepoIds:c,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(n.map(d=>jt(e,d))),await st(e,l),await go(e,{repoIds:c,workspaceIds:[l.id]}),await ho(e,l,c[0]??null),{kind:"createWorkspace",workspace:l,repos:n,created:!o}}async function Zl(e,t){let n=await Yl(t,{withFileTypes:!0}),r=await Ge(e),s=[];for(let o of n){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Le.join(t,o.name);if(!await wo(i))continue;let c=r.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await ko(i);s.push(c?mo(c,l):po([...r,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))}function po(e,t,n){let r=new Date().toISOString();return{id:ed(e,Le.basename(t)),name:Le.basename(t),rootPath:t,defaultBranch:n,createdAt:r,updatedAt:r}}function mo(e,t){return e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()}}function ed(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",r=`repo_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`repo_${n}_${s}`,s+=1;return r}function td(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",r=`workspace_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`workspace_${n}_${s}`,s+=1;return r}async function go(e,t){let n=await oe(e);await Ue(e,{...n,repoIds:[...new Set([...n.repoIds,...t.repoIds])],workspaceIds:[...new Set([...n.workspaceIds,...t.workspaceIds])]})}async function ho(e,t,n){await ae({uiStateFile:e.uiStateFile},{...await fe({uiStateFile:e.uiStateFile})??Pe(),selectedRepoId:n,selectedWorkspaceId:t.id,selectedTaskId:null})}async function wo(e){try{let n=(await x("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[r,s]=await Promise.all([fo(n).catch(()=>Le.resolve(n)),fo(e).catch(()=>Le.resolve(e))]);return r===s}catch{return!1}}async function ko(e){let t=await D("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),n=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&n.length>0)return n;for(let o of["main","master","trunk"])if((await D("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await x("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"}async function Yt(e,t){await Es(e,t);let n=await oe(e);await Ue(e,{...n,workspaceIds:n.workspaceIds.filter(r=>r!==t)})}async function Ro(e,t){let n=await fe({uiStateFile:e.uiStateFile});!n||n.selectedWorkspaceId!==t||await ae({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}var Pt=ke(()=>{"use strict";qe();He();pt();rt();ce();ht()});ue();function ss(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Repo path cannot be empty.
|
|
2
|
+
var Na=Object.defineProperty;var mn=(e,t)=>{for(var n in t)Na(e,n,{get:t[n],enumerable:!0})};var gn={};mn(gn,{RUNNER_IDS:()=>j,assertEnabled:()=>Zr,buildCommand:()=>ns,getConfiguredProfile:()=>ht,getDefault:()=>Xr,getDisplayName:()=>ts,getEnabled:()=>wt,getProfile:()=>Ke,isRunnerType:()=>kt,parse:()=>es});var j=["codex","cursor","claude"];var Qr={codex:{id:"codex",displayName:"Codex",executable:"codex",defaultAgentTitle:"Codex"},cursor:{id:"cursor",displayName:"Cursor",executable:"cursor-agent",defaultAgentTitle:"Cursor"},claude:{id:"claude",displayName:"Claude",executable:"claude",defaultAgentTitle:"Claude"}};var Ke=e=>Qr[e];var ht=(e,t={})=>{let n=Ke(e),r=t.runners?.[e]?.path?.trim();return{...n,executable:r&&r.length>0?r:n.executable}};var wt=(e={})=>j.filter(t=>e.runners?.[t]?.enabled!==!1);var Xr=(e={})=>{let t=wt(e);if(t.length===0)throw new Error("No runners are enabled. Enable at least one runner in .craig/config.json.");return t.includes("codex")?"codex":t[0]};var Zr=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var kt=e=>j.includes(e);var es=e=>{if(!e||e.length===0)return"codex";if(!kt(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${j.join(", ")}.`);return e};var ts=e=>Ke(e).displayName;var ns=(e,t,n={})=>{let r=[ht(e,n).executable];return t&&t.length>0&&r.push(t),r};import{mkdir as Wa,readFile as _a,writeFile as Ba}from"node:fs/promises";import Ua from"node:path";var qa=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",rs=async e=>{try{return await _a(e,"utf8")}catch(t){if(qa(t))return null;throw t}},ss=async(e,t)=>{await Wa(Ua.dirname(e),{recursive:!0}),await Ba(e,t,"utf8")};var Rt=(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(!j.includes(r))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" is not supported. Expected one of: ${j.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${r}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${r}.path" must be a non-empty string.`)}}if(n.checks!==void 0&&(typeof n.checks!="object"||n.checks===null||!Array.isArray(n.checks.commands)||!n.checks.commands.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(n.open!==void 0&&(typeof n.open!="object"||n.open===null||!Array.isArray(n.open.command)||!n.open.command.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(n.github!==void 0){if(typeof n.github!="object"||n.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(n.github.mergeMethod!==void 0&&n.github.mergeMethod!=="merge"&&n.github.mergeMethod!=="rebase"&&n.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(n.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(n.github.watchIntervalSeconds)||n.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return n};var hn=async(e,t={readConfigFile:rs})=>{let n=await t.readConfigFile(e.configFile);if(!n)return{};if(n.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let r;try{r=JSON.parse(n)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Rt(r,e.configFile)};var wn=async(e,t,n={writeConfigFile:ss})=>{Rt(t,e.configFile),await n.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
|
|
3
|
+
`)};var kn={};mn(kn,{checkForUpdate:()=>os,getCurrent:()=>Tt});var Tt=()=>{try{return"0.7.4"}catch{return"unknown"}};var Ka="https://registry.npmjs.org/craig-cli/latest",Va=3600*1e3,Ga={value:null},Ha=(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},os=async(e={fetch:globalThis.fetch,getCurrent:Tt,cache:Ga})=>{let t=e.getCurrent(),n=Date.now();if(e.cache.value&&n-e.cache.value.cachedAt<Va)return e.cache.value.result;let r=null;try{let o=await e.fetch(Ka,{signal:AbortSignal.timeout(5e3)});o.ok&&(r=(await o.json()).version??null)}catch{}let s={current:t,latest:r,updateAvailable:r!==null&&r!==t&&Ha(r,t)};return e.cache.value={result:s,cachedAt:n},s};var b={load:hn,save:wn,runners:gn,version:kn};function is(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Repo path cannot be empty.
|
|
4
4
|
|
|
5
|
-
`+
|
|
5
|
+
`+Q());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
|
|
|
7
|
-
`+
|
|
7
|
+
`+Q());return{mode:"command",command:{kind:"addWorkspace",path:n}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let n=t[2]==="--archived";if(t.length===3&&!n)throw new Error(`Unsupported command: ${t.join(" ")}
|
|
8
8
|
|
|
9
|
-
${
|
|
9
|
+
${Q()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:n}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let n=t.indexOf("--repo"),r=t.indexOf("--workspace"),s=t.indexOf("--runner");if(n===-1&&r===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
|
|
10
10
|
|
|
11
|
-
`+
|
|
11
|
+
`+Q());if(n!==-1&&r!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
|
|
12
12
|
|
|
13
|
-
`+
|
|
13
|
+
`+Q());let o=n===-1?void 0:t[n+1]?.trim()??"",i=r===-1?void 0:t[r+1]?.trim()??"",c=s===-1?void 0:b.runners.parse(t[s+1]?.trim()??""),d=t.filter((p,h)=>h>1&&h!==n&&h!==n+1&&h!==r&&h!==r+1&&h!==s&&h!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
|
|
14
14
|
|
|
15
|
-
`+
|
|
15
|
+
`+Q());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
|
|
16
16
|
|
|
17
|
-
`+
|
|
17
|
+
`+Q());if(d.length===0)throw new Error(`Task prompt cannot be empty.
|
|
18
18
|
|
|
19
|
-
`+
|
|
19
|
+
`+Q());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
|
-
${
|
|
21
|
+
${Q()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:me(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:me(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:me(t[2]),repoId:za(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:me(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
|
|
22
22
|
|
|
23
|
-
${
|
|
24
|
-
`)}function
|
|
23
|
+
${Q()}`)}function Q(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
|
|
24
|
+
`)}function me(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
|
|
25
25
|
|
|
26
|
-
${
|
|
26
|
+
${Q()}`);return t}function za(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
|
|
27
27
|
|
|
28
|
-
${
|
|
29
|
-
`,"utf8")}function is(e,t){if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let n=e;if(n.runners!==void 0){if(typeof n.runners!="object"||n.runners===null||Array.isArray(n.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[r,s]of Object.entries(n.runners)){if(!N.includes(r))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" is not supported. Expected one of: ${N.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${r}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${r}.path" must be a non-empty string.`)}}if(n.checks!==void 0&&(typeof n.checks!="object"||n.checks===null||!Array.isArray(n.checks.commands)||!n.checks.commands.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(n.open!==void 0&&(typeof n.open!="object"||n.open===null||!Array.isArray(n.open.command)||!n.open.command.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(n.github!==void 0){if(typeof n.github!="object"||n.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(n.github.mergeMethod!==void 0&&n.github.mergeMethod!=="merge"&&n.github.mergeMethod!=="rebase"&&n.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(n.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(n.github.watchIntervalSeconds)||n.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return n}function za(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}ye();import{readFile as Za,readdir as nm,rm}from"node:fs/promises";import ec from"node:path";async function tt(e,t){let n=await Za(Dn(e,t),"utf8"),r=JSON.parse(n);return tc(r,Dn(e,t))}async function Be(e,t){await W(Dn(e,t.id),{...t,updatedAt:new Date().toISOString()})}function Dn(e,t){return ec.join(e.sessionsDir,`${t}.json`)}function tc(e,t){let n=sc(e);if(typeof n!="object"||n===null||typeof n.id!="string"||typeof n.taskId!="string"||typeof n.repoId!="string"||typeof n.workspaceId!="string"||n.substrate!=="tmux"||typeof n.sessionName!="string"||typeof n.paneId!="string"||!(n.windowTarget===null||typeof n.windowTarget=="string")||typeof n.worktreePath!="string"||!(n.logPath===null||typeof n.logPath=="string")||!Array.isArray(n.command)||!n.command.every(r=>typeof r=="string")||!["starting","running","exited","failed"].includes(n.status)||!(n.startedAt===null||typeof n.startedAt=="string")||!(n.exitedAt===null||typeof n.exitedAt=="string")||!(n.exitCode===null||typeof n.exitCode=="number")||!(n.lastAttachedAt===null||typeof n.lastAttachedAt=="string")||!rc(n.attach)||!nc(n.snapshot)||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function nc(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function rc(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function sc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(n=>typeof n=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}ie();rt();ce();function Lt(e){return`'${e.replace(/'/g,"'\\''")}'`}import{accessSync as Lc,constants as Oc}from"node:fs";import{homedir as ws}from"node:os";import Me from"node:path";var Fc=[Me.join(ws(),".local","bin"),Me.join(ws(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Rs(e=process.env){return jc([...(e.PATH??"").split(Me.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:Fc])}function Ke(e=process.env){return{...e,PATH:Rs(e).join(Me.delimiter)}}function jn(e,t={}){if(e.includes(Me.sep)){let n=Me.isAbsolute(e)?e:Me.resolve(t.cwd??process.cwd(),e);return ks(n)?n:null}for(let n of Rs(t.env)){let r=Me.join(n,e);if(ks(r))return r}return null}function Ve(e,t={}){let n=jn(e,t);if(n)return n;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function ks(e){try{return Lc(e,Oc.X_OK),!0}catch{return!1}}function jc(e){return[...new Set(e)]}ue();ce();import{spawn as Nc}from"node:child_process";import{createHash as Wc}from"node:crypto";import _c from"node:path";var Bc="craig";async function Ts(e,t,n){let r=Nn(e,t),s=qc(),o=await x("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",r,"-n","runner",...s,"-c",n],{cwd:e}),i=Vc(o.stdout);return await Uc(e,r),i}async function Uc(e,t){let n=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let r of n)await x("tmux",r,{cwd:e})}async function ys(e,t,n){await x("tmux",["resize-window","-t",t,"-x",`${n.columns}`,"-y",`${n.rows}`],{cwd:e})}async function Ps(e,t,n){await x("tmux",["send-keys","-t",e,t,"C-m"],{cwd:n})}async function bs(e,t,n){await x("tmux",["pipe-pane","-o","-t",e,`cat >> ${Lt(t)}`],{cwd:n})}async function Ot(e,t,n,r){let s=r??Is(e);if(n?await x("tmux",["select-window","-t",n],{cwd:e}):await x("tmux",["select-window","-t",t],{cwd:e}),await x("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await x("tmux",["switch-client","-t",s],{cwd:e});return}await Hc(e,["attach-session","-t",s])}function Is(e){let n=_c.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",r=Wc("sha1").update(e).digest("hex").slice(0,8);return`${Bc}-${n}-${r}`}function Nn(e,t){return`${Is(e)}-${t.toLowerCase()}`}function qc(){let e=Kc();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]}function Kc(){let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let n="columns"in t?t.columns:void 0,r="rows"in t?t.rows:void 0;if(typeof n=="number"&&n>0&&typeof r=="number"&&r>0)return{columns:n,rows:r}}return null}function Vc(e){let t=Gc(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}}function Gc(e){return e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0)}async function Hc(e,t){await new Promise((n,r)=>{let s=Nc("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",r),s.on("exit",o=>{if(o===0){n();return}r(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})}var Wn={async prepare(e,t){let n=e.runnerSession.command[0]??z(e.runner)[0],r=Ke();await x(Ve(n,{cwd:t.repoRoot,env:r}),["--help"],{cwd:t.repoRoot,env:r})},async launch(e,t){let n=e.runnerSession.command.length>0?e.runnerSession.command:z(e.runner,e.prompt.value),r=Ve(n[0],{cwd:e.worktreePath,env:Ke()});await Ps(t.session.paneId,[r,...n.slice(1)].map(s=>Lt(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}};ue();ce();var ut={async create(e,t){let n=await Ts(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await bs(n.paneId,t.logPath,t.repoRoot);let r=await Ss({paneId:n.paneId,windowTarget:n.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:n.sessionName||Nn(t.repoRoot,t.taskId),paneId:n.paneId,windowTarget:n.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:r,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await Be(e,s),s},async attach(e,t,n){let r=await ut.snapshot(t,n);if(!r.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Ot(n,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:r};return await Be(e,s),s},async resize(e,t,n,r){await ys(r,t.sessionName,n);let s={...t,attach:{...t.attach,lastSize:n}};return await Be(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,n){let r={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:(n.length>0,t.command)};return await Be(e,r),r},async snapshot(e,t){return zc(e,t)}};async function zc(e,t){let n=await D("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Ss({paneId:e.paneId,windowTarget:e.windowTarget,alive:n.exitCode===0&&n.stdout.split(/\s+/).some(r=>r.trim()===e.paneId)})}async function Ss(e){return{paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()}}He();ie();pt();import{mkdir as mt,rm as ol,writeFile as _t}from"node:fs/promises";import $ from"node:path";ce();async function As(e,t){let n=await D("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(n.exitCode===0)return!0;if(n.exitCode===1)return!1;throw new Error(n.stderr.trim()||n.stdout.trim()||"Unable to check git branch state.")}async function _n(e,t,n,r="main"){let s=r.trim()||"main";if((await D("git",["show-ref","--verify","--quiet",`refs/heads/${s}`],{cwd:e})).exitCode!==0)throw new Error(`Base branch '${s}' does not exist locally.`);let i=await sl(e,s);await x("git",["worktree","add","-b",t,n,i],{cwd:e})}async function sl(e,t){return(await D("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await D("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await D("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t}async function Wt(e){let t=await D("git",["status","--short"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"Unable to inspect git status.");return t.stdout.trim().length>0}async function $s(e){await x("git",["add","-A"],{cwd:e})}async function Ds(e,t){await x("git",["commit","-m",t],{cwd:e})}async function Ms(e){let t=await x("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[n="",r=""]=t.stdout.trim().split(`
|
|
30
|
-
`);if(!n||!r)throw new Error("Unable to read git HEAD commit metadata.");return{sha:n,message:r}}
|
|
28
|
+
${Q()}`);return t}import Ks from"node:path";import{readFile as Za,readdir as Gm,rm as Hm}from"node:fs/promises";import ec from"node:path";import{randomUUID as Ya}from"node:crypto";import{open as Ja,readFile as Um,rename as Qa,rm as Xa}from"node:fs/promises";import Rn from"node:path";async function _(e,t){let n=Rn.dirname(e),r=Rn.join(n,`.${Rn.basename(e)}.${process.pid}.${Date.now()}.${Ya()}.tmp`),s=await Ja(r,"w");try{let o=`${JSON.stringify(t,null,2)}
|
|
29
|
+
`;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Qa(r,e)}catch(o){throw await s.close().catch(()=>{}),await Xa(r,{force:!0}).catch(()=>{}),o}}async function Ve(e,t){let n=await Za(Tn(e,t),"utf8"),r=JSON.parse(n);return tc(r,Tn(e,t))}async function Me(e,t){await _(Tn(e,t.id),{...t,updatedAt:new Date().toISOString()})}function Tn(e,t){return ec.join(e.sessionsDir,`${t}.json`)}function tc(e,t){let n=sc(e);if(typeof n!="object"||n===null||typeof n.id!="string"||typeof n.taskId!="string"||typeof n.repoId!="string"||typeof n.workspaceId!="string"||n.substrate!=="tmux"||typeof n.sessionName!="string"||typeof n.paneId!="string"||!(n.windowTarget===null||typeof n.windowTarget=="string")||typeof n.worktreePath!="string"||!(n.logPath===null||typeof n.logPath=="string")||!Array.isArray(n.command)||!n.command.every(r=>typeof r=="string")||!["starting","running","exited","failed"].includes(n.status)||!(n.startedAt===null||typeof n.startedAt=="string")||!(n.exitedAt===null||typeof n.exitedAt=="string")||!(n.exitCode===null||typeof n.exitCode=="number")||!(n.lastAttachedAt===null||typeof n.lastAttachedAt=="string")||!rc(n.attach)||!nc(n.snapshot)||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function nc(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function rc(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function sc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(n=>typeof n=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}import{readFile as ac}from"node:fs/promises";import{readFile as oc}from"node:fs/promises";var ic=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(n=>typeof n=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(n=>typeof n=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(n=>typeof n=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},yt=(e,t,n)=>{if(!ic(e))throw new Error(`Craig index at ${n} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${n} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e},ne=async e=>{let t=await oc(e.indexFile,"utf8");return yt(JSON.parse(t),e.workspaceRoot,e.indexFile)},Ce=async(e,t)=>{await _(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};async function B(e,t){let n=await ac(yn(e,t),"utf8"),r=JSON.parse(n);return cc(r,yn(e,t))}async function A(e,t){let n={...t,updatedAt:new Date().toISOString()};await _(yn(e,t.id),n)}async function Pn(e,t){let n=await ne(e);n.taskIds.includes(t)||await Ce(e,{...n,taskIds:[...n.taskIds,t]})}function yn(e,t){return`${e.tasksDir}/${t}.json`}function cc(e,t){let n=lc(e);if(!uc(n))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function lc(e){if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:bn(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[],ptyTabs:mc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:pc(t.repoTargets),runnerSession:t.runnerSession??dc(t),checks:yc(t),lastCommit:t.lastCommit??null,prs:Pc(t),artifacts:Cc(t),cleanup:xc(t)}}function dc(e){if(typeof e.title!="string")return null;let t=bn(e.runner);return{command:b.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}}function uc(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&b.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(n=>typeof n=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&cs(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||fc(t.repoTargets))&&hc(t.runnerSession)&&wc(t.prompt)&&ls(t.checks)&&ds(t.lastCommit)&&Rc(t.prs)&&Tc(t.artifacts)&&ps(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}function pc(e){if(Array.isArray(e))return e.filter(as)}function fc(e){return Array.isArray(e)&&e.every(as)}function as(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&ls(t.checks)&&ds(t.lastCommit)&&us(t.pullRequest)&&ps(t.cleanup)}function mc(e){if(cs(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return gc(e.id,e.title,t,bn(e.runner))}function gc(e,t,n,r){let s=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:b.runners.buildCommand(r),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function bn(e){return e&&b.runners.isRunnerType(e)?e:"codex"}function cs(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string")}function hc(e){return typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null)}function wc(e){return typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string"}function ls(e){return typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number")}function ds(e){return e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string"}function us(e){return typeof e=="object"&&e!==null&&e.provider==="github"&&kc(e.requiredChecks)}function kc(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null))}function Rc(e){return Array.isArray(e)&&e.every(us)}function Tc(e){return typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null)}function ps(e){return typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null)}function yc(e){return e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]}}function Pc(e){if(Array.isArray(e.prs))return e.prs.map(bc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:fs(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:ms(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]}function bc(e){let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:fs(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Sc(t.reviewDecision),requiredChecks:ms(t.requiredChecks),comments:Ic(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}}function fs(e){return e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null}function Sc(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Ic(e){return Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let n=t;return typeof n.body!="string"||!n.body.trim()?[]:[{author:typeof n.author=="string"?n.author:null,body:n.body,createdAt:typeof n.createdAt=="string"?n.createdAt:null,url:typeof n.url=="string"?n.url:null}]}):[]}function ms(e){return Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[]}function Cc(e){let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}}function xc(e){return e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}import{readFile as vc}from"node:fs/promises";async function Y(e){try{let t=await vc(e.uiStateFile,"utf8"),n=JSON.parse(t);return Ec(n,e.uiStateFile)}catch(t){if($c(t))return null;throw t}}async function H(e,t){await _(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function ge(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function Ec(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!Ge(e,"inputMode")||!Ge(e,"focusedRegion")||!Ge(e,"activeTab")||!Ge(e,"inspectorSection")||!Ge(e,"inspectionMode")||!Pt(e,"openInspectionKind")||!Pt(e,"selectedFileTreePath")||!Pt(e,"selectedFilePath")||!Pt(e,"selectedDiffPath")||!Ac(e,"collapsedFileTreePaths")||!Ge(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 Ge(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Pt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Ac(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(n=>typeof n=="string"))}function $c(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{execFile as Dc}from"node:child_process";import{promisify as Mc}from"node:util";var gs=Mc(Dc);async function v(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr}}catch(r){if(hs(r)){let s=r.stderr?.trim()||r.stdout?.trim()||r.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw r}}async function M(e,t,n={}){try{let r=await gs(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr,exitCode:0}}catch(r){if(hs(r))return{stdout:r.stdout??"",stderr:r.stderr??"",exitCode:typeof r.code=="number"?r.code:null};throw r}}function hs(e){return e instanceof Error}function bt(e){return`'${e.replace(/'/g,"'\\''")}'`}import{accessSync as Lc,constants as jc}from"node:fs";import{homedir as ws}from"node:os";import xe from"node:path";var Oc=[xe.join(ws(),".local","bin"),xe.join(ws(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Rs(e=process.env){return Fc([...(e.PATH??"").split(xe.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:Oc])}function Le(e=process.env){return{...e,PATH:Rs(e).join(xe.delimiter)}}function Sn(e,t={}){if(e.includes(xe.sep)){let n=xe.isAbsolute(e)?e:xe.resolve(t.cwd??process.cwd(),e);return ks(n)?n:null}for(let n of Rs(t.env)){let r=xe.join(n,e);if(ks(r))return r}return null}function je(e,t={}){let n=Sn(e,t);if(n)return n;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function ks(e){try{return Lc(e,jc.X_OK),!0}catch{return!1}}function Fc(e){return[...new Set(e)]}import{spawn as Nc}from"node:child_process";import{createHash as Wc}from"node:crypto";import _c from"node:path";var Bc="craig";async function Ts(e,t,n){let r=In(e,t),s=qc(),o=await v("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",r,"-n","runner",...s,"-c",n],{cwd:e}),i=Vc(o.stdout);return await Uc(e,r),i}async function Uc(e,t){let n=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let r of n)await v("tmux",r,{cwd:e})}async function ys(e,t,n){await v("tmux",["resize-window","-t",t,"-x",`${n.columns}`,"-y",`${n.rows}`],{cwd:e})}async function Ps(e,t,n){await v("tmux",["send-keys","-t",e,t,"C-m"],{cwd:n})}async function bs(e,t,n){await v("tmux",["pipe-pane","-o","-t",e,`cat >> ${bt(t)}`],{cwd:n})}async function St(e,t,n,r){let s=r??Ss(e);if(n?await v("tmux",["select-window","-t",n],{cwd:e}):await v("tmux",["select-window","-t",t],{cwd:e}),await v("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await v("tmux",["switch-client","-t",s],{cwd:e});return}await Hc(e,["attach-session","-t",s])}function Ss(e){let n=_c.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",r=Wc("sha1").update(e).digest("hex").slice(0,8);return`${Bc}-${n}-${r}`}function In(e,t){return`${Ss(e)}-${t.toLowerCase()}`}function qc(){let e=Kc();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]}function Kc(){let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let n="columns"in t?t.columns:void 0,r="rows"in t?t.rows:void 0;if(typeof n=="number"&&n>0&&typeof r=="number"&&r>0)return{columns:n,rows:r}}return null}function Vc(e){let t=Gc(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}}function Gc(e){return e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0)}async function Hc(e,t){await new Promise((n,r)=>{let s=Nc("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",r),s.on("exit",o=>{if(o===0){n();return}r(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})}var Cn={async prepare(e,t){let n=e.runnerSession.command[0]??b.runners.buildCommand(e.runner)[0],r=Le();await v(je(n,{cwd:t.repoRoot,env:r}),["--help"],{cwd:t.repoRoot,env:r})},async launch(e,t){let n=e.runnerSession.command.length>0?e.runnerSession.command:b.runners.buildCommand(e.runner,e.prompt.value),r=je(n[0],{cwd:e.worktreePath,env:Le()});await Ps(t.session.paneId,[r,...n.slice(1)].map(s=>bt(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}};var et={async create(e,t){let n=await Ts(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await bs(n.paneId,t.logPath,t.repoRoot);let r=await Is({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||In(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 Me(e,s),s},async attach(e,t,n){let r=await et.snapshot(t,n);if(!r.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await St(n,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:r};return await Me(e,s),s},async resize(e,t,n,r){await ys(r,t.sessionName,n);let s={...t,attach:{...t.attach,lastSize:n}};return await Me(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 Me(e,r),r},async snapshot(e,t){return zc(e,t)}};async function zc(e,t){let n=await M("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Is({paneId:e.paneId,windowTarget:e.windowTarget,alive:n.exitCode===0&&n.stdout.split(/\s+/).some(r=>r.trim()===e.paneId)})}async function Is(e){return{paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()}}import{mkdir as nt,rm as rl,writeFile as Ct}from"node:fs/promises";import D from"node:path";import{readFile as Yc,readdir as Jc,rm as Qc}from"node:fs/promises";import Cs from"node:path";var xn=(e,t)=>Cs.join(e.reposDir,`${t}.json`),xs=(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},de=async(e,t)=>{let n=xn(e,t),r=await Yc(n,"utf8");return xs(JSON.parse(r),n)},vn=async(e,t)=>{await _(xn(e,t.id),{...t,updatedAt:new Date().toISOString()})},tt=async e=>{let t=await Jc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>de(e,Cs.basename(r.name,".json"))))).sort((r,s)=>r.name.localeCompare(s.name)||r.id.localeCompare(s.id))},vs=async(e,t)=>{await Qc(xn(e,t),{force:!0})};import{readFile as Xc,readdir as Zc,rm as el}from"node:fs/promises";import Es from"node:path";var En=(e,t)=>Es.join(e.workspacesDir,`${t}.json`),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"):[]}},As=(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},Oe=async(e,t)=>{let n=En(e,t),r=await Xc(n,"utf8");return As(JSON.parse(r),n)},Fe=async(e,t)=>{await _(En(e,t.id),{...t,updatedAt:new Date().toISOString()})},re=async e=>{let t=await Zc(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>Oe(e,Es.basename(r.name,".json"))))).sort((r,s)=>r.id.localeCompare(s.id))},$s=async(e,t)=>{await el(En(e,t),{force:!0})};async function Ds(e,t){let n=await M("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 An(e,t,n,r="main"){let s=r.trim()||"main";if((await M("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 v("git",["worktree","add","-b",t,n,i],{cwd:e})}async function nl(e,t){return(await M("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await M("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await M("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t}async function It(e){let t=await M("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 Ms(e){await v("git",["add","-A"],{cwd:e})}async function Ls(e,t){await v("git",["commit","-m",t],{cwd:e})}async function js(e){let t=await v("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[n="",r=""]=t.stdout.trim().split(`
|
|
30
|
+
`);if(!n||!r)throw new Error("Unable to read git HEAD commit metadata.");return{sha:n,message:r}}async function Os(e,t){let n=await ne(e),r=Ns(new Date),s=Ws(n.taskIds,r);for(;;){let o=`task_${r}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await Ds(t,i))return o;s+=1}}async function Fs(e){let t=await ne(e),n=Ns(new Date),r=Ws(t.taskIds,n);return`task_${n}_${String(r).padStart(2,"0")}`}function Ns(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 Ws(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 Bs=["AGENTS","md"].join(".");async function rt(e,t,n,r={}){let s=await de(e,t),o=await cl(e,s.id),i=await Os(e,s.rootPath),c=r.sessionId??null,l=`craig/${i}`,d=D.join(e.worktreesDir,s.id,i),p=D.join(e.logsDir,`${i}.log`),h=D.join(e.artifactsDir,i);await nt(D.dirname(d),{recursive:!0}),await nt(h,{recursive:!0}),await Ct(p,"","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 A(e,R),await Pn(e,i),await An(s.rootPath,l,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:c,workspaceId:o.id,task:R}}async function vt(e,t,n,r={}){let s=(await re(e)).find(x=>x.id===t&&x.status==="active");if(!s)throw new Error(`Workspace ${t} does not exist or is archived.`);if(s.kind!=="project"){if(!s.primaryRepoId)throw new Error(`Workspace ${t} is not task-capable.`);let x=await rt(e,s.primaryRepoId,n,r);return{...x,bundlePath:x.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await Fs(e),c=new Date().toISOString(),l=r.runner??"codex",d=r.sessionId??null,p=`craig/${i}`,h=D.join(e.craigDir,"task-bundles",i),R=D.join(e.logsDir,`${i}.log`),k=D.join(e.artifactsDir,i);await nt(h,{recursive:!0}),await nt(k,{recursive:!0}),await Ct(R,"","utf8");let I=await Promise.all(o.map(x=>de(e,x))),T=il(I),a=await Promise.all(I.map(x=>ol(e,x,i,p,D.join(h,T.get(x.id))))),G=a.find(x=>x.status==="ready")??a[0];if(!a.some(x=>x.status==="ready"))throw await rl(h,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${a.map(x=>`${x.repoId}: ${x.failureReason??"unknown error"}`).join("; ")}`);await Ct(D.join(h,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:n,repos:a.map(x=>({repoId:x.repoId,repoName:I.find($e=>$e.id===x.repoId)?.name??x.repoId,path:D.relative(h,x.worktreePath),status:x.status,worktreePath:x.worktreePath,failureReason:x.failureReason}))},null,2),"utf8"),await Ct(D.join(h,Bs),al({taskId:i,workspaceId:t,prompt:n,repos:I,repoTargets:a,bundlePath:h}),"utf8");let W=Us(i,n,c,l,r.config??{}),oe={id:i,title:n,slug:qs(n),type:"project",status:"draft",runner:l,repoId:G.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:W[0]?.id??null,linkedRepoIds:o.filter(x=>x!==G.repoId),repoRoot:h,worktreePath:h,branch:p,bundlePath:h,selectedRepoTargetId:G.repoId,repoTargets:a,ptyTabs:W,runnerSession:{command:b.runners.buildCommand(l,n,r.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:n},checks:G.checks,lastCommit:null,prs:[],artifacts:{logPath:D.relative(e.workspaceRoot,R),checkSummaryPath:D.relative(e.workspaceRoot,D.join(k,"check-summary.json")),prDraftPath:null,prStatusPath:D.relative(e.workspaceRoot,D.join(k,"pr-status.json"))},cleanup:xt(),lastFailureReason:a.every(x=>x.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:c,updatedAt:c};return await A(e,oe),await Pn(e,i),{repoId:G.repoId,repoRoot:h,sessionId:d,workspaceId:s.id,task:oe,bundlePath:h,repoTargets:a}}function Us(e,t,n,r="codex",s={}){let o=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:b.runners.buildCommand(r,void 0,s),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function sl(e,t){let n=new Date().toISOString(),r=Us(t.taskId,t.prompt,n,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:qs(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:r[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:r,runnerSession:{command:b.runners.buildCommand(t.runner,t.prompt,t.config),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:t.prompt},checks:{...$n(D.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:D.relative(e.workspaceRoot,D.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:D.relative(e.workspaceRoot,D.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:D.relative(e.workspaceRoot,D.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:xt(),lastFailureReason:null,createdAt:n,updatedAt:n}}async function ol(e,t,n,r,s){await nt(D.dirname(s),{recursive:!0});try{return await An(t.rootPath,r,s,t.defaultBranch),{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:$n(D.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:_s(),cleanup:xt()}}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(D.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:_s(),cleanup:xt()}}}function il(e){let t=new Set(["manifest.json",Bs]),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=D.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
|
|
32
|
+
`)}function $n(e){return{source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}}function _s(){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 xt(){return{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}async function cl(e,t){let r=(await re(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 qs(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-")}async function Vs(e,t,n,r={}){let s=n.trim(),o=await b.load(e),i=r.runner??b.runners.getDefault(o);if(b.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(r.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let c=r.workspaceId?await vt(e,r.workspaceId,s,{runner:i,config:o}):await rt(e,t,s,{runner:i,config:o}),l=c.task,d=b.runners.buildCommand(i,s,o),p=`session_${l.id}`,h=l.artifacts.logPath?Ks.resolve(e.workspaceRoot,l.artifacts.logPath):Ks.join(e.logsDir,`${l.id}.log`);try{await Cn.prepare(l,{repoRoot:c.repoRoot});let R=await et.create(e,{sessionId:p,taskId:l.id,repoId:c.repoId,workspaceId:c.workspaceId,repoRoot:c.repoRoot,worktreePath:l.worktreePath,logPath:h,command:d});await Cn.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 A(e,I),await Me(e,R),await H({uiStateFile:e.uiStateFile},{...await Y({uiStateFile:e.uiStateFile})??ge(),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 A(e,k),R}}async function he(e,t){let n=await ne(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"}import{access as Dl}from"node:fs/promises";import oo from"node:path";import{mkdir as dl,readFile as gh,writeFile as hh}from"node:fs/promises";import ul from"node:path";import Gs from"node:path";function Et(e,t){return t?Gs.isAbsolute(t)?t:Gs.join(e.repoRoot,t):null}function V(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 Dt(e){return e.status==="merged"||e.status==="closed"}function Hs(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 zs=3,pl=1e3,fl=1e4;async function st(e){let t=await M("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 Ln(e,t){let n=V(t),r=n?.number?String(n.number):t.branch,s=await v("gh",$t(r),{cwd:t.worktreePath}),o=JSON.parse(s.stdout);return On(e,t,o,n)}async function jn(e,t){let n=await M("gh",$t(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 On(e,t,r,null)}}async function Js(e){let t=await M("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:yl(t.stdout.trim())}async function Qs(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}`],p=bl(d);return{id:c.id,found:p!==null,view:p}})}async function ml(e,t){let n;for(let r=0;r<=zs;r+=1)try{return await v("gh",t,{cwd:e})}catch(s){if(n=s,r===zs||!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)||pl,n=Math.min(t*2**e,fl),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 ot(e,t,n){let r=n.pullRequest.number?String(n.pullRequest.number):n.branch;if(n.pullRequest.number){let i=await v("gh",$t(r),{cwd:n.worktreePath}),c=Mn(JSON.parse(i.stdout));return n.pullRequest=c,await Dn(e,t,n.repoId,c),"synced"}let s=await M("gh",$t(r),{cwd:n.worktreePath});if(s.exitCode!==0)return"not_found";let o=Mn(JSON.parse(s.stdout));return n.pullRequest=o,await Dn(e,t,n.repoId,o),"discovered"}async function Xs(e,t,n){return On(e,t,n,V(t))}async function Zs(e,t,n,r){return Dn(e,t,n,Mn(r))}async function eo(e,t){let n=Et(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 $t(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
|
|
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 On(e,t,n,r){let s=Sl(n,r),o=Hs(t,s),i=Tl(o.prs),c={...o,status:i};await eo(e,c);let l=await B(e,t.id),d=l.status==="closed"?l.status:i,p=Hs({...l,status:d},s);return await A(e,p),p}async function Dn(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 A(e,i),i}function Sl(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:no(e.reviewDecision??null),requiredChecks:to(e.statusCheckRollup),comments:ro(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 Mn(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:no(e.reviewDecision??null),requiredChecks:to(e.statusCheckRollup),comments:ro(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 Cl(e){return e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function to(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:so(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):At(e)&&!At(t)?!0:!At(e)&&At(t)?!1:Ys(t.status)>=Ys(e.status)}function At(e){return e.conclusion?.toUpperCase()==="CANCELLED"}function Ys(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 no(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function ro(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 so(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?so(r,r):"unknown"}async function L(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 Fn(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)}function Nn(e,t){return t.artifacts.logPath?oo.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:oo.join(e.workspaceRoot,t.artifacts.logPath):null}async function io(e,t){let n=await Fn(t.worktreePath),r=Nn(e,t),s=r?await Fn(r):!1;return{worktreeExists:n,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Ml(t),lastCommitSummary:Ll(t),prSummary:jl(t),cleanupSummary:Ol(t)}}async function Fn(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 jl(e){if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(l=>l.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),i=s.reduce((l,d)=>{let p=d.pullRequest.status??"unknown";return l[p]=(l[p]??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=
|
|
113
|
+
`)}`}let t=V(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 Fl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function ao(e,t){let n=await L(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([de(e,n.repoId),Ve(e,n.sessionId)]),o=await et.attach(e,s,r.rootPath);return{kind:"attachTask",taskId:n.id,sessionId:o.id,disposition:"attached"}}async function lo(e,t){let n=await L(e,t),r=V(n);return r?.number?(await st(n.worktreePath),Dt(r)?(await jn(e,n)).task:Ln(e,n)):n}async function Lt(e,t){let n=await L(e,t),r=(n.repoTargets??[]).filter(i=>i.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let i of r){await st(i.worktreePath);let c=i.pullRequest.number?await ot(e,n,i):await ot(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=po(o),await A(e,o)),s}async function uo(e,t){let n=new Map,r=new Map;for(let s of t){let o=Wn(n,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(p=>p.status==="ready")){let p={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head"};await co(r,p).catch(async()=>{try{let h=d.pullRequest.number?await ot(e,s,d):await ot(e,s,d).catch(()=>"not_found");Mt(o,h,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=V(s),c=i?.number&&!Dt(i),l={id:s.id,task:s,worktreePath:s.worktreePath,selector:c?String(i.number):s.branch,mode:c?"number":"head"};await co(r,l).catch(async()=>{try{let{disposition:d,task:p}=await _n(e,s.id),h=V(p);Mt(o,d,h?.number??null,h?.url??null)}catch{}})}for(let s of r.values())try{await st(s.worktreePath);let o=await Qs(s.worktreePath,s.repository,s.items),i=new Map(o.map(c=>[c.id,c]));for(let c of s.items){let l=Wn(n,c.task),d=i.get(c.id);if(!d?.found||!d.view){Mt(l,"not_found",null,null);continue}c.targetRepoId?await Zs(e,c.task,c.targetRepoId,d.view):await Xs(e,c.task,d.view),Mt(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=po(o),await A(e,o))}return t.map(s=>Wn(n,s))}async function _n(e,t){let n=await L(e,t);await ce(n),await st(n.worktreePath);let r=V(n);if(r?.number&&!Dt(r))return{disposition:"synced",task:await Ln(e,n)};let s=await jn(e,n);return{disposition:s.discovered?"discovered":"not_found",task:s.task}}function po(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 co(e,t){let n=await Js(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 Wn(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):!!V(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,r),r}function Mt(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 Bn(e,t){let n=await L(e,t);try{n.type==="project"&&n.repoTargets?.length?(await Lt(e,t),n=await L(e,t)):n.prs.some(o=>o.number)&&(n=await lo(e,t))}catch{}let r=await io(e,n),s=n.sessionId?await Ve(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 Un(e,t){let n=await L(e,t),r=Nn(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}}async function qn(e,t){let n=await L(e,t);if(await ce(n),(await v("git",["status","--short"],{cwd:n.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:n.id,diffText:"",isEmpty:!0};let s=await _l(n.worktreePath);return{kind:"showTaskDiff",taskId:n.id,diffText:s,isEmpty:!1}}async function _l(e){let t=[],n=await v("git",["diff","--stat","--patch","HEAD"],{cwd:e});n.stdout.trim().length>0&&t.push(n.stdout.trimEnd());let r=await Bl(e);for(let s of r){let o=await M("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
|
|
114
114
|
|
|
115
|
-
`)}async function
|
|
116
|
-
`).map(n=>n.trim()).filter(n=>n.length>0)}async function er(e,t){let n=await M(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session.`);let r=await tt(e,n.sessionId).catch(s=>{throw Kl(s)?new Error(`Task ${n.id} does not have a Craig session.`):s});if(!r.paneId)throw new Error(`Task ${n.id} does not have a tmux target.`);return await Ot(e.repoRoot,r.paneId,r.windowTarget,r.sessionName),{kind:"focusTask",taskId:n.id,tmuxTarget:r.paneId}}function Kl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{spawn as Vl}from"node:child_process";async function tr(e,t){let n=await M(e,t);await le(n);let s=(await Te(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!1,command:null};let o=[...s,n.worktreePath];return await Gl(o,e.repoRoot),{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!0,command:o}}async function Gl(e,t){await new Promise((n,r)=>{let[s,...o]=e,i=Vl(s,o,{cwd:t,stdio:"inherit"});i.on("error",r),i.on("exit",c=>{if(c===0){n();return}r(new Error(`${e.join(" ")} failed with exit code ${c??"unknown"}.`))})})}ye();import{mkdir as Hl}from"node:fs/promises";import zl from"node:path";ie();ce();async function nr(e,t){let n=await M(e,t);if(await le(n),n.status==="draft"||n.status==="merged")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);if(n.status==="running"&&await Wt(n.worktreePath)&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);let s=(await Te(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);n.checks.status="running",n.checks.commands=[...s],n.checks.results=[],await E(e,n);let o=[];for(let i of s){let c=new Date().toISOString(),l=await D("sh",["-lc",i],{cwd:n.worktreePath}),d=new Date().toISOString(),f=l.exitCode??1;if(o.push({command:i,startedAt:c,finishedAt:d,exitCode:f}),f!==0)return n.checks.results=o,n.checks.status="failed",n.checks.lastRunAt=d,n.status="review",n.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await uo(e,n),await E(e,n),{kind:"runChecks",taskId:n.id,status:"failed",commands:s}}return n.checks.results=o,n.checks.status="passed",n.checks.lastRunAt=new Date().toISOString(),n.status="checked",n.lastFailureReason=null,await uo(e,n),await E(e,n),{kind:"runChecks",taskId:n.id,status:"passed",commands:s}}async function uo(e,t){let n=qt(e,t.artifacts.checkSummaryPath);n&&(await Hl(zl.dirname(n),{recursive:!0}),await W(n,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))}ie();async function rr(e,t){let n=await M(e,t);await le(n);let r=await Wt(n.worktreePath);if(n.status==="running"&&r&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot commit from status "${n.status}".`);if(!r)throw new Error(`Task ${n.id} has no uncommitted diff to commit.`);let s=n.prompt.value.trim();await $s(n.worktreePath),await Ds(n.worktreePath,s);let o=await Ms(n.worktreePath);return n.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},n.lastFailureReason=null,await E(e,n),{kind:"commitTask",taskId:n.id,status:n.status,commitSha:o.sha,message:o.message}}qe();He();pt();rt();ht();Pt();ce();import nd from"node:path";import{stat as rd}from"node:fs/promises";async function yo(e,t){let n=nd.resolve(e.workspaceRoot,t);if(!(await rd(n).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${n}`);let s=await Promise.resolve().then(()=>(Pt(),To)).then(({addWorkspace:i})=>i(e,t)),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${n}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}}async function Po(e){return{kind:"listRepos",repos:await Ge(e)}}async function bo(e,t){let n=await pe(e,t),s=(await me(e)).filter(d=>d.primaryRepoId===t),o=s.filter(d=>d.status==="active"),i=await be(e,{repoId:t});if(o.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(i.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(s.map(d=>Yt(e,d.id))),await xs(e,t);let c=await oe(e);await Ue(e,{...c,repoIds:c.repoIds.filter(d=>d!==t)});let l=await fe({uiStateFile:e.uiStateFile});return l?.selectedRepoId===t&&await ae({uiStateFile:e.uiStateFile},{...l,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}}He();ie();async function Io(e,t,n){let[r,s]=await Promise.all([M(e,t),pe(e,n)]);if(r.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${r.id}.`);let o=r.linkedRepoIds.includes(s.id)?r.linkedRepoIds:[...r.linkedRepoIds,s.id];return await E(e,{...r,linkedRepoIds:o}),{kind:"addTaskLink",taskId:r.id,repoId:s.id,linkedRepoIds:o}}async function So(e,t){let n=await M(e,t),r=await Promise.all(n.linkedRepoIds.map(s=>pe(e,s)));return{kind:"listTaskLinks",taskId:n.id,repos:r}}Pt();async function Co(e,t){switch(e.kind){case"addWorkspace":return Rt(t.paths,e.path);case"addRepo":return yo(t.paths,e.path);case"listRepos":return Po(t.paths);case"removeRepo":return bo(t.paths,e.repoId);case"listWorkspaces":return sr(t.paths,{archived:e.archived});case"archiveWorkspace":return Tt(t.paths,e.workspaceId);case"restoreWorkspace":return or(t.paths,e.workspaceId);case"removeWorkspace":return yt(t.paths,e.workspaceId);case"createTask":return qs(t.paths,e.repoId??e.workspaceId??"",e.prompt,{...e.runner?{runner:e.runner}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}});case"listTasks":return e.repoId||e.workspaceId?be(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):be(t.paths);case"attachTask":return oo(t.paths,e.taskId);case"addTaskLink":return Io(t.paths,e.taskId,e.repoId);case"listTaskLinks":return So(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return Qn(t.paths,e.taskId);case"showSelectedTask":return Qn(t.paths,ze(t,"show"));case"streamTaskLogs":return Xn(t.paths,e.taskId);case"streamSelectedTaskLogs":return Xn(t.paths,ze(t,"logs"));case"showTaskDiff":return Zn(t.paths,e.taskId);case"showSelectedTaskDiff":return Zn(t.paths,ze(t,"diff"));case"focusTask":return er(t.paths,e.taskId);case"focusSelectedTask":return er(t.paths,ze(t,"focus"));case"openTask":return tr(t.paths,e.taskId);case"openSelectedTask":return tr(t.paths,ze(t,"open"));case"runChecks":return nr(t.paths,e.taskId);case"runSelectedTaskChecks":return nr(t.paths,ze(t,"check"));case"commitTask":return rr(t.paths,e.taskId);case"commitSelectedTask":return rr(t.paths,ze(t,"commit"));case"help":return{kind:"help",text:Y()};case"exit":return{kind:"exit"};default:return sd(e)}}function sd(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function ze(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}ye();import{mkdir as Ie,readFile as od}from"node:fs/promises";import J from"node:path";function Ce(e){let t=J.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:J.join(t,"index.json"),reposDir:J.join(t,"repos"),workspacesDir:J.join(t,"workspaces"),sessionsDir:J.join(t,"sessions"),runtimeDir:J.join(t,"runtime"),uiStateFile:J.join(t,"runtime","ui-state.json"),tasksDir:J.join(t,"tasks"),jobsDir:J.join(t,"jobs"),logsDir:J.join(t,"logs"),errorLogFile:J.join(t,"logs","errors.log"),artifactsDir:J.join(t,"artifacts"),worktreesDir:J.join(t,"worktrees"),configFile:J.join(t,"config.json")}}qe();async function ot(e){let t=Ce(e);await Ie(t.craigDir,{recursive:!0}),await Promise.all([Ie(t.reposDir,{recursive:!0}),Ie(t.workspacesDir,{recursive:!0}),Ie(t.sessionsDir,{recursive:!0}),Ie(t.runtimeDir,{recursive:!0}),Ie(t.tasksDir,{recursive:!0}),Ie(t.jobsDir,{recursive:!0}),Ie(t.logsDir,{recursive:!0}),Ie(t.artifactsDir,{recursive:!0}),Ie(t.worktreesDir,{recursive:!0})]);try{let s=await od(t.indexFile,"utf8"),o=JSON.parse(s);return Mn(o,e,t.indexFile)}catch(s){if(!id(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let n=new Date().toISOString(),r={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:n,updatedAt:n};return await W(t.indexFile,r),r}function id(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}function xo(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
|
|
115
|
+
`)}async function Bl(e){return(await v("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
|
|
116
|
+
`).map(n=>n.trim()).filter(n=>n.length>0)}async function Kn(e,t){let n=await L(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session.`);let r=await Ve(e,n.sessionId).catch(s=>{throw Ul(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 St(e.repoRoot,r.paneId,r.windowTarget,r.sessionName),{kind:"focusTask",taskId:n.id,tmuxTarget:r.paneId}}function Ul(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 Vn(e,t){let n=await L(e,t);await ce(n);let s=(await b.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!1,command:null};let o=[...s,n.worktreePath];return await 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=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"}.`))})})}import{mkdir as Vl}from"node:fs/promises";import Gl from"node:path";async function Gn(e,t){let n=await L(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 It(n.worktreePath)&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);let s=(await b.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);n.checks.status="running",n.checks.commands=[...s],n.checks.results=[],await A(e,n);let o=[];for(let i of s){let c=new Date().toISOString(),l=await M("sh",["-lc",i],{cwd:n.worktreePath}),d=new Date().toISOString(),p=l.exitCode??1;if(o.push({command:i,startedAt:c,finishedAt:d,exitCode:p}),p!==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 fo(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"failed",commands:s}}return n.checks.results=o,n.checks.status="passed",n.checks.lastRunAt=new Date().toISOString(),n.status="checked",n.lastFailureReason=null,await fo(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"passed",commands:s}}async function fo(e,t){let n=Et(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}))}async function Hn(e,t){let n=await L(e,t);await ce(n);let r=await It(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 Ms(n.worktreePath),await Ls(n.worktreePath,s);let o=await js(n.worktreePath);return n.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},n.lastFailureReason=null,await A(e,n),{kind:"commitTask",taskId:n.id,status:n.status,commitSha:o.sha,message:o.message}}import{readdir as Yl,stat as Jl}from"node:fs/promises";import ze from"node:path";import{realpath as mo}from"node:fs/promises";import go from"node:path";var zn=async e=>{try{let n=(await v("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[r,s]=await Promise.all([mo(n).catch(()=>go.resolve(n)),mo(e).catch(()=>go.resolve(e))]);return r===s}catch{return!1}},Yn=async e=>{let t=await M("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 M("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await v("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as we,readFile as Hl}from"node:fs/promises";import X from"node:path";function Re(e){let t=X.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:X.join(t,"index.json"),reposDir:X.join(t,"repos"),workspacesDir:X.join(t,"workspaces"),sessionsDir:X.join(t,"sessions"),runtimeDir:X.join(t,"runtime"),uiStateFile:X.join(t,"runtime","ui-state.json"),tasksDir:X.join(t,"tasks"),jobsDir:X.join(t,"jobs"),logsDir:X.join(t,"logs"),errorLogFile:X.join(t,"logs","errors.log"),artifactsDir:X.join(t,"artifacts"),worktreesDir:X.join(t,"worktrees"),configFile:X.join(t,"config.json")}}var zl=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",He=async e=>{let t=Re(e);await we(t.craigDir,{recursive:!0}),await Promise.all([we(t.reposDir,{recursive:!0}),we(t.workspacesDir,{recursive:!0}),we(t.sessionsDir,{recursive:!0}),we(t.runtimeDir,{recursive:!0}),we(t.tasksDir,{recursive:!0}),we(t.jobsDir,{recursive:!0}),we(t.logsDir,{recursive:!0}),we(t.artifactsDir,{recursive:!0}),we(t.worktreesDir,{recursive:!0})]);try{let s=await Hl(t.indexFile,"utf8"),o=JSON.parse(s);return yt(o,e,t.indexFile)}catch(s){if(!zl(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};var ho=(e,t,n)=>{let r=new Date().toISOString();return{id:Ql(e,ze.basename(t)),name:ze.basename(t),rootPath:t,defaultBranch:n,createdAt:r,updatedAt:r}},wo=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},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},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},ko=async(e,t)=>{let n=await ne(e);await Ce(e,{...n,repoIds:[...new Set([...n.repoIds,...t.repoIds])],workspaceIds:[...new Set([...n.workspaceIds,...t.workspaceIds])]})},Ro=async(e,t,n)=>{let r=await Y({uiStateFile:e.uiStateFile})??ge();await H({uiStateFile:e.uiStateFile},{...r,selectedRepoId:n,selectedWorkspaceId:t.id,selectedTaskId:null})},Zl=async(e,t)=>{let n=await Yl(t,{withFileTypes:!0}),r=await tt(e),s=[];for(let o of n){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=ze.join(t,o.name);if(!await zn(i))continue;let c=r.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await Yn(i);s.push(c?wo(c,l):ho([...r,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},ed=async(e,t)=>{let n=await Yn(t),r=await tt(e),s=r.find(h=>h.rootPath===t)??null,o=s?wo(s,n):ho(r,t,n),i=`workspace_${o.id}`,l=(await re(e)).find(h=>h.id===i)??null,d=new Date().toISOString(),p=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 vn(e,o),l||await Fe(e,p),await ko(e,{repoIds:[o.id],workspaceIds:[p.id]}),await Ro(e,p,o.id),{kind:"createWorkspace",workspace:p,repos:[o],created:!l}},td=async(e,t)=>{let n=await Zl(e,t);if(n.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let r=await re(e),s=Xl(r,ze.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:ze.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=>vn(e,d))),await Fe(e,l),await ko(e,{repoIds:c,workspaceIds:[l.id]}),await Ro(e,l,c[0]??null),{kind:"createWorkspace",workspace:l,repos:n,created:!o}},it=async(e,t)=>{await He(e.workspaceRoot);let n=ze.resolve(e.workspaceRoot,t);if(!(await Jl(n).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${n}`);return await zn(n)?ed(e,n):td(e,n)};var Jn=async(e,t,n={listWorkspaceRecords:re,ensureCraigState:He})=>(await n.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await n.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var Qn=async(e,t,n={readWorkspace:Oe,writeWorkspace:Fe,readUiState:Y,writeUiState:H})=>{let s={...await n.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};await n.writeWorkspace(e,s);let o=await n.readUiState({uiStateFile:e.uiStateFile});return o&&o.selectedWorkspaceId===t&&await n.writeUiState({uiStateFile:e.uiStateFile},{...o,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null}),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var Xn=async(e,t)=>{let r={...await Oe(e,t),status:"active",archivedAt:null};await Fe(e,r);let s=await Y({uiStateFile:e.uiStateFile})??null;return await H({uiStateFile:e.uiStateFile},{...s??ge(),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}};var Ne=async(e,t,n={deleteWorkspace:$s,readCraigIndex:ne,writeCraigIndex:Ce})=>{await n.deleteWorkspace(e,t);let r=await n.readCraigIndex(e);await n.writeCraigIndex(e,{...r,workspaceIds:r.workspaceIds.filter(s=>s!==t)})};var nd=async(e,t)=>{let n=await Y({uiStateFile:e.uiStateFile});!n||n.selectedWorkspaceId!==t||await H({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})},Zn=async(e,t)=>{let n=await Oe(e,t),r=await he(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 Ne(e,t),await nd(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var er={};mn(er,{addRepo:()=>To,listRegisteredRepos:()=>yo,removeRepo:()=>Po});import rd from"node:path";import{stat as sd}from"node:fs/promises";var To=async(e,t)=>{let n=rd.resolve(e.workspaceRoot,t);if(!(await sd(n).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${n}`);let s=await it(e,t),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${n}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}};var yo=async(e,t={listRepos:tt,ensureCraigState:He})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var Po=async(e,t)=>{let n=await de(e,t),s=(await re(e)).filter(d=>d.primaryRepoId===t),o=s.filter(d=>d.status==="active"),i=await he(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=>Ne(e,d.id))),await vs(e,t);let c=await ne(e);await Ce(e,{...c,repoIds:c.repoIds.filter(d=>d!==t)});let l=await Y({uiStateFile:e.uiStateFile});return l?.selectedRepoId===t&&await H({uiStateFile:e.uiStateFile},{...l,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var Z={addWorkspace:it,listWorkspaces:Jn,archiveWorkspace:Qn,restoreWorkspace:Xn,removeWorkspace:Zn,removeWorkspaceRecord:Ne,repos:er};async function bo(e,t,n){let[r,s]=await Promise.all([L(e,t),de(e,n)]);if(r.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${r.id}.`);let o=r.linkedRepoIds.includes(s.id)?r.linkedRepoIds:[...r.linkedRepoIds,s.id];return await A(e,{...r,linkedRepoIds:o}),{kind:"addTaskLink",taskId:r.id,repoId:s.id,linkedRepoIds:o}}async function So(e,t){let n=await L(e,t),r=await Promise.all(n.linkedRepoIds.map(s=>de(e,s)));return{kind:"listTaskLinks",taskId:n.id,repos:r}}async function Io(e,t){switch(e.kind){case"addWorkspace":return Z.addWorkspace(t.paths,e.path);case"addRepo":return Z.repos.addRepo(t.paths,e.path);case"listRepos":return Z.repos.listRegisteredRepos(t.paths);case"removeRepo":return Z.repos.removeRepo(t.paths,e.repoId);case"listWorkspaces":return Z.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":return Z.archiveWorkspace(t.paths,e.workspaceId);case"restoreWorkspace":return Z.restoreWorkspace(t.paths,e.workspaceId);case"removeWorkspace":return Z.removeWorkspace(t.paths,e.workspaceId);case"createTask":return Vs(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?he(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):he(t.paths);case"attachTask":return ao(t.paths,e.taskId);case"addTaskLink":return bo(t.paths,e.taskId,e.repoId);case"listTaskLinks":return So(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return Bn(t.paths,e.taskId);case"showSelectedTask":return Bn(t.paths,We(t,"show"));case"streamTaskLogs":return Un(t.paths,e.taskId);case"streamSelectedTaskLogs":return Un(t.paths,We(t,"logs"));case"showTaskDiff":return qn(t.paths,e.taskId);case"showSelectedTaskDiff":return qn(t.paths,We(t,"diff"));case"focusTask":return Kn(t.paths,e.taskId);case"focusSelectedTask":return Kn(t.paths,We(t,"focus"));case"openTask":return Vn(t.paths,e.taskId);case"openSelectedTask":return Vn(t.paths,We(t,"open"));case"runChecks":return Gn(t.paths,e.taskId);case"runSelectedTaskChecks":return Gn(t.paths,We(t,"check"));case"commitTask":return Hn(t.paths,e.taskId);case"commitSelectedTask":return Hn(t.paths,We(t,"commit"));case"help":return{kind:"help",text:Q()};case"exit":return{kind:"exit"};default:return od(e)}}function od(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function We(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function Co(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} ${
|
|
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}`,...
|
|
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} ${cd(t)} ${ld(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}`,...id(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
|
|
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(
|
|
125
|
+
`);default:return ad(e)}}function id(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 ad(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function cd(e){return e.checks.status}function ld(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"}`:"-"}import{createRequire as ff}from"node:module";import{readdir as mf,stat as gf}from"node:fs/promises";import Qe from"node:path";import{appendFile as dd,mkdir as ud,readFile as pd}from"node:fs/promises";import fd from"node:path";var md=80;async function gd(e,t){await ud(fd.dirname(e.errorLogFile),{recursive:!0}),await dd(e.errorLogFile,hd(t),"utf8")}async function tr(e,t){try{await gd(e,t)}catch{}}async function xo(e,t=md){try{let r=(await pd(e.errorLogFile,"utf8")).trimEnd().split(`
|
|
126
|
+
`).filter(s=>s.length>0);return{path:e.errorLogFile,lines:r.slice(Math.max(0,r.length-t)),empty:r.length===0}}catch(n){if(wd(n))return{path:e.errorLogFile,lines:[],empty:!0};throw n}}function hd(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
|
|
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
|
|
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
|
|
133
|
-
`),byteLength:s.byteLength}}catch(r){let s=r instanceof Error?r.message:"Unable to read file.";return
|
|
134
|
-
${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let c=await
|
|
135
|
-
${c.stdout.trimEnd()}`)}if(o.includes("unstaged")){let c=await
|
|
136
|
-
${c.stdout.trimEnd()}`)}if(o.includes("untracked")){let c=await
|
|
130
|
+
`}function wd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{readFile as kd,stat as Rd}from"node:fs/promises";import nr from"node:path";var Td=200*1024,yd=500*1024,jt="100000";async function Eo(e,t,n){if(e.type==="project"&&e.repoTargets?.length)return Pd(e,t,n);try{let r=ve(n.selectedFilePath??null,t.filePaths),s=ve(n.selectedDiffPath??null,t.diffPaths),o=s?await at(e.worktreePath):null,[i,c]=await Promise.all([Ft(e.worktreePath,r),s?rr(e.worktreePath,s,t.diffRows,o):Promise.resolve(J("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 Pd(e,t,n){let r=ve(n.selectedFilePath??null,t.filePaths),s=ve(n.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([$o(e,r),(async()=>{if(!s)return J("No diff selected","No local changes found.","empty");let l=Ot(e,s),d=l?await at(l.target.worktreePath).catch(()=>null):null;return Do(e,s,t.diffRows,d)})()]),c=s?{[s]:i}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:c,selectedFile:o,selectedDiff:i}}async function Ao(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return bd(e,t);try{await ce(e);let n=await at(e.worktreePath),[r,s]=await Promise.all([Mo(e.worktreePath),Lo(e.worktreePath,n)]),o=[...new Set(s.map(h=>h.path))],i=ve(t.selectedFilePath??null,r),c=ve(t.selectedDiffPath??null,o),[l,d]=await Promise.all([Ft(e.worktreePath,i),c?rr(e.worktreePath,c,s,n):Promise.resolve(J("No diff selected","No local changes found.","empty"))]),p=c?{[c]:d}:{};return{taskId:e.id,fileRows:Fo(r),filePaths:r,diffRows:s,diffPaths:o,diffContents:p,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:J("Files unavailable",r,"error"),selectedDiff:J("Diff unavailable",r,"error"),error:r}}}async function bd(e,t){let n=(e.repoTargets??[]).filter(R=>R.status==="ready"),r=await Promise.all(n.map(async R=>{let k=await at(R.worktreePath).catch(()=>null),[I,T]=await Promise.all([Mo(R.worktreePath).catch(()=>[]),Lo(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=ve(t.selectedFilePath??null,s),l=ve(t.selectedDiffPath??null,i),[d,p]=await Promise.all([$o(e,c),(async()=>{if(!l)return J("No diff selected","No local changes found.","empty");let R=Ot(e,l),k=R?r.find(I=>I.target.repoId===R.target.repoId):null;return Do(e,l,o,k?.baseRef??null)})()]),h=l?{[l]:p}:{};return{taskId:e.id,fileRows:Fo(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:h,selectedFilePath:c,selectedDiffPath:l,selectedFile:d,selectedDiff:p,error:null}}async function $o(e,t){let n=Ot(e,t);if(!n)return J("No file selected","No Git-visible files found.","empty");let r=await Ft(n.target.worktreePath,n.relativePath);return{...r,path:t,title:t??r.title}}async function Do(e,t,n,r=null){let s=Ot(e,t);return s?{...await rr(s.target.worktreePath,s.relativePath,n.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),r),path:t,title:t}:J(t,"Repo target is unavailable.","error",t)}function Ot(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 Mo(e){let t=await v("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return No(t.stdout)}async function Lo(e,t){let[n,r,s,o]=await Promise.all([Sd(e,t),vo(e,"staged"),vo(e,"unstaged"),Id(e)]);return[...n,...r,...s,...o]}async function Sd(e,t){if(!t)return[];let[n,r]=await Promise.all([v("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),v("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=jo(n.stdout),o=Oo(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 vo(e,t){let n=t==="staged"?["diff","--cached"]:["diff"],[r,s]=await Promise.all([v("git",[...n,"--name-status"],{cwd:e}),v("git",[...n,"--numstat"],{cwd:e})]),o=jo(r.stdout),i=Oo(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 v("git",["ls-files","--others","--exclude-standard"],{cwd:e}),n=No(t.stdout);return await Promise.all(n.map(async s=>{let o=await Ft(e,s),i=o.status==="ready"?Cd(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function jo(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 Oo(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 at(e){return(await M("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await M("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function Ft(e,t){if(!t)return J("No file selected","No Git-visible files found.","empty");let n=xd(e,t);try{let r=await Rd(n);if(r.size>Td)return J(t,`File is ${r.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,r.size);let s=await kd(n);return vd(s)?J(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 J(t,s,"missing",t,null)}}async function rr(e,t,n,r=null){if(!t)return J("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 at(e);if(c){let l=await v("git",["diff","--stat","--patch",`--unified=${jt}`,`${c}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
|
|
134
|
+
${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let c=await v("git",["diff","--cached","--stat","--patch",`--unified=${jt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`staged
|
|
135
|
+
${c.stdout.trimEnd()}`)}if(o.includes("unstaged")){let c=await v("git",["diff","--stat","--patch",`--unified=${jt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`unstaged
|
|
136
|
+
${c.stdout.trimEnd()}`)}if(o.includes("untracked")){let c=await M("git",["diff","--no-index","--stat","--patch",`--unified=${jt}`,"--","/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>
|
|
140
|
-
`):["No diff for this file."],byteLength:i.length}}function
|
|
141
|
-
`).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,n)=>t.localeCompare(n))}function vd(e,t){let n=ar.resolve(e,t),r=ar.resolve(e);if(n!==r&&!n.startsWith(`${r}${ar.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return n}function Ed(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function H(e,t,n,r=null,s=null){return{path:r,status:n,title:e,lines:[t],byteLength:s}}ie();import{access as Ad}from"node:fs/promises";async function _o(e,t){let n=await M(e,t),r=await $d(n.worktreePath),s={...n,status:"closed",cleanup:{...n.cleanup,preservedWorktree:r&&n.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await E(e,s),s}async function $d(e){try{return await Ad(e),!0}catch{return!1}}ue();ce();import Ct from"node:path";function Bo(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"\u{F06E6} ";case"js":case"jsx":case"mjs":case"cjs":return"\u{F031E} ";case"json":case"jsonc":return"\u{F0871} ";case"md":case"mdx":return"\u{F0354} ";case"yaml":case"yml":return"\u{F0B10} ";case"sh":case"bash":case"zsh":return"\u{F018D} ";case"css":case"scss":case"sass":return"\u{F031C} ";case"html":case"htm":return"\u{F031D} ";case"py":return"\u{F0320} ";case"go":return"\u{F07D3} ";case"rs":return"\u{F1617} ";case"lock":return"\u{F033E} ";case"png":case"jpg":case"jpeg":case"gif":case"svg":case"webp":return"\u{F02E9} ";default:return"\u{F0214} "}}var Uo="\u{F024B} ",qo="\u{F0DCF} ",Ko="\u25CB",lr="\uEA64",Vo="\uEAFE",Go="\uEBDA",dr="\u25CB",ur="\u25CF",fr="\u2713",pr="\u2715";function Ho(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"4fc1ff";case"js":case"jsx":case"mjs":case"cjs":return"f7df1e";case"json":case"jsonc":return"fbc02d";case"md":case"mdx":return"519aba";case"yaml":case"yml":return"e06c75";case"sh":case"bash":case"zsh":return"89e051";case"css":case"scss":case"sass":return"c792ea";case"html":case"htm":return"e06c75";case"py":return"3572a5";case"go":return"00add8";case"rs":return"dea584";case"lock":return"565f89";default:return}}ue();rt();ue();var Dd=["tasks","center","inspector","actions"],Zo=["agent","terminal"],ei=[],A="inspection",Mw=[...Zo,...ei],ti=["commit","push","refresh-checks","close-task"],Md=["refresh-checks","close-task"],ni=["task","checks","pr","setup-run","actions","next-action"],ri=["diff","files","review"];function si(e,t={}){let n=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,r=Yd(e?.openInspectionKind)??n,s=Ze(t);return{inputMode:Qd(e?.inputMode),focusedRegion:Hd(e?.focusedRegion),selectedRepoId:xe(e?.selectedRepoId),selectedWorkspaceId:xe(e?.selectedWorkspaceId),selectedTaskId:xe(e?.selectedTaskId),selectedPtyTabId:xe(e?.selectedPtyTabId),selectedLeftItemId:iu(xe(e?.selectedTaskId)),activeTab:n?A:xe(e?.activeTab)??"agent",preferredPtyTabKind:Jd(e?.preferredPtyTabKind),inspectorSection:It(e?.inspectorSection,ni,"task"),inspectionMode:zd(e?.inspectionMode,n==="diff"?"diff":"files"),openInspectionKind:r,selectedFileTreePath:xe(e?.selectedFileTreePath),selectedFilePath:xe(e?.selectedFilePath),selectedDiffPath:xe(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:It(e?.selectedActionId,ti,"commit"),selectedProjectTargetId:null,selectedRunner:Xd(e?.selectedRunner,s,_e(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:Ld(),centerZoomed:!1}}function Ld(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function oi(e,t){return{...e??Pe(),selectedRepoId:t.selectedRepoId,selectedWorkspaceId:t.selectedWorkspaceId,selectedTaskId:t.selectedTaskId,selectedPtyTabId:t.selectedPtyTabId,inputMode:t.inputMode,focusedRegion:t.focusedRegion,activeTab:t.activeTab,preferredPtyTabKind:t.preferredPtyTabKind,inspectorSection:t.inspectorSection,inspectionMode:t.inspectionMode,openInspectionKind:t.openInspectionKind,selectedFileTreePath:t.selectedFileTreePath,selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath,collapsedFileTreePaths:t.collapsedFileTreePaths,selectedActionId:t.selectedActionId,selectedRunner:t.selectedRunner}}function nn(e,t,n={}){let r=su(e,t),s=pi(r),o=(s?.kind==="workspace"?t.workspaces?.find(f=>f.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(f=>f.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,c=((s?.kind==="repo"?t.repos.find(f=>f.id===s.id)??null:s?.kind==="task"?t.repos.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(f=>f.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(f.id))??null:null)??(o?.kind!=="project"?t.repos.find(f=>f.id===o?.primaryRepoId)??null:null)??t.repos.find(f=>f.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(f=>f.workspaceId===o.id):c?t.tasks.filter(f=>f.repoId===c):[],d=(s?.kind==="task"?l.find(f=>f.id===s.id)??null:null)??l.find(f=>f.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:n.resetInputMode?"control":e.inputMode,selectedLeftItemId:r,selectedWorkspaceId:o?.id??null,selectedRepoId:c,selectedTaskId:d?.id??null,...eu(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:Kd(e,t,d?.id??null),...tu(e,t,d?.id??null),selectedDiffPath:qd(e,t,d?.id??null),inspectorSection:It(e.inspectorSection,ni,"task")}}function ii(e,t,n={leftItemIds:[]}){if(e.inputMode==="terminal")return Od(t)?b({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):b({state:e});if(t==="q"||t==="Q")return b({state:e,exit:!0});if(t==="ESCAPE")return b({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return b({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(gr(e.selectedLeftItemId)||hr(e.selectedLeftItemId)))return b({state:{...e,selectedRunner:wr(e.selectedRunner,n.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return zo(e,1);if(t==="SHIFT_TAB"||t==="[")return zo(e,-1);if(t==="z"||t==="Z")return b({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===A?Fe(e,-1,n):Yo(e,-1,n);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===A?Fe(e,1,n):Yo(e,1,n);if(t==="PAGE_UP")return Fe(e,-(n.pageRows??10),n);if(t==="PAGE_DOWN")return Fe(e,n.pageRows??10,n);if(t==="MOUSE_WHEEL_UP")return Fe(e,-3,n);if(t==="MOUSE_WHEEL_DOWN")return Fe(e,3,n);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let r=n.enabledRunnerIds??N,s=e.centerTabRunner?r.indexOf(e.centerTabRunner):-1,o=s===r.length-1?null:r[s+1];return b({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let r=Zd(e,t);return b({state:{...e,preferredPtyTabKind:r,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:r,createPtyTabRunner:r==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return b({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return b({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return b({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&tn(e.selectedLeftItemId)&&e.selectedTaskId)return b({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&au(e.selectedLeftItemId)&&e.selectedWorkspaceId)return b({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Xo(e.activeTab,n.ptyTabIds??[]))return b({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return mr(e,-1,n.centerTabIds);if(e.focusedRegion==="inspector")return Jo(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return mr(e,1,n.centerTabIds);if(e.focusedRegion==="inspector")return Jo(e,1)}if(Ee(t)){if(e.focusedRegion==="tasks"&&(gr(e.selectedLeftItemId)||hr(e.selectedLeftItemId))){let r=mi(e.selectedLeftItemId),s=gi(e.selectedLeftItemId);return b({state:{...e,selectedRepoId:r??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return b({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&tn(e.selectedLeftItemId)&&e.selectedTaskId){let r=e.selectedPtyTabId??e.activeTab;return b({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:r,selectedPtyTabId:r,preferredPtyTabKind:St(r)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Xo(e.activeTab,n.ptyTabIds??[])&&e.selectedTaskId)return b({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:St(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===A)return b({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let r=e.selectedFileTreePath??e.selectedFilePath;if(r&&(n.fileTreeDirectoryIds??[]).includes(r))return b({state:_d({...e,selectedFileTreePath:r}),changed:!0});let s=r&&(n.fileTreeFileIds??[]).includes(r)?r:e.selectedFilePath;return b({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:A,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?b({state:{...e,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!n.projectTargetIds?.length?b({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):b({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?b({state:e}):e.selectedActionId==="refresh-checks"?b({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?b({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):b({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return b({state:e})}function Ye(e,t){return{...e,terminal:t}}function ai(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Od(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Ee(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
142
|
-
`}function ci(e){return e.length===1&&e>=" "&&e!=="\x7F"}function li(e){return di(e)||St(e)!==null}function Fd(e){return ei.includes(e)}function di(e){return Zo.includes(e)}function ui(e,t){return[...e?.ptyTabs.map(n=>n.id)??[],...t?.openInspectionKind?[A]:[]]}var jd=["tasks","center","inspector"];function zo(e,t){return Zt(e,"focusedRegion",jd,t)}function mr(e,t,n){let r=Zt(e,"activeTab",n&&n.length>0?n:ru(e),t);return!r.changed||Fd(r.state.activeTab)?r:{...r,state:{...r.state,selectedPtyTabId:r.state.activeTab,preferredPtyTabKind:St(r.state.activeTab)??r.state.preferredPtyTabKind}}}function Yo(e,t,n){if(e.focusedRegion==="tasks")return Nd(e,t,n.leftItemIds);if(e.focusedRegion==="center")return mr(e,t,n.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return fi(e,t,n);if(e.inspectionMode==="diff"){let r=en(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:r}if(n.projectTargetIds?.length){let r=en(e,"selectedProjectTargetId",n.projectTargetIds,t);return r.changed?{...r,state:{...r.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:r}return Zt(e,"selectedActionId",Md,t)}return Zt(e,"selectedActionId",ti,t)}function Nd(e,t,n){let r=en(e,"selectedLeftItemId",n,t);if(!r.changed)return r;let s=pi(r.state.selectedLeftItemId);if(s?.kind==="workspace")return{...r,state:{...r.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...r,state:{...r.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...r,state:{...r.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=mi(r.state.selectedLeftItemId);if(o)return{...r,state:{...r.state,selectedRepoId:o}};let i=gi(r.state.selectedLeftItemId);return i?{...r,state:{...r.state,selectedWorkspaceId:i}}:r}function Fe(e,t,n){if(t===0)return b({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return fi(e,t,n);if(e.inspectionMode==="diff"){let r=en(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,diffScrollOffset:0}}:r}return e.inspectionMode==="review"?Qo(e,"reviewScrollOffset",t,n.reviewRowCount??100,n.pageRows):b({state:e})}if(e.focusedRegion==="center"&&e.activeTab===A){if(e.openInspectionKind==="file")return Qo(e,"fileScrollOffset",t,n.fileLineCount??0,n.pageRows);if(e.openInspectionKind==="diff")return Bd(e,t,n)}return b({state:e})}function Wd(e,t){if(e.inspectionMode===t)return b({state:e});let n=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,r=t==="diff"||t==="files"?A:e.activeTab;return b({state:{...e,inspectionMode:t,activeTab:r,openInspectionKind:n,fileScrollOffset:t==="files"?0:e.fileScrollOffset,diffScrollOffset:t==="diff"?0:e.diffScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function Jo(e,t){return Wd(e,Gd(e.inspectionMode,ri,t))}function fi(e,t,n){let r=n.fileTreeRowIds&&n.fileTreeRowIds.length>0?n.fileTreeRowIds:n.filePathIds??[];if(r.length===0)return b({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??r[0]??null,o=r.indexOf(s??""),i=ve(o===-1?0:o+t,0,r.length-1),c=r[i]??null;if(c===e.selectedFileTreePath)return b({state:e});let l=c!==null&&(n.fileTreeFileIds??n.filePathIds??[]).includes(c);return b({state:{...e,selectedFileTreePath:c,selectedFilePath:l?c:e.selectedFilePath,activeTab:l?A:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function _d(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((n,r)=>n.localeCompare(r)),actionMessage:null}}function Qo(e,t,n,r,s=10){let o=Math.max(0,r-Math.max(1,s)),i=ve(e[t]+n,0,o);return i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Bd(e,t,n){if(n.diffPathRanges&&n.diffPathRanges.length>0)return Ud(e,t,n);let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=e.diffScrollOffset+t,c=n.diffPathIds??[];if(c.length===0||!e.selectedDiffPath){let f=ve(i,0,o);return f===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}let l=c.indexOf(e.selectedDiffPath);if(l===-1){let f=ve(i,0,o);return f===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}if(t>0&&i>o){let f=c[l+1]??null;return f?b({state:{...e,selectedDiffPath:f,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?b({state:e}):b({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let f=c[l-1]??null;return f?b({state:{...e,selectedDiffPath:f,activeTab:A,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?b({state:e}):b({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=ve(i,0,o);return d===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function Ud(e,t,n){let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=ve(e.diffScrollOffset+t,0,o),c=Vd(n.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&c===e.selectedDiffPath?b({state:e}):b({state:{...e,diffScrollOffset:i,selectedDiffPath:c,actionMessage:null},changed:!0})}function qd(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function Kd(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function Vd(e,t){return e.find(n=>t>=n.start&&t<n.end)?.path??e.at(-1)?.path??null}function Zt(e,t,n,r){let s=n.indexOf(e[t]),o=ve(s+r,0,n.length-1),i=n[o];return!i||i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function en(e,t,n,r,s=!1){if(n.length===0)return b({state:e});let o=n.indexOf(e[t]??n[0]??""),i=ve(o===-1?0:o+r,0,n.length-1),c=n[i]??null;return c===e[t]?b({state:e}):b({state:{...e,[t]:c,actionMessage:null},changed:!0,refreshInspection:s})}function Gd(e,t,n){let r=t.indexOf(e);return t[ve(r+n,0,t.length-1)]??e}function b(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function It(e,t,n){return t.includes(e??"")?e:n}function Hd(e){return e==="tabs"?"center":It(e,Dd,"tasks")}function zd(e,t){return e==="checks"||e==="actions"||e==="review"?"review":It(e,ri,t)}function Yd(e){return e==="file"||e==="diff"?e:null}function Jd(e){return e==="terminal"?"terminal":"agent"}function Qd(e){return e==="terminal"?"terminal":"control"}function Xd(e,t=[...N],n="codex"){return e&&et(e)&&t.includes(e)?e:n}function wr(e,t=N){let n=t.length>0?t:N,r=n.indexOf(e);return n[(r+1)%n.length]??n[0]??"codex"}function St(e){let t=N.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Zd(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":St(e.activeTab)??e.preferredPtyTabKind}function eu(e,t,n){if(!e)return{activeTab:t===A?t:"agent",selectedPtyTabId:null};let r=e.ptyTabs.find(c=>c.id===n)??null,s=e.selectedPtyTabId?e.ptyTabs.find(c=>c.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(c=>c.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(di(t)){let l=e.ptyTabs.find(d=>d.kind===t)??null??s??r??e.ptyTabs[0]??null;return{activeTab:l?.id??A,selectedPtyTabId:l?.id??null}}if(t===A)return{activeTab:A,selectedPtyTabId:r?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??r??e.ptyTabs[0]??null;return{activeTab:i?.id??A,selectedPtyTabId:i?.id??null}}function tu(e,t,n){if(!t.inspection||t.inspection.taskId!==n)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let r=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?nu(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:r,collapsedFileTreePaths:s}}function nu(e,t){let n=new Set;if(t){let r=t.split("/");for(let s=1;s<r.length;s+=1)n.add(r.slice(0,s).join("/"))}return e.filter(r=>r.kind==="directory"&&!r.path.includes("/")&&!n.has(r.path)).map(r=>r.path).sort((r,s)=>r.localeCompare(s))}function ru(e){return[e.selectedPtyTabId,e.openInspectionKind?A:null].filter(t=>typeof t=="string")}function Xo(e,t){return t.includes(e)}function su(e,t){let n=ou(t);return e.selectedLeftItemId&&n.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&n.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&n.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&n.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:n[0]??null}function ou(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function pi(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function xe(e){return typeof e=="string"?e:null}function iu(e){return e?`task:${e}`:null}function tn(e){return typeof e=="string"&&e.startsWith("task:")}function gr(e){return typeof e=="string"&&e.startsWith("new-task:")}function hr(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function au(e){return typeof e=="string"&&e.startsWith("workspace:")}function mi(e){return gr(e)?e.slice(9):null}function gi(e){return hr(e)?e.slice(19):null}function ve(e,t,n){return Math.min(n,Math.max(t,e))}var sn="empty",B={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Ri(e,t){let n=du(t,e),r=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=n?t.tasks.filter(T=>T.workspaceId===n.id):t.tasks,o=n?.kind==="project"?s:r?s.filter(T=>T.repoId===r.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,c=i?.type==="project",l=Gu(t.tasks),d=pu(e,i),f=fu(e,i,d),h=f.find(T=>T.id===d)??f[0]??{id:"agent",label:"CODEX"},R=t.inspection?.taskId===i?.id?t.inspection:null,k=r?.name??"no repo",I=i?se(i.runner):se(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${r?`[${r.name}]`:"[no repo]"} \xB7 ${se(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${se(e.selectedRunner)}] Enter create task Esc pause ? help`:tn(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?i===null?"n new task Tab tasks Esc pause ? help":d===A?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${se(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?c?"\u2191\u2193 targets Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?"\u2191\u2193 navigate Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:Ct.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Ct.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:I},leftTree:cu(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>Hu(T,l[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":h.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:k,agent:I},centerTranscript:uu(d,e,r,i,e.workspaceBrowser,R,n),tabs:f,rightContext:Vu(r,i),rightInspection:Cu(e,i,R)}}function cu(e,t){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return lu(n,e,t.repos,t.tasks);let r=t.workspaces;if(r.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of r){let i=e.selectedLeftItemId===`workspace:${o.id}`;n.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:i,focused:i&&e.focusedRegion==="tasks"});let c=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],l=t.tasks.filter(d=>d.workspaceId===o.id);if(l.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of l){let f=e.selectedLeftItemId===`task:${d.id}`,h=f?"\u25B8":"\u2022",R=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,k={id:`task:${d.id}`,taskId:d.id,text:`${h} ${R}`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks"},I=yi(d);I&&(k.prBadge=I),n.push(k)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${se(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${se(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}else{n.push({text:` Repos (${c.length})`,indent:0,muted:!0});for(let d of c.slice(0,6)){let f=t.repos.find(h=>h.id===d);n.push({text:` \xB7 ${f?.name??d}`,indent:0,muted:!0})}c.length>6&&n.push({text:` \xB7 ${c.length-6} more`,indent:0,muted:!0})}}let s=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&e.focusedRegion==="tasks"}),n}function lu(e,t,n,r){if(n.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of n){let i=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:i,focused:i&&t.focusedRegion==="tasks"});let c=r.filter(f=>f.repoId===o.id);if(c.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let f of c){let h=t.selectedLeftItemId===`task:${f.id}`,R=h?"\u25B8":"\u2022",k=f.title.length>28?`${f.title.slice(0,25)}\u2026`:f.title,I={id:`task:${f.id}`,taskId:f.id,text:`${R} ${k}`,indent:2,selected:h,focused:h&&t.focusedRegion==="tasks"},T=yi(f);T&&(I.prBadge=T),e.push(I)}let l=`new-task:${o.id}`,d=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${se(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let s=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&t.focusedRegion==="tasks"}),e}function du(e,t){let n=e.workspaces??[];if(!e.workspaces)return null;let r=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return r?n.find(s=>s.id===r.workspaceId)??null:t.selectedWorkspaceId?n.find(s=>s.id===t.selectedWorkspaceId)??null:n[0]??null}function uu(e,t,n,r,s,o=null,i=null){if(s){let l=s.entries.length===0?["No directories or git repos here."]:s.entries.map((d,f)=>{let h=f===s.selectedIndex?"\u25B8":" ",R=d.kind==="repo"?" [git repo]":"/";return`${h} ${d.name}${R}`});return ge(["Browse for a workspace to register.",s.cwd,"",...l,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!n)return ge(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!r){let l=i?.kind==="project",d=l?i.name??"this workspace":n.name,f=l?"Project Task":"Task";return ge([`No tasks in ${d}.`,"",`Press n or choose + New ${f} to create one with ${se(t.selectedRunner)}.`])}let c=r.ptyTabs.find(l=>l.id===e)??null;return c?c.kind==="agent"?ge([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):ge([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===A&&t.openInspectionKind==="file"?hu(r,o,t.fileScrollOffset):e===A&&t.openInspectionKind==="diff"?wu(r,o,t.diffScrollOffset):r.ptyTabs.length===0&&!t.openInspectionKind?ge(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ge(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function fu(e,t,n){let r=t?.ptyTabs.map(o=>({id:o.id,label:mu(o)}))??[];if(!t)return[{id:sn,label:"EMPTY",active:n===sn,focused:e.focusedRegion==="center"&&n===sn}];let s=e.openInspectionKind||n===A?[{id:A,label:gu(e)}]:[];return[...r,...s].map(o=>({...o,active:o.id===n,focused:e.focusedRegion==="center"&&o.id===n}))}function pu(e,t){return t?t.ptyTabs.some(n=>n.id===e.activeTab)||e.activeTab===A&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(n=>n.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??A:e.selectedPtyTabId&&t.ptyTabs.some(n=>n.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??A:sn}function mu(e){return e.title.toUpperCase()}function gu(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,n=t?Ct.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${n} \u0394`:n}function hu(e,t,n){if(!e)return ge(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ge(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let r=t.selectedFile,s=Ti(r.path??r.title);return[{text:r.title},{text:`${r.byteLength===null?"size unknown":`${r.byteLength} bytes`} \xB7 ${r.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...ku(r.lines,n,s)]}function wu(e,t,n){if(!e)return ge(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ge(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let r=t.selectedDiff,s=Ti(r.path??r.title);return[{text:r.title},{text:`${t.diffPaths.length} changed files \xB7 ${r.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Ru(r.lines,n,s)]}function ge(e){return e.map(t=>({text:t}))}function ku(e,t,n){let r=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let c=s+i+1;return{text:`${`${String(c).padStart(r," ")} \u2502 `}${o}`,segments:[{text:String(c).padStart(r," "),style:{fg:B.lineNumber}},{text:" \u2502 ",style:{fg:B.gutter}},...kr(o,n)],tone:"default"}})}function Ru(e,t,n){let r=Tu(e),s=Math.max(0,Math.min(t,Math.max(0,r.length-1)));return r.slice(s).map(o=>yu(o,n))}function Tu(e){let t=[],n=0,r=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){n=Number.parseInt(o[1]??"0",10),r=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:n,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),n+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:r,marker:"+",text:s.slice(1),kind:"add"}),r+=1;continue}if(s.startsWith(" ")){if(n===0&&r===0)continue;t.push({oldNumber:n,newNumber:r,marker:" ",text:s.slice(1),kind:"context"}),n+=1,r+=1;continue}}}return t}function yu(e,t){let n=hi(e.oldNumber),r=hi(e.newNumber),s=e.kind==="delete"?n:r,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:B.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:B.diffAdd}:null,i=`${s} \u2502 ${e.text}`,c=o?bu(kr(e.text,t),o.bg,o.fallbackFg):kr(e.text,t),l=o?{fg:B.lineNumber,bg:o.bg}:{fg:B.lineNumber},d=o?{fg:B.gutter,bg:o.bg}:{fg:B.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...c],fullBleed:o!==null}}function hi(e){return e===null?" ":String(e).padStart(4," ")}function Ti(e){let t=Ct.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function kr(e,t){return t==="diff"?Pu(e):t==="markdown"?Iu(e):t==="json"?Rr(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Rr(e,/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)|\/\/.*$|\/\*.*?\*\/|\b(const|let|var|function|return|if|else|for|while|class|interface|type|import|export|from|async|await|new|extends|implements|switch|case|break|continue|try|catch|throw|true|false|null|undefined)\b|-?\b\d+(?:\.\d+)?\b/g):[{text:e}]}function Pu(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:B.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:B.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:B.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:B.diffMeta}}]:[{text:e}]}function bu(e,t,n){return e.map(r=>({text:r.text,style:{...r.style??{fg:n},bg:t}}))}function Iu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:B.markup,bold:!0}}]:Rr(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Rr(e,t){let n=[],r=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>r&&n.push({text:e.slice(r,i)}),n.push({text:o,style:Su(o)}),r=i+o.length}return r<e.length&&n.push({text:e.slice(r)}),n.length>0?n:[{text:e}]}function Su(e){return e.startsWith("//")||e.startsWith("/*")?{fg:B.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:B.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:B.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:B.markup}:{fg:B.keyword}}function Cu(e,t,n){let r=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&r?t.repoTargets?.find(c=>c.repoId===r)??null:null,o=t?.type==="project"?Pi(t.repoTargets??[]):s?.pullRequest??(t?K(t):null),i=[xu(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Si(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,..._u(e,n)]}:{title:"",rows:[...i,...Uu(e,n)]}}function xu(e,t){let n=e.inspectionMode,r=[{label:"CHANGES",active:n==="diff"},{label:"FILES",active:n==="files"},{label:"REVIEW",active:n==="review"}],s=[];for(let l=0;l<r.length;l++){let d=r[l];l>0&&s.push({text:" "});let f=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:f}})}let o=Tr(t),i=yr(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function wi(e){return[{text:" "},Tr(e),{text:" "},yr(e)]}function yi(e){if(e.type==="project"&&e.repoTargets?.length){let n=Pi(e.repoTargets);return n?wi(n):null}let t=K(e);return t?.number?wi(t):null}function Pi(e){let t=e.filter(s=>s.status==="ready"),n=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(n.length===0)return null;let r=Eu(n);return{number:-1,status:vu(n),draft:n.some(s=>s.draft),mergeable:n.length===t.length&&n.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:n.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":n.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":n.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:n.flatMap(s=>s.requiredChecks),aggregateReadiness:r}}function vu(e){return e.some(t=>t.status==="open")?"open":e.every(t=>t.status==="merged")?"merged":e.some(t=>t.status==="closed")?"closed":e[0]?.status??null}function Eu(e){let t=e.map(n=>bi(n));return t.some(n=>n==="failed")?"failed":t.some(n=>n==="pending")?"pending":t.length>0&&t.every(n=>n==="success")?"success":"none"}function Tr(e){return!e||!e.number?{text:Ko,style:{fg:"565f89"}}:e.status==="merged"?{text:Vo,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Go,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:lr,style:{fg:"565f89"}}:{text:lr,style:{fg:"9ece6a"}}}function yr(e){return e?.aggregateReadiness?ki(e.aggregateReadiness):ki(bi(e))}function ki(e){return e==="failed"?{text:pr,style:{fg:"f7768e"}}:e==="pending"?{text:ur,style:{fg:"e0af68"}}:e==="success"?{text:fr,style:{fg:"9ece6a"}}:{text:dr,style:{fg:"565f89"}}}function bi(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(n=>n.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(n=>n.status==="success"||n.status==="skipped")?Ii(e)?"failed":Au(e)?"success":"pending":"pending"}function Au(e){return!!(e.mergeable&&!e.draft&&!Ii(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Ii(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Si(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return $u(e,t);let n=K(t),r=xi("pr",t.branch,n??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==n&&(o.status==="merged"||o.status==="closed")).length;return s>0&&r.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),Du(r,e)}var rn=32;function $u(e,t){let n=[],r=t.repoTargets??[],s=e.selectedProjectTargetId??r[0]?.repoId??null;for(let i of r){let c=s===i.repoId,l=e.focusedRegion==="inspector"&&c,d=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let h=i.failureReason?i.failureReason.slice(0,14):i.status,R=rn-h.length-1,k=d.length>R?d.slice(0,R-1)+"\u2026":d,I=rn-k.length-h.length;n.push({id:`project-review:${i.repoId}`,text:k+" ".repeat(Math.max(1,I))+h,selected:c,focused:l,muted:!0})}else{let f=Tr(i.pullRequest),h=yr(i.pullRequest),R=`${f.text} ${h.text}`,k=rn-R.length-1,I=d.length>k?d.slice(0,k-1)+"\u2026":d,T=rn-I.length-R.length,a=I+" ".repeat(Math.max(1,T));n.push({id:`project-review:${i.repoId}`,text:a+R,selected:c,focused:l,segments:[{text:a},{...f,text:f.text},{text:" "},{...h,text:h.text}]})}}let o=r.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(n.push({id:"target-detail-spacer",text:""}),n.push(...xi("target",o.branch,o.pullRequest))),n}function Ci(e,t){return Si(e,t).length}function xi(e,t,n){let r=h=>`${e}-${h}`;if(!n.number)return[{id:r("no-pr"),text:t,muted:!0}];let s=[],o=`#${n.number}`;s.push(n.url?{id:r("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:n.url}]}:{id:r("pr-number"),text:o});let i=n.baseBranch??"?",c=n.headBranch??t;s.push({id:r("pr-branches"),text:`${i} \u2192 ${c}`,muted:!0});let l=Mu(n.reviewDecision,n.mergeStateStatus),d=l&&l!=="review approved"?"merge blocked":n.mergeable?"merge ready":n.mergeStateStatus?`merge ${n.mergeStateStatus}`:"merge unknown";l?s.push({id:r("pr-merge"),text:`${d} \xB7 ${l}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:l,style:{fg:Lu(n.reviewDecision,n.mergeStateStatus)}}]}):s.push({id:r("pr-merge"),text:d,muted:!0}),s.push({id:r("pr-synced"),text:`synced ${vi(n.lastSyncedAt)}`,muted:!0}),s.push({id:r("checks-spacer"),text:""}),s.push({id:r("checks-header"),text:"Checks"}),n.requiredChecks.length?s.push(...n.requiredChecks.map(Ou)):s.push({id:r("checks-none"),text:n.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let f=n.comments??[];return f.length>0&&(s.push({id:r("comments-spacer"),text:""}),s.push({id:r("comments-header"),text:`Review comments (${f.length})`}),s.push(...f.slice(-4).flatMap((h,R)=>Fu(h,r(`comment:${R}`))))),s}function Du(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let n=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((r,s)=>({...r,selected:t.reviewScrollOffset===0&&r.selected||s===n,focused:t.reviewScrollOffset===0&&r.focused||s===n}))}function Mu(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Lu(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function vi(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;let r=Math.floor(n/60);if(r<60)return`${r}m ago`;let s=Math.floor(r/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function Ou(e){let{icon:t,color:n}=Nu(e.status),r=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${r.padEnd(16," ")} ${Wu(e.status)}`,color:n,muted:!1}}function Fu(e,t){let n=e.author??"unknown",r=e.createdAt?` \xB7 ${vi(e.createdAt)}`:"",s=ju(e.body,30),o=s.slice(0,4),i=o.length<s.length,c=[{id:`${t}:author`,text:`${n}${r}`,muted:!0},...o.map((l,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return c.push({id:`${t}:spacer`,text:"",muted:!0}),c}function ju(e,t){let n=e.split(/\s+/).filter(Boolean);if(n.length===0)return[];let r=[],s="";for(let o of n){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(r.push(s),s=o)}return s&&r.push(s),r}function Nu(e){switch(e){case"success":return{icon:fr,color:"9ece6a"};case"pending":return{icon:ur,color:"e0af68"};case"failed":return{icon:pr,color:"f7768e"};case"skipped":return{icon:dr,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function Wu(e){return e==="success"?"passing":e==="failed"?"failing":e}function _u(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let n=new Map(t.diffRows.map(o=>[o.path,o.status])),r=Bu(t.fileRows,e.collapsedFileTreePaths),s=e.selectedFileTreePath??t.selectedFilePath;return r.map(o=>{let i=o.kind==="file"?n.get(o.path):void 0,c=i==="A"?"9ece6a":i==="M"?"e0af68":i==="D"?"f7768e":i==="??"?"565f89":void 0,l=o.kind==="directory"?e.collapsedFileTreePaths.includes(o.path)?Uo:qo:Bo(o.label),d=o.kind==="directory"?"7aa2f7":Ho(o.label),f=" ".repeat(o.depth),h=d?{text:l,style:{fg:d}}:{text:l},R=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:c?{text:o.label,style:{fg:c}}:{text:o.label},k=[{text:f},h,R];return{id:o.path,text:`${f}${l}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:k}})}function Bu(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function Uu(e,t){if(!t)return[{id:"empty",text:"No task diff index.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.diffRows.length===0)return[{id:"empty",text:t.filePaths.some(s=>s.startsWith("repo_"))?"No changes in project task worktrees. Edits in the original repos are outside this task.":"No local changes.",muted:!0}];if(qu(t))return Ku(e,t);let n=[];for(let r of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===r);s.length!==0&&(n.push({id:r,text:r.toUpperCase(),muted:!0}),n.push(...s.map(o=>Ei(o,e,t))))}return n}function qu(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Ku(e,t){let n=[],r=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of r){let o=t.diffRows.filter(c=>c.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;n.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let c of["branch","staged","unstaged","untracked"]){let l=o.filter(d=>d.group===c);l.length!==0&&(n.push({id:`repo-diff:${s}:${c}`,text:` ${c}`,muted:!0}),n.push(...l.map(d=>Ei(d,e,t,s.length+1))))}}return n}function Ei(e,t,n,r=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",c=r>0?e.path.slice(r):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${c} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??n.selectedDiffPath),focused:e.path===(t.selectedDiffPath??n.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function Vu(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:se(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Ct.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function Gu(e){return e.reduce((t,n)=>(t[n.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Hu(e,t){return{name:se(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var on={width:120,height:36},he={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function je(e,t){return{width:Math.max(e??on.width,on.width),height:Math.max(t??on.height,on.height)}}import{spawn as wf}from"node:child_process";import{createHash as kf}from"node:crypto";import{createServer as Rf,createConnection as Ni}from"node:net";import{openSync as Tf}from"node:fs";import{mkdir as yf,readFile as vr,rm as Je,writeFile as Pf}from"node:fs/promises";import{tmpdir as bf}from"node:os";import it from"node:path";import{createRequire as rf}from"node:module";import zu from"@xterm/headless";var Yu=1e3,Ju=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function $i(e){return new zu.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:Yu,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function Di(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function br(e,t){return new Promise(n=>{e.write(t,n)})}function Mi(e,t=0){let n=e.buffer.active,r=[],s=n.getNullCell(),o=n.baseY+n.cursorY,i=Math.max(0,n.baseY-t);for(let c=0;c<e.rows;c+=1){let l=n.getLine(i+c);if(!l){r.push({segments:[]});continue}let d=[];for(let f=0;f<e.cols;f+=1){let h=l.getCell(f,s);!h||h.getWidth()===0||d.push({text:h.getChars()||" ",style:Zu(h,i+c===o&&f===n.cursorX)})}r.push({segments:Qu(Xu(d))})}return r}function Qu(e){let t=[];for(let n of e){let r=t.at(-1);if(r&&nf(r.style,n.style)){r.text+=n.text;continue}let s={text:n.text};Li(n.style)||(s.style=n.style),t.push(s)}return t}function Xu(e){let t=e.length;for(;t>0;){let n=e[t-1];if(!n||n.text!==" "||!Li(n.style))break;t-=1}return e.slice(0,t)}function Zu(e,t){let n={},r=Ai(e,"fg"),s=Ai(e,"bg");return r&&(n.fg=r),s&&(n.bg=s),e.isBold()&&(n.bold=!0),e.isDim()&&(n.dim=!0),e.isItalic()&&(n.italic=!0),e.isUnderline()&&(n.underline=!0),(e.isInverse()||t)&&(n.inverse=!0),n}function Ai(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let r=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return r?s.toString(16).padStart(6,"0"):Ju[s]??ef(s)}function ef(e){if(e>=16&&e<=231){let t=e-16,n=Math.floor(t/36),r=Math.floor(t%36/6),s=t%6;return[n,r,s].map(tf).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(n=>n.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function tf(e){return e===0?0:55+e*40}function nf(e,t){return Pr(e)===Pr(t)}function Pr(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Li(e){return Pr(e)===""}var sf=rf(import.meta.url),of=/^CTRL_([A-Z])$/,af="\x1B[6n",cf="\x1B[c",lf="\x1B[?u",df={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
|
|
143
|
-
`,TAB:" ",SHIFT_TAB:"\x1B[Z",BACK_TAB:"\x1B[Z",BACKSPACE:"\x7F",DELETE:"\x1B[3~",ESCAPE:"\x1B",UP:"\x1B[A",DOWN:"\x1B[B",RIGHT:"\x1B[C",LEFT:"\x1B[D",HOME:"\x1B[H",END:"\x1B[F",PAGE_UP:"\x1B[5~",PAGE_DOWN:"\x1B[6~",CTRL_C:"",CTRL_D:""},
|
|
144
|
-
[process exited ${k.exitCode}]`).then(()=>{this.onUpdate?.(R.tabId)})})),R}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function
|
|
139
|
+
`);return i.length>yd?J(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?J(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 Fo(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 ve(e,t){return e&&t.includes(e)?e:t[0]??null}function Cd(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function No(e){return[...new Set(e.split(`
|
|
141
|
+
`).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,n)=>t.localeCompare(n))}function xd(e,t){let n=nr.resolve(e,t),r=nr.resolve(e);if(n!==r&&!n.startsWith(`${r}${nr.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return n}function vd(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function J(e,t,n,r=null,s=null){return{path:r,status:n,title:e,lines:[t],byteLength:s}}import{access as Ed}from"node:fs/promises";async function Wo(e,t){let n=await L(e,t),r=await Ad(n.worktreePath),s={...n,status:"closed",cleanup:{...n.cleanup,preservedWorktree:r&&n.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await A(e,s),s}async function Ad(e){try{return await Ed(e),!0}catch{return!1}}import dt from"node:path";function _o(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 Bo="\u{F024B} ",Uo="\u{F0DCF} ",qo="\u25CB",sr="\uEA64",Ko="\uEAFE",Vo="\uEBDA",or="\u25CB",ir="\u25CF",ar="\u2713",cr="\u2715";function Go(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"4fc1ff";case"js":case"jsx":case"mjs":case"cjs":return"f7df1e";case"json":case"jsonc":return"fbc02d";case"md":case"mdx":return"519aba";case"yaml":case"yml":return"e06c75";case"sh":case"bash":case"zsh":return"89e051";case"css":case"scss":case"sass":return"c792ea";case"html":case"htm":return"e06c75";case"py":return"3572a5";case"go":return"00add8";case"rs":return"dea584";case"lock":return"565f89";default:return}}var $d=["tasks","center","inspector","actions"],Xo=["agent","terminal"],Zo=[],$="inspection",cR=[...Xo,...Zo],ei=["commit","push","refresh-checks","close-task"],Dd=["refresh-checks","close-task"],ti=["task","checks","pr","setup-run","actions","next-action"],ni=["diff","files","review"];function ri(e,t={}){let n=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,r=zd(e?.openInspectionKind)??n,s=b.runners.getEnabled(t);return{inputMode:Jd(e?.inputMode),focusedRegion:Gd(e?.focusedRegion),selectedRepoId:Te(e?.selectedRepoId),selectedWorkspaceId:Te(e?.selectedWorkspaceId),selectedTaskId:Te(e?.selectedTaskId),selectedPtyTabId:Te(e?.selectedPtyTabId),selectedLeftItemId:ou(Te(e?.selectedTaskId)),activeTab:n?$:Te(e?.activeTab)??"agent",preferredPtyTabKind:Yd(e?.preferredPtyTabKind),inspectorSection:ct(e?.inspectorSection,ti,"task"),inspectionMode:Hd(e?.inspectionMode,n==="diff"?"diff":"files"),openInspectionKind:r,selectedFileTreePath:Te(e?.selectedFileTreePath),selectedFilePath:Te(e?.selectedFilePath),selectedDiffPath:Te(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:ct(e?.selectedActionId,ei,"commit"),selectedProjectTargetId:null,selectedRunner:Qd(e?.selectedRunner,s,b.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:Md(),centerZoomed:!1}}function Md(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function si(e,t){return{...e??ge(),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 Bt(e,t,n={}){let r=ru(e,t),s=pi(r),o=(s?.kind==="workspace"?t.workspaces?.find(p=>p.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(p=>p.id===t.tasks.find(h=>h.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(p=>p.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,c=((s?.kind==="repo"?t.repos.find(p=>p.id===s.id)??null:s?.kind==="task"?t.repos.find(p=>p.id===t.tasks.find(h=>h.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(p=>p.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(p.id))??null:null)??(o?.kind!=="project"?t.repos.find(p=>p.id===o?.primaryRepoId)??null:null)??t.repos.find(p=>p.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(p=>p.workspaceId===o.id):c?t.tasks.filter(p=>p.repoId===c):[],d=(s?.kind==="task"?l.find(p=>p.id===s.id)??null:null)??l.find(p=>p.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,...Zd(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:qd(e,t,d?.id??null),...eu(e,t,d?.id??null),selectedDiffPath:Ud(e,t,d?.id??null),inspectorSection:ct(e.inspectorSection,ti,"task")}}function oi(e,t,n={leftItemIds:[]}){if(e.inputMode==="terminal")return Ld(t)?S({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):S({state:e});if(t==="q"||t==="Q")return S({state:e,exit:!0});if(t==="ESCAPE")return S({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return S({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(dr(e.selectedLeftItemId)||ur(e.selectedLeftItemId)))return S({state:{...e,selectedRunner:pr(e.selectedRunner,n.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return Ho(e,1);if(t==="SHIFT_TAB"||t==="[")return Ho(e,-1);if(t==="z"||t==="Z")return S({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===$?Ee(e,-1,n):zo(e,-1,n);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===$?Ee(e,1,n):zo(e,1,n);if(t==="PAGE_UP")return Ee(e,-(n.pageRows??10),n);if(t==="PAGE_DOWN")return Ee(e,n.pageRows??10,n);if(t==="MOUSE_WHEEL_UP")return Ee(e,-3,n);if(t==="MOUSE_WHEEL_DOWN")return Ee(e,3,n);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let r=n.enabledRunnerIds??j,s=e.centerTabRunner?r.indexOf(e.centerTabRunner):-1,o=s===r.length-1?null:r[s+1];return S({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=Xd(e,t);return S({state:{...e,preferredPtyTabKind:r,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:r,createPtyTabRunner:r==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return S({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return S({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return S({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&_t(e.selectedLeftItemId)&&e.selectedTaskId)return S({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&iu(e.selectedLeftItemId)&&e.selectedWorkspaceId)return S({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Qo(e.activeTab,n.ptyTabIds??[]))return S({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return lr(e,-1,n.centerTabIds);if(e.focusedRegion==="inspector")return Yo(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return lr(e,1,n.centerTabIds);if(e.focusedRegion==="inspector")return Yo(e,1)}if(Pe(t)){if(e.focusedRegion==="tasks"&&(dr(e.selectedLeftItemId)||ur(e.selectedLeftItemId))){let r=fi(e.selectedLeftItemId),s=mi(e.selectedLeftItemId);return S({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 S({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&_t(e.selectedLeftItemId)&&e.selectedTaskId){let r=e.selectedPtyTabId??e.activeTab;return S({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:r,selectedPtyTabId:r,preferredPtyTabKind:lt(r)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Qo(e.activeTab,n.ptyTabIds??[])&&e.selectedTaskId)return S({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:lt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===$)return S({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 S({state:Wd({...e,selectedFileTreePath:r}),changed:!0});let s=r&&(n.fileTreeFileIds??[]).includes(r)?r:e.selectedFilePath;return S({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:$,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?S({state:{...e,activeTab:$,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!n.projectTargetIds?.length?S({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):S({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?S({state:e}):e.selectedActionId==="refresh-checks"?S({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?S({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):S({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return S({state:e})}function _e(e,t){return{...e,terminal:t}}function ii(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Ld(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Pe(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
142
|
+
`}function ai(e){return e.length===1&&e>=" "&&e!=="\x7F"}function ci(e){return li(e)||lt(e)!==null}function jd(e){return Zo.includes(e)}function li(e){return Xo.includes(e)}function di(e,t){return[...e?.ptyTabs.map(n=>n.id)??[],...t?.openInspectionKind?[$]:[]]}var Od=["tasks","center","inspector"];function Ho(e,t){return Nt(e,"focusedRegion",Od,t)}function lr(e,t,n){let r=Nt(e,"activeTab",n&&n.length>0?n:nu(e),t);return!r.changed||jd(r.state.activeTab)?r:{...r,state:{...r.state,selectedPtyTabId:r.state.activeTab,preferredPtyTabKind:lt(r.state.activeTab)??r.state.preferredPtyTabKind}}}function zo(e,t,n){if(e.focusedRegion==="tasks")return Fd(e,t,n.leftItemIds);if(e.focusedRegion==="center")return lr(e,t,n.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return ui(e,t,n);if(e.inspectionMode==="diff"){let r=Wt(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,activeTab:$,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:r}if(n.projectTargetIds?.length){let r=Wt(e,"selectedProjectTargetId",n.projectTargetIds,t);return r.changed?{...r,state:{...r.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:r}return Nt(e,"selectedActionId",Dd,t)}return Nt(e,"selectedActionId",ei,t)}function Fd(e,t,n){let r=Wt(e,"selectedLeftItemId",n,t);if(!r.changed)return r;let s=pi(r.state.selectedLeftItemId);if(s?.kind==="workspace")return{...r,state:{...r.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...r,state:{...r.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...r,state:{...r.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=fi(r.state.selectedLeftItemId);if(o)return{...r,state:{...r.state,selectedRepoId:o}};let i=mi(r.state.selectedLeftItemId);return i?{...r,state:{...r.state,selectedWorkspaceId:i}}:r}function Ee(e,t,n){if(t===0)return S({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return ui(e,t,n);if(e.inspectionMode==="diff"){let r=Wt(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,diffScrollOffset:0}}:r}return e.inspectionMode==="review"?Jo(e,"reviewScrollOffset",t,n.reviewRowCount??100,n.pageRows):S({state:e})}if(e.focusedRegion==="center"&&e.activeTab===$){if(e.openInspectionKind==="file")return Jo(e,"fileScrollOffset",t,n.fileLineCount??0,n.pageRows);if(e.openInspectionKind==="diff")return _d(e,t,n)}return S({state:e})}function Nd(e,t){if(e.inspectionMode===t)return S({state:e});let n=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,r=t==="diff"||t==="files"?$:e.activeTab;return S({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 Yo(e,t){return Nd(e,Vd(e.inspectionMode,ni,t))}function ui(e,t,n){let r=n.fileTreeRowIds&&n.fileTreeRowIds.length>0?n.fileTreeRowIds:n.filePathIds??[];if(r.length===0)return S({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??r[0]??null,o=r.indexOf(s??""),i=ye(o===-1?0:o+t,0,r.length-1),c=r[i]??null;if(c===e.selectedFileTreePath)return S({state:e});let l=c!==null&&(n.fileTreeFileIds??n.filePathIds??[]).includes(c);return S({state:{...e,selectedFileTreePath:c,selectedFilePath:l?c:e.selectedFilePath,activeTab:l?$:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function Wd(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 Jo(e,t,n,r,s=10){let o=Math.max(0,r-Math.max(1,s)),i=ye(e[t]+n,0,o);return i===e[t]?S({state:e}):S({state:{...e,[t]:i,actionMessage:null},changed:!0})}function _d(e,t,n){if(n.diffPathRanges&&n.diffPathRanges.length>0)return Bd(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 p=ye(i,0,o);return p===e.diffScrollOffset?S({state:e}):S({state:{...e,diffScrollOffset:p,actionMessage:null},changed:!0})}let l=c.indexOf(e.selectedDiffPath);if(l===-1){let p=ye(i,0,o);return p===e.diffScrollOffset?S({state:e}):S({state:{...e,diffScrollOffset:p,actionMessage:null},changed:!0})}if(t>0&&i>o){let p=c[l+1]??null;return p?S({state:{...e,selectedDiffPath:p,activeTab:$,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?S({state:e}):S({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let p=c[l-1]??null;return p?S({state:{...e,selectedDiffPath:p,activeTab:$,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?S({state:e}):S({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=ye(i,0,o);return d===e.diffScrollOffset?S({state:e}):S({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function Bd(e,t,n){let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=ye(e.diffScrollOffset+t,0,o),c=Kd(n.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&c===e.selectedDiffPath?S({state:e}):S({state:{...e,diffScrollOffset:i,selectedDiffPath:c,actionMessage:null},changed:!0})}function Ud(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 Kd(e,t){return e.find(n=>t>=n.start&&t<n.end)?.path??e.at(-1)?.path??null}function Nt(e,t,n,r){let s=n.indexOf(e[t]),o=ye(s+r,0,n.length-1),i=n[o];return!i||i===e[t]?S({state:e}):S({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Wt(e,t,n,r,s=!1){if(n.length===0)return S({state:e});let o=n.indexOf(e[t]??n[0]??""),i=ye(o===-1?0:o+r,0,n.length-1),c=n[i]??null;return c===e[t]?S({state:e}):S({state:{...e,[t]:c,actionMessage:null},changed:!0,refreshInspection:s})}function Vd(e,t,n){let r=t.indexOf(e);return t[ye(r+n,0,t.length-1)]??e}function S(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function ct(e,t,n){return t.includes(e??"")?e:n}function Gd(e){return e==="tabs"?"center":ct(e,$d,"tasks")}function Hd(e,t){return e==="checks"||e==="actions"||e==="review"?"review":ct(e,ni,t)}function zd(e){return e==="file"||e==="diff"?e:null}function Yd(e){return e==="terminal"?"terminal":"agent"}function Jd(e){return e==="terminal"?"terminal":"control"}function Qd(e,t=[...j],n="codex"){return e&&b.runners.isRunnerType(e)&&t.includes(e)?e:n}function pr(e,t=j){let n=t.length>0?t:j,r=n.indexOf(e);return n[(r+1)%n.length]??n[0]??"codex"}function lt(e){let t=j.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Xd(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":lt(e.activeTab)??e.preferredPtyTabKind}function Zd(e,t,n){if(!e)return{activeTab:t===$?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(li(t)){let l=e.ptyTabs.find(d=>d.kind===t)??null??s??r??e.ptyTabs[0]??null;return{activeTab:l?.id??$,selectedPtyTabId:l?.id??null}}if(t===$)return{activeTab:$,selectedPtyTabId:r?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??r??e.ptyTabs[0]??null;return{activeTab:i?.id??$,selectedPtyTabId:i?.id??null}}function eu(e,t,n){if(!t.inspection||t.inspection.taskId!==n)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let r=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?tu(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:r,collapsedFileTreePaths:s}}function tu(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 nu(e){return[e.selectedPtyTabId,e.openInspectionKind?$:null].filter(t=>typeof t=="string")}function Qo(e,t){return t.includes(e)}function ru(e,t){let n=su(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 su(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function pi(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function Te(e){return typeof e=="string"?e:null}function ou(e){return e?`task:${e}`:null}function _t(e){return typeof e=="string"&&e.startsWith("task:")}function dr(e){return typeof e=="string"&&e.startsWith("new-task:")}function ur(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function iu(e){return typeof e=="string"&&e.startsWith("workspace:")}function fi(e){return dr(e)?e.slice(9):null}function mi(e){return ur(e)?e.slice(19):null}function ye(e,t,n){return Math.min(n,Math.max(t,e))}var qt="empty",U={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function ki(e,t){let n=lu(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=Vu(t.tasks),d=pu(e,i),p=uu(e,i,d),h=p.find(T=>T.id===d)??p[0]??{id:"agent",label:"CODEX"},R=t.inspection?.taskId===i?.id?t.inspection:null,k=r?.name??"no repo",I=i?b.runners.getDisplayName(i.runner):b.runners.getDisplayName(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${r?`[${r.name}]`:"[no repo]"} \xB7 ${b.runners.getDisplayName(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${b.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:_t(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===$?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${b.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?c?"\u2191\u2193 targets Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?"\u2191\u2193 navigate Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:dt.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${dt.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:I},leftTree:au(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>Gu(T,l[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":h.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:k,agent:I},centerTranscript:du(d,e,r,i,e.workspaceBrowser,R,n),tabs:p,rightContext:Ku(r,i),rightInspection:Iu(e,i,R)}}function au(e,t){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return cu(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 p=e.selectedLeftItemId===`task:${d.id}`,h=p?"\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:p,focused:p&&e.focusedRegion==="tasks"},I=Ti(d);I&&(k.prBadge=I),n.push(k)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,p=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:p,focused:p&&e.focusedRegion==="tasks",muted:!p})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,p=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:p,focused:p&&e.focusedRegion==="tasks",muted:!p})}else{n.push({text:` Repos (${c.length})`,indent:0,muted:!0});for(let d of c.slice(0,6)){let p=t.repos.find(h=>h.id===d);n.push({text:` \xB7 ${p?.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 cu(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(p=>p.repoId===o.id);if(c.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let p of c){let h=t.selectedLeftItemId===`task:${p.id}`,R=h?"\u25B8":"\u2022",k=p.title.length>28?`${p.title.slice(0,25)}\u2026`:p.title,I={id:`task:${p.id}`,taskId:p.id,text:`${R} ${k}`,indent:2,selected:h,focused:h&&t.focusedRegion==="tasks"},T=Ti(p);T&&(I.prBadge=T),e.push(I)}let l=`new-task:${o.id}`,d=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${b.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let s=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&t.focusedRegion==="tasks"}),e}function lu(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 du(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,p)=>{let h=p===s.selectedIndex?"\u25B8":" ",R=d.kind==="repo"?" [git repo]":"/";return`${h} ${d.name}${R}`});return ue(["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 ue(["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,p=l?"Project Task":"Task";return ue([`No tasks in ${d}.`,"",`Press n or choose + New ${p} to create one with ${b.runners.getDisplayName(t.selectedRunner)}.`])}let c=r.ptyTabs.find(l=>l.id===e)??null;return c?c.kind==="agent"?ue([`${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."]):ue([`${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===$&&t.openInspectionKind==="file"?gu(r,o,t.fileScrollOffset):e===$&&t.openInspectionKind==="diff"?hu(r,o,t.diffScrollOffset):r.ptyTabs.length===0&&!t.openInspectionKind?ue(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ue(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function uu(e,t,n){let r=t?.ptyTabs.map(o=>({id:o.id,label:fu(o)}))??[];if(!t)return[{id:qt,label:"EMPTY",active:n===qt,focused:e.focusedRegion==="center"&&n===qt}];let s=e.openInspectionKind||n===$?[{id:$,label:mu(e)}]:[];return[...r,...s].map(o=>({...o,active:o.id===n,focused:e.focusedRegion==="center"&&o.id===n}))}function pu(e,t){return t?t.ptyTabs.some(n=>n.id===e.activeTab)||e.activeTab===$&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(n=>n.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??$:e.selectedPtyTabId&&t.ptyTabs.some(n=>n.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??$:qt}function fu(e){return e.title.toUpperCase()}function mu(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,n=t?dt.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${n} \u0394`:n}function gu(e,t,n){if(!e)return ue(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ue(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let r=t.selectedFile,s=Ri(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:""},...wu(r.lines,n,s)]}function hu(e,t,n){if(!e)return ue(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ue(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let r=t.selectedDiff,s=Ri(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:""},...ku(r.lines,n,s)]}function ue(e){return e.map(t=>({text:t}))}function wu(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:U.lineNumber}},{text:" \u2502 ",style:{fg:U.gutter}},...fr(o,n)],tone:"default"}})}function ku(e,t,n){let r=Ru(e),s=Math.max(0,Math.min(t,Math.max(0,r.length-1)));return r.slice(s).map(o=>Tu(o,n))}function Ru(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 Tu(e,t){let n=gi(e.oldNumber),r=gi(e.newNumber),s=e.kind==="delete"?n:r,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:U.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:U.diffAdd}:null,i=`${s} \u2502 ${e.text}`,c=o?Pu(fr(e.text,t),o.bg,o.fallbackFg):fr(e.text,t),l=o?{fg:U.lineNumber,bg:o.bg}:{fg:U.lineNumber},d=o?{fg:U.gutter,bg:o.bg}:{fg:U.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...c],fullBleed:o!==null}}function gi(e){return e===null?" ":String(e).padStart(4," ")}function Ri(e){let t=dt.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 fr(e,t){return t==="diff"?yu(e):t==="markdown"?bu(e):t==="json"?mr(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?mr(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 yu(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:U.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:U.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:U.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:U.diffMeta}}]:[{text:e}]}function Pu(e,t,n){return e.map(r=>({text:r.text,style:{...r.style??{fg:n},bg:t}}))}function bu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:U.markup,bold:!0}}]:mr(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function mr(e,t){let n=[],r=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>r&&n.push({text:e.slice(r,i)}),n.push({text:o,style:Su(o)}),r=i+o.length}return r<e.length&&n.push({text:e.slice(r)}),n.length>0?n:[{text:e}]}function Su(e){return e.startsWith("//")||e.startsWith("/*")?{fg:U.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:U.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:U.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:U.markup}:{fg:U.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"?yi(t.repoTargets??[]):s?.pullRequest??(t?V(t):null),i=[Cu(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Si(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,...Wu(e,n)]}:{title:"",rows:[...i,...Bu(e,n)]}}function Cu(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 p=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:p}})}let o=gr(t),i=hr(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function hi(e){return[{text:" "},gr(e),{text:" "},hr(e)]}function Ti(e){if(e.type==="project"&&e.repoTargets?.length){let n=yi(e.repoTargets);return n?hi(n):null}let t=V(e);return t?.number?hi(t):null}function yi(e){let t=e.filter(s=>s.status==="ready"),n=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(n.length===0)return null;let r=vu(n);return{number:-1,status:xu(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 xu(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 vu(e){let t=e.map(n=>Pi(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 gr(e){return!e||!e.number?{text:qo,style:{fg:"565f89"}}:e.status==="merged"?{text:Ko,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Vo,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:sr,style:{fg:"565f89"}}:{text:sr,style:{fg:"9ece6a"}}}function hr(e){return e?.aggregateReadiness?wi(e.aggregateReadiness):wi(Pi(e))}function wi(e){return e==="failed"?{text:cr,style:{fg:"f7768e"}}:e==="pending"?{text:ir,style:{fg:"e0af68"}}:e==="success"?{text:ar,style:{fg:"9ece6a"}}:{text:or,style:{fg:"565f89"}}}function Pi(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")?bi(e)?"failed":Eu(e)?"success":"pending":"pending"}function Eu(e){return!!(e.mergeable&&!e.draft&&!bi(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function bi(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Si(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return Au(e,t);let n=V(t),r=Ci("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}),$u(r,e)}var Ut=32;function Au(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=Ut-h.length-1,k=d.length>R?d.slice(0,R-1)+"\u2026":d,I=Ut-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 p=gr(i.pullRequest),h=hr(i.pullRequest),R=`${p.text} ${h.text}`,k=Ut-R.length-1,I=d.length>k?d.slice(0,k-1)+"\u2026":d,T=Ut-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},{...p,text:p.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(...Ci("target",o.branch,o.pullRequest))),n}function Ii(e,t){return Si(e,t).length}function Ci(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=Du(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:Mu(n.reviewDecision,n.mergeStateStatus)}}]}):s.push({id:r("pr-merge"),text:d,muted:!0}),s.push({id:r("pr-synced"),text:`synced ${xi(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(Lu)):s.push({id:r("checks-none"),text:n.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let p=n.comments??[];return p.length>0&&(s.push({id:r("comments-spacer"),text:""}),s.push({id:r("comments-header"),text:`Review comments (${p.length})`}),s.push(...p.slice(-4).flatMap((h,R)=>ju(h,r(`comment:${R}`))))),s}function $u(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 Du(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Mu(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function xi(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 Lu(e){let{icon:t,color:n}=Fu(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," ")} ${Nu(e.status)}`,color:n,muted:!1}}function ju(e,t){let n=e.author??"unknown",r=e.createdAt?` \xB7 ${xi(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 Fu(e){switch(e){case"success":return{icon:ar,color:"9ece6a"};case"pending":return{icon:ir,color:"e0af68"};case"failed":return{icon:cr,color:"f7768e"};case"skipped":return{icon:or,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function Nu(e){return e==="success"?"passing":e==="failed"?"failing":e}function Wu(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=_u(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)?Bo:Uo:_o(o.label),d=o.kind==="directory"?"7aa2f7":Go(o.label),p=" ".repeat(o.depth),h=d?{text:l,style:{fg:d}}:{text:l},R=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:c?{text:o.label,style:{fg:c}}:{text:o.label},k=[{text:p},h,R];return{id:o.path,text:`${p}${l}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:k}})}function _u(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 Bu(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(Uu(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=>vi(o,e,t))))}return n}function Uu(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=>vi(d,e,t,s.length+1))))}}return n}function vi(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 Ku(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:b.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:dt.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 Vu(e){return e.reduce((t,n)=>(t[n.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Gu(e,t){return{name:b.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var Kt={width:120,height:36},pe={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function Ae(e,t){return{width:Math.max(e??Kt.width,Kt.width),height:Math.max(t??Kt.height,Kt.height)}}import{spawn as gp}from"node:child_process";import{createHash as hp}from"node:crypto";import{createServer as wp,createConnection as Fi}from"node:net";import{openSync as kp}from"node:fs";import{mkdir as Rp,readFile as br,rm as Be,writeFile as Tp}from"node:fs/promises";import{tmpdir as yp}from"node:os";import Ye from"node:path";import{createRequire as np}from"node:module";import Hu from"@xterm/headless";var zu=1e3,Yu=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function Ai(e){return new Hu.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:zu,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function $i(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function kr(e,t){return new Promise(n=>{e.write(t,n)})}function Di(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 p=0;p<e.cols;p+=1){let h=l.getCell(p,s);!h||h.getWidth()===0||d.push({text:h.getChars()||" ",style:Xu(h,i+c===o&&p===n.cursorX)})}r.push({segments:Ju(Qu(d))})}return r}function Ju(e){let t=[];for(let n of e){let r=t.at(-1);if(r&&tp(r.style,n.style)){r.text+=n.text;continue}let s={text:n.text};Mi(n.style)||(s.style=n.style),t.push(s)}return t}function Qu(e){let t=e.length;for(;t>0;){let n=e[t-1];if(!n||n.text!==" "||!Mi(n.style))break;t-=1}return e.slice(0,t)}function Xu(e,t){let n={},r=Ei(e,"fg"),s=Ei(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 Ei(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"):Yu[s]??Zu(s)}function Zu(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(ep).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 ep(e){return e===0?0:55+e*40}function tp(e,t){return wr(e)===wr(t)}function wr(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function Mi(e){return wr(e)===""}var rp=np(import.meta.url),sp=/^CTRL_([A-Z])$/,op="\x1B[6n",ip="\x1B[c",ap="\x1B[?u",cp={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:""},Vt=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")Rr(o),this.sessions.delete(n);else return this.attachedTabId=n,o.scrollbackLines=0,Li(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=lp(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&&Li(n,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let n=this.sessions.get(t);n&&(Rr(n),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Rr(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:Di(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??up().spawn,i=Ai(r),c=s??this.resolveSessionSpec(t,n),l=Le({...this.env,...c.env??{}}),{executable:d,args:p}=pp(this.shell,c.command,{cwd:c.cwd,env:l}),h=o(d,p,{name:"xterm-256color",cols:r.columns,rows:r.rows,cwd:c.cwd,env:fp(l)}),R={taskId:t,tabId:n,pty:h,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0};return R.disposables.push(h.onData(k=>{mp(h,k),kr(R.terminal,k).then(()=>{this.onUpdate?.(R.tabId)})})),R.disposables.push(h.onExit(k=>{R.status="exited",kr(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 lp(e){if(e.length===1)return e;let t=cp[e];if(t!==void 0)return t;let n=sp.exec(e);return n?.[1]?String.fromCharCode(n[1].charCodeAt(0)-64):null}function Li(e,t){dp(e.pty,t),$i(e.terminal,t)}function Rr(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function dp(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function up(){return rp("node-pty")}function pp(e,t,n){if(t.length===0)return{executable:e,args:[]};let s=`${[je(t[0],n),...t.slice(1)].map(ji).join(" ")}; exec ${ji(e)} -l`;return{executable:e,args:["-lc",s]}}function ji(e){return`'${e.replaceAll("'","'\\''")}'`}function fp(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 mp(e,t){for(let n=0;n<Tr(t,op);n+=1)e.write("\x1B[1;1R");for(let n=0;n<Tr(t,ip);n+=1)e.write("\x1B[?1;2c");for(let n=0;n<Tr(t,ap);n+=1)e.write("\x1B[?0u")}function Tr(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 Sr=3;async function Ni(e){let t=Ir(e.paths);await Pp(t,e.paths,e.spawnDaemon);let n=await Ki(t.socketPath),r=new yr(n,e);return await r.ready(),r}async function Wi(e,t={}){let n=Ir(e);await Rp(e.runtimeDir,{recursive:!0}),await Be(n.socketPath,{force:!0});let r=new Pr(e,t),s=wp(o=>r.handleConnection(o));await vp(s,n.socketPath),await Tp(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 Be(n.socketPath,{force:!0}),await Be(n.pidPath,{force:!0}),r.disposeAll()}async function _i(e){let t=Ir(e);return await Ht(t.socketPath)?(await Ui(t.socketPath),!0):!1}var yr=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!==Sr)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()}},
|
|
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()}},Pr=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,n){this.runtime=new Vt({...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{
|
|
150
|
-
${o.slice(-2e3)}`:""}`)}async function
|
|
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{Gt(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(r);Gt(t,{id:r.id,ok:!0,...r.type==="ping"?{protocolVersion:Sr}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);Gt(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 Ep(t)}}broadcastUpdate(t){let n=this.runtime.getViewState(t);for(let r of this.clients)Gt(r,{type:"update",tabId:t,view:n})}};function Ir(e){let t=hp("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:Ye.join(yp(),`craig-${t}.sock`),pidPath:Ye.join(e.runtimeDir,"pty-daemon.pid")}}async function Pp(e,t,n){if(await bp(e.socketPath,1e3))return;await Ht(e.socketPath)&&(await Ui(e.socketPath),await Oi(e.socketPath,1e3)),await Ht(e.socketPath)&&(await Cp(e),await Oi(e.socketPath,1e3)),await Ip(e);let r=t.workspaceRoot;if(n)n(r);else{let{command:i,args:c}=Sp(r),l=kp(Ye.join(t.runtimeDir,"pty-daemon.log"),"a");gp(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 Bi(e.socketPath))return;await Cr(50)}let o=await br(Ye.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
|
|
150
|
+
${o.slice(-2e3)}`:""}`)}async function Bi(e){let t=await xp(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===Sr}async function bp(e,t){let n=Date.now();for(;Date.now()-n<t;){if(await Bi(e))return!0;await Cr(50)}return!1}function Sp(e){let t=process.argv[1];if(t?.endsWith(".ts")){let r=Ye.resolve(Ye.dirname(t),"..","node_modules",".bin","tsx");return{command:Sn("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 Ip(e){let t=await br(e.pidPath,"utf8").catch(()=>null);if(t){let n=Number(t.trim());if(Number.isInteger(n)&&n>0&&Vi(n))return}await Be(e.socketPath,{force:!0}),await Be(e.pidPath,{force:!0})}async function Ht(e){let t=await Ki(e).catch(()=>null);return t?(t.end(),!0):!1}async function Ui(e){await qi(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Cp(e){let t=await br(e.pidPath,"utf8").catch(()=>null),n=Number(t?.trim());if(!Number.isInteger(n)||n<=0||!Vi(n)){await Be(e.socketPath,{force:!0});return}try{process.kill(n,"SIGTERM")}catch{await Be(e.socketPath,{force:!0})}}async function xp(e){return qi(e,{id:1,type:"ping"})}function qi(e,t){return new Promise((n,r)=>{let s=Fi(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
|
|
153
|
-
`)}catch{}}function
|
|
154
|
-
`)}function
|
|
155
|
-
`)}function
|
|
156
|
-
`)}function
|
|
157
|
-
`)}function Bf(e,t,n,r){let s=Hf(e.runners),o=1,i=e.leftTree.map(l=>Gf(l,t,r));return[...xt(i,n-o),s]}function Uf(e,t,n,r){let s=t-2,o=e.tabs.find(C=>C.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:ip(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?at(l,r,v.panelBg):gn(l,r,v.panelMuted)}`,f=[`${gn(e.centerHeader.tabLabel,r,v.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(C=>C.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!li(h)?e.centerTranscript.map(C=>({...C})):qf(e),k=zf(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?at(`${I}\u25CF `,r,v.panelBg):"",V=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-Q(k)-T)):"",te=[{text:e.inputMode==="terminal"?`${k}${V}${a}`:k},{text:d,tone:"muted"},{text:f},ee(),...R];return xt(te,n)}function qf(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},ee(),{text:e.terminal.error},ee(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(r=>r.active)?.id??"",n=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${n.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(r=>({text:oa(r.segments),segments:r.segments,fullBleed:!0}))}function Kf(e,t,n,r){let s=e.rightInspection?Vf(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,n):xt([{text:"CONTEXT"},ee(),...e.rightContext.map(o=>Yf(o,r)),...e.actionMessage?[ee(),{text:e.actionMessage}]:[]],n);return xt(s,n)}function Vf(e,t){let n=e.slice(0,2),r=e.slice(2),s=Math.max(0,t-n.length),o=r.findIndex(c=>c.focused||c.selected),i=o===-1?0:cp(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Hi(c)),...r.slice(i,i+s).map(c=>Hi(c))]}function Hi(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",n=e.focused||e.selected?"selected":e.muted?"muted":"default",r=`${t}${e.text}`;if(e.segments)return{text:r,segments:[{text:t},...e.segments],tone:n};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:r,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:n}}return e.color?{text:r,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:n}:{text:r,tone:n}}function Gf(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${at("\u25CF",n,e.selected?v.panelSelected:v.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+Q(I.text),0):0,l=t-Q(o)-Q(s)-c,d=e.selected?e.text:e.focused?at(e.text,n,v.panelBg):e.panelHeader?gn(e.text,n,v.panelMuted):e.text,f=Se(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${f}${o}${i}`},...e.prBadge];return{text:`${f}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${f}${o}${i}`,tone:h}}function Hf(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:v.success.fg}}):n.push({text:s.text,style:{fg:v.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function zf(e,t,n){return e.map(r=>r.active?n?at(r.label,t,v.panelBg):gn(r.label,t,v.panelBg):jr(r.label,t,v.panelBg)).join(" ")}function Yf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?jr(e.value,t,v.panelBg):e.value}`}}function un(e,t,n,r){let s=Jf(r,e.tone??"default"),o=Qf(e,n,s);if(r==="left"){if(e.fullBleed)return O(Se(o,t),n,s);let c=t-fn-pn;if(e.rightAlign){let d=Q(o),f=Math.max(0,c-d),h=`${" ".repeat(fn)}${" ".repeat(f)}${o}${" ".repeat(pn)}`;return O(h,n,s)}let l=`${" ".repeat(fn)}${Se(o,c)}${" ".repeat(pn)}`;return O(l,n,s)}return r==="center"&&e.fullBleed?Xf(e,t,n,s):O(Se(` ${o}`,t),n,s)}function Jf(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function xt(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(ee());return n}function ee(){return{text:""}}function Qf(e,t,n){return e.segments?e.segments.map(r=>ea(r,t,n)).join(""):e.text}function Xf(e,t,n,r){let s=" ".repeat(mn),o=Math.max(0,t-mn*2);if(!e.segments)return O(`${s}${Se(e.text,o)}${s}`,n,r);let i=tp(e.segments,o),c=`${s}${i.map(l=>ea(l,n,r)).join("")}${s}${n?Lr:""}`;return O(c,n,r)}function ea(e,t,n){let r=e.href?`${ta(e.href)}${e.text}${Lr}`:Zf(e.text);return!t||!e.style?r:`${vt(sp(e.style,n))}${op(e.style)}${r}${Mr}${vt(n)}`}function Zf(e){return e.replace(Nf,t=>{let[n,r]=ep(t);return`${ta(n)}${n}${Lr}${r}`})}function ep(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ta(e){return`\x1B]8;;${e}\x1B\\`}function tp(e,t){let n=np(e,t);return rp(n,t)}function np(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=Q(s.text);if(o<=r){n.push(s),r-=o;continue}let i=hn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function rp(e,t){let n=Q(oa(e));if(n>=t)return e;let r=e.at(-1)?.style;return r?.bg?[...e,{text:" ".repeat(t-n),style:r}]:[...e,{text:" ".repeat(t-n)}]}function sp(e,t){let n=e.inverse?e.bg??t.bg:e.fg,r=e.inverse?e.fg??t.fg:e.bg,s={},o=n??t.fg,i=r??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function op(e){let t=[];return e.bold&&t.push("1"),e.dim&&t.push("2"),e.italic&&t.push("3"),e.underline&&t.push("4"),t.length>0?`\x1B[${t.join(";")}m`:""}function ip(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function na(e,t){let n=Math.max(0,t-Q(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Se(e,t){let n=Q(e);return n>=t?ap(e,t):e+" ".repeat(t-n)}function ap(e,t){if(t<=0)return"";if(Q(e)<=t)return e;let n=sa(e);return hn(n,Math.max(0,t-1))+"\u2026"}function Q(e){let t=0;for(let n of Array.from(sa(e)))t+=ra(n);return t}function hn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=ra(s);if(r+o>t)break;n+=s,r+=o}return n}function ra(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function cp(e,t,n){return Math.min(Math.max(e,t),n)}function sa(e){return e.replace(jf,"").replace(Of,"")}function oa(e){return e.map(t=>t.text).join("")}function O(e,t,n){if(!t)return e;let r=vt(n),s=e.replace(Ff,`${Mr}${r}`);return`${r}${s}${Mr}`}function vt(e){let t=[];return e.fg&&t.push(`38;2;${zi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${zi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function zi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function at(e,t,n){return wn(e,t,v.success.fg,n)}function lp(e,t,n){return wn(e,t,v.error.fg,n)}function gn(e,t,n){return wn(e,t,v.accent.fg,n)}function jr(e,t,n){return wn(e,t,v.mutedfg.fg,n)}function wn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${vt(s)}${e}${vt(r)}`}var dp="https://registry.npmjs.org/craig-cli/latest";var kn=null;function Nr(){try{return"0.7.2"}catch{return"unknown"}}async function ia(){let e=Nr(),t=Date.now();if(kn&&t-kn.cachedAt<36e5)return kn.result;let n=null;try{let s=await fetch(dp,{signal:AbortSignal.timeout(5e3)});s.ok&&(n=(await s.json()).version??null)}catch{}let r={current:e,latest:n,updateAvailable:n!==null&&n!==e&&up(n,e)};return kn={result:r,cachedAt:t},r}function up(e,t){let n=d=>d.split(".").map(Number),[r=0,s=0,o=0]=n(e),[i=0,c=0,l=0]=n(t);return r!==i?r>i:s!==c?s>c:o>l}ue();var Wr=["Runners","Error Log","Help"];function _r(e,t){return N.map(n=>{let r=Z(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function ca(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function la(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Wr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Br(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function da(e,t,n,r){if(e.pathEdit)return fp({...e,pathEdit:e.pathEdit},t,n);let s=_r(t,e).length;if(n==="UP"||n==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(n==="DOWN"||n==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(n==="ESCAPE")return{kind:"back",state:e};if(n==="e"){let c=N[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!Br(n))return{kind:"noop",state:e};let o=N[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&r.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:pp(t,o,!i),state:{...e,message:`${Z(o).displayName} ${i?"disabled":"enabled"}.`}}}function fp(e,t,n){if(n==="ESCAPE")return{kind:"render",state:aa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Br(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:mp(t,r,s.length>0?s:null),state:aa({...e,message:s.length>0?`${Z(r).displayName} executable saved.`:`${Z(r).displayName} executable reset to default.`})}}return gp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function pp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function mp(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function aa(e){let t={...e};return delete t.pathEdit,t}function Br(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
158
|
-
`}function gp(e){return e.length===1&&e>=" "&&e!=="\x7F"}var Rp=hp(import.meta.url),Tp=Rp("terminal-kit"),yp=Tp.terminal;async function pa(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=Ce(t);await ot(t);let r=await Te(n),s=Ze(r),o=e.uiStateFile?await fe({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await Et(t,void 0,s),d=nn(si(o,r),l);l=await Et(t,d,s);let f=()=>{},h={workspaceRoot:t,onUpdate:()=>f(),resolveSessionSpec:(I,T)=>Sp(l,T,t)},R=e.ptyRuntime??await Wi({...h,paths:n}),k=I=>{if(!e.uiStateFile)return;o=oi(o,I);let T=o;i=i.then(()=>ae({uiStateFile:e.uiStateFile},T),()=>ae({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(I=>{let T=e.terminal??yp,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:nn(d,l)},V=!1,j=!1,te=null,C=0,Ne=0,Ae=null,X=null,$e=null,we=null,De=null,ne=null,Qe=null,yn=!1,Pn=null,qr=`Craig v${Nr()}`,bn=null,In=0,G=!0,Sn=null,y=()=>{},F=R;f=()=>{a.mode==="main"&&(a={mode:"main",shell:lt(a.shell)},$e||($e=setTimeout(()=>{$e=null,a.mode==="main"&&y()},50)))};function lt(m){return Ye(m,F.getViewState(Kr(m)))}function Kr(m){let u=Xe(m);return u?u.ptyTabs.some(p=>p.id===m.activeTab)?m.activeTab:m.activeTab==="agent"||m.activeTab==="terminal"?u.ptyTabs.find(p=>p.kind===m.activeTab)?.id??m.selectedPtyTabId:m.selectedPtyTabId:m.selectedPtyTabId}function P(m){return lt(Pp(m,l))}function Xe(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function Vr(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(p=>p.id));await F.pruneStale?.(m),await F.hydrateSessions?.(m)}function ha(){Vr().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function wa(m){let u=P(m),p=Xe(u),g=Kr(u);if(!p||!g||!p.ptyTabs.some(L=>L.id===g))return u;let w=F.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return Ye(u,w);let S=await F.ensureSession(p.id,g,$t(je(T.width,T.height)));return Ye({...u,inputMode:"control"},S)}function Gr(m,u){return we&&(clearTimeout(we),we=null),u?(we=setTimeout(()=>{we=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...m,footerToast:u}):{...m,footerToast:null}}function ka(m,u){return Gr(m,u?{tone:"success",message:u}:null)}function U(m,u,p){let g=u instanceof Error?u.message:p,w=u instanceof Error?u.stack??u.message:String(u);return ir(n,{context:m,message:g,details:w}),g}function q(m,u){return Gr(m,{tone:"error",message:u})}function We(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function Hr(m){let u=Xe(m),p=l.inspection,g=p&&p.taskId===u?.id?p:null,w=bp(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:Ip(l),centerTabIds:ui(u,m),ptyTabIds:u?.ptyTabs.map(S=>S.id)??[],filePathIds:g?.filePaths??[],fileTreeRowIds:w.map(S=>S.path),fileTreeFileIds:w.filter(S=>S.kind==="file").map(S=>S.path),fileTreeDirectoryIds:w.filter(S=>S.kind==="directory").map(S=>S.path),diffPathIds:g?.diffPaths??[],diffPathRanges:[],fileLineCount:g?.selectedFile.lines.length??0,diffLineCount:g?.selectedDiff.lines.length??0,reviewRowCount:Ci(m,u),pageRows:Math.max(5,je(T.width,T.height).height-he.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(S=>S.repoId)??[]}}async function Ra(m){await os(n,m),r=m,s=Ze(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:_e(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:_e(r)})}}async function Ta(m){let u=m.selectedTaskId;u&&await We(async()=>{let p=await _(n,u);!p.ptyTabs.some(g=>g.id===m.activeTab)||p.selectedPtyTabId===m.activeTab||await E(n,{...p,selectedPtyTabId:m.activeTab})})}async function re(){let m=(a.mode==="main",a.shell);l=await Et(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function zr(m){let u=++In,p=ma(l.tasks,m),g=l.inspection,w;if(p&&g?.taskId===p.id){let S={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},L=await Ao(p,g,S);if(u!==In)return;w={...l,inspection:L}}else if(w=await Et(t,m,s),u!==In)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function Cn(m){let u=await jp(m);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:u,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function Yr(m){try{let u=P(m),p=Xe(u),g=u.selectedPtyTabId;if(p&&u.focusedRegion==="tasks"){let L=p.ptyTabs.find(de=>de.kind==="agent")??null;L?g=L.id:(p=await Jr(p),await re(),g=p.selectedPtyTabId)}p&&!g&&(p=await Jr(p),await re(),g=p.selectedPtyTabId);let w=P({...u,activeTab:g??u.activeTab,selectedPtyTabId:g,focusedRegion:g?"center":u.focusedRegion});if(!w.selectedTaskId||!g){a={mode:"main",shell:w},y();return}a={mode:"main",shell:Ye({...w,inputMode:"terminal"},F.getViewState(g))},k(a.shell);let S=await F.ensureSession(w.selectedTaskId,g,$t(je(T.width,T.height)));j=Ur(g),te=null,a={mode:"main",shell:Ye({...w,inputMode:"terminal"},S)},k(a.shell)}catch(u){let p=U("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Ur(m.selectedPtyTabId)&&(await ya(m.selectedTaskId,p).catch(()=>{}),await re().catch(()=>{})),a={mode:"main",shell:q(ai(P(m),p),p)},k(a.shell)}y()}async function ya(m,u){await We(async()=>{let p=await _(n,m);await E(n,{...p,status:p.status==="running"?"draft":p.status,runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:u})})}async function Pa(m,u,p){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await We(async()=>{let S=await _(n,g.selectedTaskId),L=u??vp(S,g.activeTab,g.preferredPtyTabKind),de=ua(S,L,p??void 0,r),dt={...S,ptyTabs:[...S.ptyTabs,de],selectedPtyTabId:de.id};return await E(n,dt),dt});return await re(),P({...g,activeTab:w.selectedPtyTabId??g.activeTab,selectedPtyTabId:w.selectedPtyTabId,preferredPtyTabKind:w.ptyTabs.at(-1)?.kind??g.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${w.ptyTabs.at(-1)?.title??"tab"}`})}async function ba(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:p,nextSelectedTab:g}=await We(async()=>{let w=await _(n,u.selectedTaskId),S=w.ptyTabs.findIndex(En=>En.id===u.activeTab);if(S===-1)throw new Error("Only PTY tabs can be closed.");let L=w.ptyTabs[S],de=w.ptyTabs.filter(En=>En.id!==L.id),dt=de[Math.min(S,de.length-1)]??de[S-1]??null;return await E(n,{...w,ptyTabs:de,selectedPtyTabId:dt?.id??null}),{closedTab:L,nextSelectedTab:dt}});return F.disposeSession(p.id),await re(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${p.title}`})}async function Ia(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let p=Xe(u),g=null,w=null;if(p?.type==="project"&&p.repoTargets?.length){let S=await zt(n,u.selectedTaskId);await re();let L=S.synced+S.discovered+S.notFound;w=`Refreshed ${S.synced}/${L} targets`}else{let{disposition:S,task:L}=await Jn(n,u.selectedTaskId);await re(),g=S==="not_found"?`No PR found for ${L.branch}`:null,S!=="not_found"&&(w=`Refreshed checks: ${K(L)?.requiredChecks.length??0} reported`)}return P({...ka(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function Sa(){if(yn||a.mode!=="main")return;let m=l.tasks;yn=!0;try{if(await co(n,m),Pn=null,a.mode!=="main")return;l=await Et(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(u){let p=u instanceof Error?u.message:"Background PR discovery failed.";p!==Pn&&(Pn=p,ir(n,{context:"background PR polling",message:p,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{yn=!1}}async function Ca(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:p,task:g}=await We(async()=>{let w=await _(n,u.selectedTaskId),S=await _o(n,u.selectedTaskId);return{taskBeforeClose:w,task:S}});for(let w of p.ptyTabs)F.disposeSession(w.id);return await re(),P({...u,selectedActionId:"close-task",actionMessage:g.cleanup.preservedWorktree?`Archived task ${g.id}; worktree preserved`:`Archived task ${g.id}`})}async function xa(m){let u=P(m);if(!u.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await be(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await Tt(n,u.selectedWorkspaceId);let g=await yt(n,u.selectedWorkspaceId);return await re(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function Jr(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await We(async()=>{let S=await _(n,m.id),L=S.ptyTabs.find(de=>de.kind==="agent")??null;L&&await E(n,{...S,selectedPtyTabId:L.id})}),w}let p=ua(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,p],selectedPtyTabId:p.id};return await We(async()=>{let w=await _(n,m.id),S=w.ptyTabs.find(L=>L.kind==="agent")??null;if(S){await E(n,{...w,selectedPtyTabId:S.id});return}await E(n,{...w,ptyTabs:[...w.ptyTabs,p],selectedPtyTabId:p.id})}),g}y=()=>{va();let m=je(T.width,T.height),u=a.mode==="main"?Zi(m,Ri(P(a.shell),l),{centerOnly:a.shell.centerZoomed,focusFlashActive:De!==null&&Date.now()<De}):a.variant==="boot"?Yi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:qr,updateText:bn}):a.variant==="pause"?Ji(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:qr,updateText:bn}):a.variant==="options"?Or(m,{menuIndex:a.menuIndex,optionsMenuItems:Wr}):a.variant==="runners"?Or(m,{menuIndex:At(a).menuIndex,optionsMenuItems:_r(r,At(a)),optionsMessage:ca(At(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Xi(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Qi(m);G&&(T.moveTo(1,1),T.eraseDisplayBelow(),G=!1),T.noFormat(Ap(u)),T.hideCursor(!0)};function va(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==Sn&&(Sn=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let Ea=()=>{process.stdout.off("resize",ts),process.off("SIGCONT",ns),T.removeListener("key",Qr),T.removeListener("unknown",Xr),T.removeListener("mouse",Zr),Ae&&(clearTimeout(Ae),Ae=null),X&&(clearTimeout(X),X=null),$e&&(clearTimeout($e),$e=null),we&&(clearTimeout(we),we=null),ne&&(clearTimeout(ne),ne=null),Qe&&(clearInterval(Qe),Qe=null),F.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},xn=m=>{Ea(),I(m)},Aa=async()=>{if(a.mode!=="main"||V)return;let m=a.shell,u=m.taskPromptInput?.trim()??"";if(!m.selectedRepoId&&!m.selectedWorkspaceId){a={mode:"main",shell:P({...m,taskPromptError:"Select a workspace first."})},y();return}if(u.length===0){a={mode:"main",shell:P({...m,taskPromptError:"Task prompt cannot be empty."})},y();return}V=!0,a={mode:"main",shell:P({...m,actionMessage:`Creating ${m.selectedRunner} task in ${m.selectedWorkspaceId??m.selectedRepoId}...`})},y();let p=null;try{p=await Ep(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await re();let g=P({...a.shell,selectedRepoId:p.repoId,selectedWorkspaceId:p.workspaceId,selectedTaskId:p.id,selectedPtyTabId:p.selectedPtyTabId,selectedLeftItemId:`task:${p.id}`,activeTab:p.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),w=await F.ensureSession(p.id,g.selectedPtyTabId??ga(p,"agent"),$t(je(T.width,T.height)));j=Ur(g.selectedPtyTabId),a={mode:"main",shell:Ye(g,w)},k(a.shell)}catch(g){g instanceof Rn&&(p=g.task);let w=U("create task",g,"Failed to create task.");p&&(await E(n,{...p,status:"draft",runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:w}).catch(()=>{}),await re().catch(()=>{})),a={mode:"main",shell:q(P({...a.shell,inputMode:"control",selectedTaskId:p?.id??a.shell.selectedTaskId,selectedPtyTabId:p?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:p?`task:${p.id}`:a.shell.selectedLeftItemId,activeTab:p?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:p?null:"",taskPromptError:w,actionMessage:null}),w)}}finally{V=!1,y()}},$a=m=>{if(a.mode!=="main")return;let u=a.shell;if(u.taskPromptInput!==null){if(m==="ESCAPE"){a={mode:"main",shell:P({...u,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Ee(m)){Aa();return}if(m==="BACKSPACE"){a={mode:"main",shell:P({...u,taskPromptInput:u.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(m==="CTRL_R"){a={mode:"main",shell:P({...u,selectedRunner:wr(u.selectedRunner,s),taskPromptError:null})},y();return}ci(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},Da=m=>{if(a.mode!=="main")return;let u=a.shell.workspaceBrowser;if(u){if(m==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(m==="UP"||m==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.max(0,u.selectedIndex-1),error:null}})},y();return}if(m==="DOWN"||m==="j"){let p=Math.max(0,u.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.min(p,u.selectedIndex+1),error:null}})},y();return}if(m==="LEFT"||m==="h"){Cn(ct.dirname(u.cwd)).catch(p=>{let g=U("open parent workspace directory",p,"Failed to open parent directory.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Ee(m)){let p=u.entries[u.selectedIndex]??null;if(!p)return;if((m==="RIGHT"||m==="l")&&(p.kind==="directory"||p.kind==="repo")){Cn(p.path).catch(g=>{let w=U("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}Rt(n,p.path).then(async g=>{await re();let w=g.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${g.workspace.id}`,selectedWorkspaceId:g.workspace.id,selectedRepoId:w?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${g.workspace.name??g.workspace.id}`})},k(a.shell),y()}).catch(g=>{let w=U("add workspace",g,"Failed to add workspace.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},Qr=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){$a(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){Da(u);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(u==="F"){Fa(),y();return}De!==null&&(De=null,ne&&(clearTimeout(ne),ne=null))}if(a.mode==="main"){let p=ii(a.shell,u,Hr(a.shell));if(p.exit){xn(0);return}if(p.detachTerminal){F.detach(),a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(p.changed){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(j&&Ee(u)){j=!1;return}j&&(j=!1),te=Dp(u)?{key:u,at:Date.now()}:null;let g=Mp(u,a.shell.terminal.scrolledBack??!1);if(g!==0){vn(g);return}F.writeKey(u);return}if(u==="CTRL_C"){xn(0);return}if(u==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},G=!0,y();return}if(p.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(p.state)},G=!0,y();return}if(p.beginTaskPrompt){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(p.openWorkspaceBrowser){Cn(t).catch(g=>{let w=U("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:q(P({...p.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(p.createPtyTab){Pa(p.state,p.createPtyTabKind,p.createPtyTabRunner).then(g=>{Yr(g)}).catch(g=>{let w=U("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.closePtyTab){ba(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("close PTY tab",g,"Failed to close tab.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.refreshPullRequestChecks){Ia(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("refresh PR checks",g,"Failed to refresh PR checks.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.openPrUrl){let g=Xe(p.state),w=g?K(g)?.url??null:null;w?Np(w).catch(S=>{let L=U("open PR URL",S,"Failed to open PR in browser.");a={mode:"main",shell:q(P(p.state),L)},y()}):(a={mode:"main",shell:q(P(p.state),"No PR URL available.")},y());return}if(p.closeTask){Ca(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("close task",g,"Failed to close task.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.removeWorkspace){xa(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("remove workspace",g,"Failed to remove workspace.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.attachTerminal){Yr(p.state);return}if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),zr(a.shell).catch(g=>{let w=U("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:q(P({...a.shell,actionMessage:w}),w)},y()});return}p.changed&&(a={mode:"main",shell:P(p.state)},Ta(a.shell).catch(()=>{}),k(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},G=!0,y();return}if(a.variant==="options"){Ma(u);return}if(a.variant==="runners"){Oa(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Ee(u)){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y()}return}if(a.optionsMessage){(u==="ESCAPE"||Ee(u))&&(a={...a,optionsMessage:null},y());return}if(u==="UP"||u==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(u==="DOWN"||u==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(u==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},G=!0,y());return}if(Ee(u)){if(a.menuIndex===0){let p=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},G=!0,y(),p?Wa.then(()=>{if(a.mode!=="main")return;let g=a.shell;wa(g).then(w=>{a.mode!=="main"||a.shell!==g||(a={mode:"main",shell:w},k(a.shell),y())}).catch(w=>{if(a.mode!=="main"||a.shell!==g)return;let S=U("warm selected PTY",w,"Failed to start selected PTY.");a={mode:"main",shell:q(P(a.shell),S)},k(a.shell),y()})}):ha();return}if(a.menuIndex===1){let p=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}xn(0)}};function Ma(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=la(a.menuIndex,m);if(u.kind!=="noop"){if(u.kind==="render"){a={...a,menuIndex:u.menuIndex},y();return}if(u.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},G=!0,y());return}if(u.kind==="help"){let p=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="runners"){let p=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="error-log"){let p=a.parentVariant;La(p)}}}async function La(m){let u;try{u=await vo(n)}catch(p){let g=U("open error log",p,"Failed to read Craig error log.");u={path:n.errorLogFile,lines:[`Unable to read error log: ${g}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:u,...m!==void 0?{parentVariant:m}:{}},G=!0,y())}function Oa(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=da(At(a),r,m,s);if(u.kind!=="noop"){if(u.kind==="back"){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="render"){a={...a,runnerOptions:u.state},y();return}Ra(u.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:u.state},y())}).catch(p=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let g=U("save runner option",p,"Failed to save runner option."),w=q(P(a.shell),g);a={...a,shell:w,runnerOptions:{...At(a),message:g}},y()})}}function Fa(){De=Date.now()+600,ne&&clearTimeout(ne),ne=setTimeout(()=>{De=null,ne=null,y()},600)}let Xr=m=>{let u=$p(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){F.detach(),j=!1,te=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let p=Lp(u);if(p!==0){vn(p);return}let g=Op(u);if(g){j=!1,te={key:g,at:Date.now()},F.writeKey(g);return}if(j&&u!=="\r"&&u!==`
|
|
152
|
+
`);if(d===-1)return;let p=o.slice(0,d);c(),s.end();try{n(JSON.parse(p))}catch(h){r(h instanceof Error?h:new Error(String(h)))}}),s.once("close",()=>c())})}async function Oi(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!await Ht(e))return;await Cr(50)}}function Ki(e){return new Promise((t,n)=>{let r=Fi(e);r.once("connect",()=>t(r)),r.once("error",n)})}function vp(e,t){return new Promise((n,r)=>{e.once("error",r),e.listen(t,n)})}function Gt(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
|
|
153
|
+
`)}catch{}}function Vi(e){try{return process.kill(e,0),!0}catch{return!1}}function Cr(e){return new Promise(t=>setTimeout(t,e))}function Ep(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}import LR from"picocolors";var Ap=[" \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 xr(){return[...Ap]}var $p=["Start","Options","Exit"],Dp=["Resume","Options","Exit"],Jt=2,Qt=2,Xt=2,Mp=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Lp=new RegExp("\x1B\\[(?:0)?m","g"),jp=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),Op=/https?:\/\/[^\s<>"']+/g,vr="\x1B[0m",Er="\x1B]8;;\x1B\\",E={panelBg:{bg:"0a0a0a",fg:"c0caf5"},panelMuted:{bg:"0a0a0a",fg:"565f89"},panelSelected:{bg:"1a1b26",fg:"c0caf5"},panelFocused:{bg:"1a1b26",fg:"7aa2f7"},divider:{bg:"0a0a0a",fg:"292e42"},rail:{bg:"0a0a0a",fg:"c0caf5"},overlay:{bg:"06060f",fg:"565f89"},overlayTitle:{bg:"06060f",fg:"565f89"},overlayLogo:{bg:"06060f",fg:"9ece6a"},overlaySubtitle:{bg:"06060f",fg:"41a6b5"},overlayMenuSelected:{bg:"06060f",fg:"7aa2f7"},accent:{fg:"7aa2f7"},success:{fg:"9ece6a"},pending:{fg:"e0af68"},error:{fg:"f7768e"},mutedfg:{fg:"565f89"},disabled:{fg:"3b4261"}};function zi(e,t={}){return $r(e,{subtitle:"crAIg is that you?",menuItems:$p,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function Yi(e,t={}){return $r(e,{subtitle:"Control mode is paused.",menuItems:Dp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var zt=[" 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."],Fp=["Help"];function Ar(e,t={}){return $r(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Fp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Ji(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(F(" ".repeat(e.width),n,r)),o=xr(),i=Math.max(1,Math.floor((e.height-o.length-2-zt.length)/2));for(let p=0;p<o.length&&!(i+p>=e.height);p+=1)s[i+p]=F(ta(o[p]??"",e.width),n,E.overlayLogo);let c=Math.max(...zt.map(p=>p.length)),l=Math.max(0,Math.floor((e.width-c)/2)),d=i+o.length+2;for(let p=0;p<zt.length;p+=1){let h=d+p;if(h>=e.height)break;let R=zt[p]??"";s[h]=F(ke(" ".repeat(l)+R,e.width),n,r)}return s.join(`
|
|
154
|
+
`)}function Qi(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(F(" ".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)),p=[{text:o,tone:"selected"},{text:i,tone:"muted"},se(),...c.length>0?c.map(k=>({text:k})):[{text:"No Craig errors have been logged.",tone:"muted"}],se(),{text:"Esc returns to Options.",tone:"muted"}],h=ut(p,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]??se(),a=`${" ".repeat(d)}${en(T.text,l)}`,G=T.tone==="selected"?E.overlayMenuSelected:T.tone==="muted"?E.overlay:E.panelBg;s[I]=F(ke(a,e.width),n,G)}return s.join(`
|
|
155
|
+
`)}function Xi(e,t,n={}){let r=n.color??!0,s=pe.leftWidth,o=pe.rightWidth,i=pe.dividerWidth,c=n.centerOnly??!1,l=c?e.width:e.width-s-o-i*2,d=e.height-pe.topRailHeight-1,p=n.focusFlashActive??!1,h={bg:E.divider.bg,fg:"9ece6a"},R=p&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?h:E.divider,k=p&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?h:E.divider,I=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=F(ke(I,e.width),r,E.rail),a=Wp(t,s-Jt-Qt,d,r),G=_p(t,l,d,r),W=Up(t,o,d,r),oe=t.inputMode==="terminal",x=[];for(let te=0;te<d;te+=1){if(c){x.push(Yt(G[te]??se(),l,r,"center"));continue}let Se=Yt(a[te]??se(),s,r,"left"),fe=F("\u2502",r,R),Ie=Yt(G[te]??se(),l,r,"center"),ie=F("\u2502",r,k),Ue=Yt(W[te]??se(),o,r,"right");x.push(`${Se}${fe}${Ie}${ie}${Ue}`)}let $e=oe||t.modalInput?E.panelBg:E.panelMuted,be=Np(t.footerText,t.footerToast,e.width,r,$e);return[T,...x,be].join(`
|
|
156
|
+
`)}function Np(e,t,n,r,s){let o=` ${e}`;if(!t)return F(ke(o,n),r,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,c=ee(i),l=ee(o),d=Math.max(1,n-l-c-2),p=l+d+c+2>n?en(o,Math.max(0,n-c-3)):o,h=Math.max(1,n-ee(p)-c-2),R=t.tone==="error"?cf(i,r,s):Je(i,r,s),k=`${p}${" ".repeat(h)}${R} `;return F(ke(k,n),r,s)}function $r(e,t){let n=new Array(e.height).fill(F(" ".repeat(e.width),t.color,E.overlay)),r=xr(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,p)=>`${p===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 p=ta(c[d]??"",e.width);if(d<r.length){n[l+d]=F(p,t.color,E.overlayLogo);continue}if(d===r.length+1){n[l+d]=F(p,t.color,E.overlaySubtitle);continue}let h=d-(r.length+3),k=h>=0&&h<t.menuItems.length&&h===t.menuIndex?E.overlayMenuSelected:E.overlay;n[l+d]=F(p,t.color,k)}if(t.versionText){let d=t.updateText?" (update available)":"",p=`${t.versionText}${d} `,h=" ".repeat(Math.max(0,e.width-ee(p)));n[e.height-1]=F(`${h}${Dr(p,t.color,E.overlay)}`,t.color,E.overlay)}return n.join(`
|
|
157
|
+
`)}function Wp(e,t,n,r){let s=Vp(e.runners),o=1,i=e.leftTree.map(l=>Kp(l,t,r));return[...ut(i,n-o),s]}function _p(e,t,n,r){let s=t-2,o=e.tabs.find(x=>x.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:sf(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?Je(l,r,E.panelBg):Zt(l,r,E.panelMuted)}`,p=[`${Zt(e.centerHeader.tabLabel,r,E.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(x=>x.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!ci(h)?e.centerTranscript.map(x=>({...x})):Bp(e),k=Gp(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?Je(`${I}\u25CF `,r,E.panelBg):"",G=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-ee(k)-T)):"",oe=[{text:e.inputMode==="terminal"?`${k}${G}${a}`:k},{text:d,tone:"muted"},{text:p},se(),...R];return ut(oe,n)}function Bp(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},se(),{text:e.terminal.error},se(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(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 Up(e,t,n,r){let s=e.rightInspection?qp(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):ut([{text:"CONTEXT"},se(),...e.rightContext.map(o=>Hp(o,r)),...e.actionMessage?[se(),{text:e.actionMessage}]:[]],n);return ut(s,n)}function qp(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:af(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Gi(c)),...r.slice(i,i+s).map(c=>Gi(c))]}function Gi(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 Kp(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${Je("\u25CF",n,e.selected?E.panelSelected:E.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+ee(I.text),0):0,l=t-ee(o)-ee(s)-c,d=e.selected?e.text:e.focused?Je(e.text,n,E.panelBg):e.panelHeader?Zt(e.text,n,E.panelMuted):e.text,p=ke(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${p}${o}${i}`},...e.prBadge];return{text:`${p}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${p}${o}${i}`,tone:h}}function Vp(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:E.success.fg}}):n.push({text:s.text,style:{fg:E.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function Gp(e,t,n){return e.map(r=>r.active?n?Je(r.label,t,E.panelBg):Zt(r.label,t,E.panelBg):Dr(r.label,t,E.panelBg)).join(" ")}function Hp(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?Dr(e.value,t,E.panelBg):e.value}`}}function Yt(e,t,n,r){let s=zp(r,e.tone??"default"),o=Yp(e,n,s);if(r==="left"){if(e.fullBleed)return F(ke(o,t),n,s);let c=t-Jt-Qt;if(e.rightAlign){let d=ee(o),p=Math.max(0,c-d),h=`${" ".repeat(Jt)}${" ".repeat(p)}${o}${" ".repeat(Qt)}`;return F(h,n,s)}let l=`${" ".repeat(Jt)}${ke(o,c)}${" ".repeat(Qt)}`;return F(l,n,s)}return r==="center"&&e.fullBleed?Jp(e,t,n,s):F(ke(` ${o}`,t),n,s)}function zp(e,t){return t==="selected"||t==="focused"?E.panelSelected:t==="muted"?E.panelMuted:E.panelBg}function ut(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(se());return n}function se(){return{text:""}}function Yp(e,t,n){return e.segments?e.segments.map(r=>Zi(r,t,n)).join(""):e.text}function Jp(e,t,n,r){let s=" ".repeat(Xt),o=Math.max(0,t-Xt*2);if(!e.segments)return F(`${s}${ke(e.text,o)}${s}`,n,r);let i=Zp(e.segments,o),c=`${s}${i.map(l=>Zi(l,n,r)).join("")}${s}${n?Er:""}`;return F(c,n,r)}function Zi(e,t,n){let r=e.href?`${ea(e.href)}${e.text}${Er}`:Qp(e.text);return!t||!e.style?r:`${pt(nf(e.style,n))}${rf(e.style)}${r}${vr}${pt(n)}`}function Qp(e){return e.replace(Op,t=>{let[n,r]=Xp(t);return`${ea(n)}${n}${Er}${r}`})}function Xp(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ea(e){return`\x1B]8;;${e}\x1B\\`}function Zp(e,t){let n=ef(e,t);return tf(n,t)}function ef(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=ee(s.text);if(o<=r){n.push(s),r-=o;continue}let i=en(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function tf(e,t){let n=ee(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 nf(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 rf(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 sf(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function ta(e,t){let n=Math.max(0,t-ee(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function ke(e,t){let n=ee(e);return n>=t?of(e,t):e+" ".repeat(t-n)}function of(e,t){if(t<=0)return"";if(ee(e)<=t)return e;let n=ra(e);return en(n,Math.max(0,t-1))+"\u2026"}function ee(e){let t=0;for(let n of Array.from(ra(e)))t+=na(n);return t}function en(e,t){let n="",r=0;for(let s of Array.from(e)){let o=na(s);if(r+o>t)break;n+=s,r+=o}return n}function na(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function af(e,t,n){return Math.min(Math.max(e,t),n)}function ra(e){return e.replace(jp,"").replace(Mp,"")}function sa(e){return e.map(t=>t.text).join("")}function F(e,t,n){if(!t)return e;let r=pt(n),s=e.replace(Lp,`${vr}${r}`);return`${r}${s}${vr}`}function pt(e){let t=[];return e.fg&&t.push(`38;2;${Hi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Hi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Hi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function Je(e,t,n){return tn(e,t,E.success.fg,n)}function cf(e,t,n){return tn(e,t,E.error.fg,n)}function Zt(e,t,n){return tn(e,t,E.accent.fg,n)}function Dr(e,t,n){return tn(e,t,E.mutedfg.fg,n)}function tn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${pt(s)}${e}${pt(r)}`}var Mr=["Runners","Error Log","Help"];function Lr(e,t){return j.map(n=>{let r=b.runners.getProfile(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function ia(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 aa(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Mr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:jr(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function ca(e,t,n,r){if(e.pathEdit)return lf({...e,pathEdit:e.pathEdit},t,n);let s=Lr(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=j[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!jr(n))return{kind:"noop",state:e};let o=j[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:df(t,o,!i),state:{...e,message:`${b.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function lf(e,t,n){if(n==="ESCAPE")return{kind:"render",state:oa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(jr(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:uf(t,r,s.length>0?s:null),state:oa({...e,message:s.length>0?`${b.runners.getProfile(r).displayName} executable saved.`:`${b.runners.getProfile(r).displayName} executable reset to default.`})}}return pf(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function df(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function uf(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function oa(e){let t={...e};return delete t.pathEdit,t}function jr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
158
|
+
`}function pf(e){return e.length===1&&e>=" "&&e!=="\x7F"}var hf=ff(import.meta.url),wf=hf("terminal-kit"),kf=wf.terminal;async function ua(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=Re(t),r=await b.load(n),s=b.runners.getEnabled(r),o=e.uiStateFile?await Y({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await ft(t,void 0,s),d=Bt(ri(o,r),l);l=await ft(t,d,s);let p=()=>{},h={workspaceRoot:t,onUpdate:()=>p(),resolveSessionSpec:(I,T)=>Pf(l,T,t)},R=e.ptyRuntime??await Ni({...h,paths:n}),k=I=>{if(!e.uiStateFile)return;o=si(o,I);let T=o;i=i.then(()=>H({uiStateFile:e.uiStateFile},T),()=>H({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(I=>{let T=e.terminal??kf,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Bt(d,l)},G=!1,W=!1,oe=null,x=0,$e=0,be=null,te=null,Se=null,fe=null,Ie=null,ie=null,Ue=null,sn=!1,on=null,Fr=`Craig v${b.version.getCurrent()}`,an=null,cn=0,z=!0,ln=null,y=()=>{},N=R;p=()=>{a.mode==="main"&&(a={mode:"main",shell:Xe(a.shell)},Se||(Se=setTimeout(()=>{Se=null,a.mode==="main"&&y()},50)))};function Xe(m){return _e(m,N.getViewState(Nr(m)))}function Nr(m){let u=qe(m);return u?u.ptyTabs.some(f=>f.id===m.activeTab)?m.activeTab:m.activeTab==="agent"||m.activeTab==="terminal"?u.ptyTabs.find(f=>f.kind===m.activeTab)?.id??m.selectedPtyTabId:m.selectedPtyTabId:m.selectedPtyTabId}function P(m){return Xe(Rf(m,l))}function qe(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function Wr(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(f=>f.id));await N.pruneStale?.(m),await N.hydrateSessions?.(m)}function ma(){Wr().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function ga(m){let u=P(m),f=qe(u),g=Nr(u);if(!f||!g||!f.ptyTabs.some(O=>O.id===g))return u;let w=N.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return _e(u,w);let C=await N.ensureSession(f.id,g,gt(Ae(T.width,T.height)));return _e({...u,inputMode:"control"},C)}function _r(m,u){return fe&&(clearTimeout(fe),fe=null),u?(fe=setTimeout(()=>{fe=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...m,footerToast:u}):{...m,footerToast:null}}function ha(m,u){return _r(m,u?{tone:"success",message:u}:null)}function q(m,u,f){let g=u instanceof Error?u.message:f,w=u instanceof Error?u.stack??u.message:String(u);return tr(n,{context:m,message:g,details:w}),g}function K(m,u){return _r(m,{tone:"error",message:u})}function De(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function Br(m){let u=qe(m),f=l.inspection,g=f&&f.taskId===u?.id?f:null,w=Tf(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:yf(l),centerTabIds:di(u,m),ptyTabIds:u?.ptyTabs.map(C=>C.id)??[],filePathIds:g?.filePaths??[],fileTreeRowIds:w.map(C=>C.path),fileTreeFileIds:w.filter(C=>C.kind==="file").map(C=>C.path),fileTreeDirectoryIds:w.filter(C=>C.kind==="directory").map(C=>C.path),diffPathIds:g?.diffPaths??[],diffPathRanges:[],fileLineCount:g?.selectedFile.lines.length??0,diffLineCount:g?.selectedDiff.lines.length??0,reviewRowCount:Ii(m,u),pageRows:Math.max(5,Ae(T.width,T.height).height-pe.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(C=>C.repoId)??[]}}async function wa(m){await b.save(n,m),r=m,s=b.runners.getEnabled(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}}async function ka(m){let u=m.selectedTaskId;u&&await De(async()=>{let f=await B(n,u);!f.ptyTabs.some(g=>g.id===m.activeTab)||f.selectedPtyTabId===m.activeTab||await A(n,{...f,selectedPtyTabId:m.activeTab})})}async function ae(){let m=(a.mode==="main",a.shell);l=await ft(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function Ur(m){let u=++cn,f=pa(l.tasks,m),g=l.inspection,w;if(f&&g?.taskId===f.id){let C={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},O=await Eo(f,g,C);if(u!==cn)return;w={...l,inspection:O}}else if(w=await ft(t,m,s),u!==cn)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function dn(m){let u=await Lf(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 qr(m){try{let u=P(m),f=qe(u),g=u.selectedPtyTabId;if(f&&u.focusedRegion==="tasks"){let O=f.ptyTabs.find(le=>le.kind==="agent")??null;O?g=O.id:(f=await Kr(f),await ae(),g=f.selectedPtyTabId)}f&&!g&&(f=await Kr(f),await ae(),g=f.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:_e({...w,inputMode:"terminal"},N.getViewState(g))},k(a.shell);let C=await N.ensureSession(w.selectedTaskId,g,gt(Ae(T.width,T.height)));W=Or(g),oe=null,a={mode:"main",shell:_e({...w,inputMode:"terminal"},C)},k(a.shell)}catch(u){let f=q("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Or(m.selectedPtyTabId)&&(await Ra(m.selectedTaskId,f).catch(()=>{}),await ae().catch(()=>{})),a={mode:"main",shell:K(ii(P(m),f),f)},k(a.shell)}y()}async function Ra(m,u){await De(async()=>{let f=await B(n,m);await A(n,{...f,status:f.status==="running"?"draft":f.status,runnerSession:{...f.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:u})})}async function Ta(m,u,f){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await De(async()=>{let C=await B(n,g.selectedTaskId),O=u??If(C,g.activeTab,g.preferredPtyTabKind),le=la(C,O,f??void 0,r),Ze={...C,ptyTabs:[...C.ptyTabs,le],selectedPtyTabId:le.id};return await A(n,Ze),Ze});return await ae(),P({...g,activeTab:w.selectedPtyTabId??g.activeTab,selectedPtyTabId:w.selectedPtyTabId,preferredPtyTabKind:w.ptyTabs.at(-1)?.kind??g.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${w.ptyTabs.at(-1)?.title??"tab"}`})}async function ya(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:f,nextSelectedTab:g}=await De(async()=>{let w=await B(n,u.selectedTaskId),C=w.ptyTabs.findIndex(fn=>fn.id===u.activeTab);if(C===-1)throw new Error("Only PTY tabs can be closed.");let O=w.ptyTabs[C],le=w.ptyTabs.filter(fn=>fn.id!==O.id),Ze=le[Math.min(C,le.length-1)]??le[C-1]??null;return await A(n,{...w,ptyTabs:le,selectedPtyTabId:Ze?.id??null}),{closedTab:O,nextSelectedTab:Ze}});return N.disposeSession(f.id),await ae(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${f.title}`})}async function Pa(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let f=qe(u),g=null,w=null;if(f?.type==="project"&&f.repoTargets?.length){let C=await Lt(n,u.selectedTaskId);await ae();let O=C.synced+C.discovered+C.notFound;w=`Refreshed ${C.synced}/${O} targets`}else{let{disposition:C,task:O}=await _n(n,u.selectedTaskId);await ae(),g=C==="not_found"?`No PR found for ${O.branch}`:null,C!=="not_found"&&(w=`Refreshed checks: ${V(O)?.requiredChecks.length??0} reported`)}return P({...ha(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function ba(){if(sn||a.mode!=="main")return;let m=l.tasks;sn=!0;try{if(await uo(n,m),on=null,a.mode!=="main")return;l=await ft(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(u){let f=u instanceof Error?u.message:"Background PR discovery failed.";f!==on&&(on=f,tr(n,{context:"background PR polling",message:f,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{sn=!1}}async function Sa(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:f,task:g}=await De(async()=>{let w=await B(n,u.selectedTaskId),C=await Wo(n,u.selectedTaskId);return{taskBeforeClose:w,task:C}});for(let w of f.ptyTabs)N.disposeSession(w.id);return await ae(),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 he(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await Z.archiveWorkspace(n,u.selectedWorkspaceId);let g=await Z.removeWorkspace(n,u.selectedWorkspaceId);return await ae(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function Kr(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await De(async()=>{let C=await B(n,m.id),O=C.ptyTabs.find(le=>le.kind==="agent")??null;O&&await A(n,{...C,selectedPtyTabId:O.id})}),w}let f=la(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,f],selectedPtyTabId:f.id};return await De(async()=>{let w=await B(n,m.id),C=w.ptyTabs.find(O=>O.kind==="agent")??null;if(C){await A(n,{...w,selectedPtyTabId:C.id});return}await A(n,{...w,ptyTabs:[...w.ptyTabs,f],selectedPtyTabId:f.id})}),g}y=()=>{Ca();let m=Ae(T.width,T.height),u=a.mode==="main"?Xi(m,ki(P(a.shell),l),{centerOnly:a.shell.centerZoomed,focusFlashActive:Ie!==null&&Date.now()<Ie}):a.variant==="boot"?zi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Fr,updateText:an}):a.variant==="pause"?Yi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Fr,updateText:an}):a.variant==="options"?Ar(m,{menuIndex:a.menuIndex,optionsMenuItems:Mr}):a.variant==="runners"?Ar(m,{menuIndex:mt(a).menuIndex,optionsMenuItems:Lr(r,mt(a)),optionsMessage:ia(mt(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Qi(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Ji(m);z&&(T.moveTo(1,1),T.eraseDisplayBelow(),z=!1),T.noFormat(xf(u)),T.hideCursor(!0)};function Ca(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==ln&&(ln=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let xa=()=>{process.stdout.off("resize",Yr),process.off("SIGCONT",Jr),T.removeListener("key",Vr),T.removeListener("unknown",Gr),T.removeListener("mouse",Hr),be&&(clearTimeout(be),be=null),te&&(clearTimeout(te),te=null),Se&&(clearTimeout(Se),Se=null),fe&&(clearTimeout(fe),fe=null),ie&&(clearTimeout(ie),ie=null),Ue&&(clearInterval(Ue),Ue=null),N.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},un=m=>{xa(),I(m)},va=async()=>{if(a.mode!=="main"||G)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}G=!0,a={mode:"main",shell:P({...m,actionMessage:`Creating ${m.selectedRunner} task in ${m.selectedWorkspaceId??m.selectedRepoId}...`})},y();let f=null;try{f=await Cf(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await ae();let g=P({...a.shell,selectedRepoId:f.repoId,selectedWorkspaceId:f.workspaceId,selectedTaskId:f.id,selectedPtyTabId:f.selectedPtyTabId,selectedLeftItemId:`task:${f.id}`,activeTab:f.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),w=await N.ensureSession(f.id,g.selectedPtyTabId??fa(f,"agent"),gt(Ae(T.width,T.height)));W=Or(g.selectedPtyTabId),a={mode:"main",shell:_e(g,w)},k(a.shell)}catch(g){g instanceof nn&&(f=g.task);let w=q("create task",g,"Failed to create task.");f&&(await A(n,{...f,status:"draft",runnerSession:{...f.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:w}).catch(()=>{}),await ae().catch(()=>{})),a={mode:"main",shell:K(P({...a.shell,inputMode:"control",selectedTaskId:f?.id??a.shell.selectedTaskId,selectedPtyTabId:f?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:f?`task:${f.id}`:a.shell.selectedLeftItemId,activeTab:f?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:f?null:"",taskPromptError:w,actionMessage:null}),w)}}finally{G=!1,y()}},Ea=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(Pe(m)){va();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:pr(u.selectedRunner,s),taskPromptError:null})},y();return}ai(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},Aa=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 f=Math.max(0,u.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.min(f,u.selectedIndex+1),error:null}})},y();return}if(m==="LEFT"||m==="h"){dn(Qe.dirname(u.cwd)).catch(f=>{let g=q("open parent workspace directory",f,"Failed to open parent directory.");a={mode:"main",shell:K(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Pe(m)){let f=u.entries[u.selectedIndex]??null;if(!f)return;if((m==="RIGHT"||m==="l")&&(f.kind==="directory"||f.kind==="repo")){dn(f.path).catch(g=>{let w=q("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:K(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}Z.addWorkspace(n,f.path).then(async g=>{await ae();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=q("add workspace",g,"Failed to add workspace.");a={mode:"main",shell:K(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},Vr=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){Ea(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){Aa(u);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(u==="F"){La(),y();return}Ie!==null&&(Ie=null,ie&&(clearTimeout(ie),ie=null))}if(a.mode==="main"){let f=oi(a.shell,u,Br(a.shell));if(f.exit){un(0);return}if(f.detachTerminal){N.detach(),a={mode:"main",shell:P(f.state)},k(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(f.changed){a={mode:"main",shell:P(f.state)},k(a.shell),y();return}if(W&&Pe(u)){W=!1;return}W&&(W=!1),oe=Ef(u)?{key:u,at:Date.now()}:null;let g=Af(u,a.shell.terminal.scrolledBack??!1);if(g!==0){pn(g);return}N.writeKey(u);return}if(u==="CTRL_C"){un(0);return}if(u==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},z=!0,y();return}if(f.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(f.state)},z=!0,y();return}if(f.beginTaskPrompt){a={mode:"main",shell:P(f.state)},k(a.shell),y();return}if(f.openWorkspaceBrowser){dn(t).catch(g=>{let w=q("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:K(P({...f.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(f.createPtyTab){Ta(f.state,f.createPtyTabKind,f.createPtyTabRunner).then(g=>{qr(g)}).catch(g=>{let w=q("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.closePtyTab){ya(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("close PTY tab",g,"Failed to close tab.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.refreshPullRequestChecks){Pa(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("refresh PR checks",g,"Failed to refresh PR checks.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.openPrUrl){let g=qe(f.state),w=g?V(g)?.url??null:null;w?jf(w).catch(C=>{let O=q("open PR URL",C,"Failed to open PR in browser.");a={mode:"main",shell:K(P(f.state),O)},y()}):(a={mode:"main",shell:K(P(f.state),"No PR URL available.")},y());return}if(f.closeTask){Sa(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("close task",g,"Failed to close task.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.removeWorkspace){Ia(f.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=q("remove workspace",g,"Failed to remove workspace.");a={mode:"main",shell:K(P({...f.state,actionMessage:w}),w)},y()});return}if(f.attachTerminal){qr(f.state);return}if(f.refreshInspection){a={mode:"main",shell:P(f.state)},k(a.shell),y(),Ur(a.shell).catch(g=>{let w=q("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:K(P({...a.shell,actionMessage:w}),w)},y()});return}f.changed&&(a={mode:"main",shell:P(f.state)},ka(a.shell).catch(()=>{}),k(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},z=!0,y();return}if(a.variant==="options"){$a(u);return}if(a.variant==="runners"){Ma(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Pe(u)){let f=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y()}return}if(a.optionsMessage){(u==="ESCAPE"||Pe(u))&&(a={...a,optionsMessage:null},y());return}if(u==="UP"||u==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(u==="DOWN"||u==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(u==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},z=!0,y());return}if(Pe(u)){if(a.menuIndex===0){let f=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},z=!0,y(),f?Fa.then(()=>{if(a.mode!=="main")return;let g=a.shell;ga(g).then(w=>{a.mode!=="main"||a.shell!==g||(a={mode:"main",shell:w},k(a.shell),y())}).catch(w=>{if(a.mode!=="main"||a.shell!==g)return;let C=q("warm selected PTY",w,"Failed to start selected PTY.");a={mode:"main",shell:K(P(a.shell),C)},k(a.shell),y()})}):ma();return}if(a.menuIndex===1){let f=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}un(0)}};function $a(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=aa(a.menuIndex,m);if(u.kind!=="noop"){if(u.kind==="render"){a={...a,menuIndex:u.menuIndex},y();return}if(u.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},z=!0,y());return}if(u.kind==="help"){let f=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}if(u.kind==="runners"){let f=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}if(u.kind==="error-log"){let f=a.parentVariant;Da(f)}}}async function Da(m){let u;try{u=await xo(n)}catch(f){let g=q("open error log",f,"Failed to read Craig error log.");u={path:n.errorLogFile,lines:[`Unable to read error log: ${g}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:u,...m!==void 0?{parentVariant:m}:{}},z=!0,y())}function Ma(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=ca(mt(a),r,m,s);if(u.kind!=="noop"){if(u.kind==="back"){let f=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...f!==void 0?{parentVariant:f}:{}},z=!0,y();return}if(u.kind==="render"){a={...a,runnerOptions:u.state},y();return}wa(u.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:u.state},y())}).catch(f=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let g=q("save runner option",f,"Failed to save runner option."),w=K(P(a.shell),g);a={...a,shell:w,runnerOptions:{...mt(a),message:g}},y()})}}function La(){Ie=Date.now()+600,ie&&clearTimeout(ie),ie=setTimeout(()=>{Ie=null,ie=null,y()},600)}let Gr=m=>{let u=vf(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){N.detach(),W=!1,oe=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let f=$f(u);if(f!==0){pn(f);return}let g=Df(u);if(g){W=!1,oe={key:g,at:Date.now()},N.writeKey(g);return}if(W&&u!=="\r"&&u!==`
|
|
159
159
|
`&&u!==`\r
|
|
160
|
-
`&&(
|
|
161
|
-
`).map((t,n)=>`\x1B[${n+1};1H${t}`).join("")}function
|
|
160
|
+
`&&(W=!1),Mf(W,oe,u)){W=!1;return}N.write(u)},Hr=m=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){Oa(da(m));return}let u=da(m);u!==0&&pn(u)};function pn(m){x+=m,!be&&(be=setTimeout(()=>{be=null;let u=x;x=0,u!==0&&(ja(u),y())},16))}function ja(m){N.scrollViewport(m),a={mode:"main",shell:Xe(a.shell)}}function zr(){z=!0,T.fullscreen(!0)}function Oa(m){m!==0&&($e+=m,!te&&(te=setTimeout(()=>{te=null;let u=$e;if($e=0,u===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let f=Ee(a.shell,u,Br(a.shell));if(f.changed){if(f.refreshInspection){a={mode:"main",shell:P(f.state)},k(a.shell),y(),Ur(a.shell).catch(g=>{let w=q("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:K(P({...a.shell,actionMessage:w}),w)},y()});return}a={mode:"main",shell:P(f.state)},k(a.shell),y()}},16)))}let Yr=()=>{zr(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(N.resize(gt(Ae(T.width,T.height))),a={mode:"main",shell:Xe(a.shell)}),y()},Jr=()=>{zr(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(N.resize(gt(Ae(T.width,T.height))),a={mode:"main",shell:Xe(a.shell)}),y()};process.stdout.on("resize",Yr),process.on("SIGCONT",Jr),T.grabInput(!0),ln="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",Vr),T.on("unknown",Gr),T.on("mouse",Hr),Ue=setInterval(()=>{ba()},(r.github?.watchIntervalSeconds??5)*1e3),b.version.checkForUpdate().then(m=>{m.updateAvailable&&m.latest&&(an=`Update available: v${m.latest}`,y())});let Fa=Wr().catch(()=>{});y()})}async function ft(e,t,n){let r=Re(e),[s,o,i]=await Promise.all([Z.repos.listRegisteredRepos(r).then(p=>p.repos),re(r),he(r)]),c=pa(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=c?await Ao(c,l):null;return{workspaceRoot:e,workspaces:o.filter(p=>p.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 Rf(e,t){return Bt(e,t)}function Tf(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 yf(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 Pf(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"?Sf(s):[];return r?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:bf(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function bf(e,t){let n=(e??"").split(Qe.delimiter).filter(r=>r.length>0);return n.includes(t)?n.join(Qe.delimiter):[...n,t].join(Qe.delimiter)}function Sf(e){return e.command.length>0?e.command:["codex"]}function mt(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function If(e,t,n){return e.ptyTabs.find(r=>r.id===t)?.kind??n}function la(e,t,n,r={}){let s=n??e.runner,o=b.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",c=t==="agent"&&n&&n!==e.runner?`${e.id}:${n}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(k=>k.id)),d=1,p=c;for(;l.has(p);)d+=1,p=`${c}-${d}`;let h=new Date().toISOString(),R=n&&n!==e.runner?n:void 0;return{id:p,kind:t,...R?{runner:R}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?b.runners.buildCommand(s,void 0,r):[],createdAt:h,updatedAt:h}}async function Cf(e,t,n,r,s){let o=await b.load(e);b.runners.assertEnabled(s,o);let i=n?await vt(e,n,r,{runner:s,config:o}):await rt(e,t??"",r,{runner:s,config:o});try{let d=Le();await v(je(b.runners.getConfiguredProfile(s,o).executable,{cwd:i.repoRoot,env:d}),["--help"],{cwd:i.repoRoot,env:d})}catch(d){let p=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:p};throw await A(e,h),new nn(p,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 A(e,l),await H({uiStateFile:e.uiStateFile},{...await Y({uiStateFile:e.uiStateFile})??ge(),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 nn=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 gt(e){return{columns:Math.max(20,e.width-pe.leftWidth-pe.rightWidth-pe.dividerWidth-Xt*2),rows:Math.max(5,e.height-pe.topRailHeight-5)}}function xf(e){return e.split(`
|
|
161
|
+
`).map((t,n)=>`\x1B[${n+1};1H${t}`).join("")}function vf(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Ef(e){return e.length===1||Pe(e)||e==="BACKSPACE"||e==="TAB"}function Or(e){return typeof e=="string"&&new RegExp(`:(?:agent|${j.join("|")})(?:-\\d+)?$`).test(e)}function Af(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 da(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function $f(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 Df(e){return e==="\x1B[13;2u"?"SHIFT_ENTER":null}function Mf(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
|
|
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 Lf(e){let t=await mf(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory())continue;let s=Qe.join(e,r.name);n.push({name:r.name,path:s,kind:await Of(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 jf(e){let{spawn:t}=await import("node:child_process"),n=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((r,s)=>{let o=t(n,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",r)})}async function Of(e){let t=Qe.join(e,".git");return await gf(t).catch(()=>null)!==null}function rn(){return process.cwd()}async function Ff(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??rn(),c=Re(i);return await Wi(c),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??rn(),c=Re(i);return await _i(c),0}let e=is(process.argv.slice(2)),t=rn(),n=Re(t),r={paths:n};if(e.mode==="interactive")return await ua({uiStateFile:n.uiStateFile,workspaceRoot:n.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await Io(e.command,r),o=Co(s);return o.length>0&&process.stdout.write(`${o}
|
|
164
164
|
`),0}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
|
|
165
|
-
`),1}}var
|
|
165
|
+
`),1}}var Nf=await Ff();process.exit(Nf);
|