craig-cli 0.12.1 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +4 -4
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  var pp=Object.defineProperty;var Ar=(e,t)=>{for(var r in t)pp(e,r,{get:t[r],enumerable:!0})};import H from"node:path";function re(e){let t=H.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:H.join(t,"index.json"),reposDir:H.join(t,"repos"),workspacesDir:H.join(t,"workspaces"),sessionsDir:H.join(t,"sessions"),runtimeDir:H.join(t,"runtime"),uiStateFile:H.join(t,"runtime","ui-state.json"),tasksDir:H.join(t,"tasks"),jobsDir:H.join(t,"jobs"),commandsDir:H.join(t,"commands"),eventsDir:H.join(t,"events"),orchestrationDir:H.join(t,"orchestration"),logsDir:H.join(t,"logs"),errorLogFile:H.join(t,"logs","errors.log"),artifactsDir:H.join(t,"artifacts"),worktreesDir:H.join(t,"worktrees"),configFile:H.join(t,"config.json")}}import{readFile as yp}from"node:fs/promises";import{randomUUID as mp}from"node:crypto";import{open as fp,readFile as gp,rename as hp,rm as wp}from"node:fs/promises";import Hn from"node:path";async function M(e,t){let r=Hn.dirname(e),n=Hn.join(r,`.${Hn.basename(e)}.${process.pid}.${Date.now()}.${mp()}.tmp`),s=await fp(n,"w");try{let o=`${JSON.stringify(t,null,2)}
3
3
  `;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await hp(n,e)}catch(o){throw await s.close().catch(()=>{}),await wp(n,{force:!0}).catch(()=>{}),o}}async function Er(e){try{let t=await gp(e,"utf8");return JSON.parse(t)}catch(t){if(kp(t))return null;throw t}}function kp(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}async function yt(e){try{let t=await yp(e.uiStateFile,"utf8"),r=JSON.parse(t);return Tp(r,e.uiStateFile)}catch(t){if(bp(t))return null;throw t}}async function Me(e,t){await M(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Dr(){return{version:1,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null,selectedPtyTabId:null,inputMode:"control",focusedRegion:"tasks",activeTab:"agent",inspectorSection:"task",inspectionMode:"files",openInspectionKind:null,selectedFileTreePath:null,selectedFilePath:null,selectedDiffPath:null,collapsedFileTreePaths:[],selectedActionId:"commit",updatedAt:new Date().toISOString()}}function Tp(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!kt(e,"inputMode")||!kt(e,"focusedRegion")||!kt(e,"activeTab")||!kt(e,"inspectorSection")||!kt(e,"inspectionMode")||!xr(e,"openInspectionKind")||!xr(e,"selectedFileTreePath")||!xr(e,"selectedFilePath")||!xr(e,"selectedDiffPath")||!Rp(e,"collapsedFileTreePaths")||!kt(e,"selectedActionId")||typeof e.updatedAt!="string")throw new Error(`Craig UI state at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}function kt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function xr(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Rp(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function bp(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var zn={};Ar(zn,{RUNNER_IDS:()=>L,assertEnabled:()=>zi,buildCommand:()=>Xi,getConfiguredProfile:()=>Or,getDefault:()=>Hi,getDisplayName:()=>Ji,getEnabled:()=>$r,getProfile:()=>Tt,isRunnerType:()=>Nr,parse:()=>Yi,setRunnerEnabled:()=>Qi,setRunnerPath:()=>Zi});var L=["codex","cursor","claude"];var Gi={codex:{id:"codex",displayName:"Codex",executable:"codex",defaultAgentTitle:"Codex"},cursor:{id:"cursor",displayName:"Cursor",executable:"cursor-agent",defaultAgentTitle:"Cursor"},claude:{id:"claude",displayName:"Claude",executable:"claude",defaultAgentTitle:"Claude"}};var Tt=e=>Gi[e];var Or=(e,t={})=>{let r=Tt(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var $r=(e={})=>L.filter(t=>e.runners?.[t]?.enabled!==!1);var Hi=(e={})=>{let t=$r(e);if(t.length===0)throw new Error("No runners are enabled. Enable at least one runner in .craig/config.json.");return t.includes("codex")?"codex":t[0]};var zi=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var Nr=e=>L.includes(e);var Yi=e=>{if(!e||e.length===0)return"codex";if(!Nr(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${L.join(", ")}.`);return e};var Ji=e=>Tt(e).displayName;var Xi=(e,t,r={})=>{let n=[Or(e,r).executable];return t&&t.length>0&&n.push(t),n};var Qi=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var Zi=(e,t,r)=>{let n=e.runners?.[t]??{},{path:s,...o}=n;return{...e,runners:{...e.runners??{},[t]:r!=null?{...n,path:r}:o}}};var Yn={};Ar(Yn,{PREVIEW_FEATURE_IDS:()=>ge,isEnabled:()=>ea,setEnabled:()=>ta});var ge=["incrementalCenterPane","agentActivityIndicators","agentOrchestration"];function ea(e,t){return e.previews?.[t]===!0}function ta(e,t,r){return{...e,previews:{...e.previews,[t]:r}}}import{mkdir as Pp,readFile as Sp,writeFile as vp}from"node:fs/promises";import Ip from"node:path";var Cp=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",ra=async e=>{try{return await Sp(e,"utf8")}catch(t){if(Cp(t))return null;throw t}},na=async(e,t)=>{await Pp(Ip.dirname(e),{recursive:!0}),await vp(e,t,"utf8")};var Mr=(e,t)=>{if(typeof e!="object"||e===null)throw new Error(`Craig config at ${t} is invalid. Expected a JSON object.`);let r=e;if(r.runners!==void 0){if(typeof r.runners!="object"||r.runners===null||Array.isArray(r.runners))throw new Error(`Craig config at ${t} is invalid. "runners" must be an object.`);for(let[n,s]of Object.entries(r.runners)){if(!L.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${L.join(", ")}.`);if(typeof s!="object"||s===null||Array.isArray(s))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" must be an object.`);let o=s;if(o.enabled!==void 0&&typeof o.enabled!="boolean")throw new Error(`Craig config at ${t} is invalid. "runners.${n}.enabled" must be a boolean.`);if(o.path!==void 0&&(typeof o.path!="string"||o.path.trim().length===0))throw new Error(`Craig config at ${t} is invalid. "runners.${n}.path" must be a non-empty string.`)}}if(r.checks!==void 0&&(typeof r.checks!="object"||r.checks===null||!Array.isArray(r.checks.commands)||!r.checks.commands.every(n=>typeof n=="string")))throw new Error(`Craig config at ${t} is invalid. "checks.commands" must be an array of strings.`);if(r.open!==void 0&&(typeof r.open!="object"||r.open===null||!Array.isArray(r.open.command)||!r.open.command.every(n=>typeof n=="string")))throw new Error(`Craig config at ${t} is invalid. "open.command" must be an array of strings.`);if(r.github!==void 0){if(typeof r.github!="object"||r.github===null)throw new Error(`Craig config at ${t} is invalid. "github" must be an object.`);if(r.github.mergeMethod!==void 0&&r.github.mergeMethod!=="merge"&&r.github.mergeMethod!=="rebase"&&r.github.mergeMethod!=="squash")throw new Error(`Craig config at ${t} is invalid. "github.mergeMethod" must be "merge", "rebase", or "squash".`);if(r.github.watchIntervalSeconds!==void 0&&(!Number.isInteger(r.github.watchIntervalSeconds)||r.github.watchIntervalSeconds<=0))throw new Error(`Craig config at ${t} is invalid. "github.watchIntervalSeconds" must be a positive integer.`)}if(r.previews!==void 0){if(typeof r.previews!="object"||r.previews===null||Array.isArray(r.previews))throw new Error(`Craig config at ${t} is invalid. "previews" must be an object.`);for(let[n,s]of Object.entries(r.previews)){if(!ge.includes(n))throw new Error(`Craig config at ${t} is invalid. "previews.${n}" is not supported. Expected one of: ${ge.join(", ")}.`);if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${n}" must be a boolean.`)}}return r};var Jn=async(e,t={readConfigFile:ra})=>{let r=await t.readConfigFile(e.configFile);if(!r)return{};if(r.trimStart()[0]!=="{")throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`);let n;try{n=JSON.parse(r)}catch{throw new Error(`Craig config at ${e.configFile} is malformed. Remove or repair the file before rerunning Craig.`)}return Mr(n,e.configFile)};var Xn=async(e,t,r={writeConfigFile:na})=>{Mr(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
4
- `)};var Qn={};Ar(Qn,{checkForUpdate:()=>sa,getCurrent:()=>Lr});var Lr=()=>{try{return"0.12.1"}catch{return"unknown"}};var Ap="https://registry.npmjs.org/craig-cli/latest",Ep=3600*1e3,xp={value:null},Dp=(e,t)=>{let r=c=>c.split(".").map(Number),[n=0,s=0,o=0]=r(e),[i=0,a=0,l=0]=r(t);return n!==i?n>i:s!==a?s>a:o>l},sa=async(e={fetch:globalThis.fetch,getCurrent:Lr,cache:xp})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<Ep)return e.cache.value.result;let n=null;try{let o=await e.fetch(Ap,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&Dp(n,t)};return e.cache.value={result:s,cachedAt:r},s};var h={load:Jn,save:Xn,previews:Yn,runners:zn,version:Qn};var oa={CLI_USAGE:2,INPUT_REQUIRED:2,WORKSPACE_CONTEXT_NOT_FOUND:3,WORKSPACE_CONTEXT_INVALID:4,WORKSPACE_NOT_FOUND:3,WORKSPACE_RECORD_INVALID:2,TASK_CONTEXT_NOT_FOUND:3,TASK_CONTEXT_AMBIGUOUS:4,TASK_CONTEXT_CONFLICT:4,TASK_NOT_FOUND:3,TASK_RECORD_INVALID:2,REPO_NOT_FOUND:3,REPO_RECORD_INVALID:2,PR_REPOSITORY_MISMATCH:4,PR_BRANCH_MISMATCH:4,EXTERNAL_DEPENDENCY_FAILED:5,OPERATION_TIMEOUT:6,OPERATION_CANCELLED:6,EVENT_CURSOR_INVALID:2,EVENT_CURSOR_EXPIRED:4,EVENT_JOURNAL_CORRUPT:2,COMMAND_NOT_FOUND:3,COMMAND_RECORD_INVALID:2,COMMAND_STATE_CONFLICT:4,PARTIAL_RESULT:7,INTERNAL_ERROR:1},f=class extends Error{code;exitCode;retryable;details;constructor(t,r,n){super(r,n.cause===void 0?void 0:{cause:n.cause}),this.name="CraigError",this.code=t,this.exitCode=oa[t],this.retryable=n.retryable??!1,this.details=n.details??{}}};function Zn(e){return e instanceof f?e:new f("INTERNAL_ERROR",e instanceof Error?e.message:"Unknown Craig error",{cause:e})}import{appendFile as Op,mkdir as $p,readFile as Np}from"node:fs/promises";import Mp from"node:path";var ia=80,es=async(e,t)=>{await $p(Mp.dirname(e.errorLogFile),{recursive:!0}),await Op(e.errorLogFile,Lp(t),"utf8")},aa=async(e,t)=>{try{await es(e,t)}catch{}},ts=async(e,t=ia)=>{try{let n=(await Np(e.errorLogFile,"utf8")).trimEnd().split(`
4
+ `)};var Qn={};Ar(Qn,{checkForUpdate:()=>sa,getCurrent:()=>Lr});var Lr=()=>{try{return"0.12.3"}catch{return"unknown"}};var Ap="https://registry.npmjs.org/craig-cli/latest",Ep=3600*1e3,xp={value:null},Dp=(e,t)=>{let r=c=>c.split(".").map(Number),[n=0,s=0,o=0]=r(e),[i=0,a=0,l=0]=r(t);return n!==i?n>i:s!==a?s>a:o>l},sa=async(e={fetch:globalThis.fetch,getCurrent:Lr,cache:xp})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<Ep)return e.cache.value.result;let n=null;try{let o=await e.fetch(Ap,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&Dp(n,t)};return e.cache.value={result:s,cachedAt:r},s};var h={load:Jn,save:Xn,previews:Yn,runners:zn,version:Qn};var oa={CLI_USAGE:2,INPUT_REQUIRED:2,WORKSPACE_CONTEXT_NOT_FOUND:3,WORKSPACE_CONTEXT_INVALID:4,WORKSPACE_NOT_FOUND:3,WORKSPACE_RECORD_INVALID:2,TASK_CONTEXT_NOT_FOUND:3,TASK_CONTEXT_AMBIGUOUS:4,TASK_CONTEXT_CONFLICT:4,TASK_NOT_FOUND:3,TASK_RECORD_INVALID:2,REPO_NOT_FOUND:3,REPO_RECORD_INVALID:2,PR_REPOSITORY_MISMATCH:4,PR_BRANCH_MISMATCH:4,EXTERNAL_DEPENDENCY_FAILED:5,OPERATION_TIMEOUT:6,OPERATION_CANCELLED:6,EVENT_CURSOR_INVALID:2,EVENT_CURSOR_EXPIRED:4,EVENT_JOURNAL_CORRUPT:2,COMMAND_NOT_FOUND:3,COMMAND_RECORD_INVALID:2,COMMAND_STATE_CONFLICT:4,PARTIAL_RESULT:7,INTERNAL_ERROR:1},f=class extends Error{code;exitCode;retryable;details;constructor(t,r,n){super(r,n.cause===void 0?void 0:{cause:n.cause}),this.name="CraigError",this.code=t,this.exitCode=oa[t],this.retryable=n.retryable??!1,this.details=n.details??{}}};function Zn(e){return e instanceof f?e:new f("INTERNAL_ERROR",e instanceof Error?e.message:"Unknown Craig error",{cause:e})}import{appendFile as Op,mkdir as $p,readFile as Np}from"node:fs/promises";import Mp from"node:path";var ia=80,es=async(e,t)=>{await $p(Mp.dirname(e.errorLogFile),{recursive:!0}),await Op(e.errorLogFile,Lp(t),"utf8")},aa=async(e,t)=>{try{await es(e,t)}catch{}},ts=async(e,t=ia)=>{try{let n=(await Np(e.errorLogFile,"utf8")).trimEnd().split(`
5
5
  `).filter(s=>s.length>0);return{path:e.errorLogFile,lines:n.slice(Math.max(0,n.length-t)),empty:n.length===0}}catch(r){if(_p(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},la=async(e,t=ia)=>ts(e,t);function Lp(e){let r=[`[${new Date().toISOString()}] ${e.context}`,`message: ${e.message}`];return e.details&&e.details.trim().length>0&&(r.push("details:"),r.push(...e.details.trimEnd().split(`
6
6
  `).map(n=>` ${n}`))),`${r.join(`
7
7
  `)}
@@ -80,7 +80,7 @@ fragment PrFields on PullRequest {
80
80
  `))l.pop();else{if(!a)throw Ge(o.name,"segment has a truncated tail");l.pop()}for(let c=0;c<l.length;c+=1){let d=l[c];if(d.length===0)throw Ge(o.name,`empty record at line ${c+1}`);let u;try{u=JSON.parse(d)}catch{throw Ge(o.name,`invalid JSON at line ${c+1}`)}let m=sh(u,o.name,c+1);if(c===0&&m.sequence!==o.startSequence)throw Ge(o.name,`first record sequence ${m.sequence} does not match segment name`);if(n.has(m.id))throw Ge(o.name,`duplicate event id ${m.id}`);n.add(m.id);let p=r.at(-1);if(p&&m.sequence!==p.sequence+1)throw Ge(o.name,`non-monotonic sequence ${m.sequence} after ${p.sequence}`);r.push(m)}}return{events:r,earliestSequence:r[0]?.sequence??null}}async function sn(e){return(await Hl(e.eventsDir).catch(r=>{if(Yl(r))return[];throw r})).flatMap(r=>{let n=/^segment-(\d{16})\.jsonl$/.exec(r);return n?[{name:r,path:vo.join(e.eventsDir,r),startSequence:Number(n[1])}]:[]}).sort((r,n)=>r.startSequence-n.startSequence)}async function Jg(e,t,r){let n=await Gg(e).catch(()=>null);return n!==null&&n.size>0&&n.size+Buffer.byteLength(t)>r}async function Xg(e,t){let r=await sn(e),n=Math.max(0,r.length-t),s=await Qg(e);if(s===null)return;for(let i=0;i<n;i+=1)if(await Zg(r[i].path,s)){n=i;break}let o=r.slice(0,n);for(let i of o)await Kg(i.path,{force:!0});o.length>0&&await Jl(e.eventsDir)}async function Qg(e){let t=await Hl(e.commandsDir).catch(n=>{if(Yl(n))return[];throw n}),r=new Set;for(let n of t.filter(s=>s.endsWith(".json")))try{let s=JSON.parse(await nn(vo.join(e.commandsDir,n),"utf8"));typeof s.id=="string"&&(s.state==="queued"||s.state==="delivering")&&r.add(s.id)}catch{return null}return r}async function Zg(e,t){if(t.size===0)return!1;let r=await nn(e,"utf8");for(let n of r.split(`
81
81
  `))if(n)try{let s=JSON.parse(n);if(typeof s.commandId=="string"&&t.has(s.commandId))return!0}catch{return!0}return!1}async function eh(e){let t=(await sn(e)).at(-1);if(!t)return;let r=await nn(t.path);if(r.length===0||r[r.length-1]===10)return;let n=r.lastIndexOf(10),s=await So(t.path,"r+");try{await s.truncate(n+1),await s.sync()}finally{await s.close()}}function th(e,t,r,n){if(t===void 0)return 0;if(/^\d+$/.test(t)){let o=Number(t);if(!Number.isSafeInteger(o)||n===null&&o!==0||n!==null&&o>n)throw bo(t);return Vl(t,o,r),o}let s=e.find(o=>o.id===t);if(!s)throw r!==null&&r>1?new f("EVENT_CURSOR_EXPIRED",`Event cursor ${t} has expired.`,{details:{cursor:t,earliestAvailableSequence:r,resumeAfter:r-1}}):bo(t);return Vl(t,s.sequence,r),s.sequence}function Vl(e,t,r){if(r!==null&&t<r-1)throw new f("EVENT_CURSOR_EXPIRED",`Event cursor ${e} has expired.`,{details:{cursor:e,earliestAvailableSequence:r,resumeAfter:r-1}})}function rh(e){if(e.length===0||e.length>256)throw new f("CLI_USAGE","Event type glob must contain between 1 and 256 characters.",{});let t=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replaceAll("*",".*");return new RegExp(`^${t}$`)}function nh(e){let t=JSON.stringify(e,(r,n)=>/prompt|token|secret|password|authorization|capability/i.test(r)?"[REDACTED]":n);return t===void 0?null:JSON.parse(t)}function sh(e,t,r){if(typeof e!="object"||e===null||Array.isArray(e))throw Ge(t,`record at line ${r} is not an object`);let n=e;if(n.schemaVersion!==1||typeof n.id!="string"||n.id.length===0||n.id.length>256||!Number.isSafeInteger(n.sequence)||(n.sequence??0)<1||typeof n.type!="string"||n.type.length===0||n.type.length>256||typeof n.occurredAt!="string"||!Number.isFinite(Date.parse(n.occurredAt))||!Mt(n.workspaceId)||!Mt(n.taskId)||!Mt(n.agentTabId)||!Mt(n.commandId)||!Mt(n.swarmRunId)||!Mt(n.swarmStepId)||!oh(n.actor)||!("data"in n))throw Ge(t,`record at line ${r} has an invalid schema`);return n}function oh(e){if(typeof e!="object"||e===null||Array.isArray(e)||!("type"in e))return!1;let t=e;return t.type==="human"?(t.source==="cli"||t.source==="tui")&&Number.isInteger(t.processId):t.type==="agent"?typeof t.taskId=="string"&&typeof t.agentTabId=="string"&&typeof t.capabilityId=="string":t.type==="system"&&(t.component==="orchestration-supervisor"||t.component==="heartbeat")}var Mt=e=>e===null||typeof e=="string",Kl=e=>`segment-${String(e).padStart(16,"0")}.jsonl`,Ge=(e,t)=>new f("EVENT_JOURNAL_CORRUPT",`Event journal segment ${e} is corrupt: ${t}.`,{details:{segment:e,reason:t}}),bo=e=>new f("EVENT_CURSOR_INVALID",`Event cursor ${e} was not found.`,{details:{cursor:e}}),Yl=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";function Po(e,t){if(!Number.isSafeInteger(e)||e<1)throw new f("CLI_USAGE",`${t} must be a positive integer.`,{details:{value:e}});return e}async function Jl(e){let t=await So(e,"r");try{await t.sync()}finally{await t.close()}}import{mkdir as Zl,readdir as hh,readFile as ec}from"node:fs/promises";import tc from"node:path";import{mkdir as Xl,readFile as ih,rm as on,stat as ah,writeFile as lh}from"node:fs/promises";import Co from"node:path";var ch=20,dh=3e4,uh=5e3;async function Ao(e,t){let r=Co.join(e.runtimeDir,"command-store.lock");await Xl(e.runtimeDir,{recursive:!0});let n=Date.now();for(;;)try{await Xl(r);try{await lh(Co.join(r,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(s){throw await on(r,{recursive:!0,force:!0}),s}break}catch(s){if(!fh(s))throw s;if(await ph(r))continue;if(Date.now()-n>=dh)throw new f("OPERATION_TIMEOUT","Timed out waiting for the command store lock.",{retryable:!0});await gh(ch)}try{return await t()}finally{await on(r,{recursive:!0,force:!0})}}async function ph(e){let t=await ih(Co.join(e,"owner.json"),"utf8").then(n=>JSON.parse(n)).catch(()=>null);if(t&&typeof t.pid=="number")return mh(t.pid)?!1:(await on(e,{recursive:!0,force:!0}),!0);let r=await ah(e).catch(()=>null);return!r||Date.now()-r.mtimeMs<uh?!1:(await on(e,{recursive:!0,force:!0}),!0)}function mh(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var fh=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST",gh=e=>new Promise(t=>setTimeout(t,e));async function cn(e,t){Eo(t);try{let r=JSON.parse(await ec(mr(e,t),"utf8"));return nc(r,mr(e,t),t)}catch(r){throw Th(r)?new f("COMMAND_NOT_FOUND",`Craig command "${t}" was not found.`,{details:{commandId:t}}):r instanceof SyntaxError?ln(t,mr(e,t),r):r}}async function xe(e){await Zl(e.commandsDir,{recursive:!0});let t=await hh(e.commandsDir),r=[];for(let n of t.filter(s=>s.endsWith(".json")).sort()){let s=tc.join(e.commandsDir,n);try{r.push(nc(JSON.parse(await ec(s,"utf8")),s,n.slice(0,-5)))}catch(o){throw o instanceof f?o:ln(n.slice(0,-5),s,o)}}return r.sort((n,s)=>n.createdAt.localeCompare(s.createdAt)||n.id.localeCompare(s.id))}async function rc(e,t){return Eo(t.id),Ao(e,async()=>{await Zl(e.commandsDir,{recursive:!0});let r=await xe(e);if(t.idempotencyKey){let n=r.find(s=>s.idempotencyKey===t.idempotencyKey);if(n){if(!wh(n,t))throw new f("COMMAND_STATE_CONFLICT",`Idempotency key "${t.idempotencyKey}" is already used by command ${n.id}.`,{details:{commandId:n.id,idempotencyKey:t.idempotencyKey}});return{command:n,created:!1}}}return await M(mr(e,t.id),t),{command:t,created:!0}})}async function fr(e,t,r){return Eo(t),Ao(e,async()=>{let n=await cn(e,t),s=r(n);if(s.id!==n.id)throw new f("INTERNAL_ERROR","Command mutation cannot change its id.",{});return await M(mr(e,t),s),s})}function wh(e,t){return e.taskId===t.taskId&&e.agentTabId===t.agentTabId&&e.prompt.source===t.prompt.source&&e.prompt.text===t.prompt.text&&e.delivery===t.delivery&&e.timeoutMs===t.timeoutMs}function nc(e,t,r){if(!an(e)||e.schemaVersion!==1||typeof e.id!="string"||e.id.length===0)throw ln("unknown",t);let n=e.id,s=["queued","delivering","delivered","failed","cancelled"];if(n!==r||e.idempotencyKey!==null&&(typeof e.idempotencyKey!="string"||e.idempotencyKey.length>256)||typeof e.taskId!="string"||e.taskId.length===0||typeof e.agentTabId!="string"||e.agentTabId.length===0||!an(e.prompt)||!["inline","file","stdin"].includes(String(e.prompt.source))||typeof e.prompt.text!="string"||!yh(e.prompt.text)||!["when-ready","immediate"].includes(String(e.delivery))||!s.includes(e.state)||!Number.isInteger(e.attempts)||Number(e.attempts)<0||!Number.isInteger(e.timeoutMs)||Number(e.timeoutMs)<=0||Number(e.timeoutMs)>864e5||!_t(e.expiresAt)||!_t(e.createdAt)||!_t(e.updatedAt)||e.deliveryStartedAt!==null&&!_t(e.deliveryStartedAt)||e.deliveredAt!==null&&!_t(e.deliveredAt)||e.cancelledAt!==null&&!_t(e.cancelledAt)||e.cancelledBy!==null&&!Ql(e.cancelledBy)||!Ql(e.actor)||!kh(e.lastError)||e.state==="delivered"!=(e.deliveredAt!==null)||e.state==="failed"!=(e.lastError!==null)||Number(e.attempts)>0!=(e.deliveryStartedAt!==null)||e.state==="cancelled"!=(e.cancelledAt!==null&&e.cancelledBy!==null))throw ln(n,t);return e}function Ql(e){return!an(e)||typeof e.type!="string"?!1:e.type==="human"?["cli","tui"].includes(String(e.source))&&Number.isInteger(e.processId):e.type==="agent"?typeof e.taskId=="string"&&typeof e.agentTabId=="string"&&typeof e.capabilityId=="string":e.type==="system"&&["orchestration-supervisor","heartbeat"].includes(String(e.component))}function kh(e){return e===null||an(e)&&typeof e.code=="string"&&typeof e.message=="string"&&typeof e.retryable=="boolean"&&typeof e.deliveryUncertain=="boolean"}var mr=(e,t)=>tc.join(e.commandsDir,`${t}.json`),Eo=e=>{if(!/^command_[A-Za-z0-9_-]+$/.test(e))throw new f("CLI_USAGE",`Invalid command id "${e}".`,{details:{commandId:e}})},_t=e=>typeof e=="string"&&e.length>0&&Number.isFinite(Date.parse(e)),yh=e=>e.trim().length>0&&Buffer.byteLength(e)<=32*1024&&![...e].some(t=>{let r=t.charCodeAt(0);return r<=8||r>=11&&r<=31||r>=127&&r<=159}),an=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Th=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT",ln=(e,t,r)=>new f("COMMAND_RECORD_INVALID",`Craig command record at ${t} is invalid.`,{details:{commandId:e,filePath:t},...r?{cause:r}:{}});function sc(e,t=new Date){return dn(e,["queued"],"begin delivery"),{...e,state:"delivering",attempts:e.attempts+1,lastError:null,deliveryStartedAt:t.toISOString(),updatedAt:t.toISOString()}}function oc(e,t=new Date){return e.state==="delivered"?e:(dn(e,["delivering"],"complete delivery"),{...e,state:"delivered",deliveredAt:t.toISOString(),lastError:null,updatedAt:t.toISOString()})}function ic(e,t,r=new Date){return e.state==="failed"?e:(dn(e,["queued","delivering"],"fail"),{...e,state:"failed",lastError:t,updatedAt:r.toISOString()})}function ac(e,t,r=new Date){return e.state==="cancelled"?e:(dn(e,["queued"],"cancel"),{...e,state:"cancelled",cancelledAt:r.toISOString(),cancelledBy:t,updatedAt:r.toISOString()})}function dn(e,t,r){if(!t.includes(e.state))throw new f("COMMAND_STATE_CONFLICT",`Cannot ${r} command ${e.id} while it is ${e.state}.`,{details:{commandId:e.id,state:e.state,allowedStates:t}})}import{randomUUID as Rh}from"node:crypto";var xo=32*1024,lc=1440*60*1e3,Do=256,bh=["delivered","failed","cancelled"],Oo={type:"system",component:"orchestration-supervisor"};async function Ph(e,t){if(Dh(t.prompt.text),!Number.isSafeInteger(t.timeoutMs)||t.timeoutMs<=0||t.timeoutMs>lc)throw new f("CLI_USAGE","Prompt command timeout must be between 1ms and 24h.",{details:{maxTimeoutMs:lc}});if(t.idempotencyKey!==void 0&&t.idempotencyKey!==null&&t.idempotencyKey.trim().length===0)throw new f("CLI_USAGE","Idempotency key cannot be empty.",{});if((t.idempotencyKey?.length??0)>Do)throw new f("CLI_USAGE",`Idempotency key exceeds ${Do} characters.`,{details:{maxIdempotencyKeyLength:Do}});let r=t.now??new Date,n={schemaVersion:1,id:t.id??`command_${Rh()}`,idempotencyKey:t.idempotencyKey?.trim()||null,taskId:t.taskId,agentTabId:t.agentTabId,prompt:t.prompt,delivery:t.delivery,state:"queued",attempts:0,timeoutMs:t.timeoutMs,expiresAt:new Date(r.getTime()+t.timeoutMs).toISOString(),lastError:null,actor:t.actor,createdAt:r.toISOString(),updatedAt:r.toISOString(),deliveryStartedAt:null,deliveredAt:null,cancelledAt:null,cancelledBy:null},s=await rc(e,n);if(s.created)try{await dt(e,s.command,"command.queued")}catch(o){throw cc(s.command,o)}return{kind:"sendAgentPrompt",...s}}async function Sh(e,t){return{kind:"showPromptCommand",command:await cn(e,t)}}async function vh(e,t){let r=await xe(e);return{kind:"listPromptCommands",commands:t?r.filter(n=>n.taskId===t):r}}async function Ih(e,t,r){let n=!1,s=await fr(e,t,o=>{if(o.state==="cancelled")return o;let i=ac(o,r??o.actor);return n=!0,i});if(n)try{await dt(e,s,"command.cancelled",s.cancelledBy??s.actor)}catch(o){throw cc(s,o)}return{kind:"cancelPromptCommand",command:s,changed:n}}async function Ch(e,t){let r=await fr(e,t,n=>sc(n));return await dt(e,r,"command.delivering",Oo),r}async function Ah(e,t){let r=await fr(e,t,n=>oc(n));return await dt(e,r,"command.delivered",Oo),r}async function Eh(e,t,r){let n=await fr(e,t,s=>ic(s,r));return await dt(e,n,"command.failed",Oo),n}async function xh(e,t,r){let n=[...r.states??bh],s=Date.now()+r.timeoutMs;for(;;){let o=await cn(e,t);if(n.includes(o.state))return{kind:"waitPromptCommand",command:o,matchedStates:n};if(r.signal?.aborted)throw new f("OPERATION_CANCELLED",`Cancelled while waiting for command ${t}.`,{retryable:!0,details:{commandId:t,cancelled:!0}});let i=s-Date.now();if(i<=0)throw new f("OPERATION_TIMEOUT",`Timed out after ${r.timeoutMs}ms waiting for command ${t}.`,{retryable:!0,details:{commandId:t,states:n,timeoutMs:r.timeoutMs}});await Oh(Math.min(r.pollIntervalMs??100,i),r.signal)}}function Dh(e){if(e.trim().length===0)throw new f("CLI_USAGE","Prompt cannot be empty.",{});let t=Buffer.byteLength(e);if(t>xo)throw new f("CLI_USAGE",`Prompt exceeds the ${xo}-byte limit.`,{details:{maxPromptBytes:xo,promptBytes:t}});if([...e].some(r=>{let n=r.charCodeAt(0);return n<=8||n>=11&&n<=31||n>=127&&n<=159}))throw new f("CLI_USAGE","Prompt contains unsupported control characters.",{})}async function dt(e,t,r,n=t.actor){await Lt(e,{id:`${t.id}:${r}`,taskId:t.taskId,agentTabId:t.agentTabId,commandId:t.id,type:r,occurredAt:r==="command.queued"?t.createdAt:r==="command.delivering"?t.deliveryStartedAt??t.updatedAt:r==="command.delivered"?t.deliveredAt??t.updatedAt:r==="command.cancelled"?t.cancelledAt??t.updatedAt:t.updatedAt,actor:n,data:{state:t.state,delivery:t.delivery,attempts:t.attempts,errorCode:t.lastError?.code??null,deliveryUncertain:t.lastError?.deliveryUncertain??!1}})}function Oh(e,t){return t?.aborted?Promise.resolve():new Promise(r=>{let n=()=>{clearTimeout(s),t?.removeEventListener("abort",n),r()},s=setTimeout(n,e);t?.addEventListener("abort",n,{once:!0})})}var cc=(e,t)=>new f("PARTIAL_RESULT",`Command ${e.id} was persisted as ${e.state}, but its event could not be appended.`,{retryable:!0,details:{commandId:e.id,durableState:e.state},cause:t}),se={create:Ph,show:Sh,list:vh,cancel:Ih,wait:xh,beginDelivery:Ch,completeDelivery:Ah,fail:Eh};import{createHash as dc}from"node:crypto";import $h from"node:path";import{mkdir as Nh}from"node:fs/promises";var $o={type:"system",component:"heartbeat"};async function jt(e,t={}){await Nh(e.orchestrationDir,{recursive:!0});let[r,n,s,o]=await Promise.all([S.listTasks(e,{includeClosed:!0}),t.agentObserver?Promise.resolve(null):Ee.listAgents(e),zl(e),Fh(e)]),i=n??Re(r.tasks.filter(p=>p.status!=="closed"),t.agentObserver?.getSnapshots()??[],Date.now()),a=jh(o),l=[],c=No(s.filter(_h),p=>p.taskId),d=No(s.filter(p=>p.type.startsWith("task.pr.")),p=>p.taskId),u=No(s.filter(p=>p.type==="agent.state.changed"),p=>p.agentTabId);for(let p of r.tasks){let k=Mh(p),w=c.get(p.id),b=Lo(w?.data)??a.tasks[p.id]??null,N=w?.id??a.tasks[p.id]?.eventId??null;if(b?.signature!==k.signature){let me=b?p.status==="closed"&&b?.status!=="closed"?"task.closed":"task.updated":"task.created",de=await Lt(e,{id:Mo(me,p.id,k.signature),type:me,taskId:p.id,workspaceId:p.workspaceId||null,occurredAt:p.updatedAt,actor:$o,data:k});l.push(de),N=de.id}a.tasks[p.id]={...k,eventId:N};let _=Lh(p.prs),Y=d.get(p.id),I=Lo(Y?.data)??a.pullRequests[p.id]??null,ce=Y?.id??a.pullRequests[p.id]?.eventId??null;if((I||_.associations.length>0)&&I?.signature!==_.signature){let me=Array.isArray(I?.associations)?I.associations.length:0,de=_.associations.length>me?"task.pr.linked":_.associations.length<me?"task.pr.unlinked":"task.pr.refreshed",wt=await Lt(e,{id:Mo(de,p.id,_.signature),type:de,taskId:p.id,workspaceId:p.workspaceId||null,occurredAt:p.updatedAt,actor:$o,data:_});l.push(wt),ce=wt.id}a.pullRequests[p.id]={..._,eventId:ce}}let m=new Map(i.tasks.map(p=>[p.taskId,p.state]));for(let p of i.agents){let k=u.get(p.tabId),w=Lo(k?.data)??a.agents[p.tabId]??null;if(w?.state===p.state){a.agents[p.tabId]={state:p.state,eventId:k?.id??a.agents[p.tabId]?.eventId??null};continue}let b=[k?.id??a.agents[p.tabId]?.eventId??"initial",p.state,p.sessionState??"none",p.lastActivityAt??"none",p.exitCode??"none",p.error??"none"].join(":"),N=await Lt(e,{id:Mo("agent.state.changed",p.tabId,b),type:"agent.state.changed",taskId:p.taskId,agentTabId:p.tabId,actor:$o,data:{previousState:typeof w?.state=="string"?w.state:null,state:p.state,taskState:m.get(p.taskId)??"idle",sessionState:p.sessionState,lastActivityAt:p.lastActivityAt,exitCode:p.exitCode,error:p.error}});l.push(N),a.agents[p.tabId]={state:p.state,eventId:N.id}}return await M(pc(e),a),l}function Mh(e){let t={status:e.status,title:e.title,runner:e.runner,branch:e.branch,sourceUpdatedAt:e.updatedAt,agentTabIds:e.ptyTabs.filter(r=>r.kind==="agent").map(r=>r.id)};return{...t,signature:uc(t)}}function Lh(e){let t=e.map(r=>({provider:r.provider,owner:r.owner,repo:r.repo,number:r.number,url:r.url,status:r.status,draft:r.draft,headBranch:r.headBranch,lastSyncedAt:r.lastSyncedAt,lastSyncedHeadSha:r.lastSyncedHeadSha}));return{associations:t,signature:uc(t)}}function No(e,t){let r=new Map;for(let n of e){let s=t(n);s&&r.set(s,n)}return r}var _h=e=>e.type==="task.created"||e.type==="task.updated"||e.type==="task.closed",uc=e=>dc("sha256").update(JSON.stringify(e)).digest("hex"),Mo=(...e)=>dc("sha256").update(e.join("\0")).digest("hex"),Lo=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:null,pc=e=>$h.join(e.orchestrationDir,"event-reconciliation.json");function jh(e){return e?.schemaVersion===1&&typeof e.tasks=="object"&&e.tasks!==null&&typeof e.pullRequests=="object"&&e.pullRequests!==null&&typeof e.agents=="object"&&e.agents!==null?e:{schemaVersion:1,tasks:{},pullRequests:{},agents:{}}}async function Fh(e){try{return await Er(pc(e))}catch(t){if(t instanceof SyntaxError)return null;throw t}}async function Wh(e,t){return await _o(e),await jt(e),pr(e,t)}async function qh(e,t,r){await _o(e);let n=await Ee.openObserver(e);try{let s=t.after,o=0,i=0;for(;!r.signal?.aborted;){await jt(e,{agentObserver:n});let a=await pr(e,{...t,...s?{after:s}:{}});for(let l of a.events)r.onEvent(l),o+=1;if(s=a.cursor.after??s,i=a.cursor.sequence,r.signal?.aborted)break;await mc(r.pollIntervalMs??250,r.signal)}return{kind:"watchEvents",eventCount:o,lastSequence:i,cancelled:r.signal?.aborted??!1}}finally{n.close()}}async function Uh(e,t,r){await _o(e);let n=await S.getTask(e,t);if(r.tabId&&!n.ptyTabs.some(o=>o.kind==="agent"&&o.id===r.tabId))throw new f("TASK_CONTEXT_CONFLICT",`Agent tab ${r.tabId} does not belong to task ${t}.`,{details:{taskId:t,tabId:r.tabId}});let s=await Ee.openObserver(e);try{await jt(e,{agentObserver:s});let i=(await pr(e,{taskId:t,typeGlob:"agent.state.changed"})).cursor.after??void 0,a=Date.now()+r.timeoutMs;for(;;){let l=Date.now(),c=Re([n],s.getSnapshots(),l),d=r.tabId?c.agents.find(p=>p.tabId===r.tabId)?.state??"idle":c.tasks[0]?.state??"idle";if(r.states.includes(d))return{kind:"waitTask",taskId:t,tabId:r.tabId??null,state:d,matchedStates:[...r.states],observedAt:new Date(l).toISOString()};if(r.signal?.aborted)throw Vh(t);let u=a-Date.now();if(u<=0)throw Bh(t,r.states,r.timeoutMs);await jt(e,{agentObserver:s}),i=(await pr(e,{taskId:t,typeGlob:"agent.state.changed",...i?{after:i}:{}})).cursor.after??i,await mc(Math.min(250,u),r.signal)}}finally{s.close()}}async function _o(e){let t=await h.load(e);if(!h.previews.isEnabled(t,"agentOrchestration"))throw new f("CLI_USAGE","Event orchestration is a feature preview. Enable agentOrchestration before using events commands.",{details:{preview:"agentOrchestration"}})}function mc(e,t){return t?.aborted?Promise.resolve():new Promise(r=>{let n=()=>{clearTimeout(s),t?.removeEventListener("abort",n),r()},s=setTimeout(n,e);t?.addEventListener("abort",n,{once:!0})})}var Bh=(e,t,r)=>new f("OPERATION_TIMEOUT",`Timed out after ${r}ms waiting for task ${e} agent state ${t.join(",")}.`,{retryable:!0,details:{taskId:e,states:t,timeoutMs:r}}),Vh=e=>new f("OPERATION_CANCELLED",`Cancelled while waiting for task ${e} agent state.`,{retryable:!0,details:{taskId:e,cancelled:!0}}),un={list:Wh,watch:qh,waitForTaskState:Uh,reconcile:jt};import{readFile as zh}from"node:fs/promises";import{createConnection as Kh}from"node:net";async function gr(e){let t=await Hh(Ke(e).socketPath).catch(()=>null);if(!t)return!1;try{return(await fc(t,{type:"ping"})).protocolVersion!==Nt?!1:(await fc(t,{type:"wakeOrchestration"}),!0)}catch{return!1}finally{t.end()}}var Gh=1;function fc(e,t){let r=Gh++;return new Promise((n,s)=>{let o="",i=setTimeout(()=>s(new Error("Craig PTY daemon request timed out.")),1e3),a=c=>{o+=String(c);let d=o.indexOf(`
