craig-cli 0.7.3 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +64 -64
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,38 +1,40 @@
1
1
  #!/usr/bin/env node
2
- var fc=Object.defineProperty;var $=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var An=(e,t)=>{for(var n in t)fc(e,n,{get:t[n],enumerable:!0})};var F,Ye=$(()=>{"use strict";F=["codex","cursor","claude"]});var ps,ms=$(()=>{"use strict";ps={codex:{id:"codex",displayName:"Codex",executable:"codex",defaultAgentTitle:"Codex"},cursor:{id:"cursor",displayName:"Cursor",executable:"cursor-agent",defaultAgentTitle:"Cursor"},claude:{id:"claude",displayName:"Claude",executable:"claude",defaultAgentTitle:"Claude"}}});var Je,vt=$(()=>{"use strict";ms();Je=e=>ps[e]});var Et,$n=$(()=>{"use strict";vt();Et=(e,t={})=>{let n=Je(e),r=t.runners?.[e]?.path?.trim();return{...n,executable:r&&r.length>0?r:n.executable}}});var At,Dn=$(()=>{"use strict";Ye();At=(e={})=>F.filter(t=>e.runners?.[t]?.enabled!==!1)});var gs,hs=$(()=>{"use strict";Dn();gs=(e={})=>{let t=At(e);if(t.length===0)throw new Error("No runners are enabled. Enable at least one runner in .craig/config.json.");return t.includes("codex")?"codex":t[0]}});var ws,ks=$(()=>{"use strict";ws=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)}});var $t,Mn=$(()=>{"use strict";Ye();$t=e=>F.includes(e)});var Rs,Ts=$(()=>{"use strict";Ye();Mn();Rs=e=>{if(!e||e.length===0)return"codex";if(!$t(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${F.join(", ")}.`);return e}});var ys,Ps=$(()=>{"use strict";vt();ys=e=>Je(e).displayName});var bs,Is=$(()=>{"use strict";$n();bs=(e,t,n={})=>{let r=[Et(e,n).executable];return t&&t.length>0&&r.push(t),r}});var Ln={};An(Ln,{RUNNER_IDS:()=>F,assertEnabled:()=>ws,buildCommand:()=>bs,getConfiguredProfile:()=>Et,getDefault:()=>gs,getDisplayName:()=>ys,getEnabled:()=>At,getProfile:()=>Je,isRunnerType:()=>$t,parse:()=>Rs});var On=$(()=>{"use strict";Ye();vt();$n();Dn();hs();ks();Mn();Ts();Ps();Is()});import{mkdir as pc,readFile as mc,writeFile as gc}from"node:fs/promises";import hc from"node:path";var wc,Ss,Cs,Fn=$(()=>{"use strict";wc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Ss=async e=>{try{return await mc(e,"utf8")}catch(t){if(wc(t))return null;throw t}},Cs=async(e,t)=>{await pc(hc.dirname(e),{recursive:!0}),await gc(e,t,"utf8")}});var Dt,jn=$(()=>{"use strict";Ye();Dt=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let n=e;if(n.runners!==void 0){if(typeof n.runners!="object"||n.runners===null||Array.isArray(n.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[r,s]of Object.entries(n.runners)){if(!F.includes(r))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" is not supported. Expected one of: ${F.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${r}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${r}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${r}.path" must be a non-empty string.`)}}if(n.checks!==void 0&&(typeof n.checks!="object"||n.checks===null||!Array.isArray(n.checks.commands)||!n.checks.commands.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(n.open!==void 0&&(typeof n.open!="object"||n.open===null||!Array.isArray(n.open.command)||!n.open.command.every(r=>typeof r=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(n.github!==void 0){if(typeof n.github!="object"||n.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(n.github.mergeMethod!==void 0&&n.github.mergeMethod!=="merge"&&n.github.mergeMethod!=="rebase"&&n.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(n.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(n.github.watchIntervalSeconds)||n.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return n}});var Nn,xs=$(()=>{"use strict";Fn();jn();Nn=async(e,t={readConfigFile:Ss})=>{let n=await t.readConfigFile(e.configFile);if(!n)return{};if(n.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let r;try{r=JSON.parse(n)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Dt(r,e.configFile)}});var Wn,vs=$(()=>{"use strict";Fn();jn();Wn=async(e,t,n={writeConfigFile:Cs})=>{Dt(t,e.configFile),await n.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
3
- `)}});var Es=$(()=>{"use strict";xs();vs()});var Mt,_n=$(()=>{"use strict";Mt=()=>{try{return"0.7.3"}catch{return"unknown"}}});var kc,Rc,Tc,yc,As,$s=$(()=>{"use strict";_n();kc="https://registry.npmjs.org/craig-cli/latest",Rc=3600*1e3,Tc={value:null},yc=(e,t)=>{let n=d=>d.split(".").map(Number),[r=0,s=0,o=0]=n(e),[i=0,c=0,l=0]=n(t);return r!==i?r>i:s!==c?s>c:o>l},As=async(e={fetch:globalThis.fetch,getCurrent:Mt,cache:Tc})=>{let t=e.getCurrent(),n=Date.now();if(e.cache.value&&n-e.cache.value.cachedAt<Rc)return e.cache.value.result;let r=null;try{let o=await e.fetch(kc,{signal:AbortSignal.timeout(5e3)});o.ok&&(r=(await o.json()).version??null)}catch{}let s={current:t,latest:r,updateAvailable:r!==null&&r!==t&&yc(r,t)};return e.cache.value={result:s,cachedAt:n},s}});var Bn={};An(Bn,{checkForUpdate:()=>As,getCurrent:()=>Mt});var Ds=$(()=>{"use strict";_n();$s()});var b,ee=$(()=>{"use strict";On();Es();On();Ds();b={load:Nn,save:Wn,runners:Ln,version:Bn}});import{randomUUID as bc}from"node:crypto";import{open as Ic,readFile as wg,rename as Sc,rm as Cc}from"node:fs/promises";import Un from"node:path";async function B(e,t){let n=Un.dirname(e),r=Un.join(n,`.${Un.basename(e)}.${process.pid}.${Date.now()}.${bc()}.tmp`),s=await Ic(r,"w");try{let o=`${JSON.stringify(t,null,2)}
4
- `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await Sc(r,e)}catch(o){throw await s.close().catch(()=>{}),await Cc(r,{force:!0}).catch(()=>{}),o}}var ke=$(()=>{"use strict"});import{readFile as Mc}from"node:fs/promises";async function oe(e){let t=await Mc(e.indexFile,"utf8"),n=JSON.parse(t);return Kn(n,e.workspaceRoot,e.indexFile)}async function Ne(e,t){let n={...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()};await B(e.indexFile,n)}function Kn(e,t,n){if(!Lc(e))throw new Error(`Craig index at ${n} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${n} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e}function Lc(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(n=>typeof n=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(n=>typeof n=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(n=>typeof n=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}var We=$(()=>{"use strict";ke()});import{readFile as Oc}from"node:fs/promises";async function U(e,t){let n=await Oc(Vn(e,t),"utf8"),r=JSON.parse(n);return Fc(r,Vn(e,t))}async function A(e,t){let n={...t,updatedAt:new Date().toISOString()};await B(Vn(e,t.id),n)}async function Gn(e,t){let n=await oe(e);n.taskIds.includes(t)||await Ne(e,{...n,taskIds:[...n.taskIds,t]})}function Vn(e,t){return`${e.tasksDir}/${t}.json`}function Fc(e,t){let n=jc(e);if(!Wc(n))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function jc(e){if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Hn(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[],ptyTabs:Uc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:_c(t.repoTargets),runnerSession:t.runnerSession??Nc(t),checks:Yc(t),lastCommit:t.lastCommit??null,prs:Jc(t),artifacts:el(t),cleanup:tl(t)}}function Nc(e){if(typeof e.title!="string")return null;let t=Hn(e.runner);return{command:b.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}}function Wc(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&b.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(n=>typeof n=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&Os(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||Bc(t.repoTargets))&&Kc(t.runnerSession)&&Vc(t.prompt)&&Fs(t.checks)&&js(t.lastCommit)&&Hc(t.prs)&&zc(t.artifacts)&&Ws(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"}function _c(e){if(Array.isArray(e))return e.filter(Ls)}function Bc(e){return Array.isArray(e)&&e.every(Ls)}function Ls(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&Fs(t.checks)&&js(t.lastCommit)&&Ns(t.pullRequest)&&Ws(t.cleanup)}function Uc(e){if(Os(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return qc(e.id,e.title,t,Hn(e.runner))}function qc(e,t,n,r){let s=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:b.runners.buildCommand(r),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function Hn(e){return e&&b.runners.isRunnerType(e)?e:"codex"}function Os(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(n=>typeof n=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string")}function Kc(e){return typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null)}function Vc(e){return typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string"}function Fs(e){return typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number")}function js(e){return e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string"}function Ns(e){return typeof e=="object"&&e!==null&&e.provider==="github"&&Gc(e.requiredChecks)}function Gc(e){return Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null))}function Hc(e){return Array.isArray(e)&&e.every(Ns)}function zc(e){return typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null)}function Ws(e){return typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null)}function Yc(e){return e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]}}function Jc(e){if(Array.isArray(e.prs))return e.prs.map(Qc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:_s(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Bs(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]}function Qc(e){let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:_s(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Xc(t.reviewDecision),requiredChecks:Bs(t.requiredChecks),comments:Zc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}}function _s(e){return e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null}function Xc(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Zc(e){return Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let n=t;return typeof n.body!="string"||!n.body.trim()?[]:[{author:typeof n.author=="string"?n.author:null,body:n.body,createdAt:typeof n.createdAt=="string"?n.createdAt:null,url:typeof n.url=="string"?n.url:null}]}):[]}function Bs(e){return Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[]}function el(e){let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}}function tl(e){return e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}var ie=$(()=>{"use strict";ke();We();ee()});import{readFile as nl}from"node:fs/promises";async function ue(e){try{let t=await nl(e.uiStateFile,"utf8"),n=JSON.parse(t);return rl(n,e.uiStateFile)}catch(t){if(ol(t))return null;throw t}}async function ae(e,t){await B(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Re(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function rl(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!Xe(e,"inputMode")||!Xe(e,"focusedRegion")||!Xe(e,"activeTab")||!Xe(e,"inspectorSection")||!Xe(e,"inspectionMode")||!Lt(e,"openInspectionKind")||!Lt(e,"selectedFileTreePath")||!Lt(e,"selectedFilePath")||!Lt(e,"selectedDiffPath")||!sl(e,"collapsedFileTreePaths")||!Xe(e,"selectedActionId")||typeof e.updatedAt!="string")throw new Error(`Craig UI state at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}function Xe(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Lt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function sl(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(n=>typeof n=="string"))}function ol(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Ze=$(()=>{"use strict";ke()});import{execFile as il}from"node:child_process";import{promisify as al}from"node:util";async function v(e,t,n={}){try{let r=await Us(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr}}catch(r){if(qs(r)){let s=r.stderr?.trim()||r.stdout?.trim()||r.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw r}}async function L(e,t,n={}){try{let r=await Us(e,t,{cwd:n.cwd,env:n.env});return{stdout:r.stdout,stderr:r.stderr,exitCode:0}}catch(r){if(qs(r))return{stdout:r.stdout??"",stderr:r.stderr??"",exitCode:typeof r.code=="number"?r.code:null};throw r}}function qs(e){return e instanceof Error}var Us,ce=$(()=>{"use strict";Us=al(il)});import{readFile as bl,readdir as Il,rm as Sl}from"node:fs/promises";import Zs from"node:path";async function fe(e,t){let n=await bl(jt(e,t),"utf8"),r=JSON.parse(n);return Cl(r,jt(e,t))}async function Nt(e,t){await B(jt(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function Ue(e){let t=await Il(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>fe(e,Zs.basename(r.name,".json"))))).sort((r,s)=>r.name.localeCompare(s.name)||r.id.localeCompare(s.id))}async function eo(e,t){await Sl(jt(e,t),{force:!0})}function jt(e,t){return Zs.join(e.reposDir,`${t}.json`)}function Cl(e,t){if(typeof e!="object"||e===null||typeof e.id!="string"||typeof e.name!="string"||typeof e.rootPath!="string"||typeof e.defaultBranch!="string"||typeof e.createdAt!="string"||typeof e.updatedAt!="string")throw new Error(`Craig repo record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}var qe=$(()=>{"use strict";ke()});import{readFile as xl,readdir as vl,rm as El}from"node:fs/promises";import to from"node:path";async function ct(e,t){let n=await xl(Wt(e,t),"utf8"),r=JSON.parse(n);return Al(r,Wt(e,t))}async function et(e,t){await B(Wt(e,t.id),{...t,updatedAt:new Date().toISOString()})}async function pe(e){let t=await vl(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>ct(e,to.basename(r.name,".json"))))).sort((r,s)=>r.id.localeCompare(s.id))}async function no(e,t){await El(Wt(e,t),{force:!0})}function Wt(e,t){return to.join(e.workspacesDir,`${t}.json`)}function Al(e,t){let n=$l(e);if(typeof n!="object"||n===null||typeof n.id!="string"||n.kind!=="repo"&&n.kind!=="project"||typeof n.name!="string"||typeof n.rootPath!="string"||typeof n.primaryRepoId!="string"||typeof n.branch!="string"||n.status!=="active"&&n.status!=="archived"||!Array.isArray(n.linkedRepoIds)||!(n.linkedRepoIds??[]).every(r=>typeof r=="string")||!(n.repoId===void 0||typeof n.repoId=="string")||!Array.isArray(n.discoveredRepoIds)||!(n.discoveredRepoIds??[]).every(r=>typeof r=="string")||!(n.archivedAt===null||typeof n.archivedAt=="string")||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function $l(e){if(typeof e!="object"||e===null)return e;let t=e,n=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??n??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??n??"",repoId:t.kind==="project"?t.repoId:n,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(r=>typeof r=="string"):t.kind==="project"?[]:n?[n]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[]}}var lt=$(()=>{"use strict";ke()});async function Te(e,t){let n=await oe(e),r=[],s=[];await Promise.all(n.taskIds.map(async c=>{try{r.push(await U(e,c))}catch(l){if(Wl(l)){s.push(c);return}throw l}}));let i=(t?.includeClosed?r:r.filter(c=>c.status!=="closed")).filter(c=>!(t?.workspaceId&&c.workspaceId!==t.workspaceId||t?.repoId&&c.repoId!==t.repoId&&!(c.repoTargets??[]).some(l=>l.repoId===t.repoId)));return i.sort((c,l)=>c.id.localeCompare(l.id)),s.sort(),{kind:"listTasks",tasks:i,missingTaskIds:s,repoId:t?.repoId??null}}function Wl(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var ft=$(()=>{"use strict";We();ie()});var Ho={};An(Ho,{addWorkspace:()=>gt,archiveWorkspace:()=>ht,listWorkspaces:()=>gr,removeWorkspace:()=>wt,removeWorkspaceRecord:()=>Jt,restoreWorkspace:()=>hr});import{readdir as bd,realpath as Wo,stat as Id}from"node:fs/promises";import $e from"node:path";async function gt(e,t){let n=$e.resolve(e.workspaceRoot,t);if(!(await Id(n).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${n}`);return await Ko(n)?Sd(e,n):Cd(e,n)}async function gr(e,t){return{kind:"listWorkspaces",workspaces:(await pe(e)).filter(r=>r.status===(t.archived?"archived":"active")),archivedOnly:t.archived}}async function ht(e,t){let r={...await ct(e,t),status:"archived",archivedAt:new Date().toISOString()};return await et(e,r),await Go(e,t),{kind:"archiveWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function hr(e,t){let r={...await ct(e,t),status:"active",archivedAt:null};await et(e,r);let s=await ue({uiStateFile:e.uiStateFile})??null;return await ae({uiStateFile:e.uiStateFile},{...s??Re(),selectedWorkspaceId:r.id,selectedRepoId:r.kind==="project"?r.discoveredRepoIds?.[0]??null:r.primaryRepoId,selectedTaskId:null}),{kind:"restoreWorkspace",workspaceId:r.id,status:r.status,branch:r.branch}}async function wt(e,t){let n=await ct(e,t),r=await Te(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(r.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await Jt(e,t),await Go(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}}async function Sd(e,t){let n=await Vo(t),r=await Ue(e),s=r.find(h=>h.rootPath===t)??null,o=s?Bo(s,n):_o(r,t,n),i=`workspace_${o.id}`,l=(await pe(e)).find(h=>h.id===i)??null,d=new Date().toISOString(),f=l??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:n,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await Nt(e,o),l||await et(e,f),await Uo(e,{repoIds:[o.id],workspaceIds:[f.id]}),await qo(e,f,o.id),{kind:"createWorkspace",workspace:f,repos:[o],created:!l}}async function Cd(e,t){let n=await xd(e,t);if(n.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let r=await pe(e),s=Ed(r,$e.basename(t)),o=r.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),c=n.map(d=>d.id),l=o?{...o,discoveredRepoIds:c,primaryRepoId:c[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:$e.basename(t),rootPath:t,primaryRepoId:c[0]??"",discoveredRepoIds:c,branch:"project",status:"active",linkedRepoIds:c,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(n.map(d=>Nt(e,d))),await et(e,l),await Uo(e,{repoIds:c,workspaceIds:[l.id]}),await qo(e,l,c[0]??null),{kind:"createWorkspace",workspace:l,repos:n,created:!o}}async function xd(e,t){let n=await bd(t,{withFileTypes:!0}),r=await Ue(e),s=[];for(let o of n){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=$e.join(t,o.name);if(!await Ko(i))continue;let c=r.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await Vo(i);s.push(c?Bo(c,l):_o([...r,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))}function _o(e,t,n){let r=new Date().toISOString();return{id:vd(e,$e.basename(t)),name:$e.basename(t),rootPath:t,defaultBranch:n,createdAt:r,updatedAt:r}}function Bo(e,t){return e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()}}function vd(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",r=`repo_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`repo_${n}_${s}`,s+=1;return r}function Ed(e,t){let n=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",r=`workspace_${n}`,s=2;for(;e.some(o=>o.id===r);)r=`workspace_${n}_${s}`,s+=1;return r}async function Uo(e,t){let n=await oe(e);await Ne(e,{...n,repoIds:[...new Set([...n.repoIds,...t.repoIds])],workspaceIds:[...new Set([...n.workspaceIds,...t.workspaceIds])]})}async function qo(e,t,n){await ae({uiStateFile:e.uiStateFile},{...await ue({uiStateFile:e.uiStateFile})??Re(),selectedRepoId:n,selectedWorkspaceId:t.id,selectedTaskId:null})}async function Ko(e){try{let n=(await v("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[r,s]=await Promise.all([Wo(n).catch(()=>$e.resolve(n)),Wo(e).catch(()=>$e.resolve(e))]);return r===s}catch{return!1}}async function Vo(e){let t=await L("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),n=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&n.length>0)return n;for(let o of["main","master","trunk"])if((await L("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await v("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"}async function Jt(e,t){await no(e,t);let n=await oe(e);await Ne(e,{...n,workspaceIds:n.workspaceIds.filter(r=>r!==t)})}async function Go(e,t){let n=await ue({uiStateFile:e.uiStateFile});!n||n.selectedWorkspaceId!==t||await ae({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}var kt=$(()=>{"use strict";We();qe();lt();Ze();ce();ft()});ee();function Ms(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Repo path cannot be empty.
2
+ var cl=Object.defineProperty;var Lr=(e,t)=>{for(var r in t)cl(e,r,{get:t[r],enumerable:!0})};var jr={};Lr(jr,{RUNNER_IDS:()=>N,assertEnabled:()=>$s,buildCommand:()=>Ms,getConfiguredProfile:()=>Ot,getDefault:()=>Ds,getDisplayName:()=>js,getEnabled:()=>Nt,getProfile:()=>Qe,isRunnerType:()=>Ft,parse:()=>Ls});var N=["codex","cursor","claude"];var As={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 Qe=e=>As[e];var Ot=(e,t={})=>{let r=Qe(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var Nt=(e={})=>N.filter(t=>e.runners?.[t]?.enabled!==!1);var Ds=(e={})=>{let t=Nt(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 $s=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var Ft=e=>N.includes(e);var Ls=e=>{if(!e||e.length===0)return"codex";if(!Ft(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${N.join(", ")}.`);return e};var js=e=>Qe(e).displayName;var Ms=(e,t,r={})=>{let n=[Ot(e,r).executable];return t&&t.length>0&&n.push(t),n};import{mkdir as dl,readFile as ul,writeFile as pl}from"node:fs/promises";import fl from"node:path";var ml=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Os=async e=>{try{return await ul(e,"utf8")}catch(t){if(ml(t))return null;throw t}},Ns=async(e,t)=>{await dl(fl.dirname(e),{recursive:!0}),await pl(e,t,"utf8")};var Wt=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let r=e;if(r.runners!==void 0){if(typeof r.runners!="object"||r.runners===null||Array.isArray(r.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[n,s]of Object.entries(r.runners)){if(!N.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" 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.${n}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${n}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${n}.path" must be a non-empty string.`)}}if(r.checks!==void 0&&(typeof r.checks!="object"||r.checks===null||!Array.isArray(r.checks.commands)||!r.checks.commands.every(n=>typeof n=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(r.open!==void 0&&(typeof r.open!="object"||r.open===null||!Array.isArray(r.open.command)||!r.open.command.every(n=>typeof n=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(r.github!==void 0){if(typeof r.github!="object"||r.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(r.github.mergeMethod!==void 0&&r.github.mergeMethod!=="merge"&&r.github.mergeMethod!=="rebase"&&r.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(r.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(r.github.watchIntervalSeconds)||r.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}return r};var Mr=async(e,t={readConfigFile:Os})=>{let r=await t.readConfigFile(e.configFile);if(!r)return{};if(r.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let n;try{n=JSON.parse(r)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Wt(n,e.configFile)};var Or=async(e,t,r={writeConfigFile:Ns})=>{Wt(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
3
+ `)};var Nr={};Lr(Nr,{checkForUpdate:()=>Fs,getCurrent:()=>_t});var _t=()=>{try{return"0.7.5"}catch{return"unknown"}};var gl="https://registry.npmjs.org/craig-cli/latest",hl=3600*1e3,kl={value:null},wl=(e,t)=>{let r=d=>d.split(".").map(Number),[n=0,s=0,o=0]=r(e),[i=0,l=0,c=0]=r(t);return n!==i?n>i:s!==l?s>l:o>c},Fs=async(e={fetch:globalThis.fetch,getCurrent:_t,cache:kl})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<hl)return e.cache.value.result;let n=null;try{let o=await e.fetch(gl,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&wl(n,t)};return e.cache.value={result:s,cachedAt:r},s};var S={load:Mr,save:Or,runners:jr,version:Nr};function Ws(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let r=t.slice(2).join(" ").trim();if(r.length===0)throw new Error(`Repo path cannot be empty.
5
4
 
6
- `+J());return{mode:"command",command:{kind:"addRepo",path:n}}}if(t.length>=3&&t[0]==="workspace"&&t[1]==="add"){let n=t.slice(2).join(" ").trim();if(n.length===0)throw new Error(`Workspace path cannot be empty.
5
+ `+Z());return{mode:"command",command:{kind:"addRepo",path:r}}}if(t.length>=3&&t[0]==="workspace"&&t[1]==="add"){let r=t.slice(2).join(" ").trim();if(r.length===0)throw new Error(`Workspace path cannot be empty.
7
6
 
8
- `+J());return{mode:"command",command:{kind:"addWorkspace",path:n}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let n=t[2]==="--archived";if(t.length===3&&!n)throw new Error(`Unsupported command: ${t.join(" ")}
7
+ `+Z());return{mode:"command",command:{kind:"addWorkspace",path:r}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let r=t[2]==="--archived";if(t.length===3&&!r)throw new Error(`Unsupported command: ${t.join(" ")}
9
8
 
10
- ${J()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:n}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let n=t.indexOf("--repo"),r=t.indexOf("--workspace"),s=t.indexOf("--runner");if(n===-1&&r===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
9
+ ${Z()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:r}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let r=t.indexOf("--repo"),n=t.indexOf("--workspace"),s=t.indexOf("--runner");if(r===-1&&n===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
11
10
 
12
- `+J());if(n!==-1&&r!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
11
+ `+Z());if(r!==-1&&n!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
13
12
 
14
- `+J());let o=n===-1?void 0:t[n+1]?.trim()??"",i=r===-1?void 0:t[r+1]?.trim()??"",c=s===-1?void 0:b.runners.parse(t[s+1]?.trim()??""),d=t.filter((f,h)=>h>1&&h!==n&&h!==n+1&&h!==r&&h!==r+1&&h!==s&&h!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
13
+ `+Z());let o=r===-1?void 0:t[r+1]?.trim()??"",i=n===-1?void 0:t[n+1]?.trim()??"",l=s===-1?void 0:S.runners.parse(t[s+1]?.trim()??""),d=t.filter((u,g)=>g>1&&g!==r&&g!==r+1&&g!==n&&g!==n+1&&g!==s&&g!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
15
14
 
16
- `+J());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
15
+ `+Z());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
17
16
 
18
- `+J());if(d.length===0)throw new Error(`Task prompt cannot be empty.
17
+ `+Z());if(d.length===0)throw new Error(`Task prompt cannot be empty.
19
18
 
20
- `+J());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:d,...c?{runner:c}:{}}}}if(t.length>=2&&t.length<=4&&t[0]==="task"&&t[1]==="list"){if(t.length===2)return{mode:"command",command:{kind:"listTasks"}};if(t.length===4&&t[2]==="--repo")return{mode:"command",command:{kind:"listTasks",repoId:t[3].trim()}};throw new Error(`Unsupported command: ${t.join(" ")}
19
+ `+Z());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:d,...l?{runner:l}:{}}}}if(t.length>=2&&t.length<=4&&t[0]==="task"&&t[1]==="list"){if(t.length===2)return{mode:"command",command:{kind:"listTasks"}};if(t.length===4&&t[2]==="--repo")return{mode:"command",command:{kind:"listTasks",repoId:t[3].trim()}};throw new Error(`Unsupported command: ${t.join(" ")}
21
20
 
22
- ${J()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:we(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:we(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:we(t[2]),repoId:Pc(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:we(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
21
+ ${Z()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:ke(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:ke(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:ke(t[2]),repoId:Rl(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:ke(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
23
22
 
24
- ${J()}`)}function J(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
25
- `)}function we(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
23
+ ${Z()}`)}function Z(){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 ke(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
26
25
 
27
- ${J()}`);return t}function Pc(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
26
+ ${Z()}`);return t}function Rl(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
28
27
 
29
- ${J()}`);return t}ee();import ho from"node:path";ke();import{readFile as xc,readdir as yg,rm as Pg}from"node:fs/promises";import vc from"node:path";async function Qe(e,t){let n=await xc(qn(e,t),"utf8"),r=JSON.parse(n);return Ec(r,qn(e,t))}async function je(e,t){await B(qn(e,t.id),{...t,updatedAt:new Date().toISOString()})}function qn(e,t){return vc.join(e.sessionsDir,`${t}.json`)}function Ec(e,t){let n=Dc(e);if(typeof n!="object"||n===null||typeof n.id!="string"||typeof n.taskId!="string"||typeof n.repoId!="string"||typeof n.workspaceId!="string"||n.substrate!=="tmux"||typeof n.sessionName!="string"||typeof n.paneId!="string"||!(n.windowTarget===null||typeof n.windowTarget=="string")||typeof n.worktreePath!="string"||!(n.logPath===null||typeof n.logPath=="string")||!Array.isArray(n.command)||!n.command.every(r=>typeof r=="string")||!["starting","running","exited","failed"].includes(n.status)||!(n.startedAt===null||typeof n.startedAt=="string")||!(n.exitedAt===null||typeof n.exitedAt=="string")||!(n.exitCode===null||typeof n.exitCode=="number")||!(n.lastAttachedAt===null||typeof n.lastAttachedAt=="string")||!$c(n.attach)||!Ac(n.snapshot)||typeof n.createdAt!="string"||typeof n.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return n}function Ac(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function $c(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function Dc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(n=>typeof n=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}ie();Ze();ce();function Ot(e){return`'${e.replace(/'/g,"'\\''")}'`}import{accessSync as cl,constants as ll}from"node:fs";import{homedir as Ks}from"node:os";import Ae from"node:path";var dl=[Ae.join(Ks(),".local","bin"),Ae.join(Ks(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Gs(e=process.env){return ul([...(e.PATH??"").split(Ae.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:dl])}function _e(e=process.env){return{...e,PATH:Gs(e).join(Ae.delimiter)}}function zn(e,t={}){if(e.includes(Ae.sep)){let n=Ae.isAbsolute(e)?e:Ae.resolve(t.cwd??process.cwd(),e);return Vs(n)?n:null}for(let n of Gs(t.env)){let r=Ae.join(n,e);if(Vs(r))return r}return null}function Be(e,t={}){let n=zn(e,t);if(n)return n;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function Vs(e){try{return cl(e,ll.X_OK),!0}catch{return!1}}function ul(e){return[...new Set(e)]}ee();ce();import{spawn as fl}from"node:child_process";import{createHash as pl}from"node:crypto";import ml from"node:path";var gl="craig";async function Hs(e,t,n){let r=Yn(e,t),s=wl(),o=await v("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",r,"-n","runner",...s,"-c",n],{cwd:e}),i=Rl(o.stdout);return await hl(e,r),i}async function hl(e,t){let n=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let r of n)await v("tmux",r,{cwd:e})}async function zs(e,t,n){await v("tmux",["resize-window","-t",t,"-x",`${n.columns}`,"-y",`${n.rows}`],{cwd:e})}async function Ys(e,t,n){await v("tmux",["send-keys","-t",e,t,"C-m"],{cwd:n})}async function Js(e,t,n){await v("tmux",["pipe-pane","-o","-t",e,`cat >> ${Ot(t)}`],{cwd:n})}async function Ft(e,t,n,r){let s=r??Qs(e);if(n?await v("tmux",["select-window","-t",n],{cwd:e}):await v("tmux",["select-window","-t",t],{cwd:e}),await v("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await v("tmux",["switch-client","-t",s],{cwd:e});return}await yl(e,["attach-session","-t",s])}function Qs(e){let n=ml.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",r=pl("sha1").update(e).digest("hex").slice(0,8);return`${gl}-${n}-${r}`}function Yn(e,t){return`${Qs(e)}-${t.toLowerCase()}`}function wl(){let e=kl();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]}function kl(){let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let n="columns"in t?t.columns:void 0,r="rows"in t?t.rows:void 0;if(typeof n=="number"&&n>0&&typeof r=="number"&&r>0)return{columns:n,rows:r}}return null}function Rl(e){let t=Tl(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}}function Tl(e){return e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0)}async function yl(e,t){await new Promise((n,r)=>{let s=fl("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",r),s.on("exit",o=>{if(o===0){n();return}r(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})}var Jn={async prepare(e,t){let n=e.runnerSession.command[0]??b.runners.buildCommand(e.runner)[0],r=_e();await v(Be(n,{cwd:t.repoRoot,env:r}),["--help"],{cwd:t.repoRoot,env:r})},async launch(e,t){let n=e.runnerSession.command.length>0?e.runnerSession.command:b.runners.buildCommand(e.runner,e.prompt.value),r=Be(n[0],{cwd:e.worktreePath,env:_e()});await Ys(t.session.paneId,[r,...n.slice(1)].map(s=>Ot(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}};ce();var at={async create(e,t){let n=await Hs(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await Js(n.paneId,t.logPath,t.repoRoot);let r=await Xs({paneId:n.paneId,windowTarget:n.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:n.sessionName||Yn(t.repoRoot,t.taskId),paneId:n.paneId,windowTarget:n.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:r,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await je(e,s),s},async attach(e,t,n){let r=await at.snapshot(t,n);if(!r.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Ft(n,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:r};return await je(e,s),s},async resize(e,t,n,r){await zs(r,t.sessionName,n);let s={...t,attach:{...t.attach,lastSize:n}};return await je(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,n){let r={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:(n.length>0,t.command)};return await je(e,r),r},async snapshot(e,t){return Pl(e,t)}};async function Pl(e,t){let n=await L("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Xs({paneId:e.paneId,windowTarget:e.windowTarget,alive:n.exitCode===0&&n.stdout.split(/\s+/).some(r=>r.trim()===e.paneId)})}async function Xs(e){return{paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()}}qe();ie();ee();lt();import{mkdir as dt,rm as Ml,writeFile as Bt}from"node:fs/promises";import M from"node:path";ce();async function ro(e,t){let n=await L("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(n.exitCode===0)return!0;if(n.exitCode===1)return!1;throw new Error(n.stderr.trim()||n.stdout.trim()||"Unable to check git branch state.")}async function Qn(e,t,n,r="main"){let s=r.trim()||"main";if((await L("git",["show-ref","--verify","--quiet",`refs/heads/${s}`],{cwd:e})).exitCode!==0)throw new Error(`Base branch '${s}' does not exist locally.`);let i=await Dl(e,s);await v("git",["worktree","add","-b",t,n,i],{cwd:e})}async function Dl(e,t){return(await L("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await L("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await L("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t}async function _t(e){let t=await L("git",["status","--short"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"Unable to inspect git status.");return t.stdout.trim().length>0}async function so(e){await v("git",["add","-A"],{cwd:e})}async function oo(e,t){await v("git",["commit","-m",t],{cwd:e})}async function io(e){let t=await v("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[n="",r=""]=t.stdout.trim().split(`
30
- `);if(!n||!r)throw new Error("Unable to read git HEAD commit metadata.");return{sha:n,message:r}}We();async function ao(e,t){let n=await oe(e),r=lo(new Date),s=uo(n.taskIds,r);for(;;){let o=`task_${r}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await ro(t,i))return o;s+=1}}async function co(e){let t=await oe(e),n=lo(new Date),r=uo(t.taskIds,n);return`task_${n}_${String(r).padStart(2,"0")}`}function lo(e){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}${n}${r}`}function uo(e,t){let n=e.filter(r=>r.startsWith(`task_${t}_`)).map(r=>Number.parseInt(r.slice(-2),10)).filter(r=>Number.isInteger(r));return n.length===0?1:Math.max(...n)+1}var po=["AGENTS","md"].join(".");async function ut(e,t,n,r={}){let s=await fe(e,t),o=await Nl(e,s.id),i=await ao(e,s.rootPath),c=r.sessionId??null,l=`craig/${i}`,d=M.join(e.worktreesDir,s.id,i),f=M.join(e.logsDir,`${i}.log`),h=M.join(e.artifactsDir,i);await dt(M.dirname(d),{recursive:!0}),await dt(h,{recursive:!0}),await Bt(f,"","utf8");let R=Ll(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:c,repoRoot:s.rootPath,prompt:n,runner:r.runner??"codex",config:r.config??{},branch:l,worktreePath:d});return await A(e,R),await Gn(e,i),await Qn(s.rootPath,l,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:c,workspaceId:o.id,task:R}}async function qt(e,t,n,r={}){let s=(await pe(e)).find(x=>x.id===t&&x.status==="active");if(!s)throw new Error(`Workspace ${t} does not exist or is archived.`);if(s.kind!=="project"){if(!s.primaryRepoId)throw new Error(`Workspace ${t} is not task-capable.`);let x=await ut(e,s.primaryRepoId,n,r);return{...x,bundlePath:x.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await co(e),c=new Date().toISOString(),l=r.runner??"codex",d=r.sessionId??null,f=`craig/${i}`,h=M.join(e.craigDir,"task-bundles",i),R=M.join(e.logsDir,`${i}.log`),k=M.join(e.artifactsDir,i);await dt(h,{recursive:!0}),await dt(k,{recursive:!0}),await Bt(R,"","utf8");let S=await Promise.all(o.map(x=>fe(e,x))),T=Fl(S),a=await Promise.all(S.map(x=>Ol(e,x,i,f,M.join(h,T.get(x.id))))),H=a.find(x=>x.status==="ready")??a[0];if(!a.some(x=>x.status==="ready"))throw await Ml(h,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${a.map(x=>`${x.repoId}: ${x.failureReason??"unknown error"}`).join("; ")}`);await Bt(M.join(h,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:n,repos:a.map(x=>({repoId:x.repoId,repoName:S.find(Oe=>Oe.id===x.repoId)?.name??x.repoId,path:M.relative(h,x.worktreePath),status:x.status,worktreePath:x.worktreePath,failureReason:x.failureReason}))},null,2),"utf8"),await Bt(M.join(h,po),jl({taskId:i,workspaceId:t,prompt:n,repos:S,repoTargets:a,bundlePath:h}),"utf8");let _=mo(i,n,c,l,r.config??{}),ne={id:i,title:n,slug:go(n),type:"project",status:"draft",runner:l,repoId:H.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:_[0]?.id??null,linkedRepoIds:o.filter(x=>x!==H.repoId),repoRoot:h,worktreePath:h,branch:f,bundlePath:h,selectedRepoTargetId:H.repoId,repoTargets:a,ptyTabs:_,runnerSession:{command:b.runners.buildCommand(l,n,r.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:n},checks:H.checks,lastCommit:null,prs:[],artifacts:{logPath:M.relative(e.workspaceRoot,R),checkSummaryPath:M.relative(e.workspaceRoot,M.join(k,"check-summary.json")),prDraftPath:null,prStatusPath:M.relative(e.workspaceRoot,M.join(k,"pr-status.json"))},cleanup:Ut(),lastFailureReason:a.every(x=>x.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:c,updatedAt:c};return await A(e,ne),await Gn(e,i),{repoId:H.repoId,repoRoot:h,sessionId:d,workspaceId:s.id,task:ne,bundlePath:h,repoTargets:a}}function mo(e,t,n,r="codex",s={}){let o=b.runners.getProfile(r);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:b.runners.buildCommand(r,void 0,s),createdAt:n,updatedAt:n},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:n,updatedAt:n}]}function Ll(e,t){let n=new Date().toISOString(),r=mo(t.taskId,t.prompt,n,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:go(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:r[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:r,runnerSession:{command:b.runners.buildCommand(t.runner,t.prompt,t.config),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:t.prompt},checks:{...Xn(M.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:M.relative(e.workspaceRoot,M.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:M.relative(e.workspaceRoot,M.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:M.relative(e.workspaceRoot,M.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:Ut(),lastFailureReason:null,createdAt:n,updatedAt:n}}async function Ol(e,t,n,r,s){await dt(M.dirname(s),{recursive:!0});try{return await Qn(t.rootPath,r,s,t.defaultBranch),{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:Xn(M.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:fo(),cleanup:Ut()}}catch(o){return{repoId:t.id,branch:r,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:o instanceof Error?o.message:"Failed to create worktree.",checks:Xn(M.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:fo(),cleanup:Ut()}}}function Fl(e){let t=new Set(["manifest.json",po]),n=new Map;for(let r of e){let s=t.has(r.name)?`${r.name}-repo`:r.name,o=s,i=2;for(;t.has(o);)o=`${s}-${i}`,i+=1;t.add(o),n.set(r.id,o)}return n}function jl(e){let t=new Map(e.repos.map(r=>[r.id,r.name])),n=e.repoTargets.map(r=>{let s=t.get(r.repoId)??r.repoId,o=M.relative(e.bundlePath,r.worktreePath),i=r.status==="ready"?"ready":`unavailable: ${r.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${r.repoId}, ${i})`}).join(`
31
- `);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 Xn(e){return{source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}}function fo(){return{provider:"github",number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}}function Ut(){return{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}}async function Nl(e,t){let r=(await pe(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!r)throw new Error(`Repo ${t} does not have an active workspace.`);return r}function go(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-")}async function wo(e,t,n,r={}){let s=n.trim(),o=await b.load(e),i=r.runner??b.runners.getDefault(o);if(b.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(r.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let c=r.workspaceId?await qt(e,r.workspaceId,s,{runner:i,config:o}):await ut(e,t,s,{runner:i,config:o}),l=c.task,d=b.runners.buildCommand(i,s,o),f=`session_${l.id}`,h=l.artifacts.logPath?ho.resolve(e.workspaceRoot,l.artifacts.logPath):ho.join(e.logsDir,`${l.id}.log`);try{await Jn.prepare(l,{repoRoot:c.repoRoot});let R=await at.create(e,{sessionId:f,taskId:l.id,repoId:c.repoId,workspaceId:c.workspaceId,repoRoot:c.repoRoot,worktreePath:l.worktreePath,logPath:h,command:d});await Jn.launch(l,{repoRoot:c.repoRoot,session:R});let k=new Date().toISOString();R={...R,status:"running",startedAt:k,command:d};let S={...l,status:"running",runner:i,sessionId:R.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:R.command,pid:null,startedAt:k,lastKnownState:"running",exitCode:null,exitedAt:null}};return await A(e,S),await je(e,R),await ae({uiStateFile:e.uiStateFile},{...await ue({uiStateFile:e.uiStateFile})??Re(),selectedRepoId:S.repoId,selectedWorkspaceId:S.workspaceId,selectedTaskId:S.id,selectedPtyTabId:S.selectedPtyTabId}),{kind:"createTask",taskId:S.id,repoId:S.repoId,workspaceId:S.workspaceId,sessionId:R.id,status:S.status,branch:S.branch,worktreePath:S.worktreePath,runner:S.runner}}catch(R){let k={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:R instanceof Error?R.message:"Unknown Craig error"};throw await A(e,k),R}}ft();qe();ie();import{access as cd}from"node:fs/promises";import $o from"node:path";ke();ie();ee();ce();import{mkdir as _l,readFile as Kh,writeFile as Vh}from"node:fs/promises";import Bl from"node:path";import ko from"node:path";function Kt(e,t){return t?ko.isAbsolute(t)?t:ko.join(e.repoRoot,t):null}function G(e){return e.prs.length===0?null:[...e.prs].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e.prs[e.prs.length-1]??null}function Ht(e){return e.status==="merged"||e.status==="closed"}function Ro(e,t){let n=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),r=n>=0?e.prs.map((s,o)=>o===n?t:s):[...e.prs,t];return{...e,prs:r}}var To=3,Ul=1e3,ql=1e4;async function pt(e){let t=await L("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")}async function tr(e,t){let n=G(t),r=n?.number?String(n.number):t.branch,s=await v("gh",Gt(r),{cwd:t.worktreePath}),o=JSON.parse(s.stdout);return rr(e,t,o,n)}async function nr(e,t){let n=await L("gh",Gt(t.branch),{cwd:t.worktreePath});if(n.exitCode!==0)return{discovered:!1,task:t};let r=JSON.parse(n.stdout);return{discovered:!0,task:await rr(e,t,r,null)}}async function Po(e){let t=await L("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:Ql(t.stdout.trim())}async function bo(e,t,n){if(n.length===0)return[];let r=Xl(n),s=await Kl(e,["api","graphql","-f",`query=${r}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return n.map((c,l)=>{let d=i[`item${l}`],f=Zl(d);return{id:c.id,found:f!==null,view:f}})}async function Kl(e,t){let n;for(let r=0;r<=To;r+=1)try{return await v("gh",t,{cwd:e})}catch(s){if(n=s,r===To||!Vl(s))throw s;await Hl(Gl(r))}throw n}function Vl(e){let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")}function Gl(e){let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||Ul,n=Math.min(t*2**e,ql),r=Math.floor(Math.random()*Math.max(1,Math.floor(n*.25)));return n+r}function Hl(e){return new Promise(t=>setTimeout(t,e))}async function mt(e,t,n){let r=n.pullRequest.number?String(n.pullRequest.number):n.branch;if(n.pullRequest.number){let i=await v("gh",Gt(r),{cwd:n.worktreePath}),c=er(JSON.parse(i.stdout));return n.pullRequest=c,await Zn(e,t,n.repoId,c),"synced"}let s=await L("gh",Gt(r),{cwd:n.worktreePath});if(s.exitCode!==0)return"not_found";let o=er(JSON.parse(s.stdout));return n.pullRequest=o,await Zn(e,t,n.repoId,o),"discovered"}async function Io(e,t,n){return rr(e,t,n,G(t))}async function So(e,t,n,r){return Zn(e,t,n,er(r))}async function Co(e,t){let n=Kt(e,t.artifacts.prStatusPath);n&&(await _l(Bl.dirname(n),{recursive:!0}),await B(n,{taskId:t.id,prs:t.prs}))}function zl(e){return e.mergeable&&!Yl(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}function Yl(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Jl(e){if(e.length===0)return"checked";let t=[...e].reverse().find(n=>n.status!=="merged"&&n.status!=="closed")??e[e.length-1];return zl(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"}function Gt(e){return["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"]}function Ql(e){let t=e.replace(/\.git$/,""),n=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let r=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null}function Xl(e){return`
28
+ ${Z()}`);return t}var G=(e,t)=>{let r=Fr(e);if(!yl(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},Fr=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Wr(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[],ptyTabs:Sl(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:Pl(t.repoTargets),runnerSession:t.runnerSession??Tl(t),checks:Dl(t),lastCommit:t.lastCommit??null,prs:$l(t),artifacts:Ol(t),cleanup:Nl(t)}},Tl=e=>{if(typeof e.title!="string")return null;let t=Wr(e.runner);return{command:S.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},yl=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&S.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(r=>typeof r=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&Bs(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||bl(t.repoTargets))&&Cl(t.runnerSession)&&xl(t.prompt)&&Us(t.checks)&&qs(t.lastCommit)&&El(t.prs)&&Al(t.artifacts)&&Vs(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Pl=e=>{if(Array.isArray(e))return e.filter(_s)},bl=e=>Array.isArray(e)&&e.every(_s),_s=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&Us(t.checks)&&qs(t.lastCommit)&&Ks(t.pullRequest)&&Vs(t.cleanup)},Sl=e=>{if(Bs(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 Il(e.id,e.title,t,Wr(e.runner))},Il=(e,t,r,n)=>{let s=S.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:S.runners.buildCommand(n),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Wr=e=>e&&S.runners.isRunnerType(e)?e:"codex",Bs=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"),Cl=e=>typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null),xl=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",Us=e=>typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number"),qs=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",Ks=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&vl(e.requiredChecks),vl=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null)),El=e=>Array.isArray(e)&&e.every(Ks),Al=e=>typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null),Vs=e=>typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null),Dl=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},$l=e=>{if(Array.isArray(e.prs))return e.prs.map(Ll);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:Gs(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Hs(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},Ll=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:Gs(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:jl(t.reviewDecision),requiredChecks:Hs(t.requiredChecks),comments:Ml(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},Gs=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,jl=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Ml=e=>Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let r=t;return typeof r.body!="string"||!r.body.trim()?[]:[{author:typeof r.author=="string"?r.author:null,body:r.body,createdAt:typeof r.createdAt=="string"?r.createdAt:null,url:typeof r.url=="string"?r.url:null}]}):[],Hs=e=>Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[],Ol=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},Nl=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as gc}from"node:fs/promises";import{randomUUID as Fl}from"node:crypto";import{open as Wl,readFile as kg,rename as _l,rm as Bl}from"node:fs/promises";import _r from"node:path";async function B(e,t){let r=_r.dirname(e),n=_r.join(r,`.${_r.basename(e)}.${process.pid}.${Date.now()}.${Fl()}.tmp`),s=await Wl(n,"w");try{let o=`${JSON.stringify(t,null,2)}
29
+ `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await _l(n,e)}catch(o){throw await s.close().catch(()=>{}),await Bl(n,{force:!0}).catch(()=>{}),o}}import{readFile as Ul,readdir as ql,rm as Kl}from"node:fs/promises";import zs from"node:path";var Br=(e,t)=>zs.join(e.workspacesDir,`${t}.json`),Vl=e=>{if(typeof e!="object"||e===null)return e;let t=e,r=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??r??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??r??"",repoId:t.kind==="project"?t.repoId:r,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(n=>typeof n=="string"):t.kind==="project"?[]:r?[r]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[]}},Ys=(e,t)=>{let r=Vl(e);if(typeof r!="object"||r===null||typeof r.id!="string"||r.kind!=="repo"&&r.kind!=="project"||typeof r.name!="string"||typeof r.rootPath!="string"||typeof r.primaryRepoId!="string"||typeof r.branch!="string"||r.status!=="active"&&r.status!=="archived"||!Array.isArray(r.linkedRepoIds)||!(r.linkedRepoIds??[]).every(n=>typeof n=="string")||!(r.repoId===void 0||typeof r.repoId=="string")||!Array.isArray(r.discoveredRepoIds)||!(r.discoveredRepoIds??[]).every(n=>typeof n=="string")||!(r.archivedAt===null||typeof r.archivedAt=="string")||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},Ne=async(e,t)=>{let r=Br(e,t),n=await Ul(r,"utf8");return Ys(JSON.parse(n),r)},Fe=async(e,t)=>{await B(Br(e,t.id),{...t,updatedAt:new Date().toISOString()})},ie=async e=>{let t=await ql(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Ne(e,zs.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},Qs=async(e,t)=>{await Kl(Br(e,t),{force:!0})};import{readFile as Gl,readdir as Hl,rm as zl}from"node:fs/promises";import Js from"node:path";var Ur=(e,t)=>Js.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},ue=async(e,t)=>{let r=Ur(e,t),n=await Gl(r,"utf8");return Xs(JSON.parse(n),r)},qr=async(e,t)=>{await B(Ur(e,t.id),{...t,updatedAt:new Date().toISOString()})},pt=async e=>{let t=await Hl(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>ue(e,Js.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Zs=async(e,t)=>{await zl(Ur(e,t),{force:!0})};import{readFile as Yl}from"node:fs/promises";var Ql=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(r=>typeof r=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(r=>typeof r=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(r=>typeof r=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Bt=(e,t,r)=>{if(!Ql(e))throw new Error(`Craig index at ${r} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${r} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e},ee=async e=>{let t=await Yl(e.indexFile,"utf8");return Bt(JSON.parse(t),e.workspaceRoot,e.indexFile)},ye=async(e,t)=>{await B(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as oc,stat as ic}from"node:fs/promises";import Ze from"node:path";import{readFile as Jl}from"node:fs/promises";async function J(e){try{let t=await Jl(e.uiStateFile,"utf8"),r=JSON.parse(t);return Xl(r,e.uiStateFile)}catch(t){if(ec(t))return null;throw t}}async function Y(e,t){await B(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function we(){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 Xl(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")||!Je(e,"inputMode")||!Je(e,"focusedRegion")||!Je(e,"activeTab")||!Je(e,"inspectorSection")||!Je(e,"inspectionMode")||!Ut(e,"openInspectionKind")||!Ut(e,"selectedFileTreePath")||!Ut(e,"selectedFilePath")||!Ut(e,"selectedDiffPath")||!Zl(e,"collapsedFileTreePaths")||!Je(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 Je(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Ut(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Zl(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function ec(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}import{realpath as ro}from"node:fs/promises";import no from"node:path";import{execFile as tc}from"node:child_process";import{promisify as rc}from"node:util";var eo=rc(tc);async function v(e,t,r={}){try{let n=await eo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(to(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function M(e,t,r={}){try{let n=await eo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(to(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function to(e){return e instanceof Error}var Kr=async e=>{try{let r=(await v("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([ro(r).catch(()=>no.resolve(r)),ro(e).catch(()=>no.resolve(e))]);return n===s}catch{return!1}},Vr=async e=>{let t=await M("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),r=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&r.length>0)return r;for(let o of["main","master","trunk"])if((await 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 Re,readFile as nc}from"node:fs/promises";import te from"node:path";function Pe(e){let t=te.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:te.join(t,"index.json"),reposDir:te.join(t,"repos"),workspacesDir:te.join(t,"workspaces"),sessionsDir:te.join(t,"sessions"),runtimeDir:te.join(t,"runtime"),uiStateFile:te.join(t,"runtime","ui-state.json"),tasksDir:te.join(t,"tasks"),jobsDir:te.join(t,"jobs"),logsDir:te.join(t,"logs"),errorLogFile:te.join(t,"logs","errors.log"),artifactsDir:te.join(t,"artifacts"),worktreesDir:te.join(t,"worktrees"),configFile:te.join(t,"config.json")}}var sc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Xe=async e=>{let t=Pe(e);await Re(t.craigDir,{recursive:!0}),await Promise.all([Re(t.reposDir,{recursive:!0}),Re(t.workspacesDir,{recursive:!0}),Re(t.sessionsDir,{recursive:!0}),Re(t.runtimeDir,{recursive:!0}),Re(t.tasksDir,{recursive:!0}),Re(t.jobsDir,{recursive:!0}),Re(t.logsDir,{recursive:!0}),Re(t.artifactsDir,{recursive:!0}),Re(t.worktreesDir,{recursive:!0})]);try{let s=await nc(t.indexFile,"utf8"),o=JSON.parse(s);return Bt(o,e,t.indexFile)}catch(s){if(!sc(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let r=new Date().toISOString(),n={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:r,updatedAt:r};return await B(t.indexFile,n),n};var so=(e,t,r)=>{let n=new Date().toISOString();return{id:ac(e,Ze.basename(t)),name:Ze.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},oo=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},ac=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",n=`repo_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`repo_${r}_${s}`,s+=1;return n},lc=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",n=`workspace_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`workspace_${r}_${s}`,s+=1;return n},io=async(e,t)=>{let r=await ee(e);await ye(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},ao=async(e,t,r)=>{let n=await J({uiStateFile:e.uiStateFile})??we();await Y({uiStateFile:e.uiStateFile},{...n,selectedRepoId:r,selectedWorkspaceId:t.id,selectedTaskId:null})},cc=async(e,t)=>{let r=await oc(t,{withFileTypes:!0}),n=await pt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Ze.join(t,o.name);if(!await Kr(i))continue;let l=n.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),c=await Vr(i);s.push(l?oo(l,c):so([...n,...s],i,c))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},dc=async(e,t)=>{let r=await Vr(t),n=await pt(e),s=n.find(g=>g.rootPath===t)??null,o=s?oo(s,r):so(n,t,r),i=`workspace_${o.id}`,c=(await ie(e)).find(g=>g.id===i)??null,d=new Date().toISOString(),u=c??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:r,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await qr(e,o),c||await Fe(e,u),await io(e,{repoIds:[o.id],workspaceIds:[u.id]}),await ao(e,u,o.id),{kind:"createWorkspace",workspace:u,repos:[o],created:!c}},uc=async(e,t)=>{let r=await cc(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await ie(e),s=lc(n,Ze.basename(t)),o=n.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),l=r.map(d=>d.id),c=o?{...o,discoveredRepoIds:l,primaryRepoId:l[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:Ze.basename(t),rootPath:t,primaryRepoId:l[0]??"",discoveredRepoIds:l,branch:"project",status:"active",linkedRepoIds:l,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(r.map(d=>qr(e,d))),await Fe(e,c),await io(e,{repoIds:l,workspaceIds:[c.id]}),await ao(e,c,l[0]??null),{kind:"createWorkspace",workspace:c,repos:r,created:!o}},ft=async(e,t)=>{await Xe(e.workspaceRoot);let r=Ze.resolve(e.workspaceRoot,t);if(!(await ic(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await Kr(r)?dc(e,r):uc(e,r)};var Gr=async(e,t,r={listWorkspaceRecords:ie,ensureCraigState:Xe})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var Hr=async(e,t,r={readWorkspace:Ne,writeWorkspace:Fe,readUiState:J,writeUiState:Y})=>{let s={...await r.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};await r.writeWorkspace(e,s);let o=await r.readUiState({uiStateFile:e.uiStateFile});return o&&o.selectedWorkspaceId===t&&await r.writeUiState({uiStateFile:e.uiStateFile},{...o,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null}),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var zr=async(e,t)=>{let n={...await Ne(e,t),status:"active",archivedAt:null};await Fe(e,n);let s=await J({uiStateFile:e.uiStateFile})??null;return await Y({uiStateFile:e.uiStateFile},{...s??we(),selectedWorkspaceId:n.id,selectedRepoId:n.kind==="project"?n.discoveredRepoIds?.[0]??null:n.primaryRepoId,selectedTaskId:null}),{kind:"restoreWorkspace",workspaceId:n.id,status:n.status,branch:n.branch}};var We=async(e,t,r={deleteWorkspace:Qs,readCraigIndex:ee,writeCraigIndex:ye})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var pc=async(e,t)=>{let r=await J({uiStateFile:e.uiStateFile});!r||r.selectedWorkspaceId!==t||await Y({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})},Yr=async(e,t,r)=>{let n=await Ne(e,t),s=await r.listTasks(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(s.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await We(e,t),await pc(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var Qr={};Lr(Qr,{addRepo:()=>lo,listRegisteredRepos:()=>co,removeRepo:()=>uo});import fc from"node:path";import{stat as mc}from"node:fs/promises";var lo=async(e,t)=>{let r=fc.resolve(e.workspaceRoot,t);if(!(await mc(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await ft(e,t),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${r}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}};var co=async(e,t={listRepos:pt,ensureCraigState:Xe})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var uo=async(e,t,r)=>{let n=await ue(e,t),o=(await ie(e)).filter(u=>u.primaryRepoId===t),i=o.filter(u=>u.status==="active"),l=await r.listTasks(e,{repoId:t});if(i.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(l.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(o.map(u=>We(e,u.id))),await Zs(e,t);let c=await ee(e);await ye(e,{...c,repoIds:c.repoIds.filter(u=>u!==t)});let d=await J({uiStateFile:e.uiStateFile});return d?.selectedRepoId===t&&await Y({uiStateFile:e.uiStateFile},{...d,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var re={addWorkspace:ft,listWorkspaces:Gr,archiveWorkspace:Hr,restoreWorkspace:zr,removeWorkspace:Yr,removeWorkspaceRecord:We,repos:Qr};var ne=async(e,t)=>{let r=await gc(Xr(e,t),"utf8");return JSON.parse(r)},pe=async(e,t)=>{let r=await ne(e,t);return G(r,Xr(e,t))},A=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await B(Xr(e,t.id),r)},Jr=async(e,t)=>{let r=await ee(e);r.taskIds.includes(t)||await ye(e,{...r,taskIds:[...r.taskIds,t]})},Xr=(e,t)=>`${e.tasksDir}/${t}.json`;var O=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,Ee=e=>e.status==="merged"||e.status==="closed",et=(e,t)=>{let r=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),n=r>=0?e.prs.map((s,o)=>o===r?t:s):[...e.prs,t];return{...e,prs:n}},mt=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return Kt(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},Kt=e=>e.mergeable&&!hc(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),hc=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",Zr=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),gt=(e,t)=>{let r=e.isDraft??!1,n=kc(e.state,r);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:n,draft:r,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:wc(e.reviewDecision??null),requiredChecks:ht(e.statusCheckRollup),comments:Pc(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}},kc=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,wc=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,ht=e=>{let t=e.map(n=>Rc(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||Tc(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},Rc=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=t.name??t.context,n=t.state??t.status??t.conclusion;return r?{name:r,status:fo(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:yc(t)}:null},Tc=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):qt(e)&&!qt(t)?!0:!qt(e)&&qt(t)?!1:po(t.status)>=po(e.status),qt=e=>e.conclusion?.toUpperCase()==="CANCELLED",po=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},yc=e=>{let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let r=new Date(t).getTime();return Number.isFinite(r)?r:null},Pc=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(bc).filter(r=>r!==null).slice(-4):[]},bc=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=Sc(t.bodyText??t.body??"");return r?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:r,createdAt:t.createdAt??null,url:t.url??null}:null},Sc=e=>e.replace(/\s+/g," ").trim(),fo=(e,t)=>{let r=e?.toUpperCase()??null,n=t?.toUpperCase()??null;return n==="SKIPPED"||r==="SKIPPED"?"skipped":r==="SUCCESS"||n==="SUCCESS"||n==="NEUTRAL"?"success":r==="PENDING"||r==="EXPECTED"||r==="IN_PROGRESS"||r==="QUEUED"||r==="REQUESTED"||r==="WAITING"?"pending":r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"||n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"?"failed":r==="COMPLETED"&&n===null?"unknown":r==="COMPLETED"&&n!==null?fo(n,n):"unknown"};import{access as Ic}from"node:fs/promises";import mo from"node:path";var $=async(e,t,r={readRawTask:ne,validateTaskRecord:G})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Ac(n)?new Error(`Craig task "${t}" was not found.`):n}},H=async e=>{if(!await en(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},tt=(e,t)=>t.artifacts.logPath?mo.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:mo.join(e.workspaceRoot,t.artifacts.logPath):null,kt=async(e,t)=>{let r=await en(t.worktreePath),n=tt(e,t),s=n?await en(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Cc(t),lastCommitSummary:xc(t),prSummary:vc(t),cleanupSummary:Ec(t)}},en=async e=>{try{return await Ic(e),!0}catch{return!1}},Cc=e=>{let t=e.checks.commands.length,r=t===1?"command":"commands",n=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${r})${n}`},xc=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",vc=e=>{if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(c=>c.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(c=>` ${c.repoId} #${c.pullRequest.number} ${c.pullRequest.status??"unknown"}`),i=s.reduce((c,d)=>{let u=d.pullRequest.status??"unknown";return c[u]=(c[u]??0)+1,c},{}),l=Object.entries(i).map(([c,d])=>`${d} ${c}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${l})
30
+ ${o.join(`
31
+ `)}`}let t=O(e);if(!t?.number||!t.url)return"not linked";let r=t.requiredChecks.length,n=r===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${r} ${n})`},Ec=e=>e.status!=="merged"?"not merged":e.cleanup.warning?`warning: ${e.cleanup.warning}`:e.cleanup.preservedWorktree?"preserved worktree":e.cleanup.worktreeRemovedAt?`worktree removed at ${e.cleanup.worktreeRemovedAt}`:"cleanup pending",Ac=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var go=async(e,t)=>{let r=await M("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(r.exitCode===0)return!0;if(r.exitCode===1)return!1;throw new Error(r.stderr.trim()||r.stdout.trim()||"Unable to check git branch state.")},tn=async(e,t,r,n="main")=>{let s=n.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 Dc(e,s);await v("git",["worktree","add","-b",t,r,i],{cwd:e})},Dc=async(e,t)=>(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,Vt=async 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},ho=async e=>{await v("git",["add","-A"],{cwd:e})},ko=async(e,t)=>{await v("git",["commit","-m",t],{cwd:e})},wo=async e=>{let t=await v("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[r="",n=""]=t.stdout.trim().split(`
32
+ `);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}};var Ro=async(e,t)=>{await v("git",["worktree","remove","--force",t],{cwd:e})};var rn=async e=>rt(e,e.repoRoot),rt=async(e,t)=>{let r=await ee(e),n=To(new Date),s=yo(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await go(t,i))return o;s+=1}},wt=async e=>{let t=await ee(e),r=To(new Date),n=yo(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},To=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},yo=(e,t)=>{let r=e.filter(n=>n.startsWith(`task_${t}_`)).map(n=>Number.parseInt(n.slice(-2),10)).filter(n=>Number.isInteger(n));return r.length===0?1:Math.max(...r)+1};var nn=async(e,t,r={readRawTask:ne,validateTaskRecord:G})=>{let n=await ee(e),s=[],o=[];await Promise.all(n.taskIds.map(async c=>{try{let d=await r.readRawTask(e,c);s.push(r.validateTaskRecord(d,`${e.tasksDir}/${c}.json`))}catch(d){if($c(d)){o.push(c);return}throw d}}));let l=(t?.includeClosed?s:s.filter(c=>c.status!=="closed")).filter(c=>!(t?.workspaceId&&c.workspaceId!==t.workspaceId||t?.repoId&&c.repoId!==t.repoId&&!(c.repoTargets??[]).some(d=>d.repoId===t.repoId)));return l.sort((c,d)=>c.id.localeCompare(d.id)),o.sort(),{kind:"listTasks",tasks:l,missingTaskIds:o,repoId:t?.repoId??null}},$c=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var Po=["merge_ready","pr_open","checked","review","running","draft"],sn=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),on=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(Lc)[0]?.id??null,Lc=(e,t)=>{let r=bo(e.status),n=bo(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},bo=e=>{let t=Po.indexOf(e);return t>=0?t:Po.length};import So from"node:path";var _e=(e,t)=>t?So.isAbsolute(t)?t:So.join(e.repoRoot,t):null;import{mkdir as Rt,rm as jc,writeFile as Gt}from"node:fs/promises";import j from"node:path";var Co=["AGENTS","md"].join("."),nt=async(e,t,r,n={})=>{let s=await ue(e,t),o=await Wc(e,s.id),i=await rt(e,s.rootPath),l=n.sessionId??null,c=`craig/${i}`,d=j.join(e.worktreesDir,s.id,i),u=j.join(e.logsDir,`${i}.log`),g=j.join(e.artifactsDir,i);await Rt(j.dirname(d),{recursive:!0}),await Rt(g,{recursive:!0}),await Gt(u,"","utf8");let w=Mc(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:l,repoRoot:s.rootPath,prompt:r,runner:n.runner??"codex",config:n.config??{},branch:c,worktreePath:d});return await A(e,w),await Jr(e,i),await tn(s.rootPath,c,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:l,workspaceId:o.id,task:w}},Tt=async(e,t,r,n={})=>{let s=(await ie(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 nt(e,s.primaryRepoId,r,n);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 wt(e),l=new Date().toISOString(),c=n.runner??"codex",d=n.sessionId??null,u=`craig/${i}`,g=j.join(e.craigDir,"task-bundles",i),w=j.join(e.logsDir,`${i}.log`),R=j.join(e.artifactsDir,i);await Rt(g,{recursive:!0}),await Rt(R,{recursive:!0}),await Gt(w,"","utf8");let I=await Promise.all(o.map(x=>ue(e,x))),T=Nc(I),a=await Promise.all(I.map(x=>Oc(e,x,i,u,j.join(g,T.get(x.id))))),z=a.find(x=>x.status==="ready")??a[0];if(!a.some(x=>x.status==="ready"))throw await jc(g,{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 Gt(j.join(g,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:a.map(x=>({repoId:x.repoId,repoName:I.find(Me=>Me.id===x.repoId)?.name??x.repoId,path:j.relative(g,x.worktreePath),status:x.status,worktreePath:x.worktreePath,failureReason:x.failureReason}))},null,2),"utf8"),await Gt(j.join(g,Co),Fc({taskId:i,workspaceId:t,prompt:r,repos:I,repoTargets:a,bundlePath:g}),"utf8");let U=yt(i,r,l,c,n.config??{}),le={id:i,title:r,slug:xo(r),type:"project",status:"draft",runner:c,repoId:z.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:U[0]?.id??null,linkedRepoIds:o.filter(x=>x!==z.repoId),repoRoot:g,worktreePath:g,branch:u,bundlePath:g,selectedRepoTargetId:z.repoId,repoTargets:a,ptyTabs:U,runnerSession:{command:S.runners.buildCommand(c,r,n.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:r},checks:z.checks,lastCommit:null,prs:[],artifacts:{logPath:j.relative(e.workspaceRoot,w),checkSummaryPath:j.relative(e.workspaceRoot,j.join(R,"check-summary.json")),prDraftPath:null,prStatusPath:j.relative(e.workspaceRoot,j.join(R,"pr-status.json"))},cleanup:Ht(),lastFailureReason:a.every(x=>x.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:l,updatedAt:l};return await A(e,le),await Jr(e,i),{repoId:z.repoId,repoRoot:g,sessionId:d,workspaceId:s.id,task:le,bundlePath:g,repoTargets:a}},yt=(e,t,r,n="codex",s={})=>{let o=S.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:S.runners.buildCommand(n,void 0,s),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Mc=(e,t)=>{let r=new Date().toISOString(),n=yt(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:xo(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:n[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:n,runnerSession:{command:S.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:{...an(j.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:j.relative(e.workspaceRoot,j.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:j.relative(e.workspaceRoot,j.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:j.relative(e.workspaceRoot,j.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:Ht(),lastFailureReason:null,createdAt:r,updatedAt:r}},Oc=async(e,t,r,n,s)=>{await Rt(j.dirname(s),{recursive:!0});try{return await tn(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:an(j.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Io(),cleanup:Ht()}}catch(o){return{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:o instanceof Error?o.message:"Failed to create worktree.",checks:an(j.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Io(),cleanup:Ht()}}},Nc=e=>{let t=new Set(["manifest.json",Co]),r=new Map;for(let n of e){let s=t.has(n.name)?`${n.name}-repo`:n.name,o=s,i=2;for(;t.has(o);)o=`${s}-${i}`,i+=1;t.add(o),r.set(n.id,o)}return r},Fc=e=>{let t=new Map(e.repos.map(n=>[n.id,n.name])),r=e.repoTargets.map(n=>{let s=t.get(n.repoId)??n.repoId,o=j.relative(e.bundlePath,n.worktreePath),i=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${n.repoId}, ${i})`}).join(`
33
+ `);return["# Craig Project Task Bundle","","This directory is a Craig project task bundle. Repo work must happen inside the child repo worktrees listed below.","","Run repo Git commands from a repo worktree directory, not from the bundle root. Use `manifest.json` as the machine-readable source of truth for this bundle.","",`Task: \`${e.taskId}\``,`Workspace: \`${e.workspaceId}\``,`Prompt: ${e.prompt}`,"","## Repo Worktrees","",r,""].join(`
34
+ `)},an=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),Io=()=>({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}),Ht=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),Wc=async(e,t)=>{let n=(await ie(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!n)throw new Error(`Repo ${t} does not have an active workspace.`);return n},xo=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import Wo from"node:path";import{readFile as qc,rm as vk}from"node:fs/promises";import Kc from"node:path";function vo(e,t){let r=Uc(e);if(typeof r!="object"||r===null||typeof r.id!="string"||typeof r.taskId!="string"||typeof r.repoId!="string"||typeof r.workspaceId!="string"||r.substrate!=="tmux"||typeof r.sessionName!="string"||typeof r.paneId!="string"||!(r.windowTarget===null||typeof r.windowTarget=="string")||typeof r.worktreePath!="string"||!(r.logPath===null||typeof r.logPath=="string")||!Array.isArray(r.command)||!r.command.every(n=>typeof n=="string")||!["starting","running","exited","failed"].includes(r.status)||!(r.startedAt===null||typeof r.startedAt=="string")||!(r.exitedAt===null||typeof r.exitedAt=="string")||!(r.exitCode===null||typeof r.exitCode=="number")||!(r.lastAttachedAt===null||typeof r.lastAttachedAt=="string")||!Bc(r.attach)||!_c(r.snapshot)||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r}function _c(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 Bc(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 Uc(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(r=>typeof r=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}var Ae=async(e,t)=>{let r=await qc(ln(e,t),"utf8"),n=JSON.parse(r);return vo(n,ln(e,t))},Be=async(e,t)=>{await B(ln(e,t.id),{...t,updatedAt:new Date().toISOString()})};var ln=(e,t)=>Kc.join(e.sessionsDir,`${t}.json`);import{spawn as Vc}from"node:child_process";import{createHash as Gc}from"node:crypto";import Hc from"node:path";function zt(e){return`'${e.replace(/'/g,"'\\''")}'`}var zc="craig",Eo=async(e,t,r)=>{let n=cn(e,t),s=Qc(),o=await v("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=Xc(o.stdout);return await Yc(e,n),i};var Yc=async(e,t)=>{let r=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let n of r)await v("tmux",n,{cwd:e})},Ao=async(e,t,r)=>{await v("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},Do=async(e,t,r)=>{await v("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var $o=async(e,t,r)=>{await v("tmux",["pipe-pane","-o","-t",e,`cat >> ${zt(t)}`],{cwd:r})},Yt=async(e,t,r,n)=>{let s=n??jo(e);if(r?await v("tmux",["select-window","-t",r],{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 ed(e,["attach-session","-t",s])};var Lo=async(e,t)=>{await v("tmux",["kill-session","-t",t],{cwd:e})};var jo=e=>{let r=Hc.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=Gc("sha1").update(e).digest("hex").slice(0,8);return`${zc}-${r}-${n}`},cn=(e,t)=>`${jo(e)}-${t.toLowerCase()}`,Qc=()=>{let e=Jc();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},Jc=()=>{let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let r="columns"in t?t.columns:void 0,n="rows"in t?t.rows:void 0;if(typeof r=="number"&&r>0&&typeof n=="number"&&n>0)return{columns:r,rows:n}}return null},Xc=e=>{let t=Zc(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]}},Zc=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),ed=async(e,t)=>{await new Promise((r,n)=>{let s=Vc("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",n),s.on("exit",o=>{if(o===0){r();return}n(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})};import{accessSync as td,constants as rd}from"node:fs";import{homedir as Mo}from"node:os";import De from"node:path";var nd=[De.join(Mo(),".local","bin"),De.join(Mo(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function No(e=process.env){return sd([...(e.PATH??"").split(De.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:nd])}function Ue(e=process.env){return{...e,PATH:No(e).join(De.delimiter)}}function dn(e,t={}){if(e.includes(De.sep)){let r=De.isAbsolute(e)?e:De.resolve(t.cwd??process.cwd(),e);return Oo(r)?r:null}for(let r of No(t.env)){let n=De.join(r,e);if(Oo(n))return n}return null}function qe(e,t={}){let r=dn(e,t);if(r)return r;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function Oo(e){try{return td(e,rd.X_OK),!0}catch{return!1}}function sd(e){return[...new Set(e)]}var Pt={async create(e,t){let r=await Eo(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await $o(r.paneId,t.logPath,t.repoRoot);let n=await Fo({paneId:r.paneId,windowTarget:r.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:r.sessionName||cn(t.repoRoot,t.taskId),paneId:r.paneId,windowTarget:r.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:n,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await Be(e,s),s},async attach(e,t,r){let n=await Pt.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await Yt(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await Be(e,s),s},async resize(e,t,r,n){await Ao(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};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,r){let n={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:t.command};return await Be(e,n),n},async snapshot(e,t){return od(e,t)}},un={async prepare(e,t){let n=e.runnerSession.command[0],s=Ue();await v(qe(n,{cwd:t.repoRoot,env:s}),["--help"],{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=qe(r[0],{cwd:e.worktreePath,env:Ue()});await Do(t.session.paneId,[n,...r.slice(1)].map(s=>zt(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},od=async(e,t)=>{let r=await M("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Fo({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},Fo=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var pn=async(e,t,r,n={})=>{let s=r.trim(),o=await S.load(e),i=n.runner??S.runners.getDefault(o);if(S.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(n.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let l=n.workspaceId?await Tt(e,n.workspaceId,s,{runner:i,config:o}):await nt(e,t,s,{runner:i,config:o}),c=l.task,d=S.runners.buildCommand(i,s,o),u=`session_${c.id}`,g=c.artifacts.logPath?Wo.resolve(e.workspaceRoot,c.artifacts.logPath):Wo.join(e.logsDir,`${c.id}.log`);try{await un.prepare(c,{repoRoot:l.repoRoot});let w=await Pt.create(e,{sessionId:u,taskId:c.id,repoId:l.repoId,workspaceId:l.workspaceId,repoRoot:l.repoRoot,worktreePath:c.worktreePath,logPath:g,command:d});await un.launch(c,{repoRoot:l.repoRoot,session:w});let R=new Date().toISOString();w={...w,status:"running",startedAt:R,command:d};let I={...c,status:"running",runner:i,sessionId:w.id,selectedPtyTabId:c.selectedPtyTabId,runnerSession:{command:w.command,pid:null,startedAt:R,lastKnownState:"running",exitCode:null,exitedAt:null}};return await A(e,I),await Be(e,w),await Y({uiStateFile:e.uiStateFile},{...await J({uiStateFile:e.uiStateFile})??we(),selectedRepoId:I.repoId,selectedWorkspaceId:I.workspaceId,selectedTaskId:I.id,selectedPtyTabId:I.selectedPtyTabId}),{kind:"createTask",taskId:I.id,repoId:I.repoId,workspaceId:I.workspaceId,sessionId:w.id,status:I.status,branch:I.branch,worktreePath:I.worktreePath,runner:I.runner}}catch(w){let R={...c,sessionId:null,status:"draft",runnerSession:{...c.runnerSession,lastKnownState:"failed"},lastFailureReason:w instanceof Error?w.message:"Unknown Craig error"};throw await A(e,R),w}};import{mkdir as gd}from"node:fs/promises";import hd from"node:path";var _o=3,id=1e3,ad=1e4,st=async 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.")};var Bo=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await v("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},Qt=async(e,t)=>{let r=await v("gh",Ko(e),{cwd:t});return JSON.parse(r.stdout)},Jt=async(e,t)=>{let r=await M("gh",Ko(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},Uo=async(e,t,r)=>{if(r.length===0)return[];let n=fd(r),s=await ld(e,["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return r.map((l,c)=>{let d=i[`item${c}`],u=md(d);return{id:l.id,found:u!==null,view:u}})},qo=async e=>{let t=await M("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:pd(t.stdout.trim())},ld=async(e,t)=>{let r;for(let n=0;n<=_o;n+=1)try{return await v("gh",t,{cwd:e})}catch(s){if(r=s,n===_o||!cd(s))throw s;await ud(dd(n))}throw r},cd=e=>{let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")},dd=e=>{let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||id,r=Math.min(t*2**e,ad),n=Math.floor(Math.random()*Math.max(1,Math.floor(r*.25)));return r+n},ud=e=>new Promise(t=>setTimeout(t,e)),Ko=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],pd=e=>{let t=e.replace(/\.git$/,""),r=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let n=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null},fd=e=>`
33
35
  query CraigPullRequestBatch($owner: String!, $name: String!) {
34
36
  repository(owner: $owner, name: $name) {
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(`
37
+ ${e.map((r,n)=>{let s=`item${n}`;return r.mode==="number"?`${s}: pullRequest(number: ${Number(r.selector)}) { ...PrFields }`:`${s}: pullRequests(headRefName: ${JSON.stringify(r.selector)}, states: OPEN, first: 1, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { ...PrFields } }`}).join(`
36
38
  `)}
37
39
  }
38
40
  }
@@ -108,58 +110,56 @@ fragment PrFields on PullRequest {
108
110
  }
109
111
  }
110
112
  }
111
- `}function Zl(e){if(!e||typeof e!="object")return null;let t="nodes"in e?e.nodes?.[0]??null:e;if(!t||typeof t!="object")return null;let n=t,r=n.statusCheckRollup?.contexts?.nodes??n.commits?.nodes?.[0]?.commit?.statusCheckRollup?.contexts?.nodes??[];return{number:n.number,url:n.url,baseRefName:n.baseRefName,headRefName:n.headRefName,headRefOid:n.headRefOid??null,state:n.state,isDraft:n.isDraft??!1,title:n.title??null,createdAt:n.createdAt??null,updatedAt:n.updatedAt??null,mergedAt:n.mergedAt??null,mergeable:n.mergeable,mergeStateStatus:n.mergeStateStatus,reviewDecision:n.reviewDecision??null,statusCheckRollup:r,comments:n.comments?.nodes??[]}}async function rr(e,t,n,r){let s=ed(n,r),o=Ro(t,s),i=Jl(o.prs),c={...o,status:i};await Co(e,c);let l=await U(e,t.id),d=l.status==="closed"?l.status:i,f=Ro({...l,status:d},s);return await A(e,f),f}async function Zn(e,t,n,r){let s=await U(e,t.id),o=(s.repoTargets??t.repoTargets??[]).map(c=>c.repoId===n?{...c,pullRequest:r}:c),i={...s,repoTargets:o};return await A(e,i),i}function ed(e,t){let n=e.isDraft??!1,r=td(e.state,n);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:r,draft:n,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:vo(e.reviewDecision??null),requiredChecks:xo(e.statusCheckRollup),comments:Eo(e.comments),createdAt:e.createdAt??t?.createdAt??null,updatedAt:e.updatedAt??t?.updatedAt??null,mergedAt:e.mergedAt??t?.mergedAt??null,lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function er(e){return{provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:nd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:vo(e.reviewDecision??null),requiredChecks:xo(e.statusCheckRollup),comments:Eo(e.comments),lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}}function td(e,t){return t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function nd(e){return e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null}function xo(e){let t=e.map(r=>rd(r)).filter(r=>r!==null),n=new Map;for(let r of t){let s=n.get(r.name);(!s||sd(s,r))&&n.set(r.name,r)}return[...n.values()].map(r=>({name:r.name,status:r.status,conclusion:r.conclusion}))}function rd(e){if(typeof e!="object"||e===null)return null;let t=e,n=t.name??t.context,r=t.state??t.status??t.conclusion;return n?{name:n,status:Ao(r??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:od(t)}:null}function sd(e,t){return e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Vt(e)&&!Vt(t)?!0:!Vt(e)&&Vt(t)?!1:yo(t.status)>=yo(e.status)}function Vt(e){return e.conclusion?.toUpperCase()==="CANCELLED"}function yo(e){switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}}function od(e){let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let n=new Date(t).getTime();return Number.isFinite(n)?n:null}function vo(e){return e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null}function Eo(e){let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(id).filter(n=>n!==null).slice(-4):[]}function id(e){if(typeof e!="object"||e===null)return null;let t=e,n=ad(t.bodyText??t.body??"");return n?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:n,createdAt:t.createdAt??null,url:t.url??null}:null}function ad(e){return e.replace(/\s+/g," ").trim()}function Ao(e,t){let n=e?.toUpperCase()??null,r=t?.toUpperCase()??null;return r==="SKIPPED"||n==="SKIPPED"?"skipped":n==="SUCCESS"||r==="SUCCESS"||r==="NEUTRAL"?"success":n==="PENDING"||n==="EXPECTED"||n==="IN_PROGRESS"||n==="QUEUED"||n==="REQUESTED"||n==="WAITING"?"pending":n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"||r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"?"failed":n==="COMPLETED"&&r===null?"unknown":n==="COMPLETED"&&r!==null?Ao(r,r):"unknown"}async function O(e,t){try{return await U(e,t)}catch(n){throw pd(n)?new Error(`Craig task "${t}" was not found.`):n}}async function le(e){if(!await sr(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)}function or(e,t){return t.artifacts.logPath?$o.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:$o.join(e.workspaceRoot,t.artifacts.logPath):null}async function Do(e,t){let n=await sr(t.worktreePath),r=or(e,t),s=r?await sr(r):!1;return{worktreeExists:n,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:ld(t),lastCommitSummary:dd(t),prSummary:ud(t),cleanupSummary:fd(t)}}async function sr(e){try{return await cd(e),!0}catch{return!1}}function ld(e){let t=e.checks.commands.length,n=t===1?"command":"commands",r=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${n})${r}`}function dd(e){return e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed"}function ud(e){if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(l=>l.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),i=s.reduce((l,d)=>{let f=d.pullRequest.status??"unknown";return l[f]=(l[f]??0)+1,l},{}),c=Object.entries(i).map(([l,d])=>`${d} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${c})
112
- ${o.join(`
113
- `)}`}let t=G(e);if(!t?.number||!t.url)return"not linked";let n=t.requiredChecks.length,r=n===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${n} ${r})`}function fd(e){return e.status!=="merged"?"not merged":e.cleanup.warning?`warning: ${e.cleanup.warning}`:e.cleanup.preservedWorktree?"preserved worktree":e.cleanup.worktreeRemovedAt?`worktree removed at ${e.cleanup.worktreeRemovedAt}`:"cleanup pending"}function pd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function Mo(e,t){let n=await O(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session to attach.`);let[r,s]=await Promise.all([fe(e,n.repoId),Qe(e,n.sessionId)]),o=await at.attach(e,s,r.rootPath);return{kind:"attachTask",taskId:n.id,sessionId:o.id,disposition:"attached"}}ie();async function Oo(e,t){let n=await O(e,t),r=G(n);return r?.number?(await pt(n.worktreePath),Ht(r)?(await nr(e,n)).task:tr(e,n)):n}async function Yt(e,t){let n=await O(e,t),r=(n.repoTargets??[]).filter(i=>i.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let i of r){await pt(i.worktreePath);let c=i.pullRequest.number?await mt(e,n,i):await mt(e,n,i).catch(()=>"not_found");s[c==="not_found"?"notFound":c]++}let o=await U(e,n.id);return o.status!=="closed"&&(o.status=jo(o),await A(e,o)),s}async function Fo(e,t){let n=new Map,r=new Map;for(let s of t){let o=ir(n,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(f=>f.status==="ready")){let f={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head"};await Lo(r,f).catch(async()=>{try{let h=d.pullRequest.number?await mt(e,s,d):await mt(e,s,d).catch(()=>"not_found");zt(o,h,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=G(s),c=i?.number&&!Ht(i),l={id:s.id,task:s,worktreePath:s.worktreePath,selector:c?String(i.number):s.branch,mode:c?"number":"head"};await Lo(r,l).catch(async()=>{try{let{disposition:d,task:f}=await ar(e,s.id),h=G(f);zt(o,d,h?.number??null,h?.url??null)}catch{}})}for(let s of r.values())try{await pt(s.worktreePath);let o=await bo(s.worktreePath,s.repository,s.items),i=new Map(o.map(c=>[c.id,c]));for(let c of s.items){let l=ir(n,c.task),d=i.get(c.id);if(!d?.found||!d.view){zt(l,"not_found",null,null);continue}c.targetRepoId?await So(e,c.task,c.targetRepoId,d.view):await Io(e,c.task,d.view),zt(l,c.mode==="number"?"synced":"discovered",d.view.number,d.view.url)}}catch{}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await U(e,s.id);o.status!=="closed"&&(o.status=jo(o),await A(e,o))}return t.map(s=>ir(n,s))}async function ar(e,t){let n=await O(e,t);await le(n),await pt(n.worktreePath);let r=G(n);if(r?.number&&!Ht(r))return{disposition:"synced",task:await tr(e,n)};let s=await nr(e,n);return{disposition:s.discovered?"discovered":"not_found",task:s.task}}function jo(e){let t=(e.repoTargets??[]).filter(r=>r.status==="ready"),n=t.map(r=>r.pullRequest).filter(r=>!!r.number);return n.length===0?e.status:n.every(r=>r.status==="merged")?"merged":n.length===t.length&&n.every(md)?"merge_ready":n.some(r=>r.status==="open")?"pr_open":"checked"}async function Lo(e,t){let n=await Po(t.worktreePath);if(!n)throw new Error("GitHub repository remote could not be parsed.");let r=`${n.owner}/${n.name}`,s=e.get(r);if(s){s.items.push(t);return}e.set(r,{worktreePath:t.worktreePath,repository:n,items:[t]})}function ir(e,t){let n=e.get(t.id);if(n)return n;let r={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!G(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,r),r}function zt(e,t,n,r){if(t==="synced"){e.synced+=1;return}if(t==="discovered"){e.discovered+=1,e.firstDiscoveredPrNumber??=n,e.firstDiscoveredPrUrl??=r;return}e.notFound+=1}function md(e){return e.mergeable&&e.reviewDecision!=="REVIEW_REQUIRED"&&e.reviewDecision!=="CHANGES_REQUESTED"&&e.mergeStateStatus!=="REVIEW_REQUIRED"&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped")}async function cr(e,t){let n=await O(e,t);try{n.type==="project"&&n.repoTargets?.length?(await Yt(e,t),n=await O(e,t)):n.prs.some(o=>o.number)&&(n=await Oo(e,t))}catch{}let r=await Do(e,n),s=n.sessionId?await Qe(e,n.sessionId).catch(()=>null):null;return{kind:"showTask",task:n,inspection:r,session:s}}import{access as gd}from"node:fs/promises";async function lr(e,t){let n=await O(e,t),r=or(e,n);if(!r)throw new Error(`Task ${n.id} does not have a Craig-managed log path.`);try{await gd(r)}catch{throw new Error(`Task ${n.id} log file does not exist yet at ${r}.`)}return{kind:"streamTaskLogs",taskId:n.id,logPath:r}}ce();async function dr(e,t){let n=await O(e,t);if(await le(n),(await v("git",["status","--short"],{cwd:n.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:n.id,diffText:"",isEmpty:!0};let s=await hd(n.worktreePath);return{kind:"showTaskDiff",taskId:n.id,diffText:s,isEmpty:!1}}async function hd(e){let t=[],n=await v("git",["diff","--stat","--patch","HEAD"],{cwd:e});n.stdout.trim().length>0&&t.push(n.stdout.trimEnd());let r=await wd(e);for(let s of r){let o=await L("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
113
+ `,md=e=>{if(!e||typeof e!="object")return null;let t="nodes"in e?e.nodes?.[0]??null:e;if(!t||typeof t!="object")return null;let r=t,n=r.statusCheckRollup?.contexts?.nodes??r.commits?.nodes?.[0]?.commit?.statusCheckRollup?.contexts?.nodes??[];return{number:r.number,url:r.url,baseRefName:r.baseRefName,headRefName:r.headRefName,headRefOid:r.headRefOid??null,state:r.state,isDraft:r.isDraft??!1,title:r.title??null,createdAt:r.createdAt??null,updatedAt:r.updatedAt??null,mergedAt:r.mergedAt??null,mergeable:r.mergeable,mergeStateStatus:r.mergeStateStatus,reviewDecision:r.reviewDecision??null,statusCheckRollup:n,comments:r.comments?.nodes??[]}};var Ke=async(e,t)=>{let r=_e(e,t.artifacts.prStatusPath);r&&(await gd(hd.dirname(r),{recursive:!0}),await B(r,{taskId:t.id,prs:t.prs}))},bt=async(e,t,r,n,s={readRawTask:ne,validateTaskRecord:G,writeTask:A,writePrStatusArtifact:Ke})=>{let o=gt(r,n),i=et(t,o),l=mt(i.prs),c={...i,status:l};await s.writePrStatusArtifact(e,c);let d=await s.readRawTask(e,t.id),u=s.validateTaskRecord(d,`${e.tasksDir}/${t.id}.json`),g=u.status==="closed"?u.status:l,w=et({...u,status:g},o);return await s.writeTask(e,w),w},St=async(e,t)=>{let r=O(t),n=r?.number?String(r.number):t.branch,s=await Qt(n,t.worktreePath);return bt(e,t,s,r)},It=async(e,t)=>{let r=await Jt(t.branch,t.worktreePath);return r?{discovered:!0,task:await bt(e,t,r,null)}:{discovered:!1,task:t}};var ot=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await Qt(n,r.worktreePath),l=Go(i);return r.pullRequest=l,await Vo(e,t,r.repoId,l),"synced"}let s=await Jt(n,r.worktreePath);if(!s)return"not_found";let o=Go(s);return r.pullRequest=o,await Vo(e,t,r.repoId,o),"discovered"},Vo=async(e,t,r,n)=>{let s=await ne(e,t.id),o=G(s,`${e.tasksDir}/${t.id}.json`),i=(o.repoTargets??t.repoTargets??[]).map(c=>c.repoId===r?{...c,pullRequest:n}:c),l={...o,repoTargets:i};return await A(e,l),l},Go=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:kd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:wd(e.reviewDecision??null),requiredChecks:ht(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),kd=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,wd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var Ct=async(e,t)=>{let r=await $(e,t),n=O(r);return n?.number?(await st(r.worktreePath),Ee(n)?(await It(e,r)).task:St(e,r)):r},mn=async(e,t)=>{let r=await $(e,t);if(r.type==="project"&&r.repoTargets?.length)return await it(e,t),$(e,t);let n=O(r);if(await H(r),await st(r.worktreePath),!n?.number||Ee(n)){let o=await It(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return await Ke(e,o.task),o.task}let s=await St(e,r);return await Ke(e,s),s},it=async(e,t)=>{let r=await $(e,t),n=(r.repoTargets??[]).filter(l=>l.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let l of n){await st(l.worktreePath);let c=l.pullRequest.number?await ot(e,r,l):await ot(e,r,l).catch(()=>"not_found");s[c==="not_found"?"notFound":c]++}let o=await ne(e,r.id),i=G(o,`${e.tasksDir}/${r.id}.json`);return i.status!=="closed"&&(i.status=zo(i),await A(e,i)),s},gn=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=fn(r,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(u=>u.status==="ready")){let u={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head"};await Ho(n,u).catch(async()=>{try{let g=d.pullRequest.number?await ot(e,s,d):await ot(e,s,d).catch(()=>"not_found");Xt(o,g,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=O(s),l=i?.number&&!Ee(i),c={id:s.id,task:s,worktreePath:s.worktreePath,selector:l?String(i.number):s.branch,mode:l?"number":"head"};await Ho(n,c).catch(async()=>{try{let{disposition:d,task:u}=await Zt(e,s.id),g=O(u);Xt(o,d,g?.number??null,g?.url??null)}catch{}})}for(let s of n.values())try{await st(s.worktreePath);let o=await Uo(s.worktreePath,s.repository,s.items),i=new Map(o.map(l=>[l.id,l]));for(let l of s.items){let c=fn(r,l.task),d=i.get(l.id);if(!d?.found||!d.view){Xt(c,"not_found",null,null);continue}if(l.targetRepoId){let u=await ne(e,l.task.id),g=G(u,`${e.tasksDir}/${l.task.id}.json`);await Rd(e,g,l.targetRepoId,d.view)}else{let u=await ne(e,l.task.id),g=G(u,`${e.tasksDir}/${l.task.id}.json`);await bt(e,g,d.view,O(g))}Xt(c,l.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 ne(e,s.id),i=G(o,`${e.tasksDir}/${s.id}.json`);i.status!=="closed"&&(i.status=zo(i),await A(e,i))}return t.map(s=>fn(r,s))},Zt=async(e,t)=>{let r=await $(e,t);await H(r),await st(r.worktreePath);let n=O(r);if(n?.number&&!Ee(n))return{disposition:"synced",task:await St(e,r)};let s=await It(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},zo=e=>{let t=(e.repoTargets??[]).filter(n=>n.status==="ready"),r=t.map(n=>n.pullRequest).filter(n=>!!n.number);return r.length===0?e.status:r.every(n=>n.status==="merged")?"merged":r.length===t.length&&r.every(bd)?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"},Rd=async(e,t,r,n)=>{let s=Td(n),o=(t.repoTargets??[]).map(l=>l.repoId===r?{...l,pullRequest:s}:l),i={...t,repoTargets:o};return await A(e,i),i},Td=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:yd(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:Pd(e.reviewDecision??null),requiredChecks:ht(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),yd=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,Pd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Ho=async(e,t)=>{let r=await qo(t.worktreePath);if(!r)throw new Error("GitHub repository remote could not be parsed.");let n=`${r.owner}/${r.name}`,s=e.get(n);if(s){s.items.push(t);return}e.set(n,{worktreePath:t.worktreePath,repository:r,items:[t]})},fn=(e,t)=>{let r=e.get(t.id);if(r)return r;let n={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!O(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},Xt=(e,t,r,n)=>{if(t==="synced"){e.synced+=1;return}if(t==="discovered"){e.discovered+=1,e.firstDiscoveredPrNumber??=r,e.firstDiscoveredPrUrl??=n;return}e.notFound+=1},bd=e=>e.mergeable&&e.reviewDecision!=="REVIEW_REQUIRED"&&e.reviewDecision!=="CHANGES_REQUESTED"&&e.mergeStateStatus!=="REVIEW_REQUIRED"&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped");var hn=async(e,t)=>{let r=await $(e,t);try{r.type==="project"&&r.repoTargets?.length?(await it(e,t),r=await $(e,t)):r.prs.some(o=>o.number)&&(r=await Ct(e,t))}catch{}let n=await kt(e,r),s=r.sessionId?await Ae(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var kn=async(e,t)=>{let r=await $(e,t);if(await H(r),(await v("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await Sd(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},Sd=async e=>{let t=[],r=await v("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await Id(e);for(let s of n){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 wd(e){return(await v("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
- `).map(n=>n.trim()).filter(n=>n.length>0)}async function ur(e,t){let n=await O(e,t);if(!n.sessionId)throw new Error(`Task ${n.id} does not have a Craig session.`);let r=await Qe(e,n.sessionId).catch(s=>{throw kd(s)?new Error(`Task ${n.id} does not have a Craig session.`):s});if(!r.paneId)throw new Error(`Task ${n.id} does not have a tmux target.`);return await Ft(e.repoRoot,r.paneId,r.windowTarget,r.sessionName),{kind:"focusTask",taskId:n.id,tmuxTarget:r.paneId}}function kd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}ee();import{spawn as Rd}from"node:child_process";async function fr(e,t){let n=await O(e,t);await le(n);let s=(await b.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!1,command:null};let o=[...s,n.worktreePath];return await Td(o,e.repoRoot),{kind:"openTask",taskId:n.id,worktreePath:n.worktreePath,launched:!0,command:o}}async function Td(e,t){await new Promise((n,r)=>{let[s,...o]=e,i=Rd(s,o,{cwd:t,stdio:"inherit"});i.on("error",r),i.on("exit",c=>{if(c===0){n();return}r(new Error(`${e.join(" ")} failed with exit code ${c??"unknown"}.`))})})}ke();ee();ie();import{mkdir as yd}from"node:fs/promises";import Pd from"node:path";ce();async function pr(e,t){let n=await O(e,t);if(await le(n),n.status==="draft"||n.status==="merged")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);if(n.status==="running"&&await _t(n.worktreePath)&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot run checks from status "${n.status}".`);let s=(await b.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);n.checks.status="running",n.checks.commands=[...s],n.checks.results=[],await A(e,n);let o=[];for(let i of s){let c=new Date().toISOString(),l=await L("sh",["-lc",i],{cwd:n.worktreePath}),d=new Date().toISOString(),f=l.exitCode??1;if(o.push({command:i,startedAt:c,finishedAt:d,exitCode:f}),f!==0)return n.checks.results=o,n.checks.status="failed",n.checks.lastRunAt=d,n.status="review",n.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await No(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"failed",commands:s}}return n.checks.results=o,n.checks.status="passed",n.checks.lastRunAt=new Date().toISOString(),n.status="checked",n.lastFailureReason=null,await No(e,n),await A(e,n),{kind:"runChecks",taskId:n.id,status:"passed",commands:s}}async function No(e,t){let n=Kt(e,t.artifacts.checkSummaryPath);n&&(await yd(Pd.dirname(n),{recursive:!0}),await B(n,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))}ie();async function mr(e,t){let n=await O(e,t);await le(n);let r=await _t(n.worktreePath);if(n.status==="running"&&r&&(n.status="review"),n.status!=="review"&&n.status!=="checked")throw new Error(`Task ${n.id} cannot commit from status "${n.status}".`);if(!r)throw new Error(`Task ${n.id} has no uncommitted diff to commit.`);let s=n.prompt.value.trim();await so(n.worktreePath),await oo(n.worktreePath,s);let o=await io(n.worktreePath);return n.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},n.lastFailureReason=null,await A(e,n),{kind:"commitTask",taskId:n.id,status:n.status,commitSha:o.sha,message:o.message}}We();qe();lt();Ze();ft();kt();ce();import Ad from"node:path";import{stat as $d}from"node:fs/promises";async function zo(e,t){let n=Ad.resolve(e.workspaceRoot,t);if(!(await $d(n).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${n}`);let s=await Promise.resolve().then(()=>(kt(),Ho)).then(({addWorkspace:i})=>i(e,t)),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${n}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}}async function Yo(e){return{kind:"listRepos",repos:await Ue(e)}}async function Jo(e,t){let n=await fe(e,t),s=(await pe(e)).filter(d=>d.primaryRepoId===t),o=s.filter(d=>d.status==="active"),i=await Te(e,{repoId:t});if(o.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(i.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(s.map(d=>Jt(e,d.id))),await eo(e,t);let c=await oe(e);await Ne(e,{...c,repoIds:c.repoIds.filter(d=>d!==t)});let l=await ue({uiStateFile:e.uiStateFile});return l?.selectedRepoId===t&&await ae({uiStateFile:e.uiStateFile},{...l,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}}qe();ie();async function Qo(e,t,n){let[r,s]=await Promise.all([O(e,t),fe(e,n)]);if(r.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${r.id}.`);let o=r.linkedRepoIds.includes(s.id)?r.linkedRepoIds:[...r.linkedRepoIds,s.id];return await A(e,{...r,linkedRepoIds:o}),{kind:"addTaskLink",taskId:r.id,repoId:s.id,linkedRepoIds:o}}async function Xo(e,t){let n=await O(e,t),r=await Promise.all(n.linkedRepoIds.map(s=>fe(e,s)));return{kind:"listTaskLinks",taskId:n.id,repos:r}}kt();async function Zo(e,t){switch(e.kind){case"addWorkspace":return gt(t.paths,e.path);case"addRepo":return zo(t.paths,e.path);case"listRepos":return Yo(t.paths);case"removeRepo":return Jo(t.paths,e.repoId);case"listWorkspaces":return gr(t.paths,{archived:e.archived});case"archiveWorkspace":return ht(t.paths,e.workspaceId);case"restoreWorkspace":return hr(t.paths,e.workspaceId);case"removeWorkspace":return wt(t.paths,e.workspaceId);case"createTask":return wo(t.paths,e.repoId??e.workspaceId??"",e.prompt,{...e.runner?{runner:e.runner}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}});case"listTasks":return e.repoId||e.workspaceId?Te(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):Te(t.paths);case"attachTask":return Mo(t.paths,e.taskId);case"addTaskLink":return Qo(t.paths,e.taskId,e.repoId);case"listTaskLinks":return Xo(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return cr(t.paths,e.taskId);case"showSelectedTask":return cr(t.paths,Ke(t,"show"));case"streamTaskLogs":return lr(t.paths,e.taskId);case"streamSelectedTaskLogs":return lr(t.paths,Ke(t,"logs"));case"showTaskDiff":return dr(t.paths,e.taskId);case"showSelectedTaskDiff":return dr(t.paths,Ke(t,"diff"));case"focusTask":return ur(t.paths,e.taskId);case"focusSelectedTask":return ur(t.paths,Ke(t,"focus"));case"openTask":return fr(t.paths,e.taskId);case"openSelectedTask":return fr(t.paths,Ke(t,"open"));case"runChecks":return pr(t.paths,e.taskId);case"runSelectedTaskChecks":return pr(t.paths,Ke(t,"check"));case"commitTask":return mr(t.paths,e.taskId);case"commitSelectedTask":return mr(t.paths,Ke(t,"commit"));case"help":return{kind:"help",text:J()};case"exit":return{kind:"exit"};default:return Dd(e)}}function Dd(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Ke(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}ke();import{mkdir as ye,readFile as Md}from"node:fs/promises";import Q from"node:path";function be(e){let t=Q.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:Q.join(t,"index.json"),reposDir:Q.join(t,"repos"),workspacesDir:Q.join(t,"workspaces"),sessionsDir:Q.join(t,"sessions"),runtimeDir:Q.join(t,"runtime"),uiStateFile:Q.join(t,"runtime","ui-state.json"),tasksDir:Q.join(t,"tasks"),jobsDir:Q.join(t,"jobs"),logsDir:Q.join(t,"logs"),errorLogFile:Q.join(t,"logs","errors.log"),artifactsDir:Q.join(t,"artifacts"),worktreesDir:Q.join(t,"worktrees"),configFile:Q.join(t,"config.json")}}We();async function tt(e){let t=be(e);await ye(t.craigDir,{recursive:!0}),await Promise.all([ye(t.reposDir,{recursive:!0}),ye(t.workspacesDir,{recursive:!0}),ye(t.sessionsDir,{recursive:!0}),ye(t.runtimeDir,{recursive:!0}),ye(t.tasksDir,{recursive:!0}),ye(t.jobsDir,{recursive:!0}),ye(t.logsDir,{recursive:!0}),ye(t.artifactsDir,{recursive:!0}),ye(t.worktreesDir,{recursive:!0})]);try{let s=await Md(t.indexFile,"utf8"),o=JSON.parse(s);return Kn(o,e,t.indexFile)}catch(s){if(!Ld(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let n=new Date().toISOString(),r={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:n,updatedAt:n};return await B(t.indexFile,r),r}function Ld(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}function ei(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
115
+ `)},Id=async e=>(await v("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
116
+ `).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as Cd}from"node:child_process";import{access as xd}from"node:fs/promises";var wn=async(e,t)=>{let r=await $(e,t),n=tt(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await xd(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},Rn=async e=>{await new Promise((t,r)=>{let n=!1,s=Cd("tail",["-n","+1","-f",e],{stdio:"inherit"}),o=()=>{n=!0,s.kill("SIGINT")};process.on("SIGINT",o),s.on("error",l=>{i(),r(l)}),s.on("exit",(l,c)=>{if(i(),n||c==="SIGINT"){t();return}if(l===0){t();return}r(new Error(`tail -n +1 -f ${e} failed with exit code ${l??"unknown"}.`))});function i(){process.off("SIGINT",o)}})};import{mkdir as vd}from"node:fs/promises";import Ed from"node:path";var Tn=async(e,t)=>{let r=await $(e,t);if(await H(r),r.status==="draft"||r.status==="merged")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);if(r.status==="running"&&await Vt(r.worktreePath)&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);let s=(await S.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);r.checks.status="running",r.checks.commands=[...s],r.checks.results=[],await A(e,r);let o=[];for(let i of s){let l=new Date().toISOString(),c=await M("sh",["-lc",i],{cwd:r.worktreePath}),d=new Date().toISOString(),u=c.exitCode??1;if(o.push({command:i,startedAt:l,finishedAt:d,exitCode:u}),u!==0)return r.checks.results=o,r.checks.status="failed",r.checks.lastRunAt=d,r.status="review",r.lastFailureReason=c.stderr.trim()||c.stdout.trim()||`Check command failed: ${i}`,await Yo(e,r),await A(e,r),{kind:"runChecks",taskId:r.id,status:"failed",commands:s}}return r.checks.results=o,r.checks.status="passed",r.checks.lastRunAt=new Date().toISOString(),r.status="checked",r.lastFailureReason=null,await Yo(e,r),await A(e,r),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},Yo=async(e,t)=>{let r=_e(e,t.artifacts.checkSummaryPath);r&&(await vd(Ed.dirname(r),{recursive:!0}),await B(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var yn=async(e,t)=>{let r=await $(e,t);await H(r);let n=await Vt(r.worktreePath);if(r.status==="running"&&n&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot commit from status "${r.status}".`);if(!n)throw new Error(`Task ${r.id} has no uncommitted diff to commit.`);let s=r.prompt.value.trim();await ho(r.worktreePath),await ko(r.worktreePath,s);let o=await wo(r.worktreePath);return r.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},r.lastFailureReason=null,await A(e,r),{kind:"commitTask",taskId:r.id,status:r.status,commitSha:o.sha,message:o.message}};import{access as Ad}from"node:fs/promises";var Pn=async(e,t)=>{let r=await $(e,t),n=await Dd(r.worktreePath),s={...r,status:"closed",cleanup:{...r.cleanup,preservedWorktree:n&&r.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await A(e,s),s},Dd=async e=>{try{return await Ad(e),!0}catch{return!1}};var bn=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await Ae(e,t.sessionId);await Lo(e.repoRoot,s.sessionName),t.cleanup.paneClosedAt=new Date().toISOString()}}catch(s){n.push(s instanceof Error?s.message:"Failed to close tmux session.")}if(t.cleanup.preservedWorktree=r.preserveWorktree,!r.preserveWorktree)try{await Ro(e.repoRoot,t.worktreePath),t.cleanup.worktreeRemovedAt=new Date().toISOString()}catch(s){n.push(s instanceof Error?s.message:"Failed to remove worktree.")}t.cleanup.warning=n.length>0?n.join(" "):null,await A(e,t)};var Sn=async(e,t,r)=>{let[n,s]=await Promise.all([$(e,t),ue(e,r)]);if(n.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${n.id}.`);let o=n.linkedRepoIds.includes(s.id)?n.linkedRepoIds:[...n.linkedRepoIds,s.id];return await A(e,{...n,linkedRepoIds:o}),{kind:"addTaskLink",taskId:n.id,repoId:s.id,linkedRepoIds:o}},In=async(e,t)=>{let r=await $(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>ue(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var Cn=async(e,t)=>{let r=await $(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session to attach.`);let[n,s]=await Promise.all([ue(e,r.repoId),Ae(e,r.sessionId)]),o=await Pt.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var xn=async(e,t)=>{let r=await $(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await Ae(e,r.sessionId).catch(s=>{throw $d(s)?new Error(`Task ${r.id} does not have a Craig session.`):s});if(!n.paneId)throw new Error(`Task ${r.id} does not have a tmux target.`);return await Yt(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},$d=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as Ld}from"node:child_process";var vn=async(e,t)=>{let r=await $(e,t);await H(r);let s=(await S.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!1,command:null};let o=[...s,r.worktreePath];return await jd(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},jd=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=Ld(s,o,{cwd:t,stdio:"inherit"});i.on("error",n),i.on("exit",l=>{if(l===0){r();return}n(new Error(`${e.join(" ")} failed with exit code ${l??"unknown"}.`))})})};var En=async(e,t,r)=>{let n=await pe(e,t);await A(e,{...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})},An=async(e,t,r)=>{let n=await pe(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await A(e,s),s},Dn=async(e,t)=>{let r=await pe(e,t),n=r.ptyTabs.find(o=>o.kind==="agent");if(!n)throw new Error(`Task ${t} is missing its agent PTY tab.`);let s={...r,status:"running",selectedPtyTabId:n.id,runnerSession:{...r.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await A(e,s),s};var $n=async(e,t,r="merge",n)=>{let s=await $(e,t),o=n??O(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await Bo(s.worktreePath,o,r)};var D={listTasks:nn,getTask:$,provisionTask:nt,provisionProjectTask:Tt,createTask:pn,showTask:hn,showTaskDiff:kn,prepareTaskLogs:wn,streamTaskLogs:Rn,runChecks:Tn,commitTask:yn,closeTask:Pn,cleanupTask:bn,addTaskLink:Sn,listTaskLinks:In,sortTasksForDisplay:sn,resolveSelectedTaskId:on,allocateTaskId:rn,allocateTaskIdForRepo:rt,allocateProjectTaskId:wt,createDefaultTaskPtyTabs:yt,assertTaskWorktreeExists:H,resolveTaskLogPath:tt,buildTaskInspection:kt,resolveArtifactPath:_e,attachTask:Cn,focusTask:xn,openTask:vn,markRunnerFailed:En,recordStartupFailure:An,markTaskStarted:Dn,prs:{refresh:Ct,refreshChecks:mn,discoverOrRefresh:Zt,discoverOrRefreshAll:it,discoverOrRefreshMany:gn,merge:$n,getPrimaryPr:O,isPrTerminal:Ee,isMergeReady:Kt,deriveTaskStatus:mt,upsertPr:et,normalizePr:gt,summarizeRequiredChecks:Zr,writePrStatusArtifact:Ke}};async function Qo(e,t){switch(e.kind){case"addWorkspace":return re.addWorkspace(t.paths,e.path);case"addRepo":return re.repos.addRepo(t.paths,e.path);case"listRepos":return re.repos.listRegisteredRepos(t.paths);case"removeRepo":return re.repos.removeRepo(t.paths,e.repoId,{listTasks:D.listTasks});case"listWorkspaces":return re.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":return re.archiveWorkspace(t.paths,e.workspaceId);case"restoreWorkspace":return re.restoreWorkspace(t.paths,e.workspaceId);case"removeWorkspace":return re.removeWorkspace(t.paths,e.workspaceId,{listTasks:D.listTasks});case"createTask":return D.createTask(t.paths,e.repoId??e.workspaceId??"",e.prompt,{...e.runner?{runner:e.runner}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}});case"listTasks":return e.repoId||e.workspaceId?D.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):D.listTasks(t.paths);case"attachTask":return D.attachTask(t.paths,e.taskId);case"addTaskLink":return D.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return D.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return D.showTask(t.paths,e.taskId);case"showSelectedTask":return D.showTask(t.paths,Ve(t,"show"));case"streamTaskLogs":return D.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return D.prepareTaskLogs(t.paths,Ve(t,"logs"));case"showTaskDiff":return D.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return D.showTaskDiff(t.paths,Ve(t,"diff"));case"focusTask":return D.focusTask(t.paths,e.taskId);case"focusSelectedTask":return D.focusTask(t.paths,Ve(t,"focus"));case"openTask":return D.openTask(t.paths,e.taskId);case"openSelectedTask":return D.openTask(t.paths,Ve(t,"open"));case"runChecks":return D.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return D.runChecks(t.paths,Ve(t,"check"));case"commitTask":return D.commitTask(t.paths,e.taskId);case"commitSelectedTask":return D.commitTask(t.paths,Ve(t,"commit"));case"help":return{kind:"help",text:Z()};case"exit":return{kind:"exit"};default:return Md(e)}}function Md(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Ve(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 Jo(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} ${jd(t)} ${Nd(t)} ${t.title}`)].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} ${Fd(t)} ${Wd(t)} ${t.title}`)].join(`
123
123
  `);case"showTask":return[`${e.task.id}: ${e.task.title}`,`Status: ${e.task.status}`,`Runner: ${e.task.runner}`,`Repo: ${e.task.repoId}`,`Workspace: ${e.task.workspaceId}`,`Branch: ${e.task.branch}`,`Worktree: ${e.task.worktreePath}`,`Session: ${e.task.sessionId??"<missing>"}`,`tmux: ${e.session?.paneId??"<missing>"}`,`Linked repos: ${e.task.linkedRepoIds.length>0?e.task.linkedRepoIds.join(", "):"none"}`,`Prompt: ${e.task.prompt.source} ${JSON.stringify(e.task.prompt.value)}`,`Runner command: ${e.inspection.runnerCommandText||"<none>"}`,`Runner state: ${e.task.runnerSession.lastKnownState}`,`Started: ${e.task.runnerSession.startedAt??"not started"}`,`Exited: ${e.task.runnerSession.exitedAt??"still running"}`,`Checks: ${e.inspection.checksSummary}`,`Last commit: ${e.inspection.lastCommitSummary}`,`PR: ${e.inspection.prSummary}`,`Cleanup: ${e.inspection.cleanupSummary}`,...Od(e)].join(`
124
124
  `);case"streamTaskLogs":return`Streaming logs for ${e.taskId} from ${e.logPath}`;case"showTaskDiff":return e.isEmpty?`Task ${e.taskId} has no uncommitted diff.`:e.diffText;case"focusTask":return`Focused task ${e.taskId} on ${e.tmuxTarget}`;case"openTask":return e.launched?`Opened task ${e.taskId} at ${e.worktreePath}`:e.worktreePath;case"runChecks":return`Checks ${e.status} for ${e.taskId}: ${e.commands.join(", ")}`;case"commitTask":return[`Committed task ${e.taskId}`,`Status: ${e.status}`,`Commit: ${e.commitSha}`,`Message: ${e.message}`].join(`
125
- `);default:return Fd(e)}}function Od(e){let t=[];return e.inspection.worktreeExists||e.task.status==="merged"&&!e.task.cleanup.preservedWorktree&&e.task.cleanup.worktreeRemovedAt||t.push(`Warning: worktree is missing at ${e.task.worktreePath}`),e.task.cleanup.warning&&!(e.task.status==="merged"&&!e.task.cleanup.worktreeRemovedAt)&&t.push(`Cleanup warning: ${e.task.cleanup.warning}`),e.task.artifacts.logPath&&!e.inspection.logExists&&t.push(`Warning: log file is missing at ${e.task.artifacts.logPath}`),e.inspection.recentFailureReason&&t.push(`Last failure: ${e.inspection.recentFailureReason}`),t}function Fd(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function jd(e){return e.checks.status}function Nd(e){if(e.type==="project"&&e.repoTargets?.length){let n=e.repoTargets.filter(s=>s.pullRequest.number);if(n.length===0)return"-";let r=n.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(r).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}qe();lt();Ze();ee();ie();import{createRequire as Up}from"node:module";import{readdir as qp,stat as Kp}from"node:fs/promises";import st from"node:path";ft();import{appendFile as Wd,mkdir as _d,readFile as Bd}from"node:fs/promises";import Ud from"node:path";var qd=80;async function Kd(e,t){await _d(Ud.dirname(e.errorLogFile),{recursive:!0}),await Wd(e.errorLogFile,Vd(t),"utf8")}async function wr(e,t){try{await Kd(e,t)}catch{}}async function ti(e,t=qd){try{let r=(await Bd(e.errorLogFile,"utf8")).trimEnd().split(`
126
- `).filter(s=>s.length>0);return{path:e.errorLogFile,lines:r.slice(Math.max(0,r.length-t)),empty:r.length===0}}catch(n){if(Gd(n))return{path:e.errorLogFile,lines:[],empty:!0};throw n}}function Vd(e){let n=[`[${new Date().toISOString()}] ${e.context}`,`message: ${e.message}`];return e.details&&e.details.trim().length>0&&(n.push("details:"),n.push(...e.details.trimEnd().split(`
127
- `).map(r=>` ${r}`))),`${n.join(`
125
+ `);default:return Nd(e)}}function Od(e){let t=[];return e.inspection.worktreeExists||e.task.status==="merged"&&!e.task.cleanup.preservedWorktree&&e.task.cleanup.worktreeRemovedAt||t.push(`Warning: worktree is missing at ${e.task.worktreePath}`),e.task.cleanup.warning&&!(e.task.status==="merged"&&!e.task.cleanup.worktreeRemovedAt)&&t.push(`Cleanup warning: ${e.task.cleanup.warning}`),e.task.artifacts.logPath&&!e.inspection.logExists&&t.push(`Warning: log file is missing at ${e.task.artifacts.logPath}`),e.inspection.recentFailureReason&&t.push(`Last failure: ${e.inspection.recentFailureReason}`),t}function Nd(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function Fd(e){return e.checks.status}function Wd(e){if(e.type==="project"&&e.repoTargets?.length){let r=e.repoTargets.filter(s=>s.pullRequest.number);if(r.length===0)return"-";let n=r.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(n).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}import{createRequire as Wf}from"node:module";import{readdir as _f,stat as Bf}from"node:fs/promises";import ct from"node:path";import{appendFile as _d,mkdir as Bd,readFile as Ud}from"node:fs/promises";import qd from"node:path";var Xo=80,Ln=async(e,t)=>{await Bd(qd.dirname(e.errorLogFile),{recursive:!0}),await _d(e.errorLogFile,Kd(t),"utf8")},Zo=async(e,t)=>{try{await Ln(e,t)}catch{}},jn=async(e,t=Xo)=>{try{let n=(await Ud(e.errorLogFile,"utf8")).trimEnd().split(`
126
+ `).filter(s=>s.length>0);return{path:e.errorLogFile,lines:n.slice(Math.max(0,n.length-t)),empty:n.length===0}}catch(r){if(Vd(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},ei=async(e,t=Xo)=>jn(e,t);function Kd(e){let r=[`[${new Date().toISOString()}] ${e.context}`,`message: ${e.message}`];return e.details&&e.details.trim().length>0&&(r.push("details:"),r.push(...e.details.trimEnd().split(`
127
+ `).map(n=>` ${n}`))),`${r.join(`
128
128
  `)}
129
129
 
130
- `}function Gd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}kt();ce();import{readFile as Hd,stat as zd}from"node:fs/promises";import kr from"node:path";var Yd=200*1024,Jd=500*1024,Qt="100000";async function ri(e,t,n){if(e.type==="project"&&e.repoTargets?.length)return Qd(e,t,n);try{let r=De(n.selectedFilePath??null,t.filePaths),s=De(n.selectedDiffPath??null,t.diffPaths),o=s?await Rt(e.worktreePath):null,[i,c]=await Promise.all([Zt(e.worktreePath,r),s?Rr(e.worktreePath,s,t.diffRows,o):Promise.resolve(Y("No diff selected","No local changes found.","empty"))]),l=s?{[s]:c}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:l,selectedFile:i,selectedDiff:c,error:null}}catch(r){let s=r instanceof Error?r.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function Qd(e,t,n){let r=De(n.selectedFilePath??null,t.filePaths),s=De(n.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([oi(e,r),(async()=>{if(!s)return Y("No diff selected","No local changes found.","empty");let l=Xt(e,s),d=l?await Rt(l.target.worktreePath).catch(()=>null):null;return ii(e,s,t.diffRows,d)})()]),c=s?{[s]:i}:{};return{...t,selectedFilePath:r,selectedDiffPath:s,diffContents:c,selectedFile:o,selectedDiff:i}}async function si(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Xd(e,t);try{await le(e);let n=await Rt(e.worktreePath),[r,s]=await Promise.all([ai(e.worktreePath),ci(e.worktreePath,n)]),o=[...new Set(s.map(h=>h.path))],i=De(t.selectedFilePath??null,r),c=De(t.selectedDiffPath??null,o),[l,d]=await Promise.all([Zt(e.worktreePath,i),c?Rr(e.worktreePath,c,s,n):Promise.resolve(Y("No diff selected","No local changes found.","empty"))]),f=c?{[c]:d}:{};return{taskId:e.id,fileRows:ui(r),filePaths:r,diffRows:s,diffPaths:o,diffContents:f,selectedFilePath:i,selectedDiffPath:c,selectedFile:l,selectedDiff:d,error:null}}catch(n){let r=n instanceof Error?n.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:Y("Files unavailable",r,"error"),selectedDiff:Y("Diff unavailable",r,"error"),error:r}}}async function Xd(e,t){let n=(e.repoTargets??[]).filter(R=>R.status==="ready"),r=await Promise.all(n.map(async R=>{let k=await Rt(R.worktreePath).catch(()=>null),[S,T]=await Promise.all([ai(R.worktreePath).catch(()=>[]),ci(R.worktreePath,k).catch(()=>[])]);return{target:R,baseRef:k,targetFiles:S,targetDiffRows:T}})),s=[],o=[];for(let{target:R,targetFiles:k,targetDiffRows:S}of r)s.push(...k.map(T=>`${R.repoId}/${T}`)),o.push(...S.map(T=>({...T,path:`${R.repoId}/${T.path}`})));let i=[...new Set(o.map(R=>R.path))].sort(),c=De(t.selectedFilePath??null,s),l=De(t.selectedDiffPath??null,i),[d,f]=await Promise.all([oi(e,c),(async()=>{if(!l)return Y("No diff selected","No local changes found.","empty");let R=Xt(e,l),k=R?r.find(S=>S.target.repoId===R.target.repoId):null;return ii(e,l,o,k?.baseRef??null)})()]),h=l?{[l]:f}:{};return{taskId:e.id,fileRows:ui(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:h,selectedFilePath:c,selectedDiffPath:l,selectedFile:d,selectedDiff:f,error:null}}async function oi(e,t){let n=Xt(e,t);if(!n)return Y("No file selected","No Git-visible files found.","empty");let r=await Zt(n.target.worktreePath,n.relativePath);return{...r,path:t,title:t??r.title}}async function ii(e,t,n,r=null){let s=Xt(e,t);return s?{...await Rr(s.target.worktreePath,s.relativePath,n.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),r),path:t,title:t}:Y(t,"Repo target is unavailable.","error",t)}function Xt(e,t){if(!t)return null;let[n,...r]=t.split("/"),s=r.join("/"),o=(e.repoTargets??[]).find(i=>i.repoId===n&&i.status==="ready")??null;return!o||s.length===0?null:{target:o,relativePath:s}}async function ai(e){let t=await v("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return fi(t.stdout)}async function ci(e,t){let[n,r,s,o]=await Promise.all([Zd(e,t),ni(e,"staged"),ni(e,"unstaged"),eu(e)]);return[...n,...r,...s,...o]}async function Zd(e,t){if(!t)return[];let[n,r]=await Promise.all([v("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),v("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=li(n.stdout),o=di(r.stdout);return s.map(i=>{let c=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:c.additions,deletions:c.deletions}}).sort((i,c)=>i.path.localeCompare(c.path))}async function ni(e,t){let n=t==="staged"?["diff","--cached"]:["diff"],[r,s]=await Promise.all([v("git",[...n,"--name-status"],{cwd:e}),v("git",[...n,"--numstat"],{cwd:e})]),o=li(r.stdout),i=di(s.stdout);return o.map(c=>{let l=i.get(c.path)??{additions:null,deletions:null};return{group:t,path:c.path,status:c.status,additions:l.additions,deletions:l.deletions}}).sort((c,l)=>c.path.localeCompare(l.path))}async function eu(e){let t=await v("git",["ls-files","--others","--exclude-standard"],{cwd:e}),n=fi(t.stdout);return await Promise.all(n.map(async s=>{let o=await Zt(e,s),i=o.status==="ready"?tu(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function li(e){return e.split(`
131
- `).map(t=>t.trim()).filter(t=>t.length>0).map(t=>{let[n="M",...r]=t.split(" ");return{status:n,path:r.at(-1)??""}}).filter(t=>t.path.length>0)}function di(e){let t=new Map;for(let n of e.split(`
132
- `)){let r=n.trim();if(!r)continue;let[s="-",o="-",...i]=r.split(" "),c=i.join(" ");c&&t.set(c,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function Rt(e){return(await L("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await L("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function Zt(e,t){if(!t)return Y("No file selected","No Git-visible files found.","empty");let n=nu(e,t);try{let r=await zd(n);if(r.size>Yd)return Y(t,`File is ${r.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,r.size);let s=await Hd(n);return ru(s)?Y(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
133
- `),byteLength:s.byteLength}}catch(r){let s=r instanceof Error?r.message:"Unable to read file.";return Y(t,s,"missing",t,null)}}async function Rr(e,t,n,r=null){if(!t)return Y("No diff selected","No local changes found.","empty");let s=[],o=n.filter(c=>c.path===t).map(c=>c.group);if(o.includes("branch")){let c=r??await Rt(e);if(c){let l=await v("git",["diff","--stat","--patch",`--unified=${Qt}`,`${c}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
134
- ${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let c=await v("git",["diff","--cached","--stat","--patch",`--unified=${Qt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`staged
135
- ${c.stdout.trimEnd()}`)}if(o.includes("unstaged")){let c=await v("git",["diff","--stat","--patch",`--unified=${Qt}`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`unstaged
136
- ${c.stdout.trimEnd()}`)}if(o.includes("untracked")){let c=await L("git",["diff","--no-index","--stat","--patch",`--unified=${Qt}`,"--","/dev/null",t],{cwd:e});c.stdout.trim().length>0&&s.push(`untracked
137
- ${c.stdout.trimEnd()}`)}let i=s.join(`
138
-
139
- `);return i.length>Jd?Y(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?Y(t,"Binary diff preview is not available in Craig.","binary",t,i.length):{path:t,status:i.length>0?"ready":"empty",title:t,lines:i.length>0?i.split(`
140
- `):["No diff for this file."],byteLength:i.length}}function ui(e){let t=[],n=new Set;for(let r of e){let s=r.split("/");for(let o=0;o<s.length-1;o+=1){let i=s.slice(0,o+1).join("/");n.has(i)||(n.add(i),t.push({kind:"directory",path:i,depth:o,label:s[o]??i}))}t.push({kind:"file",path:r,depth:s.length-1,label:s.at(-1)??r})}return t}function De(e,t){return e&&t.includes(e)?e:t[0]??null}function tu(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function fi(e){return[...new Set(e.split(`
141
- `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,n)=>t.localeCompare(n))}function nu(e,t){let n=kr.resolve(e,t),r=kr.resolve(e);if(n!==r&&!n.startsWith(`${r}${kr.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return n}function ru(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function Y(e,t,n,r=null,s=null){return{path:r,status:n,title:e,lines:[t],byteLength:s}}ie();import{access as su}from"node:fs/promises";async function pi(e,t){let n=await O(e,t),r=await ou(n.worktreePath),s={...n,status:"closed",cleanup:{...n.cleanup,preservedWorktree:r&&n.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await A(e,s),s}async function ou(e){try{return await su(e),!0}catch{return!1}}ce();import Pt from"node:path";function mi(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"\u{F06E6} ";case"js":case"jsx":case"mjs":case"cjs":return"\u{F031E} ";case"json":case"jsonc":return"\u{F0871} ";case"md":case"mdx":return"\u{F0354} ";case"yaml":case"yml":return"\u{F0B10} ";case"sh":case"bash":case"zsh":return"\u{F018D} ";case"css":case"scss":case"sass":return"\u{F031C} ";case"html":case"htm":return"\u{F031D} ";case"py":return"\u{F0320} ";case"go":return"\u{F07D3} ";case"rs":return"\u{F1617} ";case"lock":return"\u{F033E} ";case"png":case"jpg":case"jpeg":case"gif":case"svg":case"webp":return"\u{F02E9} ";default:return"\u{F0214} "}}var gi="\u{F024B} ",hi="\u{F0DCF} ",wi="\u25CB",Tr="\uEA64",ki="\uEAFE",Ri="\uEBDA",yr="\u25CB",Pr="\u25CF",br="\u2713",Ir="\u2715";function Ti(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"4fc1ff";case"js":case"jsx":case"mjs":case"cjs":return"f7df1e";case"json":case"jsonc":return"fbc02d";case"md":case"mdx":return"519aba";case"yaml":case"yml":return"e06c75";case"sh":case"bash":case"zsh":return"89e051";case"css":case"scss":case"sass":return"c792ea";case"html":case"htm":return"e06c75";case"py":return"3572a5";case"go":return"00add8";case"rs":return"dea584";case"lock":return"565f89";default:return}}ee();Ze();ee();var iu=["tasks","center","inspector","actions"],Ci=["agent","terminal"],xi=[],D="inspection",Qk=[...Ci,...xi],vi=["commit","push","refresh-checks","close-task"],au=["refresh-checks","close-task"],Ei=["task","checks","pr","setup-run","actions","next-action"],Ai=["diff","files","review"];function $i(e,t={}){let n=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,r=bu(e?.openInspectionKind)??n,s=b.runners.getEnabled(t);return{inputMode:Su(e?.inputMode),focusedRegion:yu(e?.focusedRegion),selectedRepoId:Ie(e?.selectedRepoId),selectedWorkspaceId:Ie(e?.selectedWorkspaceId),selectedTaskId:Ie(e?.selectedTaskId),selectedPtyTabId:Ie(e?.selectedPtyTabId),selectedLeftItemId:Lu(Ie(e?.selectedTaskId)),activeTab:n?D:Ie(e?.activeTab)??"agent",preferredPtyTabKind:Iu(e?.preferredPtyTabKind),inspectorSection:Tt(e?.inspectorSection,Ei,"task"),inspectionMode:Pu(e?.inspectionMode,n==="diff"?"diff":"files"),openInspectionKind:r,selectedFileTreePath:Ie(e?.selectedFileTreePath),selectedFilePath:Ie(e?.selectedFilePath),selectedDiffPath:Ie(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:Tt(e?.selectedActionId,vi,"commit"),selectedProjectTargetId:null,selectedRunner:Cu(e?.selectedRunner,s,b.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:cu(),centerZoomed:!1}}function cu(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function Di(e,t){return{...e??Re(),selectedRepoId:t.selectedRepoId,selectedWorkspaceId:t.selectedWorkspaceId,selectedTaskId:t.selectedTaskId,selectedPtyTabId:t.selectedPtyTabId,inputMode:t.inputMode,focusedRegion:t.focusedRegion,activeTab:t.activeTab,preferredPtyTabKind:t.preferredPtyTabKind,inspectorSection:t.inspectorSection,inspectionMode:t.inspectionMode,openInspectionKind:t.openInspectionKind,selectedFileTreePath:t.selectedFileTreePath,selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath,collapsedFileTreePaths:t.collapsedFileTreePaths,selectedActionId:t.selectedActionId,selectedRunner:t.selectedRunner}}function rn(e,t,n={}){let r=Du(e,t),s=_i(r),o=(s?.kind==="workspace"?t.workspaces?.find(f=>f.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(f=>f.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,c=((s?.kind==="repo"?t.repos.find(f=>f.id===s.id)??null:s?.kind==="task"?t.repos.find(f=>f.id===t.tasks.find(h=>h.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(f=>f.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(f.id))??null:null)??(o?.kind!=="project"?t.repos.find(f=>f.id===o?.primaryRepoId)??null:null)??t.repos.find(f=>f.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(f=>f.workspaceId===o.id):c?t.tasks.filter(f=>f.repoId===c):[],d=(s?.kind==="task"?l.find(f=>f.id===s.id)??null:null)??l.find(f=>f.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:n.resetInputMode?"control":e.inputMode,selectedLeftItemId:r,selectedWorkspaceId:o?.id??null,selectedRepoId:c,selectedTaskId:d?.id??null,...vu(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:ku(e,t,d?.id??null),...Eu(e,t,d?.id??null),selectedDiffPath:wu(e,t,d?.id??null),inspectorSection:Tt(e.inspectorSection,Ei,"task")}}function Mi(e,t,n={leftItemIds:[]}){if(e.inputMode==="terminal")return lu(t)?I({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):I({state:e});if(t==="q"||t==="Q")return I({state:e,exit:!0});if(t==="ESCAPE")return I({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return I({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(Cr(e.selectedLeftItemId)||xr(e.selectedLeftItemId)))return I({state:{...e,selectedRunner:vr(e.selectedRunner,n.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return yi(e,1);if(t==="SHIFT_TAB"||t==="[")return yi(e,-1);if(t==="z"||t==="Z")return I({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===D?Me(e,-1,n):Pi(e,-1,n);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===D?Me(e,1,n):Pi(e,1,n);if(t==="PAGE_UP")return Me(e,-(n.pageRows??10),n);if(t==="PAGE_DOWN")return Me(e,n.pageRows??10,n);if(t==="MOUSE_WHEEL_UP")return Me(e,-3,n);if(t==="MOUSE_WHEEL_DOWN")return Me(e,3,n);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let r=n.enabledRunnerIds??F,s=e.centerTabRunner?r.indexOf(e.centerTabRunner):-1,o=s===r.length-1?null:r[s+1];return I({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let r=xu(e,t);return I({state:{...e,preferredPtyTabKind:r,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:r,createPtyTabRunner:r==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return I({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return I({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return I({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&nn(e.selectedLeftItemId)&&e.selectedTaskId)return I({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Ou(e.selectedLeftItemId)&&e.selectedWorkspaceId)return I({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Si(e.activeTab,n.ptyTabIds??[]))return I({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Sr(e,-1,n.centerTabIds);if(e.focusedRegion==="inspector")return bi(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Sr(e,1,n.centerTabIds);if(e.focusedRegion==="inspector")return bi(e,1)}if(Ce(t)){if(e.focusedRegion==="tasks"&&(Cr(e.selectedLeftItemId)||xr(e.selectedLeftItemId))){let r=Bi(e.selectedLeftItemId),s=Ui(e.selectedLeftItemId);return I({state:{...e,selectedRepoId:r??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return I({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&nn(e.selectedLeftItemId)&&e.selectedTaskId){let r=e.selectedPtyTabId??e.activeTab;return I({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:r,selectedPtyTabId:r,preferredPtyTabKind:yt(r)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Si(e.activeTab,n.ptyTabIds??[])&&e.selectedTaskId)return I({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:yt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===D)return I({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let r=e.selectedFileTreePath??e.selectedFilePath;if(r&&(n.fileTreeDirectoryIds??[]).includes(r))return I({state:mu({...e,selectedFileTreePath:r}),changed:!0});let s=r&&(n.fileTreeFileIds??[]).includes(r)?r:e.selectedFilePath;return I({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:D,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?I({state:{...e,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!n.projectTargetIds?.length?I({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):I({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.focusedRegion!=="actions"?I({state:e}):e.selectedActionId==="refresh-checks"?I({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?I({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):I({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return I({state:e})}function Ve(e,t){return{...e,terminal:t}}function Li(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function lu(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Ce(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
142
- `}function Oi(e){return e.length===1&&e>=" "&&e!=="\x7F"}function Fi(e){return ji(e)||yt(e)!==null}function du(e){return xi.includes(e)}function ji(e){return Ci.includes(e)}function Ni(e,t){return[...e?.ptyTabs.map(n=>n.id)??[],...t?.openInspectionKind?[D]:[]]}var uu=["tasks","center","inspector"];function yi(e,t){return en(e,"focusedRegion",uu,t)}function Sr(e,t,n){let r=en(e,"activeTab",n&&n.length>0?n:$u(e),t);return!r.changed||du(r.state.activeTab)?r:{...r,state:{...r.state,selectedPtyTabId:r.state.activeTab,preferredPtyTabKind:yt(r.state.activeTab)??r.state.preferredPtyTabKind}}}function Pi(e,t,n){if(e.focusedRegion==="tasks")return fu(e,t,n.leftItemIds);if(e.focusedRegion==="center")return Sr(e,t,n.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Wi(e,t,n);if(e.inspectionMode==="diff"){let r=tn(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:r}if(n.projectTargetIds?.length){let r=tn(e,"selectedProjectTargetId",n.projectTargetIds,t);return r.changed?{...r,state:{...r.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:r}return en(e,"selectedActionId",au,t)}return en(e,"selectedActionId",vi,t)}function fu(e,t,n){let r=tn(e,"selectedLeftItemId",n,t);if(!r.changed)return r;let s=_i(r.state.selectedLeftItemId);if(s?.kind==="workspace")return{...r,state:{...r.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...r,state:{...r.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...r,state:{...r.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=Bi(r.state.selectedLeftItemId);if(o)return{...r,state:{...r.state,selectedRepoId:o}};let i=Ui(r.state.selectedLeftItemId);return i?{...r,state:{...r.state,selectedWorkspaceId:i}}:r}function Me(e,t,n){if(t===0)return I({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Wi(e,t,n);if(e.inspectionMode==="diff"){let r=tn(e,"selectedDiffPath",n.diffPathIds??[],t,!0);return r.changed?{...r,state:{...r.state,diffScrollOffset:0}}:r}return e.inspectionMode==="review"?Ii(e,"reviewScrollOffset",t,n.reviewRowCount??100,n.pageRows):I({state:e})}if(e.focusedRegion==="center"&&e.activeTab===D){if(e.openInspectionKind==="file")return Ii(e,"fileScrollOffset",t,n.fileLineCount??0,n.pageRows);if(e.openInspectionKind==="diff")return gu(e,t,n)}return I({state:e})}function pu(e,t){if(e.inspectionMode===t)return I({state:e});let n=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,r=t==="diff"||t==="files"?D:e.activeTab;return I({state:{...e,inspectionMode:t,activeTab:r,openInspectionKind:n,fileScrollOffset:t==="files"?0:e.fileScrollOffset,diffScrollOffset:t==="diff"?0:e.diffScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function bi(e,t){return pu(e,Tu(e.inspectionMode,Ai,t))}function Wi(e,t,n){let r=n.fileTreeRowIds&&n.fileTreeRowIds.length>0?n.fileTreeRowIds:n.filePathIds??[];if(r.length===0)return I({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??r[0]??null,o=r.indexOf(s??""),i=Se(o===-1?0:o+t,0,r.length-1),c=r[i]??null;if(c===e.selectedFileTreePath)return I({state:e});let l=c!==null&&(n.fileTreeFileIds??n.filePathIds??[]).includes(c);return I({state:{...e,selectedFileTreePath:c,selectedFilePath:l?c:e.selectedFilePath,activeTab:l?D:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function mu(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((n,r)=>n.localeCompare(r)),actionMessage:null}}function Ii(e,t,n,r,s=10){let o=Math.max(0,r-Math.max(1,s)),i=Se(e[t]+n,0,o);return i===e[t]?I({state:e}):I({state:{...e,[t]:i,actionMessage:null},changed:!0})}function gu(e,t,n){if(n.diffPathRanges&&n.diffPathRanges.length>0)return hu(e,t,n);let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=e.diffScrollOffset+t,c=n.diffPathIds??[];if(c.length===0||!e.selectedDiffPath){let f=Se(i,0,o);return f===e.diffScrollOffset?I({state:e}):I({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}let l=c.indexOf(e.selectedDiffPath);if(l===-1){let f=Se(i,0,o);return f===e.diffScrollOffset?I({state:e}):I({state:{...e,diffScrollOffset:f,actionMessage:null},changed:!0})}if(t>0&&i>o){let f=c[l+1]??null;return f?I({state:{...e,selectedDiffPath:f,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?I({state:e}):I({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let f=c[l-1]??null;return f?I({state:{...e,selectedDiffPath:f,activeTab:D,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?I({state:e}):I({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=Se(i,0,o);return d===e.diffScrollOffset?I({state:e}):I({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function hu(e,t,n){let r=n.diffLineCount??0,s=n.pageRows??10,o=Math.max(0,r-Math.max(1,s)),i=Se(e.diffScrollOffset+t,0,o),c=Ru(n.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&c===e.selectedDiffPath?I({state:e}):I({state:{...e,diffScrollOffset:i,selectedDiffPath:c,actionMessage:null},changed:!0})}function wu(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function ku(e,t,n){return!t.inspection||t.inspection.taskId!==n||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function Ru(e,t){return e.find(n=>t>=n.start&&t<n.end)?.path??e.at(-1)?.path??null}function en(e,t,n,r){let s=n.indexOf(e[t]),o=Se(s+r,0,n.length-1),i=n[o];return!i||i===e[t]?I({state:e}):I({state:{...e,[t]:i,actionMessage:null},changed:!0})}function tn(e,t,n,r,s=!1){if(n.length===0)return I({state:e});let o=n.indexOf(e[t]??n[0]??""),i=Se(o===-1?0:o+r,0,n.length-1),c=n[i]??null;return c===e[t]?I({state:e}):I({state:{...e,[t]:c,actionMessage:null},changed:!0,refreshInspection:s})}function Tu(e,t,n){let r=t.indexOf(e);return t[Se(r+n,0,t.length-1)]??e}function I(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function Tt(e,t,n){return t.includes(e??"")?e:n}function yu(e){return e==="tabs"?"center":Tt(e,iu,"tasks")}function Pu(e,t){return e==="checks"||e==="actions"||e==="review"?"review":Tt(e,Ai,t)}function bu(e){return e==="file"||e==="diff"?e:null}function Iu(e){return e==="terminal"?"terminal":"agent"}function Su(e){return e==="terminal"?"terminal":"control"}function Cu(e,t=[...F],n="codex"){return e&&b.runners.isRunnerType(e)&&t.includes(e)?e:n}function vr(e,t=F){let n=t.length>0?t:F,r=n.indexOf(e);return n[(r+1)%n.length]??n[0]??"codex"}function yt(e){let t=F.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function xu(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":yt(e.activeTab)??e.preferredPtyTabKind}function vu(e,t,n){if(!e)return{activeTab:t===D?t:"agent",selectedPtyTabId:null};let r=e.ptyTabs.find(c=>c.id===n)??null,s=e.selectedPtyTabId?e.ptyTabs.find(c=>c.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(c=>c.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(ji(t)){let l=e.ptyTabs.find(d=>d.kind===t)??null??s??r??e.ptyTabs[0]??null;return{activeTab:l?.id??D,selectedPtyTabId:l?.id??null}}if(t===D)return{activeTab:D,selectedPtyTabId:r?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??r??e.ptyTabs[0]??null;return{activeTab:i?.id??D,selectedPtyTabId:i?.id??null}}function Eu(e,t,n){if(!t.inspection||t.inspection.taskId!==n)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let r=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?Au(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:r,collapsedFileTreePaths:s}}function Au(e,t){let n=new Set;if(t){let r=t.split("/");for(let s=1;s<r.length;s+=1)n.add(r.slice(0,s).join("/"))}return e.filter(r=>r.kind==="directory"&&!r.path.includes("/")&&!n.has(r.path)).map(r=>r.path).sort((r,s)=>r.localeCompare(s))}function $u(e){return[e.selectedPtyTabId,e.openInspectionKind?D:null].filter(t=>typeof t=="string")}function Si(e,t){return t.includes(e)}function Du(e,t){let n=Mu(t);return e.selectedLeftItemId&&n.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&n.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&n.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&n.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:n[0]??null}function Mu(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function _i(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function Ie(e){return typeof e=="string"?e:null}function Lu(e){return e?`task:${e}`:null}function nn(e){return typeof e=="string"&&e.startsWith("task:")}function Cr(e){return typeof e=="string"&&e.startsWith("new-task:")}function xr(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function Ou(e){return typeof e=="string"&&e.startsWith("workspace:")}function Bi(e){return Cr(e)?e.slice(9):null}function Ui(e){return xr(e)?e.slice(19):null}function Se(e,t,n){return Math.min(n,Math.max(t,e))}var on="empty",q={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Gi(e,t){let n=Nu(t,e),r=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=n?t.tasks.filter(T=>T.workspaceId===n.id):t.tasks,o=n?.kind==="project"?s:r?s.filter(T=>T.repoId===r.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,c=i?.type==="project",l=yf(t.tasks),d=Bu(e,i),f=_u(e,i,d),h=f.find(T=>T.id===d)??f[0]??{id:"agent",label:"CODEX"},R=t.inspection?.taskId===i?.id?t.inspection:null,k=r?.name??"no repo",S=i?b.runners.getDisplayName(i.runner):b.runners.getDisplayName(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${r?`[${r.name}]`:"[no repo]"} \xB7 ${b.runners.getDisplayName(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${b.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:nn(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?i===null?"n new task Tab tasks Esc pause ? help":d===D?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${b.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?c?"\u2191\u2193 targets Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?"\u2191\u2193 navigate Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:Pt.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Pt.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:S},leftTree:Fu(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>Pf(T,l[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":h.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:k,agent:S},centerTranscript:Wu(d,e,r,i,e.workspaceBrowser,R,n),tabs:f,rightContext:Tf(r,i),rightInspection:ef(e,i,R)}}function Fu(e,t){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return ju(n,e,t.repos,t.tasks);let r=t.workspaces;if(r.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of r){let i=e.selectedLeftItemId===`workspace:${o.id}`;n.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:i,focused:i&&e.focusedRegion==="tasks"});let c=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],l=t.tasks.filter(d=>d.workspaceId===o.id);if(l.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of l){let f=e.selectedLeftItemId===`task:${d.id}`,h=f?"\u25B8":"\u2022",R=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,k={id:`task:${d.id}`,taskId:d.id,text:`${h} ${R}`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks"},S=zi(d);S&&(k.prBadge=S),n.push(k)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,f=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${b.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:f,focused:f&&e.focusedRegion==="tasks",muted:!f})}else{n.push({text:` Repos (${c.length})`,indent:0,muted:!0});for(let d of c.slice(0,6)){let f=t.repos.find(h=>h.id===d);n.push({text:` \xB7 ${f?.name??d}`,indent:0,muted:!0})}c.length>6&&n.push({text:` \xB7 ${c.length-6} more`,indent:0,muted:!0})}}let s=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&e.focusedRegion==="tasks"}),n}function ju(e,t,n,r){if(n.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of n){let i=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:i,focused:i&&t.focusedRegion==="tasks"});let c=r.filter(f=>f.repoId===o.id);if(c.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let f of c){let h=t.selectedLeftItemId===`task:${f.id}`,R=h?"\u25B8":"\u2022",k=f.title.length>28?`${f.title.slice(0,25)}\u2026`:f.title,S={id:`task:${f.id}`,taskId:f.id,text:`${R} ${k}`,indent:2,selected:h,focused:h&&t.focusedRegion==="tasks"},T=zi(f);T&&(S.prBadge=T),e.push(S)}let l=`new-task:${o.id}`,d=t.selectedLeftItemId===l;e.push({id:l,text:`+ New Task [${b.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let s=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&t.focusedRegion==="tasks"}),e}function Nu(e,t){let n=e.workspaces??[];if(!e.workspaces)return null;let r=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return r?n.find(s=>s.id===r.workspaceId)??null:t.selectedWorkspaceId?n.find(s=>s.id===t.selectedWorkspaceId)??null:n[0]??null}function Wu(e,t,n,r,s,o=null,i=null){if(s){let l=s.entries.length===0?["No directories or git repos here."]:s.entries.map((d,f)=>{let h=f===s.selectedIndex?"\u25B8":" ",R=d.kind==="repo"?" [git repo]":"/";return`${h} ${d.name}${R}`});return me(["Browse for a workspace to register.",s.cwd,"",...l,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!n)return me(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!r){let l=i?.kind==="project",d=l?i.name??"this workspace":n.name,f=l?"Project Task":"Task";return me([`No tasks in ${d}.`,"",`Press n or choose + New ${f} to create one with ${b.runners.getDisplayName(t.selectedRunner)}.`])}let c=r.ptyTabs.find(l=>l.id===e)??null;return c?c.kind==="agent"?me([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):me([`${c.title} tab ready for ${r.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===D&&t.openInspectionKind==="file"?Ku(r,o,t.fileScrollOffset):e===D&&t.openInspectionKind==="diff"?Vu(r,o,t.diffScrollOffset):r.ptyTabs.length===0&&!t.openInspectionKind?me(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):me(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function _u(e,t,n){let r=t?.ptyTabs.map(o=>({id:o.id,label:Uu(o)}))??[];if(!t)return[{id:on,label:"EMPTY",active:n===on,focused:e.focusedRegion==="center"&&n===on}];let s=e.openInspectionKind||n===D?[{id:D,label:qu(e)}]:[];return[...r,...s].map(o=>({...o,active:o.id===n,focused:e.focusedRegion==="center"&&o.id===n}))}function Bu(e,t){return t?t.ptyTabs.some(n=>n.id===e.activeTab)||e.activeTab===D&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(n=>n.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??D:e.selectedPtyTabId&&t.ptyTabs.some(n=>n.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??D:on}function Uu(e){return e.title.toUpperCase()}function qu(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,n=t?Pt.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${n} \u0394`:n}function Ku(e,t,n){if(!e)return me(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return me(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let r=t.selectedFile,s=Hi(r.path??r.title);return[{text:r.title},{text:`${r.byteLength===null?"size unknown":`${r.byteLength} bytes`} \xB7 ${r.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Gu(r.lines,n,s)]}function Vu(e,t,n){if(!e)return me(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return me(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let r=t.selectedDiff,s=Hi(r.path??r.title);return[{text:r.title},{text:`${t.diffPaths.length} changed files \xB7 ${r.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Hu(r.lines,n,s)]}function me(e){return e.map(t=>({text:t}))}function Gu(e,t,n){let r=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let c=s+i+1;return{text:`${`${String(c).padStart(r," ")} \u2502 `}${o}`,segments:[{text:String(c).padStart(r," "),style:{fg:q.lineNumber}},{text:" \u2502 ",style:{fg:q.gutter}},...Er(o,n)],tone:"default"}})}function Hu(e,t,n){let r=zu(e),s=Math.max(0,Math.min(t,Math.max(0,r.length-1)));return r.slice(s).map(o=>Yu(o,n))}function zu(e){let t=[],n=0,r=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){n=Number.parseInt(o[1]??"0",10),r=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:n,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),n+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:r,marker:"+",text:s.slice(1),kind:"add"}),r+=1;continue}if(s.startsWith(" ")){if(n===0&&r===0)continue;t.push({oldNumber:n,newNumber:r,marker:" ",text:s.slice(1),kind:"context"}),n+=1,r+=1;continue}}}return t}function Yu(e,t){let n=qi(e.oldNumber),r=qi(e.newNumber),s=e.kind==="delete"?n:r,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:q.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:q.diffAdd}:null,i=`${s} \u2502 ${e.text}`,c=o?Qu(Er(e.text,t),o.bg,o.fallbackFg):Er(e.text,t),l=o?{fg:q.lineNumber,bg:o.bg}:{fg:q.lineNumber},d=o?{fg:q.gutter,bg:o.bg}:{fg:q.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...c],fullBleed:o!==null}}function qi(e){return e===null?" ":String(e).padStart(4," ")}function Hi(e){let t=Pt.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function Er(e,t){return t==="diff"?Ju(e):t==="markdown"?Xu(e):t==="json"?Ar(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Ar(e,/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)|\/\/.*$|\/\*.*?\*\/|\b(const|let|var|function|return|if|else|for|while|class|interface|type|import|export|from|async|await|new|extends|implements|switch|case|break|continue|try|catch|throw|true|false|null|undefined)\b|-?\b\d+(?:\.\d+)?\b/g):[{text:e}]}function Ju(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:q.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:q.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:q.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:q.diffMeta}}]:[{text:e}]}function Qu(e,t,n){return e.map(r=>({text:r.text,style:{...r.style??{fg:n},bg:t}}))}function Xu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:q.markup,bold:!0}}]:Ar(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Ar(e,t){let n=[],r=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>r&&n.push({text:e.slice(r,i)}),n.push({text:o,style:Zu(o)}),r=i+o.length}return r<e.length&&n.push({text:e.slice(r)}),n.length>0?n:[{text:e}]}function Zu(e){return e.startsWith("//")||e.startsWith("/*")?{fg:q.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:q.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:q.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:q.markup}:{fg:q.keyword}}function ef(e,t,n){let r=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&r?t.repoTargets?.find(c=>c.repoId===r)??null:null,o=t?.type==="project"?Yi(t.repoTargets??[]):s?.pullRequest??(t?G(t):null),i=[tf(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Xi(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,...gf(e,n)]}:{title:"",rows:[...i,...wf(e,n)]}}function tf(e,t){let n=e.inspectionMode,r=[{label:"CHANGES",active:n==="diff"},{label:"FILES",active:n==="files"},{label:"REVIEW",active:n==="review"}],s=[];for(let l=0;l<r.length;l++){let d=r[l];l>0&&s.push({text:" "});let f=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:f}})}let o=$r(t),i=Dr(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function Ki(e){return[{text:" "},$r(e),{text:" "},Dr(e)]}function zi(e){if(e.type==="project"&&e.repoTargets?.length){let n=Yi(e.repoTargets);return n?Ki(n):null}let t=G(e);return t?.number?Ki(t):null}function Yi(e){let t=e.filter(s=>s.status==="ready"),n=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(n.length===0)return null;let r=rf(n);return{number:-1,status:nf(n),draft:n.some(s=>s.draft),mergeable:n.length===t.length&&n.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:n.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":n.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":n.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:n.flatMap(s=>s.requiredChecks),aggregateReadiness:r}}function nf(e){return e.some(t=>t.status==="open")?"open":e.every(t=>t.status==="merged")?"merged":e.some(t=>t.status==="closed")?"closed":e[0]?.status??null}function rf(e){let t=e.map(n=>Ji(n));return t.some(n=>n==="failed")?"failed":t.some(n=>n==="pending")?"pending":t.length>0&&t.every(n=>n==="success")?"success":"none"}function $r(e){return!e||!e.number?{text:wi,style:{fg:"565f89"}}:e.status==="merged"?{text:ki,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Ri,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Tr,style:{fg:"565f89"}}:{text:Tr,style:{fg:"9ece6a"}}}function Dr(e){return e?.aggregateReadiness?Vi(e.aggregateReadiness):Vi(Ji(e))}function Vi(e){return e==="failed"?{text:Ir,style:{fg:"f7768e"}}:e==="pending"?{text:Pr,style:{fg:"e0af68"}}:e==="success"?{text:br,style:{fg:"9ece6a"}}:{text:yr,style:{fg:"565f89"}}}function Ji(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(n=>n.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(n=>n.status==="success"||n.status==="skipped")?Qi(e)?"failed":sf(e)?"success":"pending":"pending"}function sf(e){return!!(e.mergeable&&!e.draft&&!Qi(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Qi(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Xi(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return of(e,t);let n=G(t),r=ea("pr",t.branch,n??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==n&&(o.status==="merged"||o.status==="closed")).length;return s>0&&r.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),af(r,e)}var sn=32;function of(e,t){let n=[],r=t.repoTargets??[],s=e.selectedProjectTargetId??r[0]?.repoId??null;for(let i of r){let c=s===i.repoId,l=e.focusedRegion==="inspector"&&c,d=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let h=i.failureReason?i.failureReason.slice(0,14):i.status,R=sn-h.length-1,k=d.length>R?d.slice(0,R-1)+"\u2026":d,S=sn-k.length-h.length;n.push({id:`project-review:${i.repoId}`,text:k+" ".repeat(Math.max(1,S))+h,selected:c,focused:l,muted:!0})}else{let f=$r(i.pullRequest),h=Dr(i.pullRequest),R=`${f.text} ${h.text}`,k=sn-R.length-1,S=d.length>k?d.slice(0,k-1)+"\u2026":d,T=sn-S.length-R.length,a=S+" ".repeat(Math.max(1,T));n.push({id:`project-review:${i.repoId}`,text:a+R,selected:c,focused:l,segments:[{text:a},{...f,text:f.text},{text:" "},{...h,text:h.text}]})}}let o=r.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(n.push({id:"target-detail-spacer",text:""}),n.push(...ea("target",o.branch,o.pullRequest))),n}function Zi(e,t){return Xi(e,t).length}function ea(e,t,n){let r=h=>`${e}-${h}`;if(!n.number)return[{id:r("no-pr"),text:t,muted:!0}];let s=[],o=`#${n.number}`;s.push(n.url?{id:r("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:n.url}]}:{id:r("pr-number"),text:o});let i=n.baseBranch??"?",c=n.headBranch??t;s.push({id:r("pr-branches"),text:`${i} \u2192 ${c}`,muted:!0});let l=cf(n.reviewDecision,n.mergeStateStatus),d=l&&l!=="review approved"?"merge blocked":n.mergeable?"merge ready":n.mergeStateStatus?`merge ${n.mergeStateStatus}`:"merge unknown";l?s.push({id:r("pr-merge"),text:`${d} \xB7 ${l}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:l,style:{fg:lf(n.reviewDecision,n.mergeStateStatus)}}]}):s.push({id:r("pr-merge"),text:d,muted:!0}),s.push({id:r("pr-synced"),text:`synced ${ta(n.lastSyncedAt)}`,muted:!0}),s.push({id:r("checks-spacer"),text:""}),s.push({id:r("checks-header"),text:"Checks"}),n.requiredChecks.length?s.push(...n.requiredChecks.map(df)):s.push({id:r("checks-none"),text:n.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let f=n.comments??[];return f.length>0&&(s.push({id:r("comments-spacer"),text:""}),s.push({id:r("comments-header"),text:`Review comments (${f.length})`}),s.push(...f.slice(-4).flatMap((h,R)=>uf(h,r(`comment:${R}`))))),s}function af(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let n=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((r,s)=>({...r,selected:t.reviewScrollOffset===0&&r.selected||s===n,focused:t.reviewScrollOffset===0&&r.focused||s===n}))}function cf(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function lf(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function ta(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;let r=Math.floor(n/60);if(r<60)return`${r}m ago`;let s=Math.floor(r/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function df(e){let{icon:t,color:n}=pf(e.status),r=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${r.padEnd(16," ")} ${mf(e.status)}`,color:n,muted:!1}}function uf(e,t){let n=e.author??"unknown",r=e.createdAt?` \xB7 ${ta(e.createdAt)}`:"",s=ff(e.body,30),o=s.slice(0,4),i=o.length<s.length,c=[{id:`${t}:author`,text:`${n}${r}`,muted:!0},...o.map((l,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return c.push({id:`${t}:spacer`,text:"",muted:!0}),c}function ff(e,t){let n=e.split(/\s+/).filter(Boolean);if(n.length===0)return[];let r=[],s="";for(let o of n){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(r.push(s),s=o)}return s&&r.push(s),r}function pf(e){switch(e){case"success":return{icon:br,color:"9ece6a"};case"pending":return{icon:Pr,color:"e0af68"};case"failed":return{icon:Ir,color:"f7768e"};case"skipped":return{icon:yr,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function mf(e){return e==="success"?"passing":e==="failed"?"failing":e}function gf(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let n=new Map(t.diffRows.map(o=>[o.path,o.status])),r=hf(t.fileRows,e.collapsedFileTreePaths),s=e.selectedFileTreePath??t.selectedFilePath;return r.map(o=>{let i=o.kind==="file"?n.get(o.path):void 0,c=i==="A"?"9ece6a":i==="M"?"e0af68":i==="D"?"f7768e":i==="??"?"565f89":void 0,l=o.kind==="directory"?e.collapsedFileTreePaths.includes(o.path)?gi:hi:mi(o.label),d=o.kind==="directory"?"7aa2f7":Ti(o.label),f=" ".repeat(o.depth),h=d?{text:l,style:{fg:d}}:{text:l},R=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:c?{text:o.label,style:{fg:c}}:{text:o.label},k=[{text:f},h,R];return{id:o.path,text:`${f}${l}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:k}})}function hf(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function wf(e,t){if(!t)return[{id:"empty",text:"No task diff index.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.diffRows.length===0)return[{id:"empty",text:t.filePaths.some(s=>s.startsWith("repo_"))?"No changes in project task worktrees. Edits in the original repos are outside this task.":"No local changes.",muted:!0}];if(kf(t))return Rf(e,t);let n=[];for(let r of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===r);s.length!==0&&(n.push({id:r,text:r.toUpperCase(),muted:!0}),n.push(...s.map(o=>na(o,e,t))))}return n}function kf(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Rf(e,t){let n=[],r=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of r){let o=t.diffRows.filter(c=>c.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;n.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let c of["branch","staged","unstaged","untracked"]){let l=o.filter(d=>d.group===c);l.length!==0&&(n.push({id:`repo-diff:${s}:${c}`,text:` ${c}`,muted:!0}),n.push(...l.map(d=>na(d,e,t,s.length+1))))}}return n}function na(e,t,n,r=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",c=r>0?e.path.slice(r):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${c} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??n.selectedDiffPath),focused:e.path===(t.selectedDiffPath??n.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function Tf(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:b.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Pt.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function yf(e){return e.reduce((t,n)=>(t[n.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Pf(e,t){return{name:b.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var an={width:120,height:36},ge={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function Le(e,t){return{width:Math.max(e??an.width,an.width),height:Math.max(t??an.height,an.height)}}import{spawn as Vf}from"node:child_process";import{createHash as Gf}from"node:crypto";import{createServer as Hf,createConnection as ua}from"node:net";import{openSync as zf}from"node:fs";import{mkdir as Yf,readFile as Wr,rm as Ge,writeFile as Jf}from"node:fs/promises";import{tmpdir as Qf}from"node:os";import nt from"node:path";import{createRequire as Df}from"node:module";import bf from"@xterm/headless";var If=1e3,Sf=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function sa(e){return new bf.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:If,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function oa(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Lr(e,t){return new Promise(n=>{e.write(t,n)})}function ia(e,t=0){let n=e.buffer.active,r=[],s=n.getNullCell(),o=n.baseY+n.cursorY,i=Math.max(0,n.baseY-t);for(let c=0;c<e.rows;c+=1){let l=n.getLine(i+c);if(!l){r.push({segments:[]});continue}let d=[];for(let f=0;f<e.cols;f+=1){let h=l.getCell(f,s);!h||h.getWidth()===0||d.push({text:h.getChars()||" ",style:vf(h,i+c===o&&f===n.cursorX)})}r.push({segments:Cf(xf(d))})}return r}function Cf(e){let t=[];for(let n of e){let r=t.at(-1);if(r&&$f(r.style,n.style)){r.text+=n.text;continue}let s={text:n.text};aa(n.style)||(s.style=n.style),t.push(s)}return t}function xf(e){let t=e.length;for(;t>0;){let n=e[t-1];if(!n||n.text!==" "||!aa(n.style))break;t-=1}return e.slice(0,t)}function vf(e,t){let n={},r=ra(e,"fg"),s=ra(e,"bg");return r&&(n.fg=r),s&&(n.bg=s),e.isBold()&&(n.bold=!0),e.isDim()&&(n.dim=!0),e.isItalic()&&(n.italic=!0),e.isUnderline()&&(n.underline=!0),(e.isInverse()||t)&&(n.inverse=!0),n}function ra(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let r=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return r?s.toString(16).padStart(6,"0"):Sf[s]??Ef(s)}function Ef(e){if(e>=16&&e<=231){let t=e-16,n=Math.floor(t/36),r=Math.floor(t%36/6),s=t%6;return[n,r,s].map(Af).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(n=>n.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function Af(e){return e===0?0:55+e*40}function $f(e,t){return Mr(e)===Mr(t)}function Mr(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function aa(e){return Mr(e)===""}var Mf=Df(import.meta.url),Lf=/^CTRL_([A-Z])$/,Of="\x1B[6n",Ff="\x1B[c",jf="\x1B[?u",Nf={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
143
- `,TAB:" ",SHIFT_TAB:"\x1B[Z",BACK_TAB:"\x1B[Z",BACKSPACE:"\x7F",DELETE:"\x1B[3~",ESCAPE:"\x1B",UP:"\x1B[A",DOWN:"\x1B[B",RIGHT:"\x1B[C",LEFT:"\x1B[D",HOME:"\x1B[H",END:"\x1B[F",PAGE_UP:"\x1B[5~",PAGE_DOWN:"\x1B[6~",CTRL_C:"",CTRL_D:""},cn=class{sessions=new Map;shell;env;spawn;onUpdate;resolveSessionSpec;attachedTabId=null;constructor(t){this.shell=t.shell??process.env.SHELL??"/bin/zsh",this.env=t.env??process.env,this.spawn=t.spawn,this.onUpdate=t.onUpdate,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,n,r,s){let o=this.sessions.get(n);if(o)if(o.status!=="running")Or(o),this.sessions.delete(n);else return this.attachedTabId=n,o.scrollbackLines=0,ca(o,r),this.getViewState(n);let i=this.createSession(t,n,r,s);return this.sessions.set(n,i),this.attachedTabId=n,this.getViewState(n)}write(t){let n=this.getAttachedSession();!n||n.status!=="running"||n.pty.write(t)}writeKey(t){let n=Wf(t);n!==null&&this.write(n)}scrollViewport(t){let n=this.getAttachedSession();if(!n||t===0)return;let r=n.terminal.buffer.active.baseY;n.scrollbackLines=Math.max(0,Math.min(r,n.scrollbackLines-t))}resize(t){let n=this.getAttachedSession();n&&ca(n,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let n=this.sessions.get(t);n&&(Or(n),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Or(t);this.sessions.clear(),this.attachedTabId=null}getViewState(t){if(!t)return{status:"idle",rows:[],error:null,scrolledBack:!1};let n=this.sessions.get(t);return n?{status:n.status,rows:ia(n.terminal,n.scrollbackLines),error:n.error,scrolledBack:n.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,n,r,s){let o=this.spawn??Bf().spawn,i=sa(r),c=s??this.resolveSessionSpec(t,n),l=_e({...this.env,...c.env??{}}),{executable:d,args:f}=Uf(this.shell,c.command,{cwd:c.cwd,env:l}),h=o(d,f,{name:"xterm-256color",cols:r.columns,rows:r.rows,cwd:c.cwd,env:qf(l)}),R={taskId:t,tabId:n,pty:h,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0};return R.disposables.push(h.onData(k=>{Kf(h,k),Lr(R.terminal,k).then(()=>{this.onUpdate?.(R.tabId)})})),R.disposables.push(h.onExit(k=>{R.status="exited",Lr(R.terminal,`\r
144
- [process exited ${k.exitCode}]`).then(()=>{this.onUpdate?.(R.tabId)})})),R}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function Wf(e){if(e.length===1)return e;let t=Nf[e];if(t!==void 0)return t;let n=Lf.exec(e);return n?.[1]?String.fromCharCode(n[1].charCodeAt(0)-64):null}function ca(e,t){_f(e.pty,t),oa(e.terminal,t)}function Or(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function _f(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Bf(){return Mf("node-pty")}function Uf(e,t,n){if(t.length===0)return{executable:e,args:[]};let s=`${[Be(t[0],n),...t.slice(1)].map(la).join(" ")}; exec ${la(e)} -l`;return{executable:e,args:["-lc",s]}}function la(e){return`'${e.replaceAll("'","'\\''")}'`}function qf(e){let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&(t[n]=r);return t.TERM=t.TERM??"xterm-256color",t}function Kf(e,t){for(let n=0;n<Fr(t,Of);n+=1)e.write("\x1B[1;1R");for(let n=0;n<Fr(t,Ff);n+=1)e.write("\x1B[?1;2c");for(let n=0;n<Fr(t,jf);n+=1)e.write("\x1B[?0u")}function Fr(e,t){if(t.length===0)return 0;let n=0,r=e.indexOf(t);for(;r!==-1;)n+=1,r=e.indexOf(t,r+t.length);return n}var _r=3;async function fa(e){let t=Br(e.paths);await Xf(t,e.paths,e.spawnDaemon);let n=await ka(t.socketPath),r=new jr(n,e);return await r.ready(),r}async function pa(e,t={}){let n=Br(e);await Yf(e.runtimeDir,{recursive:!0}),await Ge(n.socketPath,{force:!0});let r=new Nr(e,t),s=Hf(o=>r.handleConnection(o));await sp(s,n.socketPath),await Jf(n.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=()=>{r.closeClients(),s.close(()=>o())};r.onShutdown=i,process.once("SIGTERM",i),process.once("SIGINT",i)}),await Ge(n.socketPath,{force:!0}),await Ge(n.pidPath,{force:!0}),r.disposeAll()}async function ma(e){let t=Br(e);return await dn(t.socketPath)?(await ha(t.socketPath),!0):!1}var jr=class{constructor(t,n){this.socket=t;this.options=n,t.setEncoding("utf8"),t.on("data",r=>this.handleData(String(r))),t.on("error",r=>this.rejectAll(r instanceof Error?r:new Error(String(r)))),t.on("close",()=>{this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed."))})}socket;nextRequestId=1;pending=new Map;viewCache=new Map;attachedTabId=null;buffer="";closed=!1;options;async ready(){if((await this.send({type:"ping"})).protocolVersion!==_r)throw new Error("Craig PTY daemon protocol mismatch.")}async ensureSession(t,n,r){let s=await this.send({type:"ensureSession",taskId:t,tabId:n,size:r,spec:this.options.resolveSessionSpec?.(t,n)??{cwd:this.options.workspaceRoot,command:[]}});this.attachedTabId=n;let o=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(n,o),o}async hydrateSessions(t){for(let n of t)try{let r=await this.send({type:"hydrateSession",tabId:n});r.view&&this.viewCache.set(n,r.view)}catch(r){let s=r instanceof Error?r.message:String(r);this.viewCache.set(n,{status:"failed",rows:[],error:s})}}async pruneStale(t){await this.send({type:"pruneStale",keepTabIds:t})}write(t){this.send({type:"write",input:t}).catch(()=>{})}writeKey(t){this.send({type:"writeKey",key:t}).catch(()=>{})}scrollViewport(t){this.send({type:"scrollViewport",lines:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}resize(t){this.send({type:"resize",size:t}).then(n=>{this.attachedTabId&&n.view&&this.viewCache.set(this.attachedTabId,n.view)}).catch(()=>{})}detach(){this.attachedTabId=null,this.send({type:"detach"}).catch(()=>{})}disposeSession(t){this.viewCache.delete(t),this.attachedTabId===t&&(this.attachedTabId=null),this.send({type:"disposeSession",tabId:t}).catch(()=>{})}disposeAll(){this.attachedTabId=null,!this.closed&&(this.socket.end(),this.closed=!0)}getViewState(t){return t?this.viewCache.get(t)??{status:"idle",rows:[],error:null,scrolledBack:!1}:{status:"idle",rows:[],error:null,scrolledBack:!1}}async requestShutdown(){await this.send({type:"shutdown"})}async send(t){if(this.closed)throw new Error("Craig PTY daemon connection is closed.");let n=this.nextRequestId;this.nextRequestId+=1;let r={...t,id:n},s=new Promise((i,c)=>{this.pending.set(n,{resolve:i,reject:c})});if(this.socket.destroyed)throw this.pending.delete(n),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(r)}
145
- `);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
- `);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()}},Nr=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,n){this.runtime=new cn({...n,workspaceRoot:t.workspaceRoot,onUpdate:r=>this.broadcastUpdate(r)})}handleConnection(t){let n="";this.clients.add(t),t.setEncoding("utf8"),t.on("data",r=>{n+=String(r);let s=n.indexOf(`
148
- `);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{ln(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(r);ln(t,{id:r.id,ok:!0,...r.type==="ping"?{protocolVersion:_r}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);ln(t,{id:r.id,ok:!1,error:o})}}handleRequest(t){switch(t.type){case"ping":return null;case"ensureSession":return this.attachedTabId=t.tabId,this.runtime.ensureSession(t.taskId,t.tabId,t.size,t.spec);case"hydrateSession":return this.runtime.getViewState(t.tabId);case"write":return this.runtime.write(t.input),null;case"writeKey":return this.runtime.writeKey(t.key),null;case"scrollViewport":return this.runtime.scrollViewport(t.lines),this.runtime.getViewState(this.attachedTabId);case"resize":return this.runtime.resize(t.size),this.runtime.getViewState(this.attachedTabId);case"detach":return this.runtime.detach(),this.attachedTabId=null,null;case"disposeSession":return this.runtime.disposeSession(t.tabId),this.attachedTabId===t.tabId&&(this.attachedTabId=null),null;case"pruneStale":{let n=new Set(t.keepTabIds);for(let r of this.runtime.sessionTabIds())n.has(r)||(this.runtime.disposeSession(r),this.attachedTabId===r&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(t.tabId);case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return op(t)}}broadcastUpdate(t){let n=this.runtime.getViewState(t);for(let r of this.clients)ln(r,{type:"update",tabId:t,view:n})}};function Br(e){let t=Gf("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:nt.join(Qf(),`craig-${t}.sock`),pidPath:nt.join(e.runtimeDir,"pty-daemon.pid")}}async function Xf(e,t,n){if(await Zf(e.socketPath,1e3))return;await dn(e.socketPath)&&(await ha(e.socketPath),await da(e.socketPath,1e3)),await dn(e.socketPath)&&(await np(e),await da(e.socketPath,1e3)),await tp(e);let r=t.workspaceRoot;if(n)n(r);else{let{command:i,args:c}=ep(r),l=zf(nt.join(t.runtimeDir,"pty-daemon.log"),"a");Vf(i,c,{cwd:r,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await ga(e.socketPath))return;await Ur(50)}let o=await Wr(nt.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
150
- ${o.slice(-2e3)}`:""}`)}async function ga(e){let t=await rp(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===_r}async function Zf(e,t){let n=Date.now();for(;Date.now()-n<t;){if(await ga(e))return!0;await Ur(50)}return!1}function ep(e){let t=process.argv[1];if(t?.endsWith(".ts")){let r=nt.resolve(nt.dirname(t),"..","node_modules",".bin","tsx");return{command:zn("tsx")??r,args:[t,"__craig-daemon",e]}}let n=process.argv.slice(1);return{command:process.execPath,args:[...process.execArgv,...n,"__craig-daemon",e]}}async function tp(e){let t=await Wr(e.pidPath,"utf8").catch(()=>null);if(t){let n=Number(t.trim());if(Number.isInteger(n)&&n>0&&Ra(n))return}await Ge(e.socketPath,{force:!0}),await Ge(e.pidPath,{force:!0})}async function dn(e){let t=await ka(e).catch(()=>null);return t?(t.end(),!0):!1}async function ha(e){await wa(e,{id:1,type:"shutdown"}).catch(()=>null)}async function np(e){let t=await Wr(e.pidPath,"utf8").catch(()=>null),n=Number(t?.trim());if(!Number.isInteger(n)||n<=0||!Ra(n)){await Ge(e.socketPath,{force:!0});return}try{process.kill(n,"SIGTERM")}catch{await Ge(e.socketPath,{force:!0})}}async function rp(e){return wa(e,{id:1,type:"ping"})}function wa(e,t){return new Promise((n,r)=>{let s=ua(e),o="",i=setTimeout(()=>{s.destroy(),r(new Error("Craig PTY daemon request timed out."))},500),c=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
151
- `)),s.once("error",l=>{c(),r(l)}),s.on("data",l=>{o+=String(l);let d=o.indexOf(`
152
- `);if(d===-1)return;let f=o.slice(0,d);c(),s.end();try{n(JSON.parse(f))}catch(h){r(h instanceof Error?h:new Error(String(h)))}}),s.once("close",()=>c())})}async function da(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!await dn(e))return;await Ur(50)}}function ka(e){return new Promise((t,n)=>{let r=ua(e);r.once("connect",()=>t(r)),r.once("error",n)})}function sp(e,t){return new Promise((n,r)=>{e.once("error",r),e.listen(t,n)})}function ln(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
153
- `)}catch{}}function Ra(e){try{return process.kill(e,0),!0}catch{return!1}}function Ur(e){return new Promise(t=>setTimeout(t,e))}function op(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}import bR from"picocolors";var ip=[" \u2584\u2588\u2588\u2588\u2588\u2584 \u2588\u2588\u2580\u2588\u2588\u2588 \u2584\u2584\u2584 \u2588\u2588\u2593 \u2584\u2588\u2588\u2588\u2588"," \u2592\u2588\u2588\u2580 \u2580\u2588 \u2593\u2588\u2588 \u2592 \u2588\u2588\u2592\u2592\u2588\u2588\u2588\u2588\u2584 \u2593\u2588\u2588\u2592 \u2588\u2588\u2592 \u2580\u2588\u2592"," \u2592\u2593\u2588 \u2584 \u2593\u2588\u2588 \u2591\u2584\u2588 \u2592\u2592\u2588\u2588 \u2580\u2588\u2584 \u2592\u2588\u2588\u2592\u2592\u2588\u2588\u2591\u2584\u2584\u2584\u2591"," \u2592\u2593\u2593\u2584 \u2584\u2588\u2588\u2592\u2592\u2588\u2588\u2580\u2580\u2588\u2584 \u2591\u2588\u2588\u2584\u2584\u2584\u2584\u2588\u2588 \u2591\u2588\u2588\u2591\u2591\u2593\u2588 \u2588\u2588\u2593"," \u2592 \u2593\u2588\u2588\u2588\u2580 \u2591\u2591\u2588\u2588\u2593 \u2592\u2588\u2588\u2592 \u2593\u2588 \u2593\u2588\u2588\u2592\u2591\u2588\u2588\u2591\u2591\u2592\u2593\u2588\u2588\u2588\u2580\u2592"," \u2591 \u2591\u2592 \u2592 \u2591\u2591 \u2592\u2593 \u2591\u2592\u2593\u2591 \u2592\u2592 \u2593\u2592\u2588\u2591\u2591\u2593 \u2591\u2592 \u2592"," \u2591 \u2592 \u2591\u2592 \u2591 \u2592\u2591 \u2592 \u2592\u2592 \u2591 \u2592 \u2591 \u2591 \u2591"," \u2591 \u2591\u2591 \u2591 \u2591 \u2592 \u2592 \u2591\u2591 \u2591 \u2591"," \u2591 \u2591 \u2591 \u2591 \u2591 \u2591 \u2591"," \u2591"];function qr(){return[...ip]}var ap=["Start","Options","Exit"],cp=["Resume","Options","Exit"],pn=2,mn=2,gn=2,lp=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),dp=new RegExp("\x1B\\[(?:0)?m","g"),up=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),fp=/https?:\/\/[^\s<>"']+/g,Kr="\x1B[0m",Vr="\x1B]8;;\x1B\\",E={panelBg:{bg:"0a0a0a",fg:"c0caf5"},panelMuted:{bg:"0a0a0a",fg:"565f89"},panelSelected:{bg:"1a1b26",fg:"c0caf5"},panelFocused:{bg:"1a1b26",fg:"7aa2f7"},divider:{bg:"0a0a0a",fg:"292e42"},rail:{bg:"0a0a0a",fg:"c0caf5"},overlay:{bg:"06060f",fg:"565f89"},overlayTitle:{bg:"06060f",fg:"565f89"},overlayLogo:{bg:"06060f",fg:"9ece6a"},overlaySubtitle:{bg:"06060f",fg:"41a6b5"},overlayMenuSelected:{bg:"06060f",fg:"7aa2f7"},accent:{fg:"7aa2f7"},success:{fg:"9ece6a"},pending:{fg:"e0af68"},error:{fg:"f7768e"},mutedfg:{fg:"565f89"},disabled:{fg:"3b4261"}};function Pa(e,t={}){return Hr(e,{subtitle:"crAIg is that you?",menuItems:ap,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function ba(e,t={}){return Hr(e,{subtitle:"Control mode is paused.",menuItems:cp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var un=[" GLOBAL CENTER PANEL INSPECTOR"," ? help \u2190\u2192 / hl switch tab \u2191\u2193 / jk navigate"," Esc pause / back + new tab \u2190\u2192 / hl switch mode"," Tab cycle panels a codex tab R sync PR"," q quit t terminal tab R sync PR"," x close tab X close task"," TASKS Enter attach PTY X close task"," \u2191\u2193 / jk navigate"," n new task TERMINAL MODE"," Enter attach Ctrl+] return to control mode"," Wheel / PgUp / PgDn scroll",""," Press Esc to return."],pp=["Help"];function Gr(e,t={}){return Hr(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??pp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Ia(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(N(" ".repeat(e.width),n,r)),o=qr(),i=Math.max(1,Math.floor((e.height-o.length-2-un.length)/2));for(let f=0;f<o.length&&!(i+f>=e.height);f+=1)s[i+f]=N(Ea(o[f]??"",e.width),n,E.overlayLogo);let c=Math.max(...un.map(f=>f.length)),l=Math.max(0,Math.floor((e.width-c)/2)),d=i+o.length+2;for(let f=0;f<un.length;f+=1){let h=d+f;if(h>=e.height)break;let R=un[f]??"";s[h]=N(Pe(" ".repeat(l)+R,e.width),n,r)}return s.join(`
154
- `)}function Sa(e,t={}){let n=t.color??!0,r=E.overlay,s=new Array(e.height).fill(N(" ".repeat(e.width),n,r)),o="Error Log",i=t.errorLogPath??"",c=t.errorLogLines??[],l=Math.max(20,e.width-8),d=Math.max(0,Math.floor((e.width-l)/2)),f=[{text:o,tone:"selected"},{text:i,tone:"muted"},te(),...c.length>0?c.map(k=>({text:k})):[{text:"No Craig errors have been logged.",tone:"muted"}],te(),{text:"Esc returns to Options.",tone:"muted"}],h=bt(f,e.height-2),R=Math.max(1,Math.floor((e.height-h.length)/2));for(let k=0;k<h.length;k+=1){let S=R+k;if(S>=e.height)break;let T=h[k]??te(),a=`${" ".repeat(d)}${wn(T.text,l)}`,H=T.tone==="selected"?E.overlayMenuSelected:T.tone==="muted"?E.overlay:E.panelBg;s[S]=N(Pe(a,e.width),n,H)}return s.join(`
155
- `)}function Ca(e,t,n={}){let r=n.color??!0,s=ge.leftWidth,o=ge.rightWidth,i=ge.dividerWidth,c=n.centerOnly??!1,l=c?e.width:e.width-s-o-i*2,d=e.height-ge.topRailHeight-1,f=n.focusFlashActive??!1,h={bg:E.divider.bg,fg:"9ece6a"},R=f&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?h:E.divider,k=f&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?h:E.divider,S=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=N(Pe(S,e.width),r,E.rail),a=gp(t,s-pn-mn,d,r),H=hp(t,l,d,r),_=kp(t,o,d,r),ne=t.inputMode==="terminal",x=[];for(let Z=0;Z<d;Z+=1){if(c){x.push(fn(H[Z]??te(),l,r,"center"));continue}let ve=fn(a[Z]??te(),s,r,"left"),he=N("\u2502",r,R),Ee=fn(H[Z]??te(),l,r,"center"),re=N("\u2502",r,k),He=fn(_[Z]??te(),o,r,"right");x.push(`${ve}${he}${Ee}${re}${He}`)}let Oe=ne||t.modalInput?E.panelBg:E.panelMuted,xe=mp(t.footerText,t.footerToast,e.width,r,Oe);return[T,...x,xe].join(`
156
- `)}function mp(e,t,n,r,s){let o=` ${e}`;if(!t)return N(Pe(o,n),r,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,c=X(i),l=X(o),d=Math.max(1,n-l-c-2),f=l+d+c+2>n?wn(o,Math.max(0,n-c-3)):o,h=Math.max(1,n-X(f)-c-2),R=t.tone==="error"?jp(i,r,s):rt(i,r,s),k=`${f}${" ".repeat(h)}${R} `;return N(Pe(k,n),r,s)}function Hr(e,t){let n=new Array(e.height).fill(N(" ".repeat(e.width),t.color,E.overlay)),r=qr(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,f)=>`${f===t.menuIndex?">":" "} ${d.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],c=[...r,"",t.subtitle,"",...o,...i],l=Math.max(1,Math.floor((e.height-c.length)/2));for(let d=0;d<c.length;d+=1){let f=Ea(c[d]??"",e.width);if(d<r.length){n[l+d]=N(f,t.color,E.overlayLogo);continue}if(d===r.length+1){n[l+d]=N(f,t.color,E.overlaySubtitle);continue}let h=d-(r.length+3),k=h>=0&&h<t.menuItems.length&&h===t.menuIndex?E.overlayMenuSelected:E.overlay;n[l+d]=N(f,t.color,k)}if(t.versionText){let d=t.updateText?" (update available)":"",f=`${t.versionText}${d} `,h=" ".repeat(Math.max(0,e.width-X(f)));n[e.height-1]=N(`${h}${zr(f,t.color,E.overlay)}`,t.color,E.overlay)}return n.join(`
157
- `)}function gp(e,t,n,r){let s=yp(e.runners),o=1,i=e.leftTree.map(l=>Tp(l,t,r));return[...bt(i,n-o),s]}function hp(e,t,n,r){let s=t-2,o=e.tabs.find(x=>x.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:Lp(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?rt(l,r,E.panelBg):hn(l,r,E.panelMuted)}`,f=[`${hn(e.centerHeader.tabLabel,r,E.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(x=>x.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!Fi(h)?e.centerTranscript.map(x=>({...x})):wp(e),k=Pp(e.tabs,r,e.focusedRegion==="center"),S=" engaged ",T=S.length+2,a=e.inputMode==="terminal"?rt(`${S}\u25CF `,r,E.panelBg):"",H=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-X(k)-T)):"",ne=[{text:e.inputMode==="terminal"?`${k}${H}${a}`:k},{text:d,tone:"muted"},{text:f},te(),...R];return bt(ne,n)}function wp(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},te(),{text:e.terminal.error},te(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(r=>r.active)?.id??"",n=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${n.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(r=>({text:Da(r.segments),segments:r.segments,fullBleed:!0}))}function kp(e,t,n,r){let s=e.rightInspection?Rp(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,n):bt([{text:"CONTEXT"},te(),...e.rightContext.map(o=>bp(o,r)),...e.actionMessage?[te(),{text:e.actionMessage}]:[]],n);return bt(s,n)}function Rp(e,t){let n=e.slice(0,2),r=e.slice(2),s=Math.max(0,t-n.length),o=r.findIndex(c=>c.focused||c.selected),i=o===-1?0:Fp(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Ta(c)),...r.slice(i,i+s).map(c=>Ta(c))]}function Ta(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",n=e.focused||e.selected?"selected":e.muted?"muted":"default",r=`${t}${e.text}`;if(e.segments)return{text:r,segments:[{text:t},...e.segments],tone:n};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:r,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:n}}return e.color?{text:r,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:n}:{text:r,tone:n}}function Tp(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${rt("\u25CF",n,e.selected?E.panelSelected:E.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,S)=>k+X(S.text),0):0,l=t-X(o)-X(s)-c,d=e.selected?e.text:e.focused?rt(e.text,n,E.panelBg):e.panelHeader?hn(e.text,n,E.panelMuted):e.text,f=Pe(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${f}${o}${i}`},...e.prBadge];return{text:`${f}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${f}${o}${i}`,tone:h}}function yp(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:E.success.fg}}):n.push({text:s.text,style:{fg:E.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function Pp(e,t,n){return e.map(r=>r.active?n?rt(r.label,t,E.panelBg):hn(r.label,t,E.panelBg):zr(r.label,t,E.panelBg)).join(" ")}function bp(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?zr(e.value,t,E.panelBg):e.value}`}}function fn(e,t,n,r){let s=Ip(r,e.tone??"default"),o=Sp(e,n,s);if(r==="left"){if(e.fullBleed)return N(Pe(o,t),n,s);let c=t-pn-mn;if(e.rightAlign){let d=X(o),f=Math.max(0,c-d),h=`${" ".repeat(pn)}${" ".repeat(f)}${o}${" ".repeat(mn)}`;return N(h,n,s)}let l=`${" ".repeat(pn)}${Pe(o,c)}${" ".repeat(mn)}`;return N(l,n,s)}return r==="center"&&e.fullBleed?Cp(e,t,n,s):N(Pe(` ${o}`,t),n,s)}function Ip(e,t){return t==="selected"||t==="focused"?E.panelSelected:t==="muted"?E.panelMuted:E.panelBg}function bt(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(te());return n}function te(){return{text:""}}function Sp(e,t,n){return e.segments?e.segments.map(r=>xa(r,t,n)).join(""):e.text}function Cp(e,t,n,r){let s=" ".repeat(gn),o=Math.max(0,t-gn*2);if(!e.segments)return N(`${s}${Pe(e.text,o)}${s}`,n,r);let i=Ep(e.segments,o),c=`${s}${i.map(l=>xa(l,n,r)).join("")}${s}${n?Vr:""}`;return N(c,n,r)}function xa(e,t,n){let r=e.href?`${va(e.href)}${e.text}${Vr}`:xp(e.text);return!t||!e.style?r:`${It(Dp(e.style,n))}${Mp(e.style)}${r}${Kr}${It(n)}`}function xp(e){return e.replace(fp,t=>{let[n,r]=vp(t);return`${va(n)}${n}${Vr}${r}`})}function vp(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function va(e){return`\x1B]8;;${e}\x1B\\`}function Ep(e,t){let n=Ap(e,t);return $p(n,t)}function Ap(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=X(s.text);if(o<=r){n.push(s),r-=o;continue}let i=wn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function $p(e,t){let n=X(Da(e));if(n>=t)return e;let r=e.at(-1)?.style;return r?.bg?[...e,{text:" ".repeat(t-n),style:r}]:[...e,{text:" ".repeat(t-n)}]}function Dp(e,t){let n=e.inverse?e.bg??t.bg:e.fg,r=e.inverse?e.fg??t.fg:e.bg,s={},o=n??t.fg,i=r??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function Mp(e){let t=[];return e.bold&&t.push("1"),e.dim&&t.push("2"),e.italic&&t.push("3"),e.underline&&t.push("4"),t.length>0?`\x1B[${t.join(";")}m`:""}function Lp(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function Ea(e,t){let n=Math.max(0,t-X(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Pe(e,t){let n=X(e);return n>=t?Op(e,t):e+" ".repeat(t-n)}function Op(e,t){if(t<=0)return"";if(X(e)<=t)return e;let n=$a(e);return wn(n,Math.max(0,t-1))+"\u2026"}function X(e){let t=0;for(let n of Array.from($a(e)))t+=Aa(n);return t}function wn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=Aa(s);if(r+o>t)break;n+=s,r+=o}return n}function Aa(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function Fp(e,t,n){return Math.min(Math.max(e,t),n)}function $a(e){return e.replace(up,"").replace(lp,"")}function Da(e){return e.map(t=>t.text).join("")}function N(e,t,n){if(!t)return e;let r=It(n),s=e.replace(dp,`${Kr}${r}`);return`${r}${s}${Kr}`}function It(e){let t=[];return e.fg&&t.push(`38;2;${ya(e.fg).join(";")}`),e.bg&&t.push(`48;2;${ya(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function ya(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function rt(e,t,n){return kn(e,t,E.success.fg,n)}function jp(e,t,n){return kn(e,t,E.error.fg,n)}function hn(e,t,n){return kn(e,t,E.accent.fg,n)}function zr(e,t,n){return kn(e,t,E.mutedfg.fg,n)}function kn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${It(s)}${e}${It(r)}`}ee();var Yr=["Runners","Error Log","Help"];function Jr(e,t){return F.map(n=>{let r=b.runners.getProfile(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function La(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function Oa(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Yr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Qr(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Fa(e,t,n,r){if(e.pathEdit)return Np({...e,pathEdit:e.pathEdit},t,n);let s=Jr(t,e).length;if(n==="UP"||n==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(n==="DOWN"||n==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(n==="ESCAPE")return{kind:"back",state:e};if(n==="e"){let c=F[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!Qr(n))return{kind:"noop",state:e};let o=F[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&r.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:Wp(t,o,!i),state:{...e,message:`${b.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function Np(e,t,n){if(n==="ESCAPE")return{kind:"render",state:Ma({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Qr(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:_p(t,r,s.length>0?s:null),state:Ma({...e,message:s.length>0?`${b.runners.getProfile(r).displayName} executable saved.`:`${b.runners.getProfile(r).displayName} executable reset to default.`})}}return Bp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function Wp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function _p(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function Ma(e){let t={...e};return delete t.pathEdit,t}function Qr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
158
- `}function Bp(e){return e.length===1&&e>=" "&&e!=="\x7F"}var Vp=Up(import.meta.url),Gp=Vp("terminal-kit"),Hp=Gp.terminal;async function Wa(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=be(t);await tt(t);let r=await b.load(n),s=b.runners.getEnabled(r),o=e.uiStateFile?await ue({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await St(t,void 0,s),d=rn($i(o,r),l);l=await St(t,d,s);let f=()=>{},h={workspaceRoot:t,onUpdate:()=>f(),resolveSessionSpec:(S,T)=>Qp(l,T,t)},R=e.ptyRuntime??await fa({...h,paths:n}),k=S=>{if(!e.uiStateFile)return;o=Di(o,S);let T=o;i=i.then(()=>ae({uiStateFile:e.uiStateFile},T),()=>ae({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(S=>{let T=e.terminal??Hp,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:rn(d,l)},H=!1,_=!1,ne=null,x=0,Oe=0,xe=null,Z=null,ve=null,he=null,Ee=null,re=null,He=null,yn=!1,Pn=null,Zr=`Craig v${b.version.getCurrent()}`,bn=null,In=0,z=!0,Sn=null,y=()=>{},W=R;f=()=>{a.mode==="main"&&(a={mode:"main",shell:ot(a.shell)},ve||(ve=setTimeout(()=>{ve=null,a.mode==="main"&&y()},50)))};function ot(m){return Ve(m,W.getViewState(es(m)))}function es(m){let u=ze(m);return u?u.ptyTabs.some(p=>p.id===m.activeTab)?m.activeTab:m.activeTab==="agent"||m.activeTab==="terminal"?u.ptyTabs.find(p=>p.kind===m.activeTab)?.id??m.selectedPtyTabId:m.selectedPtyTabId:m.selectedPtyTabId}function P(m){return ot(zp(m,l))}function ze(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function ts(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(p=>p.id));await W.pruneStale?.(m),await W.hydrateSessions?.(m)}function Ua(){ts().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function qa(m){let u=P(m),p=ze(u),g=es(u);if(!p||!g||!p.ptyTabs.some(j=>j.id===g))return u;let w=W.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return Ve(u,w);let C=await W.ensureSession(p.id,g,xt(Le(T.width,T.height)));return Ve({...u,inputMode:"control"},C)}function ns(m,u){return he&&(clearTimeout(he),he=null),u?(he=setTimeout(()=>{he=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...m,footerToast:u}):{...m,footerToast:null}}function Ka(m,u){return ns(m,u?{tone:"success",message:u}:null)}function K(m,u,p){let g=u instanceof Error?u.message:p,w=u instanceof Error?u.stack??u.message:String(u);return wr(n,{context:m,message:g,details:w}),g}function V(m,u){return ns(m,{tone:"error",message:u})}function Fe(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function rs(m){let u=ze(m),p=l.inspection,g=p&&p.taskId===u?.id?p:null,w=Yp(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:Jp(l),centerTabIds:Ni(u,m),ptyTabIds:u?.ptyTabs.map(C=>C.id)??[],filePathIds:g?.filePaths??[],fileTreeRowIds:w.map(C=>C.path),fileTreeFileIds:w.filter(C=>C.kind==="file").map(C=>C.path),fileTreeDirectoryIds:w.filter(C=>C.kind==="directory").map(C=>C.path),diffPathIds:g?.diffPaths??[],diffPathRanges:[],fileLineCount:g?.selectedFile.lines.length??0,diffLineCount:g?.selectedDiff.lines.length??0,reviewRowCount:Zi(m,u),pageRows:Math.max(5,Le(T.width,T.height).height-ge.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(C=>C.repoId)??[]}}async function Va(m){await b.save(n,m),r=m,s=b.runners.getEnabled(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:b.runners.getDefault(r)})}}async function Ga(m){let u=m.selectedTaskId;u&&await Fe(async()=>{let p=await U(n,u);!p.ptyTabs.some(g=>g.id===m.activeTab)||p.selectedPtyTabId===m.activeTab||await A(n,{...p,selectedPtyTabId:m.activeTab})})}async function se(){let m=(a.mode==="main",a.shell);l=await St(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function ss(m){let u=++In,p=_a(l.tasks,m),g=l.inspection,w;if(p&&g?.taskId===p.id){let C={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},j=await ri(p,g,C);if(u!==In)return;w={...l,inspection:j}}else if(w=await St(t,m,s),u!==In)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function Cn(m){let u=await lm(m);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:u,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function os(m){try{let u=P(m),p=ze(u),g=u.selectedPtyTabId;if(p&&u.focusedRegion==="tasks"){let j=p.ptyTabs.find(de=>de.kind==="agent")??null;j?g=j.id:(p=await is(p),await se(),g=p.selectedPtyTabId)}p&&!g&&(p=await is(p),await se(),g=p.selectedPtyTabId);let w=P({...u,activeTab:g??u.activeTab,selectedPtyTabId:g,focusedRegion:g?"center":u.focusedRegion});if(!w.selectedTaskId||!g){a={mode:"main",shell:w},y();return}a={mode:"main",shell:Ve({...w,inputMode:"terminal"},W.getViewState(g))},k(a.shell);let C=await W.ensureSession(w.selectedTaskId,g,xt(Le(T.width,T.height)));_=Xr(g),ne=null,a={mode:"main",shell:Ve({...w,inputMode:"terminal"},C)},k(a.shell)}catch(u){let p=K("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Xr(m.selectedPtyTabId)&&(await Ha(m.selectedTaskId,p).catch(()=>{}),await se().catch(()=>{})),a={mode:"main",shell:V(Li(P(m),p),p)},k(a.shell)}y()}async function Ha(m,u){await Fe(async()=>{let p=await U(n,m);await A(n,{...p,status:p.status==="running"?"draft":p.status,runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:u})})}async function za(m,u,p){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await Fe(async()=>{let C=await U(n,g.selectedTaskId),j=u??em(C,g.activeTab,g.preferredPtyTabKind),de=ja(C,j,p??void 0,r),it={...C,ptyTabs:[...C.ptyTabs,de],selectedPtyTabId:de.id};return await A(n,it),it});return await se(),P({...g,activeTab:w.selectedPtyTabId??g.activeTab,selectedPtyTabId:w.selectedPtyTabId,preferredPtyTabKind:w.ptyTabs.at(-1)?.kind??g.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${w.ptyTabs.at(-1)?.title??"tab"}`})}async function Ya(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:p,nextSelectedTab:g}=await Fe(async()=>{let w=await U(n,u.selectedTaskId),C=w.ptyTabs.findIndex(En=>En.id===u.activeTab);if(C===-1)throw new Error("Only PTY tabs can be closed.");let j=w.ptyTabs[C],de=w.ptyTabs.filter(En=>En.id!==j.id),it=de[Math.min(C,de.length-1)]??de[C-1]??null;return await A(n,{...w,ptyTabs:de,selectedPtyTabId:it?.id??null}),{closedTab:j,nextSelectedTab:it}});return W.disposeSession(p.id),await se(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${p.title}`})}async function Ja(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let p=ze(u),g=null,w=null;if(p?.type==="project"&&p.repoTargets?.length){let C=await Yt(n,u.selectedTaskId);await se();let j=C.synced+C.discovered+C.notFound;w=`Refreshed ${C.synced}/${j} targets`}else{let{disposition:C,task:j}=await ar(n,u.selectedTaskId);await se(),g=C==="not_found"?`No PR found for ${j.branch}`:null,C!=="not_found"&&(w=`Refreshed checks: ${G(j)?.requiredChecks.length??0} reported`)}return P({...Ka(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function Qa(){if(yn||a.mode!=="main")return;let m=l.tasks;yn=!0;try{if(await Fo(n,m),Pn=null,a.mode!=="main")return;l=await St(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(u){let p=u instanceof Error?u.message:"Background PR discovery failed.";p!==Pn&&(Pn=p,wr(n,{context:"background PR polling",message:p,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{yn=!1}}async function Xa(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:p,task:g}=await Fe(async()=>{let w=await U(n,u.selectedTaskId),C=await pi(n,u.selectedTaskId);return{taskBeforeClose:w,task:C}});for(let w of p.ptyTabs)W.disposeSession(w.id);return await se(),P({...u,selectedActionId:"close-task",actionMessage:g.cleanup.preservedWorktree?`Archived task ${g.id}; worktree preserved`:`Archived task ${g.id}`})}async function Za(m){let u=P(m);if(!u.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await Te(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await ht(n,u.selectedWorkspaceId);let g=await wt(n,u.selectedWorkspaceId);return await se(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function is(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await Fe(async()=>{let C=await U(n,m.id),j=C.ptyTabs.find(de=>de.kind==="agent")??null;j&&await A(n,{...C,selectedPtyTabId:j.id})}),w}let p=ja(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,p],selectedPtyTabId:p.id};return await Fe(async()=>{let w=await U(n,m.id),C=w.ptyTabs.find(j=>j.kind==="agent")??null;if(C){await A(n,{...w,selectedPtyTabId:C.id});return}await A(n,{...w,ptyTabs:[...w.ptyTabs,p],selectedPtyTabId:p.id})}),g}y=()=>{ec();let m=Le(T.width,T.height),u=a.mode==="main"?Ca(m,Gi(P(a.shell),l),{centerOnly:a.shell.centerZoomed,focusFlashActive:Ee!==null&&Date.now()<Ee}):a.variant==="boot"?Pa(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Zr,updateText:bn}):a.variant==="pause"?ba(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Zr,updateText:bn}):a.variant==="options"?Gr(m,{menuIndex:a.menuIndex,optionsMenuItems:Yr}):a.variant==="runners"?Gr(m,{menuIndex:Ct(a).menuIndex,optionsMenuItems:Jr(r,Ct(a)),optionsMessage:La(Ct(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Sa(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Ia(m);z&&(T.moveTo(1,1),T.eraseDisplayBelow(),z=!1),T.noFormat(nm(u)),T.hideCursor(!0)};function ec(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==Sn&&(Sn=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let tc=()=>{process.stdout.off("resize",us),process.off("SIGCONT",fs),T.removeListener("key",as),T.removeListener("unknown",cs),T.removeListener("mouse",ls),xe&&(clearTimeout(xe),xe=null),Z&&(clearTimeout(Z),Z=null),ve&&(clearTimeout(ve),ve=null),he&&(clearTimeout(he),he=null),re&&(clearTimeout(re),re=null),He&&(clearInterval(He),He=null),W.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},xn=m=>{tc(),S(m)},nc=async()=>{if(a.mode!=="main"||H)return;let m=a.shell,u=m.taskPromptInput?.trim()??"";if(!m.selectedRepoId&&!m.selectedWorkspaceId){a={mode:"main",shell:P({...m,taskPromptError:"Select a workspace first."})},y();return}if(u.length===0){a={mode:"main",shell:P({...m,taskPromptError:"Task prompt cannot be empty."})},y();return}H=!0,a={mode:"main",shell:P({...m,actionMessage:`Creating ${m.selectedRunner} task in ${m.selectedWorkspaceId??m.selectedRepoId}...`})},y();let p=null;try{p=await tm(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await se();let g=P({...a.shell,selectedRepoId:p.repoId,selectedWorkspaceId:p.workspaceId,selectedTaskId:p.id,selectedPtyTabId:p.selectedPtyTabId,selectedLeftItemId:`task:${p.id}`,activeTab:p.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),w=await W.ensureSession(p.id,g.selectedPtyTabId??Ba(p,"agent"),xt(Le(T.width,T.height)));_=Xr(g.selectedPtyTabId),a={mode:"main",shell:Ve(g,w)},k(a.shell)}catch(g){g instanceof Rn&&(p=g.task);let w=K("create task",g,"Failed to create task.");p&&(await A(n,{...p,status:"draft",runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:w}).catch(()=>{}),await se().catch(()=>{})),a={mode:"main",shell:V(P({...a.shell,inputMode:"control",selectedTaskId:p?.id??a.shell.selectedTaskId,selectedPtyTabId:p?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:p?`task:${p.id}`:a.shell.selectedLeftItemId,activeTab:p?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:p?null:"",taskPromptError:w,actionMessage:null}),w)}}finally{H=!1,y()}},rc=m=>{if(a.mode!=="main")return;let u=a.shell;if(u.taskPromptInput!==null){if(m==="ESCAPE"){a={mode:"main",shell:P({...u,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Ce(m)){nc();return}if(m==="BACKSPACE"){a={mode:"main",shell:P({...u,taskPromptInput:u.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(m==="CTRL_R"){a={mode:"main",shell:P({...u,selectedRunner:vr(u.selectedRunner,s),taskPromptError:null})},y();return}Oi(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},sc=m=>{if(a.mode!=="main")return;let u=a.shell.workspaceBrowser;if(u){if(m==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(m==="UP"||m==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.max(0,u.selectedIndex-1),error:null}})},y();return}if(m==="DOWN"||m==="j"){let p=Math.max(0,u.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.min(p,u.selectedIndex+1),error:null}})},y();return}if(m==="LEFT"||m==="h"){Cn(st.dirname(u.cwd)).catch(p=>{let g=K("open parent workspace directory",p,"Failed to open parent directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Ce(m)){let p=u.entries[u.selectedIndex]??null;if(!p)return;if((m==="RIGHT"||m==="l")&&(p.kind==="directory"||p.kind==="repo")){Cn(p.path).catch(g=>{let w=K("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}gt(n,p.path).then(async g=>{await se();let w=g.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${g.workspace.id}`,selectedWorkspaceId:g.workspace.id,selectedRepoId:w?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${g.workspace.name??g.workspace.id}`})},k(a.shell),y()}).catch(g=>{let w=K("add workspace",g,"Failed to add workspace.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},as=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){rc(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){sc(u);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(u==="F"){cc(),y();return}Ee!==null&&(Ee=null,re&&(clearTimeout(re),re=null))}if(a.mode==="main"){let p=Mi(a.shell,u,rs(a.shell));if(p.exit){xn(0);return}if(p.detachTerminal){W.detach(),a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(p.changed){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(_&&Ce(u)){_=!1;return}_&&(_=!1),ne=sm(u)?{key:u,at:Date.now()}:null;let g=om(u,a.shell.terminal.scrolledBack??!1);if(g!==0){vn(g);return}W.writeKey(u);return}if(u==="CTRL_C"){xn(0);return}if(u==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},z=!0,y();return}if(p.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(p.state)},z=!0,y();return}if(p.beginTaskPrompt){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(p.openWorkspaceBrowser){Cn(t).catch(g=>{let w=K("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:V(P({...p.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(p.createPtyTab){za(p.state,p.createPtyTabKind,p.createPtyTabRunner).then(g=>{os(g)}).catch(g=>{let w=K("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.closePtyTab){Ya(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("close PTY tab",g,"Failed to close tab.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.refreshPullRequestChecks){Ja(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("refresh PR checks",g,"Failed to refresh PR checks.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.openPrUrl){let g=ze(p.state),w=g?G(g)?.url??null:null;w?dm(w).catch(C=>{let j=K("open PR URL",C,"Failed to open PR in browser.");a={mode:"main",shell:V(P(p.state),j)},y()}):(a={mode:"main",shell:V(P(p.state),"No PR URL available.")},y());return}if(p.closeTask){Xa(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("close task",g,"Failed to close task.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.removeWorkspace){Za(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=K("remove workspace",g,"Failed to remove workspace.");a={mode:"main",shell:V(P({...p.state,actionMessage:w}),w)},y()});return}if(p.attachTerminal){os(p.state);return}if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),ss(a.shell).catch(g=>{let w=K("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:w}),w)},y()});return}p.changed&&(a={mode:"main",shell:P(p.state)},Ga(a.shell).catch(()=>{}),k(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},z=!0,y();return}if(a.variant==="options"){oc(u);return}if(a.variant==="runners"){ac(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Ce(u)){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y()}return}if(a.optionsMessage){(u==="ESCAPE"||Ce(u))&&(a={...a,optionsMessage:null},y());return}if(u==="UP"||u==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(u==="DOWN"||u==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(u==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},z=!0,y());return}if(Ce(u)){if(a.menuIndex===0){let p=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},z=!0,y(),p?uc.then(()=>{if(a.mode!=="main")return;let g=a.shell;qa(g).then(w=>{a.mode!=="main"||a.shell!==g||(a={mode:"main",shell:w},k(a.shell),y())}).catch(w=>{if(a.mode!=="main"||a.shell!==g)return;let C=K("warm selected PTY",w,"Failed to start selected PTY.");a={mode:"main",shell:V(P(a.shell),C)},k(a.shell),y()})}):Ua();return}if(a.menuIndex===1){let p=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}xn(0)}};function oc(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=Oa(a.menuIndex,m);if(u.kind!=="noop"){if(u.kind==="render"){a={...a,menuIndex:u.menuIndex},y();return}if(u.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},z=!0,y());return}if(u.kind==="help"){let p=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}if(u.kind==="runners"){let p=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}if(u.kind==="error-log"){let p=a.parentVariant;ic(p)}}}async function ic(m){let u;try{u=await ti(n)}catch(p){let g=K("open error log",p,"Failed to read Craig error log.");u={path:n.errorLogFile,lines:[`Unable to read error log: ${g}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:u,...m!==void 0?{parentVariant:m}:{}},z=!0,y())}function ac(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=Fa(Ct(a),r,m,s);if(u.kind!=="noop"){if(u.kind==="back"){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},z=!0,y();return}if(u.kind==="render"){a={...a,runnerOptions:u.state},y();return}Va(u.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:u.state},y())}).catch(p=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let g=K("save runner option",p,"Failed to save runner option."),w=V(P(a.shell),g);a={...a,shell:w,runnerOptions:{...Ct(a),message:g}},y()})}}function cc(){Ee=Date.now()+600,re&&clearTimeout(re),re=setTimeout(()=>{Ee=null,re=null,y()},600)}let cs=m=>{let u=rm(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){W.detach(),_=!1,ne=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let p=im(u);if(p!==0){vn(p);return}let g=am(u);if(g){_=!1,ne={key:g,at:Date.now()},W.writeKey(g);return}if(_&&u!=="\r"&&u!==`
159
- `&&u!==`\r
160
- `&&(_=!1),cm(_,ne,u)){_=!1;return}W.write(u)},ls=m=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){dc(Na(m));return}let u=Na(m);u!==0&&vn(u)};function vn(m){x+=m,!xe&&(xe=setTimeout(()=>{xe=null;let u=x;x=0,u!==0&&(lc(u),y())},16))}function lc(m){W.scrollViewport(m),a={mode:"main",shell:ot(a.shell)}}function ds(){z=!0,T.fullscreen(!0)}function dc(m){m!==0&&(Oe+=m,!Z&&(Z=setTimeout(()=>{Z=null;let u=Oe;if(Oe=0,u===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let p=Me(a.shell,u,rs(a.shell));if(p.changed){if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),ss(a.shell).catch(g=>{let w=K("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:w}),w)},y()});return}a={mode:"main",shell:P(p.state)},k(a.shell),y()}},16)))}let us=()=>{ds(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(W.resize(xt(Le(T.width,T.height))),a={mode:"main",shell:ot(a.shell)}),y()},fs=()=>{ds(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(W.resize(xt(Le(T.width,T.height))),a={mode:"main",shell:ot(a.shell)}),y()};process.stdout.on("resize",us),process.on("SIGCONT",fs),T.grabInput(!0),Sn="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",as),T.on("unknown",cs),T.on("mouse",ls),He=setInterval(()=>{Qa()},(r.github?.watchIntervalSeconds??5)*1e3),b.version.checkForUpdate().then(m=>{m.updateAvailable&&m.latest&&(bn=`Update available: v${m.latest}`,y())});let uc=ts().catch(()=>{});y()})}async function St(e,t,n){let r=be(e),[s,o,i]=await Promise.all([Ue(r),pe(r),Te(r)]),c=_a(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=c?await si(c,l):null;return{workspaceRoot:e,workspaces:o.filter(f=>f.status==="active"),repos:s,tasks:i.tasks,inspection:d,...n?{enabledRunnerIds:n}:{}}}function _a(e,t){return t?.selectedTaskId?e.find(n=>n.id===t.selectedTaskId)??null:null}function zp(e,t){return rn(e,t)}function Yp(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function Jp(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function Qp(e,t,n){let r=e.tasks.find(c=>c.ptyTabs.some(l=>l.id===t))??null,s=r?.ptyTabs.find(c=>c.id===t)??null,o=r?.worktreePath??n,i=s?.kind==="agent"?Zp(s):[];return r?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:Xp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function Xp(e,t){let n=(e??"").split(st.delimiter).filter(r=>r.length>0);return n.includes(t)?n.join(st.delimiter):[...n,t].join(st.delimiter)}function Zp(e){return e.command.length>0?e.command:["codex"]}function Ct(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function em(e,t,n){return e.ptyTabs.find(r=>r.id===t)?.kind??n}function ja(e,t,n,r={}){let s=n??e.runner,o=b.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",c=t==="agent"&&n&&n!==e.runner?`${e.id}:${n}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(k=>k.id)),d=1,f=c;for(;l.has(f);)d+=1,f=`${c}-${d}`;let h=new Date().toISOString(),R=n&&n!==e.runner?n:void 0;return{id:f,kind:t,...R?{runner:R}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?b.runners.buildCommand(s,void 0,r):[],createdAt:h,updatedAt:h}}async function tm(e,t,n,r,s){let o=await b.load(e);b.runners.assertEnabled(s,o);let i=n?await qt(e,n,r,{runner:s,config:o}):await ut(e,t??"",r,{runner:s,config:o});try{let d=_e();await v(Be(b.runners.getConfiguredProfile(s,o).executable,{cwd:i.repoRoot,env:d}),["--help"],{cwd:i.repoRoot,env:d})}catch(d){let f=d instanceof Error?d.message:"Failed to start runner.",h={...i.task,status:"draft",runnerSession:{...i.task.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:f};throw await A(e,h),new Rn(f,h)}let c=Ba(i.task,"agent"),l={...i.task,status:"running",selectedPtyTabId:c,runnerSession:{...i.task.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await A(e,l),await ae({uiStateFile:e.uiStateFile},{...await ue({uiStateFile:e.uiStateFile})??Re(),version:1,selectedRepoId:l.repoId,selectedWorkspaceId:l.workspaceId,selectedTaskId:l.id,selectedPtyTabId:l.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:l.selectedPtyTabId??"agent",selectedActionId:"commit",updatedAt:new Date().toISOString()}),l}var Rn=class extends Error{task;constructor(t,n){super(t),this.name="InteractiveTaskStartupError",this.task=n}};function Ba(e,t){let n=e.ptyTabs.find(r=>r.kind===t);if(!n)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return n.id}function xt(e){return{columns:Math.max(20,e.width-ge.leftWidth-ge.rightWidth-ge.dividerWidth-gn*2),rows:Math.max(5,e.height-ge.topRailHeight-5)}}function nm(e){return e.split(`
161
- `).map((t,n)=>`\x1B[${n+1};1H${t}`).join("")}function rm(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function sm(e){return e.length===1||Ce(e)||e==="BACKSPACE"||e==="TAB"}function Xr(e){return typeof e=="string"&&new RegExp(`:(?:agent|${F.join("|")})(?:-\\d+)?$`).test(e)}function om(e,t){return e==="UP"&&t?-3:e==="DOWN"&&t?3:e==="PAGE_UP"?-5:e==="PAGE_DOWN"?5:e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Na(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function im(e){let t=new RegExp("\x1B\\[<(\\d+);\\d+;\\d+[mM]").exec(e);if(!t?.[1])return 0;let n=Number.parseInt(t[1],10);return n===64?-3:n===65?3:0}function am(e){return e==="\x1B[13;2u"?"SHIFT_ENTER":null}function cm(e,t,n){return n.length===0?!1:e&&(n==="\r"||n===`
162
- `||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 lm(e){let t=await qp(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory())continue;let s=st.join(e,r.name);n.push({name:r.name,path:s,kind:await um(s)?"repo":"directory"})}return n.sort((r,s)=>r.kind!==s.kind?r.kind==="repo"?-1:1:r.name.localeCompare(s.name)),{cwd:e,entries:n,selectedIndex:0,error:null}}async function dm(e){let{spawn:t}=await import("node:child_process"),n=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((r,s)=>{let o=t(n,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",r)})}async function um(e){let t=st.join(e,".git");return await Kp(t).catch(()=>null)!==null}function Tn(){return process.cwd()}async function fm(){try{if(process.argv[2]==="__craig-daemon"){let c=process.argv[3]??Tn(),l=be(c);return await tt(c),await pa(l),0}if(process.argv[2]==="__craig-daemon-shutdown"){let c=process.argv[3]??Tn(),l=be(c);return await tt(c),await ma(l),0}let e=Ms(process.argv.slice(2)),t=Tn(),n=be(t),r=await tt(t),s={paths:n};if(e.mode==="interactive")return await Wa({uiStateFile:n.uiStateFile,workspaceRoot:n.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let o=await Zo(e.command,s),i=ei(o);return i.length>0&&process.stdout.write(`${i}
130
+ `}function Vd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var er={appendErrorLog:Ln,appendErrorLogBestEffort:Zo,readErrorLog:jn,readRecentErrorLines:ei};import{readFile as Gd,stat as Hd}from"node:fs/promises";import Mn from"node:path";var zd=200*1024,Yd=500*1024,tr="100000";async function ri(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return Qd(e,t,r);try{let n=$e(r.selectedFilePath??null,t.filePaths),s=$e(r.selectedDiffPath??null,t.diffPaths),o=s?await xt(e.worktreePath):null,[i,l]=await Promise.all([nr(e.worktreePath,n),s?On(e.worktreePath,s,t.diffRows,o):Promise.resolve(X("No diff selected","No local changes found.","empty"))]),c=s?{[s]:l}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:c,selectedFile:i,selectedDiff:l,error:null}}catch(n){let s=n instanceof Error?n.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function Qd(e,t,r){let n=$e(r.selectedFilePath??null,t.filePaths),s=$e(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([si(e,n),(async()=>{if(!s)return X("No diff selected","No local changes found.","empty");let c=rr(e,s),d=c?await xt(c.target.worktreePath).catch(()=>null):null;return oi(e,s,t.diffRows,d)})()]),l=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:l,selectedFile:o,selectedDiff:i}}async function ni(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Jd(e,t);try{await H(e);let r=await xt(e.worktreePath),[n,s]=await Promise.all([ii(e.worktreePath),ai(e.worktreePath,r)]),o=[...new Set(s.map(g=>g.path))],i=$e(t.selectedFilePath??null,n),l=$e(t.selectedDiffPath??null,o),[c,d]=await Promise.all([nr(e.worktreePath,i),l?On(e.worktreePath,l,s,r):Promise.resolve(X("No diff selected","No local changes found.","empty"))]),u=l?{[l]:d}:{};return{taskId:e.id,fileRows:di(n),filePaths:n,diffRows:s,diffPaths:o,diffContents:u,selectedFilePath:i,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}catch(r){let n=r instanceof Error?r.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:X("Files unavailable",n,"error"),selectedDiff:X("Diff unavailable",n,"error"),error:n}}}async function Jd(e,t){let r=(e.repoTargets??[]).filter(w=>w.status==="ready"),n=await Promise.all(r.map(async w=>{let R=await xt(w.worktreePath).catch(()=>null),[I,T]=await Promise.all([ii(w.worktreePath).catch(()=>[]),ai(w.worktreePath,R).catch(()=>[])]);return{target:w,baseRef:R,targetFiles:I,targetDiffRows:T}})),s=[],o=[];for(let{target:w,targetFiles:R,targetDiffRows:I}of n)s.push(...R.map(T=>`${w.repoId}/${T}`)),o.push(...I.map(T=>({...T,path:`${w.repoId}/${T.path}`})));let i=[...new Set(o.map(w=>w.path))].sort(),l=$e(t.selectedFilePath??null,s),c=$e(t.selectedDiffPath??null,i),[d,u]=await Promise.all([si(e,l),(async()=>{if(!c)return X("No diff selected","No local changes found.","empty");let w=rr(e,c),R=w?n.find(I=>I.target.repoId===w.target.repoId):null;return oi(e,c,o,R?.baseRef??null)})()]),g=c?{[c]:u}:{};return{taskId:e.id,fileRows:di(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:g,selectedFilePath:l,selectedDiffPath:c,selectedFile:d,selectedDiff:u,error:null}}async function si(e,t){let r=rr(e,t);if(!r)return X("No file selected","No Git-visible files found.","empty");let n=await nr(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function oi(e,t,r,n=null){let s=rr(e,t);return s?{...await On(s.target.worktreePath,s.relativePath,r.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),n),path:t,title:t}:X(t,"Repo target is unavailable.","error",t)}function rr(e,t){if(!t)return null;let[r,...n]=t.split("/"),s=n.join("/"),o=(e.repoTargets??[]).find(i=>i.repoId===r&&i.status==="ready")??null;return!o||s.length===0?null:{target:o,relativePath:s}}async function ii(e){let t=await v("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return ui(t.stdout)}async function ai(e,t){let[r,n,s,o]=await Promise.all([Xd(e,t),ti(e,"staged"),ti(e,"unstaged"),Zd(e)]);return[...r,...n,...s,...o]}async function Xd(e,t){if(!t)return[];let[r,n]=await Promise.all([v("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),v("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=li(r.stdout),o=ci(n.stdout);return s.map(i=>{let l=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:l.additions,deletions:l.deletions}}).sort((i,l)=>i.path.localeCompare(l.path))}async function ti(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([v("git",[...r,"--name-status"],{cwd:e}),v("git",[...r,"--numstat"],{cwd:e})]),o=li(n.stdout),i=ci(s.stdout);return o.map(l=>{let c=i.get(l.path)??{additions:null,deletions:null};return{group:t,path:l.path,status:l.status,additions:c.additions,deletions:c.deletions}}).sort((l,c)=>l.path.localeCompare(c.path))}async function Zd(e){let t=await v("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=ui(t.stdout);return await Promise.all(r.map(async s=>{let o=await nr(e,s),i=o.status==="ready"?eu(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function li(e){return e.split(`
131
+ `).map(t=>t.trim()).filter(t=>t.length>0).map(t=>{let[r="M",...n]=t.split(" ");return{status:r,path:n.at(-1)??""}}).filter(t=>t.path.length>0)}function ci(e){let t=new Map;for(let r of e.split(`
132
+ `)){let n=r.trim();if(!n)continue;let[s="-",o="-",...i]=n.split(" "),l=i.join(" ");l&&t.set(l,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function xt(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 nr(e,t){if(!t)return X("No file selected","No Git-visible files found.","empty");let r=tu(e,t);try{let n=await Hd(r);if(n.size>zd)return X(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await Gd(r);return ru(s)?X(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(n){let s=n instanceof Error?n.message:"Unable to read file.";return X(t,s,"missing",t,null)}}async function On(e,t,r,n=null){if(!t)return X("No diff selected","No local changes found.","empty");let s=[],o=r.filter(l=>l.path===t).map(l=>l.group);if(o.includes("branch")){let l=n??await xt(e);if(l){let c=await v("git",["diff","--stat","--patch",`--unified=${tr}`,`${l}...HEAD`,"--",t],{cwd:e});c.stdout.trim().length>0&&s.push(`branch
134
+ ${c.stdout.trimEnd()}`)}}if(o.includes("staged")){let l=await v("git",["diff","--cached","--stat","--patch",`--unified=${tr}`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`staged
135
+ ${l.stdout.trimEnd()}`)}if(o.includes("unstaged")){let l=await v("git",["diff","--stat","--patch",`--unified=${tr}`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`unstaged
136
+ ${l.stdout.trimEnd()}`)}if(o.includes("untracked")){let l=await M("git",["diff","--no-index","--stat","--patch",`--unified=${tr}`,"--","/dev/null",t],{cwd:e});l.stdout.trim().length>0&&s.push(`untracked
137
+ ${l.stdout.trimEnd()}`)}let i=s.join(`
138
+
139
+ `);return i.length>Yd?X(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?X(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 di(e){let t=[],r=new Set;for(let n of e){let s=n.split("/");for(let o=0;o<s.length-1;o+=1){let i=s.slice(0,o+1).join("/");r.has(i)||(r.add(i),t.push({kind:"directory",path:i,depth:o,label:s[o]??i}))}t.push({kind:"file",path:n,depth:s.length-1,label:s.at(-1)??n})}return t}function $e(e,t){return e&&t.includes(e)?e:t[0]??null}function eu(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function ui(e){return[...new Set(e.split(`
141
+ `).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function tu(e,t){let r=Mn.resolve(e,t),n=Mn.resolve(e);if(r!==n&&!r.startsWith(`${n}${Mn.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function ru(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function X(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}import At from"node:path";function pi(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 fi="\u{F024B} ",mi="\u{F0DCF} ",gi="\u25CB",Nn="\uEA64",hi="\uEAFE",ki="\uEBDA",Fn="\u25CB",Wn="\u25CF",_n="\u2713",Bn="\u2715";function wi(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 nu=["tasks","center","inspector","actions"],Si=["agent","terminal"],Ii=[],L="inspection",DT=[...Si,...Ii],Ci=["commit","push","refresh-checks","close-task"],su=["refresh-checks","close-task"],xi=["task","checks","pr","setup-run","actions","next-action"],vi=["diff","files","review"];function Ei(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=Tu(e?.openInspectionKind)??r,s=S.runners.getEnabled(t);return{inputMode:Pu(e?.inputMode),focusedRegion:wu(e?.focusedRegion),selectedRepoId:be(e?.selectedRepoId),selectedWorkspaceId:be(e?.selectedWorkspaceId),selectedTaskId:be(e?.selectedTaskId),selectedPtyTabId:be(e?.selectedPtyTabId),selectedLeftItemId:Du(be(e?.selectedTaskId)),activeTab:r?L:be(e?.activeTab)??"agent",preferredPtyTabKind:yu(e?.preferredPtyTabKind),inspectorSection:vt(e?.inspectorSection,xi,"task"),inspectionMode:Ru(e?.inspectionMode,r==="diff"?"diff":"files"),openInspectionKind:n,selectedFileTreePath:be(e?.selectedFileTreePath),selectedFilePath:be(e?.selectedFilePath),selectedDiffPath:be(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:vt(e?.selectedActionId,Ci,"commit"),selectedProjectTargetId:null,selectedRunner:bu(e?.selectedRunner,s,S.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,workspaceBrowser:null,terminal:ou(),centerZoomed:!1}}function ou(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function Ai(e,t){return{...e??we(),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 ar(e,t,r={}){let n=Eu(e,t),s=Fi(n),o=(s?.kind==="workspace"?t.workspaces?.find(u=>u.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(u=>u.id===t.tasks.find(g=>g.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(u=>u.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,l=((s?.kind==="repo"?t.repos.find(u=>u.id===s.id)??null:s?.kind==="task"?t.repos.find(u=>u.id===t.tasks.find(g=>g.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(u=>u.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(u.id))??null:null)??(o?.kind!=="project"?t.repos.find(u=>u.id===o?.primaryRepoId)??null:null)??t.repos.find(u=>u.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,c=o?t.tasks.filter(u=>u.workspaceId===o.id):l?t.tasks.filter(u=>u.repoId===l):[],d=(s?.kind==="task"?c.find(u=>u.id===s.id)??null:null)??c.find(u=>u.id===e.selectedTaskId)??c[0]??null;return{...e,inputMode:r.resetInputMode?"control":e.inputMode,selectedLeftItemId:n,selectedWorkspaceId:o?.id??null,selectedRepoId:l,selectedTaskId:d?.id??null,...Iu(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:gu(e,t,d?.id??null),...Cu(e,t,d?.id??null),selectedDiffPath:mu(e,t,d?.id??null),inspectorSection:vt(e.inspectorSection,xi,"task")}}function Di(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return iu(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"&&(qn(e.selectedLeftItemId)||Kn(e.selectedLeftItemId)))return b({state:{...e,selectedRunner:Vn(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return Ri(e,1);if(t==="SHIFT_TAB"||t==="[")return Ri(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===L?Le(e,-1,r):Ti(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===L?Le(e,1,r):Ti(e,1,r);if(t==="PAGE_UP")return Le(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Le(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Le(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Le(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??N,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[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 n=Su(e,t);return b({state:{...e,preferredPtyTabKind:n,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:n,createPtyTabRunner:n==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return 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"&&ir(e.selectedLeftItemId)&&e.selectedTaskId)return b({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&$u(e.selectedLeftItemId)&&e.selectedWorkspaceId)return b({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&bi(e.activeTab,r.ptyTabIds??[]))return b({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Un(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return yi(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Un(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return yi(e,1)}if(Ie(t)){if(e.focusedRegion==="tasks"&&(qn(e.selectedLeftItemId)||Kn(e.selectedLeftItemId))){let n=Wi(e.selectedLeftItemId),s=_i(e.selectedLeftItemId);return b({state:{...e,selectedRepoId:n??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return b({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&ir(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return b({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Et(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&bi(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return b({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Et(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===L)return b({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let n=e.selectedFileTreePath??e.selectedFilePath;if(n&&(r.fileTreeDirectoryIds??[]).includes(n))return b({state:uu({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return b({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:L,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}return e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="diff"?b({state:{...e,activeTab:L,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.focusedRegion==="inspector"&&e.inspectionMode==="review"?e.selectedActionId==="close-task"&&!r.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 Ge(e,t){return{...e,terminal:t}}function $i(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function iu(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function Ie(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
142
+ `}function Li(e){return e.length===1&&e>=" "&&e!=="\x7F"}function ji(e){return Mi(e)||Et(e)!==null}function au(e){return Ii.includes(e)}function Mi(e){return Si.includes(e)}function Oi(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[L]:[]]}var lu=["tasks","center","inspector"];function Ri(e,t){return sr(e,"focusedRegion",lu,t)}function Un(e,t,r){let n=sr(e,"activeTab",r&&r.length>0?r:vu(e),t);return!n.changed||au(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Et(n.state.activeTab)??n.state.preferredPtyTabKind}}}function Ti(e,t,r){if(e.focusedRegion==="tasks")return cu(e,t,r.leftItemIds);if(e.focusedRegion==="center")return Un(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Ni(e,t,r);if(e.inspectionMode==="diff"){let n=or(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:L,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:n}if(r.projectTargetIds?.length){let n=or(e,"selectedProjectTargetId",r.projectTargetIds,t);return n.changed?{...n,state:{...n.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:n}return sr(e,"selectedActionId",su,t)}return sr(e,"selectedActionId",Ci,t)}function cu(e,t,r){let n=or(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Fi(n.state.selectedLeftItemId);if(s?.kind==="workspace")return{...n,state:{...n.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...n,state:{...n.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...n,state:{...n.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=Wi(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=_i(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function Le(e,t,r){if(t===0)return b({state:e});if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Ni(e,t,r);if(e.inspectionMode==="diff"){let n=or(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,diffScrollOffset:0}}:n}return e.inspectionMode==="review"?Pi(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):b({state:e})}if(e.focusedRegion==="center"&&e.activeTab===L){if(e.openInspectionKind==="file")return Pi(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return pu(e,t,r)}return b({state:e})}function du(e,t){if(e.inspectionMode===t)return b({state:e});let r=t==="diff"?"diff":t==="files"?"file":e.openInspectionKind,n=t==="diff"||t==="files"?L:e.activeTab;return b({state:{...e,inspectionMode:t,activeTab:n,openInspectionKind:r,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 yi(e,t){return du(e,ku(e.inspectionMode,vi,t))}function Ni(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return b({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=Se(o===-1?0:o+t,0,n.length-1),l=n[i]??null;if(l===e.selectedFileTreePath)return b({state:e});let c=l!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(l);return b({state:{...e,selectedFileTreePath:l,selectedFilePath:c?l:e.selectedFilePath,activeTab:c?L:e.activeTab,openInspectionKind:c?"file":e.openInspectionKind,fileScrollOffset:c?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:c})}function uu(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((r,n)=>r.localeCompare(n)),actionMessage:null}}function Pi(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=Se(e[t]+r,0,o);return i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function pu(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return fu(e,t,r);let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=e.diffScrollOffset+t,l=r.diffPathIds??[];if(l.length===0||!e.selectedDiffPath){let u=Se(i,0,o);return u===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:u,actionMessage:null},changed:!0})}let c=l.indexOf(e.selectedDiffPath);if(c===-1){let u=Se(i,0,o);return u===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:u,actionMessage:null},changed:!0})}if(t>0&&i>o){let u=l[c+1]??null;return u?b({state:{...e,selectedDiffPath:u,activeTab:L,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 u=l[c-1]??null;return u?b({state:{...e,selectedDiffPath:u,activeTab:L,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?b({state:e}):b({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=Se(i,0,o);return d===e.diffScrollOffset?b({state:e}):b({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function fu(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=Se(e.diffScrollOffset+t,0,o),l=hu(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&l===e.selectedDiffPath?b({state:e}):b({state:{...e,diffScrollOffset:i,selectedDiffPath:l,actionMessage:null},changed:!0})}function mu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function gu(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function hu(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function sr(e,t,r,n){let s=r.indexOf(e[t]),o=Se(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?b({state:e}):b({state:{...e,[t]:i,actionMessage:null},changed:!0})}function or(e,t,r,n,s=!1){if(r.length===0)return b({state:e});let o=r.indexOf(e[t]??r[0]??""),i=Se(o===-1?0:o+n,0,r.length-1),l=r[i]??null;return l===e[t]?b({state:e}):b({state:{...e,[t]:l,actionMessage:null},changed:!0,refreshInspection:s})}function ku(e,t,r){let n=t.indexOf(e);return t[Se(n+r,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 vt(e,t,r){return t.includes(e??"")?e:r}function wu(e){return e==="tabs"?"center":vt(e,nu,"tasks")}function Ru(e,t){return e==="checks"||e==="actions"||e==="review"?"review":vt(e,vi,t)}function Tu(e){return e==="file"||e==="diff"?e:null}function yu(e){return e==="terminal"?"terminal":"agent"}function Pu(e){return e==="terminal"?"terminal":"control"}function bu(e,t=[...N],r="codex"){return e&&S.runners.isRunnerType(e)&&t.includes(e)?e:r}function Vn(e,t=N){let r=t.length>0?t:N,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function Et(e){let t=N.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function Su(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Et(e.activeTab)??e.preferredPtyTabKind}function Iu(e,t,r){if(!e)return{activeTab:t===L?t:"agent",selectedPtyTabId:null};let n=e.ptyTabs.find(l=>l.id===r)??null,s=e.selectedPtyTabId?e.ptyTabs.find(l=>l.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(l=>l.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(Mi(t)){let c=e.ptyTabs.find(d=>d.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:c?.id??L,selectedPtyTabId:c?.id??null}}if(t===L)return{activeTab:L,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??L,selectedPtyTabId:i?.id??null}}function Cu(e,t,r){if(!t.inspection||t.inspection.taskId!==r)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let n=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?xu(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function xu(e,t){let r=new Set;if(t){let n=t.split("/");for(let s=1;s<n.length;s+=1)r.add(n.slice(0,s).join("/"))}return e.filter(n=>n.kind==="directory"&&!n.path.includes("/")&&!r.has(n.path)).map(n=>n.path).sort((n,s)=>n.localeCompare(s))}function vu(e){return[e.selectedPtyTabId,e.openInspectionKind?L:null].filter(t=>typeof t=="string")}function bi(e,t){return t.includes(e)}function Eu(e,t){let r=Au(t);return e.selectedLeftItemId&&r.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&r.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&r.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&r.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:r[0]??null}function Au(e){let t=[];if(e.workspaces?.length)for(let r of e.workspaces){t.push(`workspace:${r.id}`);for(let n of e.tasks.filter(s=>s.workspaceId===r.id))t.push(`task:${n.id}`);r.kind==="project"&&t.push(`new-task-workspace:${r.id}`),r.kind==="repo"&&t.push(`new-task:${r.primaryRepoId}`)}else for(let r of e.repos){t.push(`repo:${r.id}`);for(let n of e.tasks.filter(s=>s.repoId===r.id))t.push(`task:${n.id}`);t.push(`new-task:${r.id}`)}return t.push("new-workspace"),t}function Fi(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 be(e){return typeof e=="string"?e:null}function Du(e){return e?`task:${e}`:null}function ir(e){return typeof e=="string"&&e.startsWith("task:")}function qn(e){return typeof e=="string"&&e.startsWith("new-task:")}function Kn(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function $u(e){return typeof e=="string"&&e.startsWith("workspace:")}function Wi(e){return qn(e)?e.slice(9):null}function _i(e){return Kn(e)?e.slice(19):null}function Se(e,t,r){return Math.min(r,Math.max(t,e))}var cr="empty",q={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Ki(e,t){let r=Mu(t,e),n=t.repos.find(T=>T.id===e.selectedRepoId)??t.repos[0]??null,s=r?t.tasks.filter(T=>T.workspaceId===r.id):t.tasks,o=r?.kind==="project"?s:n?s.filter(T=>T.repoId===n.id):[],i=o.find(T=>T.id===e.selectedTaskId)??o[0]??null,l=i?.type==="project",c=kp(t.tasks),d=Fu(e,i),u=Nu(e,i,d),g=u.find(T=>T.id===d)??u[0]??{id:"agent",label:"CODEX"},w=t.inspection?.taskId===i?.id?t.inspection:null,R=n?.name??"no repo",I=i?S.runners.getDisplayName(i.runner):S.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 ${n?`[${n.name}]`:"[no repo]"} \xB7 ${S.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 [${S.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:ir(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===L?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${S.runners.getDisplayName(e.centerTabRunner??i?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?l?"\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:At.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${At.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:I},leftTree:Lu(e,t),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(T=>wp(T,c[T])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":g.label,taskId:e.workspaceBrowser?"new workspace":i?.id??"no task",repo:R,agent:I},centerTranscript:Ou(d,e,n,i,e.workspaceBrowser,w,r),tabs:u,rightContext:hp(n,i),rightInspection:Ju(e,i,w)}}function Lu(e,t){let r=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return ju(r,e,t.repos,t.tasks);let n=t.workspaces;if(n.length===0)r.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let o of n){let i=e.selectedLeftItemId===`workspace:${o.id}`;r.push({id:`workspace:${o.id}`,text:`${o.kind==="project"?"\u2261":"\u2013"} ${o.name??o.id}`,selected:i,focused:i&&e.focusedRegion==="tasks"});let l=o.kind==="project"?o.discoveredRepoIds??[]:[o.primaryRepoId],c=t.tasks.filter(d=>d.workspaceId===o.id);if(c.length===0)r.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of c){let u=e.selectedLeftItemId===`task:${d.id}`,g=u?"\u25B8":"\u2022",w=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,R={id:`task:${d.id}`,taskId:d.id,text:`${g} ${w}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks"},I=Gi(d);I&&(R.prBadge=I),r.push(R)}if(o.kind==="project"){let d=`new-task-workspace:${o.id}`,u=e.selectedLeftItemId===d;r.push({id:d,text:`+ New Project Task [${S.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}if(o.kind==="repo"){let d=`new-task:${o.primaryRepoId}`,u=e.selectedLeftItemId===d;r.push({id:d,text:`+ New Task [${S.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}else{r.push({text:` Repos (${l.length})`,indent:0,muted:!0});for(let d of l.slice(0,6)){let u=t.repos.find(g=>g.id===d);r.push({text:` \xB7 ${u?.name??d}`,indent:0,muted:!0})}l.length>6&&r.push({text:` \xB7 ${l.length-6} more`,indent:0,muted:!0})}}let s=e.selectedLeftItemId==="new-workspace";return r.push({text:"",muted:!0}),r.push({id:"new-workspace",text:"+ New Workspace",selected:s,focused:s&&e.focusedRegion==="tasks"}),r}function ju(e,t,r,n){if(r.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let o of r){let i=t.selectedLeftItemId===`repo:${o.id}`;e.push({id:`repo:${o.id}`,text:`\u2013 ${o.name}`,selected:i,focused:i&&t.focusedRegion==="tasks"});let l=n.filter(u=>u.repoId===o.id);if(l.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let u of l){let g=t.selectedLeftItemId===`task:${u.id}`,w=g?"\u25B8":"\u2022",R=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,I={id:`task:${u.id}`,taskId:u.id,text:`${w} ${R}`,indent:2,selected:g,focused:g&&t.focusedRegion==="tasks"},T=Gi(u);T&&(I.prBadge=T),e.push(I)}let c=`new-task:${o.id}`,d=t.selectedLeftItemId===c;e.push({id:c,text:`+ New Task [${S.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 Mu(e,t){let r=e.workspaces??[];if(!e.workspaces)return null;let n=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return n?r.find(s=>s.id===n.workspaceId)??null:t.selectedWorkspaceId?r.find(s=>s.id===t.selectedWorkspaceId)??null:r[0]??null}function Ou(e,t,r,n,s,o=null,i=null){if(s){let c=s.entries.length===0?["No directories or git repos here."]:s.entries.map((d,u)=>{let g=u===s.selectedIndex?"\u25B8":" ",w=d.kind==="repo"?" [git repo]":"/";return`${g} ${d.name}${w}`});return me(["Browse for a workspace to register.",s.cwd,"",...c,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!r)return me(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let c=i?.kind==="project",d=c?i.name??"this workspace":r.name,u=c?"Project Task":"Task";return me([`No tasks in ${d}.`,"",`Press n or choose + New ${u} to create one with ${S.runners.getDisplayName(t.selectedRunner)}.`])}let l=n.ptyTabs.find(c=>c.id===e)??null;return l?l.kind==="agent"?me([`${l.title} tab ready for ${n.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):me([`${l.title} tab ready for ${n.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===L&&t.openInspectionKind==="file"?Bu(n,o,t.fileScrollOffset):e===L&&t.openInspectionKind==="diff"?Uu(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?me(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):me(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Nu(e,t,r){let n=t?.ptyTabs.map(o=>({id:o.id,label:Wu(o)}))??[];if(!t)return[{id:cr,label:"EMPTY",active:r===cr,focused:e.focusedRegion==="center"&&r===cr}];let s=e.openInspectionKind||r===L?[{id:L,label:_u(e)}]:[];return[...n,...s].map(o=>({...o,active:o.id===r,focused:e.focusedRegion==="center"&&o.id===r}))}function Fu(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===L&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??L:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??L:cr}function Wu(e){return e.title.toUpperCase()}function _u(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?At.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function Bu(e,t,r){if(!e)return me(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return me(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=Vi(n.path??n.title);return[{text:n.title},{text:`${n.byteLength===null?"size unknown":`${n.byteLength} bytes`} \xB7 ${n.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...qu(n.lines,r,s)]}function Uu(e,t,r){if(!e)return me(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return me(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=Vi(n.path??n.title);return[{text:n.title},{text:`${t.diffPaths.length} changed files \xB7 ${n.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...Ku(n.lines,r,s)]}function me(e){return e.map(t=>({text:t}))}function qu(e,t,r){let n=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let l=s+i+1;return{text:`${`${String(l).padStart(n," ")} \u2502 `}${o}`,segments:[{text:String(l).padStart(n," "),style:{fg:q.lineNumber}},{text:" \u2502 ",style:{fg:q.gutter}},...Gn(o,r)],tone:"default"}})}function Ku(e,t,r){let n=Vu(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>Gu(o,r))}function Vu(e){let t=[],r=0,n=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){r=Number.parseInt(o[1]??"0",10),n=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:r,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),r+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:n,marker:"+",text:s.slice(1),kind:"add"}),n+=1;continue}if(s.startsWith(" ")){if(r===0&&n===0)continue;t.push({oldNumber:r,newNumber:n,marker:" ",text:s.slice(1),kind:"context"}),r+=1,n+=1;continue}}}return t}function Gu(e,t){let r=Bi(e.oldNumber),n=Bi(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:q.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:q.diffAdd}:null,i=`${s} \u2502 ${e.text}`,l=o?zu(Gn(e.text,t),o.bg,o.fallbackFg):Gn(e.text,t),c=o?{fg:q.lineNumber,bg:o.bg}:{fg:q.lineNumber},d=o?{fg:q.gutter,bg:o.bg}:{fg:q.gutter};return{text:i,segments:[{text:s,style:c},{text:" \u2502 ",style:d},...l],fullBleed:o!==null}}function Bi(e){return e===null?" ":String(e).padStart(4," ")}function Vi(e){let t=At.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function Gn(e,t){return t==="diff"?Hu(e):t==="markdown"?Yu(e):t==="json"?Hn(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Hn(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 Hu(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:q.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:q.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:q.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:q.diffMeta}}]:[{text:e}]}function zu(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function Yu(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:q.markup,bold:!0}}]:Hn(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Hn(e,t){let r=[],n=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>n&&r.push({text:e.slice(n,i)}),r.push({text:o,style:Qu(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function Qu(e){return e.startsWith("//")||e.startsWith("/*")?{fg:q.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:q.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:q.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:q.markup}:{fg:q.keyword}}function Ju(e,t,r){let n=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&n?t.repoTargets?.find(l=>l.repoId===n)??null:null,o=t?.type==="project"?Hi(t.repoTargets??[]):s?.pullRequest??(t?O(t):null),i=[Xu(e,o),{id:"mode-spacer",text:"",muted:!0}];return e.inspectionMode==="review"?{title:"",rows:[...i,...Qi(e,t)]}:e.inspectionMode==="files"?{title:"",rows:[...i,...up(e,r)]}:{title:"",rows:[...i,...fp(e,r)]}}function Xu(e,t){let r=e.inspectionMode,n=[{label:"CHANGES",active:r==="diff"},{label:"FILES",active:r==="files"},{label:"REVIEW",active:r==="review"}],s=[];for(let c=0;c<n.length;c++){let d=n[c];c>0&&s.push({text:" "});let u=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:u}})}let o=zn(t),i=Yn(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(c=>c.text).join(""),segments:s}}function Ui(e){return[{text:" "},zn(e),{text:" "},Yn(e)]}function Gi(e){if(e.type==="project"&&e.repoTargets?.length){let r=Hi(e.repoTargets);return r?Ui(r):null}let t=O(e);return t?.number?Ui(t):null}function Hi(e){let t=e.filter(s=>s.status==="ready"),r=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(r.length===0)return null;let n=ep(r);return{number:-1,status:Zu(r),draft:r.some(s=>s.draft),mergeable:r.length===t.length&&r.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:r.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":r.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":r.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:r.flatMap(s=>s.requiredChecks),aggregateReadiness:n}}function Zu(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 ep(e){let t=e.map(r=>zi(r));return t.some(r=>r==="failed")?"failed":t.some(r=>r==="pending")?"pending":t.length>0&&t.every(r=>r==="success")?"success":"none"}function zn(e){return!e||!e.number?{text:gi,style:{fg:"565f89"}}:e.status==="merged"?{text:hi,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:ki,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Nn,style:{fg:"565f89"}}:{text:Nn,style:{fg:"9ece6a"}}}function Yn(e){return e?.aggregateReadiness?qi(e.aggregateReadiness):qi(zi(e))}function qi(e){return e==="failed"?{text:Bn,style:{fg:"f7768e"}}:e==="pending"?{text:Wn,style:{fg:"e0af68"}}:e==="success"?{text:_n,style:{fg:"9ece6a"}}:{text:Fn,style:{fg:"565f89"}}}function zi(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(r=>r.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(r=>r.status==="success"||r.status==="skipped")?Yi(e)?"failed":tp(e)?"success":"pending":"pending"}function tp(e){return!!(e.mergeable&&!e.draft&&!Yi(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function Yi(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Qi(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return rp(e,t);let r=O(t),n=Xi("pr",t.branch,r??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==r&&(o.status==="merged"||o.status==="closed")).length;return s>0&&n.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),np(n,e)}var lr=32;function rp(e,t){let r=[],n=t.repoTargets??[],s=e.selectedProjectTargetId??n[0]?.repoId??null;for(let i of n){let l=s===i.repoId,c=e.focusedRegion==="inspector"&&l,d=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let g=i.failureReason?i.failureReason.slice(0,14):i.status,w=lr-g.length-1,R=d.length>w?d.slice(0,w-1)+"\u2026":d,I=lr-R.length-g.length;r.push({id:`project-review:${i.repoId}`,text:R+" ".repeat(Math.max(1,I))+g,selected:l,focused:c,muted:!0})}else{let u=zn(i.pullRequest),g=Yn(i.pullRequest),w=`${u.text} ${g.text}`,R=lr-w.length-1,I=d.length>R?d.slice(0,R-1)+"\u2026":d,T=lr-I.length-w.length,a=I+" ".repeat(Math.max(1,T));r.push({id:`project-review:${i.repoId}`,text:a+w,selected:l,focused:c,segments:[{text:a},{...u,text:u.text},{text:" "},{...g,text:g.text}]})}}let o=n.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(r.push({id:"target-detail-spacer",text:""}),r.push(...Xi("target",o.branch,o.pullRequest))),r}function Ji(e,t){return Qi(e,t).length}function Xi(e,t,r){let n=g=>`${e}-${g}`;if(!r.number)return[{id:n("no-pr"),text:t,muted:!0}];let s=[],o=`#${r.number}`;s.push(r.url?{id:n("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:r.url}]}:{id:n("pr-number"),text:o});let i=r.baseBranch??"?",l=r.headBranch??t;s.push({id:n("pr-branches"),text:`${i} \u2192 ${l}`,muted:!0});let c=sp(r.reviewDecision,r.mergeStateStatus),d=c&&c!=="review approved"?"merge blocked":r.mergeable?"merge ready":r.mergeStateStatus?`merge ${r.mergeStateStatus}`:"merge unknown";c?s.push({id:n("pr-merge"),text:`${d} \xB7 ${c}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:c,style:{fg:op(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:d,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${Zi(r.lastSyncedAt)}`,muted:!0}),s.push({id:n("checks-spacer"),text:""}),s.push({id:n("checks-header"),text:"Checks"}),r.requiredChecks.length?s.push(...r.requiredChecks.map(ip)):s.push({id:n("checks-none"),text:r.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let u=r.comments??[];return u.length>0&&(s.push({id:n("comments-spacer"),text:""}),s.push({id:n("comments-header"),text:`Review comments (${u.length})`}),s.push(...u.slice(-4).flatMap((g,w)=>ap(g,n(`comment:${w}`))))),s}function np(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let r=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((n,s)=>({...n,selected:t.reviewScrollOffset===0&&n.selected||s===r,focused:t.reviewScrollOffset===0&&n.focused||s===r}))}function sp(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function op(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function Zi(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),r=Math.floor(t/1e3);if(r<60)return`${r}s ago`;let n=Math.floor(r/60);if(n<60)return`${n}m ago`;let s=Math.floor(n/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function ip(e){let{icon:t,color:r}=cp(e.status),n=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${n.padEnd(16," ")} ${dp(e.status)}`,color:r,muted:!1}}function ap(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${Zi(e.createdAt)}`:"",s=lp(e.body,30),o=s.slice(0,4),i=o.length<s.length,l=[{id:`${t}:author`,text:`${r}${n}`,muted:!0},...o.map((c,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${c}\u2026`:c}`,muted:!0}))];return l.push({id:`${t}:spacer`,text:"",muted:!0}),l}function lp(e,t){let r=e.split(/\s+/).filter(Boolean);if(r.length===0)return[];let n=[],s="";for(let o of r){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(n.push(s),s=o)}return s&&n.push(s),n}function cp(e){switch(e){case"success":return{icon:_n,color:"9ece6a"};case"pending":return{icon:Wn,color:"e0af68"};case"failed":return{icon:Bn,color:"f7768e"};case"skipped":return{icon:Fn,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function dp(e){return e==="success"?"passing":e==="failed"?"failing":e}function up(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let r=new Map(t.diffRows.map(o=>[o.path,o.status])),n=pp(t.fileRows,e.collapsedFileTreePaths),s=e.selectedFileTreePath??t.selectedFilePath;return n.map(o=>{let i=o.kind==="file"?r.get(o.path):void 0,l=i==="A"?"9ece6a":i==="M"?"e0af68":i==="D"?"f7768e":i==="??"?"565f89":void 0,c=o.kind==="directory"?e.collapsedFileTreePaths.includes(o.path)?fi:mi:pi(o.label),d=o.kind==="directory"?"7aa2f7":wi(o.label),u=" ".repeat(o.depth),g=d?{text:c,style:{fg:d}}:{text:c},w=o.kind==="directory"?{text:o.label,style:{fg:"7aa2f7"}}:l?{text:o.label,style:{fg:l}}:{text:o.label},R=[{text:u},g,w];return{id:o.path,text:`${u}${c}${o.label}`,selected:o.path===s,focused:o.path===s&&e.focusedRegion==="inspector",segments:R}})}function pp(e,t){let r=new Set(t);return e.filter(n=>{let s=n.path.split("/");for(let o=1;o<s.length;o+=1)if(r.has(s.slice(0,o).join("/")))return!1;return!0})}function fp(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(mp(t))return gp(e,t);let r=[];for(let n of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===n);s.length!==0&&(r.push({id:n,text:n.toUpperCase(),muted:!0}),r.push(...s.map(o=>ea(o,e,t))))}return r}function mp(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function gp(e,t){let r=[],n=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of n){let o=t.diffRows.filter(l=>l.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;r.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let l of["branch","staged","unstaged","untracked"]){let c=o.filter(d=>d.group===l);c.length!==0&&(r.push({id:`repo-diff:${s}:${l}`,text:` ${l}`,muted:!0}),r.push(...c.map(d=>ea(d,e,t,s.length+1))))}}return r}function ea(e,t,r,n=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",l=n>0?e.path.slice(n):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${l} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??r.selectedDiffPath),focused:e.path===(t.selectedDiffPath??r.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function hp(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:S.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:At.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function kp(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function wp(e,t){return{name:S.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}var dr={width:120,height:36},ge={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function je(e,t){return{width:Math.max(e??dr.width,dr.width),height:Math.max(t??dr.height,dr.height)}}import{spawn as Bp}from"node:child_process";import{createHash as Up}from"node:crypto";import{createServer as qp,createConnection as ca}from"node:net";import{openSync as Kp}from"node:fs";import{mkdir as Vp,readFile as rs,rm as He,writeFile as Gp}from"node:fs/promises";import{tmpdir as Hp}from"node:os";import at from"node:path";import{createRequire as vp}from"node:module";import Rp from"@xterm/headless";var Tp=1e3,yp=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function ra(e){return new Rp.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:Tp,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function na(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Jn(e,t){return new Promise(r=>{e.write(t,r)})}function sa(e,t=0){let r=e.buffer.active,n=[],s=r.getNullCell(),o=r.baseY+r.cursorY,i=Math.max(0,r.baseY-t);for(let l=0;l<e.rows;l+=1){let c=r.getLine(i+l);if(!c){n.push({segments:[]});continue}let d=[];for(let u=0;u<e.cols;u+=1){let g=c.getCell(u,s);!g||g.getWidth()===0||d.push({text:g.getChars()||" ",style:Sp(g,i+l===o&&u===r.cursorX)})}n.push({segments:Pp(bp(d))})}return n}function Pp(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&xp(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};oa(r.style)||(s.style=r.style),t.push(s)}return t}function bp(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!oa(r.style))break;t-=1}return e.slice(0,t)}function Sp(e,t){let r={},n=ta(e,"fg"),s=ta(e,"bg");return n&&(r.fg=n),s&&(r.bg=s),e.isBold()&&(r.bold=!0),e.isDim()&&(r.dim=!0),e.isItalic()&&(r.italic=!0),e.isUnderline()&&(r.underline=!0),(e.isInverse()||t)&&(r.inverse=!0),r}function ta(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let n=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return n?s.toString(16).padStart(6,"0"):yp[s]??Ip(s)}function Ip(e){if(e>=16&&e<=231){let t=e-16,r=Math.floor(t/36),n=Math.floor(t%36/6),s=t%6;return[r,n,s].map(Cp).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(r=>r.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function Cp(e){return e===0?0:55+e*40}function xp(e,t){return Qn(e)===Qn(t)}function Qn(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function oa(e){return Qn(e)===""}var Ep=vp(import.meta.url),Ap=/^CTRL_([A-Z])$/,Dp="\x1B[6n",$p="\x1B[c",Lp="\x1B[?u",jp={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:""},ur=class{sessions=new Map;shell;env;spawn;onUpdate;resolveSessionSpec;attachedTabId=null;constructor(t){this.shell=t.shell??process.env.SHELL??"/bin/zsh",this.env=t.env??process.env,this.spawn=t.spawn,this.onUpdate=t.onUpdate,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,r,n,s){let o=this.sessions.get(r);if(o)if(o.status!=="running")Xn(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,ia(o,n),this.getViewState(r);let i=this.createSession(t,r,n,s);return this.sessions.set(r,i),this.attachedTabId=r,this.getViewState(r)}write(t){let r=this.getAttachedSession();!r||r.status!=="running"||r.pty.write(t)}writeKey(t){let r=Mp(t);r!==null&&this.write(r)}scrollViewport(t){let r=this.getAttachedSession();if(!r||t===0)return;let n=r.terminal.buffer.active.baseY;r.scrollbackLines=Math.max(0,Math.min(n,r.scrollbackLines-t))}resize(t){let r=this.getAttachedSession();r&&ia(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}disposeSession(t){let r=this.sessions.get(t);r&&(Xn(r),this.sessions.delete(t),this.attachedTabId===t&&(this.attachedTabId=null))}disposeAll(){for(let t of this.sessions.values())Xn(t);this.sessions.clear(),this.attachedTabId=null}getViewState(t){if(!t)return{status:"idle",rows:[],error:null,scrolledBack:!1};let r=this.sessions.get(t);return r?{status:r.status,rows:sa(r.terminal,r.scrollbackLines),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??Np().spawn,i=ra(n),l=s??this.resolveSessionSpec(t,r),c=Ue({...this.env,...l.env??{}}),{executable:d,args:u}=Fp(this.shell,l.command,{cwd:l.cwd,env:c}),g=o(d,u,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:l.cwd,env:Wp(c)}),w={taskId:t,tabId:r,pty:g,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0};return w.disposables.push(g.onData(R=>{_p(g,R),Jn(w.terminal,R).then(()=>{this.onUpdate?.(w.tabId)})})),w.disposables.push(g.onExit(R=>{w.status="exited",Jn(w.terminal,`\r
144
+ [process exited ${R.exitCode}]`).then(()=>{this.onUpdate?.(w.tabId)})})),w}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}};function Mp(e){if(e.length===1)return e;let t=jp[e];if(t!==void 0)return t;let r=Ap.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function ia(e,t){Op(e.pty,t),na(e.terminal,t)}function Xn(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function Op(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Np(){return Ep("node-pty")}function Fp(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[qe(t[0],r),...t.slice(1)].map(aa).join(" ")}; exec ${aa(e)} -l`;return{executable:e,args:["-lc",s]}}function aa(e){return`'${e.replaceAll("'","'\\''")}'`}function Wp(e){let t={};for(let[r,n]of Object.entries(e))typeof n=="string"&&(t[r]=n);return t.TERM=t.TERM??"xterm-256color",t}function _p(e,t){for(let r=0;r<Zn(t,Dp);r+=1)e.write("\x1B[1;1R");for(let r=0;r<Zn(t,$p);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<Zn(t,Lp);r+=1)e.write("\x1B[?0u")}function Zn(e,t){if(t.length===0)return 0;let r=0,n=e.indexOf(t);for(;n!==-1;)r+=1,n=e.indexOf(t,n+t.length);return r}var ns=3;async function da(e){let t=ss(e.paths);await zp(t,e.paths,e.spawnDaemon);let r=await ha(t.socketPath),n=new es(r,e);return await n.ready(),n}async function ua(e,t={}){let r=ss(e);await Vp(e.runtimeDir,{recursive:!0}),await He(r.socketPath,{force:!0});let n=new ts(e,t),s=qp(o=>n.handleConnection(o));await ef(s,r.socketPath),await Gp(r.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=()=>{n.closeClients(),s.close(()=>o())};n.onShutdown=i,process.once("SIGTERM",i),process.once("SIGINT",i)}),await He(r.socketPath,{force:!0}),await He(r.pidPath,{force:!0}),n.disposeAll()}async function pa(e){let t=ss(e);return await fr(t.socketPath)?(await ma(t.socketPath),!0):!1}var es=class{constructor(t,r){this.socket=t;this.options=r,t.setEncoding("utf8"),t.on("data",n=>this.handleData(String(n))),t.on("error",n=>this.rejectAll(n instanceof Error?n:new Error(String(n)))),t.on("close",()=>{this.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!==ns)throw new Error("Craig PTY daemon protocol mismatch.")}async ensureSession(t,r,n){let s=await this.send({type:"ensureSession",taskId:t,tabId:r,size:n,spec:this.options.resolveSessionSpec?.(t,r)??{cwd:this.options.workspaceRoot,command:[]}});this.attachedTabId=r;let o=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(r,o),o}async hydrateSessions(t){for(let r of t)try{let n=await this.send({type:"hydrateSession",tabId:r});n.view&&this.viewCache.set(r,n.view)}catch(n){let s=n instanceof Error?n.message:String(n);this.viewCache.set(r,{status:"failed",rows:[],error:s})}}async pruneStale(t){await this.send({type:"pruneStale",keepTabIds:t})}write(t){this.send({type:"write",input:t}).catch(()=>{})}writeKey(t){this.send({type:"writeKey",key:t}).catch(()=>{})}scrollViewport(t){this.send({type:"scrollViewport",lines:t}).then(r=>{this.attachedTabId&&r.view&&this.viewCache.set(this.attachedTabId,r.view)}).catch(()=>{})}resize(t){this.send({type:"resize",size:t}).then(r=>{this.attachedTabId&&r.view&&this.viewCache.set(this.attachedTabId,r.view)}).catch(()=>{})}detach(){this.attachedTabId=null,this.send({type:"detach"}).catch(()=>{})}disposeSession(t){this.viewCache.delete(t),this.attachedTabId===t&&(this.attachedTabId=null),this.send({type:"disposeSession",tabId:t}).catch(()=>{})}disposeAll(){this.attachedTabId=null,!this.closed&&(this.socket.end(),this.closed=!0)}getViewState(t){return t?this.viewCache.get(t)??{status:"idle",rows:[],error:null,scrolledBack:!1}:{status:"idle",rows:[],error:null,scrolledBack:!1}}async requestShutdown(){await this.send({type:"shutdown"})}async send(t){if(this.closed)throw new Error("Craig PTY daemon connection is closed.");let r=this.nextRequestId;this.nextRequestId+=1;let n={...t,id:r},s=new Promise((i,l)=>{this.pending.set(r,{resolve:i,reject:l})});if(this.socket.destroyed)throw this.pending.delete(r),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(n)}
145
+ `);let o=await s;if(!o.ok)throw new Error(o.error);return o}handleData(t){this.buffer+=t;let r=this.buffer.indexOf(`
146
+ `);for(;r!==-1;){let n=this.buffer.slice(0,r);this.buffer=this.buffer.slice(r+1),this.handleMessage(n),r=this.buffer.indexOf(`
147
+ `)}}handleMessage(t){if(t.trim().length===0)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r){let n=this.pending.get(r.id);if(!n)return;this.pending.delete(r.id),n.resolve(r);return}r.type==="update"&&(r.tabId&&this.viewCache.set(r.tabId,r.view),this.options.onUpdate?.(r.tabId??""))}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}},ts=class{onShutdown=null;clients=new Set;runtime;attachedTabId=null;constructor(t,r){this.runtime=new ur({...r,workspaceRoot:t.workspaceRoot,onUpdate:n=>this.broadcastUpdate(n)})}handleConnection(t){let r="";this.clients.add(t),t.setEncoding("utf8"),t.on("data",n=>{r+=String(n);let s=r.indexOf(`
148
+ `);for(;s!==-1;){let o=r.slice(0,s);r=r.slice(s+1),this.handleLine(t,o),s=r.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,r){if(r.trim().length===0)return;let n;try{n=JSON.parse(r)}catch{pr(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(n);pr(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:ns}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);pr(t,{id:n.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 r=new Set(t.keepTabIds);for(let n of this.runtime.sessionTabIds())r.has(n)||(this.runtime.disposeSession(n),this.attachedTabId===n&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(t.tabId);case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return tf(t)}}broadcastUpdate(t){let r=this.runtime.getViewState(t);for(let n of this.clients)pr(n,{type:"update",tabId:t,view:r})}};function ss(e){let t=Up("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:at.join(Hp(),`craig-${t}.sock`),pidPath:at.join(e.runtimeDir,"pty-daemon.pid")}}async function zp(e,t,r){if(await Yp(e.socketPath,1e3))return;await fr(e.socketPath)&&(await ma(e.socketPath),await la(e.socketPath,1e3)),await fr(e.socketPath)&&(await Xp(e),await la(e.socketPath,1e3)),await Jp(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:l}=Qp(n),c=Kp(at.join(t.runtimeDir,"pty-daemon.log"),"a");Bp(i,l,{cwd:n,detached:!0,stdio:["ignore",c,c],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await fa(e.socketPath))return;await os(50)}let o=await rs(at.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
150
+ ${o.slice(-2e3)}`:""}`)}async function fa(e){let t=await Zp(e).catch(()=>null);return t?.ok===!0&&t.protocolVersion===ns}async function Yp(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await fa(e))return!0;await os(50)}return!1}function Qp(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=at.resolve(at.dirname(t),"..","node_modules",".bin","tsx");return{command:dn("tsx")??n,args:[t,"__craig-daemon",e]}}let r=process.argv.slice(1);return{command:process.execPath,args:[...process.execArgv,...r,"__craig-daemon",e]}}async function Jp(e){let t=await rs(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&ka(r))return}await He(e.socketPath,{force:!0}),await He(e.pidPath,{force:!0})}async function fr(e){let t=await ha(e).catch(()=>null);return t?(t.end(),!0):!1}async function ma(e){await ga(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Xp(e){let t=await rs(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!ka(r)){await He(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await He(e.socketPath,{force:!0})}}async function Zp(e){return ga(e,{id:1,type:"ping"})}function ga(e,t){return new Promise((r,n)=>{let s=ca(e),o="",i=setTimeout(()=>{s.destroy(),n(new Error("Craig PTY daemon request timed out."))},500),l=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
151
+ `)),s.once("error",c=>{l(),n(c)}),s.on("data",c=>{o+=String(c);let d=o.indexOf(`
152
+ `);if(d===-1)return;let u=o.slice(0,d);l(),s.end();try{r(JSON.parse(u))}catch(g){n(g instanceof Error?g:new Error(String(g)))}}),s.once("close",()=>l())})}async function la(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await fr(e))return;await os(50)}}function ha(e){return new Promise((t,r)=>{let n=ca(e);n.once("connect",()=>t(n)),n.once("error",r)})}function ef(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function pr(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
153
+ `)}catch{}}function ka(e){try{return process.kill(e,0),!0}catch{return!1}}function os(e){return new Promise(t=>setTimeout(t,e))}function tf(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}import ny from"picocolors";var rf=[" \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 is(){return[...rf]}var nf=["Start","Options","Exit"],sf=["Resume","Options","Exit"],hr=2,kr=2,wr=2,of=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),af=new RegExp("\x1B\\[(?:0)?m","g"),lf=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),cf=/https?:\/\/[^\s<>"']+/g,as="\x1B[0m",ls="\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 Ta(e,t={}){return ds(e,{subtitle:"crAIg is that you?",menuItems:nf,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function ya(e,t={}){return ds(e,{subtitle:"Control mode is paused.",menuItems:sf,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var mr=[" 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."],df=["Help"];function cs(e,t={}){return ds(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??df,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Pa(e,t={}){let r=t.color??!0,n=E.overlay,s=new Array(e.height).fill(W(" ".repeat(e.width),r,n)),o=is(),i=Math.max(1,Math.floor((e.height-o.length-2-mr.length)/2));for(let u=0;u<o.length&&!(i+u>=e.height);u+=1)s[i+u]=W(xa(o[u]??"",e.width),r,E.overlayLogo);let l=Math.max(...mr.map(u=>u.length)),c=Math.max(0,Math.floor((e.width-l)/2)),d=i+o.length+2;for(let u=0;u<mr.length;u+=1){let g=d+u;if(g>=e.height)break;let w=mr[u]??"";s[g]=W(Te(" ".repeat(c)+w,e.width),r,n)}return s.join(`
154
+ `)}function ba(e,t={}){let r=t.color??!0,n=E.overlay,s=new Array(e.height).fill(W(" ".repeat(e.width),r,n)),o="Error Log",i=t.errorLogPath??"",l=t.errorLogLines??[],c=Math.max(20,e.width-8),d=Math.max(0,Math.floor((e.width-c)/2)),u=[{text:o,tone:"selected"},{text:i,tone:"muted"},ae(),...l.length>0?l.map(R=>({text:R})):[{text:"No Craig errors have been logged.",tone:"muted"}],ae(),{text:"Esc returns to Options.",tone:"muted"}],g=Dt(u,e.height-2),w=Math.max(1,Math.floor((e.height-g.length)/2));for(let R=0;R<g.length;R+=1){let I=w+R;if(I>=e.height)break;let T=g[R]??ae(),a=`${" ".repeat(d)}${Tr(T.text,c)}`,z=T.tone==="selected"?E.overlayMenuSelected:T.tone==="muted"?E.overlay:E.panelBg;s[I]=W(Te(a,e.width),r,z)}return s.join(`
155
+ `)}function Sa(e,t,r={}){let n=r.color??!0,s=ge.leftWidth,o=ge.rightWidth,i=ge.dividerWidth,l=r.centerOnly??!1,c=l?e.width:e.width-s-o-i*2,d=e.height-ge.topRailHeight-1,u=r.focusFlashActive??!1,g={bg:E.divider.bg,fg:"9ece6a"},w=u&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?g:E.divider,R=u&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?g:E.divider,I=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=W(Te(I,e.width),n,E.rail),a=pf(t,s-hr-kr,d,n),z=ff(t,c,d,n),U=gf(t,o,d,n),le=t.inputMode==="terminal",x=[];for(let oe=0;oe<d;oe+=1){if(l){x.push(gr(z[oe]??ae(),c,n,"center"));continue}let xe=gr(a[oe]??ae(),s,n,"left"),he=W("\u2502",n,w),ve=gr(z[oe]??ae(),c,n,"center"),ce=W("\u2502",n,R),ze=gr(U[oe]??ae(),o,n,"right");x.push(`${xe}${he}${ve}${ce}${ze}`)}let Me=le||t.modalInput?E.panelBg:E.panelMuted,Ce=uf(t.footerText,t.footerToast,e.width,n,Me);return[T,...x,Ce].join(`
156
+ `)}function uf(e,t,r,n,s){let o=` ${e}`;if(!t)return W(Te(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,l=se(i),c=se(o),d=Math.max(1,r-c-l-2),u=c+d+l+2>r?Tr(o,Math.max(0,r-l-3)):o,g=Math.max(1,r-se(u)-l-2),w=t.tone==="error"?jf(i,n,s):lt(i,n,s),R=`${u}${" ".repeat(g)}${w} `;return W(Te(R,r),n,s)}function ds(e,t){let r=new Array(e.height).fill(W(" ".repeat(e.width),t.color,E.overlay)),n=is(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,u)=>`${u===t.menuIndex?">":" "} ${d.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],l=[...n,"",t.subtitle,"",...o,...i],c=Math.max(1,Math.floor((e.height-l.length)/2));for(let d=0;d<l.length;d+=1){let u=xa(l[d]??"",e.width);if(d<n.length){r[c+d]=W(u,t.color,E.overlayLogo);continue}if(d===n.length+1){r[c+d]=W(u,t.color,E.overlaySubtitle);continue}let g=d-(n.length+3),R=g>=0&&g<t.menuItems.length&&g===t.menuIndex?E.overlayMenuSelected:E.overlay;r[c+d]=W(u,t.color,R)}if(t.versionText){let d=t.updateText?" (update available)":"",u=`${t.versionText}${d} `,g=" ".repeat(Math.max(0,e.width-se(u)));r[e.height-1]=W(`${g}${us(u,t.color,E.overlay)}`,t.color,E.overlay)}return r.join(`
157
+ `)}function pf(e,t,r,n){let s=wf(e.runners),o=1,i=e.leftTree.map(c=>kf(c,t,n));return[...Dt(i,r-o),s]}function ff(e,t,r,n){let s=t-2,o=e.tabs.find(x=>x.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:Df(e.tabs),l=e.inputMode==="terminal"?s:o.length+1,c="\u2500".repeat(Math.max(0,l)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?lt(c,n,E.panelBg):Rr(c,n,E.panelMuted)}`,u=[`${Rr(e.centerHeader.tabLabel,n,E.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),g=e.tabs.find(x=>x.active)?.id??"agent",w=e.centerHeader.tabLabel==="BROWSER"||!ji(g)?e.centerTranscript.map(x=>({...x})):mf(e),R=Rf(e.tabs,n,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?lt(`${I}\u25CF `,n,E.panelBg):"",z=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-se(R)-T)):"",le=[{text:e.inputMode==="terminal"?`${R}${z}${a}`:R},{text:d,tone:"muted"},{text:u},ae(),...w];return Dt(le,r)}function mf(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},ae(),{text:e.terminal.error},ae(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(n=>n.active)?.id??"",r=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${r.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(n=>({text:Aa(n.segments),segments:n.segments,fullBleed:!0}))}function gf(e,t,r,n){let s=e.rightInspection?hf(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,r):Dt([{text:"CONTEXT"},ae(),...e.rightContext.map(o=>Tf(o,n)),...e.actionMessage?[ae(),{text:e.actionMessage}]:[]],r);return Dt(s,r)}function hf(e,t){let r=e.slice(0,2),n=e.slice(2),s=Math.max(0,t-r.length),o=n.findIndex(l=>l.focused||l.selected),i=o===-1?0:Lf(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(l=>wa(l)),...n.slice(i,i+s).map(l=>wa(l))]}function wa(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",r=e.focused||e.selected?"selected":e.muted?"muted":"default",n=`${t}${e.text}`;if(e.segments)return{text:n,segments:[{text:t},...e.segments],tone:r};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:n,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:r}}return e.color?{text:n,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:r}:{text:n,tone:r}}function kf(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${lt("\u25CF",r,e.selected?E.panelSelected:E.panelBg)}`:"",l=e.prBadge?e.prBadge.reduce((R,I)=>R+se(I.text),0):0,c=t-se(o)-se(s)-l,d=e.selected?e.text:e.focused?lt(e.text,r,E.panelBg):e.panelHeader?Rr(e.text,r,E.panelMuted):e.text,u=Te(`${n}${d}`,Math.max(0,c)),g=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let R=[{text:`${u}${o}${i}`},...e.prBadge];return{text:`${u}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:R,tone:g}}return{text:`${u}${o}${i}`,tone:g}}function wf(e){let t=e.map(n=>{let s=n.health>=1,o=parseInt(n.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${n.name}${i}`,active:s}}),r=[];for(let n=0;n<t.length;n++){let s=t[n];n>0&&r.push({text:" "}),s.active?r.push({text:s.text,style:{fg:E.success.fg}}):r.push({text:s.text,style:{fg:E.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function Rf(e,t,r){return e.map(n=>n.active?r?lt(n.label,t,E.panelBg):Rr(n.label,t,E.panelBg):us(n.label,t,E.panelBg)).join(" ")}function Tf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?us(e.value,t,E.panelBg):e.value}`}}function gr(e,t,r,n){let s=yf(n,e.tone??"default"),o=Pf(e,r,s);if(n==="left"){if(e.fullBleed)return W(Te(o,t),r,s);let l=t-hr-kr;if(e.rightAlign){let d=se(o),u=Math.max(0,l-d),g=`${" ".repeat(hr)}${" ".repeat(u)}${o}${" ".repeat(kr)}`;return W(g,r,s)}let c=`${" ".repeat(hr)}${Te(o,l)}${" ".repeat(kr)}`;return W(c,r,s)}return n==="center"&&e.fullBleed?bf(e,t,r,s):W(Te(` ${o}`,t),r,s)}function yf(e,t){return t==="selected"||t==="focused"?E.panelSelected:t==="muted"?E.panelMuted:E.panelBg}function Dt(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(ae());return r}function ae(){return{text:""}}function Pf(e,t,r){return e.segments?e.segments.map(n=>Ia(n,t,r)).join(""):e.text}function bf(e,t,r,n){let s=" ".repeat(wr),o=Math.max(0,t-wr*2);if(!e.segments)return W(`${s}${Te(e.text,o)}${s}`,r,n);let i=Cf(e.segments,o),l=`${s}${i.map(c=>Ia(c,r,n)).join("")}${s}${r?ls:""}`;return W(l,r,n)}function Ia(e,t,r){let n=e.href?`${Ca(e.href)}${e.text}${ls}`:Sf(e.text);return!t||!e.style?n:`${$t(Ef(e.style,r))}${Af(e.style)}${n}${as}${$t(r)}`}function Sf(e){return e.replace(cf,t=>{let[r,n]=If(t);return`${Ca(r)}${r}${ls}${n}`})}function If(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function Ca(e){return`\x1B]8;;${e}\x1B\\`}function Cf(e,t){let r=xf(e,t);return vf(r,t)}function xf(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=se(s.text);if(o<=n){r.push(s),n-=o;continue}let i=Tr(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function vf(e,t){let r=se(Aa(e));if(r>=t)return e;let n=e.at(-1)?.style;return n?.bg?[...e,{text:" ".repeat(t-r),style:n}]:[...e,{text:" ".repeat(t-r)}]}function Ef(e,t){let r=e.inverse?e.bg??t.bg:e.fg,n=e.inverse?e.fg??t.fg:e.bg,s={},o=r??t.fg,i=n??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function Af(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 Df(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+3}return 0}function xa(e,t){let r=Math.max(0,t-se(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function Te(e,t){let r=se(e);return r>=t?$f(e,t):e+" ".repeat(t-r)}function $f(e,t){if(t<=0)return"";if(se(e)<=t)return e;let r=Ea(e);return Tr(r,Math.max(0,t-1))+"\u2026"}function se(e){let t=0;for(let r of Array.from(Ea(e)))t+=va(r);return t}function Tr(e,t){let r="",n=0;for(let s of Array.from(e)){let o=va(s);if(n+o>t)break;r+=s,n+=o}return r}function va(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 Lf(e,t,r){return Math.min(Math.max(e,t),r)}function Ea(e){return e.replace(lf,"").replace(of,"")}function Aa(e){return e.map(t=>t.text).join("")}function W(e,t,r){if(!t)return e;let n=$t(r),s=e.replace(af,`${as}${n}`);return`${n}${s}${as}`}function $t(e){let t=[];return e.fg&&t.push(`38;2;${Ra(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Ra(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Ra(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function lt(e,t,r){return yr(e,t,E.success.fg,r)}function jf(e,t,r){return yr(e,t,E.error.fg,r)}function Rr(e,t,r){return yr(e,t,E.accent.fg,r)}function us(e,t,r){return yr(e,t,E.mutedfg.fg,r)}function yr(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${$t(s)}${e}${$t(n)}`}var ps=["Runners","Error Log","Help"];function fs(e,t){return N.map(r=>{let n=S.runners.getProfile(r),s=e.runners?.[r]?.enabled!==!1,o=e.runners?.[r]?.path?.trim(),i=t.pathEdit?.runner===r?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${n.executable})`;return`${n.displayName} ${s?"enabled":"disabled"} ${i}`})}function $a(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(ps.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:ms(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function ja(e,t,r,n){if(e.pathEdit)return Mf({...e,pathEdit:e.pathEdit},t,r);let s=fs(t,e).length;if(r==="UP"||r==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(r==="DOWN"||r==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(r==="e"){let l=N[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:l,value:t.runners?.[l]?.path??""}}}}if(!ms(r))return{kind:"noop",state:e};let o=N[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&n.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:Of(t,o,!i),state:{...e,message:`${S.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function Mf(e,t,r){if(r==="ESCAPE")return{kind:"render",state:Da({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(ms(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:Nf(t,n,s.length>0?s:null),state:Da({...e,message:s.length>0?`${S.runners.getProfile(n).displayName} executable saved.`:`${S.runners.getProfile(n).displayName} executable reset to default.`})}}return Ff(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function Of(e,t,r){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}}}function Nf(e,t,r){let n={...e.runners?.[t]??{},...r?{path:r}:{}};return r||delete n.path,{...e,runners:{...e.runners??{},[t]:n}}}function Da(e){let t={...e};return delete t.pathEdit,t}function ms(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
158
+ `}function Ff(e){return e.length===1&&e>=" "&&e!=="\x7F"}var Uf=Wf(import.meta.url),qf=Uf("terminal-kit"),Kf=qf.terminal;async function Na(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=Pe(t),n=await S.load(r),s=S.runners.getEnabled(n),o=e.uiStateFile?await J({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),l=Promise.resolve(),c=await Lt(t,void 0,s),d=ar(Ei(o,n),c);c=await Lt(t,d,s);let u=()=>{},g={workspaceRoot:t,onUpdate:()=>u(),resolveSessionSpec:(I,T)=>zf(c,T,t)},w=e.ptyRuntime??await da({...g,paths:r}),R=I=>{if(!e.uiStateFile)return;o=Ai(o,I);let T=o;i=i.then(()=>Y({uiStateFile:e.uiStateFile},T),()=>Y({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:ar(d,c)},z=!1,U=!1,le=null,x=0,Me=0,Ce=null,oe=null,xe=null,he=null,ve=null,ce=null,ze=null,Sr=!1,Ir=null,hs=`Craig v${S.version.getCurrent()}`,Cr=null,xr=0,Q=!0,vr=null,y=()=>{},_=w;u=()=>{a.mode==="main"&&(a={mode:"main",shell:dt(a.shell)},xe||(xe=setTimeout(()=>{xe=null,a.mode==="main"&&y()},50)))};function dt(f){return Ge(f,_.getViewState(ks(f)))}function ks(f){let p=Ye(f);return p?p.ptyTabs.some(m=>m.id===f.activeTab)?f.activeTab:f.activeTab==="agent"||f.activeTab==="terminal"?p.ptyTabs.find(m=>m.kind===f.activeTab)?.id??f.selectedPtyTabId:f.selectedPtyTabId:f.selectedPtyTabId}function P(f){return dt(Vf(f,c))}function Ye(f){return c.tasks.find(p=>p.id===f.selectedTaskId)??null}async function ws(){let f=c.tasks.flatMap(p=>p.ptyTabs.map(m=>m.id));await _.pruneStale?.(f),await _.hydrateSessions?.(f)}function Wa(){ws().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function _a(f){let p=P(f),m=Ye(p),h=ks(p);if(!m||!h||!m.ptyTabs.some(F=>F.id===h))return p;let k=_.getViewState(h);if(k.status!=="idle"||k.rows.length>0||k.error)return Ge(p,k);let C=await _.ensureSession(m.id,h,Mt(je(T.width,T.height)));return Ge({...p,inputMode:"control"},C)}function Rs(f,p){return he&&(clearTimeout(he),he=null),p?(he=setTimeout(()=>{he=null,!(a.mode!=="main"||a.shell.footerToast!==p)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...f,footerToast:p}):{...f,footerToast:null}}function Ba(f,p){return Rs(f,p?{tone:"success",message:p}:null)}function K(f,p,m){let h=p instanceof Error?p.message:m,k=p instanceof Error?p.stack??p.message:String(p);return er.appendErrorLogBestEffort(r,{context:f,message:h,details:k}),h}function V(f,p){return Rs(f,{tone:"error",message:p})}function Oe(f){let p=l.then(f,f);return l=p.then(()=>{},()=>{}),p}function Ts(f){let p=Ye(f),m=c.inspection,h=m&&m.taskId===p?.id?m:null,k=Gf(h?.fileRows??[],f.collapsedFileTreePaths);return{leftItemIds:Hf(c),centerTabIds:Oi(p,f),ptyTabIds:p?.ptyTabs.map(C=>C.id)??[],filePathIds:h?.filePaths??[],fileTreeRowIds:k.map(C=>C.path),fileTreeFileIds:k.filter(C=>C.kind==="file").map(C=>C.path),fileTreeDirectoryIds:k.filter(C=>C.kind==="directory").map(C=>C.path),diffPathIds:h?.diffPaths??[],diffPathRanges:[],fileLineCount:h?.selectedFile.lines.length??0,diffLineCount:h?.selectedDiff.lines.length??0,reviewRowCount:Ji(f,p),pageRows:Math.max(5,je(T.width,T.height).height-ge.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:p?.repoTargets?.map(C=>C.repoId)??[]}}async function Ua(f){await S.save(r,f),n=f,s=S.runners.getEnabled(n),c={...c,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:S.runners.getDefault(n)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:S.runners.getDefault(n)})}}async function qa(f){let p=f.selectedTaskId;p&&await Oe(async()=>{let m=await pe(r,p);!m.ptyTabs.some(h=>h.id===f.activeTab)||m.selectedPtyTabId===f.activeTab||await A(r,{...m,selectedPtyTabId:f.activeTab})})}async function de(){let f=(a.mode==="main",a.shell);c=await Lt(t,f,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function ys(f){let p=++xr,m=Fa(c.tasks,f),h=c.inspection,k;if(m&&h?.taskId===m.id){let C={selectedFilePath:f.selectedFilePath,selectedDiffPath:f.selectedDiffPath},F=await ri(m,h,C);if(p!==xr)return;k={...c,inspection:F}}else if(k=await Lt(t,f,s),p!==xr)return;c=k,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},R(a.shell),y())}async function Er(f){let p=await am(f);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:p,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function Ps(f){try{let p=P(f),m=Ye(p),h=p.selectedPtyTabId;if(m&&p.focusedRegion==="tasks"){let F=m.ptyTabs.find(fe=>fe.kind==="agent")??null;F?h=F.id:(m=await bs(m),await de(),h=m.selectedPtyTabId)}m&&!h&&(m=await bs(m),await de(),h=m.selectedPtyTabId);let k=P({...p,activeTab:h??p.activeTab,selectedPtyTabId:h,focusedRegion:h?"center":p.focusedRegion});if(!k.selectedTaskId||!h){a={mode:"main",shell:k},y();return}a={mode:"main",shell:Ge({...k,inputMode:"terminal"},_.getViewState(h))},R(a.shell);let C=await _.ensureSession(k.selectedTaskId,h,Mt(je(T.width,T.height)));U=gs(h),le=null,a={mode:"main",shell:Ge({...k,inputMode:"terminal"},C)},R(a.shell)}catch(p){let m=K("attach PTY",p,"Failed to start PTY.");f.selectedTaskId&&f.selectedPtyTabId&&gs(f.selectedPtyTabId)&&(await Ka(f.selectedTaskId,m).catch(()=>{}),await de().catch(()=>{})),a={mode:"main",shell:V($i(P(f),m),m)},R(a.shell)}y()}async function Ka(f,p){await Oe(async()=>{await D.markRunnerFailed(r,f,p)})}async function Va(f,p,m){let h=P(f);if(!h.selectedTaskId)throw new Error("Select a task before creating a tab.");let k=await Oe(async()=>{let C=await pe(r,h.selectedTaskId),F=p??Jf(C,h.activeTab,h.preferredPtyTabKind),fe=Ma(C,F,m??void 0,n),ut={...C,ptyTabs:[...C.ptyTabs,fe],selectedPtyTabId:fe.id};return await A(r,ut),ut});return await de(),P({...h,activeTab:k.selectedPtyTabId??h.activeTab,selectedPtyTabId:k.selectedPtyTabId,preferredPtyTabKind:k.ptyTabs.at(-1)?.kind??h.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${k.ptyTabs.at(-1)?.title??"tab"}`})}async function Ga(f){let p=P(f);if(!p.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:m,nextSelectedTab:h}=await Oe(async()=>{let k=await pe(r,p.selectedTaskId),C=k.ptyTabs.findIndex($r=>$r.id===p.activeTab);if(C===-1)throw new Error("Only PTY tabs can be closed.");let F=k.ptyTabs[C],fe=k.ptyTabs.filter($r=>$r.id!==F.id),ut=fe[Math.min(C,fe.length-1)]??fe[C-1]??null;return await A(r,{...k,ptyTabs:fe,selectedPtyTabId:ut?.id??null}),{closedTab:F,nextSelectedTab:ut}});return _.disposeSession(m.id),await de(),P({...p,activeTab:h?.id??(p.openInspectionKind?"inspection":p.activeTab),selectedPtyTabId:h?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${m.title}`})}async function Ha(f){let p=P(f);if(!p.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let m=Ye(p),h=null,k=null;if(m?.type==="project"&&m.repoTargets?.length){let C=await D.prs.discoverOrRefreshAll(r,p.selectedTaskId);await de();let F=C.synced+C.discovered+C.notFound;k=`Refreshed ${C.synced}/${F} targets`}else{let{disposition:C,task:F}=await D.prs.discoverOrRefresh(r,p.selectedTaskId);await de(),h=C==="not_found"?`No PR found for ${F.branch}`:null,C!=="not_found"&&(k=`Refreshed checks: ${O(F)?.requiredChecks.length??0} reported`)}return P({...Ba(p,k),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:h})}async function za(){if(Sr||a.mode!=="main")return;let f=c.tasks;Sr=!0;try{if(await D.prs.discoverOrRefreshMany(r,f),Ir=null,a.mode!=="main")return;c=await Lt(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(p){let m=p instanceof Error?p.message:"Background PR discovery failed.";m!==Ir&&(Ir=m,er.appendErrorLogBestEffort(r,{context:"background PR polling",message:m,details:p instanceof Error?p.stack??p.message:String(p)}))}finally{Sr=!1}}async function Ya(f){let p=P(f);if(!p.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:m,task:h}=await Oe(async()=>{let k=await pe(r,p.selectedTaskId),C=await D.closeTask(r,p.selectedTaskId);return{taskBeforeClose:k,task:C}});for(let k of m.ptyTabs)_.disposeSession(k.id);return await de(),P({...p,selectedActionId:"close-task",actionMessage:h.cleanup.preservedWorktree?`Archived task ${h.id}; worktree preserved`:`Archived task ${h.id}`})}async function Qa(f){let p=P(f);if(!p.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await D.listTasks(r,{workspaceId:p.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${p.selectedWorkspaceId} while task records still reference it.`);await re.archiveWorkspace(r,p.selectedWorkspaceId);let h=await re.removeWorkspace(r,p.selectedWorkspaceId,{listTasks:D.listTasks});return await de(),P({...p,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${h.workspaceId}`})}async function bs(f){let p=f.ptyTabs.find(k=>k.kind==="agent")??null;if(p){let k={...f,selectedPtyTabId:p.id};return await Oe(async()=>{let C=await pe(r,f.id),F=C.ptyTabs.find(fe=>fe.kind==="agent")??null;F&&await A(r,{...C,selectedPtyTabId:F.id})}),k}let m=Ma(f,"agent",void 0,n),h={...f,ptyTabs:[...f.ptyTabs,m],selectedPtyTabId:m.id};return await Oe(async()=>{let k=await pe(r,f.id),C=k.ptyTabs.find(F=>F.kind==="agent")??null;if(C){await A(r,{...k,selectedPtyTabId:C.id});return}await A(r,{...k,ptyTabs:[...k.ptyTabs,m],selectedPtyTabId:m.id})}),h}y=()=>{Ja();let f=je(T.width,T.height),p=a.mode==="main"?Sa(f,Ki(P(a.shell),c),{centerOnly:a.shell.centerZoomed,focusFlashActive:ve!==null&&Date.now()<ve}):a.variant==="boot"?Ta(f,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:hs,updateText:Cr}):a.variant==="pause"?ya(f,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:hs,updateText:Cr}):a.variant==="options"?cs(f,{menuIndex:a.menuIndex,optionsMenuItems:ps}):a.variant==="runners"?cs(f,{menuIndex:jt(a).menuIndex,optionsMenuItems:fs(n,jt(a)),optionsMessage:$a(jt(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?ba(f,{errorLogPath:a.errorLog?.path??r.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Pa(f);Q&&(T.moveTo(1,1),T.eraseDisplayBelow(),Q=!1),T.noFormat(em(p)),T.hideCursor(!0)};function Ja(){let f=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";f!==vr&&(vr=f,T.grabInput(f==="terminal"?{mouse:"button"}:!0))}let Xa=()=>{process.stdout.off("resize",vs),process.off("SIGCONT",Es),T.removeListener("key",Ss),T.removeListener("unknown",Is),T.removeListener("mouse",Cs),Ce&&(clearTimeout(Ce),Ce=null),oe&&(clearTimeout(oe),oe=null),xe&&(clearTimeout(xe),xe=null),he&&(clearTimeout(he),he=null),ce&&(clearTimeout(ce),ce=null),ze&&(clearInterval(ze),ze=null),_.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},Ar=f=>{Xa(),I(f)},Za=async()=>{if(a.mode!=="main"||z)return;let f=a.shell,p=f.taskPromptInput?.trim()??"";if(!f.selectedRepoId&&!f.selectedWorkspaceId){a={mode:"main",shell:P({...f,taskPromptError:"Select a workspace first."})},y();return}if(p.length===0){a={mode:"main",shell:P({...f,taskPromptError:"Task prompt cannot be empty."})},y();return}z=!0,a={mode:"main",shell:P({...f,actionMessage:`Creating ${f.selectedRunner} task in ${f.selectedWorkspaceId??f.selectedRepoId}...`})},y();let m=null;try{m=await Xf(r,f.selectedRepoId,f.selectedWorkspaceId,p,f.selectedRunner),await de();let h=P({...a.shell,selectedRepoId:m.repoId,selectedWorkspaceId:m.workspaceId,selectedTaskId:m.id,selectedPtyTabId:m.selectedPtyTabId,selectedLeftItemId:`task:${m.id}`,activeTab:m.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),k=await _.ensureSession(m.id,h.selectedPtyTabId??Zf(m,"agent"),Mt(je(T.width,T.height)));U=gs(h.selectedPtyTabId),a={mode:"main",shell:Ge(h,k)},R(a.shell)}catch(h){h instanceof Pr&&(m=h.task);let k=K("create task",h,"Failed to create task.");m&&(await A(r,{...m,status:"draft",runnerSession:{...m.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:k}).catch(()=>{}),await de().catch(()=>{})),a={mode:"main",shell:V(P({...a.shell,inputMode:"control",selectedTaskId:m?.id??a.shell.selectedTaskId,selectedPtyTabId:m?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:m?`task:${m.id}`:a.shell.selectedLeftItemId,activeTab:m?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:m?null:"",taskPromptError:k,actionMessage:null}),k)}}finally{z=!1,y()}},el=f=>{if(a.mode!=="main")return;let p=a.shell;if(p.taskPromptInput!==null){if(f==="ESCAPE"){a={mode:"main",shell:P({...p,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Ie(f)){Za();return}if(f==="BACKSPACE"){a={mode:"main",shell:P({...p,taskPromptInput:p.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(f==="CTRL_R"){a={mode:"main",shell:P({...p,selectedRunner:Vn(p.selectedRunner,s),taskPromptError:null})},y();return}Li(f)&&(a={mode:"main",shell:P({...p,taskPromptInput:`${p.taskPromptInput}${f}`,taskPromptError:null})},y())}},tl=f=>{if(a.mode!=="main")return;let p=a.shell.workspaceBrowser;if(p){if(f==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(f==="UP"||f==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...p,selectedIndex:Math.max(0,p.selectedIndex-1),error:null}})},y();return}if(f==="DOWN"||f==="j"){let m=Math.max(0,p.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...p,selectedIndex:Math.min(m,p.selectedIndex+1),error:null}})},y();return}if(f==="LEFT"||f==="h"){Er(ct.dirname(p.cwd)).catch(m=>{let h=K("open parent workspace directory",m,"Failed to open parent directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...p,error:h}}),h)},y()});return}if(f==="RIGHT"||f==="l"||Ie(f)){let m=p.entries[p.selectedIndex]??null;if(!m)return;if((f==="RIGHT"||f==="l")&&(m.kind==="directory"||m.kind==="repo")){Er(m.path).catch(h=>{let k=K("open workspace directory",h,"Failed to open directory.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...p,error:k}}),k)},y()});return}re.addWorkspace(r,m.path).then(async h=>{await de();let k=h.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${h.workspace.id}`,selectedWorkspaceId:h.workspace.id,selectedRepoId:k?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${h.workspace.name??h.workspace.id}`})},R(a.shell),y()}).catch(h=>{let k=K("add workspace",h,"Failed to add workspace.");a={mode:"main",shell:V(P({...a.shell,workspaceBrowser:{...p,error:k}}),k)},y()})}}},Ss=f=>{let p=typeof f=="string"?f:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){el(p);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){tl(p);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(p==="F"){ol(),y();return}ve!==null&&(ve=null,ce&&(clearTimeout(ce),ce=null))}if(a.mode==="main"){let m=Di(a.shell,p,Ts(a.shell));if(m.exit){Ar(0);return}if(m.detachTerminal){_.detach(),a={mode:"main",shell:P(m.state)},R(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(m.changed){a={mode:"main",shell:P(m.state)},R(a.shell),y();return}if(U&&Ie(p)){U=!1;return}U&&(U=!1),le=rm(p)?{key:p,at:Date.now()}:null;let h=nm(p,a.shell.terminal.scrolledBack??!1);if(h!==0){Dr(h);return}_.writeKey(p);return}if(p==="CTRL_C"){Ar(0);return}if(p==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},Q=!0,y();return}if(m.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(m.state)},Q=!0,y();return}if(m.beginTaskPrompt){a={mode:"main",shell:P(m.state)},R(a.shell),y();return}if(m.openWorkspaceBrowser){Er(t).catch(h=>{let k=K("browse workspaces",h,"Failed to browse workspaces.");a={mode:"main",shell:V(P({...m.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:k}}),k)},y()});return}if(m.createPtyTab){Va(m.state,m.createPtyTabKind,m.createPtyTabRunner).then(h=>{Ps(h)}).catch(h=>{let k=K("create PTY tab",h,"Failed to create tab.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.closePtyTab){Ga(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("close PTY tab",h,"Failed to close tab.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.refreshPullRequestChecks){Ha(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("refresh PR checks",h,"Failed to refresh PR checks.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.openPrUrl){let h=Ye(m.state),k=h?O(h)?.url??null:null;k?lm(k).catch(C=>{let F=K("open PR URL",C,"Failed to open PR in browser.");a={mode:"main",shell:V(P(m.state),F)},y()}):(a={mode:"main",shell:V(P(m.state),"No PR URL available.")},y());return}if(m.closeTask){Ya(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("close task",h,"Failed to close task.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.removeWorkspace){Qa(m.state).then(h=>{a={mode:"main",shell:h},R(a.shell),y()}).catch(h=>{let k=K("remove workspace",h,"Failed to remove workspace.");a={mode:"main",shell:V(P({...m.state,actionMessage:k}),k)},y()});return}if(m.attachTerminal){Ps(m.state);return}if(m.refreshInspection){a={mode:"main",shell:P(m.state)},R(a.shell),y(),ys(a.shell).catch(h=>{let k=K("refresh inspection",h,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:k}),k)},y()});return}m.changed&&(a={mode:"main",shell:P(m.state)},qa(a.shell).catch(()=>{}),R(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)},Q=!0,y();return}if(a.variant==="options"){rl(p);return}if(a.variant==="runners"){sl(p);return}if(a.variant==="error-log"){if(p==="ESCAPE"||Ie(p)){let m=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y()}return}if(a.optionsMessage){(p==="ESCAPE"||Ie(p))&&(a={...a,optionsMessage:null},y());return}if(p==="UP"||p==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(p==="DOWN"||p==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(p==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},Q=!0,y());return}if(Ie(p)){if(a.menuIndex===0){let m=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},Q=!0,y(),m?ll.then(()=>{if(a.mode!=="main")return;let h=a.shell;_a(h).then(k=>{a.mode!=="main"||a.shell!==h||(a={mode:"main",shell:k},R(a.shell),y())}).catch(k=>{if(a.mode!=="main"||a.shell!==h)return;let C=K("warm selected PTY",k,"Failed to start selected PTY.");a={mode:"main",shell:V(P(a.shell),C)},R(a.shell),y()})}):Wa();return}if(a.menuIndex===1){let m=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}Ar(0)}};function rl(f){if(a.mode!=="overlay"||a.variant!=="options")return;let p=La(a.menuIndex,f);if(p.kind!=="noop"){if(p.kind==="render"){a={...a,menuIndex:p.menuIndex},y();return}if(p.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},Q=!0,y());return}if(p.kind==="help"){let m=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}if(p.kind==="runners"){let m=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}if(p.kind==="error-log"){let m=a.parentVariant;nl(m)}}}async function nl(f){let p;try{p=await er.readRecentErrorLines(r)}catch(m){let h=K("open error log",m,"Failed to read Craig error log.");p={path:r.errorLogFile,lines:[`Unable to read error log: ${h}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:p,...f!==void 0?{parentVariant:f}:{}},Q=!0,y())}function sl(f){if(a.mode!=="overlay"||a.variant!=="runners")return;let p=ja(jt(a),n,f,s);if(p.kind!=="noop"){if(p.kind==="back"){let m=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...m!==void 0?{parentVariant:m}:{}},Q=!0,y();return}if(p.kind==="render"){a={...a,runnerOptions:p.state},y();return}Ua(p.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:p.state},y())}).catch(m=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let h=K("save runner option",m,"Failed to save runner option."),k=V(P(a.shell),h);a={...a,shell:k,runnerOptions:{...jt(a),message:h}},y()})}}function ol(){ve=Date.now()+600,ce&&clearTimeout(ce),ce=setTimeout(()=>{ve=null,ce=null,y()},600)}let Is=f=>{let p=tm(f);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||p.length===0)return;if(p.includes("")){_.detach(),U=!1,le=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},R(a.shell),y();return}let m=sm(p);if(m!==0){Dr(m);return}let h=om(p);if(h){U=!1,le={key:h,at:Date.now()},_.writeKey(h);return}if(U&&p!=="\r"&&p!==`
159
+ `&&p!==`\r
160
+ `&&(U=!1),im(U,le,p)){U=!1;return}_.write(p)},Cs=f=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){al(Oa(f));return}let p=Oa(f);p!==0&&Dr(p)};function Dr(f){x+=f,!Ce&&(Ce=setTimeout(()=>{Ce=null;let p=x;x=0,p!==0&&(il(p),y())},16))}function il(f){_.scrollViewport(f),a={mode:"main",shell:dt(a.shell)}}function xs(){Q=!0,T.fullscreen(!0)}function al(f){f!==0&&(Me+=f,!oe&&(oe=setTimeout(()=>{oe=null;let p=Me;if(Me=0,p===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let m=Le(a.shell,p,Ts(a.shell));if(m.changed){if(m.refreshInspection){a={mode:"main",shell:P(m.state)},R(a.shell),y(),ys(a.shell).catch(h=>{let k=K("refresh inspection",h,"Failed to refresh inspection.");a={mode:"main",shell:V(P({...a.shell,actionMessage:k}),k)},y()});return}a={mode:"main",shell:P(m.state)},R(a.shell),y()}},16)))}let vs=()=>{xs(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(_.resize(Mt(je(T.width,T.height))),a={mode:"main",shell:dt(a.shell)}),y()},Es=()=>{xs(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(_.resize(Mt(je(T.width,T.height))),a={mode:"main",shell:dt(a.shell)}),y()};process.stdout.on("resize",vs),process.on("SIGCONT",Es),T.grabInput(!0),vr="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",Ss),T.on("unknown",Is),T.on("mouse",Cs),ze=setInterval(()=>{za()},(n.github?.watchIntervalSeconds??5)*1e3),S.version.checkForUpdate().then(f=>{f.updateAvailable&&f.latest&&(Cr=`Update available: v${f.latest}`,y())});let ll=ws().catch(()=>{});y()})}async function Lt(e,t,r){let n=Pe(e),[s,o,i]=await Promise.all([re.repos.listRegisteredRepos(n).then(u=>u.repos),ie(n),D.listTasks(n)]),l=Fa(i.tasks,t),c=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=l?await ni(l,c):null;return{workspaceRoot:e,workspaces:o.filter(u=>u.status==="active"),repos:s,tasks:i.tasks,inspection:d,...r?{enabledRunnerIds:r}:{}}}function Fa(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function Vf(e,t){return ar(e,t)}function Gf(e,t){let r=new Set(t);return e.filter(n=>{let s=n.path.split("/");for(let o=1;o<s.length;o+=1)if(r.has(s.slice(0,o).join("/")))return!1;return!0})}function Hf(e){let t=[];if(e.workspaces?.length)for(let r of e.workspaces){t.push(`workspace:${r.id}`);for(let n of e.tasks.filter(s=>s.workspaceId===r.id))t.push(`task:${n.id}`);r.kind==="project"&&t.push(`new-task-workspace:${r.id}`),r.kind==="repo"&&t.push(`new-task:${r.primaryRepoId}`)}else for(let r of e.repos){t.push(`repo:${r.id}`);for(let n of e.tasks.filter(s=>s.repoId===r.id))t.push(`task:${n.id}`);t.push(`new-task:${r.id}`)}return t.push("new-workspace"),t}function zf(e,t,r){let n=e.tasks.find(l=>l.ptyTabs.some(c=>c.id===t))??null,s=n?.ptyTabs.find(l=>l.id===t)??null,o=n?.worktreePath??r,i=s?.kind==="agent"?Qf(s):[];return n?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:Yf(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function Yf(e,t){let r=(e??"").split(ct.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(ct.delimiter):[...r,t].join(ct.delimiter)}function Qf(e){return e.command.length>0?e.command:["codex"]}function jt(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function Jf(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Ma(e,t,r,n={}){let s=r??e.runner,o=S.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",l=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,c=new Set(e.ptyTabs.map(R=>R.id)),d=1,u=l;for(;c.has(u);)d+=1,u=`${l}-${d}`;let g=new Date().toISOString(),w=r&&r!==e.runner?r:void 0;return{id:u,kind:t,...w?{runner:w}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?S.runners.buildCommand(s,void 0,n):[],createdAt:g,updatedAt:g}}async function Xf(e,t,r,n,s){let o=await S.load(e);S.runners.assertEnabled(s,o);let i=r?await D.provisionProjectTask(e,r,n,{runner:s,config:o}):await D.provisionTask(e,t??"",n,{runner:s,config:o});try{let c=Ue();await v(qe(S.runners.getConfiguredProfile(s,o).executable,{cwd:i.repoRoot,env:c}),["--help"],{cwd:i.repoRoot,env:c})}catch(c){let d=c instanceof Error?c.message:"Failed to start runner.",u=await D.recordStartupFailure(e,i.task.id,d);throw new Pr(d,u)}let l=await D.markTaskStarted(e,i.task.id);return await Y({uiStateFile:e.uiStateFile},{...await J({uiStateFile:e.uiStateFile})??we(),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 Pr=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}};function Zf(e,t){let r=e.ptyTabs.find(n=>n.kind===t);if(!r)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return r.id}function Mt(e){return{columns:Math.max(20,e.width-ge.leftWidth-ge.rightWidth-ge.dividerWidth-wr*2),rows:Math.max(5,e.height-ge.topRailHeight-5)}}function em(e){return e.split(`
161
+ `).map((t,r)=>`\x1B[${r+1};1H${t}`).join("")}function tm(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function rm(e){return e.length===1||Ie(e)||e==="BACKSPACE"||e==="TAB"}function gs(e){return typeof e=="string"&&new RegExp(`:(?:agent|${N.join("|")})(?:-\\d+)?$`).test(e)}function nm(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 Oa(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function sm(e){let t=new RegExp("\x1B\\[<(\\d+);\\d+;\\d+[mM]").exec(e);if(!t?.[1])return 0;let r=Number.parseInt(t[1],10);return r===64?-3:r===65?3:0}function om(e){return e==="\x1B[13;2u"?"SHIFT_ENTER":null}function im(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
162
+ `||r===`\r
163
+ `)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}async function am(e){let t=await _f(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=ct.join(e,n.name);r.push({name:n.name,path:s,kind:await cm(s)?"repo":"directory"})}return r.sort((n,s)=>n.kind!==s.kind?n.kind==="repo"?-1:1:n.name.localeCompare(s.name)),{cwd:e,entries:r,selectedIndex:0,error:null}}async function lm(e){let{spawn:t}=await import("node:child_process"),r=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((n,s)=>{let o=t(r,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",n)})}async function cm(e){let t=ct.join(e,".git");return await Bf(t).catch(()=>null)!==null}function br(){return process.cwd()}async function dm(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??br(),l=Pe(i);return await ua(l),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??br(),l=Pe(i);return await pa(l),0}let e=Ws(process.argv.slice(2)),t=br(),r=Pe(t),n={paths:r};if(e.mode==="interactive")return await Na({uiStateFile:r.uiStateFile,workspaceRoot:r.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await Qo(e.command,n),o=Jo(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 pm=await fm();process.exit(pm);
165
+ `),1}}var um=await dm();process.exit(um);