82
82
  `);if(d===-1)return;l();let u=JSON.parse(o.slice(0,d));u.ok?n(u):s(new Error(u.error??"Craig PTY daemon request failed."))},l=()=>{clearTimeout(i),e.off("data",a)};e.on("data",a),e.write(`${JSON.stringify({...t,id:r})}
83
- `)})}function Hh(e){return new Promise((t,r)=>{let n=Kh(e);n.once("connect",()=>t(n)),n.once("error",r)})}async function Yh(e,t){await tw(e);let r=await S.getTask(e,t.taskId);if(r.status==="closed"||r.status==="merged")throw new f("COMMAND_STATE_CONFLICT",`Task ${r.id} is ${r.status} and cannot receive prompts.`,{details:{taskId:r.id,taskStatus:r.status}});let n=r.ptyTabs.filter(a=>a.kind==="agent"),s=t.tabId?n.find(a=>a.id===t.tabId):n[0];if(!s)throw new f("TASK_CONTEXT_CONFLICT",t.tabId?`Agent tab ${t.tabId} does not belong to task ${r.id}.`:`Task ${r.id} has no agent tab.`,{details:{taskId:r.id,tabId:t.tabId??null}});let o=await ew(t.prompt,t.readStdin),i;try{i=await se.create(e,{taskId:r.id,agentTabId:s.id,prompt:o,delivery:t.delivery,timeoutMs:t.timeoutMs,idempotencyKey:t.idempotencyKey??null,actor:{type:"human",source:"cli",processId:process.pid}})}catch(a){throw await gr(e),a}return await gr(e),i}async function Jh(e,t){return se.show(e,t)}async function Xh(e,t){return se.list(e,t)}async function Qh(e,t){let r;try{r=await se.cancel(e,t,{type:"human",source:"cli",processId:process.pid})}catch(n){throw await gr(e),n}return await gr(e),r}async function Zh(e,t,r){return se.wait(e,t,r)}async function ew(e,t){if(e.source==="inline")return e;if(e.source==="file")try{return{source:"file",text:await zh(e.path,"utf8")}}catch(r){throw new f("CLI_USAGE",`Unable to read prompt file ${e.path}.`,{details:{promptFile:e.path},cause:r})}if(!t)throw new f("INPUT_REQUIRED","Prompt input from stdin is unavailable.",{});return{source:"stdin",text:await t()}}async function tw(e){let t=await h.load(e);if(!h.previews.isEnabled(t,"agentOrchestration"))throw new f("CLI_USAGE","Prompt dispatch is a feature preview. Enable agentOrchestration before sending prompts.",{details:{preview:"agentOrchestration"}})}var Ft={send:Yh,show:Jh,list:Xh,cancel:Qh,wait:Zh};async function gc(e,t){switch(e.kind){case"addWorkspace":{let r=await J.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await jo(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await J.repos.addRepo(t.paths,e.path);return await jo(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return J.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await yt({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await ie(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await J.repos.removeRepo(t.paths,e.repoId,{listTasks:S.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await Me({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await Me({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return J.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await J.archiveWorkspace(t.paths,e.workspaceId);return await rw(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await J.restoreWorkspace(t.paths,e.workspaceId);return await jo(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return J.removeWorkspace(t.paths,e.workspaceId,{listTasks:S.listTasks});case"createTask":return S.createTask(t.paths,e.repoId??e.workspaceId??"",e.prompt,{...e.runner?{runner:e.runner}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}});case"listTasks":return e.repoId||e.workspaceId?S.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):S.listTasks(t.paths);case"currentTask":{let r=Fo(t);return{kind:"currentTask",task:r.task,context:{source:r.source,agentTabId:r.agentTabId}}}case"attachTask":return S.attachTask(t.paths,e.taskId);case"addTaskLink":return S.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return S.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return S.showTask(t.paths,e.taskId);case"showCurrentTask":return S.showTask(t.paths,Fo(t).task.id);case"showTaskPr":return S.prs.show(t.paths,pt(e.taskId,t),e.repoId);case"discoverTaskPr":return S.prs.discover(t.paths,pt(e.taskId,t),e.repoId);case"linkTaskPr":return S.prs.link(t.paths,pt(e.taskId,t),e.pullRequest,e.repoId);case"refreshTaskPr":return S.prs.refreshAssociation(t.paths,pt(e.taskId,t),e.repoId);case"unlinkTaskPr":return S.prs.unlink(t.paths,pt(e.taskId,t),e.pullRequest,e.repoId);case"listAgents":return Ee.listAgents(t.paths,e.taskId);case"showAgentStatus":return Ee.showAgentStatus(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.tabId?{tabId:e.tabId}:{}});case"waitTask":{let r={states:e.states,timeoutMs:e.timeoutMs,...e.tabId?{tabId:e.tabId}:{},...t.signal?{signal:t.signal}:{}},n=pt(e.taskId,t),s=await h.load(t.paths);return h.previews.isEnabled(s,"agentOrchestration")?un.waitForTaskState(t.paths,n,r):Ee.waitForTask(t.paths,n,r)}case"listEvents":return un.list(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}});case"watchEvents":return un.watch(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}},{onEvent:t.emitEvent??(()=>{}),...t.signal?{signal:t.signal}:{}});case"sendAgentPrompt":return Ft.send(t.paths,{taskId:pt(e.taskId,t),...e.tabId?{tabId:e.tabId}:t.taskContext?.agentTabId?{tabId:t.taskContext.agentTabId}:{},prompt:e.prompt,delivery:e.delivery,timeoutMs:e.timeoutMs,...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{},...t.readStdin?{readStdin:t.readStdin}:{}});case"showPromptCommand":return Ft.show(t.paths,e.commandId);case"listPromptCommands":return Ft.list(t.paths,e.taskId);case"cancelPromptCommand":return Ft.cancel(t.paths,e.commandId);case"waitPromptCommand":return Ft.wait(t.paths,e.commandId,{...e.states?{states:e.states}:{},timeoutMs:e.timeoutMs,...t.signal?{signal:t.signal}:{}});case"showSelectedTask":return S.showTask(t.paths,ut(t,"show"));case"streamTaskLogs":return S.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return S.prepareTaskLogs(t.paths,ut(t,"logs"));case"showTaskDiff":return S.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return S.showTaskDiff(t.paths,ut(t,"diff"));case"focusTask":return S.focusTask(t.paths,e.taskId);case"focusSelectedTask":return S.focusTask(t.paths,ut(t,"focus"));case"openTask":return S.openTask(t.paths,e.taskId);case"openSelectedTask":return S.openTask(t.paths,ut(t,"open"));case"runChecks":return S.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return S.runChecks(t.paths,ut(t,"check"));case"commitTask":return S.commitTask(t.paths,e.taskId);case"commitSelectedTask":return S.commitTask(t.paths,ut(t,"commit"));case"showContext":{let r=sw(t);return{kind:"showContext",workspace:{root:r.workspaceRoot,source:r.source,initialized:r.initialized},task:t.taskContext?{id:t.taskContext.task.id,source:t.taskContext.source,agentTabId:t.taskContext.agentTabId}:null}}case"help":return{kind:"help",text:rs()};case"exit":return{kind:"exit"};default:return nw(e)}}async function jo(e,t,r){let n=await yt({uiStateFile:e.uiStateFile})??Dr();await Me({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function rw(e,t){let r=await yt({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Me({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function nw(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function ut(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function Fo(e){if(e.taskContext)return e.taskContext;throw new Error("Command requires resolved task context.")}function pt(e,t){return e??Fo(t).task.id}function sw(e){if(e.workspaceContext)return e.workspaceContext;throw new Error("Command requires resolved workspace context.")}function hc(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
83
+ `)})}function Hh(e){return new Promise((t,r)=>{let n=Kh(e);n.once("connect",()=>t(n)),n.once("error",r)})}async function Yh(e,t){await tw(e);let r=await S.getTask(e,t.taskId);if(r.status==="closed")throw new f("COMMAND_STATE_CONFLICT",`Task ${r.id} is ${r.status} and cannot receive prompts.`,{details:{taskId:r.id,taskStatus:r.status}});let n=r.ptyTabs.filter(a=>a.kind==="agent"),s=t.tabId?n.find(a=>a.id===t.tabId):n[0];if(!s)throw new f("TASK_CONTEXT_CONFLICT",t.tabId?`Agent tab ${t.tabId} does not belong to task ${r.id}.`:`Task ${r.id} has no agent tab.`,{details:{taskId:r.id,tabId:t.tabId??null}});let o=await ew(t.prompt,t.readStdin),i;try{i=await se.create(e,{taskId:r.id,agentTabId:s.id,prompt:o,delivery:t.delivery,timeoutMs:t.timeoutMs,idempotencyKey:t.idempotencyKey??null,actor:{type:"human",source:"cli",processId:process.pid}})}catch(a){throw await gr(e),a}return await gr(e),i}async function Jh(e,t){return se.show(e,t)}async function Xh(e,t){return se.list(e,t)}async function Qh(e,t){let r;try{r=await se.cancel(e,t,{type:"human",source:"cli",processId:process.pid})}catch(n){throw await gr(e),n}return await gr(e),r}async function Zh(e,t,r){return se.wait(e,t,r)}async function ew(e,t){if(e.source==="inline")return e;if(e.source==="file")try{return{source:"file",text:await zh(e.path,"utf8")}}catch(r){throw new f("CLI_USAGE",`Unable to read prompt file ${e.path}.`,{details:{promptFile:e.path},cause:r})}if(!t)throw new f("INPUT_REQUIRED","Prompt input from stdin is unavailable.",{});return{source:"stdin",text:await t()}}async function tw(e){let t=await h.load(e);if(!h.previews.isEnabled(t,"agentOrchestration"))throw new f("CLI_USAGE","Prompt dispatch is a feature preview. Enable agentOrchestration before sending prompts.",{details:{preview:"agentOrchestration"}})}var Ft={send:Yh,show:Jh,list:Xh,cancel:Qh,wait:Zh};async function gc(e,t){switch(e.kind){case"addWorkspace":{let r=await J.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await jo(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await J.repos.addRepo(t.paths,e.path);return await jo(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return J.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await yt({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await ie(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await J.repos.removeRepo(t.paths,e.repoId,{listTasks:S.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await Me({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await Me({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return J.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await J.archiveWorkspace(t.paths,e.workspaceId);return await rw(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await J.restoreWorkspace(t.paths,e.workspaceId);return await jo(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return J.removeWorkspace(t.paths,e.workspaceId,{listTasks:S.listTasks});case"createTask":return S.createTask(t.paths,e.repoId??e.workspaceId??"",e.prompt,{...e.runner?{runner:e.runner}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}});case"listTasks":return e.repoId||e.workspaceId?S.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):S.listTasks(t.paths);case"currentTask":{let r=Fo(t);return{kind:"currentTask",task:r.task,context:{source:r.source,agentTabId:r.agentTabId}}}case"attachTask":return S.attachTask(t.paths,e.taskId);case"addTaskLink":return S.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return S.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return S.showTask(t.paths,e.taskId);case"showCurrentTask":return S.showTask(t.paths,Fo(t).task.id);case"showTaskPr":return S.prs.show(t.paths,pt(e.taskId,t),e.repoId);case"discoverTaskPr":return S.prs.discover(t.paths,pt(e.taskId,t),e.repoId);case"linkTaskPr":return S.prs.link(t.paths,pt(e.taskId,t),e.pullRequest,e.repoId);case"refreshTaskPr":return S.prs.refreshAssociation(t.paths,pt(e.taskId,t),e.repoId);case"unlinkTaskPr":return S.prs.unlink(t.paths,pt(e.taskId,t),e.pullRequest,e.repoId);case"listAgents":return Ee.listAgents(t.paths,e.taskId);case"showAgentStatus":return Ee.showAgentStatus(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.tabId?{tabId:e.tabId}:{}});case"waitTask":{let r={states:e.states,timeoutMs:e.timeoutMs,...e.tabId?{tabId:e.tabId}:{},...t.signal?{signal:t.signal}:{}},n=pt(e.taskId,t),s=await h.load(t.paths);return h.previews.isEnabled(s,"agentOrchestration")?un.waitForTaskState(t.paths,n,r):Ee.waitForTask(t.paths,n,r)}case"listEvents":return un.list(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}});case"watchEvents":return un.watch(t.paths,{...e.taskId?{taskId:e.taskId}:{},...e.typeGlob?{typeGlob:e.typeGlob}:{},...e.after?{after:e.after}:{}},{onEvent:t.emitEvent??(()=>{}),...t.signal?{signal:t.signal}:{}});case"sendAgentPrompt":return Ft.send(t.paths,{taskId:pt(e.taskId,t),...e.tabId?{tabId:e.tabId}:t.taskContext?.agentTabId?{tabId:t.taskContext.agentTabId}:{},prompt:e.prompt,delivery:e.delivery,timeoutMs:e.timeoutMs,...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{},...t.readStdin?{readStdin:t.readStdin}:{}});case"showPromptCommand":return Ft.show(t.paths,e.commandId);case"listPromptCommands":return Ft.list(t.paths,e.taskId);case"cancelPromptCommand":return Ft.cancel(t.paths,e.commandId);case"waitPromptCommand":return Ft.wait(t.paths,e.commandId,{...e.states?{states:e.states}:{},timeoutMs:e.timeoutMs,...t.signal?{signal:t.signal}:{}});case"showSelectedTask":return S.showTask(t.paths,ut(t,"show"));case"streamTaskLogs":return S.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return S.prepareTaskLogs(t.paths,ut(t,"logs"));case"showTaskDiff":return S.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return S.showTaskDiff(t.paths,ut(t,"diff"));case"focusTask":return S.focusTask(t.paths,e.taskId);case"focusSelectedTask":return S.focusTask(t.paths,ut(t,"focus"));case"openTask":return S.openTask(t.paths,e.taskId);case"openSelectedTask":return S.openTask(t.paths,ut(t,"open"));case"runChecks":return S.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return S.runChecks(t.paths,ut(t,"check"));case"commitTask":return S.commitTask(t.paths,e.taskId);case"commitSelectedTask":return S.commitTask(t.paths,ut(t,"commit"));case"showContext":{let r=sw(t);return{kind:"showContext",workspace:{root:r.workspaceRoot,source:r.source,initialized:r.initialized},task:t.taskContext?{id:t.taskContext.task.id,source:t.taskContext.source,agentTabId:t.taskContext.agentTabId}:null}}case"help":return{kind:"help",text:rs()};case"exit":return{kind:"exit"};default:return nw(e)}}async function jo(e,t,r){let n=await yt({uiStateFile:e.uiStateFile})??Dr();await Me({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function rw(e,t){let r=await yt({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Me({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function nw(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function ut(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function Fo(e){if(e.taskContext)return e.taskContext;throw new Error("Command requires resolved task context.")}function pt(e,t){return e??Fo(t).task.id}function sw(e){if(e.workspaceContext)return e.workspaceContext;throw new Error("Command requires resolved workspace context.")}function hc(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
84
84
  `);case"createRepo":return[`${e.created?"Registered":"Already registered"} repo ${e.repo.id}`,`Path: ${e.repo.rootPath}`,`Branch: ${e.repo.defaultBranch}`,`Workspace: ${e.workspaceId}`].join(`
85
85
  `);case"listRepos":return e.repos.length===0?"No repos registered yet. Use 'craig repo add <path>'.":["ID NAME BRANCH PATH",...e.repos.map(t=>`${t.id} ${t.name} ${t.defaultBranch} ${t.rootPath}`)].join(`
86
86
  `);case"removeRepo":return`Removed repo ${e.repoId} (${e.rootPath})`;case"listWorkspaces":return e.workspaces.length===0?e.archivedOnly?"No archived workspaces.":"No active workspaces yet. Register one with 'craig workspace add <path>'.":["ID KIND STATUS REPOS PATH",...e.workspaces.map(t=>`${t.id} ${t.kind??"repo"} ${t.status} ${(t.discoveredRepoIds??[t.primaryRepoId]).join(",")} ${t.rootPath??""}`)].join(`
@@ -119,7 +119,7 @@ ${a.stdout.trimEnd()}`)}let i=s.join(`
119
119
  `||r===`\r
120
120
  `)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function hd(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function wd(e,t=null){let r=t?.split(`
121
121
  `)??[];return e.split(`
122
- `).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function An(e,t,r,n){return e.map((s,o)=>t?.[o]===s?"":`\x1B[${r+o};${n}H${s}`).join("")}import{spawn as iy}from"node:child_process";import{createServer as ay,createConnection as Ed}from"node:net";import{openSync as ly}from"node:fs";import{mkdir as cy,readFile as yi,rm as gt,writeFile as dy}from"node:fs/promises";import On from"node:path";var Bt=class{jobs=new Map;resolutionMs;now;onError;timer=null;abortController=null;constructor(t){this.resolutionMs=ci(t.resolutionMs??1e3,"Heartbeat resolution"),this.now=t.now??Date.now,this.onError=t.onError}register(t){if(this.jobs.has(t.id))throw new Error(`Heartbeat job "${t.id}" is already registered.`);let r={...t,intervalMs:ci(t.intervalMs,`Heartbeat job "${t.id}" interval`),inFlight:!1,nextRunAt:this.timer?this.now()+t.intervalMs:null};this.jobs.set(t.id,r)}start(){if(this.timer)return;let t=this.now();for(let r of this.jobs.values())r.nextRunAt=t+r.intervalMs;this.abortController=new AbortController,this.timer=setInterval(()=>this.tick(),this.resolutionMs)}stop(){this.abortController?.abort(),this.abortController=null,this.timer&&clearInterval(this.timer),this.timer=null;for(let t of this.jobs.values())t.nextRunAt=null}setResolutionMs(t){let r=ci(t,"Heartbeat resolution");r!==this.resolutionMs&&(this.resolutionMs=r,this.timer&&(clearInterval(this.timer),this.timer=setInterval(()=>this.tick(),this.resolutionMs)))}tick(){let t=this.abortController?.signal;if(!t)return;let r=this.now();for(let n of this.jobs.values())n.inFlight||n.nextRunAt===null||r<n.nextRunAt||(n.inFlight=!0,n.nextRunAt=r+n.intervalMs,Promise.resolve().then(()=>n.run(t)).catch(s=>{if(!t.aborted)return Promise.resolve(this.onError(n.id,s)).catch(()=>{})}).finally(()=>{n.inFlight=!1}))}};function ci(e,t){if(!Number.isFinite(e)||e<=0)throw new Error(`${t} must be a positive number.`);return e}import{mkdir as kd,readFile as Ak,rm as di,stat as Ek,writeFile as xk}from"node:fs/promises";import ui from"node:path";async function pi(e){let t=ui.join(e.runtimeDir,"orchestration-supervisor.lock");await kd(e.runtimeDir,{recursive:!0});try{await kd(t)}catch(n){if(!Ok(n))throw n;let s=await Ak(ui.join(t,"owner.json"),"utf8").then(i=>JSON.parse(i)).catch(()=>null),o=await Ek(t).catch(()=>null);if(typeof s?.pid=="number"&&!Dk(s.pid)||!s&&o&&Date.now()-o.mtimeMs>=5e3)return await di(t,{recursive:!0,force:!0}),pi(e);throw new f("COMMAND_STATE_CONFLICT","Another orchestration supervisor already leads this workspace.",{details:{ownerPid:s?.pid??null}})}try{await xk(ui.join(t,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(n){throw await di(t,{recursive:!0,force:!0}),n}let r=!1;return{async release(){r||(r=!0,await di(t,{recursive:!0,force:!0}))}}}function Dk(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var Ok=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST";function yd(e,t){switch(e){case"codex":case"cursor":case"claude":return`\x1B[200~${t}\x1B[201~\r`;default:return $k(e)}}function $k(e){throw new Error(`Unsupported prompt-delivery runner: ${String(e)}`)}import Nk from"node:path";var Mk={type:"system",component:"orchestration-supervisor"};async function Td(e){let t=Nk.join(e.orchestrationDir,"command-event-reconciliation.json"),r=await Er(t)??{version:1,commands:{}},n=await xe(e),s=!1;for(let o of n){let i=new Set(r.commands[o.id]??[]);for(let a of Lk(o))i.has(a)||(await dt(e,o,a,a==="command.queued"?o.actor:a==="command.cancelled"?o.cancelledBy??o.actor:Mk),i.add(a),s=!0);r.commands[o.id]=[...i]}s&&await M(t,r)}function Lk(e){let t=["command.queued"];return e.attempts>0&&t.push("command.delivering"),e.state==="delivered"?t.push("command.delivered"):e.state==="failed"?t.push("command.failed"):e.state==="cancelled"&&t.push("command.cancelled"),t}var En=class{constructor(t,r,n={}){this.paths=t;this.runtime=r;let s=n.intervalMs??250;this.heartbeat=new Bt({resolutionMs:s,onError:(o,i)=>n.onError?.(i)}),this.heartbeat.register({id:"orchestration.commands",intervalMs:s,run:()=>this.reconcile()})}paths;runtime;heartbeat;lease=null;reconciliation=null;async start(){if(!this.lease){this.lease=await pi(this.paths);try{await this.reconcile(),this.heartbeat.start()}catch(t){throw await this.lease.release(),this.lease=null,t}}}async wake(){await this.reconcile()}async stop(){this.heartbeat.stop(),await this.reconciliation?.catch(()=>{}),await this.lease?.release(),this.lease=null}reconcile(){return this.reconciliation?this.reconciliation:(this.reconciliation=this.reconcileCommands().finally(()=>{this.reconciliation=null}),this.reconciliation)}async reconcileCommands(){await Td(this.paths);let t=await xe(this.paths);for(let r of t){if(r.state==="delivering"){await se.fail(this.paths,r.id,Pr("PROMPT_DELIVERY_UNCERTAIN","Craig resumed after prompt delivery began; the prompt was not replayed.",!1,!0));continue}r.state==="queued"&&await this.reconcileCommand(r)}}async reconcileCommand(t){if(Date.now()>=Date.parse(t.expiresAt)){await se.fail(this.paths,t.id,Pr("PROMPT_DELIVERY_TIMEOUT",`Prompt delivery timed out after ${t.timeoutMs}ms.`,!1,!1));return}let r=await S.getTask(this.paths,t.taskId).catch(o=>{if(o instanceof f&&o.code==="TASK_NOT_FOUND")return null;throw o}),n=r?.ptyTabs.find(o=>o.id===t.agentTabId);if(!r||!n||n.kind!=="agent"||r.status==="closed"||r.status==="merged"){await se.fail(this.paths,t.id,Pr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer available in task ${t.taskId}.`,!1,!1));return}let s=this.runtime.getActivitySnapshots().find(o=>o.tabId===t.agentTabId);if(s&&s.sessionState!=="running"){await se.fail(this.paths,t.id,Pr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer running.`,!1,!1));return}if(this.runtime.hasRunningSession(t.agentTabId)&&!(t.delivery==="when-ready"&&Ve(r,t.agentTabId,this.runtime.getActivitySnapshots(),Date.now())!=="ready")){await se.beginDelivery(this.paths,t.id);try{this.runtime.writeToSession(t.agentTabId,yd(n.runner??r.runner,t.prompt.text))}catch(o){await se.fail(this.paths,t.id,Pr("PROMPT_DELIVERY_UNCERTAIN",o instanceof Error?o.message:"Prompt delivery failed after it began.",!1,!0));return}await se.completeDelivery(this.paths,t.id)}}},Pr=(e,t,r,n)=>({code:e,message:t,retryable:r,deliveryUncertain:n});import{createRequire as Gk}from"node:module";import _k from"@xterm/headless";var jk=1e3,Fk=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function bd(e){return new _k.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:jk,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function Pd(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function fi(e,t){return new Promise(r=>{e.write(t,r)})}function Sd(e,t=0){let r=e.buffer.active,n=[],s=r.getNullCell(),o=r.baseY+r.cursorY,i=Math.max(0,r.baseY-t);for(let a=0;a<e.rows;a+=1){let l=r.getLine(i+a);if(!l){n.push({segments:[]});continue}let c=[];for(let d=0;d<e.cols;d+=1){let u=l.getCell(d,s);!u||u.getWidth()===0||c.push({text:u.getChars()||" ",style:Uk(u,i+a===o&&d===r.cursorX)})}n.push({segments:Wk(qk(c))})}return n}function Wk(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&Kk(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};vd(r.style)||(s.style=r.style),t.push(s)}return t}function qk(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!vd(r.style))break;t-=1}return e.slice(0,t)}function Uk(e,t){let r={},n=Rd(e,"fg"),s=Rd(e,"bg");return n&&(r.fg=n),s&&(r.bg=s),e.isBold()&&(r.bold=!0),e.isDim()&&(r.dim=!0),e.isItalic()&&(r.italic=!0),e.isUnderline()&&(r.underline=!0),(e.isInverse()||t)&&(r.inverse=!0),r}function Rd(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let n=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return n?s.toString(16).padStart(6,"0"):Fk[s]??Bk(s)}function Bk(e){if(e>=16&&e<=231){let t=e-16,r=Math.floor(t/36),n=Math.floor(t%36/6),s=t%6;return[r,n,s].map(Vk).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(r=>r.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function Vk(e){return e===0?0:55+e*40}function Kk(e,t){return mi(e)===mi(t)}function mi(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function vd(e){return mi(e)===""}var Hk=Gk(import.meta.url),zk=/^CTRL_([A-Z])$/,Yk="\x1B[6n",Jk="\x1B[c",Xk="\x1B[?u",Qk={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
122
+ `).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function An(e,t,r,n){return e.map((s,o)=>t?.[o]===s?"":`\x1B[${r+o};${n}H${s}`).join("")}import{spawn as iy}from"node:child_process";import{createServer as ay,createConnection as Ed}from"node:net";import{openSync as ly}from"node:fs";import{mkdir as cy,readFile as yi,rm as gt,writeFile as dy}from"node:fs/promises";import On from"node:path";var Bt=class{jobs=new Map;resolutionMs;now;onError;timer=null;abortController=null;constructor(t){this.resolutionMs=ci(t.resolutionMs??1e3,"Heartbeat resolution"),this.now=t.now??Date.now,this.onError=t.onError}register(t){if(this.jobs.has(t.id))throw new Error(`Heartbeat job "${t.id}" is already registered.`);let r={...t,intervalMs:ci(t.intervalMs,`Heartbeat job "${t.id}" interval`),inFlight:!1,nextRunAt:this.timer?this.now()+t.intervalMs:null};this.jobs.set(t.id,r)}start(){if(this.timer)return;let t=this.now();for(let r of this.jobs.values())r.nextRunAt=t+r.intervalMs;this.abortController=new AbortController,this.timer=setInterval(()=>this.tick(),this.resolutionMs)}stop(){this.abortController?.abort(),this.abortController=null,this.timer&&clearInterval(this.timer),this.timer=null;for(let t of this.jobs.values())t.nextRunAt=null}setResolutionMs(t){let r=ci(t,"Heartbeat resolution");r!==this.resolutionMs&&(this.resolutionMs=r,this.timer&&(clearInterval(this.timer),this.timer=setInterval(()=>this.tick(),this.resolutionMs)))}tick(){let t=this.abortController?.signal;if(!t)return;let r=this.now();for(let n of this.jobs.values())n.inFlight||n.nextRunAt===null||r<n.nextRunAt||(n.inFlight=!0,n.nextRunAt=r+n.intervalMs,Promise.resolve().then(()=>n.run(t)).catch(s=>{if(!t.aborted)return Promise.resolve(this.onError(n.id,s)).catch(()=>{})}).finally(()=>{n.inFlight=!1}))}};function ci(e,t){if(!Number.isFinite(e)||e<=0)throw new Error(`${t} must be a positive number.`);return e}import{mkdir as kd,readFile as Ak,rm as di,stat as Ek,writeFile as xk}from"node:fs/promises";import ui from"node:path";async function pi(e){let t=ui.join(e.runtimeDir,"orchestration-supervisor.lock");await kd(e.runtimeDir,{recursive:!0});try{await kd(t)}catch(n){if(!Ok(n))throw n;let s=await Ak(ui.join(t,"owner.json"),"utf8").then(i=>JSON.parse(i)).catch(()=>null),o=await Ek(t).catch(()=>null);if(typeof s?.pid=="number"&&!Dk(s.pid)||!s&&o&&Date.now()-o.mtimeMs>=5e3)return await di(t,{recursive:!0,force:!0}),pi(e);throw new f("COMMAND_STATE_CONFLICT","Another orchestration supervisor already leads this workspace.",{details:{ownerPid:s?.pid??null}})}try{await xk(ui.join(t,"owner.json"),JSON.stringify({pid:process.pid,acquiredAt:new Date().toISOString()}),"utf8")}catch(n){throw await di(t,{recursive:!0,force:!0}),n}let r=!1;return{async release(){r||(r=!0,await di(t,{recursive:!0,force:!0}))}}}function Dk(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="EPERM"}}var Ok=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="EEXIST";function yd(e,t){switch(e){case"codex":case"cursor":case"claude":return`\x1B[200~${t}\x1B[201~\r`;default:return $k(e)}}function $k(e){throw new Error(`Unsupported prompt-delivery runner: ${String(e)}`)}import Nk from"node:path";var Mk={type:"system",component:"orchestration-supervisor"};async function Td(e){let t=Nk.join(e.orchestrationDir,"command-event-reconciliation.json"),r=await Er(t)??{version:1,commands:{}},n=await xe(e),s=!1;for(let o of n){let i=new Set(r.commands[o.id]??[]);for(let a of Lk(o))i.has(a)||(await dt(e,o,a,a==="command.queued"?o.actor:a==="command.cancelled"?o.cancelledBy??o.actor:Mk),i.add(a),s=!0);r.commands[o.id]=[...i]}s&&await M(t,r)}function Lk(e){let t=["command.queued"];return e.attempts>0&&t.push("command.delivering"),e.state==="delivered"?t.push("command.delivered"):e.state==="failed"?t.push("command.failed"):e.state==="cancelled"&&t.push("command.cancelled"),t}var En=class{constructor(t,r,n={}){this.paths=t;this.runtime=r;let s=n.intervalMs??250;this.heartbeat=new Bt({resolutionMs:s,onError:(o,i)=>n.onError?.(i)}),this.heartbeat.register({id:"orchestration.commands",intervalMs:s,run:()=>this.reconcile()})}paths;runtime;heartbeat;lease=null;reconciliation=null;async start(){if(!this.lease){this.lease=await pi(this.paths);try{await this.reconcile(),this.heartbeat.start()}catch(t){throw await this.lease.release(),this.lease=null,t}}}async wake(){await this.reconcile()}async stop(){this.heartbeat.stop(),await this.reconciliation?.catch(()=>{}),await this.lease?.release(),this.lease=null}reconcile(){return this.reconciliation?this.reconciliation:(this.reconciliation=this.reconcileCommands().finally(()=>{this.reconciliation=null}),this.reconciliation)}async reconcileCommands(){await Td(this.paths);let t=await xe(this.paths);for(let r of t){if(r.state==="delivering"){await se.fail(this.paths,r.id,Pr("PROMPT_DELIVERY_UNCERTAIN","Craig resumed after prompt delivery began; the prompt was not replayed.",!1,!0));continue}r.state==="queued"&&await this.reconcileCommand(r)}}async reconcileCommand(t){if(Date.now()>=Date.parse(t.expiresAt)){await se.fail(this.paths,t.id,Pr("PROMPT_DELIVERY_TIMEOUT",`Prompt delivery timed out after ${t.timeoutMs}ms.`,!1,!1));return}let r=await S.getTask(this.paths,t.taskId).catch(o=>{if(o instanceof f&&o.code==="TASK_NOT_FOUND")return null;throw o}),n=r?.ptyTabs.find(o=>o.id===t.agentTabId);if(!r||!n||n.kind!=="agent"||r.status==="closed"){await se.fail(this.paths,t.id,Pr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer available in task ${t.taskId}.`,!1,!1));return}let s=this.runtime.getActivitySnapshots().find(o=>o.tabId===t.agentTabId);if(s&&s.sessionState!=="running"){await se.fail(this.paths,t.id,Pr("PROMPT_TARGET_UNAVAILABLE",`Agent tab ${t.agentTabId} is no longer running.`,!1,!1));return}if(this.runtime.hasRunningSession(t.agentTabId)&&!(t.delivery==="when-ready"&&Ve(r,t.agentTabId,this.runtime.getActivitySnapshots(),Date.now())!=="ready")){await se.beginDelivery(this.paths,t.id);try{this.runtime.writeToSession(t.agentTabId,yd(n.runner??r.runner,t.prompt.text))}catch(o){await se.fail(this.paths,t.id,Pr("PROMPT_DELIVERY_UNCERTAIN",o instanceof Error?o.message:"Prompt delivery failed after it began.",!1,!0));return}await se.completeDelivery(this.paths,t.id)}}},Pr=(e,t,r,n)=>({code:e,message:t,retryable:r,deliveryUncertain:n});import{createRequire as Gk}from"node:module";import _k from"@xterm/headless";var jk=1e3,Fk=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function bd(e){return new _k.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:jk,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function Pd(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function fi(e,t){return new Promise(r=>{e.write(t,r)})}function Sd(e,t=0){let r=e.buffer.active,n=[],s=r.getNullCell(),o=r.baseY+r.cursorY,i=Math.max(0,r.baseY-t);for(let a=0;a<e.rows;a+=1){let l=r.getLine(i+a);if(!l){n.push({segments:[]});continue}let c=[];for(let d=0;d<e.cols;d+=1){let u=l.getCell(d,s);!u||u.getWidth()===0||c.push({text:u.getChars()||" ",style:Uk(u,i+a===o&&d===r.cursorX)})}n.push({segments:Wk(qk(c))})}return n}function Wk(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&Kk(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};vd(r.style)||(s.style=r.style),t.push(s)}return t}function qk(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!vd(r.style))break;t-=1}return e.slice(0,t)}function Uk(e,t){let r={},n=Rd(e,"fg"),s=Rd(e,"bg");return n&&(r.fg=n),s&&(r.bg=s),e.isBold()&&(r.bold=!0),e.isDim()&&(r.dim=!0),e.isItalic()&&(r.italic=!0),e.isUnderline()&&(r.underline=!0),(e.isInverse()||t)&&(r.inverse=!0),r}function Rd(e,t){if(t==="fg"?e.isFgDefault():e.isBgDefault())return;let n=t==="fg"?e.isFgRGB():e.isBgRGB(),s=t==="fg"?e.getFgColor():e.getBgColor();return n?s.toString(16).padStart(6,"0"):Fk[s]??Bk(s)}function Bk(e){if(e>=16&&e<=231){let t=e-16,r=Math.floor(t/36),n=Math.floor(t%36/6),s=t%6;return[r,n,s].map(Vk).map(o=>o.toString(16).padStart(2,"0")).join("")}if(e>=232&&e<=255){let t=8+(e-232)*10;return[t,t,t].map(r=>r.toString(16).padStart(2,"0")).join("")}return"e6e6e6"}function Vk(e){return e===0?0:55+e*40}function Kk(e,t){return mi(e)===mi(t)}function mi(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function vd(e){return mi(e)===""}var Hk=Gk(import.meta.url),zk=/^CTRL_([A-Z])$/,Yk="\x1B[6n",Jk="\x1B[c",Xk="\x1B[?u",Qk={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
123
123
  `,TAB:" ",SHIFT_TAB:"\x1B[Z",BACK_TAB:"\x1B[Z",BACKSPACE:"\x7F",DELETE:"\x1B[3~",ESCAPE:"\x1B",UP:"\x1B[A",DOWN:"\x1B[B",RIGHT:"\x1B[C",LEFT:"\x1B[D",HOME:"\x1B[H",END:"\x1B[F",PAGE_UP:"\x1B[5~",PAGE_DOWN:"\x1B[6~",CTRL_C:"",CTRL_D:""},xn=class{sessions=new Map;activitySnapshots=new Map;shell;env;spawn;onUpdate;onActivity;onActivityRemoved;activityEnabled;resolveSessionSpec;attachedTabId=null;constructor(t){this.shell=t.shell??process.env.SHELL??"/bin/zsh",this.env=t.env??process.env,this.spawn=t.spawn,this.onUpdate=t.onUpdate,this.onActivity=t.onActivity,this.onActivityRemoved=t.onActivityRemoved,this.activityEnabled=t.activityEnabled??!0,this.resolveSessionSpec=t.resolveSessionSpec??(()=>({cwd:t.workspaceRoot,command:[]}))}ensureSession(t,r,n,s){let o=this.sessions.get(r);if(o)if(o.status!=="running")gi(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,Id(o,n),this.getViewState(r);let i;try{i=this.createSession(t,r,n,s)}catch(a){throw this.recordActivity({taskId:t,tabId:r,sessionState:"failed",lastActivityAt:Date.now(),exitCode:null,error:a instanceof Error?a.message:String(a)}),a}return this.sessions.set(r,i),this.notifyActivity(i),this.attachedTabId=r,this.getViewState(r)}write(t){let r=this.getAttachedSession();!r||r.status!=="running"||(r.pty.write(t),(t.includes("\r")||t.includes(`
124
124
  `))&&this.touchActivity(r))}writeKey(t){let r=Zk(t);r!==null&&this.write(r)}hasRunningSession(t){return this.sessions.get(t)?.status==="running"}writeToSession(t,r){let n=this.sessions.get(t);if(!n||n.status!=="running")throw new Error(`Agent tab ${t} is not running.`);n.pty.write(r),this.touchActivity(n)}scrollViewport(t){let r=this.getAttachedSession();if(!r||t===0)return;let n=r.terminal.buffer.active.baseY;r.scrollbackLines=Math.max(0,Math.min(n,r.scrollbackLines-t))}resize(t){let r=this.getAttachedSession();r&&Id(r,t)}detach(){this.attachedTabId=null}sessionTabIds(){return[...this.sessions.keys()]}getActivitySnapshots(){return[...this.activitySnapshots.values()]}setActivityEnabled(t){if(this.activityEnabled!==t&&(this.activityEnabled=t,!!t))for(let r of this.sessions.values())this.notifyActivity(r)}disposeSession(t){let r=this.sessions.get(t);r&&(gi(r),this.sessions.delete(t)),this.removeActivity(t),this.attachedTabId===t&&(this.attachedTabId=null)}disposeAll(){for(let t of this.sessions.values())gi(t);this.sessions.clear();for(let t of this.activitySnapshots.keys())this.onActivityRemoved?.(t);this.activitySnapshots.clear(),this.attachedTabId=null}getViewState(t){if(!t)return{status:"idle",rows:[],error:null,scrolledBack:!1};let r=this.sessions.get(t);return r?{status:r.status,rows:ey(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??ry().spawn,i=bd(n),a=s??this.resolveSessionSpec(t,r),l=it({...this.env,...a.env??{}}),{executable:c,args:d}=ny(this.shell,a.command,{cwd:a.cwd,env:l}),u=o(c,d,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:a.cwd,env:sy(l)}),m={taskId:t,tabId:r,pty:u,terminal:i,status:"running",error:null,disposables:[],scrollbackLines:0,rows:[],renderedScrollbackLines:null,screenDirty:!0,lastActivityAt:Date.now(),exitCode:null};return m.disposables.push(u.onData(p=>{this.touchActivity(m),oy(u,p),fi(m.terminal,p).then(()=>{m.screenDirty=!0,this.onUpdate?.({tabId:m.tabId,kind:"full"})})})),m.disposables.push(u.onExit(p=>{m.status="exited",m.exitCode=p.exitCode,m.lastActivityAt=Date.now(),this.notifyActivity(m),fi(m.terminal,`\r
125
125
  [process exited ${p.exitCode}]`).then(()=>{m.screenDirty=!0,this.onUpdate?.({tabId:m.tabId,kind:"full"})})})),m}getAttachedSession(){return this.attachedTabId?this.sessions.get(this.attachedTabId)??null:null}touchActivity(t){t.lastActivityAt=Date.now(),this.activityEnabled&&this.notifyActivity(t)}notifyActivity(t){this.activityEnabled&&this.recordActivity(this.buildActivitySnapshot(t))}recordActivity(t){this.activityEnabled&&(this.activitySnapshots.set(t.tabId,t),this.onActivity?.(t))}removeActivity(t){this.activitySnapshots.delete(t)&&this.onActivityRemoved?.(t)}buildActivitySnapshot(t){return{taskId:t.taskId,tabId:t.tabId,sessionState:t.status==="failed"?"failed":t.status==="exited"?"exited":"running",lastActivityAt:t.lastActivityAt,exitCode:t.exitCode,error:t.error}}};function Zk(e){if(e.length===1)return e;let t=Qk[e];if(t!==void 0)return t;let r=zk.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function Id(e,t){ty(e.pty,t),Pd(e.terminal,t),e.screenDirty=!0}function ey(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=Sd(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function gi(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function ty(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function ry(){return Hk("node-pty")}function ny(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[at(t[0],r),...t.slice(1)].map(Cd).join(" ")}; exec ${Cd(e)} -l`;return{executable:e,args:["-lc",s]}}function Cd(e){return`'${e.replaceAll("'","'\\''")}'`}function sy(e){let t={};for(let[r,n]of Object.entries(e))typeof n=="string"&&(t[r]=n);return t.TERM=t.TERM??"xterm-256color",t}function oy(e,t){for(let r=0;r<hi(t,Yk);r+=1)e.write("\x1B[1;1R");for(let r=0;r<hi(t,Jk);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<hi(t,Xk);r+=1)e.write("\x1B[?0u")}function hi(e,t){if(t.length===0)return 0;let r=0,n=e.indexOf(t);for(;n!==-1;)r+=1,n=e.indexOf(t,n+t.length);return r}var xd=Nt,uy=new Set([xd]),py=16,my=250;async function Dd(e){let t=Ke(e.paths);await wy(t,e.paths,e.spawnDaemon);let r=await jd(t.socketPath),n=new wi(r,e);return await n.ready(),n}async function Od(e,t={}){let r=Ke(e);await cy(e.runtimeDir,{recursive:!0}),await gt(r.socketPath,{force:!0});let n=new ki(e,t),s=ay(o=>n.handleConnection(o));try{await n.start(),await Py(s,r.socketPath),await dy(r.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,n.closeClients(),s.close(()=>{process.removeListener("SIGTERM",a),process.removeListener("SIGINT",a),o()}))};n.onShutdown=a,process.once("SIGTERM",a),process.once("SIGINT",a)})}finally{n.onShutdown=null,await gt(r.socketPath,{force:!0}),await gt(r.pidPath,{force:!0}),await n.stop(),n.disposeAll()}}async function $d(e){let t=Ke(e);return await $n(t.socketPath)?(await Ld(t.socketPath),!0):!1}var wi=class{constructor(t,r){this.socket=t;this.options=r,this.viewUpdateMode=r.viewUpdateMode??"snapshot",this.activityEnabled=r.activityEnabled??!1,t.setEncoding("utf8"),t.on("data",n=>this.handleData(String(n))),t.on("error",n=>this.rejectAll(n instanceof Error?n:new Error(String(n)))),t.on("close",()=>{this.closed||(this.closed=!0,this.rejectAll(new Error("Craig PTY daemon connection closed.")),this.failRunningActivities("Craig PTY daemon connection closed."))})}socket;nextRequestId=1;pending=new Map;viewCache=new Map;activityCache=new Map;activityRevisionByTabId=new Map;activityRevision=0;attachedTabId=null;viewedTabId=null;subscribedTabId=null;viewUpdateMode;activityEnabled;buffer="";closed=!1;options;async ready(){let t=await this.send({type:"ping"});if(!Md(t.protocolVersion))throw new Error("Craig PTY daemon protocol mismatch.");await this.send({type:"setViewUpdateMode",mode:this.viewUpdateMode}),await this.send({type:"setActivityEnabled",enabled:this.activityEnabled}),this.activityEnabled&&await this.refreshActivitySnapshots()}async ensureSession(t,r,n){let s=await this.send({type:"ensureSession",taskId:t,tabId:r,size:n,spec:this.options.resolveSessionSpec?.(t,r)??{cwd:this.options.workspaceRoot,command:[]}});this.attachedTabId=r,this.viewedTabId=r;let o=s.view??{status:"idle",rows:[],error:null};return this.viewCache.set(r,o),o}async hydrateSessions(t){for(let r of t)try{let n=await this.send({type:"hydrateSession",tabId:r});n.view&&this.viewCache.set(r,n.view)}catch(n){let s=n instanceof Error?n.message:String(n);this.viewCache.set(r,{status:"failed",rows:[],error:s})}this.activityEnabled&&await this.refreshActivitySnapshots()}async pruneStale(t){await this.send({type:"pruneStale",keepTabIds:t})}write(t){this.send({type:"write",input:t}).catch(()=>{})}writeKey(t){this.send({type:"writeKey",key:t}).catch(()=>{})}scrollViewport(t){let r=this.attachedTabId;this.send({type:"scrollViewport",lines:t}).then(n=>{r&&n.view&&(this.viewCache.set(r,n.view),this.notifyFullUpdate(r))}).catch(()=>{})}resize(t){let r=this.attachedTabId;this.send({type:"resize",size:t}).then(n=>{r&&n.view&&(this.viewCache.set(r,n.view),this.notifyFullUpdate(r))}).catch(()=>{})}detach(){this.attachedTabId=null,this.send({type:"detach"}).catch(()=>{})}setViewedTab(t){this.closed||(this.viewedTabId=t,this.viewUpdateMode==="incremental"&&this.subscribeToView(t))}setViewUpdateMode(t){if(this.closed||this.viewUpdateMode===t)return;this.viewUpdateMode=t,this.subscribedTabId=null;let r=this.viewedTabId;this.send({type:"setViewUpdateMode",mode:t}).then(n=>{r&&n.view&&this.viewCache.set(r,n.view),this.viewUpdateMode===t&&this.viewedTabId===r&&this.notifyFullUpdate(r),t==="incremental"&&this.viewUpdateMode===t&&(this.viewedTabId===r&&this.subscribedTabId===null?this.subscribedTabId=r:this.viewedTabId!==r&&this.subscribeToView(this.viewedTabId))}).catch(()=>{this.viewUpdateMode===t&&(this.subscribedTabId=null)})}setActivityEnabled(t){if(!(this.closed||this.activityEnabled===t)){if(this.activityEnabled=t,!t){for(let r of[...this.activityCache.keys()])this.removeCachedActivity(r);this.send({type:"setActivityEnabled",enabled:t}).catch(()=>{});return}this.send({type:"setActivityEnabled",enabled:t}).then(()=>this.refreshActivitySnapshots(!0)).catch(()=>{})}}disposeSession(t){this.viewCache.delete(t),this.removeCachedActivity(t),this.attachedTabId===t&&(this.attachedTabId=null),this.send({type:"disposeSession",tabId:t}).catch(()=>{})}disposeAll(){this.attachedTabId=null,!this.closed&&(this.socket.end(),this.closed=!0)}getViewState(t){return t?this.viewCache.get(t)??{status:"idle",rows:[],error:null,scrolledBack:!1}:{status:"idle",rows:[],error:null,scrolledBack:!1}}getActivitySnapshots(){return[...this.activityCache.values()]}async requestShutdown(){await this.send({type:"shutdown"})}async send(t){if(this.closed)throw new Error("Craig PTY daemon connection is closed.");let r=this.nextRequestId;this.nextRequestId+=1;let n={...t,id:r},s=new Promise((i,a)=>{this.pending.set(r,{resolve:i,reject:a})});if(this.socket.destroyed)throw this.pending.delete(r),new Error("Craig PTY daemon connection is closed.");this.socket.write(`${JSON.stringify(n)}
@@ -132,7 +132,7 @@ ${o.slice(-2e3)}`:""}`)}async function Nd(e){let t=await by(e).catch(()=>null);r
132
132
  `)),s.once("error",l=>{a(),n(l)}),s.on("data",l=>{o+=String(l);let c=o.indexOf(`
133
133
  `);if(c===-1)return;let d=o.slice(0,c);a(),s.end();try{r(JSON.parse(d))}catch(u){n(u instanceof Error?u:new Error(String(u)))}}),s.once("close",()=>a())})}async function Ad(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await $n(e))return;await Ti(50)}}function jd(e){return new Promise((t,r)=>{let n=Ed(e);n.once("connect",()=>t(n)),n.once("error",r)})}function Py(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function ft(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
134
134
  `)}catch{}}function Fd(e){try{return process.kill(e,0),!0}catch{return!1}}function Ti(e){return new Promise(t=>setTimeout(t,e))}function Sy(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var Ri=["Runners","Feature Previews","Error Log","Help"],qd={incrementalCenterPane:"Incremental center pane",agentActivityIndicators:"Agent activity indicators",agentOrchestration:"Agent orchestration"};function bi(e,t){return L.map(r=>{let n=h.runners.getProfile(r),s=e.runners?.[r]?.enabled!==!1,o=e.runners?.[r]?.path?.trim(),i=t.pathEdit?.runner===r?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${n.executable})`;return`${n.displayName} ${s?"enabled":"disabled"} ${i}`})}function Ud(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function Bd(e){return ge.map(t=>`${h.previews.isEnabled(e,t)?"[x]":"[ ]"} ${qd[t]}`)}function Vd(e){return e.message??"Experimental features may change or be removed. Enter toggles."}function Kd(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Ri.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Nn(t)?e===0?{kind:"runners"}:e===1?{kind:"previews"}:e===2?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Gd(e,t,r){if(r==="UP"||r==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(r==="DOWN"||r==="j")return{kind:"render",state:{...e,menuIndex:Math.min(ge.length-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(!Nn(r))return{kind:"noop",state:e};let n=ge[e.menuIndex]??ge[0],s=!h.previews.isEnabled(t,n);return{kind:"save-enabled",feature:n,enabled:s,state:{...e,message:`${qd[n]} ${s?"enabled":"disabled"}.`}}}function Hd(e,t,r,n){if(e.pathEdit)return vy({...e,pathEdit:e.pathEdit},t,r);let s=bi(t,e).length;if(r==="UP"||r==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(r==="DOWN"||r==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(r==="e"){let a=L[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:a,value:t.runners?.[a]?.path??""}}}}if(!Nn(r))return{kind:"noop",state:e};let o=L[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&n.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save-enabled",runner:o,enabled:!i,state:{...e,message:`${h.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function vy(e,t,r){if(r==="ESCAPE")return{kind:"render",state:Wd({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Nn(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:Wd({...e,message:s.length>0?`${h.runners.getProfile(n).displayName} executable saved.`:`${h.runners.getProfile(n).displayName} executable reset to default.`})}}return Iy(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function Wd(e){let t={...e};return delete t.pathEdit,t}function Nn(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
135
- `}function Iy(e){return e.length===1&&e>=" "&&e!==""}import Sr from"node:path";function zd(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"\u{F06E6} ";case"js":case"jsx":case"mjs":case"cjs":return"\u{F031E} ";case"json":case"jsonc":return"\u{F0871} ";case"md":case"mdx":return"\u{F0354} ";case"yaml":case"yml":return"\u{F0B10} ";case"sh":case"bash":case"zsh":return"\u{F018D} ";case"css":case"scss":case"sass":return"\u{F031C} ";case"html":case"htm":return"\u{F031D} ";case"py":return"\u{F0320} ";case"go":return"\u{F07D3} ";case"rs":return"\u{F1617} ";case"lock":return"\u{F033E} ";case"png":case"jpg":case"jpeg":case"gif":case"svg":case"webp":return"\u{F02E9} ";default:return"\u{F0214} "}}var Yd="\u{F024B} ",Jd="\u{F0DCF} ",Xd="\u25CB",Pi="\uEA64",Qd="\uEAFE",Zd="\uEBDA",Si="\u25CB",vi="\u25CF",Ii="\u2713",Ci="\u2715";function eu(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"4fc1ff";case"js":case"jsx":case"mjs":case"cjs":return"f7df1e";case"json":case"jsonc":return"fbc02d";case"md":case"mdx":return"519aba";case"yaml":case"yml":return"e06c75";case"sh":case"bash":case"zsh":return"89e051";case"css":case"scss":case"sass":return"c792ea";case"html":case"htm":return"e06c75";case"py":return"3572a5";case"go":return"00add8";case"rs":return"dea584";case"lock":return"565f89";default:return}}var Mn=150,tu=6;var _n="empty",G={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function ou(e,t,r){let n=Ey(t,e),s=t.repos.find(b=>b.id===e.selectedRepoId)??t.repos[0]??null,o=n?t.tasks.filter(b=>b.workspaceId===n.id):t.tasks,i=n?.kind==="project"?o:s?o.filter(b=>b.repoId===s.id):[],a=i.find(b=>b.id===e.selectedTaskId)??i[0]??null,l=a?.type==="project",c=cT(t.tasks),d=Oy(e,a),u=Dy(e,a,d,r),m=u.find(b=>b.id===d)??u[0]??{id:"agent",label:"CODEX"},p=t.inspection?.taskId===a?.id?t.inspection:null,k=s?.name??"no repo",w=a?h.runners.getDisplayName(a.runner):h.runners.getDisplayName(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?e.workspaceBrowser.query!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} Search: ${e.workspaceBrowser.query} \u2191\u2193 move Enter select Esc clear search`:`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up / search Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${s?`[${s.name}]`:"[no repo]"} \xB7 ${h.runners.getDisplayName(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${h.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:yr(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?a===null?"n new task Tab tasks Esc pause ? help":d===D?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${h.runners.getDisplayName(e.centerTabRunner??a?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?l?"\u2191\u2193 targets Enter open change Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 changes Enter open change Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?e.fileSearchQuery!==null?`Search: ${e.fileSearchQuery} \u2191\u2193 navigate Enter open Esc cancel search`:"\u2191\u2193 navigate / search Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:Sr.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Sr.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:w},leftTree:Cy(e,t,r),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(b=>dT(b,c[b])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":m.label,taskId:e.workspaceBrowser?"new workspace":a?.id??"no task",repo:k,agent:w},centerTranscript:xy(d,e,s,a,e.workspaceBrowser,p,n),tabs:u,rightContext:lT(s,a),rightInspection:Ky(e,a,p)}}function Cy(e,t,r){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return Ay(n,e,t.repos,t.tasks,r);let s=t.workspaces;if(s.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let i of s){let a=e.selectedLeftItemId===`workspace:${i.id}`;n.push({id:`workspace:${i.id}`,text:`${i.kind==="project"?"\u2261":"\u2013"} ${i.name??i.id}`,selected:a,focused:a&&e.focusedRegion==="tasks"});let l=i.kind==="project"?i.discoveredRepoIds??[]:[i.primaryRepoId],c=t.tasks.filter(d=>d.workspaceId===i.id);if(c.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of c){let u=e.selectedLeftItemId===`task:${d.id}`,m=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,p={id:`task:${d.id}`,taskId:d.id,text:r?m:`${u?"\u25B8":"\u2022"} ${m}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",...r?{activity:$t(d,r.snapshots,r.now),activityAnimationFrame:r.animationFrame}:{}},k=au(d);k&&(p.prBadge=k),n.push(p)}if(i.kind==="project"){let d=`new-task-workspace:${i.id}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}if(i.kind==="repo"){let d=`new-task:${i.primaryRepoId}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}else{n.push({text:` Repos (${l.length})`,indent:0,muted:!0});for(let d of l.slice(0,6)){let u=t.repos.find(m=>m.id===d);n.push({text:` \xB7 ${u?.name??d}`,indent:0,muted:!0})}l.length>6&&n.push({text:` \xB7 ${l.length-6} more`,indent:0,muted:!0})}}let o=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:o,focused:o&&e.focusedRegion==="tasks"}),n}function Ay(e,t,r,n,s){if(r.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let i of r){let a=t.selectedLeftItemId===`repo:${i.id}`;e.push({id:`repo:${i.id}`,text:`\u2013 ${i.name}`,selected:a,focused:a&&t.focusedRegion==="tasks"});let l=n.filter(u=>u.repoId===i.id);if(l.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let u of l){let m=t.selectedLeftItemId===`task:${u.id}`,p=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,k={id:`task:${u.id}`,taskId:u.id,text:s?p:`${m?"\u25B8":"\u2022"} ${p}`,indent:2,selected:m,focused:m&&t.focusedRegion==="tasks",...s?{activity:$t(u,s.snapshots,s.now),activityAnimationFrame:s.animationFrame}:{}},w=au(u);w&&(k.prBadge=w),e.push(k)}let c=`new-task:${i.id}`,d=t.selectedLeftItemId===c;e.push({id:c,text:`+ New Task [${h.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let o=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:o,focused:o&&t.focusedRegion==="tasks"}),e}function Ey(e,t){let r=e.workspaces??[];if(!e.workspaces)return null;let n=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return n?r.find(s=>s.id===n.workspaceId)??null:t.selectedWorkspaceId?r.find(s=>s.id===t.selectedWorkspaceId)??null:r[0]??null}function xy(e,t,r,n,s,o=null,i=null){if(s){let l=s.query?s.entries.filter(u=>u.name.toLowerCase().includes(s.query.toLowerCase())):s.entries,c=l.length===0?["No matching directories or git repos."]:l.map((u,m)=>{let p=m===s.selectedIndex?"\u25B8":" ",k=u.kind==="repo"?" [git repo]":"/";return`${p} ${u.name}${k}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return ke(["Browse for a workspace to register.",s.cwd,...d?[d]:[],"",...c,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!r)return ke(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let l=i?.kind==="project",c=l?i.name??"this workspace":r.name,d=l?"Project Task":"Task";return ke([`No tasks in ${c}.`,"",`Press n or choose + New ${d} to create one with ${h.runners.getDisplayName(t.selectedRunner)}.`])}let a=n.ptyTabs.find(l=>l.id===e)??null;return a?a.kind==="agent"?ke([`${a.title} tab ready for ${n.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):ke([`${a.title} tab ready for ${n.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===D&&t.openInspectionKind==="file"?My(n,o,t.fileScrollOffset):e===D&&t.openInspectionKind==="diff"?Ly(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?ke(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ke(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Dy(e,t,r,n){let s=t?.ptyTabs.map(i=>({id:i.id,label:$y(i),...i.kind==="agent"&&n&&t?{activity:Ve(t,i.id,n.snapshots,n.now),activityAnimationFrame:n.animationFrame}:{}}))??[];if(!t)return[{id:_n,label:"EMPTY",active:r===_n,focused:e.focusedRegion==="center"&&r===_n}];let o=e.openInspectionKind||r===D?[{id:D,label:Ny(e)}]:[];return[...s,...o].map(i=>({...i,active:i.id===r,focused:e.focusedRegion==="center"&&i.id===r}))}function Oy(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===D&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??D:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??D:_n}function $y(e){return e.title.toUpperCase()}function Ny(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?Sr.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function My(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ke(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=iu(n.path??n.title);return[{text:n.title},{text:`${n.byteLength===null?"size unknown":`${n.byteLength} bytes`} \xB7 ${n.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},..._y(n.lines,r,s)]}function Ly(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ke(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=iu(n.path??n.title);return[{text:n.title},{text:`${t.diffPaths.length} changed files \xB7 ${n.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...jy(n.lines,r,s)]}function ke(e){return e.map(t=>({text:t}))}function _y(e,t,r){let n=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let a=s+i+1;return{text:`${`${String(a).padStart(n," ")} \u2502 `}${o}`,segments:[{text:String(a).padStart(n," "),style:{fg:G.lineNumber}},{text:" \u2502 ",style:{fg:G.gutter}},...Ai(o,r)],tone:"default"}})}function jy(e,t,r){let n=Fy(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>Wy(o,r))}function Fy(e){let t=[],r=0,n=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){r=Number.parseInt(o[1]??"0",10),n=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:r,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),r+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:n,marker:"+",text:s.slice(1),kind:"add"}),n+=1;continue}if(s.startsWith(" ")){if(r===0&&n===0)continue;t.push({oldNumber:r,newNumber:n,marker:" ",text:s.slice(1),kind:"context"}),r+=1,n+=1;continue}}}return t}function Wy(e,t){let r=ru(e.oldNumber),n=ru(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:G.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:G.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?Uy(Ai(e.text,t),o.bg,o.fallbackFg):Ai(e.text,t),l=o?{fg:G.lineNumber,bg:o.bg}:{fg:G.lineNumber},c=o?{fg:G.gutter,bg:o.bg}:{fg:G.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:o!==null}}function ru(e){return e===null?" ":String(e).padStart(4," ")}function iu(e){let t=Sr.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function Ai(e,t){return t==="diff"?qy(e):t==="markdown"?By(e):t==="json"?Ei(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Ei(e,/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)|\/\/.*$|\/\*.*?\*\/|\b(const|let|var|function|return|if|else|for|while|class|interface|type|import|export|from|async|await|new|extends|implements|switch|case|break|continue|try|catch|throw|true|false|null|undefined)\b|-?\b\d+(?:\.\d+)?\b/g):[{text:e}]}function qy(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:G.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:G.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:G.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:G.diffMeta}}]:[{text:e}]}function Uy(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function By(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:G.markup,bold:!0}}]:Ei(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Ei(e,t){let r=[],n=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>n&&r.push({text:e.slice(n,i)}),r.push({text:o,style:Vy(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function Vy(e){return e.startsWith("//")||e.startsWith("/*")?{fg:G.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:G.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:G.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:G.markup}:{fg:G.keyword}}function Ky(e,t,r){let n=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&n?t.repoTargets?.find(a=>a.repoId===n)??null:null,o=t?.type==="project"?lu(t.repoTargets??[]):s?.pullRequest??(t?E(t):null),i=[Gy(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=uu(e,t),l=xi(e,r),c=Xy([{id:"review-pr-header",text:"PULL REQUEST",muted:!0},...a,{id:"review-changes-spacer",text:"",muted:!0},{id:"review-changes-header",text:"CHANGES",muted:!0},...l],e);return{title:"",rows:[...i,...c]}}return e.inspectionMode==="files"?{title:"",rows:[...i,...oT(e,r)]}:{title:"",rows:[...i,...xi(e,r)]}}function Gy(e,t){let r=e.inspectionMode,n=[{label:"FILES",active:r==="files"},{label:"REVIEW",active:r==="review"}],s=[];for(let l=0;l<n.length;l++){let c=n[l];l>0&&s.push({text:" "});let d=c.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:c.label,style:{fg:d}})}let o=Di(t),i=Oi(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function nu(e){return[{text:" "},Di(e),{text:" "},Oi(e)]}function au(e){if(e.type==="project"&&e.repoTargets?.length){let r=lu(e.repoTargets);return r?nu(r):null}let t=E(e);return t?.number?nu(t):null}function lu(e){let t=e.filter(s=>s.status==="ready"),r=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(r.length===0)return null;let n=zy(r);return{number:-1,status:Hy(r),draft:r.some(s=>s.draft),mergeable:r.length===t.length&&r.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:r.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":r.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":r.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:r.flatMap(s=>s.requiredChecks),aggregateReadiness:n}}function Hy(e){return e.some(t=>t.status==="open")?"open":e.every(t=>t.status==="merged")?"merged":e.some(t=>t.status==="closed")?"closed":e[0]?.status??null}function zy(e){let t=e.map(r=>cu(r));return t.some(r=>r==="failed")?"failed":t.some(r=>r==="pending")?"pending":t.length>0&&t.every(r=>r==="success")?"success":"none"}function Di(e){return!e||!e.number?{text:Xd,style:{fg:"565f89"}}:e.status==="merged"?{text:Qd,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Zd,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Pi,style:{fg:"565f89"}}:{text:Pi,style:{fg:"9ece6a"}}}function Oi(e){return e?.aggregateReadiness?su(e.aggregateReadiness):su(cu(e))}function su(e){return e==="failed"?{text:Ci,style:{fg:"f7768e"}}:e==="pending"?{text:vi,style:{fg:"e0af68"}}:e==="success"?{text:Ii,style:{fg:"9ece6a"}}:{text:Si,style:{fg:"565f89"}}}function cu(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(r=>r.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(r=>r.status==="success"||r.status==="skipped")?du(e)?"failed":Yy(e)?"success":"pending":"pending"}function Yy(e){return!!(e.mergeable&&!e.draft&&!du(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function du(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function uu(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return Jy(e,t);let r=E(t),n=mu("pr",t.branch,r??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==r&&(o.status==="merged"||o.status==="closed")).length;return s>0&&n.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),n}var Ln=32;function Jy(e,t){let r=[],n=t.repoTargets??[],s=e.selectedProjectTargetId??n[0]?.repoId??null;for(let i of n){let a=s===i.repoId,l=e.focusedRegion==="inspector"&&a,c=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let u=i.failureReason?i.failureReason.slice(0,14):i.status,m=Ln-u.length-1,p=c.length>m?c.slice(0,m-1)+"\u2026":c,k=Ln-p.length-u.length;r.push({id:`project-review:${i.repoId}`,text:p+" ".repeat(Math.max(1,k))+u,selected:a,focused:l,muted:!0})}else{let d=Di(i.pullRequest),u=Oi(i.pullRequest),m=`${d.text} ${u.text}`,p=Ln-m.length-1,k=c.length>p?c.slice(0,p-1)+"\u2026":c,w=Ln-k.length-m.length,b=k+" ".repeat(Math.max(1,w));r.push({id:`project-review:${i.repoId}`,text:b+m,selected:a,focused:l,segments:[{text:b},{...d,text:d.text},{text:" "},{...u,text:u.text}]})}}let o=n.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(r.push({id:"target-detail-spacer",text:""}),r.push(...mu("target",o.branch,o.pullRequest))),r}function pu(e,t,r=null){return 3+uu(e,t).length+xi(e,r).length}function mu(e,t,r){let n=u=>`${e}-${u}`;if(!r.number)return[{id:n("no-pr"),text:t,muted:!0}];let s=[],o=`#${r.number}`;s.push(r.url?{id:n("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:r.url}]}:{id:n("pr-number"),text:o});let i=r.baseBranch??"?",a=r.headBranch??t;s.push({id:n("pr-branches"),text:`${i} \u2192 ${a}`,muted:!0});let l=Qy(r.reviewDecision,r.mergeStateStatus),c=l&&l!=="review approved"?"merge blocked":r.mergeable?"merge ready":r.mergeStateStatus?`merge ${r.mergeStateStatus}`:"merge unknown";l?s.push({id:n("pr-merge"),text:`${c} \xB7 ${l}`,muted:!0,segments:[{text:c},{text:" \xB7 "},{text:l,style:{fg:Zy(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${fu(r.lastSyncedAt)}`,muted:!0}),s.push({id:n("checks-spacer"),text:""}),s.push({id:n("checks-header"),text:"Checks"}),r.requiredChecks.length?s.push(...r.requiredChecks.map(eT)):s.push({id:n("checks-none"),text:r.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let d=r.comments??[];return d.length>0&&(s.push({id:n("comments-spacer"),text:""}),s.push({id:n("comments-header"),text:`Review comments (${d.length})`}),s.push(...d.slice(-4).flatMap((u,m)=>tT(u,n(`comment:${m}`))))),s}function Xy(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let r=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((n,s)=>({...n,selected:t.reviewScrollOffset===0&&n.selected||s===r,focused:t.reviewScrollOffset===0&&n.focused||s===r}))}function Qy(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Zy(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function fu(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),r=Math.floor(t/1e3);if(r<60)return`${r}s ago`;let n=Math.floor(r/60);if(n<60)return`${n}m ago`;let s=Math.floor(n/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function eT(e){let{icon:t,color:r}=nT(e.status),n=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${n.padEnd(16," ")} ${sT(e.status)}`,color:r,muted:!1}}function tT(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${fu(e.createdAt)}`:"",s=rT(e.body,30),o=s.slice(0,4),i=o.length<s.length,a=[{id:`${t}:author`,text:`${r}${n}`,muted:!0},...o.map((l,c)=>({id:`${t}:body:${c}`,text:` ${i&&c===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return a.push({id:`${t}:spacer`,text:"",muted:!0}),a}function rT(e,t){let r=e.split(/\s+/).filter(Boolean);if(r.length===0)return[];let n=[],s="";for(let o of r){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(n.push(s),s=o)}return s&&n.push(s),n}function nT(e){switch(e){case"success":return{icon:Ii,color:"9ece6a"};case"pending":return{icon:vi,color:"e0af68"};case"failed":return{icon:Ci,color:"f7768e"};case"skipped":return{icon:Si,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function sT(e){return e==="success"?"passing":e==="failed"?"failing":e}function oT(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let r=new Map(t.diffRows.map(l=>[l.path,l.status])),n=$i(t.fileRows,e.collapsedFileTreePaths),s=e.fileSearchQuery,o=s?n.filter(l=>l.path.toLowerCase().includes(s.toLowerCase())):n,i=s!==null?[{id:"file-search",text:`Search: ${s}\u2588`,muted:!1}]:[],a=e.selectedFileTreePath??t.selectedFilePath;return[...i,...o.map(l=>{let c=l.kind==="file"?r.get(l.path):void 0,d=c==="A"?"9ece6a":c==="M"?"e0af68":c==="D"?"f7768e":c==="??"?"565f89":void 0,u=l.kind==="directory"?e.collapsedFileTreePaths.includes(l.path)?Yd:Jd:zd(l.label),m=l.kind==="directory"?"7aa2f7":eu(l.label),p=" ".repeat(l.depth),k=m?{text:u,style:{fg:m}}:{text:u},w=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},b=[{text:p},k,w];return{id:l.path,text:`${p}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:b}})]}function $i(e,t){let r=new Set(t);return e.filter(n=>{let s=n.path.split("/");for(let o=1;o<s.length;o+=1)if(r.has(s.slice(0,o).join("/")))return!1;return!0})}function xi(e,t){if(!t)return[{id:"empty",text:"No task diff index.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.diffRows.length===0)return[{id:"empty",text:t.filePaths.some(s=>s.startsWith("repo_"))?"No changes in project task worktrees. Edits in the original repos are outside this task.":"No local changes.",muted:!0}];if(iT(t))return aT(e,t);let r=[];for(let n of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===n);s.length!==0&&(r.push({id:n,text:n.toUpperCase(),muted:!0}),r.push(...s.map(o=>gu(o,e,t))))}return r}function iT(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function aT(e,t){let r=[],n=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of n){let o=t.diffRows.filter(a=>a.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;r.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let a of["branch","staged","unstaged","untracked"]){let l=o.filter(c=>c.group===a);l.length!==0&&(r.push({id:`repo-diff:${s}:${a}`,text:` ${a}`,muted:!0}),r.push(...l.map(c=>gu(c,e,t,s.length+1))))}}return r}function gu(e,t,r,n=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",a=n>0?e.path.slice(n):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${a} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??r.selectedDiffPath),focused:e.path===(t.selectedDiffPath??r.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function lT(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:h.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Sr.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function cT(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function dT(e,t){return{name:h.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function hu(e,t,r,n,s=null){if(s)return uT(e,t,r,n,s);let o=ti(e,t,{centerOnly:n});return pT(r,o)?{output:An(o.rows,r.rows,o.row,o.column),region:o}:null}function uT(e,t,r,n,s){let o=Zc(e,t,s,{centerOnly:n});if(!o||!mT(r,o))return null;let i=r.rows.slice();return{output:o.rows.map(({index:l,row:c})=>i[l]===c?"":(i[l]=c,`\x1B[${o.row+l};${o.column}H${c}`)).join(""),region:{row:o.row,column:o.column,width:o.width,rows:i}}}function pT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}function mT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rowCount}function wu(e,t,r){let n={...e},s="";for(let o of r){let i=e[o],a=t[o];if(!fT(i,a))return null;!i||!a||(s+=An(a.rows,i.rows,a.row,a.column),n[o]=a)}return{output:s,regions:n}}function fT(e,t){return!e||!t?e===t:e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}var gT=["tasks","center","inspector"];function hT(e,t,r){if(t==="ESCAPE")return R({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return R({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return Mi(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return _i({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return R({state:{...e,fileSearchQuery:n},changed:!0})}return R({state:e})}function _i(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return Fc(t)?R({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):R({state:e});if(e.fileSearchQuery!==null)return hT(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return R({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return R({state:e,exit:!0});if(t==="ESCAPE")return R({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return R({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(hn(e.selectedLeftItemId)||wn(e.selectedLeftItemId)))return R({state:{...e,selectedRunner:gn(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return ku(e,1);if(t==="SHIFT_TAB"||t==="[")return ku(e,-1);if(t==="z"||t==="Z")return R({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===D?Je(e,-1,r):Mi(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===D?Je(e,1,r):Mi(e,1,r);if(t==="PAGE_UP")return Je(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Je(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Je(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Je(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??L,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return R({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let n=ST(e,t);return R({state:{...e,preferredPtyTabKind:n,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:n,createPtyTabRunner:n==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return R({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&yr(e.selectedLeftItemId)&&e.selectedTaskId)return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Vc(e.selectedLeftItemId)&&e.selectedWorkspaceId)return R({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Ru(e.activeTab,r.ptyTabIds??[]))return R({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Ni(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return yu(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Ni(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return yu(e,1)}if(he(t)){if(e.focusedRegion==="tasks"&&(hn(e.selectedLeftItemId)||wn(e.selectedLeftItemId))){let n=zo(e.selectedLeftItemId),s=Yo(e.selectedLeftItemId);return R({state:{...e,selectedRepoId:n??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return R({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&yr(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return R({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Wt(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Ru(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return R({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Wt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===D)return R({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let n=e.selectedFileTreePath??e.selectedFilePath;if(n&&(r.fileTreeDirectoryIds??[]).includes(n))return R({state:yT({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return R({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:D,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}if(e.focusedRegion==="inspector"&&e.inspectionMode==="review"){let n=e.selectedDiffPath??r.diffPathIds?.[0]??null;return n?R({state:{...e,selectedDiffPath:n,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?R({state:e}):e.selectedActionId==="refresh-checks"?R({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return R({state:e})}function Je(e,t,r){if(t===0)return R({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?bu(e,t,r):e.inspectionMode==="review"?Tu(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):R({state:e});if(e.focusedRegion==="center"&&e.activeTab===D){if(e.openInspectionKind==="file")return Tu(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return TT(e,t,r)}return R({state:e})}function ku(e,t){return jn(e,"focusedRegion",gT,t)}function Ni(e,t,r){let n=jn(e,"activeTab",r&&r.length>0?r:vT(e),t);return!n.changed||qc(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Wt(n.state.activeTab)??n.state.preferredPtyTabKind}}}function Mi(e,t,r){if(e.focusedRegion==="tasks")return wT(e,t,r.leftItemIds);if(e.focusedRegion==="center")return Ni(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return bu(e,t,r);if(r.projectTargetIds?.length){let s=Li(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=Li(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:jn(e,"selectedActionId",Nc,t)}return jn(e,"selectedActionId",Vo,t)}function wT(e,t,r){let n=Li(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Ho(n.state.selectedLeftItemId);if(s?.kind==="workspace")return{...n,state:{...n.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...n,state:{...n.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...n,state:{...n.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=zo(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=Yo(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function kT(e,t){if(e.inspectionMode===t)return R({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?D:e.activeTab;return R({state:{...e,inspectionMode:t,activeTab:n,openInspectionKind:r,fileScrollOffset:t==="files"?0:e.fileScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function yu(e,t){return kT(e,PT(e.inspectionMode,Ko,t))}function bu(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return R({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=$e(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return R({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return R({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?D:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function yT(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((r,n)=>r.localeCompare(n)),actionMessage:null}}function Tu(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=$e(e[t]+r,0,o);return i===e[t]?R({state:e}):R({state:{...e,[t]:i,actionMessage:null},changed:!0})}function TT(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return RT(e,t,r);let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=e.diffScrollOffset+t,a=r.diffPathIds??[];if(a.length===0||!e.selectedDiffPath){let d=$e(i,0,o);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let d=$e(i,0,o);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}if(t>0&&i>o){let d=a[l+1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?R({state:e}):R({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let d=a[l-1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?R({state:e}):R({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let c=$e(i,0,o);return c===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function RT(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=$e(e.diffScrollOffset+t,0,o),a=bT(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?R({state:e}):R({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function bT(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function jn(e,t,r,n){let s=r.indexOf(e[t]),o=$e(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?R({state:e}):R({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Li(e,t,r,n,s=!1){if(r.length===0)return R({state:e});let o=r.indexOf(e[t]??r[0]??""),i=$e(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?R({state:e}):R({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function PT(e,t,r){let n=t.indexOf(e);return t[$e(n+r,0,t.length-1)]??e}function R(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function Ru(e,t){return t.includes(e)}function ST(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Wt(e.activeTab)??e.preferredPtyTabKind}function vT(e){return[e.selectedPtyTabId,e.openInspectionKind?D:null].filter(t=>typeof t=="string")}function $e(e,t,r){return Math.min(r,Math.max(t,e))}var Pu=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>x(n.paths,e.selectedTaskId,o=>{let i=t??IT(o,e.activeTab,e.preferredPtyTabKind),a=Cu(o,i,r??void 0,n.config);return{...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id}}));return{updatedTask:s,nextShell:{activeTab:s.selectedPtyTabId??e.activeTab,selectedPtyTabId:s.selectedPtyTabId,preferredPtyTabKind:s.ptyTabs.at(-1)?.kind??e.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${s.ptyTabs.at(-1)?.title??"tab"}`}}},Su=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:r,nextSelectedTab:n}=await t.queueTaskMutation(async()=>{let s={closedTab:null,nextSelectedTab:null};if(await x(t.paths,e.selectedTaskId,o=>{let i=o.ptyTabs.findIndex(l=>l.id===e.activeTab);if(i===-1)throw new Error("Only PTY tabs can be closed.");s.closedTab=o.ptyTabs[i];let a=o.ptyTabs.filter(l=>l.id!==s.closedTab.id);return s.nextSelectedTab=a[Math.min(i,a.length-1)]??null,{...o,ptyTabs:a,selectedPtyTabId:s.nextSelectedTab?.id??null}}),!s.closedTab)throw new Error("Only PTY tabs can be closed.");return{closedTab:s.closedTab,nextSelectedTab:s.nextSelectedTab}});return{closedTab:r,nextSelectedTab:n,nextShell:{activeTab:n?.id??(e.openInspectionKind?"inspection":e.activeTab),selectedPtyTabId:n?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${r.title}`}}},vu=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{await x(t.paths,r,n=>!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab?n:{...n,selectedPtyTabId:e.activeTab})})},Iu=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let o=s.ptyTabs.find(i=>i.kind==="agent")??null;return o?{...s,selectedPtyTabId:o.id}:s})}),{...e,selectedPtyTabId:r.id};let n=Cu(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let o=s.ptyTabs.find(i=>i.kind==="agent")??null;return o?{...s,selectedPtyTabId:o.id}:{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id}})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function IT(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Cu(e,t,r,n={}){let s=r??e.runner,o=h.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",a=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(p=>p.id)),c=1,d=a;for(;l.has(d);)c+=1,d=`${a}-${c}`;let u=new Date().toISOString(),m=r&&r!==e.runner?r:void 0;return{id:d,kind:t,...m?{runner:m}:{},title:c===1?i:`${i} ${c}`,command:t==="agent"?h.runners.buildCommand(s,void 0,n):[],createdAt:u,updatedAt:u}}var Vt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Au=async(e,t,r,n,s)=>{h.runners.assertEnabled(n,s.config);let o=t?await s.taskService.provisionProjectTask(s.paths,t,r,{runner:n,config:s.config}):await s.taskService.provisionTask(s.paths,e??"",r,{runner:n,config:s.config});try{let l=it();at(h.runners.getConfiguredProfile(n,s.config).executable,{cwd:o.repoRoot,env:l})}catch(l){let c=l instanceof Error?l.message:"Failed to start runner.",d=await s.taskService.recordStartupFailure(s.paths,o.task.id,c);throw new Vt(c,d)}let i=await s.taskService.markTaskStarted(s.paths,o.task.id),a={selectedRepoId:i.repoId,selectedWorkspaceId:i.workspaceId,selectedTaskId:i.id,selectedPtyTabId:i.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:i.selectedPtyTabId??"agent",selectedActionId:"commit"};return{task:i,nextShell:a}},Eu=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},xu=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:r,task:n}=await t.queueTaskMutation(async()=>{let s=await Jt(t.paths,e.selectedTaskId),o=await t.taskService.closeTask(t.paths,e.selectedTaskId);return{taskBeforeClose:s,task:o}});return{closedTabIds:r.ptyTabs.map(s=>s.id),nextShell:{selectedActionId:"close-task",actionMessage:n.cleanup.preservedWorktree?`Archived task ${n.id}; worktree preserved`:`Archived task ${n.id}`}}},Du=async(e,t)=>(await t.taskService.prs.discoverOrRefreshMany(t.paths,e),Promise.all(e.map(r=>Jt(t.paths,r.id)))),Fn=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await Le.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var Ou=async(e,t)=>{if(!e.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await t.taskService.listTasks(t.paths,{workspaceId:e.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${e.selectedWorkspaceId} while task records still reference it.`);return await t.workspaceService.archiveWorkspace(t.paths,e.selectedWorkspaceId),{nextShell:{selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${(await t.workspaceService.removeWorkspace(t.paths,e.selectedWorkspaceId,{listTasks:t.taskService.listTasks})).workspaceId}`}}};var $u=async(e,t,r)=>{let n=h.runners.setRunnerEnabled(r.config,e,t);return await h.save(r.paths,n),n},Nu=async(e,t,r)=>{let n=h.runners.setRunnerPath(r.config,e,t);return await h.save(r.paths,n),n},Mu=async(e,t,r)=>{let n=h.previews.setEnabled(r.config,e,t);return await h.save(r.paths,n),n};var CT=250;function Ne(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function ht(e,t){return Oe(t,e.ptyRuntime.getViewState(Kt(e,t)))}function Kt(e,t){let r=Ne(e.model.tasks,t);return r?r.ptyTabs.some(n=>n.id===t.activeTab)?t.activeTab:t.activeTab==="agent"||t.activeTab==="terminal"?r.ptyTabs.find(n=>n.kind===t.activeTab)?.id??t.selectedPtyTabId:t.selectedPtyTabId:t.selectedPtyTabId}function y(e,t){return ht(e,Kc(t,e.model))}function Lu(e,t,r){return e.footerToastTimer&&(clearTimeout(e.footerToastTimer),e.footerToastTimer=null),r?(e.footerToastTimer=setTimeout(()=>{e.footerToastTimer=null,!(e.state.mode!=="main"||e.state.shell.footerToast!==r)&&(e.state={mode:"main",shell:y(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function _u(e,t,r){return Lu(e,t,r?{tone:"success",message:r}:null)}function B(e,t,r){return Lu(e,t,{tone:"error",message:r})}function V(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return Le.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function q(e,t){if(!e.uiStateFile)return;e.runtimeState=_c(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Me({uiStateFile:e.uiStateFile},r),()=>Me({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function AT(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function K(e){return{paths:e.paths,config:e.config,taskService:S,workspaceService:J,queueTaskMutation:t=>AT(e,t)}}function ji(e,t){let r=Ne(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?$i(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:mt(e.model),centerTabIds:Bc(r,t),ptyTabIds:r?.ptyTabs.map(a=>a.id)??[],filePathIds:s?.filePaths??[],fileTreeRowIds:i.map(a=>a.path),fileTreeFileIds:i.filter(a=>a.kind==="file").map(a=>a.path),fileTreeDirectoryIds:i.filter(a=>a.kind==="directory").map(a=>a.path),diffPathIds:s?.diffPaths??[],diffPathRanges:[],fileLineCount:s?.selectedFile.lines.length??0,diffLineCount:s?.selectedDiff.lines.length??0,reviewRowCount:pu(t,r,s),pageRows:Math.max(5,le(e.activeTerminal.width,e.activeTerminal.height).height-W.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function ju(e,t){await vu(t,K(e))}async function Z(e){e.model=await qt(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:y(e,e.state.shell)}:e.state={...e.state,shell:y(e,e.state.shell)}}function Wn(e,t){e.model={...e.model,tasks:[...e.model.tasks.filter(r=>r.id!==t.id),t].sort((r,n)=>r.id.localeCompare(n.id))}}async function qn(e,t){let r=++e.inspectionRefreshSequence,n=Jo(e.model.tasks,t),s=e.model.inspection,o=t.focusedRegion==="inspector"&&t.inspectionMode==="review"&&t.openInspectionKind!=="diff",i;if(n&&s?.taskId===n.id&&!o){let a={selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath},l=await bc(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await qt(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=i,e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},q(e,e.state.shell),e.render())}function Fu(e,t){e.pendingLeftNavInspectionShell=t,!e.leftNavInspectionTimer&&(e.leftNavInspectionTimer=setTimeout(()=>{e.leftNavInspectionTimer=null;let r=e.pendingLeftNavInspectionShell;e.pendingLeftNavInspectionShell=null,!(!r||e.state.mode!=="main"||e.state.shell!==r)&&qn(e,r).catch(n=>{let s=V(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},CT))}function Wu(e,t){t!==0&&(e.pendingInspectionScrollLines+=t,!e.inspectionScrollRenderTimer&&(e.inspectionScrollRenderTimer=setTimeout(()=>{e.inspectionScrollRenderTimer=null;let r=e.pendingInspectionScrollLines;if(e.pendingInspectionScrollLines=0,r===0||e.state.mode!=="main"||e.state.shell.inputMode!=="control")return;let n=Je(e.state.shell,r,ji(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render(),qn(e,e.state.shell).catch(s=>{let o=V(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render()}},16)))}function Fi(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function Wi(e){let t=e.model.tasks.flatMap(r=>r.ptyTabs.map(n=>n.id));await e.ptyRuntime.pruneStale?.(t),await e.ptyRuntime.hydrateSessions?.(t)}function Uu(e){Wi(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},e.render())})}async function Bu(e,t){let r=y(e,t),n=Ne(e.model.tasks,r),s=Kt(e,r);if(!n||!s||!n.ptyTabs.some(a=>a.id===s))return r;let o=e.ptyRuntime.getViewState(s);if(o.status!=="idle"||o.rows.length>0||o.error)return Oe(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,ze(le(e.activeTerminal.width,e.activeTerminal.height)));return Oe({...r,inputMode:"control"},i)}function qi(e){let t=e.state.mode==="main"&&e.state.shell.inputMode==="terminal"?"terminal":"control";t!==e.inputCaptureMode&&(e.inputCaptureMode=t,e.activeTerminal.grabInput(t==="terminal"?{mouse:"button"}:!0))}async function Ui(e,t){try{let r=y(e,t),n=Ne(e.model.tasks,r),s=r.selectedPtyTabId;if(n&&r.focusedRegion==="tasks"){let a=n.ptyTabs.find(l=>l.kind==="agent")??null;a?s=a.id:(n=await qu(e,n),await Z(e),s=n.selectedPtyTabId)}n&&!s&&(n=await qu(e,n),await Z(e),s=n.selectedPtyTabId);let o=y(e,{...r,activeTab:s??r.activeTab,selectedPtyTabId:s,focusedRegion:s?"center":r.focusedRegion});if(!o.selectedTaskId||!s){e.state={mode:"main",shell:o},e.render();return}e.state={mode:"main",shell:Oe({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},q(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,ze(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ye(s),e.lastTerminalKey=null,e.state={mode:"main",shell:Oe({...o,inputMode:"terminal"},i)},q(e,e.state.shell)}catch(r){let n=V(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Ye(t.selectedPtyTabId)&&(await ET(e,t.selectedTaskId,n).catch(()=>{}),await Z(e).catch(()=>{})),e.state={mode:"main",shell:B(e,jc(y(e,t),n),n)},q(e,e.state.shell)}e.render()}async function ET(e,t,r){await Eu(t,r,K(e))}async function Vu(e,t,r,n){let s=y(e,t),{nextShell:o}=await Pu(s,r,n,K(e));return await Z(e),y(e,{...s,...o})}async function Ku(e,t){let r=y(e,t),{closedTab:n,nextShell:s}=await Su(r,K(e));return e.ptyRuntime.disposeSession(n.id),await Z(e),y(e,{...r,...s})}async function Gu(e,t){let r=y(e,t),n=mt(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await xu(r,K(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await Z(e),y(e,{...r,...i,selectedLeftItemId:xT(n,mt(e.model),s)})}async function Hu(e,t){let r=y(e,t),{nextShell:n}=await Ou(r,K(e));return await Z(e),y(e,{...r,...n})}async function qu(e,t){return Iu(t,K(e))}function Un(e,t){e.pendingScrollLines+=t,!e.scrollRenderTimer&&(e.scrollRenderTimer=setTimeout(()=>{e.scrollRenderTimer=null;let r=e.pendingScrollLines;e.pendingScrollLines=0,r!==0&&(e.ptyRuntime.scrollViewport(r),e.state={mode:"main",shell:ht(e,e.state.shell)},e.render())},16))}function xT(e,t,r){if(t.length===0)return null;for(let n=r-1;n>=0;n-=1){let s=e[n];if(s&&t.includes(s))return s}return t[Math.min(Math.max(0,r),t.length-1)]??null}async function Yu(e,t,r){if(r?.aborted||e.state.mode!=="main")return;let n=zu(e),s=t.takeDueTasks(e.model.tasks,n);if(s.length!==0)try{let o=await Du(s,K(e));if(r?.aborted||(e.lastBackgroundPrPollError=null,e.state.mode!=="main"))return;for(let i of o)Wn(e,i);t.recordSuccess(o,zu(e)),e.state={mode:"main",shell:y(e,e.state.shell)},e.render()}catch(o){if(r?.aborted)return;t.recordFailure(s,o);let i=o instanceof Error?o.message:"Background PR discovery failed.";i!==e.lastBackgroundPrPollError&&(e.lastBackgroundPrPollError=i,Fn("background PR polling",o,K(e)))}}function zu(e){return e.state.mode!=="main"?{selectedTaskId:null,reviewVisible:!1}:{selectedTaskId:e.state.shell.selectedTaskId,reviewVisible:e.state.shell.inspectionMode==="review"}}async function Ju(e,t){let r=y(e,t),n=Ne(e.model.tasks,r),s=null,o=null;if(n?.type==="project"&&n.repoTargets?.length){let i=await S.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await Z(e);let a=i.synced+i.discovered+i.notFound;o=`Refreshed ${i.synced}/${a} targets`}else{let{disposition:i,task:a}=await S.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await Z(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${E(a)?.requiredChecks.length??0} reported`)}return y(e,{..._u(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}var DT={pendingForegroundMs:5e3,pendingBackgroundMs:15e3,stableForegroundMs:3e4,stableBackgroundMs:6e4,discoveryForegroundMs:6e4,discoveryBackgroundMs:18e4,rateLimitBaseMs:6e4,rateLimitMaxMs:15*6e4},Bn=class{scheduledTasks=new Map;now;intervals;minimumIntervalMs;rateLimitFailures=0;notBefore=0;constructor(t={}){this.minimumIntervalMs=Math.max(1e3,t.minimumIntervalMs??5e3),this.intervals={...DT,...t.intervals},this.now=t.now??Date.now}takeDueTasks(t,r){let n=this.now(),s=new Set(t.map(i=>i.id));for(let i of this.scheduledTasks.keys())s.has(i)||this.scheduledTasks.delete(i);let o=[];for(let i of t){let a=this.getTaskIntervalMs(i,r);if(a===null){this.scheduledTasks.delete(i.id);continue}let l=this.scheduledTasks.get(i.id);if(!l){this.scheduledTasks.set(i.id,{intervalMs:a,nextPollAt:n}),n>=this.notBefore&&o.push(i);continue}a<l.intervalMs&&(l.nextPollAt=Math.min(l.nextPollAt,n+a)),l.intervalMs=a,n>=this.notBefore&&n>=l.nextPollAt&&o.push(i)}return o}recordSuccess(t,r){let n=this.now();this.rateLimitFailures=0,this.notBefore=0;for(let s of t){let o=this.getTaskIntervalMs(s,r);o===null?this.scheduledTasks.delete(s.id):this.scheduledTasks.set(s.id,{intervalMs:o,nextPollAt:n+o})}}recordFailure(t,r){let n=this.now(),s=r instanceof ye,o=s?Math.min(this.intervals.rateLimitBaseMs*2**this.rateLimitFailures,this.intervals.rateLimitMaxMs):Math.max(this.minimumIntervalMs,this.intervals.pendingBackgroundMs);s&&(this.rateLimitFailures+=1,this.notBefore=n+o);for(let i of t){let a=this.scheduledTasks.get(i.id);a&&(a.nextPollAt=n+o)}}getTaskIntervalMs(t,r){let n=OT(t),s=t.id===r.selectedTaskId&&r.reviewVisible;if(n.length>0){let o=n.some($T);return this.withMinimum(o?s?this.intervals.pendingForegroundMs:this.intervals.pendingBackgroundMs:s?this.intervals.stableForegroundMs:this.intervals.stableBackgroundMs)}return t.status==="checked"?this.withMinimum(s?this.intervals.discoveryForegroundMs:this.intervals.discoveryBackgroundMs):null}withMinimum(t){return Math.max(t,this.minimumIntervalMs)}};function OT(e){return e.type==="project"&&e.repoTargets?.length?e.repoTargets.map(t=>t.pullRequest).filter(t=>t.status==="open"):e.prs.filter(t=>t.status==="open")}function $T(e){return e.requiredChecks.some(t=>t.status==="pending"||t.status==="unknown")}import jT from"node:path";import{readdir as NT,stat as MT}from"node:fs/promises";import Xu from"node:path";async function LT(e){let t=await NT(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=Xu.join(e,n.name);r.push({name:n.name,path:s,kind:await _T(s)?"repo":"directory"})}return r.sort((n,s)=>n.kind!==s.kind?n.kind==="repo"?-1:1:n.name.localeCompare(s.name)),{cwd:e,entries:r,selectedIndex:0,query:null,error:null}}function Qu(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function Zu(e){let{spawn:t}=await import("node:child_process"),r=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((n,s)=>{let o=t(r,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",n)})}async function Vn(e,t){let r=await LT(t);e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function _T(e){let t=Xu.join(e,".git");return await MT(t).catch(()=>null)!==null}function ep(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function tp(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function FT(e){if(e.state.mode!=="main"||e.creatingTask)return;let t=e.state.shell,r=t.taskPromptInput?.trim()??"";if(!t.selectedRepoId&&!t.selectedWorkspaceId){e.state={mode:"main",shell:y(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:y(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:y(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await Au(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,K(e));n=s.task,Wn(e,n);let o=y(e,{...e.state.shell,...s.nextShell,selectedLeftItemId:`task:${n.id}`,inputMode:"terminal",taskPromptInput:null,taskPromptError:null,actionMessage:null}),i=await e.ptyRuntime.ensureSession(n.id,o.selectedPtyTabId??cd(n,"agent"),ze(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ye(o.selectedPtyTabId),e.state={mode:"main",shell:Oe(o,i)},q(e,e.state.shell)}catch(s){s instanceof Vt&&(n=s.task);let o=V(e,"create task",s,"Failed to create task.");n&&!(s instanceof Vt)?(await x(e.paths,n.id,i=>({...i,status:"draft",runnerSession:{...i.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o})).catch(()=>{}),await Z(e).catch(()=>{})):n&&(await x(e.paths,n.id,i=>({...i,lastFailureReason:o})).catch(()=>{}),await Z(e).catch(()=>{})),e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,inputMode:"control",selectedTaskId:n?.id??e.state.shell.selectedTaskId,selectedPtyTabId:n?.selectedPtyTabId??e.state.shell.selectedPtyTabId,selectedLeftItemId:n?`task:${n.id}`:e.state.shell.selectedLeftItemId,activeTab:n?.selectedPtyTabId??e.state.shell.activeTab,taskPromptInput:n?null:"",taskPromptError:o,actionMessage:null}),o)}}finally{e.creatingTask=!1,e.render()}}function WT(e,t){if(e.state.mode!=="main")return;let r=e.state.shell;if(r.taskPromptInput!==null){if(t==="ESCAPE"){e.state={mode:"main",shell:y(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(he(t)){FT(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:y(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:y(e,{...r,selectedRunner:gn(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}Wc(t)&&(e.state={mode:"main",shell:y(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function qT(e,t){if(e.state.mode!=="main")return;let r=e.state.shell.workspaceBrowser;if(!r)return;if(t==="ESCAPE"){if(r.query!==null){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:"",selectedIndex:0}})},e.render();return}if(r.query!==null&&(t==="BACKSPACE"||t==="DELETE")){let s=r.query.slice(0,-1);e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}if(r.query!==null&&t.length===1&&t>=" "){let s=r.query+t;e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=Qu(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.max(0,r.selectedIndex-1),error:null}})},e.render();return}if(t==="DOWN"||t==="j"){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.min(Math.max(0,n.length-1),r.selectedIndex+1),error:null}})},e.render();return}if(t==="LEFT"||t==="h"){Vn(e,jT.dirname(r.cwd)).catch(s=>{let o=V(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:o}}),o)},e.render()});return}if(t==="RIGHT"||t==="l"||he(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){Vn(e,s.path).catch(i=>{let a=V(e,"open workspace directory",i,"Failed to open directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:o}=K(e);o.addWorkspace(e.paths,s.path).then(async i=>{await Z(e);let a=i.repos[0]??null,l=y(e,{...e.state.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${i.workspace.id}`,selectedWorkspaceId:i.workspace.id,selectedRepoId:a?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${i.workspace.name??i.workspace.id}`});e.state={mode:"main",shell:l},q(e,e.state.shell),e.render()}).catch(i=>{let a=V(e,"add workspace",i,"Failed to add workspace.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function UT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=Kd(e.state.menuIndex,t);if(r.kind!=="noop"){if(r.kind==="render"){e.state={...e.state,menuIndex:r.menuIndex},e.render();return}if(r.kind==="back"){e.state.parentVariant&&(e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render());return}if(r.kind==="help"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell,viaOptions:!0,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="runners"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="previews"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"previews",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="error-log"){let n=e.state.parentVariant;BT(e,n)}}}async function BT(e,t){let r;try{r=await Le.readRecentErrorLines(e.paths)}catch(n){let s=V(e,"open error log",n,"Failed to read Craig error log.");r={path:e.paths.errorLogFile,lines:[`Unable to read error log: ${s}`],empty:!1}}e.state.mode==="overlay"&&(e.state={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:e.state.shell,errorLog:r,...t!==void 0?{parentVariant:t}:{}},e.pendingClear=!0,e.render())}function VT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=Hd(ep(e),e.config,t,e.enabledRunnerIds);if(r.kind==="noop")return;if(r.kind==="back"){let s=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...s!==void 0?{parentVariant:s}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="render"){e.state={...e.state,runnerOptions:r.state},e.render();return}(r.kind==="save-enabled"?$u(r.runner,r.enabled,K(e)):Nu(r.runner,r.path,K(e))).then(s=>{e.state.mode!=="overlay"||e.state.variant!=="runners"||(e.config=s,e.enabledRunnerIds=h.runners.getEnabled(e.config),e.model={...e.model,enabledRunnerIds:e.enabledRunnerIds},e.state={...e.state,shell:y(e,{...e.state.shell,selectedRunner:e.enabledRunnerIds.includes(e.state.shell.selectedRunner)?e.state.shell.selectedRunner:h.runners.getDefault(e.config)}),runnerOptions:r.state},e.render())}).catch(s=>{if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let o=V(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:B(e,y(e,e.state.shell),o),runnerOptions:{...ep(e),message:o}},e.render()})}function KT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=Gd(tp(e),e.config,t);if(r.kind!=="noop"){if(r.kind==="back"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="render"){e.state={...e.state,previewOptions:r.state},e.render();return}Mu(r.feature,r.enabled,K(e)).then(n=>{e.state.mode!=="overlay"||e.state.variant!=="previews"||(e.config=n,r.feature==="incrementalCenterPane"&&e.ptyRuntime.setViewUpdateMode?.(r.enabled?"incremental":"snapshot"),r.feature==="agentActivityIndicators"&&e.setAgentActivityEnabled(r.enabled),e.state={...e.state,previewOptions:r.state},e.render())}).catch(n=>{if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let s=V(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:B(e,y(e,e.state.shell),s),previewOptions:{...tp(e),message:s}},e.render()})}}function rp(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){WT(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){qT(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){HT(e),e.render();return}e.focusFlashUntil!==null&&(e.focusFlashUntil=null,e.focusFlashTimer&&(clearTimeout(e.focusFlashTimer),e.focusFlashTimer=null))}if(e.state.mode==="main"){let n=_i(e.state.shell,r,ji(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&he(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=br(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(GT(e,r))return;e.lastTerminalKey=dd(r)?{key:r,at:Date.now()}:null;let o=ud(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){Un(e,o);return}e.ptyRuntime.writeKey(r);return}if(r==="CTRL_C"){e.exit(0);return}if(r==="?"&&e.state.shell.inputMode==="control"){e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render();return}if(n.pause){e.state={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:y(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){Vn(e,e.workspaceRoot).catch(s=>{let o=V(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:B(e,y(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:o}}),o)},e.render()});return}if(n.createPtyTab){Vu(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{Ui(e,s)}).catch(s=>{let o=V(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.closePtyTab){Ku(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.refreshPullRequestChecks){Ju(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.openPrUrl){let s=Ne(e.model.tasks,n.state),o=s?E(s)?.url??null:null;o?Zu(o).catch(i=>{let a=V(e,"open PR URL",i,"Failed to open PR in browser.");e.state={mode:"main",shell:B(e,y(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:B(e,y(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){Gu(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.removeWorkspace){Hu(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.attachTerminal){Ui(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),(e.state.shell.focusedRegion!=="tasks"||!e.renderTaskNavigation())&&e.render(),e.state.shell.focusedRegion==="tasks"){Fu(e,e.state.shell);return}qn(e,e.state.shell).catch(s=>{let o=V(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}n.changed&&(e.state={mode:"main",shell:y(e,n.state)},ju(e,e.state.shell).catch(()=>{}),q(e,e.state.shell),e.render());return}if(e.state.variant==="help"){e.state.viaOptions&&e.state.parentVariant?e.state={mode:"overlay",variant:"options",menuIndex:3,optionsMessage:null,shell:e.state.shell,parentVariant:e.state.parentVariant}:e.state.parentVariant?e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell}:e.state={mode:"main",shell:y(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){UT(e,r);return}if(e.state.variant==="runners"){VT(e,r);return}if(e.state.variant==="previews"){KT(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||he(r)){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render()}return}if(e.state.optionsMessage){(r==="ESCAPE"||he(r))&&(e.state={...e.state,optionsMessage:null},e.render());return}if(r==="UP"||r==="k"){e.state={...e.state,menuIndex:Math.max(0,e.state.menuIndex-1)},e.render();return}if(r==="DOWN"||r==="j"){e.state={...e.state,menuIndex:Math.min(2,e.state.menuIndex+1)},e.render();return}if(r==="ESCAPE"){e.state.variant==="pause"&&(e.state={mode:"main",shell:y(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(he(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:y(e,{...e.state.shell,inputMode:"control"})},e.pendingClear=!0,e.render(),n?e.bootHydrationReady.then(()=>{if(e.state.mode!=="main")return;let s=e.state.shell;Bu(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},q(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=V(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:B(e,y(e,e.state.shell),i)},q(e,e.state.shell),e.render()})}):Uu(e);return}if(e.state.menuIndex===1){let n=e.state.variant==="boot"||e.state.variant==="pause"?e.state.variant:void 0;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}e.exit(0)}}function np(e,t){let r=hd(t);if(e.state.mode!=="main"||e.state.shell.inputMode!=="terminal"||r.length===0)return;if(e.pendingTerminalKeySequence){let o=`${e.pendingTerminalKeySequence.raw}${r}`,i=br(o);if(i){op(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(li(o)){e.pendingTerminalKeySequence.raw=o,sp(e);return}Kn(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:y(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},q(e,e.state.shell),e.render();return}let n=pd(r);if(n!==0){Un(e,n);return}let s=br(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
135
+ `}function Iy(e){return e.length===1&&e>=" "&&e!==""}import Sr from"node:path";function zd(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"\u{F06E6} ";case"js":case"jsx":case"mjs":case"cjs":return"\u{F031E} ";case"json":case"jsonc":return"\u{F0871} ";case"md":case"mdx":return"\u{F0354} ";case"yaml":case"yml":return"\u{F0B10} ";case"sh":case"bash":case"zsh":return"\u{F018D} ";case"css":case"scss":case"sass":return"\u{F031C} ";case"html":case"htm":return"\u{F031D} ";case"py":return"\u{F0320} ";case"go":return"\u{F07D3} ";case"rs":return"\u{F1617} ";case"lock":return"\u{F033E} ";case"png":case"jpg":case"jpeg":case"gif":case"svg":case"webp":return"\u{F02E9} ";default:return"\u{F0214} "}}var Yd="\u{F024B} ",Jd="\u{F0DCF} ",Xd="\u25CB",Pi="\uEA64",Qd="\uEAFE",Zd="\uEBDA",Si="\u25CB",vi="\u25CF",Ii="\u2713",Ci="\u2715";function eu(e){switch(e.toLowerCase().split(".").pop()??""){case"ts":case"tsx":return"4fc1ff";case"js":case"jsx":case"mjs":case"cjs":return"f7df1e";case"json":case"jsonc":return"fbc02d";case"md":case"mdx":return"519aba";case"yaml":case"yml":return"e06c75";case"sh":case"bash":case"zsh":return"89e051";case"css":case"scss":case"sass":return"c792ea";case"html":case"htm":return"e06c75";case"py":return"3572a5";case"go":return"00add8";case"rs":return"dea584";case"lock":return"565f89";default:return}}var Mn=150,tu=6;var _n="empty",G={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function ou(e,t,r){let n=Ey(t,e),s=t.repos.find(b=>b.id===e.selectedRepoId)??t.repos[0]??null,o=n?t.tasks.filter(b=>b.workspaceId===n.id):t.tasks,i=n?.kind==="project"?o:s?o.filter(b=>b.repoId===s.id):[],a=i.find(b=>b.id===e.selectedTaskId)??i[0]??null,l=a?.type==="project",c=cT(t.tasks),d=Oy(e,a),u=Dy(e,a,d,r),m=u.find(b=>b.id===d)??u[0]??{id:"agent",label:"CODEX"},p=t.inspection?.taskId===a?.id?t.inspection:null,k=s?.name??"no repo",w=a?h.runners.getDisplayName(a.runner):h.runners.getDisplayName(e.selectedRunner);return{inputMode:e.inputMode,modalInput:e.taskPromptInput!==null||e.workspaceBrowser!==null,focusedRegion:e.focusedRegion,actionMessage:e.actionMessage,footerToast:e.footerToast,terminal:e.terminal,footerText:e.workspaceBrowser!==null?e.workspaceBrowser.query!==null?`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} Search: ${e.workspaceBrowser.query} \u2191\u2193 move Enter select Esc clear search`:`BROWSE WORKSPACE ${e.workspaceBrowser.cwd} \u2191\u2193 move \u2192 open \u2190 up / search Enter add repo Esc cancel`:e.taskPromptInput!==null?`NEW TASK ${s?`[${s.name}]`:"[no repo]"} \xB7 ${h.runners.getDisplayName(e.selectedRunner)} Ctrl+R switch runner Enter create Esc cancel \u203A ${e.taskPromptInput}${e.taskPromptError?` \u2717 ${e.taskPromptError}`:""}`:e.inputMode==="terminal"?"TERMINAL \u2191\u2193/PgUp/PgDn scroll Ctrl+] return to control":e.focusedRegion==="tasks"?e.selectedLeftItemId?.startsWith("new-task:")||e.selectedLeftItemId?.startsWith("new-task-workspace:")?`r runner [${h.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:yr(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?a===null?"n new task Tab tasks Esc pause ? help":d===D?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${h.runners.getDisplayName(e.centerTabRunner??a?.runner??e.selectedRunner)} r runner t terminal x close Enter attach Esc pause ? help`:e.inspectionMode==="review"?l?"\u2191\u2193 targets Enter open change Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 changes Enter open change Wheel/PgUp/PgDn scroll o open PR R refresh checks X close task \u2190/\u2192 mode Esc pause ? help":e.inspectionMode==="files"?e.fileSearchQuery!==null?`Search: ${e.fileSearchQuery} \u2191\u2193 navigate Enter open Esc cancel search`:"\u2191\u2193 navigate / search Enter open file \u2190/\u2192 mode Esc pause ? help":"\u2191\u2193 navigate \u2190/\u2192 mode Esc pause ? help",topRail:{workspacePath:Sr.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Sr.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:w},leftTree:Cy(e,t,r),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(b=>dT(b,c[b])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":m.label,taskId:e.workspaceBrowser?"new workspace":a?.id??"no task",repo:k,agent:w},centerTranscript:xy(d,e,s,a,e.workspaceBrowser,p,n),tabs:u,rightContext:lT(s,a),rightInspection:Ky(e,a,p)}}function Cy(e,t,r){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return Ay(n,e,t.repos,t.tasks,r);let s=t.workspaces;if(s.length===0)n.push({text:"No workspaces registered.",indent:2,muted:!0});else for(let i of s){let a=e.selectedLeftItemId===`workspace:${i.id}`;n.push({id:`workspace:${i.id}`,text:`${i.kind==="project"?"\u2261":"\u2013"} ${i.name??i.id}`,selected:a,focused:a&&e.focusedRegion==="tasks"});let l=i.kind==="project"?i.discoveredRepoIds??[]:[i.primaryRepoId],c=t.tasks.filter(d=>d.workspaceId===i.id);if(c.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let d of c){let u=e.selectedLeftItemId===`task:${d.id}`,m=d.title.length>28?`${d.title.slice(0,25)}\u2026`:d.title,p={id:`task:${d.id}`,taskId:d.id,text:r?m:`${u?"\u25B8":"\u2022"} ${m}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",...r?{activity:$t(d,r.snapshots,r.now),activityAnimationFrame:r.animationFrame}:{}},k=au(d);k&&(p.prBadge=k),n.push(p)}if(i.kind==="project"){let d=`new-task-workspace:${i.id}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}if(i.kind==="repo"){let d=`new-task:${i.primaryRepoId}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Task [${h.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}else{n.push({text:` Repos (${l.length})`,indent:0,muted:!0});for(let d of l.slice(0,6)){let u=t.repos.find(m=>m.id===d);n.push({text:` \xB7 ${u?.name??d}`,indent:0,muted:!0})}l.length>6&&n.push({text:` \xB7 ${l.length-6} more`,indent:0,muted:!0})}}let o=e.selectedLeftItemId==="new-workspace";return n.push({text:"",muted:!0}),n.push({id:"new-workspace",text:"+ New Workspace",selected:o,focused:o&&e.focusedRegion==="tasks"}),n}function Ay(e,t,r,n,s){if(r.length===0)e.push({text:"No repos registered.",indent:2,muted:!0});else for(let i of r){let a=t.selectedLeftItemId===`repo:${i.id}`;e.push({id:`repo:${i.id}`,text:`\u2013 ${i.name}`,selected:a,focused:a&&t.focusedRegion==="tasks"});let l=n.filter(u=>u.repoId===i.id);if(l.length===0)e.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let u of l){let m=t.selectedLeftItemId===`task:${u.id}`,p=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,k={id:`task:${u.id}`,taskId:u.id,text:s?p:`${m?"\u25B8":"\u2022"} ${p}`,indent:2,selected:m,focused:m&&t.focusedRegion==="tasks",...s?{activity:$t(u,s.snapshots,s.now),activityAnimationFrame:s.animationFrame}:{}},w=au(u);w&&(k.prBadge=w),e.push(k)}let c=`new-task:${i.id}`,d=t.selectedLeftItemId===c;e.push({id:c,text:`+ New Task [${h.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:d,focused:d&&t.focusedRegion==="tasks",muted:!d})}let o=t.selectedLeftItemId==="new-workspace";return e.push({text:"",muted:!0}),e.push({id:"new-workspace",text:"+ New Workspace",selected:o,focused:o&&t.focusedRegion==="tasks"}),e}function Ey(e,t){let r=e.workspaces??[];if(!e.workspaces)return null;let n=e.tasks.find(s=>s.id===t.selectedTaskId)??null;return n?r.find(s=>s.id===n.workspaceId)??null:t.selectedWorkspaceId?r.find(s=>s.id===t.selectedWorkspaceId)??null:r[0]??null}function xy(e,t,r,n,s,o=null,i=null){if(s){let l=s.query?s.entries.filter(u=>u.name.toLowerCase().includes(s.query.toLowerCase())):s.entries,c=l.length===0?["No matching directories or git repos."]:l.map((u,m)=>{let p=m===s.selectedIndex?"\u25B8":" ",k=u.kind==="repo"?" [git repo]":"/";return`${p} ${u.name}${k}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return ke(["Browse for a workspace to register.",s.cwd,...d?[d]:[],"",...c,"",s.error??"Use \u2191\u2193 to move, \u2192 or Enter to open, \u2190 to go up, Enter on a git repo to add it."])}if(!r)return ke(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let l=i?.kind==="project",c=l?i.name??"this workspace":r.name,d=l?"Project Task":"Task";return ke([`No tasks in ${c}.`,"",`Press n or choose + New ${d} to create one with ${h.runners.getDisplayName(t.selectedRunner)}.`])}let a=n.ptyTabs.find(l=>l.id===e)??null;return a?a.kind==="agent"?ke([`${a.title} tab ready for ${n.id}.`,"","Press Enter to attach this PTY-backed agent session.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):ke([`${a.title} tab ready for ${n.id}.`,"","Press Enter to attach this plain task shell.","Use + to create another task tab, a/t for a specific kind, or x to close this tab."]):e===D&&t.openInspectionKind==="file"?My(n,o,t.fileScrollOffset):e===D&&t.openInspectionKind==="diff"?Ly(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?ke(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ke(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Dy(e,t,r,n){let s=t?.ptyTabs.map(i=>({id:i.id,label:$y(i),...i.kind==="agent"&&n&&t?{activity:Ve(t,i.id,n.snapshots,n.now),activityAnimationFrame:n.animationFrame}:{}}))??[];if(!t)return[{id:_n,label:"EMPTY",active:r===_n,focused:e.focusedRegion==="center"&&r===_n}];let o=e.openInspectionKind||r===D?[{id:D,label:Ny(e)}]:[];return[...s,...o].map(i=>({...i,active:i.id===r,focused:e.focusedRegion==="center"&&i.id===r}))}function Oy(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===D&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??D:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??D:_n}function $y(e){return e.title.toUpperCase()}function Ny(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?Sr.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function My(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ke(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=iu(n.path??n.title);return[{text:n.title},{text:`${n.byteLength===null?"size unknown":`${n.byteLength} bytes`} \xB7 ${n.lines.length} lines \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},..._y(n.lines,r,s)]}function Ly(e,t,r){if(!e)return ke(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ke(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=iu(n.path??n.title);return[{text:n.title},{text:`${t.diffPaths.length} changed files \xB7 ${n.lines.length} rows \xB7 PgUp/PgDn or wheel scroll`,tone:"muted"},{text:""},...jy(n.lines,r,s)]}function ke(e){return e.map(t=>({text:t}))}function _y(e,t,r){let n=Math.max(3,String(e.length).length),s=Math.max(0,Math.min(t,Math.max(0,e.length-1)));return e.slice(s).map((o,i)=>{let a=s+i+1;return{text:`${`${String(a).padStart(n," ")} \u2502 `}${o}`,segments:[{text:String(a).padStart(n," "),style:{fg:G.lineNumber}},{text:" \u2502 ",style:{fg:G.gutter}},...Ai(o,r)],tone:"default"}})}function jy(e,t,r){let n=Fy(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>Wy(o,r))}function Fy(e){let t=[],r=0,n=0;for(let s of e){let o=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){r=Number.parseInt(o[1]??"0",10),n=Number.parseInt(o[2]??"0",10);continue}if(!(s.startsWith("diff --git")||s.startsWith("index ")||s.startsWith("+++ ")||s.startsWith("--- "))&&!(s==="staged"||s==="unstaged"||s==="untracked")){if(s.startsWith("-")&&!s.startsWith("---")){t.push({oldNumber:r,newNumber:null,marker:"-",text:s.slice(1),kind:"delete"}),r+=1;continue}if(s.startsWith("+")&&!s.startsWith("+++")){t.push({oldNumber:null,newNumber:n,marker:"+",text:s.slice(1),kind:"add"}),n+=1;continue}if(s.startsWith(" ")){if(r===0&&n===0)continue;t.push({oldNumber:r,newNumber:n,marker:" ",text:s.slice(1),kind:"context"}),r+=1,n+=1;continue}}}return t}function Wy(e,t){let r=ru(e.oldNumber),n=ru(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:G.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:G.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?Uy(Ai(e.text,t),o.bg,o.fallbackFg):Ai(e.text,t),l=o?{fg:G.lineNumber,bg:o.bg}:{fg:G.lineNumber},c=o?{fg:G.gutter,bg:o.bg}:{fg:G.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:o!==null}}function ru(e){return e===null?" ":String(e).padStart(4," ")}function iu(e){let t=Sr.extname(e).toLowerCase();return[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(t)?"javascript":[".json",".jsonc"].includes(t)?"json":[".md",".mdx"].includes(t)?"markdown":[".css",".scss"].includes(t)?"css":"plain"}function Ai(e,t){return t==="diff"?qy(e):t==="markdown"?By(e):t==="json"?Ei(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Ei(e,/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)|\/\/.*$|\/\*.*?\*\/|\b(const|let|var|function|return|if|else|for|while|class|interface|type|import|export|from|async|await|new|extends|implements|switch|case|break|continue|try|catch|throw|true|false|null|undefined)\b|-?\b\d+(?:\.\d+)?\b/g):[{text:e}]}function qy(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:G.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:G.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:G.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:G.diffMeta}}]:[{text:e}]}function Uy(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function By(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:G.markup,bold:!0}}]:Ei(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Ei(e,t){let r=[],n=0;for(let s of e.matchAll(t)){let o=s[0],i=s.index??0;i>n&&r.push({text:e.slice(n,i)}),r.push({text:o,style:Vy(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function Vy(e){return e.startsWith("//")||e.startsWith("/*")?{fg:G.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:G.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:G.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:G.markup}:{fg:G.keyword}}function Ky(e,t,r){let n=e.selectedProjectTargetId??t?.repoTargets?.[0]?.repoId??null,s=t?.type==="project"&&n?t.repoTargets?.find(a=>a.repoId===n)??null:null,o=t?.type==="project"?lu(t.repoTargets??[]):s?.pullRequest??(t?E(t):null),i=[Gy(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=uu(e,t),l=xi(e,r),c=Xy([{id:"review-pr-header",text:"PULL REQUEST",muted:!0},...a,{id:"review-changes-spacer",text:"",muted:!0},{id:"review-changes-header",text:"CHANGES",muted:!0},...l],e);return{title:"",rows:[...i,...c]}}return e.inspectionMode==="files"?{title:"",rows:[...i,...oT(e,r)]}:{title:"",rows:[...i,...xi(e,r)]}}function Gy(e,t){let r=e.inspectionMode,n=[{label:"FILES",active:r==="files"},{label:"REVIEW",active:r==="review"}],s=[];for(let l=0;l<n.length;l++){let c=n[l];l>0&&s.push({text:" "});let d=c.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:c.label,style:{fg:d}})}let o=Di(t),i=Oi(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function nu(e){return[{text:" "},Di(e),{text:" "},Oi(e)]}function au(e){if(e.type==="project"&&e.repoTargets?.length){let r=lu(e.repoTargets);return r?nu(r):null}let t=E(e);return t?.number?nu(t):null}function lu(e){let t=e.filter(s=>s.status==="ready"),r=t.map(s=>s.pullRequest).filter(s=>!!s.number);if(r.length===0)return null;let n=zy(r);return{number:-1,status:Hy(r),draft:r.some(s=>s.draft),mergeable:r.length===t.length&&r.every(s=>s.mergeable),mergeStateStatus:null,reviewDecision:r.some(s=>s.reviewDecision==="CHANGES_REQUESTED")?"CHANGES_REQUESTED":r.some(s=>s.reviewDecision==="REVIEW_REQUIRED")?"REVIEW_REQUIRED":r.every(s=>s.reviewDecision==="APPROVED")?"APPROVED":null,requiredChecks:r.flatMap(s=>s.requiredChecks),aggregateReadiness:n}}function Hy(e){return e.some(t=>t.status==="open")?"open":e.every(t=>t.status==="merged")?"merged":e.some(t=>t.status==="closed")?"closed":e[0]?.status??null}function zy(e){let t=e.map(r=>cu(r));return t.some(r=>r==="failed")?"failed":t.some(r=>r==="pending")?"pending":t.length>0&&t.every(r=>r==="success")?"success":"none"}function Di(e){return!e||!e.number?{text:Xd,style:{fg:"565f89"}}:e.status==="merged"?{text:Qd,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Zd,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Pi,style:{fg:"565f89"}}:{text:Pi,style:{fg:"9ece6a"}}}function Oi(e){return e?.aggregateReadiness?su(e.aggregateReadiness):su(cu(e))}function su(e){return e==="failed"?{text:Ci,style:{fg:"f7768e"}}:e==="pending"?{text:vi,style:{fg:"e0af68"}}:e==="success"?{text:Ii,style:{fg:"9ece6a"}}:{text:Si,style:{fg:"565f89"}}}function cu(e){let t=e?.requiredChecks??null;return e?.status==="merged"?"success":e?.status==="closed"||!e?.number||!t||t.length===0?"none":t.some(r=>r.status==="failed")||e.reviewDecision==="CHANGES_REQUESTED"?"failed":t.every(r=>r.status==="success"||r.status==="skipped")?du(e)?"failed":Yy(e)?"success":"pending":"pending"}function Yy(e){return!!(e.mergeable&&!e.draft&&!du(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function du(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function uu(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return Jy(e,t);let r=E(t),n=mu("pr",t.branch,r??{number:null,url:null,baseBranch:null,headBranch:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,lastSyncedAt:null,requiredChecks:[],comments:[]}),s=t.prs.filter(o=>o!==r&&(o.status==="merged"||o.status==="closed")).length;return s>0&&n.push({id:"pr-history",text:`+ ${s} previous PR${s!==1?"s":""}`,muted:!0}),n}var Ln=32;function Jy(e,t){let r=[],n=t.repoTargets??[],s=e.selectedProjectTargetId??n[0]?.repoId??null;for(let i of n){let a=s===i.repoId,l=e.focusedRegion==="inspector"&&a,c=i.repoId.startsWith("repo_")?i.repoId.slice(5):i.repoId;if(i.status!=="ready"){let u=i.failureReason?i.failureReason.slice(0,14):i.status,m=Ln-u.length-1,p=c.length>m?c.slice(0,m-1)+"\u2026":c,k=Ln-p.length-u.length;r.push({id:`project-review:${i.repoId}`,text:p+" ".repeat(Math.max(1,k))+u,selected:a,focused:l,muted:!0})}else{let d=Di(i.pullRequest),u=Oi(i.pullRequest),m=`${d.text} ${u.text}`,p=Ln-m.length-1,k=c.length>p?c.slice(0,p-1)+"\u2026":c,w=Ln-k.length-m.length,b=k+" ".repeat(Math.max(1,w));r.push({id:`project-review:${i.repoId}`,text:b+m,selected:a,focused:l,segments:[{text:b},{...d,text:d.text},{text:" "},{...u,text:u.text}]})}}let o=n.find(i=>i.repoId===s)??null;return o?.status==="ready"&&o.pullRequest.number&&(r.push({id:"target-detail-spacer",text:""}),r.push(...mu("target",o.branch,o.pullRequest))),r}function pu(e,t,r=null){return 3+uu(e,t).length+xi(e,r).length}function mu(e,t,r){let n=u=>`${e}-${u}`;if(!r.number)return[{id:n("no-pr"),text:t,muted:!0}];let s=[],o=`#${r.number}`;s.push(r.url?{id:n("pr-number"),text:`${o} Open in GitHub \u2197`,segments:[{text:o},{text:" Open in GitHub \u2197",style:{fg:"7aa2f7",underline:!0},href:r.url}]}:{id:n("pr-number"),text:o});let i=r.baseBranch??"?",a=r.headBranch??t;s.push({id:n("pr-branches"),text:`${i} \u2192 ${a}`,muted:!0});let l=Qy(r.reviewDecision,r.mergeStateStatus),c=l&&l!=="review approved"?"merge blocked":r.mergeable?"merge ready":r.mergeStateStatus?`merge ${r.mergeStateStatus}`:"merge unknown";l?s.push({id:n("pr-merge"),text:`${c} \xB7 ${l}`,muted:!0,segments:[{text:c},{text:" \xB7 "},{text:l,style:{fg:Zy(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${fu(r.lastSyncedAt)}`,muted:!0}),s.push({id:n("checks-spacer"),text:""}),s.push({id:n("checks-header"),text:"Checks"}),r.requiredChecks.length?s.push(...r.requiredChecks.map(eT)):s.push({id:n("checks-none"),text:r.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let d=r.comments??[];return d.length>0&&(s.push({id:n("comments-spacer"),text:""}),s.push({id:n("comments-header"),text:`Review comments (${d.length})`}),s.push(...d.slice(-4).flatMap((u,m)=>tT(u,n(`comment:${m}`))))),s}function Xy(e,t){if(t.focusedRegion!=="inspector"||t.inspectionMode!=="review"||e.length===0)return e;let r=Math.max(0,Math.min(t.reviewScrollOffset,e.length-1));return e.map((n,s)=>({...n,selected:t.reviewScrollOffset===0&&n.selected||s===r,focused:t.reviewScrollOffset===0&&n.focused||s===r}))}function Qy(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function Zy(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function fu(e){if(!e)return"--";let t=Date.now()-new Date(e).getTime(),r=Math.floor(t/1e3);if(r<60)return`${r}s ago`;let n=Math.floor(r/60);if(n<60)return`${n}m ago`;let s=Math.floor(n/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function eT(e){let{icon:t,color:r}=nT(e.status),n=e.name.length>16?`${e.name.slice(0,15)}\u2026`:e.name;return{id:`pr-check:${e.name}`,text:`${t} ${n.padEnd(16," ")} ${sT(e.status)}`,color:r,muted:!1}}function tT(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${fu(e.createdAt)}`:"",s=rT(e.body,30),o=s.slice(0,4),i=o.length<s.length,a=[{id:`${t}:author`,text:`${r}${n}`,muted:!0},...o.map((l,c)=>({id:`${t}:body:${c}`,text:` ${i&&c===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return a.push({id:`${t}:spacer`,text:"",muted:!0}),a}function rT(e,t){let r=e.split(/\s+/).filter(Boolean);if(r.length===0)return[];let n=[],s="";for(let o of r){if(!s){s=o;continue}`${s} ${o}`.length<=t?s=`${s} ${o}`:(n.push(s),s=o)}return s&&n.push(s),n}function nT(e){switch(e){case"success":return{icon:Ii,color:"9ece6a"};case"pending":return{icon:vi,color:"e0af68"};case"failed":return{icon:Ci,color:"f7768e"};case"skipped":return{icon:Si,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function sT(e){return e==="success"?"passing":e==="failed"?"failing":e}function oT(e,t){if(!t)return[{id:"empty",text:"No file index. Select a task with local changes.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.fileRows.length===0)return[{id:"empty",text:"No Git-visible files.",muted:!0}];let r=new Map(t.diffRows.map(l=>[l.path,l.status])),n=$i(t.fileRows,e.collapsedFileTreePaths),s=e.fileSearchQuery,o=s?n.filter(l=>l.path.toLowerCase().includes(s.toLowerCase())):n,i=s!==null?[{id:"file-search",text:`Search: ${s}\u2588`,muted:!1}]:[],a=e.selectedFileTreePath??t.selectedFilePath;return[...i,...o.map(l=>{let c=l.kind==="file"?r.get(l.path):void 0,d=c==="A"?"9ece6a":c==="M"?"e0af68":c==="D"?"f7768e":c==="??"?"565f89":void 0,u=l.kind==="directory"?e.collapsedFileTreePaths.includes(l.path)?Yd:Jd:zd(l.label),m=l.kind==="directory"?"7aa2f7":eu(l.label),p=" ".repeat(l.depth),k=m?{text:u,style:{fg:m}}:{text:u},w=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},b=[{text:p},k,w];return{id:l.path,text:`${p}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:b}})]}function $i(e,t){let r=new Set(t);return e.filter(n=>{let s=n.path.split("/");for(let o=1;o<s.length;o+=1)if(r.has(s.slice(0,o).join("/")))return!1;return!0})}function xi(e,t){if(!t)return[{id:"empty",text:"No task diff index.",muted:!0}];if(t.error)return[{id:"error",text:t.error,muted:!0}];if(t.diffRows.length===0)return[{id:"empty",text:t.filePaths.some(s=>s.startsWith("repo_"))?"No changes in project task worktrees. Edits in the original repos are outside this task.":"No local changes.",muted:!0}];if(iT(t))return aT(e,t);let r=[];for(let n of["branch","staged","unstaged","untracked"]){let s=t.diffRows.filter(o=>o.group===n);s.length!==0&&(r.push({id:n,text:n.toUpperCase(),muted:!0}),r.push(...s.map(o=>gu(o,e,t))))}return r}function iT(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function aT(e,t){let r=[],n=[...new Set(t.diffRows.map(s=>s.path.split("/")[0]).filter(s=>typeof s=="string"&&s.length>0))].sort();for(let s of n){let o=t.diffRows.filter(a=>a.path.startsWith(`${s}/`)),i=s.startsWith("repo_")?s.slice(5):s;r.push({id:`repo-diff:${s}`,text:i,muted:!0});for(let a of["branch","staged","unstaged","untracked"]){let l=o.filter(c=>c.group===a);l.length!==0&&(r.push({id:`repo-diff:${s}:${a}`,text:` ${a}`,muted:!0}),r.push(...l.map(c=>gu(c,e,t,s.length+1))))}}return r}function gu(e,t,r,n=0){let s=e.additions===null?"-":`+${e.additions}`,o=e.deletions===null?"-":`-${e.deletions}`,i=e.status==="A"||e.group==="untracked"?"9ece6a":e.status==="D"?"f7768e":"e0af68",a=n>0?e.path.slice(n):e.path;return{id:`${e.group}:${e.path}`,text:` ${e.status.padEnd(2," ")} ${a} ${s}/${o}`,selected:e.path===(t.selectedDiffPath??r.selectedDiffPath),focused:e.path===(t.selectedDiffPath??r.selectedDiffPath)&&t.focusedRegion==="inspector",color:i}}function lT(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:h.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Sr.basename(t.worktreePath)}]:[{label:"Repo",value:e.name},{label:"Branch",value:e.defaultBranch},{label:"Task",value:"none",mutedValue:!0}]:[{label:"Repo",value:"none",mutedValue:!0}]}function cT(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function dT(e,t){return{name:h.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function hu(e,t,r,n,s=null){if(s)return uT(e,t,r,n,s);let o=ti(e,t,{centerOnly:n});return pT(r,o)?{output:An(o.rows,r.rows,o.row,o.column),region:o}:null}function uT(e,t,r,n,s){let o=Zc(e,t,s,{centerOnly:n});if(!o||!mT(r,o))return null;let i=r.rows.slice();return{output:o.rows.map(({index:l,row:c})=>i[l]===c?"":(i[l]=c,`\x1B[${o.row+l};${o.column}H${c}`)).join(""),region:{row:o.row,column:o.column,width:o.width,rows:i}}}function pT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}function mT(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rowCount}function wu(e,t,r){let n={...e},s="";for(let o of r){let i=e[o],a=t[o];if(!fT(i,a))return null;!i||!a||(s+=An(a.rows,i.rows,a.row,a.column),n[o]=a)}return{output:s,regions:n}}function fT(e,t){return!e||!t?e===t:e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}var gT=["tasks","center","inspector"];function hT(e,t,r){if(t==="ESCAPE")return R({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return R({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return Mi(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return _i({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return R({state:{...e,fileSearchQuery:n},changed:!0})}return R({state:e})}function _i(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return Fc(t)?R({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):R({state:e});if(e.fileSearchQuery!==null)return hT(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return R({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return R({state:e,exit:!0});if(t==="ESCAPE")return R({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return R({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(hn(e.selectedLeftItemId)||wn(e.selectedLeftItemId)))return R({state:{...e,selectedRunner:gn(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return ku(e,1);if(t==="SHIFT_TAB"||t==="[")return ku(e,-1);if(t==="z"||t==="Z")return R({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===D?Je(e,-1,r):Mi(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===D?Je(e,1,r):Mi(e,1,r);if(t==="PAGE_UP")return Je(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Je(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Je(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Je(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??L,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return R({state:{...e,centerTabRunner:o,actionMessage:null},changed:!0})}if((t==="+"||t==="a"||t==="A"||t==="t"||t==="T")&&e.focusedRegion==="center"&&e.selectedTaskId){let n=ST(e,t);return R({state:{...e,preferredPtyTabKind:n,actionMessage:null},changed:!0,createPtyTab:!0,createPtyTabKind:n,createPtyTabRunner:n==="agent"?e.centerTabRunner:null})}if(t==="R"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return R({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&yr(e.selectedLeftItemId)&&e.selectedTaskId)return R({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Vc(e.selectedLeftItemId)&&e.selectedWorkspaceId)return R({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Ru(e.activeTab,r.ptyTabIds??[]))return R({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Ni(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return yu(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Ni(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return yu(e,1)}if(he(t)){if(e.focusedRegion==="tasks"&&(hn(e.selectedLeftItemId)||wn(e.selectedLeftItemId))){let n=zo(e.selectedLeftItemId),s=Yo(e.selectedLeftItemId);return R({state:{...e,selectedRepoId:n??e.selectedRepoId,selectedWorkspaceId:s??e.selectedWorkspaceId,actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0})}if(e.focusedRegion==="tasks"&&e.selectedLeftItemId==="new-workspace")return R({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&yr(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return R({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:Wt(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Ru(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return R({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:Wt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===D)return R({state:{...e,actionMessage:null},changed:!0,refreshInspection:!0});if(e.focusedRegion==="inspector"&&e.selectedTaskId&&e.inspectionMode==="files"){let n=e.selectedFileTreePath??e.selectedFilePath;if(n&&(r.fileTreeDirectoryIds??[]).includes(n))return R({state:yT({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return R({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:D,openInspectionKind:"file",fileScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0})}if(e.focusedRegion==="inspector"&&e.inspectionMode==="review"){let n=e.selectedDiffPath??r.diffPathIds?.[0]??null;return n?R({state:{...e,selectedDiffPath:n,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?R({state:e}):e.selectedActionId==="refresh-checks"?R({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?R({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):R({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return R({state:e})}function Je(e,t,r){if(t===0)return R({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?bu(e,t,r):e.inspectionMode==="review"?Tu(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):R({state:e});if(e.focusedRegion==="center"&&e.activeTab===D){if(e.openInspectionKind==="file")return Tu(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return TT(e,t,r)}return R({state:e})}function ku(e,t){return jn(e,"focusedRegion",gT,t)}function Ni(e,t,r){let n=jn(e,"activeTab",r&&r.length>0?r:vT(e),t);return!n.changed||qc(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:Wt(n.state.activeTab)??n.state.preferredPtyTabKind}}}function Mi(e,t,r){if(e.focusedRegion==="tasks")return wT(e,t,r.leftItemIds);if(e.focusedRegion==="center")return Ni(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return bu(e,t,r);if(r.projectTargetIds?.length){let s=Li(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=Li(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:jn(e,"selectedActionId",Nc,t)}return jn(e,"selectedActionId",Vo,t)}function wT(e,t,r){let n=Li(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Ho(n.state.selectedLeftItemId);if(s?.kind==="workspace")return{...n,state:{...n.state,selectedWorkspaceId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="task")return{...n,state:{...n.state,selectedTaskId:s.id,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};if(s?.kind==="repo")return{...n,state:{...n.state,selectedRepoId:s.id,selectedTaskId:null,selectedPtyTabId:null,selectedFilePath:null,selectedFileTreePath:null,selectedDiffPath:null,fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0},refreshInspection:!0};let o=zo(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=Yo(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function kT(e,t){if(e.inspectionMode===t)return R({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?D:e.activeTab;return R({state:{...e,inspectionMode:t,activeTab:n,openInspectionKind:r,fileScrollOffset:t==="files"?0:e.fileScrollOffset,reviewScrollOffset:t==="review"?0:e.reviewScrollOffset,actionMessage:null},changed:!0,refreshInspection:!0})}function yu(e,t){return kT(e,PT(e.inspectionMode,Ko,t))}function bu(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return R({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=$e(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return R({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return R({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?D:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function yT(e){if(!e.selectedFileTreePath)return e;let t=new Set(e.collapsedFileTreePaths);return t.has(e.selectedFileTreePath)?t.delete(e.selectedFileTreePath):t.add(e.selectedFileTreePath),{...e,collapsedFileTreePaths:[...t].sort((r,n)=>r.localeCompare(n)),actionMessage:null}}function Tu(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=$e(e[t]+r,0,o);return i===e[t]?R({state:e}):R({state:{...e,[t]:i,actionMessage:null},changed:!0})}function TT(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return RT(e,t,r);let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=e.diffScrollOffset+t,a=r.diffPathIds??[];if(a.length===0||!e.selectedDiffPath){let d=$e(i,0,o);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let d=$e(i,0,o);return d===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}if(t>0&&i>o){let d=a[l+1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?R({state:e}):R({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let d=a[l-1]??null;return d?R({state:{...e,selectedDiffPath:d,activeTab:D,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?R({state:e}):R({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let c=$e(i,0,o);return c===e.diffScrollOffset?R({state:e}):R({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function RT(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=$e(e.diffScrollOffset+t,0,o),a=bT(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?R({state:e}):R({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function bT(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function jn(e,t,r,n){let s=r.indexOf(e[t]),o=$e(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?R({state:e}):R({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Li(e,t,r,n,s=!1){if(r.length===0)return R({state:e});let o=r.indexOf(e[t]??r[0]??""),i=$e(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?R({state:e}):R({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function PT(e,t,r){let n=t.indexOf(e);return t[$e(n+r,0,t.length-1)]??e}function R(e){return{state:e.state,changed:e.changed??!1,exit:e.exit??!1,pause:e.pause??!1,attachTerminal:e.attachTerminal??!1,detachTerminal:e.detachTerminal??!1,beginTaskPrompt:e.beginTaskPrompt??!1,openWorkspaceBrowser:e.openWorkspaceBrowser??!1,createWorkspaceTask:e.createWorkspaceTask??!1,createPtyTab:e.createPtyTab??!1,createPtyTabKind:e.createPtyTabKind??null,createPtyTabRunner:e.createPtyTabRunner??null,closePtyTab:e.closePtyTab??!1,refreshPullRequestChecks:e.refreshPullRequestChecks??!1,closeTask:e.closeTask??!1,removeWorkspace:e.removeWorkspace??!1,refreshInspection:e.refreshInspection??!1,openPrUrl:e.openPrUrl??!1}}function Ru(e,t){return t.includes(e)}function ST(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":Wt(e.activeTab)??e.preferredPtyTabKind}function vT(e){return[e.selectedPtyTabId,e.openInspectionKind?D:null].filter(t=>typeof t=="string")}function $e(e,t,r){return Math.min(r,Math.max(t,e))}var Pu=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>x(n.paths,e.selectedTaskId,o=>{let i=t??IT(o,e.activeTab,e.preferredPtyTabKind),a=Cu(o,i,r??void 0,n.config);return{...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id}}));return{updatedTask:s,nextShell:{activeTab:s.selectedPtyTabId??e.activeTab,selectedPtyTabId:s.selectedPtyTabId,preferredPtyTabKind:s.ptyTabs.at(-1)?.kind??e.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${s.ptyTabs.at(-1)?.title??"tab"}`}}},Su=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:r,nextSelectedTab:n}=await t.queueTaskMutation(async()=>{let s={closedTab:null,nextSelectedTab:null};if(await x(t.paths,e.selectedTaskId,o=>{let i=o.ptyTabs.findIndex(l=>l.id===e.activeTab);if(i===-1)throw new Error("Only PTY tabs can be closed.");s.closedTab=o.ptyTabs[i];let a=o.ptyTabs.filter(l=>l.id!==s.closedTab.id);return s.nextSelectedTab=a[Math.min(i,a.length-1)]??null,{...o,ptyTabs:a,selectedPtyTabId:s.nextSelectedTab?.id??null}}),!s.closedTab)throw new Error("Only PTY tabs can be closed.");return{closedTab:s.closedTab,nextSelectedTab:s.nextSelectedTab}});return{closedTab:r,nextSelectedTab:n,nextShell:{activeTab:n?.id??(e.openInspectionKind?"inspection":e.activeTab),selectedPtyTabId:n?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${r.title}`}}},vu=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{await x(t.paths,r,n=>!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab?n:{...n,selectedPtyTabId:e.activeTab})})},Iu=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let o=s.ptyTabs.find(i=>i.kind==="agent")??null;return o?{...s,selectedPtyTabId:o.id}:s})}),{...e,selectedPtyTabId:r.id};let n=Cu(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{await x(t.paths,e.id,s=>{let o=s.ptyTabs.find(i=>i.kind==="agent")??null;return o?{...s,selectedPtyTabId:o.id}:{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id}})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function IT(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function Cu(e,t,r,n={}){let s=r??e.runner,o=h.runners.getProfile(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",a=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(p=>p.id)),c=1,d=a;for(;l.has(d);)c+=1,d=`${a}-${c}`;let u=new Date().toISOString(),m=r&&r!==e.runner?r:void 0;return{id:d,kind:t,...m?{runner:m}:{},title:c===1?i:`${i} ${c}`,command:t==="agent"?h.runners.buildCommand(s,void 0,n):[],createdAt:u,updatedAt:u}}var Vt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Au=async(e,t,r,n,s)=>{h.runners.assertEnabled(n,s.config);let o=t?await s.taskService.provisionProjectTask(s.paths,t,r,{runner:n,config:s.config}):await s.taskService.provisionTask(s.paths,e??"",r,{runner:n,config:s.config});try{let l=it();at(h.runners.getConfiguredProfile(n,s.config).executable,{cwd:o.repoRoot,env:l})}catch(l){let c=l instanceof Error?l.message:"Failed to start runner.",d=await s.taskService.recordStartupFailure(s.paths,o.task.id,c);throw new Vt(c,d)}let i=await s.taskService.markTaskStarted(s.paths,o.task.id),a={selectedRepoId:i.repoId,selectedWorkspaceId:i.workspaceId,selectedTaskId:i.id,selectedPtyTabId:i.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:i.selectedPtyTabId??"agent",selectedActionId:"commit"};return{task:i,nextShell:a}},Eu=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},xu=async(e,t)=>{if(!e.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:r,task:n}=await t.queueTaskMutation(async()=>{let s=await Jt(t.paths,e.selectedTaskId),o=await t.taskService.closeTask(t.paths,e.selectedTaskId);return{taskBeforeClose:s,task:o}});return{closedTabIds:r.ptyTabs.map(s=>s.id),nextShell:{selectedActionId:"close-task",actionMessage:n.cleanup.preservedWorktree?`Archived task ${n.id}; worktree preserved`:`Archived task ${n.id}`}}},Du=async(e,t)=>(await t.taskService.prs.discoverOrRefreshMany(t.paths,e),Promise.all(e.map(r=>Jt(t.paths,r.id)))),Fn=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await Le.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var Ou=async(e,t)=>{if(!e.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await t.taskService.listTasks(t.paths,{workspaceId:e.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${e.selectedWorkspaceId} while task records still reference it.`);return await t.workspaceService.archiveWorkspace(t.paths,e.selectedWorkspaceId),{nextShell:{selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${(await t.workspaceService.removeWorkspace(t.paths,e.selectedWorkspaceId,{listTasks:t.taskService.listTasks})).workspaceId}`}}};var $u=async(e,t,r)=>{let n=h.runners.setRunnerEnabled(r.config,e,t);return await h.save(r.paths,n),n},Nu=async(e,t,r)=>{let n=h.runners.setRunnerPath(r.config,e,t);return await h.save(r.paths,n),n},Mu=async(e,t,r)=>{let n=h.previews.setEnabled(r.config,e,t);return await h.save(r.paths,n),n};var CT=250;function Ne(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function ht(e,t){return Oe(t,e.ptyRuntime.getViewState(Kt(e,t)))}function Kt(e,t){let r=Ne(e.model.tasks,t);return r?r.ptyTabs.some(n=>n.id===t.activeTab)?t.activeTab:t.activeTab==="agent"||t.activeTab==="terminal"?r.ptyTabs.find(n=>n.kind===t.activeTab)?.id??t.selectedPtyTabId:t.selectedPtyTabId:t.selectedPtyTabId}function y(e,t){return ht(e,Kc(t,e.model))}function Lu(e,t,r){return e.footerToastTimer&&(clearTimeout(e.footerToastTimer),e.footerToastTimer=null),r?(e.footerToastTimer=setTimeout(()=>{e.footerToastTimer=null,!(e.state.mode!=="main"||e.state.shell.footerToast!==r)&&(e.state={mode:"main",shell:y(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function _u(e,t,r){return Lu(e,t,r?{tone:"success",message:r}:null)}function B(e,t,r){return Lu(e,t,{tone:"error",message:r})}function V(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return Le.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function q(e,t){if(!e.uiStateFile)return;e.runtimeState=_c(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Me({uiStateFile:e.uiStateFile},r),()=>Me({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function AT(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function K(e){return{paths:e.paths,config:e.config,taskService:S,workspaceService:J,queueTaskMutation:t=>AT(e,t)}}function ji(e,t){let r=Ne(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?$i(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:mt(e.model),centerTabIds:Bc(r,t),ptyTabIds:r?.ptyTabs.map(a=>a.id)??[],filePathIds:s?.filePaths??[],fileTreeRowIds:i.map(a=>a.path),fileTreeFileIds:i.filter(a=>a.kind==="file").map(a=>a.path),fileTreeDirectoryIds:i.filter(a=>a.kind==="directory").map(a=>a.path),diffPathIds:s?.diffPaths??[],diffPathRanges:[],fileLineCount:s?.selectedFile.lines.length??0,diffLineCount:s?.selectedDiff.lines.length??0,reviewRowCount:pu(t,r,s),pageRows:Math.max(5,le(e.activeTerminal.width,e.activeTerminal.height).height-W.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function ju(e,t){await vu(t,K(e))}async function Z(e){e.model=await qt(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:y(e,e.state.shell)}:e.state={...e.state,shell:y(e,e.state.shell)}}function Wn(e,t){e.model={...e.model,tasks:[...e.model.tasks.filter(r=>r.id!==t.id),t].sort((r,n)=>r.id.localeCompare(n.id))}}async function qn(e,t){let r=++e.inspectionRefreshSequence,n=Jo(e.model.tasks,t),s=e.model.inspection,o=t.focusedRegion==="inspector"&&t.inspectionMode==="review"&&t.openInspectionKind!=="diff",i;if(n&&s?.taskId===n.id&&!o){let a={selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath},l=await bc(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await qt(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=i,e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},q(e,e.state.shell),e.render())}function Fu(e,t){e.pendingLeftNavInspectionShell=t,!e.leftNavInspectionTimer&&(e.leftNavInspectionTimer=setTimeout(()=>{e.leftNavInspectionTimer=null;let r=e.pendingLeftNavInspectionShell;e.pendingLeftNavInspectionShell=null,!(!r||e.state.mode!=="main"||e.state.shell!==r)&&qn(e,r).catch(n=>{let s=V(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},CT))}function Wu(e,t){t!==0&&(e.pendingInspectionScrollLines+=t,!e.inspectionScrollRenderTimer&&(e.inspectionScrollRenderTimer=setTimeout(()=>{e.inspectionScrollRenderTimer=null;let r=e.pendingInspectionScrollLines;if(e.pendingInspectionScrollLines=0,r===0||e.state.mode!=="main"||e.state.shell.inputMode!=="control")return;let n=Je(e.state.shell,r,ji(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render(),qn(e,e.state.shell).catch(s=>{let o=V(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render()}},16)))}function Fi(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function Wi(e){let t=e.model.tasks.flatMap(r=>r.ptyTabs.map(n=>n.id));await e.ptyRuntime.pruneStale?.(t),await e.ptyRuntime.hydrateSessions?.(t)}function Uu(e){Wi(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,e.state.shell)},e.render())})}async function Bu(e,t){let r=y(e,t),n=Ne(e.model.tasks,r),s=Kt(e,r);if(!n||!s||!n.ptyTabs.some(a=>a.id===s))return r;let o=e.ptyRuntime.getViewState(s);if(o.status!=="idle"||o.rows.length>0||o.error)return Oe(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,ze(le(e.activeTerminal.width,e.activeTerminal.height)));return Oe({...r,inputMode:"control"},i)}function qi(e){let t=e.state.mode==="main"&&e.state.shell.inputMode==="terminal"?"terminal":"control";t!==e.inputCaptureMode&&(e.inputCaptureMode=t,e.activeTerminal.grabInput(t==="terminal"?{mouse:"button"}:!0))}async function Ui(e,t){try{let r=y(e,t),n=Ne(e.model.tasks,r),s=r.selectedPtyTabId;if(n&&r.focusedRegion==="tasks"){let a=n.ptyTabs.find(l=>l.kind==="agent")??null;a?s=a.id:(n=await qu(e,n),await Z(e),s=n.selectedPtyTabId)}n&&!s&&(n=await qu(e,n),await Z(e),s=n.selectedPtyTabId);let o=y(e,{...r,activeTab:s??r.activeTab,selectedPtyTabId:s,focusedRegion:s?"center":r.focusedRegion});if(!o.selectedTaskId||!s){e.state={mode:"main",shell:o},e.render();return}e.state={mode:"main",shell:Oe({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},q(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,ze(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ye(s),e.lastTerminalKey=null,e.state={mode:"main",shell:Oe({...o,inputMode:"terminal"},i)},q(e,e.state.shell)}catch(r){let n=V(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Ye(t.selectedPtyTabId)&&(await ET(e,t.selectedTaskId,n).catch(()=>{}),await Z(e).catch(()=>{})),e.state={mode:"main",shell:B(e,jc(y(e,t),n),n)},q(e,e.state.shell)}e.render()}async function ET(e,t,r){await Eu(t,r,K(e))}async function Vu(e,t,r,n){let s=y(e,t),{nextShell:o}=await Pu(s,r,n,K(e));return await Z(e),y(e,{...s,...o})}async function Ku(e,t){let r=y(e,t),{closedTab:n,nextShell:s}=await Su(r,K(e));return e.ptyRuntime.disposeSession(n.id),await Z(e),y(e,{...r,...s})}async function Gu(e,t){let r=y(e,t),n=mt(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await xu(r,K(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await Z(e),y(e,{...r,...i,selectedLeftItemId:xT(n,mt(e.model),s)})}async function Hu(e,t){let r=y(e,t),{nextShell:n}=await Ou(r,K(e));return await Z(e),y(e,{...r,...n})}async function qu(e,t){return Iu(t,K(e))}function Un(e,t){e.pendingScrollLines+=t,!e.scrollRenderTimer&&(e.scrollRenderTimer=setTimeout(()=>{e.scrollRenderTimer=null;let r=e.pendingScrollLines;e.pendingScrollLines=0,r!==0&&(e.ptyRuntime.scrollViewport(r),e.state={mode:"main",shell:ht(e,e.state.shell)},e.render())},16))}function xT(e,t,r){if(t.length===0)return null;for(let n=r-1;n>=0;n-=1){let s=e[n];if(s&&t.includes(s))return s}return t[Math.min(Math.max(0,r),t.length-1)]??null}async function Yu(e,t,r){if(r?.aborted||e.state.mode!=="main")return;let n=zu(e),s=t.takeDueTasks(e.model.tasks,n);if(s.length!==0)try{let o=await Du(s,K(e));if(r?.aborted||(e.lastBackgroundPrPollError=null,e.state.mode!=="main"))return;for(let i of o)Wn(e,i);t.recordSuccess(o,zu(e)),e.state={mode:"main",shell:y(e,e.state.shell)},e.render()}catch(o){if(r?.aborted)return;t.recordFailure(s,o);let i=o instanceof Error?o.message:"Background PR discovery failed.";i!==e.lastBackgroundPrPollError&&(e.lastBackgroundPrPollError=i,Fn("background PR polling",o,K(e)))}}function zu(e){return e.state.mode!=="main"?{selectedTaskId:null,reviewVisible:!1}:{selectedTaskId:e.state.shell.selectedTaskId,reviewVisible:e.state.shell.inspectionMode==="review"}}async function Ju(e,t){let r=y(e,t),n=Ne(e.model.tasks,r),s=null,o=null;if(n?.type==="project"&&n.repoTargets?.length){let i=await S.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await Z(e);let a=i.synced+i.discovered+i.notFound;o=`Refreshed ${i.synced}/${a} targets`}else{let{disposition:i,task:a}=await S.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await Z(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${E(a)?.requiredChecks.length??0} reported`)}return y(e,{..._u(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}var DT={pendingForegroundMs:5e3,pendingBackgroundMs:15e3,stableForegroundMs:3e4,stableBackgroundMs:6e4,discoveryForegroundMs:6e4,discoveryBackgroundMs:18e4,rateLimitBaseMs:6e4,rateLimitMaxMs:15*6e4},Bn=class{scheduledTasks=new Map;now;intervals;minimumIntervalMs;rateLimitFailures=0;notBefore=0;constructor(t={}){this.minimumIntervalMs=Math.max(1e3,t.minimumIntervalMs??5e3),this.intervals={...DT,...t.intervals},this.now=t.now??Date.now}takeDueTasks(t,r){let n=this.now(),s=new Set(t.map(i=>i.id));for(let i of this.scheduledTasks.keys())s.has(i)||this.scheduledTasks.delete(i);let o=[];for(let i of t){let a=this.getTaskIntervalMs(i,r);if(a===null){this.scheduledTasks.delete(i.id);continue}let l=this.scheduledTasks.get(i.id);if(!l){this.scheduledTasks.set(i.id,{intervalMs:a,nextPollAt:n}),n>=this.notBefore&&o.push(i);continue}a<l.intervalMs&&(l.nextPollAt=Math.min(l.nextPollAt,n+a)),l.intervalMs=a,n>=this.notBefore&&n>=l.nextPollAt&&o.push(i)}return o}recordSuccess(t,r){let n=this.now();this.rateLimitFailures=0,this.notBefore=0;for(let s of t){let o=this.getTaskIntervalMs(s,r);o===null?this.scheduledTasks.delete(s.id):this.scheduledTasks.set(s.id,{intervalMs:o,nextPollAt:n+o})}}recordFailure(t,r){let n=this.now(),s=r instanceof ye,o=s?Math.min(this.intervals.rateLimitBaseMs*2**this.rateLimitFailures,this.intervals.rateLimitMaxMs):Math.max(this.minimumIntervalMs,this.intervals.pendingBackgroundMs);s&&(this.rateLimitFailures+=1,this.notBefore=n+o);for(let i of t){let a=this.scheduledTasks.get(i.id);a&&(a.nextPollAt=n+o)}}getTaskIntervalMs(t,r){let n=OT(t),s=t.id===r.selectedTaskId&&r.reviewVisible;if(n.length>0){let o=n.some($T);return this.withMinimum(o?s?this.intervals.pendingForegroundMs:this.intervals.pendingBackgroundMs:s?this.intervals.stableForegroundMs:this.intervals.stableBackgroundMs)}return t.status!=="closed"?this.withMinimum(s?this.intervals.discoveryForegroundMs:this.intervals.discoveryBackgroundMs):null}withMinimum(t){return Math.max(t,this.minimumIntervalMs)}};function OT(e){return e.type==="project"&&e.repoTargets?.length?e.repoTargets.map(t=>t.pullRequest).filter(t=>t.status==="open"):e.prs.filter(t=>t.status==="open")}function $T(e){return e.requiredChecks.some(t=>t.status==="pending"||t.status==="unknown")}import jT from"node:path";import{readdir as NT,stat as MT}from"node:fs/promises";import Xu from"node:path";async function LT(e){let t=await NT(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=Xu.join(e,n.name);r.push({name:n.name,path:s,kind:await _T(s)?"repo":"directory"})}return r.sort((n,s)=>n.kind!==s.kind?n.kind==="repo"?-1:1:n.name.localeCompare(s.name)),{cwd:e,entries:r,selectedIndex:0,query:null,error:null}}function Qu(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function Zu(e){let{spawn:t}=await import("node:child_process"),r=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";await new Promise((n,s)=>{let o=t(r,[e],{stdio:"ignore",detached:!0});o.unref(),o.on("error",s),o.on("spawn",n)})}async function Vn(e,t){let r=await LT(t);e.state.mode==="main"&&(e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function _T(e){let t=Xu.join(e,".git");return await MT(t).catch(()=>null)!==null}function ep(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function tp(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function FT(e){if(e.state.mode!=="main"||e.creatingTask)return;let t=e.state.shell,r=t.taskPromptInput?.trim()??"";if(!t.selectedRepoId&&!t.selectedWorkspaceId){e.state={mode:"main",shell:y(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:y(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:y(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await Au(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,K(e));n=s.task,Wn(e,n);let o=y(e,{...e.state.shell,...s.nextShell,selectedLeftItemId:`task:${n.id}`,inputMode:"terminal",taskPromptInput:null,taskPromptError:null,actionMessage:null}),i=await e.ptyRuntime.ensureSession(n.id,o.selectedPtyTabId??cd(n,"agent"),ze(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ye(o.selectedPtyTabId),e.state={mode:"main",shell:Oe(o,i)},q(e,e.state.shell)}catch(s){s instanceof Vt&&(n=s.task);let o=V(e,"create task",s,"Failed to create task.");n&&!(s instanceof Vt)?(await x(e.paths,n.id,i=>({...i,status:"draft",runnerSession:{...i.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o})).catch(()=>{}),await Z(e).catch(()=>{})):n&&(await x(e.paths,n.id,i=>({...i,lastFailureReason:o})).catch(()=>{}),await Z(e).catch(()=>{})),e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,inputMode:"control",selectedTaskId:n?.id??e.state.shell.selectedTaskId,selectedPtyTabId:n?.selectedPtyTabId??e.state.shell.selectedPtyTabId,selectedLeftItemId:n?`task:${n.id}`:e.state.shell.selectedLeftItemId,activeTab:n?.selectedPtyTabId??e.state.shell.activeTab,taskPromptInput:n?null:"",taskPromptError:o,actionMessage:null}),o)}}finally{e.creatingTask=!1,e.render()}}function WT(e,t){if(e.state.mode!=="main")return;let r=e.state.shell;if(r.taskPromptInput!==null){if(t==="ESCAPE"){e.state={mode:"main",shell:y(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(he(t)){FT(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:y(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:y(e,{...r,selectedRunner:gn(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}Wc(t)&&(e.state={mode:"main",shell:y(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function qT(e,t){if(e.state.mode!=="main")return;let r=e.state.shell.workspaceBrowser;if(!r)return;if(t==="ESCAPE"){if(r.query!==null){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:"",selectedIndex:0}})},e.render();return}if(r.query!==null&&(t==="BACKSPACE"||t==="DELETE")){let s=r.query.slice(0,-1);e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}if(r.query!==null&&t.length===1&&t>=" "){let s=r.query+t;e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=Qu(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.max(0,r.selectedIndex-1),error:null}})},e.render();return}if(t==="DOWN"||t==="j"){e.state={mode:"main",shell:y(e,{...e.state.shell,workspaceBrowser:{...r,selectedIndex:Math.min(Math.max(0,n.length-1),r.selectedIndex+1),error:null}})},e.render();return}if(t==="LEFT"||t==="h"){Vn(e,jT.dirname(r.cwd)).catch(s=>{let o=V(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:o}}),o)},e.render()});return}if(t==="RIGHT"||t==="l"||he(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){Vn(e,s.path).catch(i=>{let a=V(e,"open workspace directory",i,"Failed to open directory.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:o}=K(e);o.addWorkspace(e.paths,s.path).then(async i=>{await Z(e);let a=i.repos[0]??null,l=y(e,{...e.state.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${i.workspace.id}`,selectedWorkspaceId:i.workspace.id,selectedRepoId:a?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${i.workspace.name??i.workspace.id}`});e.state={mode:"main",shell:l},q(e,e.state.shell),e.render()}).catch(i=>{let a=V(e,"add workspace",i,"Failed to add workspace.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function UT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=Kd(e.state.menuIndex,t);if(r.kind!=="noop"){if(r.kind==="render"){e.state={...e.state,menuIndex:r.menuIndex},e.render();return}if(r.kind==="back"){e.state.parentVariant&&(e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render());return}if(r.kind==="help"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell,viaOptions:!0,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="runners"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="previews"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"previews",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="error-log"){let n=e.state.parentVariant;BT(e,n)}}}async function BT(e,t){let r;try{r=await Le.readRecentErrorLines(e.paths)}catch(n){let s=V(e,"open error log",n,"Failed to read Craig error log.");r={path:e.paths.errorLogFile,lines:[`Unable to read error log: ${s}`],empty:!1}}e.state.mode==="overlay"&&(e.state={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:e.state.shell,errorLog:r,...t!==void 0?{parentVariant:t}:{}},e.pendingClear=!0,e.render())}function VT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=Hd(ep(e),e.config,t,e.enabledRunnerIds);if(r.kind==="noop")return;if(r.kind==="back"){let s=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...s!==void 0?{parentVariant:s}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="render"){e.state={...e.state,runnerOptions:r.state},e.render();return}(r.kind==="save-enabled"?$u(r.runner,r.enabled,K(e)):Nu(r.runner,r.path,K(e))).then(s=>{e.state.mode!=="overlay"||e.state.variant!=="runners"||(e.config=s,e.enabledRunnerIds=h.runners.getEnabled(e.config),e.model={...e.model,enabledRunnerIds:e.enabledRunnerIds},e.state={...e.state,shell:y(e,{...e.state.shell,selectedRunner:e.enabledRunnerIds.includes(e.state.shell.selectedRunner)?e.state.shell.selectedRunner:h.runners.getDefault(e.config)}),runnerOptions:r.state},e.render())}).catch(s=>{if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let o=V(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:B(e,y(e,e.state.shell),o),runnerOptions:{...ep(e),message:o}},e.render()})}function KT(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=Gd(tp(e),e.config,t);if(r.kind!=="noop"){if(r.kind==="back"){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}if(r.kind==="render"){e.state={...e.state,previewOptions:r.state},e.render();return}Mu(r.feature,r.enabled,K(e)).then(n=>{e.state.mode!=="overlay"||e.state.variant!=="previews"||(e.config=n,r.feature==="incrementalCenterPane"&&e.ptyRuntime.setViewUpdateMode?.(r.enabled?"incremental":"snapshot"),r.feature==="agentActivityIndicators"&&e.setAgentActivityEnabled(r.enabled),e.state={...e.state,previewOptions:r.state},e.render())}).catch(n=>{if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let s=V(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:B(e,y(e,e.state.shell),s),previewOptions:{...tp(e),message:s}},e.render()})}}function rp(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){WT(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){qT(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){HT(e),e.render();return}e.focusFlashUntil!==null&&(e.focusFlashUntil=null,e.focusFlashTimer&&(clearTimeout(e.focusFlashTimer),e.focusFlashTimer=null))}if(e.state.mode==="main"){let n=_i(e.state.shell,r,ji(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&he(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=br(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(GT(e,r))return;e.lastTerminalKey=dd(r)?{key:r,at:Date.now()}:null;let o=ud(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){Un(e,o);return}e.ptyRuntime.writeKey(r);return}if(r==="CTRL_C"){e.exit(0);return}if(r==="?"&&e.state.shell.inputMode==="control"){e.state={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:e.state.shell},e.pendingClear=!0,e.render();return}if(n.pause){e.state={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:y(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){Vn(e,e.workspaceRoot).catch(s=>{let o=V(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:B(e,y(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:o}}),o)},e.render()});return}if(n.createPtyTab){Vu(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{Ui(e,s)}).catch(s=>{let o=V(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.closePtyTab){Ku(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.refreshPullRequestChecks){Ju(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.openPrUrl){let s=Ne(e.model.tasks,n.state),o=s?E(s)?.url??null:null;o?Zu(o).catch(i=>{let a=V(e,"open PR URL",i,"Failed to open PR in browser.");e.state={mode:"main",shell:B(e,y(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:B(e,y(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){Gu(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.removeWorkspace){Hu(e,n.state).then(s=>{e.state={mode:"main",shell:s},q(e,e.state.shell),e.render()}).catch(s=>{let o=V(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:B(e,y(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.attachTerminal){Ui(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:y(e,n.state)},q(e,e.state.shell),(e.state.shell.focusedRegion!=="tasks"||!e.renderTaskNavigation())&&e.render(),e.state.shell.focusedRegion==="tasks"){Fu(e,e.state.shell);return}qn(e,e.state.shell).catch(s=>{let o=V(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:B(e,y(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}n.changed&&(e.state={mode:"main",shell:y(e,n.state)},ju(e,e.state.shell).catch(()=>{}),q(e,e.state.shell),e.render());return}if(e.state.variant==="help"){e.state.viaOptions&&e.state.parentVariant?e.state={mode:"overlay",variant:"options",menuIndex:3,optionsMessage:null,shell:e.state.shell,parentVariant:e.state.parentVariant}:e.state.parentVariant?e.state={mode:"overlay",variant:e.state.parentVariant,menuIndex:1,optionsMessage:null,shell:e.state.shell}:e.state={mode:"main",shell:y(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){UT(e,r);return}if(e.state.variant==="runners"){VT(e,r);return}if(e.state.variant==="previews"){KT(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||he(r)){let n=e.state.parentVariant;e.state={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render()}return}if(e.state.optionsMessage){(r==="ESCAPE"||he(r))&&(e.state={...e.state,optionsMessage:null},e.render());return}if(r==="UP"||r==="k"){e.state={...e.state,menuIndex:Math.max(0,e.state.menuIndex-1)},e.render();return}if(r==="DOWN"||r==="j"){e.state={...e.state,menuIndex:Math.min(2,e.state.menuIndex+1)},e.render();return}if(r==="ESCAPE"){e.state.variant==="pause"&&(e.state={mode:"main",shell:y(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(he(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:y(e,{...e.state.shell,inputMode:"control"})},e.pendingClear=!0,e.render(),n?e.bootHydrationReady.then(()=>{if(e.state.mode!=="main")return;let s=e.state.shell;Bu(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},q(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=V(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:B(e,y(e,e.state.shell),i)},q(e,e.state.shell),e.render()})}):Uu(e);return}if(e.state.menuIndex===1){let n=e.state.variant==="boot"||e.state.variant==="pause"?e.state.variant:void 0;e.state={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:e.state.shell,...n!==void 0?{parentVariant:n}:{}},e.pendingClear=!0,e.render();return}e.exit(0)}}function np(e,t){let r=hd(t);if(e.state.mode!=="main"||e.state.shell.inputMode!=="terminal"||r.length===0)return;if(e.pendingTerminalKeySequence){let o=`${e.pendingTerminalKeySequence.raw}${r}`,i=br(o);if(i){op(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(li(o)){e.pendingTerminalKeySequence.raw=o,sp(e);return}Kn(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:y(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},q(e,e.state.shell),e.render();return}let n=pd(r);if(n!==0){Un(e,n);return}let s=br(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
136
136
  `&&r!==`\r
137
137
  `&&(e.suppressTerminalEnterOnAttach=!1),gd(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function GT(e,t){if(e.pendingTerminalKeySequence){let r=md(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=br(n);if(s)return op(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(li(n))return e.pendingTerminalKeySequence.raw=n,sp(e),!0}return Kn(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>Kn(e),30)},!0)}function sp(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>Kn(e),30))}function Kn(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function op(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function ip(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){Wu(e,ai(t));return}let r=ai(t);r!==0&&Un(e,r)}function HT(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var ap=1e3,YT=zT(import.meta.url),JT=YT("terminal-kit"),XT=JT.terminal;function Bi(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function lp(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function QT(e,t){return e?e.tabId!==t.tabId?{tabId:t.tabId,kind:"full"}:e.kind==="full"||t.kind==="full"?{tabId:t.tabId,kind:"full"}:{tabId:t.tabId,kind:"rows",rowIndices:[...new Set([...e.rowIndices,...t.rowIndices])]}:t}async function cp(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=re(t),n=await h.load(r),s=h.runners.getEnabled(n),o=e.uiStateFile?await yt({uiStateFile:e.uiStateFile}):null,i=await qt(t,void 0,s),a=kr(Lc(o,n),i);i=await qt(t,a,s);let l={current:i},c=()=>{},d=()=>{},u=()=>{},m={workspaceRoot:t,onUpdate:k=>c(k),onActivity:k=>d(k),onActivityRemoved:k=>u(k),resolveSessionSpec:(k,w)=>ld(l.current,w,t)},p=e.ptyRuntime??await Dd({...m,paths:r,viewUpdateMode:h.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot",activityEnabled:h.previews.isEnabled(n,"agentActivityIndicators")});return new Promise(k=>{let w=e.terminal??XT,b=null,N=null,_=null,Y=null,I=null,ce=0,me=!1,de=new Map,wt=new Bn({minimumIntervalMs:(n.github?.watchIntervalSeconds??5)*1e3}),g,Xe=new Bt({resolutionMs:h.previews.isEnabled(n,"agentActivityIndicators")?Mn:ap,onError:(T,j)=>Fn(`heartbeat job "${T}"`,j,K(g))});g={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:kr(a,i)},get model(){return l.current},set model(T){l.current=T},config:n,enabledRunnerIds:s,creatingTask:!1,suppressTerminalEnterOnAttach:!1,lastTerminalKey:null,pendingScrollLines:0,pendingInspectionScrollLines:0,leftNavInspectionTimer:null,pendingLeftNavInspectionShell:null,pendingTerminalKeySequence:null,scrollRenderTimer:null,inspectionScrollRenderTimer:null,ptyRenderTimer:null,footerToastTimer:null,focusFlashUntil:null,focusFlashTimer:null,lastBackgroundPrPollError:null,versionText:`Craig v${h.version.getCurrent()}`,updateText:null,inspectionRefreshSequence:0,pendingClear:!0,inputCaptureMode:null,runtimeState:o,persistQueue:Promise.resolve(),taskMutationQueue:Promise.resolve(),bootHydrationReady:Promise.resolve(),paths:r,workspaceRoot:t,uiStateFile:e.uiStateFile,activeTerminal:w,ptyRuntime:p,resolve:k,render:()=>{},renderTaskNavigation:()=>!1,exit:T=>k(T),setAgentActivityEnabled:T=>{Xe.setResolutionMs(T?Mn:ap),g.ptyRuntime.setActivityEnabled?.(T)}},g.setAgentActivityEnabled(h.previews.isEnabled(n,"agentActivityIndicators")),c=T=>{g.state.mode==="main"&&(I=QT(I,T),g.ptyRenderTimer||(g.ptyRenderTimer=setTimeout(()=>{g.ptyRenderTimer=null;let j=I;if(I=null,g.state.mode==="main"){let ee=ht(g,g.state.shell);if(g.state={mode:"main",shell:ee},!h.previews.isEnabled(g.config,"incrementalCenterPane")||!Y||!N){g.render();return}let te=le(w.width,w.height),Gt={...Y,terminal:ee.terminal},Ze=hu(te,Gt,N,ee.centerZoomed,j?.kind==="rows"?j.rowIndices:null);if(!Ze){g.render();return}Ze.output.length>0&&w.noFormat(Ze.output),Y=Gt,N=Ze.region,_&&(_={..._,center:Ze.region}),b=null,w.hideCursor(!0)}},h.previews.isEnabled(g.config,"incrementalCenterPane")?0:50)))},d=T=>{g.state.mode==="main"&&h.previews.isEnabled(g.config,"agentActivityIndicators")&&Ye(T.tabId)&&de.get(T.tabId)!==ct(T.tabId,[T],Date.now())&&g.render()},u=T=>{g.state.mode==="main"&&h.previews.isEnabled(g.config,"agentActivityIndicators")&&Ye(T)&&de.get(T)!=="idle"&&g.render()};let Pe=T=>{let j=le(w.width,w.height),ee=h.previews.isEnabled(g.config,"agentActivityIndicators"),fe=ee?g.ptyRuntime.getActivitySnapshots?.()??[]:[],te=Date.now(),Gt=ou(y(g,T.shell),g.model,ee?{snapshots:fe,now:te,animationFrame:ce}:void 0);if(de.clear(),ee)for(let up of g.model.tasks)for(let Gn of up.ptyTabs)Gn.kind==="agent"&&de.set(Gn.id,ct(Gn.id,fe,te));let Ze=Qc(j,Gt,{centerOnly:T.shell.centerZoomed,focusFlashActive:g.focusFlashUntil!==null&&Date.now()<g.focusFlashUntil});return{data:Gt,presentation:Ze}},Qe=(T,j,ee,fe)=>{if(!_)return!1;let te=wu(_,j.regions,ee);return te?(te.output.length>0&&w.noFormat(te.output),Y=T,_=te.regions,N=te.regions.center,b=fe?j.frame:null,w.hideCursor(!0),!0):!1};g.renderTaskNavigation=()=>{if(g.state.mode!=="main"||g.pendingClear||!h.previews.isEnabled(g.config,"incrementalCenterPane"))return!1;qi(g),g.ptyRuntime.setViewedTab?.(Kt(g,g.state.shell));let{data:T,presentation:j}=Pe(g.state);return Qe(T,j,["rail","left","center","footer"],!1)},g.render=()=>{qi(g);let T=g.state;g.ptyRuntime.setViewedTab?.(T.mode==="main"?Kt(g,T.shell):null);let j=le(w.width,w.height),ee,fe=null;if(T.mode==="main"){let te=Pe(T);if(fe=te.presentation,ee=fe.frame,h.previews.isEnabled(g.config,"incrementalCenterPane")&&!g.pendingClear&&Qe(te.data,fe,["rail","left","center","right","footer"],!0))return;Y=te.data,N=fe.center}else ee=T.variant==="boot"?zc(j,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:g.versionText,updateText:g.updateText}):T.variant==="pause"?Yc(j,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:g.versionText,updateText:g.updateText}):T.variant==="options"?vn(j,{menuIndex:T.menuIndex,optionsMenuItems:Ri}):T.variant==="runners"?vn(j,{menuIndex:Bi(T).menuIndex,optionsMenuItems:bi(g.config,Bi(T)),optionsMessage:Ud(Bi(T)),optionsSubtitle:"Runners"}):T.variant==="previews"?vn(j,{menuIndex:lp(T).menuIndex,optionsMenuItems:Bd(g.config),optionsMessage:Vd(lp(T)),optionsSubtitle:"Feature Previews - Experimental"}):T.variant==="error-log"?Xc(j,{errorLogPath:T.errorLog?.path??r.errorLogFile,errorLogLines:T.errorLog?.lines??[]}):Jc(j),Y=null,N=null,_=null;g.pendingClear&&(w.moveTo(1,1),w.eraseDisplayBelow(),g.pendingClear=!1,b=null),w.noFormat(wd(ee,b)),b=ee,_=fe?.regions??null,w.hideCursor(!0)};let vr=T=>rp(g,T),Ir=T=>np(g,T),Cr=T=>ip(g,T),dp=()=>{process.stdout.off("resize",Vi),process.off("SIGCONT",Ki),w.removeListener("key",vr),w.removeListener("unknown",Ir),w.removeListener("mouse",Cr),g.scrollRenderTimer&&(clearTimeout(g.scrollRenderTimer),g.scrollRenderTimer=null),g.inspectionScrollRenderTimer&&(clearTimeout(g.inspectionScrollRenderTimer),g.inspectionScrollRenderTimer=null),g.leftNavInspectionTimer&&(clearTimeout(g.leftNavInspectionTimer),g.leftNavInspectionTimer=null),g.pendingTerminalKeySequence&&(clearTimeout(g.pendingTerminalKeySequence.timer),g.pendingTerminalKeySequence=null),g.ptyRenderTimer&&(clearTimeout(g.ptyRenderTimer),g.ptyRenderTimer=null),g.footerToastTimer&&(clearTimeout(g.footerToastTimer),g.footerToastTimer=null),g.focusFlashTimer&&(clearTimeout(g.focusFlashTimer),g.focusFlashTimer=null),Xe.stop(),g.ptyRuntime.disposeAll(),w.grabInput(!1),w.hideCursor(!1),w.fullscreen(!1)};g.exit=T=>{dp(),k(T)};let Vi=()=>{Fi(g),g.state.mode==="main"&&g.state.shell.inputMode==="terminal"&&(g.ptyRuntime.resize(ze(le(w.width,w.height))),g.state={mode:"main",shell:ht(g,g.state.shell)}),g.render()},Ki=()=>{Fi(g),g.state.mode==="main"&&g.state.shell.inputMode==="terminal"&&(g.ptyRuntime.resize(ze(le(w.width,w.height))),g.state={mode:"main",shell:ht(g,g.state.shell)}),g.render()};process.stdout.on("resize",Vi),process.on("SIGCONT",Ki),w.grabInput(!0),g.inputCaptureMode="control",w.hideCursor(!0),w.fullscreen(!0),w.on("key",vr),w.on("unknown",Ir),w.on("mouse",Cr),Xe.register({id:"github.pull-requests",intervalMs:1e3,run:T=>Yu(g,wt,T)}),Xe.register({id:"agent.activity-indicators",intervalMs:Mn,run:()=>{if(!h.previews.isEnabled(g.config,"agentActivityIndicators")){ce=0,me=!1;return}let T=Date.now(),j=tn(g.model.tasks,g.ptyRuntime.getActivitySnapshots?.()??[],T);(j||me)&&(ce=(ce+1)%tu,g.state.mode==="main"&&g.render()),me=j}}),Xe.start(),h.version.checkForUpdate().then(T=>{T.updateAvailable&&T.latest&&(g.updateText=`Update available: v${T.latest}`,g.render())}),g.bootHydrationReady=Wi(g).catch(()=>{}),g.render()})}async function ZT(){try{if(process.argv[2]==="__craig-daemon"){let e=process.argv[3]??process.cwd(),t=re(e);return await Od(t),0}if(process.argv[2]==="__craig-daemon-shutdown"){let e=process.argv[3]??process.cwd(),t=re(e);return await $d(t),0}}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
138
138
  `),1}return yc({argv:process.argv.slice(2),cwd:process.cwd(),env:process.env,isInputTty:process.stdin.isTTY===!0,isOutputTty:process.stdout.isTTY===!0,writeStdout:e=>process.stdout.write(e),writeStderr:e=>process.stderr.write(e),readStdin:async()=>{let e="";process.stdin.setEncoding("utf8");for await(let t of process.stdin)e+=t;return e},runInteractive:e=>cp({uiStateFile:re(e).uiStateFile,workspaceRoot:e})})}var eR=await ZT();process.exit(eR);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "craig-cli",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "description": "Craig local control plane CLI",
5
5
  "license": "MIT",
6
6
  "keywords": [