craig-cli 0.8.6 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cli.js +50 -94
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,37 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await
|
|
4
|
-
`)};var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`+G());return{mode:"command",command:{kind:"addWorkspace",path:r}}}if(t.length===2&&t[0]==="repo"&&t[1]==="list")return{mode:"command",command:{kind:"listRepos"}};if(t.length===3&&t[0]==="repo"&&t[1]==="remove")return{mode:"command",command:{kind:"removeRepo",repoId:t[2].trim()}};if(t.length>=2&&t.length<=3&&t[0]==="workspace"&&t[1]==="list"){let r=t[2]==="--archived";if(t.length===3&&!r)throw new Error(`Unsupported command: ${t.join(" ")}
|
|
9
|
-
|
|
10
|
-
${G()}`);return{mode:"command",command:{kind:"listWorkspaces",archived:r}}}if(t.length===3&&t[0]==="workspace"&&t[1]==="archive")return{mode:"command",command:{kind:"archiveWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="restore")return{mode:"command",command:{kind:"restoreWorkspace",workspaceId:t[2].trim()}};if(t.length===3&&t[0]==="workspace"&&t[1]==="remove")return{mode:"command",command:{kind:"removeWorkspace",workspaceId:t[2].trim()}};if(t.length>=2&&t[0]==="task"&&t[1]==="new"){let r=t.indexOf("--repo"),n=t.indexOf("--workspace"),s=t.indexOf("--runner");if(r===-1&&n===-1)throw new Error(`Task creation now requires '--repo <repo-id>' or '--workspace <workspace-id>'.
|
|
11
|
-
|
|
12
|
-
`+G());if(r!==-1&&n!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
|
|
13
|
-
|
|
14
|
-
`+G());let o=r===-1?void 0:t[r+1]?.trim()??"",i=n===-1?void 0:t[n+1]?.trim()??"",a=s===-1?void 0:f.runners.parse(t[s+1]?.trim()??""),d=t.filter((c,u)=>u>1&&u!==r&&u!==r+1&&u!==n&&u!==n+1&&u!==s&&u!==s+1).join(" ").trim();if(o!==void 0&&o.length===0)throw new Error(`Repo id cannot be empty.
|
|
15
|
-
|
|
16
|
-
`+G());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
|
|
17
|
-
|
|
18
|
-
`+G());if(d.length===0)throw new Error(`Task prompt cannot be empty.
|
|
19
|
-
|
|
20
|
-
`+G());return{mode:"command",command:{kind:"createTask",...o?{repoId:o}:{},...i?{workspaceId:i}:{},prompt:d,...a?{runner:a}:{}}}}if(t.length>=2&&t.length<=4&&t[0]==="task"&&t[1]==="list"){if(t.length===2)return{mode:"command",command:{kind:"listTasks"}};if(t.length===4&&t[2]==="--repo")return{mode:"command",command:{kind:"listTasks",repoId:t[3].trim()}};throw new Error(`Unsupported command: ${t.join(" ")}
|
|
21
|
-
|
|
22
|
-
${G()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:ce(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:ce(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:ce(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:ce(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:ce(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:ce(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:ce(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:ce(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:ce(t[2]),repoId:Ic(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:ce(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
|
|
23
|
-
|
|
24
|
-
${G()}`)}function G(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
|
|
25
|
-
`)}function ce(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
|
|
2
|
+
var Kc=Object.defineProperty;var Yt=(e,t)=>{for(var r in t)Kc(e,r,{get:t[r],enumerable:!0})};import Z from"node:path";function ee(e){let t=Z.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:Z.join(t,"index.json"),reposDir:Z.join(t,"repos"),workspacesDir:Z.join(t,"workspaces"),sessionsDir:Z.join(t,"sessions"),runtimeDir:Z.join(t,"runtime"),uiStateFile:Z.join(t,"runtime","ui-state.json"),tasksDir:Z.join(t,"tasks"),jobsDir:Z.join(t,"jobs"),logsDir:Z.join(t,"logs"),errorLogFile:Z.join(t,"logs","errors.log"),artifactsDir:Z.join(t,"artifacts"),worktreesDir:Z.join(t,"worktrees"),configFile:Z.join(t,"config.json")}}import{readFile as Qc}from"node:fs/promises";import{randomUUID as Gc}from"node:crypto";import{open as Hc,readFile as Sh,rename as zc,rm as Yc}from"node:fs/promises";import zr from"node:path";async function U(e,t){let r=zr.dirname(e),n=zr.join(r,`.${zr.basename(e)}.${process.pid}.${Date.now()}.${Gc()}.tmp`),s=await Hc(n,"w");try{let o=`${JSON.stringify(t,null,2)}
|
|
3
|
+
`;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await zc(n,e)}catch(o){throw await s.close().catch(()=>{}),await Yc(n,{force:!0}).catch(()=>{}),o}}async function Ze(e){try{let t=await Qc(e.uiStateFile,"utf8"),r=JSON.parse(t);return Jc(r,e.uiStateFile)}catch(t){if(Zc(t))return null;throw t}}async function Ce(e,t){await U(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Jt(){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 Jc(e,t){if(typeof e!="object"||e===null||e.version!==1||!(e.selectedRepoId===null||typeof e.selectedRepoId=="string")||!(e.selectedWorkspaceId===null||typeof e.selectedWorkspaceId=="string")||!(e.selectedTaskId===null||typeof e.selectedTaskId=="string")||!(e.selectedPtyTabId===void 0||e.selectedPtyTabId===null||typeof e.selectedPtyTabId=="string")||!Xe(e,"inputMode")||!Xe(e,"focusedRegion")||!Xe(e,"activeTab")||!Xe(e,"inspectorSection")||!Xe(e,"inspectionMode")||!Qt(e,"openInspectionKind")||!Qt(e,"selectedFileTreePath")||!Qt(e,"selectedFilePath")||!Qt(e,"selectedDiffPath")||!Xc(e,"collapsedFileTreePaths")||!Xe(e,"selectedActionId")||typeof e.updatedAt!="string")throw new Error(`Craig UI state at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e}function Xe(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Qt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Xc(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function Zc(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var Yr={};Yt(Yr,{RUNNER_IDS:()=>O,assertEnabled:()=>po,buildCommand:()=>go,getConfiguredProfile:()=>Xt,getDefault:()=>uo,getDisplayName:()=>fo,getEnabled:()=>Zt,getProfile:()=>et,isRunnerType:()=>er,parse:()=>mo,setRunnerEnabled:()=>ho,setRunnerPath:()=>ko});var O=["codex","cursor","claude"];var co={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 et=e=>co[e];var Xt=(e,t={})=>{let r=et(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var Zt=(e={})=>O.filter(t=>e.runners?.[t]?.enabled!==!1);var uo=(e={})=>{let t=Zt(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 po=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var er=e=>O.includes(e);var mo=e=>{if(!e||e.length===0)return"codex";if(!er(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${O.join(", ")}.`);return e};var fo=e=>et(e).displayName;var go=(e,t,r={})=>{let n=[Xt(e,r).executable];return t&&t.length>0&&n.push(t),n};var ho=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var ko=(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 Qr={};Yt(Qr,{PREVIEW_FEATURE_IDS:()=>ue,isEnabled:()=>wo,setEnabled:()=>To});var ue=["incrementalCenterPane","agentActivityIndicators"];function wo(e,t){return e.previews?.[t]===!0}function To(e,t,r){return{...e,previews:{...e.previews,[t]:r}}}import{mkdir as ed,readFile as td,writeFile as rd}from"node:fs/promises";import nd from"node:path";var sd=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Ro=async e=>{try{return await td(e,"utf8")}catch(t){if(sd(t))return null;throw t}},yo=async(e,t)=>{await ed(nd.dirname(e),{recursive:!0}),await rd(e,t,"utf8")};var tr=(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(!O.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${O.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(!ue.includes(n))throw new Error(`Craig config at ${t} is invalid. "previews.${n}" is not supported. Expected one of: ${ue.join(", ")}.`);if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${n}" must be a boolean.`)}}return r};var Jr=async(e,t={readConfigFile:Ro})=>{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 tr(n,e.configFile)};var Xr=async(e,t,r={writeConfigFile:yo})=>{tr(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
|
|
4
|
+
`)};var Zr={};Yt(Zr,{checkForUpdate:()=>bo,getCurrent:()=>rr});var rr=()=>{try{return"0.9.0"}catch{return"unknown"}};var od="https://registry.npmjs.org/craig-cli/latest",id=3600*1e3,ad={value:null},ld=(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},bo=async(e={fetch:globalThis.fetch,getCurrent:rr,cache:ad})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<id)return e.cache.value.result;let n=null;try{let o=await e.fetch(od,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&ld(n,t)};return e.cache.value={result:s,cachedAt:r},s};var f={load:Jr,save:Xr,previews:Qr,runners:Yr,version:Zr};var Po={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,EXTERNAL_DEPENDENCY_FAILED:5,OPERATION_TIMEOUT:6,PARTIAL_RESULT:7,INTERNAL_ERROR:1},S=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=Po[t],this.retryable=n.retryable??!1,this.details=n.details??{}}};function en(e){return e instanceof S?e:new S("INTERNAL_ERROR",e instanceof Error?e.message:"Unknown Craig error",{cause:e})}import{appendFile as cd,mkdir as dd,readFile as ud}from"node:fs/promises";import pd from"node:path";var So=80,tn=async(e,t)=>{await dd(pd.dirname(e.errorLogFile),{recursive:!0}),await cd(e.errorLogFile,md(t),"utf8")},Io=async(e,t)=>{try{await tn(e,t)}catch{}},rn=async(e,t=So)=>{try{let n=(await ud(e.errorLogFile,"utf8")).trimEnd().split(`
|
|
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(fd(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},Co=async(e,t=So)=>rn(e,t);function md(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
|
+
`).map(n=>` ${n}`))),`${r.join(`
|
|
7
|
+
`)}
|
|
26
8
|
|
|
27
|
-
|
|
9
|
+
`}function fd(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var tt={appendErrorLog:tn,appendErrorLogBestEffort:Io,readErrorLog:rn,readRecentErrorLines:Co};function Do(e){let{commandTokens:t,options:r,help:n}=hd(e);if(n)return vo({kind:"help"},r);if(t.length===0)return{mode:"interactive",options:r};let[s,o,...i]=t,a;switch(`${s??""}:${o??""}`){case"context:show":nn(i,"context show"),a={kind:"showContext"};break;case"repo:add":a={kind:"addRepo",path:Ao(i,"Repo path")};break;case"repo:list":nn(i,"repo list"),a={kind:"listRepos"};break;case"repo:remove":a={kind:"removeRepo",repoId:oe(i,"Repo id")};break;case"workspace:add":a={kind:"addWorkspace",path:Ao(i,"Workspace path")};break;case"workspace:list":a=kd(i);break;case"workspace:archive":a={kind:"archiveWorkspace",workspaceId:oe(i,"Workspace id")};break;case"workspace:restore":a={kind:"restoreWorkspace",workspaceId:oe(i,"Workspace id")};break;case"workspace:remove":a={kind:"removeWorkspace",workspaceId:oe(i,"Workspace id")};break;case"task:new":a=Td(i);break;case"task:list":a=wd(i);break;case"task:current":nn(i,"task current"),a={kind:"currentTask"};break;case"task:show":a=i.length===0?{kind:"showCurrentTask"}:{kind:"showTask",taskId:oe(i,"Task id")};break;case"task:attach":a={kind:"attachTask",taskId:oe(i,"Task id")};break;case"task:logs":a={kind:"streamTaskLogs",taskId:oe(i,"Task id")};break;case"task:diff":a={kind:"showTaskDiff",taskId:oe(i,"Task id")};break;case"task:focus":a={kind:"focusTask",taskId:oe(i,"Task id")};break;case"task:open":a={kind:"openTask",taskId:oe(i,"Task id")};break;case"task:check":a={kind:"runChecks",taskId:oe(i,"Task id")};break;case"task:commit":a={kind:"commitTask",taskId:oe(i,"Task id")};break;case"link:add":a={kind:"addTaskLink",taskId:xo(i,0,"Task id"),repoId:xo(i,1,"Repo id")},Oo(i,2,"link add");break;case"link:list":a={kind:"listTaskLinks",taskId:oe(i,"Task id")};break;default:if(t.length===1&&(s==="help"||s==="--help"||s==="-h")){a={kind:"help"};break}throw G(`Unsupported command: ${t.join(" ")}`)}return vo(a,r)}function $o(e){let t=e[0]==="--"?e.slice(1):e,r=!0;for(let n of t){if(n==="--"){r=!1;continue}if(r&&n==="--json")return!0}return!1}function gd(e){return{addWorkspace:"workspace.add",addRepo:"repo.add",listRepos:"repo.list",removeRepo:"repo.remove",listWorkspaces:"workspace.list",archiveWorkspace:"workspace.archive",restoreWorkspace:"workspace.restore",removeWorkspace:"workspace.remove",createTask:"task.new",listTasks:"task.list",currentTask:"task.current",showTask:"task.show",showCurrentTask:"task.show",attachTask:"task.attach",addTaskLink:"link.add",listTaskLinks:"link.list",refreshInteractiveState:"interactive.refresh",showSelectedTask:"task.show",streamTaskLogs:"task.logs",streamSelectedTaskLogs:"task.logs",showTaskDiff:"task.diff",showSelectedTaskDiff:"task.diff",focusTask:"task.focus",focusSelectedTask:"task.focus",openTask:"task.open",openSelectedTask:"task.open",runChecks:"task.check",runSelectedTaskChecks:"task.check",commitTask:"task.commit",commitSelectedTask:"task.commit",showContext:"context.show",help:"help",exit:"exit"}[e.kind]}function sn(){return["Craig commands:"," craig [--workspace-root <path>] [--task <id>] [--json] [--no-input] <command>"," craig context show Show resolved workspace, task, and agent-tab context"," craig repo add <path> Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove <id> Remove a registered repo"," craig workspace list [--archived] List workspaces"," craig workspace archive <id> Archive a workspace"," craig workspace restore <id> Restore an archived workspace"," craig workspace remove <id> Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt>"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt>"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task current Show the task resolved from flags, environment, or cwd"," craig task show [<id>] Show task details; omit id to use resolved context"," craig task logs <id> Stream Craig-managed logs for a task"," craig task diff <id> Show the current worktree diff for a task"," craig task attach <id> Attach to a live task session"," craig task focus <id> Focus the tmux pane for a task"," craig task open <id> Open the task worktree or print its path"," craig task check <id> Run configured checks for a task"," craig task commit <id> Commit all task worktree changes"," craig link add <task-id> <repo-id> Add a linked repo to a task"," craig link list <task-id> List linked repos for a task"].join(`
|
|
10
|
+
`)}function hd(e){let t=[...e];t[0]==="--"&&t.shift();let r=[],n={json:!1,noInput:!1},s=new Set,o=!1,i=!0;for(let a=0;a<t.length;a+=1){let l=t[a];if(l==="--"){i=!1,r.push(l);continue}if(!i||!Eo(l)){r.push(l);continue}if(s.has(l))throw G(`Global option ${l} may only be provided once.`);if(s.add(l),l==="--json"){n.json=!0;continue}if(l==="--no-input"){n.noInput=!0;continue}if(l==="--help"||l==="-h"){o=!0;continue}let c=t[a+1];if(c===void 0||c==="--"||Eo(c))throw G(`Global option ${l} requires a value.`);a+=1,l==="--workspace-root"?n.workspaceRoot=Re(c,"Workspace root"):n.taskId=Re(c,"Task id")}return{commandTokens:r,options:n,help:o}}function kd(e){if(e.length===0)return{kind:"listWorkspaces",archived:!1};if(e.length===1&&e[0]==="--archived")return{kind:"listWorkspaces",archived:!0};throw G(`Unsupported command: workspace list ${e.join(" ")}`)}function wd(e){if(e.length===0)return{kind:"listTasks"};if(e.length===2&&e[0]==="--repo")return{kind:"listTasks",repoId:Re(e[1],"Repo id")};throw G(`Unsupported command: task list ${e.join(" ")}`)}function Td(e){let t,r,n,s=[],o=!0;for(let a=0;a<e.length;a+=1){let l=e[a];if(l==="--"){o=!1;continue}if(!o||!["--repo","--workspace","--runner"].includes(l)){if(o&&l.startsWith("--"))throw G(`Unsupported task new option: ${l}`);s.push(l);continue}let c=e[a+1];if(c===void 0||c==="--")throw G(`Task option ${l} requires a value.`);if(a+=1,l==="--repo"){if(t!==void 0)throw G("Task option --repo may only be provided once.");t=Re(c,"Repo id")}else if(l==="--workspace"){if(r!==void 0)throw G("Task option --workspace may only be provided once.");r=Re(c,"Workspace id")}else{if(n!==void 0)throw G("Task option --runner may only be provided once.");try{n=f.runners.parse(c)}catch(d){throw G(d instanceof Error?d.message:"Unsupported runner.")}}}if(!t&&!r)throw G("Task creation requires '--repo <repo-id>' or '--workspace <workspace-id>'.");if(t&&r)throw G("Task creation accepts either '--repo' or '--workspace', not both.");let i=Re(s.join(" "),"Task prompt");return{kind:"createTask",...t?{repoId:t}:{},...r?{workspaceId:r}:{},...n?{runner:n}:{},prompt:i}}function vo(e,t){return{mode:"command",command:e,commandName:gd(e),options:t}}function Eo(e){return["--json","--no-input","--workspace-root","--task","--help","-h"].includes(e)}function nn(e,t){Oo(e,0,t)}function Oo(e,t,r){if(e.length!==t)throw G(`Command ${r} received an unexpected number of arguments.`)}function oe(e,t){if(e.length!==1)throw G(`${t} is required and must be provided once.`);return Re(e[0],t)}function Ao(e,t){return Re(e.join(" "),t)}function xo(e,t,r){return Re(e[t]??"",r)}function Re(e,t){let r=e.trim();if(r.length===0)throw G(`${t} cannot be empty.`);return r}function G(e){return new S("CLI_USAGE",`${e}
|
|
28
11
|
|
|
29
|
-
${G()}`);return t}var U=(e,t)=>{let r=_r(e);if(!Cc(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},_r=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Ur(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[],ptyTabs:xc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:Ec(t.repoTargets),runnerSession:t.runnerSession??vc(t),checks:Fc(t),lastCommit:t.lastCommit??null,prs:Nc(t),artifacts:Bc(t),cleanup:qc(t)}},vc=e=>{if(typeof e.title!="string")return null;let t=Ur(e.runner);return{command:f.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},Cc=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&f.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(r=>typeof r=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&oo(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||Ac(t.repoTargets))&&$c(t.runnerSession)&&Mc(t.prompt)&&io(t.checks)&&ao(t.lastCommit)&&Oc(t.prs)&&jc(t.artifacts)&&co(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Ec=e=>{if(Array.isArray(e))return e.filter(so)},Ac=e=>Array.isArray(e)&&e.every(so),so=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&io(t.checks)&&ao(t.lastCommit)&&lo(t.pullRequest)&&co(t.cleanup)},xc=e=>{if(oo(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return Dc(e.id,e.title,t,Ur(e.runner))},Dc=(e,t,r,n)=>{let s=f.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:f.runners.buildCommand(n),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},Ur=e=>e&&f.runners.isRunnerType(e)?e:"codex",oo=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"),$c=e=>typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null),Mc=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",io=e=>typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number"),ao=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",lo=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&Lc(e.requiredChecks),Lc=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null)),Oc=e=>Array.isArray(e)&&e.every(lo),jc=e=>typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null),co=e=>typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null),Fc=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},Nc=e=>{if(Array.isArray(e.prs))return e.prs.map(Wc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:uo(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:po(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},Wc=e=>{let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:uo(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:_c(t.reviewDecision),requiredChecks:po(t.requiredChecks),comments:Uc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},uo=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,_c=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Uc=e=>Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let r=t;return typeof r.body!="string"||!r.body.trim()?[]:[{author:typeof r.author=="string"?r.author:null,body:r.body,createdAt:typeof r.createdAt=="string"?r.createdAt:null,url:typeof r.url=="string"?r.url:null}]}):[],po=e=>Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[],Bc=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},qc=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as pd}from"node:fs/promises";import{readFile as Vc,readdir as Kc,rm as Hc}from"node:fs/promises";import mo from"node:path";var Br=(e,t)=>mo.join(e.workspacesDir,`${t}.json`),Gc=e=>{if(typeof e!="object"||e===null)return e;let t=e,r=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??r??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??r??"",repoId:t.kind==="project"?t.repoId:r,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(n=>typeof n=="string"):t.kind==="project"?[]:r?[r]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[]}},fo=(e,t)=>{let r=Gc(e);if(typeof r!="object"||r===null||typeof r.id!="string"||r.kind!=="repo"&&r.kind!=="project"||typeof r.name!="string"||typeof r.rootPath!="string"||typeof r.primaryRepoId!="string"||typeof r.branch!="string"||r.status!=="active"&&r.status!=="archived"||!Array.isArray(r.linkedRepoIds)||!(r.linkedRepoIds??[]).every(n=>typeof n=="string")||!(r.repoId===void 0||typeof r.repoId=="string")||!Array.isArray(r.discoveredRepoIds)||!(r.discoveredRepoIds??[]).every(n=>typeof n=="string")||!(r.archivedAt===null||typeof r.archivedAt=="string")||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},De=async(e,t)=>{let r=Br(e,t),n=await Vc(r,"utf8");return fo(JSON.parse(n),r)},$e=async(e,t)=>{await N(Br(e,t.id),{...t,updatedAt:new Date().toISOString()})},Z=async e=>{let t=await Kc(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>De(e,mo.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},go=async(e,t)=>{await Hc(Br(e,t),{force:!0})};import{readFile as zc,readdir as Yc,rm as Qc}from"node:fs/promises";import ho from"node:path";var qr=(e,t)=>ho.join(e.reposDir,`${t}.json`),wo=(e,t)=>{if(typeof e!="object"||e===null||typeof e.id!="string"||typeof e.name!="string"||typeof e.rootPath!="string"||typeof e.defaultBranch!="string"||typeof e.createdAt!="string"||typeof e.updatedAt!="string")throw new Error(`Craig repo record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e},ne=async(e,t)=>{let r=qr(e,t),n=await zc(r,"utf8");return wo(JSON.parse(n),r)},Vr=async(e,t)=>{await N(qr(e,t.id),{...t,updatedAt:new Date().toISOString()})},dt=async e=>{let t=await Yc(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>ne(e,ho.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},ko=async(e,t)=>{await Qc(qr(e,t),{force:!0})};import{readFile as Jc}from"node:fs/promises";var Xc=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(r=>typeof r=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(r=>typeof r=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(r=>typeof r=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Gt=(e,t,r)=>{if(!Xc(e))throw new Error(`Craig index at ${r} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${r} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e},z=async e=>{let t=await Jc(e.indexFile,"utf8");return Gt(JSON.parse(t),e.workspaceRoot,e.indexFile)},fe=async(e,t)=>{await N(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as nd,stat as sd}from"node:fs/promises";import Ye from"node:path";import{realpath as Ro}from"node:fs/promises";import bo from"node:path";import{execFile as Zc}from"node:child_process";import{promisify as ed}from"node:util";var yo=ed(Zc);async function P(e,t,r={}){try{let n=await yo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(To(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function x(e,t,r={}){try{let n=await yo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(To(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function To(e){return e instanceof Error}var Kr=async e=>{try{let r=(await P("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([Ro(r).catch(()=>bo.resolve(r)),Ro(e).catch(()=>bo.resolve(e))]);return n===s}catch{return!1}},Hr=async e=>{let t=await x("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),r=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&r.length>0)return r;for(let o of["main","master","trunk"])if((await x("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await P("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as ue,readFile as td}from"node:fs/promises";import Y from"node:path";function de(e){let t=Y.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:Y.join(t,"index.json"),reposDir:Y.join(t,"repos"),workspacesDir:Y.join(t,"workspaces"),sessionsDir:Y.join(t,"sessions"),runtimeDir:Y.join(t,"runtime"),uiStateFile:Y.join(t,"runtime","ui-state.json"),tasksDir:Y.join(t,"tasks"),jobsDir:Y.join(t,"jobs"),logsDir:Y.join(t,"logs"),errorLogFile:Y.join(t,"logs","errors.log"),artifactsDir:Y.join(t,"artifacts"),worktreesDir:Y.join(t,"worktrees"),configFile:Y.join(t,"config.json")}}var rd=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",ze=async e=>{let t=de(e);await ue(t.craigDir,{recursive:!0}),await Promise.all([ue(t.reposDir,{recursive:!0}),ue(t.workspacesDir,{recursive:!0}),ue(t.sessionsDir,{recursive:!0}),ue(t.runtimeDir,{recursive:!0}),ue(t.tasksDir,{recursive:!0}),ue(t.jobsDir,{recursive:!0}),ue(t.logsDir,{recursive:!0}),ue(t.artifactsDir,{recursive:!0}),ue(t.worktreesDir,{recursive:!0})]);try{let s=await td(t.indexFile,"utf8"),o=JSON.parse(s);return Gt(o,e,t.indexFile)}catch(s){if(!rd(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let r=new Date().toISOString(),n={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:r,updatedAt:r};return await N(t.indexFile,n),n};var Po=(e,t,r)=>{let n=new Date().toISOString();return{id:od(e,Ye.basename(t)),name:Ye.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},So=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},od=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",n=`repo_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`repo_${r}_${s}`,s+=1;return n},id=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",n=`workspace_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`workspace_${r}_${s}`,s+=1;return n},Io=async(e,t)=>{let r=await z(e);await fe(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},ad=async(e,t)=>{let r=await nd(t,{withFileTypes:!0}),n=await dt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=Ye.join(t,o.name);if(!await Kr(i))continue;let a=n.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await Hr(i);s.push(a?So(a,l):Po([...n,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},ld=async(e,t)=>{let r=await Hr(t),n=await dt(e),s=n.find(u=>u.rootPath===t)??null,o=s?So(s,r):Po(n,t,r),i=`workspace_${o.id}`,l=(await Z(e)).find(u=>u.id===i)??null,d=new Date().toISOString(),c=l??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:r,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:d,updatedAt:d};return await Vr(e,o),l||await $e(e,c),await Io(e,{repoIds:[o.id],workspaceIds:[c.id]}),{kind:"createWorkspace",workspace:c,repos:[o],created:!l}},cd=async(e,t)=>{let r=await ad(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await Z(e),s=id(n,Ye.basename(t)),o=n.find(d=>d.kind==="project"&&d.rootPath===t)??null,i=new Date().toISOString(),a=r.map(d=>d.id),l=o?{...o,discoveredRepoIds:a,primaryRepoId:a[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:Ye.basename(t),rootPath:t,primaryRepoId:a[0]??"",discoveredRepoIds:a,branch:"project",status:"active",linkedRepoIds:a,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(r.map(d=>Vr(e,d))),await $e(e,l),await Io(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!o}},ut=async(e,t)=>{await ze(e.workspaceRoot);let r=Ye.resolve(e.workspaceRoot,t);if(!(await sd(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await Kr(r)?ld(e,r):cd(e,r)};var Gr=async(e,t,r={listWorkspaceRecords:Z,ensureCraigState:ze})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var zr=async(e,t,r={readWorkspace:De,writeWorkspace:$e})=>{let s={...await r.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};return await r.writeWorkspace(e,s),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var Yr=async(e,t)=>{let n={...await De(e,t),status:"active",archivedAt:null};await $e(e,n);let s=n.kind==="project"?n.discoveredRepoIds?.[0]??null:n.primaryRepoId;return{kind:"restoreWorkspace",workspaceId:n.id,status:n.status,branch:n.branch,primaryRepoId:s}};var Me=async(e,t,r={deleteWorkspace:go,readCraigIndex:z,writeCraigIndex:fe})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var Qr=async(e,t,r)=>{let n=await De(e,t),s=await r.listTasks(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(s.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await Me(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var Jr={};Wt(Jr,{addRepo:()=>vo,listRegisteredRepos:()=>Co,removeRepo:()=>Eo});import dd from"node:path";import{stat as ud}from"node:fs/promises";var vo=async(e,t)=>{let r=dd.resolve(e.workspaceRoot,t);if(!(await ud(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await ut(e,t),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${r}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}};var Co=async(e,t={listRepos:dt,ensureCraigState:ze})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var Eo=async(e,t,r)=>{let n=await ne(e,t),o=(await Z(e)).filter(d=>d.primaryRepoId===t),i=o.filter(d=>d.status==="active"),a=await r.listTasks(e,{repoId:t});if(i.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(a.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(o.map(d=>Me(e,d.id))),await ko(e,t);let l=await z(e);return await fe(e,{...l,repoIds:l.repoIds.filter(d=>d!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var Q={addWorkspace:ut,listWorkspaces:Gr,archiveWorkspace:zr,restoreWorkspace:Yr,removeWorkspace:Qr,removeWorkspaceRecord:Me,repos:Jr};var J=async(e,t)=>{let r=await pd(Zr(e,t),"utf8");return JSON.parse(r)},ee=async(e,t)=>{let r=await J(e,t);return U(r,Zr(e,t))},S=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await N(Zr(e,t.id),r)},Xr=async(e,t)=>{let r=await z(e);r.taskIds.includes(t)||await fe(e,{...r,taskIds:[...r.taskIds,t]})},Zr=(e,t)=>`${e.tasksDir}/${t}.json`;var D=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,Re=e=>e.status==="merged"||e.status==="closed",Qe=(e,t)=>{let r=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),n=r>=0?e.prs.map((s,o)=>o===r?t:s):[...e.prs,t];return{...e,prs:n}},pt=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return Yt(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},Yt=e=>e.mergeable&&!md(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),md=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",en=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),mt=(e,t)=>{let r=e.isDraft??!1,n=fd(e.state,r);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:n,draft:r,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:gd(e.reviewDecision??null),requiredChecks:ft(e.statusCheckRollup),comments:yd(e.comments),createdAt:e.createdAt??t?.createdAt??null,updatedAt:e.updatedAt??t?.updatedAt??null,mergedAt:e.mergedAt??t?.mergedAt??null,lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}},fd=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,gd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,ft=e=>{let t=e.map(n=>hd(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||wd(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},hd=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=t.name??t.context,n=t.state??t.status??t.conclusion;return r?{name:r,status:xo(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:kd(t)}:null},wd=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):zt(e)&&!zt(t)?!0:!zt(e)&&zt(t)?!1:Ao(t.status)>=Ao(e.status),zt=e=>e.conclusion?.toUpperCase()==="CANCELLED",Ao=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},kd=e=>{let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let r=new Date(t).getTime();return Number.isFinite(r)?r:null},yd=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(Td).filter(r=>r!==null).slice(-4):[]},Td=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=Rd(t.bodyText??t.body??"");return r?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:r,createdAt:t.createdAt??null,url:t.url??null}:null},Rd=e=>e.replace(/\s+/g," ").trim(),xo=(e,t)=>{let r=e?.toUpperCase()??null,n=t?.toUpperCase()??null;return n==="SKIPPED"||r==="SKIPPED"?"skipped":r==="SUCCESS"||n==="SUCCESS"||n==="NEUTRAL"?"success":r==="PENDING"||r==="EXPECTED"||r==="IN_PROGRESS"||r==="QUEUED"||r==="REQUESTED"||r==="WAITING"?"pending":r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"||n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"?"failed":r==="COMPLETED"&&n===null?"unknown":r==="COMPLETED"&&n!==null?xo(n,n):"unknown"};import{access as bd}from"node:fs/promises";import Do from"node:path";var v=async(e,t,r={readRawTask:J,validateTaskRecord:U})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Cd(n)?new Error(`Craig task "${t}" was not found.`):n}},B=async e=>{if(!await tn(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},Je=(e,t)=>t.artifacts.logPath?Do.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:Do.join(e.workspaceRoot,t.artifacts.logPath):null,gt=async(e,t)=>{let r=await tn(t.worktreePath),n=Je(e,t),s=n?await tn(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:Pd(t),lastCommitSummary:Sd(t),prSummary:Id(t),cleanupSummary:vd(t)}},tn=async e=>{try{return await bd(e),!0}catch{return!1}},Pd=e=>{let t=e.checks.commands.length,r=t===1?"command":"commands",n=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${r})${n}`},Sd=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",Id=e=>{if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(l=>l.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),i=s.reduce((l,d)=>{let c=d.pullRequest.status??"unknown";return l[c]=(l[c]??0)+1,l},{}),a=Object.entries(i).map(([l,d])=>`${d} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${a})
|
|
12
|
+
${sn()}`,{})}var V=(e,t)=>{let r=on(e);if(!yd(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},on=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:an(t.runner),repoId:typeof t.repoId=="string"?t.repoId:"legacy_repo",workspaceId:typeof t.workspaceId=="string"?t.workspaceId:"legacy_workspace",sessionId:typeof t.sessionId=="string"||t.sessionId===null?t.sessionId:null,selectedPtyTabId:typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null?t.selectedPtyTabId:null,linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(r=>typeof r=="string"):[],ptyTabs:Sd(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:bd(t.repoTargets),runnerSession:t.runnerSession??Rd(t),checks:Dd(t),lastCommit:t.lastCommit??null,prs:$d(t),artifacts:Ld(t),cleanup:Fd(t)}},Rd=e=>{if(typeof e.title!="string")return null;let t=an(e.runner);return{command:f.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},yd=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&f.runners.isRunnerType(t.runner??"")&&typeof t.repoId=="string"&&typeof t.workspaceId=="string"&&(typeof t.sessionId=="string"||t.sessionId===null)&&(typeof t.selectedPtyTabId=="string"||t.selectedPtyTabId===null)&&Array.isArray(t.linkedRepoIds)&&t.linkedRepoIds.every(r=>typeof r=="string")&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&typeof t.branch=="string"&&No(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||Pd(t.repoTargets))&&Cd(t.runnerSession)&&vd(t.prompt)&&Lo(t.checks)&&Fo(t.lastCommit)&&Ad(t.prs)&&xd(t.artifacts)&&Wo(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},bd=e=>{if(Array.isArray(e))return e.filter(Mo)},Pd=e=>Array.isArray(e)&&e.every(Mo),Mo=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.repoId=="string"&&typeof t.branch=="string"&&typeof t.repoRoot=="string"&&typeof t.worktreePath=="string"&&(t.status==="ready"||t.status==="unavailable"||t.status==="merged"||t.status==="closed")&&(typeof t.failureReason=="string"||t.failureReason===null)&&Lo(t.checks)&&Fo(t.lastCommit)&&jo(t.pullRequest)&&Wo(t.cleanup)},Sd=e=>{if(No(e.ptyTabs))return e.ptyTabs;if(typeof e.id!="string"||typeof e.title!="string")return[];let t=typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString();return Id(e.id,e.title,t,an(e.runner))},Id=(e,t,r,n)=>{let s=f.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:s.defaultAgentTitle,command:f.runners.buildCommand(n),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},an=e=>e&&f.runners.isRunnerType(e)?e:"codex",No=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.id=="string"&&(t.kind==="agent"||t.kind==="terminal")&&typeof t.title=="string"&&Array.isArray(t.command)&&t.command.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"),Cd=e=>typeof e=="object"&&e!==null&&Array.isArray(e.command)&&e.command.every(t=>typeof t=="string")&&(typeof e.pid=="number"||e.pid===null)&&(typeof e.startedAt=="string"||e.startedAt===null)&&(e.lastKnownState==="starting"||e.lastKnownState==="running"||e.lastKnownState==="exited"||e.lastKnownState==="failed")&&(typeof e.exitCode=="number"||e.exitCode===null)&&(typeof e.exitedAt=="string"||e.exitedAt===null),vd=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",Lo=e=>typeof e=="object"&&e!==null&&typeof e.source=="object"&&e.source!==null&&e.source.type==="repo_config"&&typeof e.source.path=="string"&&(typeof e.lastRunAt=="string"||e.lastRunAt===null)&&(e.status==="not_run"||e.status==="running"||e.status==="passed"||e.status==="failed")&&Array.isArray(e.commands)&&e.commands.every(t=>typeof t=="string")&&Array.isArray(e.results)&&e.results.every(t=>typeof t=="object"&&t!==null&&typeof t.command=="string"&&typeof t.startedAt=="string"&&typeof t.finishedAt=="string"&&typeof t.exitCode=="number"),Fo=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",jo=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&Ed(e.requiredChecks),Ed=e=>Array.isArray(e)&&e.every(t=>typeof t=="object"&&t!==null&&typeof t.name=="string"&&(t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown")&&(typeof t.conclusion=="string"||t.conclusion===null)),Ad=e=>Array.isArray(e)&&e.every(jo),xd=e=>typeof e=="object"&&e!==null&&(typeof e.logPath=="string"||e.logPath===null)&&(typeof e.checkSummaryPath=="string"||e.checkSummaryPath===null)&&(typeof e.prDraftPath=="string"||e.prDraftPath===null)&&(typeof e.prStatusPath=="string"||e.prStatusPath===null),Wo=e=>typeof e=="object"&&e!==null&&(typeof e.paneClosedAt=="string"||e.paneClosedAt===null)&&(typeof e.worktreeRemovedAt=="string"||e.worktreeRemovedAt===null)&&typeof e.preservedWorktree=="boolean"&&(typeof e.warning=="string"||e.warning===null),Dd=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},$d=e=>{if(Array.isArray(e.prs))return e.prs.map(Od);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:_o(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:Uo(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},Od=e=>{let t=e??{};return{provider:"github",owner:t.owner??null,repo:t.repo??null,number:typeof t.number=="number"?t.number:null,url:t.url??null,title:t.title??null,status:_o(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Md(t.reviewDecision),requiredChecks:Uo(t.requiredChecks),comments:Nd(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},_o=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,Md=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Nd=e=>Array.isArray(e)?e.flatMap(t=>{if(typeof t!="object"||t===null)return[];let r=t;return typeof r.body!="string"||!r.body.trim()?[]:[{author:typeof r.author=="string"?r.author:null,body:r.body,createdAt:typeof r.createdAt=="string"?r.createdAt:null,url:typeof r.url=="string"?r.url:null}]}):[],Uo=e=>Array.isArray(e)?e.map(t=>({...t,status:t.status==="pending"||t.status==="success"||t.status==="failed"||t.status==="skipped"||t.status==="unknown"?t.status:"unknown",conclusion:t.conclusion??null})):[],Ld=e=>{let t=e.artifacts;return t?{...t,checkSummaryPath:t.checkSummaryPath??null}:{logPath:null,checkSummaryPath:null,prDraftPath:null,prStatusPath:null}},Fd=e=>e.cleanup??{paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null};import{readFile as uu}from"node:fs/promises";import{readFile as jd,readdir as Wd,rm as _d}from"node:fs/promises";import qo from"node:path";var ln=(e,t)=>qo.join(e.workspacesDir,`${t}.json`),Ud=e=>{if(typeof e!="object"||e===null)return e;let t=e,r=t.repoId??t.primaryRepoId;return{...t,kind:t.kind??"repo",name:t.name??r??t.id,rootPath:t.rootPath??"",primaryRepoId:t.primaryRepoId??r??"",repoId:t.kind==="project"?t.repoId:r,discoveredRepoIds:Array.isArray(t.discoveredRepoIds)?t.discoveredRepoIds.filter(n=>typeof n=="string"):t.kind==="project"?[]:r?[r]:[],linkedRepoIds:Array.isArray(t.linkedRepoIds)?t.linkedRepoIds.filter(n=>typeof n=="string"):[]}},Bo=(e,t)=>{let r=Ud(e);if(typeof r!="object"||r===null||typeof r.id!="string"||r.kind!=="repo"&&r.kind!=="project"||typeof r.name!="string"||typeof r.rootPath!="string"||typeof r.primaryRepoId!="string"||typeof r.branch!="string"||r.status!=="active"&&r.status!=="archived"||!Array.isArray(r.linkedRepoIds)||!(r.linkedRepoIds??[]).every(n=>typeof n=="string")||!(r.repoId===void 0||typeof r.repoId=="string")||!Array.isArray(r.discoveredRepoIds)||!(r.discoveredRepoIds??[]).every(n=>typeof n=="string")||!(r.archivedAt===null||typeof r.archivedAt=="string")||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig workspace record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},je=async(e,t)=>{let r=ln(e,t);try{let n=await jd(r,"utf8");return Bo(JSON.parse(n),r)}catch(n){throw qd(n)?new S("WORKSPACE_NOT_FOUND",`Craig workspace "${t}" was not found.`,{details:{workspaceId:t}}):n instanceof SyntaxError||n instanceof Error&&n.message.startsWith("Craig workspace record at ")?new S("WORKSPACE_RECORD_INVALID",n instanceof Error?n.message:`Craig workspace "${t}" is invalid.`,{details:{workspaceId:t},cause:n}):n}},We=async(e,t)=>{await U(ln(e,t.id),{...t,updatedAt:new Date().toISOString()})},ie=async e=>{let t=await Wd(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>je(e,qo.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},Vo=async(e,t)=>{await _d(ln(e,t),{force:!0})},qd=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";import{readFile as Bd,readdir as Vd,rm as Kd}from"node:fs/promises";import Ko from"node:path";var cn=(e,t)=>Ko.join(e.reposDir,`${t}.json`),Go=(e,t)=>{if(typeof e!="object"||e===null||typeof e.id!="string"||typeof e.name!="string"||typeof e.rootPath!="string"||typeof e.defaultBranch!="string"||typeof e.createdAt!="string"||typeof e.updatedAt!="string")throw new Error(`Craig repo record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return e},ce=async(e,t)=>{let r=cn(e,t);try{let n=await Bd(r,"utf8");return Go(JSON.parse(n),r)}catch(n){throw Gd(n)?new S("REPO_NOT_FOUND",`Craig repo "${t}" was not found.`,{details:{repoId:t}}):n instanceof SyntaxError||n instanceof Error&&n.message.startsWith("Craig repo record at ")?new S("REPO_RECORD_INVALID",n instanceof Error?n.message:`Craig repo "${t}" is invalid.`,{details:{repoId:t},cause:n}):n}},dn=async(e,t)=>{await U(cn(e,t.id),{...t,updatedAt:new Date().toISOString()})},Rt=async e=>{let t=await Vd(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>ce(e,Ko.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Ho=async(e,t)=>{await Kd(cn(e,t),{force:!0})},Gd=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT";import{readFile as Hd}from"node:fs/promises";var zd=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return t.version===2&&typeof t.workspaceRoot=="string"&&Array.isArray(t.repoIds)&&t.repoIds.every(r=>typeof r=="string")&&Array.isArray(t.workspaceIds)&&t.workspaceIds.every(r=>typeof r=="string")&&Array.isArray(t.taskIds)&&t.taskIds.every(r=>typeof r=="string")&&Array.isArray(t.jobIds)&&t.jobIds.every(r=>typeof r=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},rt=(e,t,r)=>{if(!zd(e))throw new Error(`Craig index at ${r} is invalid. Remove or repair the file before rerunning Craig.`);if(e.workspaceRoot!==t)throw new Error(`Craig index at ${r} belongs to ${e.workspaceRoot}, not ${t}. Remove or repair the file before rerunning Craig.`);return e},te=async e=>{let t=await Hd(e.indexFile,"utf8");return rt(JSON.parse(t),e.workspaceRoot,e.indexFile)},ye=async(e,t)=>{await U(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as Zd,stat as eu}from"node:fs/promises";import st from"node:path";import{realpath as Qo}from"node:fs/promises";import nr from"node:path";import{execFile as Yd}from"node:child_process";import{promisify as Qd}from"node:util";var zo=Qd(Yd);async function I(e,t,r={}){try{let n=await zo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(Yo(n)){let s=n.stderr?.trim()||n.stdout?.trim()||n.message;throw new Error(`${e} ${t.join(" ")} failed: ${s}`)}throw n}}async function x(e,t,r={}){try{let n=await zo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(Yo(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function Yo(e){return e instanceof Error}var un=async e=>{try{let r=(await I("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([Qo(r).catch(()=>nr.resolve(r)),Qo(e).catch(()=>nr.resolve(e))]);return n===s}catch{return!1}},pn=async e=>{let t=await x("git",["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"],{cwd:e}),r=t.stdout.trim().replace(/^origin\//,"");if(t.exitCode===0&&r.length>0)return r;for(let o of["main","master","trunk"])if((await x("git",["show-ref","--verify","--quiet",`refs/heads/${o}`],{cwd:e})).exitCode===0)return o;let s=(await I("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"},Jo=async e=>{let t=await x("git",["rev-parse","--path-format=absolute","--git-common-dir"],{cwd:e}),r=t.stdout.trim();if(t.exitCode!==0||r.length===0)return null;let n=nr.resolve(e,r);return nr.dirname(n)};import{mkdir as ge,readFile as Jd}from"node:fs/promises";var Xd=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",nt=async e=>{let t=ee(e);await ge(t.craigDir,{recursive:!0}),await Promise.all([ge(t.reposDir,{recursive:!0}),ge(t.workspacesDir,{recursive:!0}),ge(t.sessionsDir,{recursive:!0}),ge(t.runtimeDir,{recursive:!0}),ge(t.tasksDir,{recursive:!0}),ge(t.jobsDir,{recursive:!0}),ge(t.logsDir,{recursive:!0}),ge(t.artifactsDir,{recursive:!0}),ge(t.worktreesDir,{recursive:!0})]);try{let s=await Jd(t.indexFile,"utf8"),o=JSON.parse(s);return rt(o,e,t.indexFile)}catch(s){if(!Xd(s))throw s instanceof SyntaxError?new Error(`Craig index at ${t.indexFile} is malformed. Remove or repair the file before rerunning Craig.`):s}let r=new Date().toISOString(),n={version:2,workspaceRoot:e,repoIds:[],workspaceIds:[],taskIds:[],jobIds:[],createdAt:r,updatedAt:r};return await U(t.indexFile,n),n};var Xo=(e,t,r)=>{let n=new Date().toISOString();return{id:tu(e,st.basename(t)),name:st.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},Zo=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},tu=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"repo",n=`repo_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`repo_${r}_${s}`,s+=1;return n},ru=(e,t)=>{let r=t.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"workspace",n=`workspace_${r}`,s=2;for(;e.some(o=>o.id===n);)n=`workspace_${r}_${s}`,s+=1;return n},ei=async(e,t)=>{let r=await te(e);await ye(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},nu=async(e,t)=>{let r=await Zd(t,{withFileTypes:!0}),n=await Rt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=st.join(t,o.name);if(!await un(i))continue;let a=n.find(c=>c.rootPath===i)??s.find(c=>c.rootPath===i),l=await pn(i);s.push(a?Zo(a,l):Xo([...n,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},su=async(e,t)=>{let r=await pn(t),n=await Rt(e),s=n.find(u=>u.rootPath===t)??null,o=s?Zo(s,r):Xo(n,t,r),i=`workspace_${o.id}`,l=(await ie(e)).find(u=>u.id===i)??null,c=new Date().toISOString(),d=l??{id:i,kind:"repo",name:o.name,rootPath:t,primaryRepoId:o.id,repoId:o.id,discoveredRepoIds:[o.id],branch:r,status:"active",linkedRepoIds:[],archivedAt:null,createdAt:c,updatedAt:c};return await dn(e,o),l||await We(e,d),await ei(e,{repoIds:[o.id],workspaceIds:[d.id]}),{kind:"createWorkspace",workspace:d,repos:[o],created:!l}},ou=async(e,t)=>{let r=await nu(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await ie(e),s=ru(n,st.basename(t)),o=n.find(c=>c.kind==="project"&&c.rootPath===t)??null,i=new Date().toISOString(),a=r.map(c=>c.id),l=o?{...o,discoveredRepoIds:a,primaryRepoId:a[0]??o.primaryRepoId,status:"active",archivedAt:null}:{id:s,kind:"project",name:st.basename(t),rootPath:t,primaryRepoId:a[0]??"",discoveredRepoIds:a,branch:"project",status:"active",linkedRepoIds:a,archivedAt:null,createdAt:i,updatedAt:i};return await Promise.all(r.map(c=>dn(e,c))),await We(e,l),await ei(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!o}},yt=async(e,t)=>{await nt(e.workspaceRoot);let r=st.resolve(e.workspaceRoot,t);if(!(await eu(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await un(r)?su(e,r):ou(e,r)};var mn=async(e,t,r={listWorkspaceRecords:ie,ensureCraigState:nt})=>(await r.ensureCraigState(e.workspaceRoot),{kind:"listWorkspaces",workspaces:(await r.listWorkspaceRecords(e)).filter(s=>s.status===(t.archived?"archived":"active")),archivedOnly:t.archived});var fn=async(e,t,r={readWorkspace:je,writeWorkspace:We})=>{let s={...await r.readWorkspace(e,t),status:"archived",archivedAt:new Date().toISOString()};return await r.writeWorkspace(e,s),{kind:"archiveWorkspace",workspaceId:s.id,status:s.status,branch:s.branch}};var gn=async(e,t)=>{let n={...await je(e,t),status:"active",archivedAt:null};await We(e,n);let s=n.kind==="project"?n.discoveredRepoIds?.[0]??null:n.primaryRepoId;return{kind:"restoreWorkspace",workspaceId:n.id,status:n.status,branch:n.branch,primaryRepoId:s}};var _e=async(e,t,r={deleteWorkspace:Vo,readCraigIndex:te,writeCraigIndex:ye})=>{await r.deleteWorkspace(e,t);let n=await r.readCraigIndex(e);await r.writeCraigIndex(e,{...n,workspaceIds:n.workspaceIds.filter(s=>s!==t)})};var hn=async(e,t,r)=>{let n=await je(e,t),s=await r.listTasks(e,{workspaceId:t,includeClosed:!0});if(n.status==="active")throw new Error(`Cannot remove workspace ${t} while it is active. Archive it first.`);if(s.tasks.length>0)throw new Error(`Cannot remove workspace ${t} while task records still reference it.`);return await _e(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};import{readFile as iu,realpath as ni,stat as au}from"node:fs/promises";import sr from"node:path";async function kn(e){let t=await oi(e.cwd,"Current working directory");if(e.explicitWorkspaceRoot!==void 0)return ti(e.explicitWorkspaceRoot,"explicit",t,e.allowUninitializedCwd??!1);if(e.environmentWorkspaceRoot!==void 0)return ti(e.environmentWorkspaceRoot,"environment",t,e.allowUninitializedCwd??!1);let r=await ri(t);if(r)return{workspaceRoot:r,source:"ancestor",initialized:!0};let n=await Jo(t);if(n){let s=await ri(n);if(s)return{workspaceRoot:s,source:"git_common_dir",initialized:!0}}if(e.allowUninitializedCwd)return{workspaceRoot:t,source:"cwd",initialized:!1};throw new S("WORKSPACE_CONTEXT_NOT_FOUND",`No Craig workspace was found from ${t}. Use --workspace-root <path> or run Craig inside an initialized workspace.`,{details:{cwd:t}})}async function ti(e,t,r,n){let s=t==="explicit"?"Workspace root":"CRAIG_WORKSPACE_ROOT",o=await oi(sr.resolve(r,e),s),i=await si(o);if(i)return{workspaceRoot:i,source:t,initialized:!0};if(n)return{workspaceRoot:o,source:t,initialized:!1};throw new S("WORKSPACE_CONTEXT_NOT_FOUND",`${s} ${o} is not an initialized Craig workspace.`,{details:{workspaceRoot:o,source:t}})}async function ri(e){let t=e;for(;;){let r=await si(t);if(r)return r;let n=sr.dirname(t);if(n===t)return null;t=n}}async function si(e){let t=ee(e);try{let r=await iu(t.indexFile,"utf8"),n=JSON.parse(r),s=typeof n=="object"&&n!==null&&"workspaceRoot"in n&&typeof n.workspaceRoot=="string"?n.workspaceRoot:e,o=rt(n,s,t.indexFile);if(await ni(o.workspaceRoot).catch(()=>sr.resolve(o.workspaceRoot))!==e)throw new Error(`Craig index at ${t.indexFile} belongs to ${o.workspaceRoot}, not ${e}. Remove or repair the file before rerunning Craig.`);return o.workspaceRoot}catch(r){if(lu(r))return null;throw r instanceof S?r:new S("WORKSPACE_CONTEXT_INVALID",r instanceof Error?r.message:`Craig workspace at ${e} is invalid.`,{details:{workspaceRoot:e},cause:r})}}async function oi(e,t){let r=sr.resolve(e);try{if(!(await au(r)).isDirectory())throw new S("WORKSPACE_CONTEXT_INVALID",`${t} ${r} is not a directory.`,{details:{path:r}});return await ni(r)}catch(n){throw n instanceof S?n:new S("WORKSPACE_CONTEXT_NOT_FOUND",`${t} ${r} does not exist or cannot be read.`,{details:{path:r},cause:n})}}function lu(e){return typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT"}var wn={};Yt(wn,{addRepo:()=>ii,listRegisteredRepos:()=>ai,removeRepo:()=>li});import cu from"node:path";import{stat as du}from"node:fs/promises";var ii=async(e,t)=>{let r=cu.resolve(e.workspaceRoot,t);if(!(await du(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await yt(e,t),o=s.repos[0];if(!o||s.workspace.kind==="project")throw new Error(`Repo path is not a git repository: ${r}`);return{kind:"createRepo",repo:o,workspaceId:s.workspace.id,created:s.created}};var ai=async(e,t={listRepos:Rt,ensureCraigState:nt})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var li=async(e,t,r)=>{let n=await ce(e,t),o=(await ie(e)).filter(c=>c.primaryRepoId===t),i=o.filter(c=>c.status==="active"),a=await r.listTasks(e,{repoId:t});if(i.length>0)throw new Error(`Cannot remove repo ${t} while active workspace records still reference it.`);if(a.tasks.length>0)throw new Error(`Cannot remove repo ${t} while task records still reference it.`);await Promise.all(o.map(c=>_e(e,c.id))),await Ho(e,t);let l=await te(e);return await ye(e,{...l,repoIds:l.repoIds.filter(c=>c!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var H={addWorkspace:yt,listWorkspaces:mn,archiveWorkspace:fn,restoreWorkspace:gn,removeWorkspace:hn,removeWorkspaceRecord:_e,resolveContext:kn,repos:wn};var re=async(e,t)=>{let r=await uu(Rn(e,t),"utf8");return JSON.parse(r)},ae=async(e,t)=>{let r=await re(e,t);return V(r,Rn(e,t))},P=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await U(Rn(e,t.id),r)},Tn=async(e,t)=>{let r=await te(e);r.taskIds.includes(t)||await ye(e,{...r,taskIds:[...r.taskIds,t]})},Rn=(e,t)=>`${e.tasksDir}/${t}.json`;var $=e=>e.prs.length===0?null:[...e.prs].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e.prs[e.prs.length-1]??null,ve=e=>e.status==="merged"||e.status==="closed",ot=(e,t)=>{let r=e.prs.findIndex(s=>s.number!==null&&s.number===t.number),n=r>=0?e.prs.map((s,o)=>o===r?t:s):[...e.prs,t];return{...e,prs:n}},bt=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return ir(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},ir=e=>e.mergeable&&!pu(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),pu=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",yn=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),Pt=(e,t)=>{let r=e.isDraft??!1,n=mu(e.state,r);return{provider:"github",owner:t?.owner??null,repo:t?.repo??null,number:e.number,url:e.url,title:e.title??t?.title??null,status:n,draft:r,baseBranch:e.baseRefName,headBranch:e.headRefName,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:fu(e.reviewDecision??null),requiredChecks:St(e.statusCheckRollup),comments:e.comments===void 0?t?.comments??[]:wu(e.comments),createdAt:e.createdAt??t?.createdAt??null,updatedAt:e.updatedAt??t?.updatedAt??null,mergedAt:e.mergedAt??t?.mergedAt??null,lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}},mu=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,fu=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,St=e=>{let t=e.map(n=>gu(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||hu(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},gu=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=t.name??t.context,n=t.state??t.status??t.conclusion;return r?{name:r,status:di(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:ku(t)}:null},hu=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):or(e)&&!or(t)?!0:!or(e)&&or(t)?!1:ci(t.status)>=ci(e.status),or=e=>e.conclusion?.toUpperCase()==="CANCELLED",ci=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},ku=e=>{let t=e.completedAt??e.startedAt??e.createdAt??null;if(!t)return null;let r=new Date(t).getTime();return Number.isFinite(r)?r:null},wu=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(Tu).filter(r=>r!==null).slice(-4):[]},Tu=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=Ru(t.bodyText??t.body??"");return r?{author:typeof t.author=="string"?t.author:t.author?.login??null,body:r,createdAt:t.createdAt??null,url:t.url??null}:null},Ru=e=>e.replace(/\s+/g," ").trim(),di=(e,t)=>{let r=e?.toUpperCase()??null,n=t?.toUpperCase()??null;return n==="SKIPPED"||r==="SKIPPED"?"skipped":r==="SUCCESS"||n==="SUCCESS"||n==="NEUTRAL"?"success":r==="PENDING"||r==="EXPECTED"||r==="IN_PROGRESS"||r==="QUEUED"||r==="REQUESTED"||r==="WAITING"?"pending":r==="FAILURE"||r==="FAILED"||r==="ERROR"||r==="TIMED_OUT"||r==="CANCELLED"||r==="ACTION_REQUIRED"||r==="STARTUP_FAILURE"||n==="FAILURE"||n==="FAILED"||n==="ERROR"||n==="TIMED_OUT"||n==="CANCELLED"||n==="ACTION_REQUIRED"||n==="STARTUP_FAILURE"?"failed":r==="COMPLETED"&&n===null?"unknown":r==="COMPLETED"&&n!==null?di(n,n):"unknown"};var he=class extends Error{constructor(t){super(t),this.name="GitHubRateLimitError"}};import{access as yu}from"node:fs/promises";import ui from"node:path";var v=async(e,t,r={readRawTask:re,validateTaskRecord:V})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Cu(n)?new S("TASK_NOT_FOUND",`Craig task "${t}" was not found.`,{details:{taskId:t}}):vu(n)?new S("TASK_RECORD_INVALID",n instanceof Error?n.message:`Craig task "${t}" is invalid.`,{details:{taskId:t},cause:n}):n}},K=async e=>{if(!await bn(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},it=(e,t)=>t.artifacts.logPath?ui.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:ui.join(e.workspaceRoot,t.artifacts.logPath):null,It=async(e,t)=>{let r=await bn(t.worktreePath),n=it(e,t),s=n?await bn(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:bu(t),lastCommitSummary:Pu(t),prSummary:Su(t),cleanupSummary:Iu(t)}},bn=async e=>{try{return await yu(e),!0}catch{return!1}},bu=e=>{let t=e.checks.commands.length,r=t===1?"command":"commands",n=e.checks.lastRunAt?` at ${e.checks.lastRunAt}`:"";return`${e.checks.status} (${t} ${r})${n}`},Pu=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",Su=e=>{if(e.type==="project"&&e.repoTargets?.length){let s=e.repoTargets.filter(l=>l.pullRequest.number);if(s.length===0)return"not linked";let o=s.map(l=>` ${l.repoId} #${l.pullRequest.number} ${l.pullRequest.status??"unknown"}`),i=s.reduce((l,c)=>{let d=c.pullRequest.status??"unknown";return l[d]=(l[d]??0)+1,l},{}),a=Object.entries(i).map(([l,c])=>`${c} ${l}`).join(", ");return`${s.length} PR${s.length!==1?"s":""} (${a})
|
|
30
13
|
${o.join(`
|
|
31
|
-
`)}`}let t
|
|
32
|
-
`);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}},
|
|
14
|
+
`)}`}let t=$(e);if(!t?.number||!t.url)return"not linked";let r=t.requiredChecks.length,n=r===1?"check":"checks";return`#${t.number} ${t.status??"unknown"} mergeable=${t.mergeable} mergeState=${t.mergeStateStatus??"unknown"} (${r} ${n})`},Iu=e=>e.status!=="merged"?"not merged":e.cleanup.warning?`warning: ${e.cleanup.warning}`:e.cleanup.preservedWorktree?"preserved worktree":e.cleanup.worktreeRemovedAt?`worktree removed at ${e.cleanup.worktreeRemovedAt}`:"cleanup pending",Cu=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",vu=e=>e instanceof SyntaxError||e instanceof Error&&e.message.startsWith("Craig task record at ");var pi=async(e,t)=>{let r=await x("git",["show-ref","--verify","--quiet",`refs/heads/${t}`],{cwd:e});if(r.exitCode===0)return!0;if(r.exitCode===1)return!1;throw new Error(r.stderr.trim()||r.stdout.trim()||"Unable to check git branch state.")},Pn=async(e,t,r,n="main")=>{let s=n.trim()||"main";if((await x("git",["show-ref","--verify","--quiet",`refs/heads/${s}`],{cwd:e})).exitCode!==0)throw new Error(`Base branch '${s}' does not exist locally.`);let i=await Eu(e,s);await I("git",["worktree","add","-b",t,r,i],{cwd:e})},Eu=async(e,t)=>(await x("git",["remote","get-url","origin"],{cwd:e})).exitCode!==0||(await x("git",["fetch","origin",t],{cwd:e})).exitCode!==0?t:(await x("git",["show-ref","--verify","--quiet",`refs/remotes/origin/${t}`],{cwd:e})).exitCode===0?`refs/remotes/origin/${t}`:t,ar=async e=>{let t=await x("git",["status","--short"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"Unable to inspect git status.");return t.stdout.trim().length>0},mi=async e=>{await I("git",["add","-A"],{cwd:e})},fi=async(e,t)=>{await I("git",["commit","-m",t],{cwd:e})},gi=async e=>{let t=await I("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[r="",n=""]=t.stdout.trim().split(`
|
|
15
|
+
`);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}},hi=async e=>{let t=await x("git",["branch","--show-current"],{cwd:e});if(t.exitCode!==0)return null;let r=t.stdout.trim();return r.length>0?r:null};var ki=async(e,t)=>{await I("git",["worktree","remove","--force",t],{cwd:e})};var Sn=async e=>at(e,e.repoRoot),at=async(e,t)=>{let r=await te(e),n=wi(new Date),s=Ti(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await pi(t,i))return o;s+=1}},Ct=async e=>{let t=await te(e),r=wi(new Date),n=Ti(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},wi=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},Ti=(e,t)=>{let r=e.filter(n=>n.startsWith(`task_${t}_`)).map(n=>Number.parseInt(n.slice(-2),10)).filter(n=>Number.isInteger(n));return r.length===0?1:Math.max(...r)+1};var vt=async(e,t,r={readRawTask:re,validateTaskRecord:V})=>{let n=await te(e),s=[],o=[];await Promise.all(n.taskIds.map(async l=>{try{let c=await r.readRawTask(e,l);s.push(r.validateTaskRecord(c,`${e.tasksDir}/${l}.json`))}catch(c){if(Au(c)){o.push(l);return}throw c}}));let a=(t?.includeClosed?s:s.filter(l=>l.status!=="closed")).filter(l=>!(t?.workspaceId&&l.workspaceId!==t.workspaceId||t?.repoId&&l.repoId!==t.repoId&&!(l.repoTargets??[]).some(c=>c.repoId===t.repoId)));return a.sort((l,c)=>l.id.localeCompare(c.id)),o.sort(),{kind:"listTasks",tasks:a,missingTaskIds:o,repoId:t?.repoId??null}},Au=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var Ri=["merge_ready","pr_open","checked","review","running","draft"],In=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),Cn=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(xu)[0]?.id??null,xu=(e,t)=>{let r=yi(e.status),n=yi(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},yi=e=>{let t=Ri.indexOf(e);return t>=0?t:Ri.length};import bi from"node:path";var Ue=(e,t)=>t?bi.isAbsolute(t)?t:bi.join(e.repoRoot,t):null;import{mkdir as Et,rm as Du,writeFile as lr}from"node:fs/promises";import D from"node:path";var Si=["AGENTS","md"].join("."),lt=async(e,t,r,n={})=>{let s=await ce(e,t),[o,i]=await Promise.all([Lu(e,s.id),at(e,s.rootPath)]),a=n.sessionId??null,l=`craig/${i}`,c=D.join(e.worktreesDir,s.id,i),d=D.join(e.logsDir,`${i}.log`),u=D.join(e.artifactsDir,i);await Promise.all([Et(D.dirname(c),{recursive:!0}),Et(u,{recursive:!0}),lr(d,"","utf8")]);let m=$u(e,{taskId:i,repoId:s.id,workspaceId:o.id,sessionId:a,repoRoot:s.rootPath,prompt:r,runner:n.runner??"codex",config:n.config??{},branch:l,worktreePath:c});return await P(e,m),await Tn(e,i),await Pn(s.rootPath,l,c,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:a,workspaceId:o.id,task:m}},At=async(e,t,r,n={})=>{let s=(await ie(e)).find(C=>C.id===t&&C.status==="active");if(!s)throw new Error(`Workspace ${t} does not exist or is archived.`);if(s.kind!=="project"){if(!s.primaryRepoId)throw new Error(`Workspace ${t} is not task-capable.`);let C=await lt(e,s.primaryRepoId,r,n);return{...C,bundlePath:C.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await Ct(e),a=new Date().toISOString(),l=n.runner??"codex",c=n.sessionId??null,d=`craig/${i}`,u=D.join(e.craigDir,"task-bundles",i),m=D.join(e.logsDir,`${i}.log`),T=D.join(e.artifactsDir,i);await Et(u,{recursive:!0}),await Et(T,{recursive:!0}),await lr(m,"","utf8");let R=await Promise.all(o.map(C=>ce(e,C))),h=Mu(R),y=await Promise.all(R.map(C=>Ou(e,C,i,d,D.join(u,h.get(C.id))))),B=y.find(C=>C.status==="ready")??y[0];if(!y.some(C=>C.status==="ready"))throw await Du(u,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${y.map(C=>`${C.repoId}: ${C.failureReason??"unknown error"}`).join("; ")}`);await lr(D.join(u,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:y.map(C=>({repoId:C.repoId,repoName:R.find(we=>we.id===C.repoId)?.name??C.repoId,path:D.relative(u,C.worktreePath),status:C.status,worktreePath:C.worktreePath,failureReason:C.failureReason}))},null,2),"utf8"),await lr(D.join(u,Si),Nu({taskId:i,workspaceId:t,prompt:r,repos:R,repoTargets:y,bundlePath:u}),"utf8");let z=xt(i,r,a,l,n.config??{}),se={id:i,title:r,slug:Ii(r),type:"project",status:"draft",runner:l,repoId:B.repoId,workspaceId:s.id,sessionId:c,selectedPtyTabId:z[0]?.id??null,linkedRepoIds:o.filter(C=>C!==B.repoId),repoRoot:u,worktreePath:u,branch:d,bundlePath:u,selectedRepoTargetId:B.repoId,repoTargets:y,ptyTabs:z,runnerSession:{command:f.runners.buildCommand(l,r,n.config??{}),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:r},checks:B.checks,lastCommit:null,prs:[],artifacts:{logPath:D.relative(e.workspaceRoot,m),checkSummaryPath:D.relative(e.workspaceRoot,D.join(T,"check-summary.json")),prDraftPath:null,prStatusPath:D.relative(e.workspaceRoot,D.join(T,"pr-status.json"))},cleanup:cr(),lastFailureReason:y.every(C=>C.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:a,updatedAt:a};return await P(e,se),await Tn(e,i),{repoId:B.repoId,repoRoot:u,sessionId:c,workspaceId:s.id,task:se,bundlePath:u,repoTargets:y}},xt=(e,t,r,n="codex",s={})=>{let o=f.runners.getProfile(n);return[{id:`${e}:agent`,kind:"agent",title:o.defaultAgentTitle,command:f.runners.buildCommand(n,void 0,s),createdAt:r,updatedAt:r},{id:`${e}:terminal`,kind:"terminal",title:"Terminal",command:[],createdAt:r,updatedAt:r}]},$u=(e,t)=>{let r=new Date().toISOString(),n=xt(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:Ii(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:n[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:n,runnerSession:{command:f.runners.buildCommand(t.runner,t.prompt,t.config),pid:null,startedAt:null,lastKnownState:"starting",exitCode:null,exitedAt:null},prompt:{source:"inline",value:t.prompt},checks:{...vn(D.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:D.relative(e.workspaceRoot,D.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:D.relative(e.workspaceRoot,D.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:D.relative(e.workspaceRoot,D.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:cr(),lastFailureReason:null,createdAt:r,updatedAt:r}},Ou=async(e,t,r,n,s)=>{await Et(D.dirname(s),{recursive:!0});try{return await Pn(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:vn(D.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Pi(),cleanup:cr()}}catch(o){return{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"unavailable",failureReason:o instanceof Error?o.message:"Failed to create worktree.",checks:vn(D.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Pi(),cleanup:cr()}}},Mu=e=>{let t=new Set(["manifest.json",Si]),r=new Map;for(let n of e){let s=t.has(n.name)?`${n.name}-repo`:n.name,o=s,i=2;for(;t.has(o);)o=`${s}-${i}`,i+=1;t.add(o),r.set(n.id,o)}return r},Nu=e=>{let t=new Map(e.repos.map(n=>[n.id,n.name])),r=e.repoTargets.map(n=>{let s=t.get(n.repoId)??n.repoId,o=D.relative(e.bundlePath,n.worktreePath),i=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${n.repoId}, ${i})`}).join(`
|
|
33
16
|
`);return["# Craig Project Task Bundle","","This directory is a Craig project task bundle. Repo work must happen inside the child repo worktrees listed below.","","Run repo Git commands from a repo worktree directory, not from the bundle root. Use `manifest.json` as the machine-readable source of truth for this bundle.","",`Task: \`${e.taskId}\``,`Workspace: \`${e.workspaceId}\``,`Prompt: ${e.prompt}`,"","## Repo Worktrees","",r,""].join(`
|
|
34
|
-
`)},ln=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),qo=()=>({provider:"github",number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}),Xt=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),jd=async(e,t)=>{let n=(await Z(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!n)throw new Error(`Repo ${t} does not have an active workspace.`);return n},Ko=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import ri from"node:path";import{readFile as Fd,rm as Nk}from"node:fs/promises";import Nd from"node:path";var be=async(e,t)=>{let r=await Fd(cn(e,t),"utf8"),n=JSON.parse(r);return Wd(n,cn(e,t))},Oe=async(e,t)=>{await N(cn(e,t.id),{...t,updatedAt:new Date().toISOString()})};var cn=(e,t)=>Nd.join(e.sessionsDir,`${t}.json`);function Wd(e,t){let r=Bd(e);if(typeof r!="object"||r===null||typeof r.id!="string"||typeof r.taskId!="string"||typeof r.repoId!="string"||typeof r.workspaceId!="string"||r.substrate!=="tmux"||typeof r.sessionName!="string"||typeof r.paneId!="string"||!(r.windowTarget===null||typeof r.windowTarget=="string")||typeof r.worktreePath!="string"||!(r.logPath===null||typeof r.logPath=="string")||!Array.isArray(r.command)||!r.command.every(n=>typeof n=="string")||!["starting","running","exited","failed"].includes(r.status)||!(r.startedAt===null||typeof r.startedAt=="string")||!(r.exitedAt===null||typeof r.exitedAt=="string")||!(r.exitCode===null||typeof r.exitCode=="number")||!(r.lastAttachedAt===null||typeof r.lastAttachedAt=="string")||!Ud(r.attach)||!_d(r.snapshot)||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r}function _d(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function Ud(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function Bd(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(r=>typeof r=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}import{spawn as qd}from"node:child_process";import{createHash as Vd}from"node:crypto";import Kd from"node:path";function Zt(e){return`'${e.replace(/'/g,"'\\''")}'`}var Hd="craig",Ho=async(e,t,r)=>{let n=dn(e,t),s=zd(),o=await P("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=Qd(o.stdout);return await Gd(e,n),i};var Gd=async(e,t)=>{let r=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let n of r)await P("tmux",n,{cwd:e})},Go=async(e,t,r)=>{await P("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},zo=async(e,t,r)=>{await P("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var Yo=async(e,t,r)=>{await P("tmux",["pipe-pane","-o","-t",e,`cat >> ${Zt(t)}`],{cwd:r})},er=async(e,t,r,n)=>{let s=n??Jo(e);if(r?await P("tmux",["select-window","-t",r],{cwd:e}):await P("tmux",["select-window","-t",t],{cwd:e}),await P("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await P("tmux",["switch-client","-t",s],{cwd:e});return}await Xd(e,["attach-session","-t",s])};var Qo=async(e,t)=>{await P("tmux",["kill-session","-t",t],{cwd:e})};var Jo=e=>{let r=Kd.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=Vd("sha1").update(e).digest("hex").slice(0,8);return`${Hd}-${r}-${n}`},dn=(e,t)=>`${Jo(e)}-${t.toLowerCase()}`,zd=()=>{let e=Yd();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},Yd=()=>{let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let r="columns"in t?t.columns:void 0,n="rows"in t?t.rows:void 0;if(typeof r=="number"&&r>0&&typeof n=="number"&&n>0)return{columns:r,rows:n}}return null},Qd=e=>{let t=Jd(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}},Jd=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),Xd=async(e,t)=>{await new Promise((r,n)=>{let s=qd("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",n),s.on("exit",o=>{if(o===0){r();return}n(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})};import{accessSync as Zd,constants as eu}from"node:fs";import{homedir as Xo}from"node:os";import Pe from"node:path";var tu=[Pe.join(Xo(),".local","bin"),Pe.join(Xo(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function ei(e=process.env){return ru([...(e.PATH??"").split(Pe.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:tu])}function je(e=process.env){return{...e,PATH:ei(e).join(Pe.delimiter)}}function un(e,t={}){if(e.includes(Pe.sep)){let r=Pe.isAbsolute(e)?e:Pe.resolve(t.cwd??process.cwd(),e);return Zo(r)?r:null}for(let r of ei(t.env)){let n=Pe.join(r,e);if(Zo(n))return n}return null}function Fe(e,t={}){let r=un(e,t);if(r)return r;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function Zo(e){try{return Zd(e,eu.X_OK),!0}catch{return!1}}function ru(e){return[...new Set(e)]}var Tt={async create(e,t){let r=await Ho(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await Yo(r.paneId,t.logPath,t.repoRoot);let n=await ti({paneId:r.paneId,windowTarget:r.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:r.sessionName||dn(t.repoRoot,t.taskId),paneId:r.paneId,windowTarget:r.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:n,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await Oe(e,s),s},async attach(e,t,r){let n=await Tt.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await er(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await Oe(e,s),s},async resize(e,t,r,n){await Go(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await Oe(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,r){let n={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:t.command};return await Oe(e,n),n},async snapshot(e,t){return nu(e,t)}},pn={async prepare(e,t){let n=e.runnerSession.command[0],s=je();await P(Fe(n,{cwd:t.repoRoot,env:s}),["--help"],{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=Fe(r[0],{cwd:e.worktreePath,env:je()});await zo(t.session.paneId,[n,...r.slice(1)].map(s=>Zt(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},nu=async(e,t)=>{let r=await x("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return ti({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},ti=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var mn=async(e,t,r,n={})=>{let s=r.trim(),o=await f.load(e),i=n.runner??f.runners.getDefault(o);if(f.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(n.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let a=n.workspaceId?await kt(e,n.workspaceId,s,{runner:i,config:o}):await Ze(e,t,s,{runner:i,config:o}),l=a.task,d=f.runners.buildCommand(i,s,o),c=`session_${l.id}`,u=l.artifacts.logPath?ri.resolve(e.workspaceRoot,l.artifacts.logPath):ri.join(e.logsDir,`${l.id}.log`);try{await pn.prepare(l,{repoRoot:a.repoRoot});let p=await Tt.create(e,{sessionId:c,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:u,command:d});await pn.launch(l,{repoRoot:a.repoRoot,session:p});let k=new Date().toISOString();p={...p,status:"running",startedAt:k,command:d};let y={...l,status:"running",runner:i,sessionId:p.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:p.command,pid:null,startedAt:k,lastKnownState:"running",exitCode:null,exitedAt:null}};return await S(e,y),await Oe(e,p),{kind:"createTask",taskId:y.id,repoId:y.repoId,workspaceId:y.workspaceId,sessionId:p.id,status:y.status,branch:y.branch,worktreePath:y.worktreePath,runner:y.runner}}catch(p){let k={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:p instanceof Error?p.message:"Unknown Craig error"};throw await S(e,k),p}};import{mkdir as mu}from"node:fs/promises";import fu from"node:path";var ni=3,su=1e3,ou=1e4,et=async e=>{let t=await x("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var si=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await P("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},tr=async(e,t)=>{let r=await P("gh",ai(e),{cwd:t});return JSON.parse(r.stdout)},tt=async(e,t)=>{let r=await x("gh",ai(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},oi=async(e,t,r)=>{if(r.length===0)return[];let n=uu(r),s=await iu(e,["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`]),i=JSON.parse(s.stdout).data?.repository??{};return r.map((a,l)=>{let d=i[`item${l}`],c=pu(d);return{id:a.id,found:c!==null,view:c}})},ii=async e=>{let t=await x("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:du(t.stdout.trim())},iu=async(e,t)=>{let r;for(let n=0;n<=ni;n+=1)try{return await P("gh",t,{cwd:e})}catch(s){if(r=s,n===ni||!au(s))throw s;await cu(lu(n))}throw r},au=e=>{let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")},lu=e=>{let t=Number(process.env.CRAIG_GH_RATE_LIMIT_RETRY_BASE_MS)||su,r=Math.min(t*2**e,ou),n=Math.floor(Math.random()*Math.max(1,Math.floor(r*.25)));return r+n},cu=e=>new Promise(t=>setTimeout(t,e)),ai=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],du=e=>{let t=e.replace(/\.git$/,""),r=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let n=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null},uu=e=>`
|
|
17
|
+
`)},vn=e=>({source:{type:"repo_config",path:e},lastRunAt:null,status:"not_run",commands:[],results:[]}),Pi=()=>({provider:"github",number:null,url:null,baseBranch:null,headBranch:null,status:null,draft:!1,mergeable:!1,mergeStateStatus:null,reviewDecision:null,requiredChecks:[],comments:[],lastSyncedAt:null,lastSyncedHeadSha:null}),cr=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),Lu=async(e,t)=>{let n=(await ie(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!n)throw new Error(`Repo ${t} does not have an active workspace.`);return n},Ii=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import Li from"node:path";import{readFile as Fu,rm as iR}from"node:fs/promises";import ju from"node:path";var Ee=async(e,t)=>{let r=await Fu(En(e,t),"utf8"),n=JSON.parse(r);return Wu(n,En(e,t))},qe=async(e,t)=>{await U(En(e,t.id),{...t,updatedAt:new Date().toISOString()})};var En=(e,t)=>ju.join(e.sessionsDir,`${t}.json`);function Wu(e,t){let r=qu(e);if(typeof r!="object"||r===null||typeof r.id!="string"||typeof r.taskId!="string"||typeof r.repoId!="string"||typeof r.workspaceId!="string"||r.substrate!=="tmux"||typeof r.sessionName!="string"||typeof r.paneId!="string"||!(r.windowTarget===null||typeof r.windowTarget=="string")||typeof r.worktreePath!="string"||!(r.logPath===null||typeof r.logPath=="string")||!Array.isArray(r.command)||!r.command.every(n=>typeof n=="string")||!["starting","running","exited","failed"].includes(r.status)||!(r.startedAt===null||typeof r.startedAt=="string")||!(r.exitedAt===null||typeof r.exitedAt=="string")||!(r.exitCode===null||typeof r.exitCode=="number")||!(r.lastAttachedAt===null||typeof r.lastAttachedAt=="string")||!Uu(r.attach)||!_u(r.snapshot)||typeof r.createdAt!="string"||typeof r.updatedAt!="string")throw new Error(`Craig session record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r}function _u(e){return e===null||typeof e=="object"&&e!==null&&typeof e.paneId=="string"&&(typeof e.windowTarget=="string"||e.windowTarget===null)&&typeof e.alive=="boolean"&&typeof e.capturedAt=="string"}function Uu(e){return typeof e=="object"&&e!==null&&e.detachChord==="ctrl+]"&&(e.lastSize===null||typeof e.lastSize=="object"&&e.lastSize!==null&&typeof e.lastSize.columns=="number"&&typeof e.lastSize.rows=="number")}function qu(e){let t=typeof e=="object"&&e!==null?e:{};return{id:t.id??"",taskId:t.taskId??"",repoId:t.repoId??"",workspaceId:t.workspaceId??"",substrate:t.substrate??"tmux",sessionName:t.sessionName??"",paneId:t.paneId??"",windowTarget:typeof t.windowTarget=="string"?t.windowTarget:null,worktreePath:t.worktreePath??"",logPath:typeof t.logPath=="string"?t.logPath:null,command:Array.isArray(t.command)?t.command.filter(r=>typeof r=="string"):[],status:t.status??"starting",startedAt:typeof t.startedAt=="string"?t.startedAt:null,exitedAt:typeof t.exitedAt=="string"?t.exitedAt:null,exitCode:typeof t.exitCode=="number"?t.exitCode:null,lastAttachedAt:typeof t.lastAttachedAt=="string"?t.lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:typeof t.attach=="object"&&t.attach!==null&&t.attach.lastSize&&typeof t.attach.lastSize.columns=="number"&&typeof t.attach.lastSize.rows=="number"?t.attach.lastSize:null},snapshot:t.snapshot&&typeof t.snapshot=="object"?{paneId:typeof t.snapshot.paneId=="string"?t.snapshot.paneId:t.paneId??"",windowTarget:typeof t.snapshot.windowTarget=="string"?t.snapshot.windowTarget:null,alive:!!t.snapshot.alive,capturedAt:typeof t.snapshot.capturedAt=="string"?t.snapshot.capturedAt:new Date().toISOString()}:null,createdAt:t.createdAt??"",updatedAt:t.updatedAt??""}}import{spawn as Bu}from"node:child_process";import{createHash as Vu}from"node:crypto";import Ku from"node:path";function dr(e){return`'${e.replace(/'/g,"'\\''")}'`}var Gu="craig",Ci=async(e,t,r)=>{let n=An(e,t),s=zu(),o=await I("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=Qu(o.stdout);return await Hu(e,n),i};var Hu=async(e,t)=>{let r=[["set-option","-t",t,"status","off"],["set-option","-t",t,"detach-on-destroy","off"],["set-window-option","-t",t,"pane-border-status","off"],["set-window-option","-t",t,"aggressive-resize","on"]];for(let n of r)await I("tmux",n,{cwd:e})},vi=async(e,t,r)=>{await I("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},Ei=async(e,t,r)=>{await I("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var Ai=async(e,t,r)=>{await I("tmux",["pipe-pane","-o","-t",e,`cat >> ${dr(t)}`],{cwd:r})},ur=async(e,t,r,n)=>{let s=n??Di(e);if(r?await I("tmux",["select-window","-t",r],{cwd:e}):await I("tmux",["select-window","-t",t],{cwd:e}),await I("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await I("tmux",["switch-client","-t",s],{cwd:e});return}await Xu(e,["attach-session","-t",s])};var xi=async(e,t)=>{await I("tmux",["kill-session","-t",t],{cwd:e})};var Di=e=>{let r=Ku.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=Vu("sha1").update(e).digest("hex").slice(0,8);return`${Gu}-${r}-${n}`},An=(e,t)=>`${Di(e)}-${t.toLowerCase()}`,zu=()=>{let e=Yu();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},Yu=()=>{let e=[process.stdout,process.stderr,process.stdin];for(let t of e){let r="columns"in t?t.columns:void 0,n="rows"in t?t.rows:void 0;if(typeof r=="number"&&r>0&&typeof n=="number"&&n>0)return{columns:r,rows:n}}return null},Qu=e=>{let t=Ju(e);if(t.length<3)throw new Error("tmux did not return the expected session, window, and pane targets for the Craig task session.");return{sessionName:t[0],windowTarget:t[1],paneId:t[2]}},Ju=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),Xu=async(e,t)=>{await new Promise((r,n)=>{let s=Bu("tmux",t,{cwd:e,stdio:"inherit"});s.on("error",n),s.on("exit",o=>{if(o===0){r();return}n(new Error(`tmux ${t.join(" ")} failed with exit code ${o??"unknown"}.`))})})};import{accessSync as Zu,constants as ep}from"node:fs";import{homedir as $i}from"node:os";import Ae from"node:path";var tp=[Ae.join($i(),".local","bin"),Ae.join($i(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function Mi(e=process.env){return rp([...(e.PATH??"").split(Ae.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:tp])}function Be(e=process.env){return{...e,PATH:Mi(e).join(Ae.delimiter)}}function xn(e,t={}){if(e.includes(Ae.sep)){let r=Ae.isAbsolute(e)?e:Ae.resolve(t.cwd??process.cwd(),e);return Oi(r)?r:null}for(let r of Mi(t.env)){let n=Ae.join(r,e);if(Oi(n))return n}return null}function Ve(e,t={}){let r=xn(e,t);if(r)return r;throw new Error(`Command not found: ${e}. Install it or add its directory to PATH. Craig also checks ~/.local/bin, /opt/homebrew/bin, and /usr/local/bin.`)}function Oi(e){try{return Zu(e,ep.X_OK),!0}catch{return!1}}function rp(e){return[...new Set(e)]}var Dt={async create(e,t){let r=await Ci(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await Ai(r.paneId,t.logPath,t.repoRoot);let n=await Ni({paneId:r.paneId,windowTarget:r.windowTarget,alive:!0}),s={id:t.sessionId,taskId:t.taskId,repoId:t.repoId,workspaceId:t.workspaceId,substrate:"tmux",sessionName:r.sessionName||An(t.repoRoot,t.taskId),paneId:r.paneId,windowTarget:r.windowTarget,worktreePath:t.worktreePath,logPath:t.logPath,command:t.command,status:"starting",startedAt:null,exitedAt:null,exitCode:null,lastAttachedAt:null,attach:{detachChord:"ctrl+]",lastSize:null},snapshot:n,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return await qe(e,s),s},async attach(e,t,r){let n=await Dt.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await ur(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await qe(e,s),s},async resize(e,t,r,n){await vi(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await qe(e,s),s},async write(){throw new Error("Direct session writes are owned by the terminal bridge.")},async read(){throw new Error("Direct session reads are owned by the terminal bridge.")},async terminate(e,t,r){let n={...t,status:"failed",exitedAt:new Date().toISOString(),snapshot:{...t.snapshot??{paneId:t.paneId,windowTarget:t.windowTarget,alive:!1,capturedAt:new Date().toISOString()},alive:!1,capturedAt:new Date().toISOString()},command:t.command};return await qe(e,n),n},async snapshot(e,t){return np(e,t)}},Dn={async prepare(e,t){let n=e.runnerSession.command[0],s=Be();Ve(n,{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=Ve(r[0],{cwd:e.worktreePath,env:Be()});await Ei(t.session.paneId,[n,...r.slice(1)].map(s=>dr(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},np=async(e,t)=>{let r=await x("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return Ni({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},Ni=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var $n=async(e,t,r,n={})=>{let s=r.trim(),o=await f.load(e),i=n.runner??f.runners.getDefault(o);if(f.runners.assertEnabled(i,o),t.trim().length===0)throw new Error(n.workspaceId?"Workspace id cannot be empty.":"Repo id cannot be empty.");if(s.length===0)throw new Error("Task prompt cannot be empty.");let a=n.workspaceId?await At(e,n.workspaceId,s,{runner:i,config:o}):await lt(e,t,s,{runner:i,config:o}),l=a.task,c=f.runners.buildCommand(i,s,o),d=`session_${l.id}`,u=l.artifacts.logPath?Li.resolve(e.workspaceRoot,l.artifacts.logPath):Li.join(e.logsDir,`${l.id}.log`);try{await Dn.prepare(l,{repoRoot:a.repoRoot});let m=await Dt.create(e,{sessionId:d,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:u,command:c});await Dn.launch(l,{repoRoot:a.repoRoot,session:m});let T=new Date().toISOString();m={...m,status:"running",startedAt:T,command:c};let R={...l,status:"running",runner:i,sessionId:m.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:m.command,pid:null,startedAt:T,lastKnownState:"running",exitCode:null,exitedAt:null}};return await P(e,R),await qe(e,m),{kind:"createTask",taskId:R.id,repoId:R.repoId,workspaceId:R.workspaceId,sessionId:m.id,status:R.status,branch:R.branch,worktreePath:R.worktreePath,runner:R.runner}}catch(m){let T={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:m instanceof Error?m.message:"Unknown Craig error"};throw await P(e,T),m}};import{mkdir as lp}from"node:fs/promises";import cp from"node:path";var ct=async e=>{let t=await x("gh",["auth","status"],{cwd:e});if(t.exitCode!==0)throw new Error(t.stderr.trim()||t.stdout.trim()||"GitHub CLI auth is required.")};var Fi=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await I("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},pr=async(e,t)=>{let r=await I("gh",_i(e),{cwd:t});return JSON.parse(r.stdout)},dt=async(e,t)=>{let r=await x("gh",_i(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},ji=async(e,t,r)=>{if(r.length===0)return[];let n=ip(r),s;try{s=await I("gh",["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`])}catch(a){throw sp(a)?new he(a instanceof Error?a.message:String(a)):a}let i=JSON.parse(s.stdout).data?.repository??{};return r.map((a,l)=>{let c=i[`item${l}`],d=ap(c);return{id:a.id,found:d!==null,view:d}})},Wi=async e=>{let t=await x("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:op(t.stdout.trim())},sp=e=>{let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase();return t.includes("rate limit")||t.includes("secondary rate limit")||t.includes("abuse detection")||t.includes("api rate limit exceeded")||t.includes("you have exceeded")},_i=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],op=e=>{let t=e.replace(/\.git$/,""),r=t.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)$/);if(r?.[1]&&r[2])return{owner:r[1],name:r[2]};let n=t.match(/^git@github\.com:([^/]+)\/([^/]+)$/);if(n?.[1]&&n[2])return{owner:n[1],name:n[2]};let s=t.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+)$/);return s?.[1]&&s[2]?{owner:s[1],name:s[2]}:null},ip=e=>`
|
|
35
18
|
query CraigPullRequestBatch($owner: String!, $name: String!) {
|
|
36
19
|
repository(owner: $owner, name: $name) {
|
|
37
20
|
${e.map((r,n)=>{let s=`item${n}`;return r.mode==="number"?`${s}: pullRequest(number: ${Number(r.selector)}) { ...PrFields }`:`${s}: pullRequests(headRefName: ${JSON.stringify(r.selector)}, states: OPEN, first: 1, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { ...PrFields } }`}).join(`
|
|
@@ -73,31 +56,6 @@ fragment PrFields on PullRequest {
|
|
|
73
56
|
}
|
|
74
57
|
}
|
|
75
58
|
}
|
|
76
|
-
commits(last: 1) {
|
|
77
|
-
nodes {
|
|
78
|
-
commit {
|
|
79
|
-
statusCheckRollup {
|
|
80
|
-
contexts(first: 100) {
|
|
81
|
-
nodes {
|
|
82
|
-
__typename
|
|
83
|
-
... on CheckRun {
|
|
84
|
-
name
|
|
85
|
-
status
|
|
86
|
-
conclusion
|
|
87
|
-
startedAt
|
|
88
|
-
completedAt
|
|
89
|
-
}
|
|
90
|
-
... on StatusContext {
|
|
91
|
-
context
|
|
92
|
-
state
|
|
93
|
-
createdAt
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
59
|
comments(last: 4) {
|
|
102
60
|
nodes {
|
|
103
61
|
author {
|
|
@@ -110,58 +68,56 @@ fragment PrFields on PullRequest {
|
|
|
110
68
|
}
|
|
111
69
|
}
|
|
112
70
|
}
|
|
113
|
-
`,
|
|
71
|
+
`,ap=e=>{if(!e||typeof e!="object")return null;let t="nodes"in e?e.nodes?.[0]??null:e;if(!t||typeof t!="object")return null;let r=t,n=r.statusCheckRollup?.contexts?.nodes??[];return{number:r.number,url:r.url,baseRefName:r.baseRefName,headRefName:r.headRefName,headRefOid:r.headRefOid??null,state:r.state,isDraft:r.isDraft??!1,title:r.title??null,createdAt:r.createdAt??null,updatedAt:r.updatedAt??null,mergedAt:r.mergedAt??null,mergeable:r.mergeable,mergeStateStatus:r.mergeStateStatus,reviewDecision:r.reviewDecision??null,statusCheckRollup:n,comments:r.comments?.nodes??[]}};var Ke=async(e,t)=>{let r=Ue(e,t.artifacts.prStatusPath);r&&(await lp(cp.dirname(r),{recursive:!0}),await U(r,{taskId:t.id,prs:t.prs}))},$t=async(e,t,r,n,s={readRawTask:re,validateTaskRecord:V,writeTask:P,writePrStatusArtifact:Ke})=>{let o=Pt(r,n),i=ot(t,o),a=bt(i.prs),l={...i,status:a};await s.writePrStatusArtifact(e,l);let c=await s.readRawTask(e,t.id),d=s.validateTaskRecord(c,`${e.tasksDir}/${t.id}.json`),u=d.status==="closed"?d.status:a,m=ot({...d,status:u},o);return await s.writeTask(e,m),m},Ot=async(e,t)=>{let r=$(t),n=r?.number?String(r.number):t.branch,s=await pr(n,t.worktreePath);return $t(e,t,s,r)},Mt=async(e,t)=>{for(let r of await On(t)){let n=await dt(r,t.worktreePath);if(!n)continue;return{discovered:!0,task:await $t(e,t,n,null)}}return{discovered:!1,task:t}},On=async e=>{let t=await hi(e.worktreePath).catch(()=>null);return[...new Set([t,e.branch].filter(r=>!!r))]};var ut=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await pr(n,r.worktreePath),a=qi(i);return r.pullRequest=a,await Ui(e,t,r.repoId,a),"synced"}let s=await dt(n,r.worktreePath);if(!s)return"not_found";let o=qi(s);return r.pullRequest=o,await Ui(e,t,r.repoId,o),"discovered"},Ui=async(e,t,r,n)=>{let s=await re(e,t.id),o=V(s,`${e.tasksDir}/${t.id}.json`),i=(o.repoTargets??t.repoTargets??[]).map(l=>l.repoId===r?{...l,pullRequest:n}:l),a={...o,repoTargets:i};return await P(e,a),a},qi=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:dp(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:up(e.reviewDecision??null),requiredChecks:St(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),dp=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,up=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var Nt=async(e,t)=>{let r=await v(e,t),n=$(r);return n?.number?(await ct(r.worktreePath),ve(n)?(await Mt(e,r)).task:Ot(e,r)):r},Nn=async(e,t)=>{let r=await v(e,t);if(r.type==="project"&&r.repoTargets?.length)return await pt(e,t),v(e,t);let n=$(r);if(await K(r),await ct(r.worktreePath),!n?.number||ve(n)){let o=await Mt(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return await Ke(e,o.task),o.task}let s=await Ot(e,r);return await Ke(e,s),s},pt=async(e,t)=>{let r=await v(e,t),n=(r.repoTargets??[]).filter(a=>a.status==="ready"),s={synced:0,discovered:0,notFound:0};for(let a of n){await ct(a.worktreePath);let l=a.pullRequest.number?await ut(e,r,a):await ut(e,r,a).catch(()=>"not_found");s[l==="not_found"?"notFound":l]++}let o=await re(e,r.id),i=V(o,`${e.tasksDir}/${r.id}.json`);return i.status!=="closed"&&(i.status=Vi(i),await P(e,i)),s},Ln=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=Mn(r,s);if(s.type==="project"&&s.repoTargets?.length){for(let d of s.repoTargets.filter(u=>u.status==="ready")){let u={id:`${s.id}:${d.repoId}`,task:s,targetRepoId:d.repoId,worktreePath:d.worktreePath,selector:d.pullRequest.number?String(d.pullRequest.number):d.branch,mode:d.pullRequest.number?"number":"head",fallbackSelectors:[]};await Bi(n,u).catch(async()=>{try{let m=d.pullRequest.number?await ut(e,s,d):await ut(e,s,d).catch(()=>"not_found");mr(o,m,d.pullRequest.number??null,d.pullRequest.url??null)}catch{}})}continue}let i=$(s),a=i?.number&&!ve(i),l=a?[]:await On(s),c={id:s.id,task:s,worktreePath:s.worktreePath,selector:a?String(i.number):l[0]??s.branch,mode:a?"number":"head",fallbackSelectors:a?[]:l.slice(1)};await Bi(n,c).catch(async()=>{try{let{disposition:d,task:u}=await fr(e,s.id),m=$(u);mr(o,d,m?.number??null,m?.url??null)}catch{}})}for(let s of n.values())try{await ct(s.worktreePath);let o=await ji(s.worktreePath,s.repository,s.items),i=new Map(o.map(a=>[a.id,a]));for(let a of s.items){let l=Mn(r,a.task),d=i.get(a.id)?.view??await hp(s.worktreePath,a);if(!d){mr(l,"not_found",null,null);continue}if(a.targetRepoId){let u=await re(e,a.task.id),m=V(u,`${e.tasksDir}/${a.task.id}.json`);await pp(e,m,a.targetRepoId,d)}else{let u=await re(e,a.task.id),m=V(u,`${e.tasksDir}/${a.task.id}.json`);await $t(e,m,d,a.mode==="number"?$(m):null)}mr(l,a.mode==="number"?"synced":"discovered",d.number,d.url)}}catch(o){if(o instanceof he)throw o}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await re(e,s.id),i=V(o,`${e.tasksDir}/${s.id}.json`);i.status!=="closed"&&(i.status=Vi(i),await P(e,i))}return t.map(s=>Mn(r,s))},fr=async(e,t)=>{let r=await v(e,t);await K(r),await ct(r.worktreePath);let n=$(r);if(n?.number&&!ve(n))return{disposition:"synced",task:await Ot(e,r)};let s=await Mt(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},Vi=e=>{let t=(e.repoTargets??[]).filter(n=>n.status==="ready"),r=t.map(n=>n.pullRequest).filter(n=>!!n.number);return r.length===0?e.status:r.every(n=>n.status==="merged")?"merged":r.length===t.length&&r.every(kp)?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"},pp=async(e,t,r,n)=>{let s=mp(n),o=(t.repoTargets??[]).map(a=>a.repoId===r?{...a,pullRequest:s}:a),i={...t,repoTargets:o};return await P(e,i),i},mp=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:fp(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:gp(e.reviewDecision??null),requiredChecks:St(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),fp=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,gp=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,hp=async(e,t)=>{if(t.mode!=="head")return null;for(let r of t.fallbackSelectors){let n=await dt(r,e);if(n)return n}return null},Bi=async(e,t)=>{let r=await Wi(t.worktreePath);if(!r)throw new Error("GitHub repository remote could not be parsed.");let n=`${r.owner}/${r.name}`,s=e.get(n);if(s){s.items.push(t);return}e.set(n,{worktreePath:t.worktreePath,repository:r,items:[t]})},Mn=(e,t)=>{let r=e.get(t.id);if(r)return r;let n={taskId:t.id,synced:0,discovered:0,notFound:0,hadPr:t.type==="project"?!!t.repoTargets?.some(s=>s.pullRequest.number):!!$(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},mr=(e,t,r,n)=>{if(t==="synced"){e.synced+=1;return}if(t==="discovered"){e.discovered+=1,e.firstDiscoveredPrNumber??=r,e.firstDiscoveredPrUrl??=n;return}e.notFound+=1},kp=e=>e.mergeable&&e.reviewDecision!=="REVIEW_REQUIRED"&&e.reviewDecision!=="CHANGES_REQUESTED"&&e.mergeStateStatus!=="REVIEW_REQUIRED"&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped");var Fn=async(e,t)=>{let r=await v(e,t);try{r.type==="project"&&r.repoTargets?.length?(await pt(e,t),r=await v(e,t)):r.prs.some(o=>o.number)&&(r=await Nt(e,t))}catch{}let n=await It(e,r),s=r.sessionId?await Ee(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var jn=async(e,t)=>{let r=await v(e,t);if(await K(r),(await I("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await wp(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},wp=async e=>{let t=[],r=await I("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await Tp(e);for(let s of n){let o=await x("git",["diff","--no-index","--stat","--patch","--","/dev/null",s],{cwd:e});t.push(o.stdout.trimEnd())}return t.join(`
|
|
114
72
|
|
|
115
|
-
`)},
|
|
116
|
-
`).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as Iu}from"node:child_process";import{access as vu}from"node:fs/promises";var Tn=async(e,t)=>{let r=await v(e,t),n=Je(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await vu(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},Rn=async e=>{await new Promise((t,r)=>{let n=!1,s=Iu("tail",["-n","+1","-f",e],{stdio:"inherit"}),o=()=>{n=!0,s.kill("SIGINT")};process.on("SIGINT",o),s.on("error",a=>{i(),r(a)}),s.on("exit",(a,l)=>{if(i(),n||l==="SIGINT"){t();return}if(a===0){t();return}r(new Error(`tail -n +1 -f ${e} failed with exit code ${a??"unknown"}.`))});function i(){process.off("SIGINT",o)}})};import{mkdir as Cu}from"node:fs/promises";import Eu from"node:path";var bn=async(e,t)=>{let r=await v(e,t);if(await B(r),r.status==="draft"||r.status==="merged")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);if(r.status==="running"&&await Qt(r.worktreePath)&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);let s=(await f.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);r.checks.status="running",r.checks.commands=[...s],r.checks.results=[],await S(e,r);let o=[];for(let i of s){let a=new Date().toISOString(),l=await x("sh",["-lc",i],{cwd:r.worktreePath}),d=new Date().toISOString(),c=l.exitCode??1;if(o.push({command:i,startedAt:a,finishedAt:d,exitCode:c}),c!==0)return r.checks.results=o,r.checks.status="failed",r.checks.lastRunAt=d,r.status="review",r.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await pi(e,r),await S(e,r),{kind:"runChecks",taskId:r.id,status:"failed",commands:s}}return r.checks.results=o,r.checks.status="passed",r.checks.lastRunAt=new Date().toISOString(),r.status="checked",r.lastFailureReason=null,await pi(e,r),await S(e,r),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},pi=async(e,t)=>{let r=Le(e,t.artifacts.checkSummaryPath);r&&(await Cu(Eu.dirname(r),{recursive:!0}),await N(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var Pn=async(e,t)=>{let r=await v(e,t);await B(r);let n=await Qt(r.worktreePath);if(r.status==="running"&&n&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot commit from status "${r.status}".`);if(!n)throw new Error(`Task ${r.id} has no uncommitted diff to commit.`);let s=r.prompt.value.trim();await Mo(r.worktreePath),await Lo(r.worktreePath,s);let o=await Oo(r.worktreePath);return r.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},r.lastFailureReason=null,await S(e,r),{kind:"commitTask",taskId:r.id,status:r.status,commitSha:o.sha,message:o.message}};import{access as Au}from"node:fs/promises";var Sn=async(e,t)=>{let r=await v(e,t),n=await xu(r.worktreePath),s={...r,status:"closed",cleanup:{...r.cleanup,preservedWorktree:n&&r.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await S(e,s),s},xu=async e=>{try{return await Au(e),!0}catch{return!1}};var In=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await be(e,t.sessionId);await Qo(e.repoRoot,s.sessionName),t.cleanup.paneClosedAt=new Date().toISOString()}}catch(s){n.push(s instanceof Error?s.message:"Failed to close tmux session.")}if(t.cleanup.preservedWorktree=r.preserveWorktree,!r.preserveWorktree)try{await Fo(e.repoRoot,t.worktreePath),t.cleanup.worktreeRemovedAt=new Date().toISOString()}catch(s){n.push(s instanceof Error?s.message:"Failed to remove worktree.")}t.cleanup.warning=n.length>0?n.join(" "):null,await S(e,t)};var vn=async(e,t,r)=>{let[n,s]=await Promise.all([v(e,t),ne(e,r)]);if(n.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${n.id}.`);let o=n.linkedRepoIds.includes(s.id)?n.linkedRepoIds:[...n.linkedRepoIds,s.id];return await S(e,{...n,linkedRepoIds:o}),{kind:"addTaskLink",taskId:n.id,repoId:s.id,linkedRepoIds:o}},Cn=async(e,t)=>{let r=await v(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>ne(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var En=async(e,t)=>{let r=await v(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session to attach.`);let[n,s]=await Promise.all([ne(e,r.repoId),be(e,r.sessionId)]),o=await Tt.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var An=async(e,t)=>{let r=await v(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await be(e,r.sessionId).catch(s=>{throw Du(s)?new Error(`Task ${r.id} does not have a Craig session.`):s});if(!n.paneId)throw new Error(`Task ${r.id} does not have a tmux target.`);return await er(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},Du=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as $u}from"node:child_process";var xn=async(e,t)=>{let r=await v(e,t);await B(r);let s=(await f.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!1,command:null};let o=[...s,r.worktreePath];return await Mu(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},Mu=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=$u(s,o,{cwd:t,stdio:"inherit"});i.on("error",n),i.on("exit",a=>{if(a===0){r();return}n(new Error(`${e.join(" ")} failed with exit code ${a??"unknown"}.`))})})};var Dn=async(e,t,r)=>{let n=await ee(e,t);await S(e,{...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})},$n=async(e,t,r)=>{let n=await ee(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await S(e,s),s},Mn=async(e,t)=>{let r=await ee(e,t),n=r.ptyTabs.find(o=>o.kind==="agent");if(!n)throw new Error(`Task ${t} is missing its agent PTY tab.`);let s={...r,status:"running",selectedPtyTabId:n.id,runnerSession:{...r.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await S(e,s),s};var Ln=async(e,t,r="merge",n)=>{let s=await v(e,t),o=n??D(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await si(s.worktreePath,o,r)};var C={listTasks:sn,getTask:v,provisionTask:Ze,provisionProjectTask:kt,createTask:mn,showTask:kn,showTaskDiff:yn,prepareTaskLogs:Tn,streamTaskLogs:Rn,runChecks:bn,commitTask:Pn,closeTask:Sn,cleanupTask:In,addTaskLink:vn,listTaskLinks:Cn,sortTasksForDisplay:on,resolveSelectedTaskId:an,allocateTaskId:nn,allocateTaskIdForRepo:Xe,allocateProjectTaskId:ht,createDefaultTaskPtyTabs:yt,assertTaskWorktreeExists:B,resolveTaskLogPath:Je,buildTaskInspection:gt,resolveArtifactPath:Le,attachTask:En,focusTask:An,openTask:xn,markRunnerFailed:Dn,recordStartupFailure:$n,markTaskStarted:Mn,prs:{refresh:St,refreshChecks:hn,discoverOrRefresh:nr,discoverOrRefreshAll:nt,discoverOrRefreshMany:wn,merge:Ln,getPrimaryPr:D,isPrTerminal:Re,isMergeReady:Yt,deriveTaskStatus:pt,upsertPr:Qe,normalizePr:mt,summarizeRequiredChecks:en,writePrStatusArtifact:Ne}};async function mi(e,t){switch(e.kind){case"addWorkspace":{let r=await Q.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await On(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await Q.repos.addRepo(t.paths,e.path);return await On(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return Q.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await He({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await Z(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await Q.repos.removeRepo(t.paths,e.repoId,{listTasks:C.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await Te({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await Te({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return Q.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await Q.archiveWorkspace(t.paths,e.workspaceId);return await Lu(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await Q.restoreWorkspace(t.paths,e.workspaceId);return await On(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return Q.removeWorkspace(t.paths,e.workspaceId,{listTasks:C.listTasks});case"createTask":return C.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?C.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):C.listTasks(t.paths);case"attachTask":return C.attachTask(t.paths,e.taskId);case"addTaskLink":return C.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return C.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return C.showTask(t.paths,e.taskId);case"showSelectedTask":return C.showTask(t.paths,We(t,"show"));case"streamTaskLogs":return C.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return C.prepareTaskLogs(t.paths,We(t,"logs"));case"showTaskDiff":return C.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return C.showTaskDiff(t.paths,We(t,"diff"));case"focusTask":return C.focusTask(t.paths,e.taskId);case"focusSelectedTask":return C.focusTask(t.paths,We(t,"focus"));case"openTask":return C.openTask(t.paths,e.taskId);case"openSelectedTask":return C.openTask(t.paths,We(t,"open"));case"runChecks":return C.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return C.runChecks(t.paths,We(t,"check"));case"commitTask":return C.commitTask(t.paths,e.taskId);case"commitSelectedTask":return C.commitTask(t.paths,We(t,"commit"));case"help":return{kind:"help",text:G()};case"exit":return{kind:"exit"};default:return Ou(e)}}async function On(e,t,r){let n=await He({uiStateFile:e.uiStateFile})??Ut();await Te({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function Lu(e,t){let r=await He({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Te({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function Ou(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function We(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function fi(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(`
|
|
73
|
+
`)},Tp=async e=>(await I("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
|
|
74
|
+
`).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as Rp}from"node:child_process";import{access as yp}from"node:fs/promises";var Wn=async(e,t)=>{let r=await v(e,t),n=it(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await yp(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},_n=async e=>{await new Promise((t,r)=>{let n=!1,s=Rp("tail",["-n","+1","-f",e],{stdio:"inherit"}),o=()=>{n=!0,s.kill("SIGINT")};process.on("SIGINT",o),s.on("error",a=>{i(),r(a)}),s.on("exit",(a,l)=>{if(i(),n||l==="SIGINT"){t();return}if(a===0){t();return}r(new Error(`tail -n +1 -f ${e} failed with exit code ${a??"unknown"}.`))});function i(){process.off("SIGINT",o)}})};import{mkdir as bp}from"node:fs/promises";import Pp from"node:path";var Un=async(e,t)=>{let r=await v(e,t);if(await K(r),r.status==="draft"||r.status==="merged")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);if(r.status==="running"&&await ar(r.worktreePath)&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot run checks from status "${r.status}".`);let s=(await f.load(e)).checks?.commands??[];if(s.length===0)throw new Error(`Craig config at ${e.configFile} does not define any "checks.commands".`);r.checks.status="running",r.checks.commands=[...s],r.checks.results=[],await P(e,r);let o=[];for(let i of s){let a=new Date().toISOString(),l=await x("sh",["-lc",i],{cwd:r.worktreePath}),c=new Date().toISOString(),d=l.exitCode??1;if(o.push({command:i,startedAt:a,finishedAt:c,exitCode:d}),d!==0)return r.checks.results=o,r.checks.status="failed",r.checks.lastRunAt=c,r.status="review",r.lastFailureReason=l.stderr.trim()||l.stdout.trim()||`Check command failed: ${i}`,await Ki(e,r),await P(e,r),{kind:"runChecks",taskId:r.id,status:"failed",commands:s}}return r.checks.results=o,r.checks.status="passed",r.checks.lastRunAt=new Date().toISOString(),r.status="checked",r.lastFailureReason=null,await Ki(e,r),await P(e,r),{kind:"runChecks",taskId:r.id,status:"passed",commands:s}},Ki=async(e,t)=>{let r=Ue(e,t.artifacts.checkSummaryPath);r&&(await bp(Pp.dirname(r),{recursive:!0}),await U(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var qn=async(e,t)=>{let r=await v(e,t);await K(r);let n=await ar(r.worktreePath);if(r.status==="running"&&n&&(r.status="review"),r.status!=="review"&&r.status!=="checked")throw new Error(`Task ${r.id} cannot commit from status "${r.status}".`);if(!n)throw new Error(`Task ${r.id} has no uncommitted diff to commit.`);let s=r.prompt.value.trim();await mi(r.worktreePath),await fi(r.worktreePath,s);let o=await gi(r.worktreePath);return r.lastCommit={sha:o.sha,message:o.message,committedAt:new Date().toISOString()},r.lastFailureReason=null,await P(e,r),{kind:"commitTask",taskId:r.id,status:r.status,commitSha:o.sha,message:o.message}};import{access as Sp}from"node:fs/promises";var Bn=async(e,t)=>{let r=await v(e,t),n=await Ip(r.worktreePath),s={...r,status:"closed",cleanup:{...r.cleanup,preservedWorktree:n&&r.cleanup.worktreeRemovedAt===null,warning:null},lastFailureReason:null};return await P(e,s),s},Ip=async e=>{try{return await Sp(e),!0}catch{return!1}};var Vn=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await Ee(e,t.sessionId);await xi(e.repoRoot,s.sessionName),t.cleanup.paneClosedAt=new Date().toISOString()}}catch(s){n.push(s instanceof Error?s.message:"Failed to close tmux session.")}if(t.cleanup.preservedWorktree=r.preserveWorktree,!r.preserveWorktree)try{await ki(e.repoRoot,t.worktreePath),t.cleanup.worktreeRemovedAt=new Date().toISOString()}catch(s){n.push(s instanceof Error?s.message:"Failed to remove worktree.")}t.cleanup.warning=n.length>0?n.join(" "):null,await P(e,t)};var Kn=async(e,t,r)=>{let[n,s]=await Promise.all([v(e,t),ce(e,r)]);if(n.repoId===s.id)throw new Error(`Repo ${s.id} is already the primary repo for task ${n.id}.`);let o=n.linkedRepoIds.includes(s.id)?n.linkedRepoIds:[...n.linkedRepoIds,s.id];return await P(e,{...n,linkedRepoIds:o}),{kind:"addTaskLink",taskId:n.id,repoId:s.id,linkedRepoIds:o}},Gn=async(e,t)=>{let r=await v(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>ce(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var Hn=async(e,t)=>{let r=await v(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session to attach.`);let[n,s]=await Promise.all([ce(e,r.repoId),Ee(e,r.sessionId)]),o=await Dt.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var zn=async(e,t)=>{let r=await v(e,t);if(!r.sessionId)throw new Error(`Task ${r.id} does not have a Craig session.`);let n=await Ee(e,r.sessionId).catch(s=>{throw Cp(s)?new Error(`Task ${r.id} does not have a Craig session.`):s});if(!n.paneId)throw new Error(`Task ${r.id} does not have a tmux target.`);return await ur(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},Cp=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as vp}from"node:child_process";var Yn=async(e,t)=>{let r=await v(e,t);await K(r);let s=(await f.load(e)).open?.command??[];if(s.length===0)return{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!1,command:null};let o=[...s,r.worktreePath];return await Ep(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},Ep=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=vp(s,o,{cwd:t,stdio:"inherit"});i.on("error",n),i.on("exit",a=>{if(a===0){r();return}n(new Error(`${e.join(" ")} failed with exit code ${a??"unknown"}.`))})})};var Qn=async(e,t,r)=>{let n=await ae(e,t);await P(e,{...n,status:n.status==="running"?"draft":n.status,runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r})},Jn=async(e,t,r)=>{let n=await ae(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await P(e,s),s},Xn=async(e,t)=>{let r=await ae(e,t),n=r.ptyTabs.find(o=>o.kind==="agent");if(!n)throw new Error(`Task ${t} is missing its agent PTY tab.`);let s={...r,status:"running",selectedPtyTabId:n.id,runnerSession:{...r.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await P(e,s),s};import{realpath as Hi}from"node:fs/promises";import Lt from"node:path";async function es(e,t){if(t.explicitTaskId!==void 0){let l=await Gi(e,t.explicitTaskId,"explicit");return Zn(l,"explicit",t.environmentAgentTabId)}if(t.environmentTaskId!==void 0){let l=await Gi(e,t.environmentTaskId,"environment");return Zn(l,"environment",t.environmentAgentTabId)}let r=await Hi(t.cwd).catch(()=>Lt.resolve(t.cwd)),n=await vt(e,{includeClosed:!0}),o=(await Promise.all(n.tasks.map(async l=>({task:l,matches:await xp(l,r)})))).filter(l=>l.matches).map(l=>l.task),i=[...new Map(o.map(l=>[l.id,l])).values()];if(i.length>1)throw new S("TASK_CONTEXT_AMBIGUOUS",`Multiple Craig tasks match ${r}: ${i.map(l=>l.id).join(", ")}. Use --task <id>.`,{details:{cwd:r,taskIds:i.map(l=>l.id)}});let a=i[0];if(a)return Zn(a,"cwd",t.environmentAgentTabId);if(t.environmentAgentTabId!==void 0)throw new S("TASK_CONTEXT_CONFLICT",`CRAIG_AGENT_TAB_ID is set to ${t.environmentAgentTabId}, but no task context could be resolved.`,{details:{agentTabId:t.environmentAgentTabId}});if(t.required)throw new S("TASK_CONTEXT_NOT_FOUND",`No Craig task was found from ${r}. Use --task <id> or run the command inside a task worktree.`,{details:{cwd:r}});return null}async function Gi(e,t,r){try{return await v(e,t)}catch(n){throw!(n instanceof S)||n.code!=="TASK_NOT_FOUND"?n:new S("TASK_CONTEXT_NOT_FOUND",`Craig task "${t}" from ${r==="explicit"?"--task":"CRAIG_TASK_ID"} was not found.`,{details:{taskId:t,source:r},cause:n})}}function Zn(e,t,r){let n=r??null;if(n!==null){let s=e.ptyTabs.find(o=>o.id===n);if(!s||s.kind!=="agent")throw new S("TASK_CONTEXT_CONFLICT",`Agent tab ${n} does not belong to Craig task ${e.id}.`,{details:{taskId:e.id,agentTabId:n}})}return{task:e,source:t,agentTabId:n}}function Ap(e){return[e.worktreePath,...e.bundlePath?[e.bundlePath]:[],...(e.repoTargets??[]).map(t=>t.worktreePath)]}async function xp(e,t){return(await Promise.all(Ap(e).map(n=>Hi(n).catch(()=>Lt.resolve(n))))).some(n=>Dp(n,t))}function Dp(e,t){let r=Lt.relative(Lt.resolve(e),t);return r===""||!r.startsWith("..")&&!Lt.isAbsolute(r)}var ts=async(e,t,r="merge",n)=>{let s=await v(e,t),o=n??$(s)?.number;if(!o)throw new Error(`Task ${s.id} has no pull request to merge.`);await Fi(s.worktreePath,o,r)};var E={listTasks:vt,getTask:v,provisionTask:lt,provisionProjectTask:At,createTask:$n,showTask:Fn,showTaskDiff:jn,prepareTaskLogs:Wn,streamTaskLogs:_n,runChecks:Un,commitTask:qn,closeTask:Bn,cleanupTask:Vn,addTaskLink:Kn,listTaskLinks:Gn,sortTasksForDisplay:In,resolveSelectedTaskId:Cn,allocateTaskId:Sn,allocateTaskIdForRepo:at,allocateProjectTaskId:Ct,createDefaultTaskPtyTabs:xt,assertTaskWorktreeExists:K,resolveTaskLogPath:it,buildTaskInspection:It,resolveArtifactPath:Ue,attachTask:Hn,focusTask:zn,openTask:Yn,markRunnerFailed:Qn,recordStartupFailure:Jn,markTaskStarted:Xn,resolveContext:es,prs:{refresh:Nt,refreshChecks:Nn,discoverOrRefresh:fr,discoverOrRefreshAll:pt,discoverOrRefreshMany:Ln,merge:ts,getPrimaryPr:$,isPrTerminal:ve,isMergeReady:ir,deriveTaskStatus:bt,upsertPr:ot,normalizePr:Pt,summarizeRequiredChecks:yn,writePrStatusArtifact:Ke}};async function Yi(e,t){switch(e.kind){case"addWorkspace":{let r=await H.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await rs(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await H.repos.addRepo(t.paths,e.path);return await rs(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return H.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await Ze({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await ie(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await H.repos.removeRepo(t.paths,e.repoId,{listTasks:E.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await Ce({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await Ce({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return H.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await H.archiveWorkspace(t.paths,e.workspaceId);return await $p(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await H.restoreWorkspace(t.paths,e.workspaceId);return await rs(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return H.removeWorkspace(t.paths,e.workspaceId,{listTasks:E.listTasks});case"createTask":return E.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?E.listTasks(t.paths,{...e.repoId?{repoId:e.repoId}:{},...e.workspaceId?{workspaceId:e.workspaceId}:{}}):E.listTasks(t.paths);case"currentTask":{let r=zi(t);return{kind:"currentTask",task:r.task,context:{source:r.source,agentTabId:r.agentTabId}}}case"attachTask":return E.attachTask(t.paths,e.taskId);case"addTaskLink":return E.addTaskLink(t.paths,e.taskId,e.repoId);case"listTaskLinks":return E.listTaskLinks(t.paths,e.taskId);case"refreshInteractiveState":throw new Error("Interactive refresh should be handled by the interactive app.");case"showTask":return E.showTask(t.paths,e.taskId);case"showCurrentTask":return E.showTask(t.paths,zi(t).task.id);case"showSelectedTask":return E.showTask(t.paths,Ge(t,"show"));case"streamTaskLogs":return E.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return E.prepareTaskLogs(t.paths,Ge(t,"logs"));case"showTaskDiff":return E.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return E.showTaskDiff(t.paths,Ge(t,"diff"));case"focusTask":return E.focusTask(t.paths,e.taskId);case"focusSelectedTask":return E.focusTask(t.paths,Ge(t,"focus"));case"openTask":return E.openTask(t.paths,e.taskId);case"openSelectedTask":return E.openTask(t.paths,Ge(t,"open"));case"runChecks":return E.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return E.runChecks(t.paths,Ge(t,"check"));case"commitTask":return E.commitTask(t.paths,e.taskId);case"commitSelectedTask":return E.commitTask(t.paths,Ge(t,"commit"));case"showContext":{let r=Mp(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:sn()};case"exit":return{kind:"exit"};default:return Op(e)}}async function rs(e,t,r){let n=await Ze({uiStateFile:e.uiStateFile})??Jt();await Ce({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function $p(e,t){let r=await Ze({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Ce({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function Op(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Ge(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function zi(e){if(e.taskContext)return e.taskContext;throw new Error("Command requires resolved task context.")}function Mp(e){if(e.workspaceContext)return e.workspaceContext;throw new Error("Command requires resolved workspace context.")}function Qi(e){switch(e.kind){case"createWorkspace":return[`${e.created?"Registered":"Updated"} ${e.workspace.kind??"repo"} workspace ${e.workspace.id}`,`Path: ${e.workspace.rootPath??""}`,`Repos: ${e.repos.map(t=>t.id).join(", ")}`].join(`
|
|
117
75
|
`);case"createRepo":return[`${e.created?"Registered":"Already registered"} repo ${e.repo.id}`,`Path: ${e.repo.rootPath}`,`Branch: ${e.repo.defaultBranch}`,`Workspace: ${e.workspaceId}`].join(`
|
|
118
76
|
`);case"listRepos":return e.repos.length===0?"No repos registered yet. Use 'craig repo add <path>'.":["ID NAME BRANCH PATH",...e.repos.map(t=>`${t.id} ${t.name} ${t.defaultBranch} ${t.rootPath}`)].join(`
|
|
119
77
|
`);case"removeRepo":return`Removed repo ${e.repoId} (${e.rootPath})`;case"listWorkspaces":return e.workspaces.length===0?e.archivedOnly?"No archived workspaces.":"No active workspaces yet. Register one with 'craig workspace add <path>'.":["ID KIND STATUS REPOS PATH",...e.workspaces.map(t=>`${t.id} ${t.kind??"repo"} ${t.status} ${(t.discoveredRepoIds??[t.primaryRepoId]).join(",")} ${t.rootPath??""}`)].join(`
|
|
120
78
|
`);case"archiveWorkspace":return`Archived workspace ${e.workspaceId} on branch ${e.branch}`;case"restoreWorkspace":return`Restored workspace ${e.workspaceId} on branch ${e.branch}`;case"removeWorkspace":return`Removed workspace ${e.workspaceId} (${e.rootPath})`;case"createTask":return[`Created task ${e.taskId}`,`Repo: ${e.repoId}`,`Workspace: ${e.workspaceId}`,`Session: ${e.sessionId}`,`Status: ${e.status}`,`Branch: ${e.branch}`,`Worktree: ${e.worktreePath}`,`Runner: ${e.runner}`].join(`
|
|
121
79
|
`);case"attachTask":return`Attached to task ${e.taskId} via session ${e.sessionId}`;case"addTaskLink":return`Linked repo ${e.repoId} to task ${e.taskId}: ${e.linkedRepoIds.join(", ")}`;case"listTaskLinks":return e.repos.length===0?`Task ${e.taskId} has no linked repos.`:["ID NAME BRANCH PATH",...e.repos.map(t=>`${t.id} ${t.name} ${t.defaultBranch} ${t.rootPath}`)].join(`
|
|
122
|
-
`);case"help":return e.text;case"exit":return"";case"listTasks":return e.tasks.length===0?`No Craig tasks yet. Use 'task new --repo <repo-id> <prompt>' to create one.${e.missingTaskIds.length>0?` (${e.missingTaskIds.length} referenced task file(s) missing from .craig/tasks)`:""}`:["ID REPO STATUS CHECKS PR TITLE",...e.tasks.map(t=>`${t.id} ${t.repoId} ${t.status} ${
|
|
123
|
-
`);case"showTask":return[`${e.task.id}: ${e.task.title}`,`Status: ${e.task.status}`,`Runner: ${e.task.runner}`,`Repo: ${e.task.repoId}`,`Workspace: ${e.task.workspaceId}`,`Branch: ${e.task.branch}`,`Worktree: ${e.task.worktreePath}`,`Session: ${e.task.sessionId??"<missing>"}`,`tmux: ${e.session?.paneId??"<missing>"}`,`Linked repos: ${e.task.linkedRepoIds.length>0?e.task.linkedRepoIds.join(", "):"none"}`,`Prompt: ${e.task.prompt.source} ${JSON.stringify(e.task.prompt.value)}`,`Runner command: ${e.inspection.runnerCommandText||"<none>"}`,`Runner state: ${e.task.runnerSession.lastKnownState}`,`Started: ${e.task.runnerSession.startedAt??"not started"}`,`Exited: ${e.task.runnerSession.exitedAt??"still running"}`,`Checks: ${e.inspection.checksSummary}`,`Last commit: ${e.inspection.lastCommitSummary}`,`PR: ${e.inspection.prSummary}`,`Cleanup: ${e.inspection.cleanupSummary}`,...
|
|
80
|
+
`);case"help":return e.text;case"exit":return"";case"listTasks":return e.tasks.length===0?`No Craig tasks yet. Use 'task new --repo <repo-id> <prompt>' to create one.${e.missingTaskIds.length>0?` (${e.missingTaskIds.length} referenced task file(s) missing from .craig/tasks)`:""}`:["ID REPO STATUS CHECKS PR TITLE",...e.tasks.map(t=>`${t.id} ${t.repoId} ${t.status} ${Fp(t)} ${jp(t)} ${t.title}`)].join(`
|
|
81
|
+
`);case"showTask":return[`${e.task.id}: ${e.task.title}`,`Status: ${e.task.status}`,`Runner: ${e.task.runner}`,`Repo: ${e.task.repoId}`,`Workspace: ${e.task.workspaceId}`,`Branch: ${e.task.branch}`,`Worktree: ${e.task.worktreePath}`,`Session: ${e.task.sessionId??"<missing>"}`,`tmux: ${e.session?.paneId??"<missing>"}`,`Linked repos: ${e.task.linkedRepoIds.length>0?e.task.linkedRepoIds.join(", "):"none"}`,`Prompt: ${e.task.prompt.source} ${JSON.stringify(e.task.prompt.value)}`,`Runner command: ${e.inspection.runnerCommandText||"<none>"}`,`Runner state: ${e.task.runnerSession.lastKnownState}`,`Started: ${e.task.runnerSession.startedAt??"not started"}`,`Exited: ${e.task.runnerSession.exitedAt??"still running"}`,`Checks: ${e.inspection.checksSummary}`,`Last commit: ${e.inspection.lastCommitSummary}`,`PR: ${e.inspection.prSummary}`,`Cleanup: ${e.inspection.cleanupSummary}`,...Np(e)].join(`
|
|
82
|
+
`);case"currentTask":return[`${e.task.id}: ${e.task.title}`,`Workspace: ${e.task.workspaceId}`,`Repo: ${e.task.repoId}`,`Worktree: ${e.task.worktreePath}`,`Context source: ${e.context.source}`,`Agent tab: ${e.context.agentTabId??"none"}`].join(`
|
|
83
|
+
`);case"showContext":return[`Workspace: ${e.workspace.root}`,`Workspace source: ${e.workspace.source}`,`Initialized: ${e.workspace.initialized?"yes":"no"}`,`Task: ${e.task?.id??"none"}`,`Task source: ${e.task?.source??"none"}`,`Agent tab: ${e.task?.agentTabId??"none"}`].join(`
|
|
124
84
|
`);case"streamTaskLogs":return`Streaming logs for ${e.taskId} from ${e.logPath}`;case"showTaskDiff":return e.isEmpty?`Task ${e.taskId} has no uncommitted diff.`:e.diffText;case"focusTask":return`Focused task ${e.taskId} on ${e.tmuxTarget}`;case"openTask":return e.launched?`Opened task ${e.taskId} at ${e.worktreePath}`:e.worktreePath;case"runChecks":return`Checks ${e.status} for ${e.taskId}: ${e.commands.join(", ")}`;case"commitTask":return[`Committed task ${e.taskId}`,`Status: ${e.status}`,`Commit: ${e.commitSha}`,`Message: ${e.message}`].join(`
|
|
125
|
-
`);default:return
|
|
126
|
-
`)
|
|
127
|
-
`)){let
|
|
128
|
-
`)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
${
|
|
85
|
+
`);default:return Lp(e)}}function Np(e){let t=[];return e.inspection.worktreeExists||e.task.status==="merged"&&!e.task.cleanup.preservedWorktree&&e.task.cleanup.worktreeRemovedAt||t.push(`Warning: worktree is missing at ${e.task.worktreePath}`),e.task.cleanup.warning&&!(e.task.status==="merged"&&!e.task.cleanup.worktreeRemovedAt)&&t.push(`Cleanup warning: ${e.task.cleanup.warning}`),e.task.artifacts.logPath&&!e.inspection.logExists&&t.push(`Warning: log file is missing at ${e.task.artifacts.logPath}`),e.inspection.recentFailureReason&&t.push(`Last failure: ${e.inspection.recentFailureReason}`),t}function Lp(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function Fp(e){return e.checks.status}function jp(e){if(e.type==="project"&&e.repoTargets?.length){let r=e.repoTargets.filter(s=>s.pullRequest.number);if(r.length===0)return"-";let n=r.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(n).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}function Ji(e,t){return JSON.stringify({schemaVersion:1,command:e,ok:!0,data:t,warnings:[]})}function Xi(e,t){let r={schemaVersion:1,command:e,ok:!1,error:{code:t.code,message:t.message,retryable:t.retryable,details:t.details}};return JSON.stringify(r)}async function ns(e){let t=await H.resolveContext({cwd:e.cwd,...e.explicitWorkspaceRoot!==void 0?{explicitWorkspaceRoot:e.explicitWorkspaceRoot}:{},...e.environmentWorkspaceRoot!==void 0?{environmentWorkspaceRoot:e.environmentWorkspaceRoot}:{},...e.allowUninitializedWorkspace!==void 0?{allowUninitializedCwd:e.allowUninitializedWorkspace}:{}}),r=ee(t.workspaceRoot),n=e.resolveTask===!0||e.requireTask===!0||e.explicitTaskId!==void 0||e.environmentTaskId!==void 0||e.environmentAgentTabId!==void 0;if(n&&!t.initialized)throw new S("TASK_CONTEXT_NOT_FOUND",`Task context cannot be resolved because ${t.workspaceRoot} is not an initialized Craig workspace.`,{details:{workspaceRoot:t.workspaceRoot}});let s=n&&t.initialized?await E.resolveContext(r,{cwd:e.cwd,...e.explicitTaskId!==void 0?{explicitTaskId:e.explicitTaskId}:{},...e.environmentTaskId!==void 0?{environmentTaskId:e.environmentTaskId}:{},...e.environmentAgentTabId!==void 0?{environmentAgentTabId:e.environmentAgentTabId}:{},...e.requireTask!==void 0?{required:e.requireTask}:{}}):null;return{paths:r,workspace:t,task:s}}async function Zi(e){let t="cli",r=$o(e.argv);try{let n=Do(e.argv);if(r=n.options.json,n.mode==="interactive"){if(n.options.noInput||n.options.json||Bp(e.env)||!e.isInputTty||!e.isOutputTty)throw new S("INPUT_REQUIRED","Interactive Craig requires a TTY. Provide a command instead of starting the terminal application.",{});let c=await ns({cwd:e.cwd,...n.options.workspaceRoot!==void 0?{explicitWorkspaceRoot:n.options.workspaceRoot}:{},...e.env.CRAIG_WORKSPACE_ROOT!==void 0?{environmentWorkspaceRoot:e.env.CRAIG_WORKSPACE_ROOT}:{},allowUninitializedWorkspace:!0});return e.runInteractive(c.workspace.workspaceRoot)}if(!n.command||!n.commandName)throw new S("CLI_USAGE","Command mode requires a command.",{});t=n.commandName,Up(n.command,n.options.taskId);let s=_p(n.command);qp(n.command,n.options.taskId,s);let o=s!=="none",i=await ns({cwd:e.cwd,...n.options.workspaceRoot!==void 0?{explicitWorkspaceRoot:n.options.workspaceRoot}:{},...e.env.CRAIG_WORKSPACE_ROOT!==void 0?{environmentWorkspaceRoot:e.env.CRAIG_WORKSPACE_ROOT}:{},...o&&n.options.taskId!==void 0?{explicitTaskId:n.options.taskId}:{},...o&&e.env.CRAIG_TASK_ID!==void 0?{environmentTaskId:e.env.CRAIG_TASK_ID}:{},...o&&e.env.CRAIG_AGENT_TAB_ID!==void 0?{environmentAgentTabId:e.env.CRAIG_AGENT_TAB_ID}:{},allowUninitializedWorkspace:Wp(n.command),resolveTask:s!=="none",requireTask:s==="required"}),a=await Yi(n.command,{paths:i.paths,workspaceContext:i.workspace,taskContext:i.task}),l=r?Ji(t,a):Qi(a);return l.length>0&&e.writeStdout(`${l}
|
|
86
|
+
`),0}catch(n){let s=en(n),o=r?Xi(t,s):s.message;return e.writeStderr(`${o}
|
|
87
|
+
`),s.exitCode}}function Wp(e){return["addWorkspace","addRepo","listRepos","listWorkspaces","help"].includes(e.kind)}function _p(e){return e.kind==="showContext"?"optional":e.kind==="currentTask"||e.kind==="showCurrentTask"?"required":"none"}function Up(e,t){let r=ea(e);if(!(r===void 0||t===void 0||t===r))throw new S("CLI_USAGE",`Task ${r} conflicts with --task ${t}. Provide only one task target.`,{details:{positionalTaskId:r,globalTaskId:t}})}function qp(e,t,r){if(!(t===void 0||r!=="none"||ea(e)===t))throw new S("CLI_USAGE",`--task is not supported by ${e.kind}. Use it with context show, task current, or task show without an id.`,{details:{commandKind:e.kind,globalTaskId:t}})}function ea(e){switch(e.kind){case"showTask":case"attachTask":case"listTaskLinks":case"streamTaskLogs":case"showTaskDiff":case"focusTask":case"openTask":case"runChecks":case"commitTask":return e.taskId;case"addTaskLink":return e.taskId;default:return}}function Bp(e){let t=e.CI?.trim().toLowerCase();return t!==void 0&&t!==""&&t!=="0"&&t!=="false"}import{createRequire as ph}from"node:module";import{readFile as Vp,stat as Kp}from"node:fs/promises";import ss from"node:path";var Gp=200*1024,Hp=500*1024,gr="100000";async function ra(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return zp(e,t,r);try{let n=xe(r.selectedFilePath??null,t.filePaths),s=xe(r.selectedDiffPath??null,t.diffPaths),o=s?await Ft(e.worktreePath):null,[i,a]=await Promise.all([kr(e.worktreePath,n),s?os(e.worktreePath,s,t.diffRows,o):Promise.resolve(Y("No diff selected","No local changes found.","empty"))]),l=s?{[s]:a}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:l,selectedFile:i,selectedDiff:a,error:null}}catch(n){let s=n instanceof Error?n.message:"Unable to inspect task worktree.";return{...t,error:s}}}async function zp(e,t,r){let n=xe(r.selectedFilePath??null,t.filePaths),s=xe(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([sa(e,n),(async()=>{if(!s)return Y("No diff selected","No local changes found.","empty");let l=hr(e,s),c=l?await Ft(l.target.worktreePath).catch(()=>null):null;return oa(e,s,t.diffRows,c)})()]),a=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:a,selectedFile:o,selectedDiff:i}}async function na(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Yp(e,t);try{await K(e);let r=await Ft(e.worktreePath),[n,s]=await Promise.all([ia(e.worktreePath),aa(e.worktreePath,r)]),o=[...new Set(s.map(u=>u.path))],i=xe(t.selectedFilePath??null,n),a=xe(t.selectedDiffPath??null,o),[l,c]=await Promise.all([kr(e.worktreePath,i),a?os(e.worktreePath,a,s,r):Promise.resolve(Y("No diff selected","No local changes found.","empty"))]),d=a?{[a]:c}:{};return{taskId:e.id,fileRows:da(n),filePaths:n,diffRows:s,diffPaths:o,diffContents:d,selectedFilePath:i,selectedDiffPath:a,selectedFile:l,selectedDiff:c,error:null}}catch(r){let n=r instanceof Error?r.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:Y("Files unavailable",n,"error"),selectedDiff:Y("Diff unavailable",n,"error"),error:n}}}async function Yp(e,t){let r=(e.repoTargets??[]).filter(m=>m.status==="ready"),n=await Promise.all(r.map(async m=>{let T=await Ft(m.worktreePath).catch(()=>null),[R,h]=await Promise.all([ia(m.worktreePath).catch(()=>[]),aa(m.worktreePath,T).catch(()=>[])]);return{target:m,baseRef:T,targetFiles:R,targetDiffRows:h}})),s=[],o=[];for(let{target:m,targetFiles:T,targetDiffRows:R}of n)s.push(...T.map(h=>`${m.repoId}/${h}`)),o.push(...R.map(h=>({...h,path:`${m.repoId}/${h.path}`})));let i=[...new Set(o.map(m=>m.path))].sort(),a=xe(t.selectedFilePath??null,s),l=xe(t.selectedDiffPath??null,i),[c,d]=await Promise.all([sa(e,a),(async()=>{if(!l)return Y("No diff selected","No local changes found.","empty");let m=hr(e,l),T=m?n.find(R=>R.target.repoId===m.target.repoId):null;return oa(e,l,o,T?.baseRef??null)})()]),u=l?{[l]:d}:{};return{taskId:e.id,fileRows:da(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:u,selectedFilePath:a,selectedDiffPath:l,selectedFile:c,selectedDiff:d,error:null}}async function sa(e,t){let r=hr(e,t);if(!r)return Y("No file selected","No Git-visible files found.","empty");let n=await kr(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function oa(e,t,r,n=null){let s=hr(e,t);return s?{...await os(s.target.worktreePath,s.relativePath,r.filter(i=>i.path.startsWith(`${s.target.repoId}/`)).map(i=>({...i,path:i.path.slice(s.target.repoId.length+1)})),n),path:t,title:t}:Y(t,"Repo target is unavailable.","error",t)}function hr(e,t){if(!t)return null;let[r,...n]=t.split("/"),s=n.join("/"),o=(e.repoTargets??[]).find(i=>i.repoId===r&&i.status==="ready")??null;return!o||s.length===0?null:{target:o,relativePath:s}}async function ia(e){let t=await I("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return ua(t.stdout)}async function aa(e,t){let[r,n,s,o]=await Promise.all([Qp(e,t),ta(e,"staged"),ta(e,"unstaged"),Jp(e)]);return[...r,...n,...s,...o]}async function Qp(e,t){if(!t)return[];let[r,n]=await Promise.all([I("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),I("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=la(r.stdout),o=ca(n.stdout);return s.map(i=>{let a=o.get(i.path)??{additions:null,deletions:null};return{group:"branch",path:i.path,status:i.status,additions:a.additions,deletions:a.deletions}}).sort((i,a)=>i.path.localeCompare(a.path))}async function ta(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([I("git",[...r,"--name-status"],{cwd:e}),I("git",[...r,"--numstat"],{cwd:e})]),o=la(n.stdout),i=ca(s.stdout);return o.map(a=>{let l=i.get(a.path)??{additions:null,deletions:null};return{group:t,path:a.path,status:a.status,additions:l.additions,deletions:l.deletions}}).sort((a,l)=>a.path.localeCompare(l.path))}async function Jp(e){let t=await I("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=ua(t.stdout);return await Promise.all(r.map(async s=>{let o=await kr(e,s),i=o.status==="ready"?Xp(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function la(e){return e.split(`
|
|
88
|
+
`).map(t=>t.trim()).filter(t=>t.length>0).map(t=>{let[r="M",...n]=t.split(" ");return{status:r,path:n.at(-1)??""}}).filter(t=>t.path.length>0)}function ca(e){let t=new Map;for(let r of e.split(`
|
|
89
|
+
`)){let n=r.trim();if(!n)continue;let[s="-",o="-",...i]=n.split(" "),a=i.join(" ");a&&t.set(a,{additions:s==="-"?null:Number(s),deletions:o==="-"?null:Number(o)})}return t}async function Ft(e){return(await x("git",["show-ref","--verify","--quiet","refs/remotes/origin/main"],{cwd:e})).exitCode===0?"origin/main":(await x("git",["show-ref","--verify","--quiet","refs/heads/main"],{cwd:e})).exitCode===0?"main":null}async function kr(e,t){if(!t)return Y("No file selected","No Git-visible files found.","empty");let r=Zp(e,t);try{let n=await Kp(r);if(n.size>Gp)return Y(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await Vp(r);return em(s)?Y(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
|
|
90
|
+
`),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return Y(t,s,"missing",t,null)}}async function os(e,t,r,n=null){if(!t)return Y("No diff selected","No local changes found.","empty");let s=[],o=r.filter(a=>a.path===t).map(a=>a.group);if(o.includes("branch")){let a=n??await Ft(e);if(a){let l=await I("git",["diff","--stat","--patch",`--unified=${gr}`,`${a}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
|
|
91
|
+
${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let a=await I("git",["diff","--cached","--stat","--patch",`--unified=${gr}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`staged
|
|
92
|
+
${a.stdout.trimEnd()}`)}if(o.includes("unstaged")){let a=await I("git",["diff","--stat","--patch",`--unified=${gr}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`unstaged
|
|
93
|
+
${a.stdout.trimEnd()}`)}if(o.includes("untracked")){let a=await x("git",["diff","--no-index","--stat","--patch",`--unified=${gr}`,"--","/dev/null",t],{cwd:e});a.stdout.trim().length>0&&s.push(`untracked
|
|
132
94
|
${a.stdout.trimEnd()}`)}let i=s.join(`
|
|
133
95
|
|
|
134
|
-
`);return i.length>
|
|
135
|
-
`):["No diff for this file."],byteLength:i.length}}function
|
|
136
|
-
`).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function
|
|
137
|
-
`}function
|
|
138
|
-
`)}function
|
|
139
|
-
`)}function
|
|
140
|
-
`),center:
|
|
141
|
-
`)}function
|
|
96
|
+
`);return i.length>Hp?Y(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?Y(t,"Binary diff preview is not available in Craig.","binary",t,i.length):{path:t,status:i.length>0?"ready":"empty",title:t,lines:i.length>0?i.split(`
|
|
97
|
+
`):["No diff for this file."],byteLength:i.length}}function da(e){let t=[],r=new Set;for(let n of e){let s=n.split("/");for(let o=0;o<s.length-1;o+=1){let i=s.slice(0,o+1).join("/");r.has(i)||(r.add(i),t.push({kind:"directory",path:i,depth:o,label:s[o]??i}))}t.push({kind:"file",path:n,depth:s.length-1,label:s.at(-1)??n})}return t}function xe(e,t){return e&&t.includes(e)?e:t[0]??null}function Xp(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function ua(e){return[...new Set(e.split(`
|
|
98
|
+
`).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function Zp(e,t){let r=ss.resolve(e,t),n=ss.resolve(e);if(r!==n&&!r.startsWith(`${n}${ss.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function em(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function Y(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}var tm=["tasks","center","inspector","actions"],pa=["agent","terminal"],ma=[],A="inspection",CP=[...pa,...ma],is=["commit","push","refresh-checks","close-task"],fa=["refresh-checks","close-task"],ga=["task","checks","pr","setup-run","actions","next-action"],as=["files","review"];function ha(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=am(e?.openInspectionKind)??r,s=f.runners.getEnabled(t);return{inputMode:cm(e?.inputMode),focusedRegion:om(e?.focusedRegion),selectedRepoId:be(e?.selectedRepoId),selectedWorkspaceId:be(e?.selectedWorkspaceId),selectedTaskId:be(e?.selectedTaskId),selectedPtyTabId:be(e?.selectedPtyTabId),selectedLeftItemId:gm(be(e?.selectedTaskId)),activeTab:r?A:be(e?.activeTab)??"agent",preferredPtyTabKind:lm(e?.preferredPtyTabKind),inspectorSection:jt(e?.inspectorSection,ga,"task"),inspectionMode:im(e?.inspectionMode,r==="diff"?"review":"files"),openInspectionKind:n,selectedFileTreePath:be(e?.selectedFileTreePath),selectedFilePath:be(e?.selectedFilePath),selectedDiffPath:be(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:jt(e?.selectedActionId,is,"commit"),selectedProjectTargetId:null,selectedRunner:dm(e?.selectedRunner,s,f.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,fileSearchQuery:null,workspaceBrowser:null,terminal:rm(),centerZoomed:!1}}function rm(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function ka(e,t){return{...e??Jt(),selectedRepoId:t.selectedRepoId,selectedWorkspaceId:t.selectedWorkspaceId,selectedTaskId:t.selectedTaskId,selectedPtyTabId:t.selectedPtyTabId,inputMode:t.inputMode,focusedRegion:t.focusedRegion,activeTab:t.activeTab,preferredPtyTabKind:t.preferredPtyTabKind,inspectorSection:t.inspectorSection,inspectionMode:t.inspectionMode,openInspectionKind:t.openInspectionKind,selectedFileTreePath:t.selectedFileTreePath,selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath,collapsedFileTreePaths:t.collapsedFileTreePaths,selectedActionId:t.selectedActionId,selectedRunner:t.selectedRunner}}function Wt(e,t,r={}){let n=fm(e,t),s=cs(n),o=(s?.kind==="workspace"?t.workspaces?.find(d=>d.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(d=>d.id===t.tasks.find(u=>u.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(d=>d.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,a=((s?.kind==="repo"?t.repos.find(d=>d.id===s.id)??null:s?.kind==="task"?t.repos.find(d=>d.id===t.tasks.find(u=>u.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(d=>d.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(d.id))??null:null)??(o?.kind!=="project"?t.repos.find(d=>d.id===o?.primaryRepoId)??null:null)??t.repos.find(d=>d.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(d=>d.workspaceId===o.id):a?t.tasks.filter(d=>d.repoId===a):[],c=(s?.kind==="task"?l.find(d=>d.id===s.id)??null:null)??l.find(d=>d.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:r.resetInputMode?"control":e.inputMode,selectedLeftItemId:n,selectedWorkspaceId:o?.id??null,selectedRepoId:a,selectedTaskId:c?.id??null,...um(c,e.activeTab,e.selectedPtyTabId),selectedFilePath:sm(e,t,c?.id??null),...pm(e,t,c?.id??null),selectedDiffPath:nm(e,t,c?.id??null),inspectorSection:jt(e.inspectorSection,ga,"task")}}function Pe(e,t){return{...e,terminal:t}}function wa(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Ta(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function pe(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
99
|
+
`}function Ra(e){return e.length===1&&e>=" "&&e!=="\x7F"}function ls(e){return ba(e)||mt(e)!==null}function ya(e){return ma.includes(e)}function ba(e){return pa.includes(e)}function Pa(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[A]:[]]}function nm(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function sm(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function jt(e,t,r){return t.includes(e??"")?e:r}function om(e){return e==="tabs"?"center":jt(e,tm,"tasks")}function im(e,t){return e==="checks"||e==="actions"||e==="diff"||e==="review"?"review":jt(e,as,t)}function am(e){return e==="file"||e==="diff"?e:null}function lm(e){return e==="terminal"?"terminal":"agent"}function cm(e){return e==="terminal"?"terminal":"control"}function dm(e,t=[...O],r="codex"){return e&&f.runners.isRunnerType(e)&&t.includes(e)?e:r}function wr(e,t=O){let r=t.length>0?t:O,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function mt(e){let t=O.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function um(e,t,r){if(!e)return{activeTab:t===A?t:"agent",selectedPtyTabId:null};let n=e.ptyTabs.find(a=>a.id===r)??null,s=e.selectedPtyTabId?e.ptyTabs.find(a=>a.id===e.selectedPtyTabId)??null:null,o=e.ptyTabs.find(a=>a.id===t)??null;if(o)return{activeTab:o.id,selectedPtyTabId:o.id};if(ba(t)){let l=e.ptyTabs.find(c=>c.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:l?.id??A,selectedPtyTabId:l?.id??null}}if(t===A)return{activeTab:A,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??A,selectedPtyTabId:i?.id??null}}function pm(e,t,r){if(!t.inspection||t.inspection.taskId!==r)return{selectedFileTreePath:e.selectedFileTreePath,collapsedFileTreePaths:e.collapsedFileTreePaths};let n=e.selectedFileTreePath??t.inspection.selectedFilePath,s=e.selectedFileTreePath===null&&e.collapsedFileTreePaths.length===0?mm(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function mm(e,t){let r=new Set;if(t){let n=t.split("/");for(let s=1;s<n.length;s+=1)r.add(n.slice(0,s).join("/"))}return e.filter(n=>n.kind==="directory"&&!n.path.includes("/")&&!r.has(n.path)).map(n=>n.path).sort((n,s)=>n.localeCompare(s))}function fm(e,t){let r=He(t);return e.selectedLeftItemId&&r.includes(e.selectedLeftItemId)?e.selectedLeftItemId:e.selectedWorkspaceId&&r.includes(`workspace:${e.selectedWorkspaceId}`)?`workspace:${e.selectedWorkspaceId}`:e.selectedTaskId&&r.includes(`task:${e.selectedTaskId}`)?`task:${e.selectedTaskId}`:e.selectedRepoId&&r.includes(`repo:${e.selectedRepoId}`)?`repo:${e.selectedRepoId}`:r[0]??null}function He(e){let t=[];if(e.workspaces?.length)for(let r of e.workspaces){t.push(`workspace:${r.id}`);for(let n of e.tasks.filter(s=>s.workspaceId===r.id))t.push(`task:${n.id}`);r.kind==="project"&&t.push(`new-task-workspace:${r.id}`),r.kind==="repo"&&t.push(`new-task:${r.primaryRepoId}`)}else for(let r of e.repos){t.push(`repo:${r.id}`);for(let n of e.tasks.filter(s=>s.repoId===r.id))t.push(`task:${n.id}`);t.push(`new-task:${r.id}`)}return t.push("new-workspace"),t}function cs(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function be(e){return typeof e=="string"?e:null}function gm(e){return e?`task:${e}`:null}function _t(e){return typeof e=="string"&&e.startsWith("task:")}function Tr(e){return typeof e=="string"&&e.startsWith("new-task:")}function Rr(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function Sa(e){return typeof e=="string"&&e.startsWith("workspace:")}function ds(e){return Tr(e)?e.slice(9):null}function us(e){return Rr(e)?e.slice(19):null}async function De(e,t,r){let n=ee(e),[s,o]=await Promise.all([H.repos.listRegisteredRepos(n),H.listWorkspaces(n,{archived:!1})]),i=await E.listTasks(n),a=ps(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},c=a?await na(a,l):null;return{workspaceRoot:e,workspaces:o.workspaces,repos:s.repos,tasks:i.tasks,inspection:c,...r?{enabledRunnerIds:r}:{}}}function ps(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function Ia(e,t){return Wt(e,t)}import bs from"node:path";import NP from"picocolors";var hm=[" \u2584\u2588\u2588\u2588\u2588\u2584 \u2588\u2588\u2580\u2588\u2588\u2588 \u2584\u2584\u2584 \u2588\u2588\u2593 \u2584\u2588\u2588\u2588\u2588"," \u2592\u2588\u2588\u2580 \u2580\u2588 \u2593\u2588\u2588 \u2592 \u2588\u2588\u2592\u2592\u2588\u2588\u2588\u2588\u2584 \u2593\u2588\u2588\u2592 \u2588\u2588\u2592 \u2580\u2588\u2592"," \u2592\u2593\u2588 \u2584 \u2593\u2588\u2588 \u2591\u2584\u2588 \u2592\u2592\u2588\u2588 \u2580\u2588\u2584 \u2592\u2588\u2588\u2592\u2592\u2588\u2588\u2591\u2584\u2584\u2584\u2591"," \u2592\u2593\u2593\u2584 \u2584\u2588\u2588\u2592\u2592\u2588\u2588\u2580\u2580\u2588\u2584 \u2591\u2588\u2588\u2584\u2584\u2584\u2584\u2588\u2588 \u2591\u2588\u2588\u2591\u2591\u2593\u2588 \u2588\u2588\u2593"," \u2592 \u2593\u2588\u2588\u2588\u2580 \u2591\u2591\u2588\u2588\u2593 \u2592\u2588\u2588\u2592 \u2593\u2588 \u2593\u2588\u2588\u2592\u2591\u2588\u2588\u2591\u2591\u2592\u2593\u2588\u2588\u2588\u2580\u2592"," \u2591 \u2591\u2592 \u2592 \u2591\u2591 \u2592\u2593 \u2591\u2592\u2593\u2591 \u2592\u2592 \u2593\u2592\u2588\u2591\u2591\u2593 \u2591\u2592 \u2592"," \u2591 \u2592 \u2591\u2592 \u2591 \u2592\u2591 \u2592 \u2592\u2592 \u2591 \u2592 \u2591 \u2591 \u2591"," \u2591 \u2591\u2591 \u2591 \u2591 \u2592 \u2592 \u2591\u2591 \u2591 \u2591"," \u2591 \u2591 \u2591 \u2591 \u2591 \u2591 \u2591"," \u2591"];function ms(){return[...hm]}var yr={width:120,height:36},N={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function le(e,t){return{width:Math.max(e??yr.width,yr.width),height:Math.max(t??yr.height,yr.height)}}var km=["Start","Options","Exit"],wm=["Resume","Options","Exit"],Pr=2,Sr=2,Ir=2,Tm=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),Rm=new RegExp("\x1B\\[(?:0)?m","g"),ym=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),bm=/https?:\/\/[^\s<>"']+/g,gs="\x1B[0m",hs="\x1B]8;;\x1B\\",b={panelBg:{bg:"0a0a0a",fg:"c0caf5"},panelMuted:{bg:"0a0a0a",fg:"565f89"},panelSelected:{bg:"1a1b26",fg:"c0caf5"},panelFocused:{bg:"1a1b26",fg:"7aa2f7"},divider:{bg:"0a0a0a",fg:"292e42"},rail:{bg:"0a0a0a",fg:"c0caf5"},overlay:{bg:"06060f",fg:"565f89"},overlayTitle:{bg:"06060f",fg:"565f89"},overlayLogo:{bg:"06060f",fg:"9ece6a"},overlaySubtitle:{bg:"06060f",fg:"41a6b5"},overlayMenuSelected:{bg:"06060f",fg:"7aa2f7"},accent:{fg:"7aa2f7"},success:{fg:"9ece6a"},pending:{fg:"e0af68"},error:{fg:"f7768e"},mutedfg:{fg:"565f89"},disabled:{fg:"3b4261"}},fs=["3d59a1","506eb8","6386d0","7aa2f7","6386d0","506eb8"];function Ea(e,t={}){return ws(e,{subtitle:"crAIg is that you?",menuItems:km,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function Aa(e,t={}){return ws(e,{subtitle:"Control mode is paused.",menuItems:wm,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var br=[" GLOBAL CENTER PANEL INSPECTOR"," ? help \u2190\u2192 / hl switch tab \u2191\u2193 / jk navigate"," Esc pause / back + new tab \u2190\u2192 / hl switch mode"," Tab cycle panels a codex tab R sync PR"," q quit t terminal tab R sync PR"," x close tab X close task"," TASKS Enter attach PTY X close task"," \u2191\u2193 / jk navigate"," n new task TERMINAL MODE"," Enter attach Ctrl+] return to control mode"," Wheel / PgUp / PgDn scroll",""," Press Esc to return."],Pm=["Help"],Sm=5;function Er(e,t={}){return ws(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Pm,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function xa(e,t={}){let r=t.color??!0,n=b.overlay,s=new Array(e.height).fill(F(" ".repeat(e.width),r,n)),o=ms(),i=Math.max(1,Math.floor((e.height-o.length-2-br.length)/2));for(let d=0;d<o.length&&!(i+d>=e.height);d+=1)s[i+d]=F(Wa(o[d]??"",e.width),r,b.overlayLogo);let a=Math.max(...br.map(d=>d.length)),l=Math.max(0,Math.floor((e.width-a)/2)),c=i+o.length+2;for(let d=0;d<br.length;d+=1){let u=c+d;if(u>=e.height)break;let m=br[d]??"";s[u]=F(ke(" ".repeat(l)+m,e.width),r,n)}return s.join(`
|
|
100
|
+
`)}function Da(e,t={}){let r=t.color??!0,n=b.overlay,s=new Array(e.height).fill(F(" ".repeat(e.width),r,n)),o="Error Log",i=t.errorLogPath??"",a=t.errorLogLines??[],l=Math.max(20,e.width-8),c=Math.max(0,Math.floor((e.width-l)/2)),d=[{text:o,tone:"selected"},{text:i,tone:"muted"},me(),...a.length>0?a.map(T=>({text:T})):[{text:"No Craig errors have been logged.",tone:"muted"}],me(),{text:"Esc returns to Options.",tone:"muted"}],u=Ut(d,e.height-2),m=Math.max(1,Math.floor((e.height-u.length)/2));for(let T=0;T<u.length;T+=1){let R=m+T;if(R>=e.height)break;let h=u[T]??me(),y=`${" ".repeat(c)}${Ar(h.text,l)}`,B=h.tone==="selected"?b.overlayMenuSelected:h.tone==="muted"?b.overlay:b.panelBg;s[R]=F(ke(y,e.width),r,B)}return s.join(`
|
|
101
|
+
`)}function $a(e,t,r={}){let n=r.color??!0,s=N.leftWidth,o=N.rightWidth,i=r.centerOnly??!1,a=e.height-N.topRailHeight-1,l=r.focusFlashActive??!1,c={bg:b.divider.bg,fg:"9ece6a"},d=l&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?c:b.divider,u=l&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?c:b.divider,m=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=F(ke(m,e.width),n,b.rail),R=Cm(t,s-Pr-Sr,a,n),h=ks(e,t,{color:n,centerOnly:i}),y=Am(t,o,a,n),B=t.inputMode==="terminal",z=[],se=[];for(let Te=0;Te<a;Te+=1)if(!i){let Le=Cr(R[Te]??me(),s,n,"left"),Gt=F("\u2502",n,d),Ht=F("\u2502",n,u),zt=Cr(y[Te]??me(),o,n,"right");z.push(`${Le}${Gt}`),se.push(`${Ht}${zt}`)}let C=B||t.modalInput?b.panelBg:b.panelMuted,we=Im(t.footerText,t.footerToast,e.width,n,C),wt={row:1,column:1,width:e.width,rows:[T]},Je=i?null:{row:N.topRailHeight+1,column:1,width:s+N.dividerWidth,rows:z},Gr=i?null:{row:N.topRailHeight+1,column:h.column+h.width,width:N.dividerWidth+o,rows:se},p={row:e.height,column:1,width:e.width,rows:[we]},Ne=i?h.rows:h.rows.map((Te,Le)=>`${z[Le]??""}${Te}${se[Le]??""}`);return{frame:[T,...Ne,we].join(`
|
|
102
|
+
`),center:h,regions:{rail:wt,left:Je,center:h,right:Gr,footer:p}}}function ks(e,t,r={}){let n=r.color??!0,s=Ma(e,r.centerOnly??!1),o=vm(t,s.width,s.rowCount,n);return{row:s.row,column:s.column,width:s.width,rows:o.map(i=>Cr(i,s.width,n,"center"))}}function Oa(e,t,r,n={}){let s=t.tabs.find(c=>c.active)?.id??"";if(!ls(s)||t.centerHeader.tabLabel==="BROWSER"||t.terminal.error||t.terminal.rows.length===0||r.some(c=>c<0||c>=t.terminal.rows.length))return null;let o=n.color??!0,i=Ma(e,n.centerOnly??!1),a=Na(t,i.width,o).length,l=[...new Set(r)].map(c=>({terminalIndex:c,index:a+c})).filter(({index:c})=>c<i.rowCount).map(({terminalIndex:c,index:d})=>({index:d,row:Cr(La(t.terminal.rows[c]),i.width,o,"center")}));return{...i,rows:l}}function Ma(e,t){return{row:N.topRailHeight+1,column:t?1:N.leftWidth+N.dividerWidth+1,width:t?e.width:e.width-N.leftWidth-N.rightWidth-N.dividerWidth*2,rowCount:e.height-N.topRailHeight-1}}function Im(e,t,r,n,s){let o=` ${e}`;if(!t)return F(ke(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,a=ne(i),l=ne(o),c=Math.max(1,r-l-a-2),d=l+c+a+2>r?Ar(o,Math.max(0,r-a-3)):o,u=Math.max(1,r-ne(d)-a-2),m=t.tone==="error"?zm(i,n,s):ft(i,n,s),T=`${d}${" ".repeat(u)}${m} `;return F(ke(T,r),n,s)}function ws(e,t){let r=new Array(e.height).fill(F(" ".repeat(e.width),t.color,b.overlay)),n=ms(),s=t.menuItems.map((c,d)=>`${d===t.menuIndex?">":" "} ${c}`),o=t.optionsMessage?["",t.optionsMessage]:[],i=[...s,...o];for(;i.length<Sm;)i.push("");let a=[...n,"",t.subtitle,"",...i],l=Math.max(1,Math.floor((e.height-a.length)/2));for(let c=0;c<a.length;c+=1){let d=Wa(a[c]??"",e.width);if(c<n.length){r[l+c]=F(d,t.color,b.overlayLogo);continue}if(c===n.length+1){r[l+c]=F(d,t.color,b.overlaySubtitle);continue}let u=c-(n.length+3),T=u>=0&&u<t.menuItems.length&&u===t.menuIndex?b.overlayMenuSelected:b.overlay;r[l+c]=F(d,t.color,T)}if(t.versionText){let c=t.updateText?" (update available)":"",d=`${t.versionText}${c} `,u=" ".repeat(Math.max(0,e.width-ne(d)));r[e.height-1]=F(`${u}${ys(d,t.color,b.overlay)}`,t.color,b.overlay)}return r.join(`
|
|
103
|
+
`)}function Cm(e,t,r,n){let s=$m(e.runners),o=1,i=e.leftTree.map(l=>Dm(l,t,n));return[...Ut(i,r-o),s]}function vm(e,t,r,n){let s=e.tabs.find(i=>i.active)?.id??"agent",o=e.centerHeader.tabLabel==="BROWSER"||!ls(s)?e.centerTranscript.map(i=>({...i})):Em(e);return Ut([...Na(e,t,n),...o],r)}function Na(e,t,r){let n=t-2,s=e.tabs.find(y=>y.active)?.label??"AGENT",o=e.inputMode==="terminal"?0:Km(e.tabs),i=e.inputMode==="terminal"?n:s.length+1,a="\u2500".repeat(Math.max(0,i)),l=`${" ".repeat(o)}${e.inputMode==="terminal"?ft(a,r,b.panelBg):vr(a,r,b.panelMuted)}`,c=[`${vr(e.centerHeader.tabLabel,r,b.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),d=Om(e.tabs,r,e.focusedRegion==="center"),u=" engaged ",m=u.length+2,T=e.inputMode==="terminal"?ft(`${u}\u25CF `,r,b.panelBg):"",R=e.inputMode==="terminal"?" ".repeat(Math.max(0,n-ne(d)-m)):"";return[{text:e.inputMode==="terminal"?`${d}${R}${T}`:d},{text:l,tone:"muted"},{text:c},me()]}function Em(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},me(),{text:e.terminal.error},me(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(n=>n.active)?.id??"",r=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${r.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(La)}function La(e){return{text:Rs(e.segments),segments:e.segments,fullBleed:!0}}function Am(e,t,r,n){let s=e.rightInspection?xm(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,r):Ut([{text:"CONTEXT"},me(),...e.rightContext.map(o=>Mm(o,n)),...e.actionMessage?[me(),{text:e.actionMessage}]:[]],r);return Ut(s,r)}function xm(e,t){let r=e.slice(0,2),n=e.slice(2),s=Math.max(0,t-r.length),o=n.findIndex(a=>a.focused||a.selected),i=o===-1?0:Hm(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(a=>Ca(a)),...n.slice(i,i+s).map(a=>Ca(a))]}function Ca(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",r=e.focused||e.selected?"selected":e.muted?"muted":"default",n=`${t}${e.text}`;if(e.segments)return{text:n,segments:[{text:t},...e.segments],tone:r};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:n,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:r}}return e.color?{text:n,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:r}:{text:n,tone:r}}function Dm(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${ft("\u25CF",r,e.selected?b.panelSelected:b.panelBg)}`:"",a=e.prBadge?e.prBadge.reduce((R,h)=>R+ne(h.text),0):0,l=t-ne(o)-ne(s)-a,c=e.activity?`${e.selected?"\u25B8":" "} \u25CF `:"",d=e.selected?e.text:e.focused?ft(e.text,r,b.panelBg):e.panelHeader?vr(e.text,r,b.panelMuted):e.text,u=ke(`${n}${c}${d}`,Math.max(0,l)),m=e.selected?"selected":e.muted?"muted":"default";if(e.activity){let R=`${n}${e.selected?"\u25B8":" "} `,h=u.slice(R.length+2),y=[{text:R},Fa(e.activity,e.activityAnimationFrame??0),{text:` ${h}${o}${i}`},...e.prBadge??[]];return{text:Rs(y),segments:y,tone:m}}if(e.prBadge){let R=[{text:`${u}${o}${i}`},...e.prBadge];return{text:`${u}${o}${e.prBadge.map(y=>y.text).join("")}`,segments:R,tone:m}}return{text:`${u}${o}${i}`,tone:m}}function $m(e){let t=e.map(n=>{let s=n.health>=1,o=parseInt(n.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${n.name}${i}`,active:s}}),r=[];for(let n=0;n<t.length;n++){let s=t[n];n>0&&r.push({text:" "}),s.active?r.push({text:s.text,style:{fg:b.success.fg}}):r.push({text:s.text,style:{fg:b.panelMuted.fg}})}return{text:t.map(n=>n.text).join(" "),segments:r,tone:"muted"}}function Om(e,t,r){return e.map(n=>{let s=n.active?r?ft(n.label,t,b.panelBg):vr(n.label,t,b.panelBg):ys(n.label,t,b.panelBg),o=n.activity?Ts(Fa(n.activity,n.activityAnimationFrame??0),t,b.panelBg):"";return`${s}${o?` ${o}`:""}`}).join(" ")}function Fa(e,t){return{text:"\u25CF",style:{fg:e==="working"?fs[t%fs.length]??fs[0]:e==="ready"?b.success.fg:e==="error"?b.error.fg:b.panelMuted.fg}}}function Mm(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?ys(e.value,t,b.panelBg):e.value}`}}function Cr(e,t,r,n){let s=Nm(n,e.tone??"default"),o=Lm(e,r,s);if(n==="left"){if(e.fullBleed)return F(ke(o,t),r,s);let a=t-Pr-Sr;if(e.rightAlign){let c=ne(o),d=Math.max(0,a-c),u=`${" ".repeat(Pr)}${" ".repeat(d)}${o}${" ".repeat(Sr)}`;return F(u,r,s)}let l=`${" ".repeat(Pr)}${ke(o,a)}${" ".repeat(Sr)}`;return F(l,r,s)}return n==="center"&&e.fullBleed?Fm(e,t,r,s):F(ke(` ${o}`,t),r,s)}function Nm(e,t){return t==="selected"||t==="focused"?b.panelSelected:t==="muted"?b.panelMuted:b.panelBg}function Ut(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(me());return r}function me(){return{text:""}}function Lm(e,t,r){return e.segments?e.segments.map(n=>Ts(n,t,r)).join(""):e.text}function Fm(e,t,r,n){let s=" ".repeat(Ir),o=Math.max(0,t-Ir*2);if(!e.segments)return F(`${s}${ke(e.text,o)}${s}`,r,n);let i=_m(e.segments,o),a=`${s}${i.map(l=>Ts(l,r,n)).join("")}${s}${r?hs:""}`;return F(a,r,n)}function Ts(e,t,r){let n=e.href?`${ja(e.href)}${e.text}${hs}`:jm(e.text);return!t||!e.style?n:`${qt(Bm(e.style,r))}${Vm(e.style)}${n}${gs}${qt(r)}`}function jm(e){return e.replace(bm,t=>{let[r,n]=Wm(t);return`${ja(r)}${r}${hs}${n}`})}function Wm(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ja(e){return`\x1B]8;;${e}\x1B\\`}function _m(e,t){let r=Um(e,t);return qm(r,t)}function Um(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=ne(s.text);if(o<=n){r.push(s),n-=o;continue}let i=Ar(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function qm(e,t){let r=ne(Rs(e));if(r>=t)return e;let n=[...e].reverse().find(s=>s.style?.bg)?.style;return n?.bg?[...e,{text:" ".repeat(t-r),style:n}]:[...e,{text:" ".repeat(t-r)}]}function Bm(e,t){let r=e.inverse?e.bg??t.bg:e.fg,n=e.inverse?e.fg??t.fg:e.bg,s={},o=r??t.fg,i=n??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function Vm(e){let t=[];return e.bold&&t.push("1"),e.dim&&t.push("2"),e.italic&&t.push("3"),e.underline&&t.push("4"),t.length>0?`\x1B[${t.join(";")}m`:""}function Km(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+(r.activity?2:0)+3}return 0}function Wa(e,t){let r=Math.max(0,t-ne(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function ke(e,t){let r=ne(e);return r>=t?Gm(e,t):e+" ".repeat(t-r)}function Gm(e,t){if(t<=0)return"";if(ne(e)<=t)return e;let r=Ua(e);return Ar(r,Math.max(0,t-1))+"\u2026"}function ne(e){let t=0;for(let r of Array.from(Ua(e)))t+=_a(r);return t}function Ar(e,t){let r="",n=0;for(let s of Array.from(e)){let o=_a(s);if(n+o>t)break;r+=s,n+=o}return r}function _a(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function Hm(e,t,r){return Math.min(Math.max(e,t),r)}function Ua(e){return e.replace(ym,"").replace(Tm,"")}function Rs(e){return e.map(t=>t.text).join("")}function F(e,t,r){if(!t)return e;let n=qt(r),s=e.replace(Rm,`${gs}${n}`);return`${n}${s}${gs}`}function qt(e){let t=[];return e.fg&&t.push(`38;2;${va(e.fg).join(";")}`),e.bg&&t.push(`48;2;${va(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function va(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function ft(e,t,r){return xr(e,t,b.success.fg,r)}function zm(e,t,r){return xr(e,t,b.error.fg,r)}function vr(e,t,r){return xr(e,t,b.accent.fg,r)}function ys(e,t,r){return xr(e,t,b.mutedfg.fg,r)}function xr(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${qt(s)}${e}${qt(n)}`}function qa(e,t,r){let n=e.tasks.find(l=>l.ptyTabs.some(c=>c.id===t))??null,s=n?.ptyTabs.find(l=>l.id===t)??null,o=n?.worktreePath??r,i=s?.kind==="agent"?Qm(s):[],a=n?{CRAIG_WORKSPACE_ROOT:r,CRAIG_TASK_ID:n.id,...s?.kind==="agent"?{CRAIG_AGENT_TAB_ID:s.id}:{}}:{};return n?.type==="project"?{cwd:o,command:i,env:{...a,GIT_CEILING_DIRECTORIES:Ym(process.env.GIT_CEILING_DIRECTORIES,o)}}:n?{cwd:o,command:i,env:a}:{cwd:o,command:i}}function Ym(e,t){let r=(e??"").split(bs.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(bs.delimiter):[...r,t].join(bs.delimiter)}function Qm(e){return e.command.length>0?e.command:["codex"]}function Ba(e,t){let r=e.ptyTabs.find(n=>n.kind===t);if(!r)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return r.id}function $e(e){return{columns:Math.max(20,e.width-N.leftWidth-N.rightWidth-N.dividerWidth-Ir*2),rows:Math.max(5,e.height-N.topRailHeight-5)}}function Va(e){return e.length===1||pe(e)||e==="BACKSPACE"||e==="TAB"}function Oe(e){return typeof e=="string"&&new RegExp(`:(?:agent|${O.join("|")})(?:-\\d+)?$`).test(e)}function Ka(e,t){return e==="UP"&&t?-3:e==="DOWN"&&t?3:e==="PAGE_UP"?-5:e==="PAGE_DOWN"?5:e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Ps(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Ga(e){let t=new RegExp("\x1B\\[<(\\d+);\\d+;\\d+[mM]").exec(e);if(!t?.[1])return 0;let r=Number.parseInt(t[1],10);return r===64?-3:r===65?3:0}function Bt(e){return za.includes(e)?"SHIFT_ENTER":null}function Ss(e){return za.some(t=>t.startsWith(e))}function Ha(e){return e==="ESCAPE"?"\x1B":e.length===1?e:null}var za=["\x1B[13;2u","\x1B[13;2~","\x1B[27;2;13~","\x1B[27;2;10~"];function Ya(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
|
|
142
104
|
`||r===`\r
|
|
143
|
-
`)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function
|
|
105
|
+
`)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function Qa(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Ja(e,t=null){let r=t?.split(`
|
|
144
106
|
`)??[];return e.split(`
|
|
145
|
-
`).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function
|
|
146
|
-
`,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:""}
|
|
147
|
-
`))&&this.touchActivity(r))}writeKey(t){let r=
|
|
148
|
-
[process exited ${
|
|
107
|
+
`).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function Dr(e,t,r,n){return e.map((s,o)=>t?.[o]===s?"":`\x1B[${r+o};${n}H${s}`).join("")}import{spawn as yf}from"node:child_process";import{createHash as bf}from"node:crypto";import{createServer as Pf,createConnection as il}from"node:net";import{openSync as Sf}from"node:fs";import{mkdir as If,readFile as Ds,rm as Ye,writeFile as Cf}from"node:fs/promises";import{tmpdir as vf}from"node:os";import gt from"node:path";import{createRequire as af}from"node:module";import Jm from"@xterm/headless";var Xm=1e3,Zm=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function Za(e){return new Jm.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:Xm,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function el(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function Cs(e,t){return new Promise(r=>{e.write(t,r)})}function tl(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:rf(u,i+a===o&&d===r.cursorX)})}n.push({segments:ef(tf(c))})}return n}function ef(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&of(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};rl(r.style)||(s.style=r.style),t.push(s)}return t}function tf(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!rl(r.style))break;t-=1}return e.slice(0,t)}function rf(e,t){let r={},n=Xa(e,"fg"),s=Xa(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 Xa(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"):Zm[s]??nf(s)}function nf(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(sf).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 sf(e){return e===0?0:55+e*40}function of(e,t){return Is(e)===Is(t)}function Is(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function rl(e){return Is(e)===""}var lf=af(import.meta.url),cf=/^CTRL_([A-Z])$/,df="\x1B[6n",uf="\x1B[c",pf="\x1B[?u",mf={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
|
|
108
|
+
`,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:""},$r=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")vs(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,nl(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(`
|
|
109
|
+
`))&&this.touchActivity(r))}writeKey(t){let r=ff(t);r!==null&&this.write(r)}scrollViewport(t){let r=this.getAttachedSession();if(!r||t===0)return;let n=r.terminal.buffer.active.baseY;r.scrollbackLines=Math.max(0,Math.min(n,r.scrollbackLines-t))}resize(t){let r=this.getAttachedSession();r&&nl(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&&(vs(r),this.sessions.delete(t)),this.removeActivity(t),this.attachedTabId===t&&(this.attachedTabId=null)}disposeAll(){for(let t of this.sessions.values())vs(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:gf(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??kf().spawn,i=Za(n),a=s??this.resolveSessionSpec(t,r),l=Be({...this.env,...a.env??{}}),{executable:c,args:d}=wf(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:Tf(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(T=>{this.touchActivity(m),Rf(u,T),Cs(m.terminal,T).then(()=>{m.screenDirty=!0,this.onUpdate?.({tabId:m.tabId,kind:"full"})})})),m.disposables.push(u.onExit(T=>{m.status="exited",m.exitCode=T.exitCode,m.lastActivityAt=Date.now(),this.notifyActivity(m),Cs(m.terminal,`\r
|
|
110
|
+
[process exited ${T.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 ff(e){if(e.length===1)return e;let t=mf[e];if(t!==void 0)return t;let r=cf.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function nl(e,t){hf(e.pty,t),el(e.terminal,t),e.screenDirty=!0}function gf(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=tl(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function vs(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function hf(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function kf(){return lf("node-pty")}function wf(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[Ve(t[0],r),...t.slice(1)].map(sl).join(" ")}; exec ${sl(e)} -l`;return{executable:e,args:["-lc",s]}}function sl(e){return`'${e.replaceAll("'","'\\''")}'`}function Tf(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 Rf(e,t){for(let r=0;r<Es(t,df);r+=1)e.write("\x1B[1;1R");for(let r=0;r<Es(t,uf);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<Es(t,pf);r+=1)e.write("\x1B[?0u")}function Es(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 al=6,Ef=new Set([al]),Af=16,xf=250;async function ll(e){let t=$s(e.paths);await Mf(t,e.paths,e.spawnDaemon);let r=await gl(t.socketPath),n=new As(r,e);return await n.ready(),n}async function cl(e,t={}){let r=$s(e);await If(e.runtimeDir,{recursive:!0}),await Ye(r.socketPath,{force:!0});let n=new xs(e,t),s=Pf(o=>n.handleConnection(o));await _f(s,r.socketPath),await Cf(r.pidPath,String(process.pid),"utf8"),await new Promise(o=>{let i=()=>{n.closeClients(),s.close(()=>o())};n.onShutdown=i,process.once("SIGTERM",i),process.once("SIGINT",i)}),await Ye(r.socketPath,{force:!0}),await Ye(r.pidPath,{force:!0}),n.disposeAll()}async function dl(e){let t=$s(e);return await Mr(t.socketPath)?(await ml(t.socketPath),!0):!1}var As=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(!pl(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)}
|
|
149
111
|
`);let o=await s;if(!o.ok)throw new Error(o.error);return o}handleData(t){this.buffer+=t;let r=this.buffer.indexOf(`
|
|
150
112
|
`);for(;r!==-1;){let n=this.buffer.slice(0,r);this.buffer=this.buffer.slice(r+1),this.handleMessage(n),r=this.buffer.indexOf(`
|
|
151
|
-
`)}}handleMessage(t){if(t.trim().length===0)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r){let n=this.pending.get(r.id);if(!n)return;this.pending.delete(r.id),n.resolve(r);return}if(r.type==="update"){if("view"in r){this.viewCache.set(r.tabId,r.view),this.notifyFullUpdate(r.tabId);return}let n=this.viewCache.get(r.tabId)??{status:"idle",rows:[],error:null,scrolledBack:!1},s=
|
|
113
|
+
`)}}handleMessage(t){if(t.trim().length===0)return;let r;try{r=JSON.parse(t)}catch{return}if("id"in r){let n=this.pending.get(r.id);if(!n)return;this.pending.delete(r.id),n.resolve(r);return}if(r.type==="update"){if("view"in r){this.viewCache.set(r.tabId,r.view),this.notifyFullUpdate(r.tabId);return}let n=this.viewCache.get(r.tabId)??{status:"idle",rows:[],error:null,scrolledBack:!1},s=Of(n,r.patch),o=n.rows.slice(0,r.patch.rowCount);for(let i of r.patch.rows)o[i.index]=i.row;this.viewCache.set(r.tabId,{status:r.patch.status,rows:o,error:r.patch.error,scrolledBack:r.patch.scrolledBack}),this.viewUpdateMode==="incremental"&&this.viewedTabId===r.tabId&&this.options.onUpdate?.(s?{tabId:r.tabId,kind:"full"}:{tabId:r.tabId,kind:"rows",rowIndices:r.patch.rows.map(i=>i.index)})}r.type==="activity"&&(this.recordCachedActivity(r.snapshot),this.options.onActivity?.(r.snapshot)),r.type==="activityRemoved"&&this.removeCachedActivity(r.tabId)}subscribeToView(t){this.closed||this.viewUpdateMode!=="incremental"||this.subscribedTabId===t||(this.subscribedTabId=t,this.send({type:"subscribeView",tabId:t}).then(r=>{t&&r.view&&this.viewCache.set(t,r.view),this.viewUpdateMode==="incremental"&&this.viewedTabId===t&&this.subscribedTabId===t&&this.notifyFullUpdate(t)}).catch(()=>{this.subscribedTabId===t&&(this.subscribedTabId=null)}))}rejectAll(t){for(let r of this.pending.values())r.reject(t);this.pending.clear()}notifyFullUpdate(t){t&&this.options.onUpdate?.({tabId:t,kind:"full"})}replaceActivityCache(t,r){let n=new Map;for(let[s,o]of this.activityRevisionByTabId)o>r&&n.set(s,this.activityCache.get(s)??null);this.activityCache.clear();for(let s of t)this.activityCache.set(s.tabId,s);for(let[s,o]of n)o?this.activityCache.set(s,o):this.activityCache.delete(s)}async refreshActivitySnapshots(t=!1){let r=this.activityRevision,n=await this.send({type:"getActivitySnapshots"});if(this.replaceActivityCache(n.activities??[],r),t)for(let s of this.activityCache.values())this.options.onActivity?.(s)}recordCachedActivity(t){this.activityRevision+=1,this.activityRevisionByTabId.set(t.tabId,this.activityRevision),this.activityCache.set(t.tabId,t)}removeCachedActivity(t){this.activityRevision+=1,this.activityRevisionByTabId.set(t,this.activityRevision),this.activityCache.delete(t),this.options.onActivityRemoved?.(t)}failRunningActivities(t){for(let r of this.activityCache.values()){if(r.sessionState!=="running")continue;let n={...r,sessionState:"failed",lastActivityAt:Date.now(),error:t};this.recordCachedActivity(n),this.options.onActivity?.(n)}}},xs=class{onShutdown=null;clients=new Set;subscriptions=new Map;updateTimers=new Map;activityTimers=new Map;pendingActivities=new Map;runtime;attachedTabId=null;constructor(t,r){this.runtime=new $r({...r,workspaceRoot:t.workspaceRoot,activityEnabled:!1,onUpdate:n=>this.handleRuntimeUpdate(n.tabId),onActivity:n=>this.handleActivityUpdate(n),onActivityRemoved:n=>this.handleActivityRemoved(n)})}handleConnection(t){let r="";this.clients.add(t),this.subscriptions.set(t,{mode:"snapshot",activityEnabled:!1,tabId:null,view:null,rowKeys:[]}),t.setEncoding("utf8"),t.on("data",s=>{r+=String(s);let o=r.indexOf(`
|
|
152
114
|
`);for(;o!==-1;){let i=r.slice(0,o);r=r.slice(o+1),this.handleLine(t,i),o=r.indexOf(`
|
|
153
|
-
`)}});let n=()=>{this.clients.delete(t),this.subscriptions.delete(t),this.hasActivitySubscribers()||(this.runtime.setActivityEnabled(!1),this.clearPendingActivityBroadcasts())};t.on("close",n),t.on("error",n)}disposeAll(){for(let t of this.updateTimers.values())clearTimeout(t);this.updateTimers.clear();for(let t of this.activityTimers.values())clearTimeout(t);this.activityTimers.clear(),this.pendingActivities.clear(),this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear(),this.subscriptions.clear(),this.runtime.setActivityEnabled(!1)}async handleLine(t,r){if(r.trim().length===0)return;let n;try{n=JSON.parse(r)}catch{
|
|
154
|
-
${o.slice(-2e3)}`:""}`)}async function
|
|
155
|
-
`)),s.once("error",l=>{a(),n(l)}),s.on("data",l=>{o+=String(l);let
|
|
156
|
-
`);if(
|
|
157
|
-
`)}catch{}}function
|
|
158
|
-
`}function Nm(e){return e.length===1&&e>=" "&&e!==""}import Mt from"node:path";function _a(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 Ua="\u{F024B} ",Ba="\u{F0DCF} ",qa="\u25CB",fs="\uEA64",Va="\uEAFE",Ka="\uEBDA",gs="\u25CB",hs="\u25CF",ws="\u2713",ks="\u2715";function Ha(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 Ga={idle:0,working:1,ready:2,error:3};function $t(e,t,r,n="idle"){let s=t.find(o=>o.tabId===e);return s?s.sessionState==="failed"||s.sessionState==="exited"&&s.exitCode!==0?"error":s.sessionState==="exited"?"ready":r-s.lastActivityAt<5e3?"working":"ready":n}function ys(e,t,r,n){let s=e.ptyTabs.find(i=>i.kind==="agent")?.id,o=t===s&&e.runnerSession?.lastKnownState==="failed"?"error":"idle";return $t(t,r,n,o)}function Ts(e,t,r){let n="idle";for(let s of e.ptyTabs){if(s.kind!=="agent")continue;let o=ys(e,s.id,t,r);Ga[o]>Ga[n]&&(n=o)}return n}function za(e,t,r){return e.some(n=>n.ptyTabs.some(s=>s.kind==="agent"&&$t(s.id,t,r)==="working"))}var Ir="empty",_={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Xa(e,t,r){let n=Um(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",d=bf(t.tasks),c=Vm(e,a),u=qm(e,a,c,r),p=u.find(b=>b.id===c)??u[0]??{id:"agent",label:"CODEX"},k=t.inspection?.taskId===a?.id?t.inspection:null,y=s?.name??"no repo",w=a?f.runners.getDisplayName(a.runner):f.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 ${f.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 [${f.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:Et(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":c===E?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${f.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:Mt.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Mt.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:w},leftTree:Wm(e,t,r),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(b=>Pf(b,d[b])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":p.label,taskId:e.workspaceBrowser?"new workspace":a?.id??"no task",repo:y,agent:w},centerTranscript:Bm(c,e,s,a,e.workspaceBrowser,k,n),tabs:u,rightContext:Rf(s,a),rightInspection:nf(e,a,k)}}function Wm(e,t,r){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return _m(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],d=t.tasks.filter(c=>c.workspaceId===i.id);if(d.length===0)n.push({text:" \xB7 no tasks yet",indent:0,muted:!0});else for(let c of d){let u=e.selectedLeftItemId===`task:${c.id}`,p=c.title.length>28?`${c.title.slice(0,25)}\u2026`:c.title,k={id:`task:${c.id}`,taskId:c.id,text:r?p:`${u?"\u25B8":"\u2022"} ${p}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",...r?{activity:Ts(c,r.snapshots,r.now),activityAnimationFrame:r.animationFrame}:{}},y=el(c);y&&(k.prBadge=y),n.push(k)}if(i.kind==="project"){let c=`new-task-workspace:${i.id}`,u=e.selectedLeftItemId===c;n.push({id:c,text:`+ New Project Task [${f.runners.getDisplayName(e.selectedRunner)}]`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",muted:!u})}if(i.kind==="repo"){let c=`new-task:${i.primaryRepoId}`,u=e.selectedLeftItemId===c;n.push({id:c,text:`+ New Task [${f.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 c of l.slice(0,6)){let u=t.repos.find(p=>p.id===c);n.push({text:` \xB7 ${u?.name??c}`,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 _m(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 p=t.selectedLeftItemId===`task:${u.id}`,k=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,y={id:`task:${u.id}`,taskId:u.id,text:s?k:`${p?"\u25B8":"\u2022"} ${k}`,indent:2,selected:p,focused:p&&t.focusedRegion==="tasks",...s?{activity:Ts(u,s.snapshots,s.now),activityAnimationFrame:s.animationFrame}:{}},w=el(u);w&&(y.prBadge=w),e.push(y)}let d=`new-task:${i.id}`,c=t.selectedLeftItemId===d;e.push({id:d,text:`+ New Task [${f.runners.getDisplayName(t.selectedRunner)}]`,indent:2,selected:c,focused:c&&t.focusedRegion==="tasks",muted:!c})}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 Um(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 Bm(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,d=l.length===0?["No matching directories or git repos."]:l.map((u,p)=>{let k=p===s.selectedIndex?"\u25B8":" ",y=u.kind==="repo"?" [git repo]":"/";return`${k} ${u.name}${y}`}),c=s.query!==null?`Search: ${s.query}\u2588`:"";return le(["Browse for a workspace to register.",s.cwd,...c?[c]:[],"",...d,"",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 le(["No repos registered yet.","","Run `craig repo add <path>` in command mode, then reopen the shell."]);if(!n){let l=i?.kind==="project",d=l?i.name??"this workspace":r.name,c=l?"Project Task":"Task";return le([`No tasks in ${d}.`,"",`Press n or choose + New ${c} to create one with ${f.runners.getDisplayName(t.selectedRunner)}.`])}let a=n.ptyTabs.find(l=>l.id===e)??null;return a?a.kind==="agent"?le([`${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."]):le([`${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===E&&t.openInspectionKind==="file"?Gm(n,o,t.fileScrollOffset):e===E&&t.openInspectionKind==="diff"?zm(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?le(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):le(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function qm(e,t,r,n){let s=t?.ptyTabs.map(i=>({id:i.id,label:Km(i),...i.kind==="agent"&&n&&t?{activity:ys(t,i.id,n.snapshots,n.now),activityAnimationFrame:n.animationFrame}:{}}))??[];if(!t)return[{id:Ir,label:"EMPTY",active:r===Ir,focused:e.focusedRegion==="center"&&r===Ir}];let o=e.openInspectionKind||r===E?[{id:E,label:Hm(e)}]:[];return[...s,...o].map(i=>({...i,active:i.id===r,focused:e.focusedRegion==="center"&&i.id===r}))}function Vm(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===E&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??E:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??E:Ir}function Km(e){return e.title.toUpperCase()}function Hm(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?Mt.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function Gm(e,t,r){if(!e)return le(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return le(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=Za(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:""},...Ym(n.lines,r,s)]}function zm(e,t,r){if(!e)return le(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return le(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=Za(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:""},...Qm(n.lines,r,s)]}function le(e){return e.map(t=>({text:t}))}function Ym(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:_.lineNumber}},{text:" \u2502 ",style:{fg:_.gutter}},...Rs(o,r)],tone:"default"}})}function Qm(e,t,r){let n=Jm(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>Xm(o,r))}function Jm(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 Xm(e,t){let r=Ya(e.oldNumber),n=Ya(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:_.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:_.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?ef(Rs(e.text,t),o.bg,o.fallbackFg):Rs(e.text,t),l=o?{fg:_.lineNumber,bg:o.bg}:{fg:_.lineNumber},d=o?{fg:_.gutter,bg:o.bg}:{fg:_.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...a],fullBleed:o!==null}}function Ya(e){return e===null?" ":String(e).padStart(4," ")}function Za(e){let t=Mt.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 Rs(e,t){return t==="diff"?Zm(e):t==="markdown"?tf(e):t==="json"?bs(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?bs(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 Zm(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:_.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:_.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:_.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:_.diffMeta}}]:[{text:e}]}function ef(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function tf(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:_.markup,bold:!0}}]:bs(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function bs(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:rf(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function rf(e){return e.startsWith("//")||e.startsWith("/*")?{fg:_.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:_.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:_.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:_.markup}:{fg:_.keyword}}function nf(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"?tl(t.repoTargets??[]):s?.pullRequest??(t?D(t):null),i=[sf(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=sl(e,t),l=Ps(e,r),d=df([{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,...d]}}return e.inspectionMode==="files"?{title:"",rows:[...i,...kf(e,r)]}:{title:"",rows:[...i,...Ps(e,r)]}}function sf(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 d=n[l];l>0&&s.push({text:" "});let c=d.active?e.focusedRegion==="inspector"||e.focusedRegion==="actions"?"9ece6a":"7aa2f7":"565f89";s.push({text:d.label,style:{fg:c}})}let o=Ss(t),i=Is(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function Qa(e){return[{text:" "},Ss(e),{text:" "},Is(e)]}function el(e){if(e.type==="project"&&e.repoTargets?.length){let r=tl(e.repoTargets);return r?Qa(r):null}let t=D(e);return t?.number?Qa(t):null}function tl(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=af(r);return{number:-1,status:of(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 of(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 af(e){let t=e.map(r=>rl(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 Ss(e){return!e||!e.number?{text:qa,style:{fg:"565f89"}}:e.status==="merged"?{text:Va,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Ka,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:fs,style:{fg:"565f89"}}:{text:fs,style:{fg:"9ece6a"}}}function Is(e){return e?.aggregateReadiness?Ja(e.aggregateReadiness):Ja(rl(e))}function Ja(e){return e==="failed"?{text:ks,style:{fg:"f7768e"}}:e==="pending"?{text:hs,style:{fg:"e0af68"}}:e==="success"?{text:ws,style:{fg:"9ece6a"}}:{text:gs,style:{fg:"565f89"}}}function rl(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")?nl(e)?"failed":lf(e)?"success":"pending":"pending"}function lf(e){return!!(e.mergeable&&!e.draft&&!nl(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function nl(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function sl(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return cf(e,t);let r=D(t),n=il("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 Sr=32;function cf(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,d=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,p=Sr-u.length-1,k=d.length>p?d.slice(0,p-1)+"\u2026":d,y=Sr-k.length-u.length;r.push({id:`project-review:${i.repoId}`,text:k+" ".repeat(Math.max(1,y))+u,selected:a,focused:l,muted:!0})}else{let c=Ss(i.pullRequest),u=Is(i.pullRequest),p=`${c.text} ${u.text}`,k=Sr-p.length-1,y=d.length>k?d.slice(0,k-1)+"\u2026":d,w=Sr-y.length-p.length,b=y+" ".repeat(Math.max(1,w));r.push({id:`project-review:${i.repoId}`,text:b+p,selected:a,focused:l,segments:[{text:b},{...c,text:c.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(...il("target",o.branch,o.pullRequest))),r}function ol(e,t,r=null){return 3+sl(e,t).length+Ps(e,r).length}function il(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=uf(r.reviewDecision,r.mergeStateStatus),d=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:`${d} \xB7 ${l}`,muted:!0,segments:[{text:d},{text:" \xB7 "},{text:l,style:{fg:pf(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:d,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${al(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(mf)):s.push({id:n("checks-none"),text:r.number?"No GitHub checks reported.":"No checks \u2014 sync after creating a PR.",muted:!0});let c=r.comments??[];return c.length>0&&(s.push({id:n("comments-spacer"),text:""}),s.push({id:n("comments-header"),text:`Review comments (${c.length})`}),s.push(...c.slice(-4).flatMap((u,p)=>ff(u,n(`comment:${p}`))))),s}function df(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 uf(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function pf(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function al(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 mf(e){let{icon:t,color:r}=hf(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," ")} ${wf(e.status)}`,color:r,muted:!1}}function ff(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${al(e.createdAt)}`:"",s=gf(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,d)=>({id:`${t}:body:${d}`,text:` ${i&&d===o.length-1?`${l}\u2026`:l}`,muted:!0}))];return a.push({id:`${t}:spacer`,text:"",muted:!0}),a}function gf(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 hf(e){switch(e){case"success":return{icon:ws,color:"9ece6a"};case"pending":return{icon:hs,color:"e0af68"};case"failed":return{icon:ks,color:"f7768e"};case"skipped":return{icon:gs,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function wf(e){return e==="success"?"passing":e==="failed"?"failing":e}function kf(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=vs(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 d=l.kind==="file"?r.get(l.path):void 0,c=d==="A"?"9ece6a":d==="M"?"e0af68":d==="D"?"f7768e":d==="??"?"565f89":void 0,u=l.kind==="directory"?e.collapsedFileTreePaths.includes(l.path)?Ua:Ba:_a(l.label),p=l.kind==="directory"?"7aa2f7":Ha(l.label),k=" ".repeat(l.depth),y=p?{text:u,style:{fg:p}}:{text:u},w=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:c?{text:l.label,style:{fg:c}}:{text:l.label},b=[{text:k},y,w];return{id:l.path,text:`${k}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:b}})]}function vs(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 Ps(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(yf(t))return Tf(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=>ll(o,e,t))))}return r}function yf(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Tf(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(d=>d.group===a);l.length!==0&&(r.push({id:`repo-diff:${s}:${a}`,text:` ${a}`,muted:!0}),r.push(...l.map(d=>ll(d,e,t,s.length+1))))}}return r}function ll(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 Rf(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:f.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Mt.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 bf(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function Pf(e,t){return{name:f.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function cl(e,t,r,n,s=null){if(s)return Sf(e,t,r,n,s);let o=Yn(e,t,{centerOnly:n});return If(r,o)?{output:pa(o.rows,r.rows,o.row,o.column),region:o}:null}function Sf(e,t,r,n,s){let o=Gi(e,t,s,{centerOnly:n});if(!o||!vf(r,o))return null;let i=r.rows.slice();return{output:o.rows.map(({index:l,row:d})=>i[l]===d?"":(i[l]=d,`\x1B[${o.row+l};${o.column}H${d}`)).join(""),region:{row:o.row,column:o.column,width:o.width,rows:i}}}function If(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}function vf(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rowCount}import{appendFile as Cf,mkdir as Ef,readFile as Af}from"node:fs/promises";import xf from"node:path";var dl=80,Cs=async(e,t)=>{await Ef(xf.dirname(e.errorLogFile),{recursive:!0}),await Cf(e.errorLogFile,Df(t),"utf8")},ul=async(e,t)=>{try{await Cs(e,t)}catch{}},Es=async(e,t=dl)=>{try{let n=(await Af(e.errorLogFile,"utf8")).trimEnd().split(`
|
|
159
|
-
`).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($f(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},pl=async(e,t=dl)=>Es(e,t);function Df(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(`
|
|
160
|
-
`).map(n=>` ${n}`))),`${r.join(`
|
|
161
|
-
`)}
|
|
162
|
-
|
|
163
|
-
`}function $f(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var at={appendErrorLog:Cs,appendErrorLogBestEffort:ul,readErrorLog:Es,readRecentErrorLines:pl};var Mf=["tasks","center","inspector"];function Lf(e,t,r){if(t==="ESCAPE")return h({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return h({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return xs(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return $s({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return h({state:{...e,fileSearchQuery:n},changed:!0})}return h({state:e})}function $s(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return Mi(t)?h({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):h({state:e});if(e.fileSearchQuery!==null)return Lf(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return h({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return h({state:e,exit:!0});if(t==="ESCAPE")return h({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return h({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(lr(e.selectedLeftItemId)||cr(e.selectedLeftItemId)))return h({state:{...e,selectedRunner:ar(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return ml(e,1);if(t==="SHIFT_TAB"||t==="[")return ml(e,-1);if(t==="z"||t==="Z")return h({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===E?Ee(e,-1,r):xs(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===E?Ee(e,1,r):xs(e,1,r);if(t==="PAGE_UP")return Ee(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Ee(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Ee(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Ee(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??$,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return h({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=Bf(e,t);return h({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 h({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return h({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return h({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Et(e.selectedLeftItemId)&&e.selectedTaskId)return h({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Ni(e.selectedLeftItemId)&&e.selectedWorkspaceId)return h({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&hl(e.activeTab,r.ptyTabIds??[]))return h({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return As(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return fl(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return As(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return fl(e,1)}if(ie(t)){if(e.focusedRegion==="tasks"&&(lr(e.selectedLeftItemId)||cr(e.selectedLeftItemId))){let n=Bn(e.selectedLeftItemId),s=qn(e.selectedLeftItemId);return h({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 h({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&Et(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return h({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:st(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&hl(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return h({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:st(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===E)return h({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 h({state:Ff({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return h({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:E,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?h({state:{...e,selectedDiffPath:n,activeTab:E,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?h({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):h({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?h({state:e}):e.selectedActionId==="refresh-checks"?h({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?h({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):h({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return h({state:e})}function Ee(e,t,r){if(t===0)return h({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?wl(e,t,r):e.inspectionMode==="review"?gl(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):h({state:e});if(e.focusedRegion==="center"&&e.activeTab===E){if(e.openInspectionKind==="file")return gl(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return Nf(e,t,r)}return h({state:e})}function ml(e,t){return vr(e,"focusedRegion",Mf,t)}function As(e,t,r){let n=vr(e,"activeTab",r&&r.length>0?r:qf(e),t);return!n.changed||Oi(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:st(n.state.activeTab)??n.state.preferredPtyTabKind}}}function xs(e,t,r){if(e.focusedRegion==="tasks")return Of(e,t,r.leftItemIds);if(e.focusedRegion==="center")return As(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return wl(e,t,r);if(r.projectTargetIds?.length){let s=Ds(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=Ds(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:E,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:vr(e,"selectedActionId",Ei,t)}return vr(e,"selectedActionId",Nn,t)}function Of(e,t,r){let n=Ds(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Un(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=Bn(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=qn(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function jf(e,t){if(e.inspectionMode===t)return h({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?E:e.activeTab;return h({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 fl(e,t){return jf(e,Uf(e.inspectionMode,Wn,t))}function wl(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return h({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=we(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return h({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return h({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?E:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function Ff(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 gl(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=we(e[t]+r,0,o);return i===e[t]?h({state:e}):h({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Nf(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return Wf(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 c=we(i,0,o);return c===e.diffScrollOffset?h({state:e}):h({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let c=we(i,0,o);return c===e.diffScrollOffset?h({state:e}):h({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}if(t>0&&i>o){let c=a[l+1]??null;return c?h({state:{...e,selectedDiffPath:c,activeTab:E,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?h({state:e}):h({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let c=a[l-1]??null;return c?h({state:{...e,selectedDiffPath:c,activeTab:E,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?h({state:e}):h({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=we(i,0,o);return d===e.diffScrollOffset?h({state:e}):h({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function Wf(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=we(e.diffScrollOffset+t,0,o),a=_f(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?h({state:e}):h({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function _f(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function vr(e,t,r,n){let s=r.indexOf(e[t]),o=we(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?h({state:e}):h({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Ds(e,t,r,n,s=!1){if(r.length===0)return h({state:e});let o=r.indexOf(e[t]??r[0]??""),i=we(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?h({state:e}):h({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function Uf(e,t,r){let n=t.indexOf(e);return t[we(n+r,0,t.length-1)]??e}function h(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 hl(e,t){return t.includes(e)}function Bf(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":st(e.activeTab)??e.preferredPtyTabKind}function qf(e){return[e.selectedPtyTabId,e.openInspectionKind?E:null].filter(t=>typeof t=="string")}function we(e,t,r){return Math.min(r,Math.max(t,e))}var kl=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>{let o=await ee(n.paths,e.selectedTaskId),i=t??Vf(o,e.activeTab,e.preferredPtyTabKind),a=bl(o,i,r??void 0,n.config),l={...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id};return await S(n.paths,l),l});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"}`}}},yl=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=await ee(t.paths,e.selectedTaskId),o=s.ptyTabs.findIndex(d=>d.id===e.activeTab);if(o===-1)throw new Error("Only PTY tabs can be closed.");let i=s.ptyTabs[o],a=s.ptyTabs.filter(d=>d.id!==i.id),l=a[Math.min(o,a.length-1)]??null;return await S(t.paths,{...s,ptyTabs:a,selectedPtyTabId:l?.id??null}),{closedTab:i,nextSelectedTab:l}});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}`}}},Tl=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{let n=await ee(t.paths,r);!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab||await S(t.paths,{...n,selectedPtyTabId:e.activeTab})})},Rl=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{let s=await ee(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;o&&await S(t.paths,{...s,selectedPtyTabId:o.id})}),{...e,selectedPtyTabId:r.id};let n=bl(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{let s=await ee(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;if(o){await S(t.paths,{...s,selectedPtyTabId:o.id});return}await S(t.paths,{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function Vf(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function bl(e,t,r,n={}){let s=r??e.runner,o=f.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(k=>k.id)),d=1,c=a;for(;l.has(c);)d+=1,c=`${a}-${d}`;let u=new Date().toISOString(),p=r&&r!==e.runner?r:void 0;return{id:c,kind:t,...p?{runner:p}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?f.runners.buildCommand(s,void 0,n):[],createdAt:u,updatedAt:u}}var lt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Pl=async(e,t,r,n,s)=>{f.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=je();await P(Fe(f.runners.getConfiguredProfile(n,s.config).executable,{cwd:o.repoRoot,env:l}),["--help"],{cwd:o.repoRoot,env:l})}catch(l){let d=l instanceof Error?l.message:"Failed to start runner.",c=await s.taskService.recordStartupFailure(s.paths,o.task.id,d);throw new lt(d,c)}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}},Sl=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},Il=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 ee(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}`}}},vl=async(e,t)=>{await t.taskService.prs.discoverOrRefreshMany(t.paths,e)},Cr=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await at.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var Cl=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 El=async(e,t,r)=>{let n=f.runners.setRunnerEnabled(r.config,e,t);return await f.save(r.paths,n),n},Al=async(e,t,r)=>{let n=f.runners.setRunnerPath(r.config,e,t);return await f.save(r.paths,n),n},xl=async(e,t,r)=>{let n=f.previews.setEnabled(r.config,e,t);return await f.save(r.paths,n),n};var Kf=250;function ke(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function qe(e,t){return he(t,e.ptyRuntime.getViewState(Lt(e,t)))}function Lt(e,t){let r=ke(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 g(e,t){return qe(e,Wi(t,e.model))}function Dl(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:g(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function $l(e,t,r){return Dl(e,t,r?{tone:"success",message:r}:null)}function O(e,t,r){return Dl(e,t,{tone:"error",message:r})}function j(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return at.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function M(e,t){if(!e.uiStateFile)return;e.runtimeState=Di(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Te({uiStateFile:e.uiStateFile},r),()=>Te({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function Hf(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function F(e){return{paths:e.paths,config:e.config,taskService:C,workspaceService:Q,queueTaskMutation:t=>Hf(e,t)}}function Ms(e,t){let r=ke(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?vs(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:_e(e.model),centerTabIds:Fi(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:ol(t,r,s),pageRows:Math.max(5,se(e.activeTerminal.width,e.activeTerminal.height).height-W.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function Ml(e,t){await Tl(t,F(e))}async function K(e){e.model=await Ie(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:g(e,e.state.shell)}:e.state={...e.state,shell:g(e,e.state.shell)}}async function Er(e,t){let r=++e.inspectionRefreshSequence,n=Vn(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 hi(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await Ie(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=i,e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},M(e,e.state.shell),e.render())}function Ll(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)&&Er(e,r).catch(n=>{let s=j(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:O(e,g(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},Kf))}function Ol(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=Ee(e.state.shell,r,Ms(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:g(e,n.state)},M(e,e.state.shell),e.render(),Er(e,e.state.shell).catch(s=>{let o=j(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:O(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}e.state={mode:"main",shell:g(e,n.state)},M(e,e.state.shell),e.render()}},16)))}function Ls(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function Os(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 Fl(e){Os(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.render())})}async function Nl(e,t){let r=g(e,t),n=ke(e.model.tasks,r),s=Lt(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 he(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,ve(se(e.activeTerminal.width,e.activeTerminal.height)));return he({...r,inputMode:"control"},i)}function Wl(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 js(e,t){try{let r=g(e,t),n=ke(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 jl(e,n),await K(e),s=n.selectedPtyTabId)}n&&!s&&(n=await jl(e,n),await K(e),s=n.selectedPtyTabId);let o=g(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:he({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},M(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,ve(se(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ce(s),e.lastTerminalKey=null,e.state={mode:"main",shell:he({...o,inputMode:"terminal"},i)},M(e,e.state.shell)}catch(r){let n=j(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Ce(t.selectedPtyTabId)&&(await Gf(e,t.selectedTaskId,n).catch(()=>{}),await K(e).catch(()=>{})),e.state={mode:"main",shell:O(e,$i(g(e,t),n),n)},M(e,e.state.shell)}e.render()}async function Gf(e,t,r){await Sl(t,r,F(e))}async function _l(e,t,r,n){let s=g(e,t),{nextShell:o}=await kl(s,r,n,F(e));return await K(e),g(e,{...s,...o})}async function Ul(e,t){let r=g(e,t),{closedTab:n,nextShell:s}=await yl(r,F(e));return e.ptyRuntime.disposeSession(n.id),await K(e),g(e,{...r,...s})}async function Bl(e,t){let r=g(e,t),n=_e(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await Il(r,F(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await K(e),g(e,{...r,...i,selectedLeftItemId:zf(n,_e(e.model),s)})}async function ql(e,t){let r=g(e,t),{nextShell:n}=await Cl(r,F(e));return await K(e),g(e,{...r,...n})}async function jl(e,t){return Rl(t,F(e))}function Ar(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:qe(e,e.state.shell)},e.render())},16))}function zf(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 Vl(e,t){if(!(t?.aborted||e.state.mode!=="main"))try{if(await vl(e.model.tasks,F(e)),t?.aborted||(e.lastBackgroundPrPollError=null,e.state.mode!=="main"))return;let r=await Ie(e.workspaceRoot,e.state.shell,e.enabledRunnerIds);if(t?.aborted)return;e.model=r,e.state={mode:"main",shell:g(e,e.state.shell)},e.render()}catch(r){if(t?.aborted)return;let n=r instanceof Error?r.message:"Background PR discovery failed.";n!==e.lastBackgroundPrPollError&&(e.lastBackgroundPrPollError=n,Cr("background PR polling",r,F(e)))}}async function Kl(e,t){let r=g(e,t),n=ke(e.model.tasks,r),s=null,o=null;if(n?.type==="project"&&n.repoTargets?.length){let i=await C.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await K(e);let a=i.synced+i.discovered+i.notFound;o=`Refreshed ${i.synced}/${a} targets`}else{let{disposition:i,task:a}=await C.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await K(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${D(a)?.requiredChecks.length??0} reported`)}return g(e,{...$l(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}import Zf from"node:path";import{readdir as Yf,stat as Qf}from"node:fs/promises";import Hl from"node:path";async function Jf(e){let t=await Yf(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=Hl.join(e,n.name);r.push({name:n.name,path:s,kind:await Xf(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 Gl(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function zl(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 xr(e,t){let r=await Jf(t);e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function Xf(e){let t=Hl.join(e,".git");return await Qf(t).catch(()=>null)!==null}function Yl(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function Ql(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function eg(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:g(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:g(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:g(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await Pl(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,F(e));n=s.task,await K(e);let o=g(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??na(n,"agent"),ve(se(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Ce(o.selectedPtyTabId),e.state={mode:"main",shell:he(o,i)},M(e,e.state.shell)}catch(s){s instanceof lt&&(n=s.task);let o=j(e,"create task",s,"Failed to create task.");n&&!(s instanceof lt)?(await S(e.paths,{...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o}).catch(()=>{}),await K(e).catch(()=>{})):n&&(await S(e.paths,{...n,lastFailureReason:o}).catch(()=>{}),await K(e).catch(()=>{})),e.state={mode:"main",shell:O(e,g(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 tg(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:g(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(ie(t)){eg(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:g(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:g(e,{...r,selectedRunner:ar(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}Li(t)&&(e.state={mode:"main",shell:g(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function rg(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:g(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:g(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:g(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:g(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=Gl(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:g(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:g(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"){xr(e,Zf.dirname(r.cwd)).catch(s=>{let o=j(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:O(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:o}}),o)},e.render()});return}if(t==="RIGHT"||t==="l"||ie(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){xr(e,s.path).catch(i=>{let a=j(e,"open workspace directory",i,"Failed to open directory.");e.state={mode:"main",shell:O(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:o}=F(e);o.addWorkspace(e.paths,s.path).then(async i=>{await K(e);let a=i.repos[0]??null,l=g(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},M(e,e.state.shell),e.render()}).catch(i=>{let a=j(e,"add workspace",i,"Failed to add workspace.");e.state={mode:"main",shell:O(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function ng(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=Fa(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;sg(e,n)}}}async function sg(e,t){let r;try{r=await at.readRecentErrorLines(e.paths)}catch(n){let s=j(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 og(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=Wa(Yl(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"?El(r.runner,r.enabled,F(e)):Al(r.runner,r.path,F(e))).then(s=>{e.state.mode!=="overlay"||e.state.variant!=="runners"||(e.config=s,e.enabledRunnerIds=f.runners.getEnabled(e.config),e.model={...e.model,enabledRunnerIds:e.enabledRunnerIds},e.state={...e.state,shell:g(e,{...e.state.shell,selectedRunner:e.enabledRunnerIds.includes(e.state.shell.selectedRunner)?e.state.shell.selectedRunner:f.runners.getDefault(e.config)}),runnerOptions:r.state},e.render())}).catch(s=>{if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let o=j(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:O(e,g(e,e.state.shell),o),runnerOptions:{...Yl(e),message:o}},e.render()})}function ig(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=Na(Ql(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}xl(r.feature,r.enabled,F(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=j(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:O(e,g(e,e.state.shell),s),previewOptions:{...Ql(e),message:s}},e.render()})}}function Jl(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){tg(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){rg(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){lg(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=$s(e.state.shell,r,Ms(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:g(e,n.state)},M(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:g(e,n.state)},M(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&ie(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=Dt(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(ag(e,r))return;e.lastTerminalKey=sa(r)?{key:r,at:Date.now()}:null;let o=oa(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){Ar(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:g(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:g(e,n.state)},M(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){xr(e,e.workspaceRoot).catch(s=>{let o=j(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:O(e,g(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:o}}),o)},e.render()});return}if(n.createPtyTab){_l(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{js(e,s)}).catch(s=>{let o=j(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:O(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.closePtyTab){Ul(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:O(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.refreshPullRequestChecks){Kl(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:O(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.openPrUrl){let s=ke(e.model.tasks,n.state),o=s?D(s)?.url??null:null;o?zl(o).catch(i=>{let a=j(e,"open PR URL",i,"Failed to open PR in browser.");e.state={mode:"main",shell:O(e,g(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:O(e,g(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){Bl(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:O(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.removeWorkspace){ql(e,n.state).then(s=>{e.state={mode:"main",shell:s},M(e,e.state.shell),e.render()}).catch(s=>{let o=j(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:O(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.attachTerminal){js(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:g(e,n.state)},M(e,e.state.shell),e.render(),e.state.shell.focusedRegion==="tasks"){Ll(e,e.state.shell);return}Er(e,e.state.shell).catch(s=>{let o=j(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:O(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}n.changed&&(e.state={mode:"main",shell:g(e,n.state)},Ml(e,e.state.shell).catch(()=>{}),M(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:g(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){ng(e,r);return}if(e.state.variant==="runners"){og(e,r);return}if(e.state.variant==="previews"){ig(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||ie(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"||ie(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:g(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(ie(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:g(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;Nl(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},M(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=j(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:O(e,g(e,e.state.shell),i)},M(e,e.state.shell),e.render()})}):Fl(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 Xl(e,t){let r=da(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=Dt(o);if(i){ec(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(rs(o)){e.pendingTerminalKeySequence.raw=o,Zl(e);return}Dr(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:g(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},M(e,e.state.shell),e.render();return}let n=ia(r);if(n!==0){Ar(e,n);return}let s=Dt(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
|
|
115
|
+
`)}});let n=()=>{this.clients.delete(t),this.subscriptions.delete(t),this.hasActivitySubscribers()||(this.runtime.setActivityEnabled(!1),this.clearPendingActivityBroadcasts())};t.on("close",n),t.on("error",n)}disposeAll(){for(let t of this.updateTimers.values())clearTimeout(t);this.updateTimers.clear();for(let t of this.activityTimers.values())clearTimeout(t);this.activityTimers.clear(),this.pendingActivities.clear(),this.runtime.disposeAll()}closeClients(){for(let t of this.clients)t.destroy();this.clients.clear(),this.subscriptions.clear(),this.runtime.setActivityEnabled(!1)}async handleLine(t,r){if(r.trim().length===0)return;let n;try{n=JSON.parse(r)}catch{ze(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(t,n);ze(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:al}:{},...n.type==="getActivitySnapshots"?{activities:this.runtime.getActivitySnapshots()}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);ze(t,{id:n.id,ok:!1,error:o})}}handleRequest(t,r){switch(r.type){case"ping":return null;case"ensureSession":return this.attachedTabId=r.tabId,this.subscribe(t,r.tabId,this.runtime.ensureSession(r.taskId,r.tabId,r.size,r.spec));case"hydrateSession":return this.runtime.getViewState(r.tabId);case"write":return this.runtime.write(r.input),null;case"writeKey":return this.runtime.writeKey(r.key),null;case"scrollViewport":return this.runtime.scrollViewport(r.lines),this.runtime.getViewState(this.attachedTabId);case"resize":return this.runtime.resize(r.size),this.runtime.getViewState(this.attachedTabId);case"detach":return this.runtime.detach(),this.attachedTabId=null,null;case"disposeSession":return this.runtime.disposeSession(r.tabId),this.attachedTabId===r.tabId&&(this.attachedTabId=null),null;case"setViewUpdateMode":return this.setViewUpdateMode(t,r.mode);case"setActivityEnabled":return this.setActivityEnabled(t,r.enabled),null;case"subscribeView":return this.subscribe(t,r.tabId,this.runtime.getViewState(r.tabId));case"pruneStale":{let n=new Set(r.keepTabIds),s=new Set([...this.runtime.sessionTabIds(),...this.runtime.getActivitySnapshots().map(o=>o.tabId)]);for(let o of s)n.has(o)||(this.runtime.disposeSession(o),this.attachedTabId===o&&(this.attachedTabId=null));return null}case"getViewState":return this.runtime.getViewState(r.tabId);case"getActivitySnapshots":return null;case"shutdown":return setTimeout(()=>this.onShutdown?.(),0),null;default:return Uf(r)}}subscribe(t,r,n){let s=this.subscriptions.get(t),o=s?.mode??"snapshot";return this.subscriptions.set(t,{mode:o,activityEnabled:s?.activityEnabled??!1,tabId:r,view:n,rowKeys:n.rows.map(Or)}),n}setViewUpdateMode(t,r){let n=this.subscriptions.get(t),s=n?.tabId??null,o=this.runtime.getViewState(s);return this.subscriptions.set(t,{mode:r,activityEnabled:n?.activityEnabled??!1,tabId:s,view:o,rowKeys:o.rows.map(Or)}),o}setActivityEnabled(t,r){let n=this.subscriptions.get(t);if(!n)return;this.subscriptions.set(t,{...n,activityEnabled:r});let s=this.hasActivitySubscribers();this.runtime.setActivityEnabled(s),s||this.clearPendingActivityBroadcasts()}handleRuntimeUpdate(t){let r=null;for(let n of this.clients)this.subscriptions.get(n)?.mode==="snapshot"&&(r??=this.runtime.getViewState(t),ze(n,{type:"update",tabId:t,view:r}));this.scheduleBroadcastUpdate(t)}handleActivityUpdate(t){if(this.hasActivitySubscribers()){if(this.pendingActivities.set(t.tabId,t),t.sessionState!=="running"){let r=this.activityTimers.get(t.tabId);r&&(clearTimeout(r),this.activityTimers.delete(t.tabId)),this.broadcastActivity(t.tabId);return}this.activityTimers.has(t.tabId)||this.activityTimers.set(t.tabId,setTimeout(()=>{this.activityTimers.delete(t.tabId),this.broadcastActivity(t.tabId)},xf))}}handleActivityRemoved(t){let r=this.activityTimers.get(t);r&&(clearTimeout(r),this.activityTimers.delete(t)),this.pendingActivities.delete(t);for(let[n,s]of this.subscriptions)s.activityEnabled&&ze(n,{type:"activityRemoved",tabId:t})}broadcastActivity(t){let r=this.pendingActivities.get(t);if(r){this.pendingActivities.delete(t);for(let[n,s]of this.subscriptions)s.activityEnabled&&ze(n,{type:"activity",snapshot:r})}}hasActivitySubscribers(){return[...this.subscriptions.values()].some(t=>t.activityEnabled)}clearPendingActivityBroadcasts(){for(let t of this.activityTimers.values())clearTimeout(t);this.activityTimers.clear(),this.pendingActivities.clear()}scheduleBroadcastUpdate(t){this.updateTimers.has(t)||!this.hasViewSubscriber(t)||this.updateTimers.set(t,setTimeout(()=>{this.updateTimers.delete(t),this.broadcastUpdate(t)},Af))}hasViewSubscriber(t){for(let r of this.subscriptions.values())if(r.mode==="incremental"&&r.tabId===t)return!0;return!1}broadcastUpdate(t){let r=this.runtime.getViewState(t);for(let n of this.clients){let s=this.subscriptions.get(n);if(!s||s.mode!=="incremental"||s.tabId!==t)continue;let o=Df(s,r),i=$f(s.view,r);s.view=r,s.rowKeys=r.rows.map(Or),(o.rows.length>0||i)&&ze(n,{type:"update",tabId:t,patch:o})}}};function Df(e,t){let r=[];for(let n=0;n<t.rows.length;n+=1){let s=t.rows[n];e.rowKeys[n]!==Or(s)&&r.push({index:n,row:s})}return{status:t.status,error:t.error,scrolledBack:t.scrolledBack??!1,rowCount:t.rows.length,rows:r}}function $f(e,t){return!e||e.status!==t.status||e.error!==t.error||(e.scrolledBack??!1)!==(t.scrolledBack??!1)||e.rows.length!==t.rows.length}function Of(e,t){return e.status!==t.status||e.error!==t.error||(e.scrolledBack??!1)!==t.scrolledBack||e.rows.length!==t.rowCount}function Or(e){return JSON.stringify(e)}function $s(e){let t=bf("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:gt.join(vf(),`craig-${t}.sock`),pidPath:gt.join(e.runtimeDir,"pty-daemon.pid")}}async function Mf(e,t,r){if(await Nf(e.socketPath,1e3))return;await Mr(e.socketPath)&&(await ml(e.socketPath),await ol(e.socketPath,1e3)),await Mr(e.socketPath)&&(await jf(e),await ol(e.socketPath,1e3)),await Ff(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:a}=Lf(n),l=Sf(gt.join(t.runtimeDir,"pty-daemon.log"),"a");yf(i,a,{cwd:n,detached:!0,stdio:["ignore",l,l],env:process.env}).unref()}let s=Date.now();for(;Date.now()-s<5e3;){if(await ul(e.socketPath))return;await Os(50)}let o=await Ds(gt.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
|
|
116
|
+
${o.slice(-2e3)}`:""}`)}async function ul(e){let t=await Wf(e).catch(()=>null);return t?.ok===!0&&pl(t.protocolVersion)}function pl(e){return e!==void 0&&Ef.has(e)}async function Nf(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await ul(e))return!0;await Os(50)}return!1}function Lf(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=gt.resolve(gt.dirname(t),"..","node_modules",".bin","tsx");return{command:xn("tsx")??n,args:[t,"__craig-daemon",e]}}let r=process.argv.slice(1);return{command:process.execPath,args:[...process.execArgv,...r,"__craig-daemon",e]}}async function Ff(e){let t=await Ds(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&hl(r))return}await Ye(e.socketPath,{force:!0}),await Ye(e.pidPath,{force:!0})}async function Mr(e){let t=await gl(e).catch(()=>null);return t?(t.end(),!0):!1}async function ml(e){await fl(e,{id:1,type:"shutdown"}).catch(()=>null)}async function jf(e){let t=await Ds(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!hl(r)){await Ye(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await Ye(e.socketPath,{force:!0})}}async function Wf(e){return fl(e,{id:1,type:"ping"})}function fl(e,t){return new Promise((r,n)=>{let s=il(e),o="",i=setTimeout(()=>{s.destroy(),n(new Error("Craig PTY daemon request timed out."))},500),a=()=>clearTimeout(i);s.setEncoding("utf8"),s.once("connect",()=>s.write(`${JSON.stringify(t)}
|
|
117
|
+
`)),s.once("error",l=>{a(),n(l)}),s.on("data",l=>{o+=String(l);let c=o.indexOf(`
|
|
118
|
+
`);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 ol(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await Mr(e))return;await Os(50)}}function gl(e){return new Promise((t,r)=>{let n=il(e);n.once("connect",()=>t(n)),n.once("error",r)})}function _f(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function ze(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
|
|
119
|
+
`)}catch{}}function hl(e){try{return process.kill(e,0),!0}catch{return!1}}function Os(e){return new Promise(t=>setTimeout(t,e))}function Uf(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var Ms=["Runners","Feature Previews","Error Log","Help"],wl={incrementalCenterPane:"Incremental center pane",agentActivityIndicators:"Agent activity indicators"};function Ns(e,t){return O.map(r=>{let n=f.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 Tl(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 Rl(e){return ue.map(t=>`${f.previews.isEnabled(e,t)?"[x]":"[ ]"} ${wl[t]}`)}function yl(e){return e.message??"Experimental features may change or be removed. Enter toggles."}function bl(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Ms.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Nr(t)?e===0?{kind:"runners"}:e===1?{kind:"previews"}:e===2?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Pl(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(ue.length-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(!Nr(r))return{kind:"noop",state:e};let n=ue[e.menuIndex]??ue[0],s=!f.previews.isEnabled(t,n);return{kind:"save-enabled",feature:n,enabled:s,state:{...e,message:`${wl[n]} ${s?"enabled":"disabled"}.`}}}function Sl(e,t,r,n){if(e.pathEdit)return qf({...e,pathEdit:e.pathEdit},t,r);let s=Ns(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=O[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:a,value:t.runners?.[a]?.path??""}}}}if(!Nr(r))return{kind:"noop",state:e};let o=O[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:`${f.runners.getProfile(o).displayName} ${i?"disabled":"enabled"}.`}}}function qf(e,t,r){if(r==="ESCAPE")return{kind:"render",state:kl({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Nr(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:kl({...e,message:s.length>0?`${f.runners.getProfile(n).displayName} executable saved.`:`${f.runners.getProfile(n).displayName} executable reset to default.`})}}return Bf(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function kl(e){let t={...e};return delete t.pathEdit,t}function Nr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
120
|
+
`}function Bf(e){return e.length===1&&e>=" "&&e!==""}import Kt from"node:path";function Il(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 Cl="\u{F024B} ",vl="\u{F0DCF} ",El="\u25CB",Ls="\uEA64",Al="\uEAFE",xl="\uEBDA",Fs="\u25CB",js="\u25CF",Ws="\u2713",_s="\u2715";function Dl(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 $l={idle:0,working:1,ready:2,error:3};function Vt(e,t,r,n="idle"){let s=t.find(o=>o.tabId===e);return s?s.sessionState==="failed"||s.sessionState==="exited"&&s.exitCode!==0?"error":s.sessionState==="exited"?"ready":r-s.lastActivityAt<5e3?"working":"ready":n}function Us(e,t,r,n){let s=e.ptyTabs.find(i=>i.kind==="agent")?.id,o=t===s&&e.runnerSession?.lastKnownState==="failed"?"error":"idle";return Vt(t,r,n,o)}function qs(e,t,r){let n="idle";for(let s of e.ptyTabs){if(s.kind!=="agent")continue;let o=Us(e,s.id,t,r);$l[o]>$l[n]&&(n=o)}return n}function Ol(e,t,r){return e.some(n=>n.ptyTabs.some(s=>s.kind==="agent"&&Vt(s.id,t,r)==="working"))}var Fr="empty",q={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function Fl(e,t,r){let n=Gf(t,e),s=t.repos.find(y=>y.id===e.selectedRepoId)??t.repos[0]??null,o=n?t.tasks.filter(y=>y.workspaceId===n.id):t.tasks,i=n?.kind==="project"?o:s?o.filter(y=>y.repoId===s.id):[],a=i.find(y=>y.id===e.selectedTaskId)??i[0]??null,l=a?.type==="project",c=Cg(t.tasks),d=Yf(e,a),u=zf(e,a,d,r),m=u.find(y=>y.id===d)??u[0]??{id:"agent",label:"CODEX"},T=t.inspection?.taskId===a?.id?t.inspection:null,R=s?.name??"no repo",h=a?f.runners.getDisplayName(a.runner):f.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 ${f.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 [${f.runners.getDisplayName(e.selectedRunner)}] Enter create task Esc pause ? help`:_t(e.selectedLeftItemId)?"n new task Enter attach X close task Esc pause ? help":e.selectedLeftItemId?.startsWith("workspace:")?"n new task Enter select X remove workspace Esc pause ? help":"n new task Enter select Esc pause ? help":e.focusedRegion==="center"?a===null?"n new task Tab tasks Esc pause ? help":d===A?"\u2191\u2193/wheel/PgUp/PgDn scroll \u2190/\u2192 switch Tab inspector Esc pause ? help":`+ new tab a ${f.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:Kt.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${Kt.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:h},leftTree:Vf(e,t,r),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(y=>vg(y,c[y])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":m.label,taskId:e.workspaceBrowser?"new workspace":a?.id??"no task",repo:R,agent:h},centerTranscript:Hf(d,e,s,a,e.workspaceBrowser,T,n),tabs:u,rightContext:Ig(s,a),rightInspection:lg(e,a,T)}}function Vf(e,t,r){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return Kf(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,T={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:qs(d,r.snapshots,r.now),activityAnimationFrame:r.animationFrame}:{}},R=Wl(d);R&&(T.prBadge=R),n.push(T)}if(i.kind==="project"){let d=`new-task-workspace:${i.id}`,u=e.selectedLeftItemId===d;n.push({id:d,text:`+ New Project Task [${f.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 [${f.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 Kf(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}`,T=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,R={id:`task:${u.id}`,taskId:u.id,text:s?T:`${m?"\u25B8":"\u2022"} ${T}`,indent:2,selected:m,focused:m&&t.focusedRegion==="tasks",...s?{activity:qs(u,s.snapshots,s.now),activityAnimationFrame:s.animationFrame}:{}},h=Wl(u);h&&(R.prBadge=h),e.push(R)}let c=`new-task:${i.id}`,d=t.selectedLeftItemId===c;e.push({id:c,text:`+ New Task [${f.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 Gf(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 Hf(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 T=m===s.selectedIndex?"\u25B8":" ",R=u.kind==="repo"?" [git repo]":"/";return`${T} ${u.name}${R}`}),d=s.query!==null?`Search: ${s.query}\u2588`:"";return fe(["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 fe(["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 fe([`No tasks in ${c}.`,"",`Press n or choose + New ${d} to create one with ${f.runners.getDisplayName(t.selectedRunner)}.`])}let a=n.ptyTabs.find(l=>l.id===e)??null;return a?a.kind==="agent"?fe([`${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."]):fe([`${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===A&&t.openInspectionKind==="file"?Xf(n,o,t.fileScrollOffset):e===A&&t.openInspectionKind==="diff"?Zf(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?fe(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):fe(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function zf(e,t,r,n){let s=t?.ptyTabs.map(i=>({id:i.id,label:Qf(i),...i.kind==="agent"&&n&&t?{activity:Us(t,i.id,n.snapshots,n.now),activityAnimationFrame:n.animationFrame}:{}}))??[];if(!t)return[{id:Fr,label:"EMPTY",active:r===Fr,focused:e.focusedRegion==="center"&&r===Fr}];let o=e.openInspectionKind||r===A?[{id:A,label:Jf(e)}]:[];return[...s,...o].map(i=>({...i,active:i.id===r,focused:e.focusedRegion==="center"&&i.id===r}))}function Yf(e,t){return t?t.ptyTabs.some(r=>r.id===e.activeTab)||e.activeTab===A&&e.openInspectionKind?e.activeTab:e.activeTab==="agent"||e.activeTab==="terminal"?t.ptyTabs.find(r=>r.kind===e.activeTab)?.id??t.ptyTabs[0]?.id??A:e.selectedPtyTabId&&t.ptyTabs.some(r=>r.id===e.selectedPtyTabId)?e.selectedPtyTabId:t.ptyTabs[0]?.id??A:Fr}function Qf(e){return e.title.toUpperCase()}function Jf(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?Kt.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function Xf(e,t,r){if(!e)return fe(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return fe(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=jl(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:""},...eg(n.lines,r,s)]}function Zf(e,t,r){if(!e)return fe(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return fe(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=jl(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:""},...tg(n.lines,r,s)]}function fe(e){return e.map(t=>({text:t}))}function eg(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:q.lineNumber}},{text:" \u2502 ",style:{fg:q.gutter}},...Bs(o,r)],tone:"default"}})}function tg(e,t,r){let n=rg(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>ng(o,r))}function rg(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 ng(e,t){let r=Ml(e.oldNumber),n=Ml(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:q.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:q.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?og(Bs(e.text,t),o.bg,o.fallbackFg):Bs(e.text,t),l=o?{fg:q.lineNumber,bg:o.bg}:{fg:q.lineNumber},c=o?{fg:q.gutter,bg:o.bg}:{fg:q.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:c},...a],fullBleed:o!==null}}function Ml(e){return e===null?" ":String(e).padStart(4," ")}function jl(e){let t=Kt.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 Bs(e,t){return t==="diff"?sg(e):t==="markdown"?ig(e):t==="json"?Vs(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?Vs(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 sg(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:q.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:q.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:q.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:q.diffMeta}}]:[{text:e}]}function og(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function ig(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:q.markup,bold:!0}}]:Vs(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function Vs(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:ag(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function ag(e){return e.startsWith("//")||e.startsWith("/*")?{fg:q.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:q.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:q.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:q.markup}:{fg:q.keyword}}function lg(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"?_l(t.repoTargets??[]):s?.pullRequest??(t?$(t):null),i=[cg(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=Bl(e,t),l=Ks(e,r),c=fg([{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,...bg(e,r)]}:{title:"",rows:[...i,...Ks(e,r)]}}function cg(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=Gs(t),i=Hs(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function Nl(e){return[{text:" "},Gs(e),{text:" "},Hs(e)]}function Wl(e){if(e.type==="project"&&e.repoTargets?.length){let r=_l(e.repoTargets);return r?Nl(r):null}let t=$(e);return t?.number?Nl(t):null}function _l(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=ug(r);return{number:-1,status:dg(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 dg(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 ug(e){let t=e.map(r=>Ul(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 Gs(e){return!e||!e.number?{text:El,style:{fg:"565f89"}}:e.status==="merged"?{text:Al,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:xl,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:Ls,style:{fg:"565f89"}}:{text:Ls,style:{fg:"9ece6a"}}}function Hs(e){return e?.aggregateReadiness?Ll(e.aggregateReadiness):Ll(Ul(e))}function Ll(e){return e==="failed"?{text:_s,style:{fg:"f7768e"}}:e==="pending"?{text:js,style:{fg:"e0af68"}}:e==="success"?{text:Ws,style:{fg:"9ece6a"}}:{text:Fs,style:{fg:"565f89"}}}function Ul(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")?ql(e)?"failed":pg(e)?"success":"pending":"pending"}function pg(e){return!!(e.mergeable&&!e.draft&&!ql(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function ql(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function Bl(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return mg(e,t);let r=$(t),n=Kl("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 Lr=32;function mg(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=Lr-u.length-1,T=c.length>m?c.slice(0,m-1)+"\u2026":c,R=Lr-T.length-u.length;r.push({id:`project-review:${i.repoId}`,text:T+" ".repeat(Math.max(1,R))+u,selected:a,focused:l,muted:!0})}else{let d=Gs(i.pullRequest),u=Hs(i.pullRequest),m=`${d.text} ${u.text}`,T=Lr-m.length-1,R=c.length>T?c.slice(0,T-1)+"\u2026":c,h=Lr-R.length-m.length,y=R+" ".repeat(Math.max(1,h));r.push({id:`project-review:${i.repoId}`,text:y+m,selected:a,focused:l,segments:[{text:y},{...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(...Kl("target",o.branch,o.pullRequest))),r}function Vl(e,t,r=null){return 3+Bl(e,t).length+Ks(e,r).length}function Kl(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=gg(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:hg(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:c,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${Gl(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(kg)):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)=>wg(u,n(`comment:${m}`))))),s}function fg(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 gg(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function hg(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function Gl(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 kg(e){let{icon:t,color:r}=Rg(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," ")} ${yg(e.status)}`,color:r,muted:!1}}function wg(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${Gl(e.createdAt)}`:"",s=Tg(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 Tg(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 Rg(e){switch(e){case"success":return{icon:Ws,color:"9ece6a"};case"pending":return{icon:js,color:"e0af68"};case"failed":return{icon:_s,color:"f7768e"};case"skipped":return{icon:Fs,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function yg(e){return e==="success"?"passing":e==="failed"?"failing":e}function bg(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=zs(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)?Cl:vl:Il(l.label),m=l.kind==="directory"?"7aa2f7":Dl(l.label),T=" ".repeat(l.depth),R=m?{text:u,style:{fg:m}}:{text:u},h=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:d?{text:l.label,style:{fg:d}}:{text:l.label},y=[{text:T},R,h];return{id:l.path,text:`${T}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:y}})]}function zs(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 Ks(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(Pg(t))return Sg(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=>Hl(o,e,t))))}return r}function Pg(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function Sg(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=>Hl(c,e,t,s.length+1))))}}return r}function Hl(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 Ig(e,t){return e?t?[{label:"Task",value:t.id},{label:"Repo",value:e.name},{label:"Agent",value:f.runners.getDisplayName(t.runner)},{label:"Branch",value:t.branch},{label:"Status",value:t.status},{label:"Worktree",value:Kt.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 Cg(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function vg(e,t){return{name:f.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function zl(e,t,r,n,s=null){if(s)return Eg(e,t,r,n,s);let o=ks(e,t,{centerOnly:n});return Ag(r,o)?{output:Dr(o.rows,r.rows,o.row,o.column),region:o}:null}function Eg(e,t,r,n,s){let o=Oa(e,t,s,{centerOnly:n});if(!o||!xg(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 Ag(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}function xg(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rowCount}function Yl(e,t,r){let n={...e},s="";for(let o of r){let i=e[o],a=t[o];if(!Dg(i,a))return null;!i||!a||(s+=Dr(a.rows,i.rows,a.row,a.column),n[o]=a)}return{output:s,regions:n}}function Dg(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 $g=["tasks","center","inspector"];function Og(e,t,r){if(t==="ESCAPE")return w({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return w({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return Qs(e,t==="UP"||t==="k"?-1:1,r);if(t==="ENTER")return Xs({...e,fileSearchQuery:null},t,r);if(t.length===1&&t>=" "){let n=(e.fileSearchQuery??"")+t;return w({state:{...e,fileSearchQuery:n},changed:!0})}return w({state:e})}function Xs(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return Ta(t)?w({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):w({state:e});if(e.fileSearchQuery!==null)return Og(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return w({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return w({state:e,exit:!0});if(t==="ESCAPE")return w({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return w({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(Tr(e.selectedLeftItemId)||Rr(e.selectedLeftItemId)))return w({state:{...e,selectedRunner:wr(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return Ql(e,1);if(t==="SHIFT_TAB"||t==="[")return Ql(e,-1);if(t==="z"||t==="Z")return w({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===A?Me(e,-1,r):Qs(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===A?Me(e,1,r):Qs(e,1,r);if(t==="PAGE_UP")return Me(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return Me(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return Me(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return Me(e,3,r);if(t==="r"&&e.focusedRegion==="center"&&e.selectedTaskId){let n=r.enabledRunnerIds??O,s=e.centerTabRunner?n.indexOf(e.centerTabRunner):-1,o=s===n.length-1?null:n[s+1];return w({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=Ug(e,t);return w({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 w({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return w({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return w({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&_t(e.selectedLeftItemId)&&e.selectedTaskId)return w({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Sa(e.selectedLeftItemId)&&e.selectedWorkspaceId)return w({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&Zl(e.activeTab,r.ptyTabIds??[]))return w({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return Ys(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return Jl(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return Ys(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return Jl(e,1)}if(pe(t)){if(e.focusedRegion==="tasks"&&(Tr(e.selectedLeftItemId)||Rr(e.selectedLeftItemId))){let n=ds(e.selectedLeftItemId),s=us(e.selectedLeftItemId);return w({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 w({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&_t(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return w({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:mt(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&Zl(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return w({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:mt(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===A)return w({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 w({state:Lg({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return w({state:{...e,selectedFileTreePath:s,selectedFilePath:s,activeTab:A,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?w({state:{...e,selectedDiffPath:n,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?w({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):w({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?w({state:e}):e.selectedActionId==="refresh-checks"?w({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?w({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):w({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return w({state:e})}function Me(e,t,r){if(t===0)return w({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?ec(e,t,r):e.inspectionMode==="review"?Xl(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):w({state:e});if(e.focusedRegion==="center"&&e.activeTab===A){if(e.openInspectionKind==="file")return Xl(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return Fg(e,t,r)}return w({state:e})}function Ql(e,t){return jr(e,"focusedRegion",$g,t)}function Ys(e,t,r){let n=jr(e,"activeTab",r&&r.length>0?r:qg(e),t);return!n.changed||ya(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:mt(n.state.activeTab)??n.state.preferredPtyTabKind}}}function Qs(e,t,r){if(e.focusedRegion==="tasks")return Mg(e,t,r.leftItemIds);if(e.focusedRegion==="center")return Ys(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return ec(e,t,r);if(r.projectTargetIds?.length){let s=Js(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=Js(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:jr(e,"selectedActionId",fa,t)}return jr(e,"selectedActionId",is,t)}function Mg(e,t,r){let n=Js(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=cs(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=ds(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=us(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function Ng(e,t){if(e.inspectionMode===t)return w({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?A:e.activeTab;return w({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 Jl(e,t){return Ng(e,_g(e.inspectionMode,as,t))}function ec(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return w({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=Se(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return w({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return w({state:{...e,selectedFileTreePath:a,selectedFilePath:l?a:e.selectedFilePath,activeTab:l?A:e.activeTab,openInspectionKind:l?"file":e.openInspectionKind,fileScrollOffset:l?0:e.fileScrollOffset,actionMessage:null},changed:!0,refreshInspection:l})}function Lg(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 Xl(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=Se(e[t]+r,0,o);return i===e[t]?w({state:e}):w({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Fg(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return jg(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=Se(i,0,o);return d===e.diffScrollOffset?w({state:e}):w({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let d=Se(i,0,o);return d===e.diffScrollOffset?w({state:e}):w({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}if(t>0&&i>o){let d=a[l+1]??null;return d?w({state:{...e,selectedDiffPath:d,activeTab:A,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?w({state:e}):w({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let d=a[l-1]??null;return d?w({state:{...e,selectedDiffPath:d,activeTab:A,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?w({state:e}):w({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let c=Se(i,0,o);return c===e.diffScrollOffset?w({state:e}):w({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}function jg(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=Se(e.diffScrollOffset+t,0,o),a=Wg(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?w({state:e}):w({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function Wg(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function jr(e,t,r,n){let s=r.indexOf(e[t]),o=Se(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?w({state:e}):w({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Js(e,t,r,n,s=!1){if(r.length===0)return w({state:e});let o=r.indexOf(e[t]??r[0]??""),i=Se(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?w({state:e}):w({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function _g(e,t,r){let n=t.indexOf(e);return t[Se(n+r,0,t.length-1)]??e}function w(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 Zl(e,t){return t.includes(e)}function Ug(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":mt(e.activeTab)??e.preferredPtyTabKind}function qg(e){return[e.selectedPtyTabId,e.openInspectionKind?A:null].filter(t=>typeof t=="string")}function Se(e,t,r){return Math.min(r,Math.max(t,e))}var tc=async(e,t,r,n)=>{if(!e.selectedTaskId)throw new Error("Select a task before creating a tab.");let s=await n.queueTaskMutation(async()=>{let o=await ae(n.paths,e.selectedTaskId),i=t??Bg(o,e.activeTab,e.preferredPtyTabKind),a=oc(o,i,r??void 0,n.config),l={...o,ptyTabs:[...o.ptyTabs,a],selectedPtyTabId:a.id};return await P(n.paths,l),l});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"}`}}},rc=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=await ae(t.paths,e.selectedTaskId),o=s.ptyTabs.findIndex(c=>c.id===e.activeTab);if(o===-1)throw new Error("Only PTY tabs can be closed.");let i=s.ptyTabs[o],a=s.ptyTabs.filter(c=>c.id!==i.id),l=a[Math.min(o,a.length-1)]??null;return await P(t.paths,{...s,ptyTabs:a,selectedPtyTabId:l?.id??null}),{closedTab:i,nextSelectedTab:l}});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}`}}},nc=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{let n=await ae(t.paths,r);!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab||await P(t.paths,{...n,selectedPtyTabId:e.activeTab})})},sc=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{let s=await ae(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;o&&await P(t.paths,{...s,selectedPtyTabId:o.id})}),{...e,selectedPtyTabId:r.id};let n=oc(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{let s=await ae(t.paths,e.id),o=s.ptyTabs.find(i=>i.kind==="agent")??null;if(o){await P(t.paths,{...s,selectedPtyTabId:o.id});return}await P(t.paths,{...s,ptyTabs:[...s.ptyTabs,n],selectedPtyTabId:n.id})}),{...e,ptyTabs:[...e.ptyTabs,n],selectedPtyTabId:n.id}};function Bg(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function oc(e,t,r,n={}){let s=r??e.runner,o=f.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(T=>T.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"?f.runners.buildCommand(s,void 0,n):[],createdAt:u,updatedAt:u}}var ht=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},ic=async(e,t,r,n,s)=>{f.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=Be();Ve(f.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 ht(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}},ac=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},lc=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 ae(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}`}}},cc=async(e,t)=>{await t.taskService.prs.discoverOrRefreshMany(t.paths,e)},Wr=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await tt.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var dc=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 uc=async(e,t,r)=>{let n=f.runners.setRunnerEnabled(r.config,e,t);return await f.save(r.paths,n),n},pc=async(e,t,r)=>{let n=f.runners.setRunnerPath(r.config,e,t);return await f.save(r.paths,n),n},mc=async(e,t,r)=>{let n=f.previews.setEnabled(r.config,e,t);return await f.save(r.paths,n),n};var Vg=250;function Ie(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function Qe(e,t){return Pe(t,e.ptyRuntime.getViewState(kt(e,t)))}function kt(e,t){let r=Ie(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 g(e,t){return Qe(e,Ia(t,e.model))}function fc(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:g(e,{...e.state.shell,footerToast:null})},e.render())},600),{...t,footerToast:r}):{...t,footerToast:null}}function gc(e,t,r){return fc(e,t,r?{tone:"success",message:r}:null)}function j(e,t,r){return fc(e,t,{tone:"error",message:r})}function W(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return tt.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function L(e,t){if(!e.uiStateFile)return;e.runtimeState=ka(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Ce({uiStateFile:e.uiStateFile},r),()=>Ce({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function Kg(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function _(e){return{paths:e.paths,config:e.config,taskService:E,workspaceService:H,queueTaskMutation:t=>Kg(e,t)}}function Zs(e,t){let r=Ie(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?zs(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:He(e.model),centerTabIds:Pa(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:Vl(t,r,s),pageRows:Math.max(5,le(e.activeTerminal.width,e.activeTerminal.height).height-N.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function hc(e,t){await nc(t,_(e))}async function Q(e){e.model=await De(e.workspaceRoot,e.state.shell,e.enabledRunnerIds),e.state.mode==="main"?e.state={mode:"main",shell:g(e,e.state.shell)}:e.state={...e.state,shell:g(e,e.state.shell)}}function kc(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 _r(e,t){let r=++e.inspectionRefreshSequence,n=ps(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 ra(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await De(e.workspaceRoot,t,e.enabledRunnerIds),r!==e.inspectionRefreshSequence)return;e.model=i,e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},L(e,e.state.shell),e.render())}function wc(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)&&_r(e,r).catch(n=>{let s=W(e,"refresh inspection",n,"Failed to refresh inspection.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,actionMessage:s}),s)},e.render()})},Vg))}function Tc(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=Me(e.state.shell,r,Zs(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:g(e,n.state)},L(e,e.state.shell),e.render(),_r(e,e.state.shell).catch(s=>{let o=W(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}e.state={mode:"main",shell:g(e,n.state)},L(e,e.state.shell),e.render()}},16)))}function eo(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function to(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 yc(e){to(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.render())})}async function bc(e,t){let r=g(e,t),n=Ie(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 Pe(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,$e(le(e.activeTerminal.width,e.activeTerminal.height)));return Pe({...r,inputMode:"control"},i)}function ro(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 no(e,t){try{let r=g(e,t),n=Ie(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 Rc(e,n),await Q(e),s=n.selectedPtyTabId)}n&&!s&&(n=await Rc(e,n),await Q(e),s=n.selectedPtyTabId);let o=g(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:Pe({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},L(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,$e(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Oe(s),e.lastTerminalKey=null,e.state={mode:"main",shell:Pe({...o,inputMode:"terminal"},i)},L(e,e.state.shell)}catch(r){let n=W(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&Oe(t.selectedPtyTabId)&&(await Gg(e,t.selectedTaskId,n).catch(()=>{}),await Q(e).catch(()=>{})),e.state={mode:"main",shell:j(e,wa(g(e,t),n),n)},L(e,e.state.shell)}e.render()}async function Gg(e,t,r){await ac(t,r,_(e))}async function Pc(e,t,r,n){let s=g(e,t),{nextShell:o}=await tc(s,r,n,_(e));return await Q(e),g(e,{...s,...o})}async function Sc(e,t){let r=g(e,t),{closedTab:n,nextShell:s}=await rc(r,_(e));return e.ptyRuntime.disposeSession(n.id),await Q(e),g(e,{...r,...s})}async function Ic(e,t){let r=g(e,t),n=He(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await lc(r,_(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await Q(e),g(e,{...r,...i,selectedLeftItemId:Hg(n,He(e.model),s)})}async function Cc(e,t){let r=g(e,t),{nextShell:n}=await dc(r,_(e));return await Q(e),g(e,{...r,...n})}async function Rc(e,t){return sc(t,_(e))}function Ur(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:Qe(e,e.state.shell)},e.render())},16))}function Hg(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 Ec(e,t,r){if(r?.aborted||e.state.mode!=="main")return;let n=vc(e),s=t.takeDueTasks(e.model.tasks,n);if(s.length!==0)try{if(await cc(s,_(e)),r?.aborted||(e.lastBackgroundPrPollError=null,e.state.mode!=="main"))return;let o=await De(e.workspaceRoot,e.state.shell,e.enabledRunnerIds);if(r?.aborted)return;t.recordSuccess(s.map(i=>o.tasks.find(a=>a.id===i.id)??i),vc(e)),e.model=o,e.state={mode:"main",shell:g(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,Wr("background PR polling",o,_(e)))}}function vc(e){return e.state.mode!=="main"?{selectedTaskId:null,reviewVisible:!1}:{selectedTaskId:e.state.shell.selectedTaskId,reviewVisible:e.state.shell.inspectionMode==="review"}}async function Ac(e,t){let r=g(e,t),n=Ie(e.model.tasks,r),s=null,o=null;if(n?.type==="project"&&n.repoTargets?.length){let i=await E.prs.discoverOrRefreshAll(e.paths,r.selectedTaskId);await Q(e);let a=i.synced+i.discovered+i.notFound;o=`Refreshed ${i.synced}/${a} targets`}else{let{disposition:i,task:a}=await E.prs.discoverOrRefresh(e.paths,r.selectedTaskId);await Q(e),s=i==="not_found"?`No PR found for ${a.branch}`:null,i!=="not_found"&&(o=`Refreshed checks: ${$(a)?.requiredChecks.length??0} reported`)}return g(e,{...gc(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}var zg={pendingForegroundMs:5e3,pendingBackgroundMs:15e3,stableForegroundMs:3e4,stableBackgroundMs:6e4,discoveryForegroundMs:6e4,discoveryBackgroundMs:18e4,rateLimitBaseMs:6e4,rateLimitMaxMs:15*6e4},qr=class{scheduledTasks=new Map;now;intervals;minimumIntervalMs;rateLimitFailures=0;notBefore=0;constructor(t={}){this.minimumIntervalMs=Math.max(1e3,t.minimumIntervalMs??5e3),this.intervals={...zg,...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 he,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=Yg(t),s=t.id===r.selectedTaskId&&r.reviewVisible;if(n.length>0){let o=n.some(Qg);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 Yg(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 Qg(e){return e.requiredChecks.some(t=>t.status==="pending"||t.status==="unknown")}import th from"node:path";import{readdir as Jg,stat as Xg}from"node:fs/promises";import xc from"node:path";async function Zg(e){let t=await Jg(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=xc.join(e,n.name);r.push({name:n.name,path:s,kind:await eh(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 Dc(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function $c(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 Br(e,t){let r=await Zg(t);e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:r,activeTab:e.state.shell.selectedPtyTabId??e.state.shell.activeTab,actionMessage:null})},e.render())}async function eh(e){let t=xc.join(e,".git");return await Xg(t).catch(()=>null)!==null}function Oc(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function Mc(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function rh(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:g(e,{...t,taskPromptError:"Select a workspace first."})},e.render();return}if(r.length===0){e.state={mode:"main",shell:g(e,{...t,taskPromptError:"Task prompt cannot be empty."})},e.render();return}e.creatingTask=!0,e.state={mode:"main",shell:g(e,{...t,actionMessage:`Creating ${t.selectedRunner} task in ${t.selectedWorkspaceId??t.selectedRepoId}...`})},e.render();let n=null;try{let s=await ic(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,_(e));n=s.task,kc(e,n);let o=g(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??Ba(n,"agent"),$e(le(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=Oe(o.selectedPtyTabId),e.state={mode:"main",shell:Pe(o,i)},L(e,e.state.shell)}catch(s){s instanceof ht&&(n=s.task);let o=W(e,"create task",s,"Failed to create task.");n&&!(s instanceof ht)?(await P(e.paths,{...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o}).catch(()=>{}),await Q(e).catch(()=>{})):n&&(await P(e.paths,{...n,lastFailureReason:o}).catch(()=>{}),await Q(e).catch(()=>{})),e.state={mode:"main",shell:j(e,g(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 nh(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:g(e,{...r,taskPromptInput:null,taskPromptError:null,actionMessage:null})},e.render();return}if(pe(t)){rh(e);return}if(t==="BACKSPACE"){e.state={mode:"main",shell:g(e,{...r,taskPromptInput:r.taskPromptInput.slice(0,-1),taskPromptError:null})},e.render();return}if(t==="CTRL_R"){e.state={mode:"main",shell:g(e,{...r,selectedRunner:wr(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}Ra(t)&&(e.state={mode:"main",shell:g(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function sh(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:g(e,{...e.state.shell,workspaceBrowser:{...r,query:null,selectedIndex:0}})},e.render();return}e.state={mode:"main",shell:g(e,{...e.state.shell,workspaceBrowser:null,actionMessage:null})},e.render();return}if(t==="/"){e.state={mode:"main",shell:g(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:g(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:g(e,{...e.state.shell,workspaceBrowser:{...r,query:s,selectedIndex:0}})},e.render();return}let n=Dc(r);if(t==="UP"||t==="k"){e.state={mode:"main",shell:g(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:g(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"){Br(e,th.dirname(r.cwd)).catch(s=>{let o=W(e,"open parent workspace directory",s,"Failed to open parent directory.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:o}}),o)},e.render()});return}if(t==="RIGHT"||t==="l"||pe(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){Br(e,s.path).catch(i=>{let a=W(e,"open workspace directory",i,"Failed to open directory.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()});return}let{workspaceService:o}=_(e);o.addWorkspace(e.paths,s.path).then(async i=>{await Q(e);let a=i.repos[0]??null,l=g(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},L(e,e.state.shell),e.render()}).catch(i=>{let a=W(e,"add workspace",i,"Failed to add workspace.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,workspaceBrowser:{...r,error:a}}),a)},e.render()})}}function oh(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=bl(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;ih(e,n)}}}async function ih(e,t){let r;try{r=await tt.readRecentErrorLines(e.paths)}catch(n){let s=W(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 ah(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=Sl(Oc(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"?uc(r.runner,r.enabled,_(e)):pc(r.runner,r.path,_(e))).then(s=>{e.state.mode!=="overlay"||e.state.variant!=="runners"||(e.config=s,e.enabledRunnerIds=f.runners.getEnabled(e.config),e.model={...e.model,enabledRunnerIds:e.enabledRunnerIds},e.state={...e.state,shell:g(e,{...e.state.shell,selectedRunner:e.enabledRunnerIds.includes(e.state.shell.selectedRunner)?e.state.shell.selectedRunner:f.runners.getDefault(e.config)}),runnerOptions:r.state},e.render())}).catch(s=>{if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let o=W(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:j(e,g(e,e.state.shell),o),runnerOptions:{...Oc(e),message:o}},e.render()})}function lh(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=Pl(Mc(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}mc(r.feature,r.enabled,_(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=W(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:j(e,g(e,e.state.shell),s),previewOptions:{...Mc(e),message:s}},e.render()})}}function Nc(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){nh(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){sh(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){dh(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=Xs(e.state.shell,r,Zs(e,e.state.shell));if(n.exit){e.exit(0);return}if(n.detachTerminal){e.ptyRuntime.detach(),e.state={mode:"main",shell:g(e,n.state)},L(e,e.state.shell),e.render();return}if(e.state.shell.inputMode==="terminal"){if(n.changed){e.state={mode:"main",shell:g(e,n.state)},L(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&pe(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=Bt(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(ch(e,r))return;e.lastTerminalKey=Va(r)?{key:r,at:Date.now()}:null;let o=Ka(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){Ur(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:g(e,n.state)},e.pendingClear=!0,e.render();return}if(n.beginTaskPrompt){e.state={mode:"main",shell:g(e,n.state)},L(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){Br(e,e.workspaceRoot).catch(s=>{let o=W(e,"browse workspaces",s,"Failed to browse workspaces.");e.state={mode:"main",shell:j(e,g(e,{...n.state,workspaceBrowser:{cwd:e.workspaceRoot,entries:[],selectedIndex:0,query:null,error:o}}),o)},e.render()});return}if(n.createPtyTab){Pc(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{no(e,s)}).catch(s=>{let o=W(e,"create PTY tab",s,"Failed to create tab.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.closePtyTab){Sc(e,n.state).then(s=>{e.state={mode:"main",shell:s},L(e,e.state.shell),e.render()}).catch(s=>{let o=W(e,"close PTY tab",s,"Failed to close tab.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.refreshPullRequestChecks){Ac(e,n.state).then(s=>{e.state={mode:"main",shell:s},L(e,e.state.shell),e.render()}).catch(s=>{let o=W(e,"refresh PR checks",s,"Failed to refresh PR checks.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.openPrUrl){let s=Ie(e.model.tasks,n.state),o=s?$(s)?.url??null:null;o?$c(o).catch(i=>{let a=W(e,"open PR URL",i,"Failed to open PR in browser.");e.state={mode:"main",shell:j(e,g(e,n.state),a)},e.render()}):(e.state={mode:"main",shell:j(e,g(e,n.state),"No PR URL available.")},e.render());return}if(n.closeTask){Ic(e,n.state).then(s=>{e.state={mode:"main",shell:s},L(e,e.state.shell),e.render()}).catch(s=>{let o=W(e,"close task",s,"Failed to close task.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.removeWorkspace){Cc(e,n.state).then(s=>{e.state={mode:"main",shell:s},L(e,e.state.shell),e.render()}).catch(s=>{let o=W(e,"remove workspace",s,"Failed to remove workspace.");e.state={mode:"main",shell:j(e,g(e,{...n.state,actionMessage:o}),o)},e.render()});return}if(n.attachTerminal){no(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:g(e,n.state)},L(e,e.state.shell),(e.state.shell.focusedRegion!=="tasks"||!e.renderTaskNavigation())&&e.render(),e.state.shell.focusedRegion==="tasks"){wc(e,e.state.shell);return}_r(e,e.state.shell).catch(s=>{let o=W(e,"refresh inspection",s,"Failed to refresh inspection.");e.state={mode:"main",shell:j(e,g(e,{...e.state.shell,actionMessage:o}),o)},e.render()});return}n.changed&&(e.state={mode:"main",shell:g(e,n.state)},hc(e,e.state.shell).catch(()=>{}),L(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:g(e,e.state.shell)},e.pendingClear=!0,e.render();return}if(e.state.variant==="options"){oh(e,r);return}if(e.state.variant==="runners"){ah(e,r);return}if(e.state.variant==="previews"){lh(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||pe(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"||pe(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:g(e,e.state.shell)},e.pendingClear=!0,e.render());return}if(pe(r)){if(e.state.menuIndex===0){let n=e.state.variant==="boot";e.state={mode:"main",shell:g(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;bc(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},L(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=W(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:j(e,g(e,e.state.shell),i)},L(e,e.state.shell),e.render()})}):yc(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 Lc(e,t){let r=Qa(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=Bt(o);if(i){jc(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(Ss(o)){e.pendingTerminalKeySequence.raw=o,Fc(e);return}Vr(e)}if(r.includes("")){e.ptyRuntime.detach(),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey=null,e.state={mode:"main",shell:g(e,{...e.state.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},L(e,e.state.shell),e.render();return}let n=Ga(r);if(n!==0){Ur(e,n);return}let s=Bt(r);if(s){e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(e.suppressTerminalEnterOnAttach&&r!=="\r"&&r!==`
|
|
164
121
|
`&&r!==`\r
|
|
165
|
-
`&&(e.suppressTerminalEnterOnAttach=!1),ca(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function ag(e,t){if(e.pendingTerminalKeySequence){let r=aa(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=Dt(n);if(s)return ec(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(rs(n))return e.pendingTerminalKeySequence.raw=n,Zl(e),!0}return Dr(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>Dr(e),30)},!0)}function Zl(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>Dr(e),30))}function Dr(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function ec(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function tc(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){Ol(e,ts(t));return}let r=ts(t);r!==0&&Ar(e,r)}function lg(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var $r=class{jobs=new Map;resolutionMs;now;onError;timer=null;abortController=null;constructor(t){this.resolutionMs=Fs(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:Fs(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=Fs(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 Fs(e,t){if(!Number.isFinite(e)||e<=0)throw new Error(`${t} must be a positive number.`);return e}var rc=1e3,ug=dg(import.meta.url),pg=ug("terminal-kit"),mg=pg.terminal;function Ws(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function nc(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function fg(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 sc(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=de(t),n=await f.load(r),s=f.runners.getEnabled(n),o=e.uiStateFile?await He({uiStateFile:e.uiStateFile}):null,i=await Ie(t,void 0,s),a=Ct(xi(o,n),i);i=await Ie(t,a,s);let l={current:i},d=()=>{},c=()=>{},u=()=>{},p={workspaceRoot:t,onUpdate:y=>d(y),onActivity:y=>c(y),onActivityRemoved:y=>u(y),resolveSessionSpec:(y,w)=>ra(l.current,w,t)},k=e.ptyRuntime??await Pa({...p,paths:r,viewUpdateMode:f.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot",activityEnabled:f.previews.isEnabled(n,"agentActivityIndicators")});return new Promise(y=>{let w=e.terminal??mg,b=null,q=null,te=null,me=null,I=0,re=!1,Ve=new Map,m,Ae=new $r({resolutionMs:f.previews.isEnabled(n,"agentActivityIndicators")?150:rc,onError:(T,V)=>Cr(`heartbeat job "${T}"`,V,F(m))});m={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Ct(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${f.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:k,resolve:y,render:()=>{},exit:T=>y(T),setAgentActivityEnabled:T=>{Ae.setResolutionMs(T?150:rc),m.ptyRuntime.setActivityEnabled?.(T)}},m.setAgentActivityEnabled(f.previews.isEnabled(n,"agentActivityIndicators")),d=T=>{m.state.mode==="main"&&(me=fg(me,T),m.ptyRenderTimer||(m.ptyRenderTimer=setTimeout(()=>{m.ptyRenderTimer=null;let V=me;if(me=null,m.state.mode==="main"){let ye=qe(m,m.state.shell);if(m.state={mode:"main",shell:ye},!f.previews.isEnabled(m.config,"incrementalCenterPane")||!te||!q){m.render();return}let Nt=se(w.width,w.height),ct={...te,terminal:ye.terminal},xe=cl(Nt,ct,q,ye.centerZoomed,V?.kind==="rows"?V.rowIndices:null);if(!xe){m.render();return}xe.output.length>0&&w.noFormat(xe.output),te=ct,q=xe.region,w.hideCursor(!0)}},f.previews.isEnabled(m.config,"incrementalCenterPane")?0:50)))},c=T=>{m.state.mode==="main"&&f.previews.isEnabled(m.config,"agentActivityIndicators")&&Ce(T.tabId)&&Ve.get(T.tabId)!==$t(T.tabId,[T],Date.now())&&m.render()},u=T=>{m.state.mode==="main"&&f.previews.isEnabled(m.config,"agentActivityIndicators")&&Ce(T)&&Ve.get(T)!=="idle"&&m.render()},m.render=()=>{Wl(m);let T=m.state;m.ptyRuntime.setViewedTab?.(T.mode==="main"?Lt(m,T.shell):null);let V=se(w.width,w.height),ye;if(T.mode==="main"){let Ft=f.previews.isEnabled(m.config,"agentActivityIndicators"),Nt=Ft?m.ptyRuntime.getActivitySnapshots?.()??[]:[],ct=Date.now(),xe=Xa(g(m,T.shell),m.model,Ft?{snapshots:Nt,now:ct,animationFrame:I}:void 0);if(Ve.clear(),Ft)for(let ic of m.model.tasks)for(let Mr of ic.ptyTabs)Mr.kind==="agent"&&Ve.set(Mr.id,$t(Mr.id,Nt,ct));let qs=Hi(V,xe,{centerOnly:T.shell.centerZoomed,focusFlashActive:m.focusFlashUntil!==null&&Date.now()<m.focusFlashUntil});ye=qs.frame,te=xe,q=qs.center}else ye=T.variant==="boot"?Bi(V,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:m.versionText,updateText:m.updateText}):T.variant==="pause"?qi(V,{menuIndex:T.menuIndex,optionsMessage:T.optionsMessage,versionText:m.versionText,updateText:m.updateText}):T.variant==="options"?wr(V,{menuIndex:T.menuIndex,optionsMenuItems:ps}):T.variant==="runners"?wr(V,{menuIndex:Ws(T).menuIndex,optionsMenuItems:ms(m.config,Ws(T)),optionsMessage:La(Ws(T)),optionsSubtitle:"Runners"}):T.variant==="previews"?wr(V,{menuIndex:nc(T).menuIndex,optionsMenuItems:Oa(m.config),optionsMessage:ja(nc(T)),optionsSubtitle:"Feature Previews - Experimental"}):T.variant==="error-log"?Ki(V,{errorLogPath:T.errorLog?.path??r.errorLogFile,errorLogLines:T.errorLog?.lines??[]}):Vi(V),te=null,q=null;m.pendingClear&&(w.moveTo(1,1),w.eraseDisplayBelow(),m.pendingClear=!1,b=null),w.noFormat(ua(ye,b)),b=ye,w.hideCursor(!0)};let Ot=T=>Jl(m,T),jt=T=>Xl(m,T),_s=T=>tc(m,T),oc=()=>{process.stdout.off("resize",Us),process.off("SIGCONT",Bs),w.removeListener("key",Ot),w.removeListener("unknown",jt),w.removeListener("mouse",_s),m.scrollRenderTimer&&(clearTimeout(m.scrollRenderTimer),m.scrollRenderTimer=null),m.inspectionScrollRenderTimer&&(clearTimeout(m.inspectionScrollRenderTimer),m.inspectionScrollRenderTimer=null),m.leftNavInspectionTimer&&(clearTimeout(m.leftNavInspectionTimer),m.leftNavInspectionTimer=null),m.pendingTerminalKeySequence&&(clearTimeout(m.pendingTerminalKeySequence.timer),m.pendingTerminalKeySequence=null),m.ptyRenderTimer&&(clearTimeout(m.ptyRenderTimer),m.ptyRenderTimer=null),m.footerToastTimer&&(clearTimeout(m.footerToastTimer),m.footerToastTimer=null),m.focusFlashTimer&&(clearTimeout(m.focusFlashTimer),m.focusFlashTimer=null),Ae.stop(),m.ptyRuntime.disposeAll(),w.grabInput(!1),w.hideCursor(!1),w.fullscreen(!1)};m.exit=T=>{oc(),y(T)};let Us=()=>{Ls(m),m.state.mode==="main"&&m.state.shell.inputMode==="terminal"&&(m.ptyRuntime.resize(ve(se(w.width,w.height))),m.state={mode:"main",shell:qe(m,m.state.shell)}),m.render()},Bs=()=>{Ls(m),m.state.mode==="main"&&m.state.shell.inputMode==="terminal"&&(m.ptyRuntime.resize(ve(se(w.width,w.height))),m.state={mode:"main",shell:qe(m,m.state.shell)}),m.render()};process.stdout.on("resize",Us),process.on("SIGCONT",Bs),w.grabInput(!0),m.inputCaptureMode="control",w.hideCursor(!0),w.fullscreen(!0),w.on("key",Ot),w.on("unknown",jt),w.on("mouse",_s),Ae.register({id:"github.pull-requests",intervalMs:(m.config.github?.watchIntervalSeconds??5)*1e3,run:T=>Vl(m,T)}),Ae.register({id:"agent.activity-indicators",intervalMs:150,run:()=>{if(!f.previews.isEnabled(m.config,"agentActivityIndicators")){I=0,re=!1;return}let T=Date.now(),V=za(m.model.tasks,m.ptyRuntime.getActivitySnapshots?.()??[],T);(V||re)&&(I=(I+1)%6,m.state.mode==="main"&&m.render()),re=V}}),Ae.start(),f.version.checkForUpdate().then(T=>{T.updateAvailable&&T.latest&&(m.updateText=`Update available: v${T.latest}`,m.render())}),m.bootHydrationReady=Os(m).catch(()=>{}),m.render()})}async function gg(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??process.cwd(),a=de(i);return await Sa(a),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??process.cwd(),a=de(i);return await Ia(a),0}let e=no(process.argv.slice(2)),t=process.cwd(),r=de(t),n={paths:r};if(e.mode==="interactive")return await sc({uiStateFile:r.uiStateFile,workspaceRoot:r.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await mi(e.command,n),o=fi(s);return o.length>0&&process.stdout.write(`${o}
|
|
166
|
-
`),
|
|
167
|
-
`),1}}var hg=await gg();process.exit(hg);
|
|
122
|
+
`&&(e.suppressTerminalEnterOnAttach=!1),Ya(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function ch(e,t){if(e.pendingTerminalKeySequence){let r=Ha(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=Bt(n);if(s)return jc(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(Ss(n))return e.pendingTerminalKeySequence.raw=n,Fc(e),!0}return Vr(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>Vr(e),30)},!0)}function Fc(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>Vr(e),30))}function Vr(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function jc(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function Wc(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){Tc(e,Ps(t));return}let r=Ps(t);r!==0&&Ur(e,r)}function dh(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var Kr=class{jobs=new Map;resolutionMs;now;onError;timer=null;abortController=null;constructor(t){this.resolutionMs=so(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:so(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=so(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 so(e,t){if(!Number.isFinite(e)||e<=0)throw new Error(`${t} must be a positive number.`);return e}var _c=1e3,mh=ph(import.meta.url),fh=mh("terminal-kit"),gh=fh.terminal;function io(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function Uc(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function hh(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 qc(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=ee(t),n=await f.load(r),s=f.runners.getEnabled(n),o=e.uiStateFile?await Ze({uiStateFile:e.uiStateFile}):null,i=await De(t,void 0,s),a=Wt(ha(o,n),i);i=await De(t,a,s);let l={current:i},c=()=>{},d=()=>{},u=()=>{},m={workspaceRoot:t,onUpdate:R=>c(R),onActivity:R=>d(R),onActivityRemoved:R=>u(R),resolveSessionSpec:(R,h)=>qa(l.current,h,t)},T=e.ptyRuntime??await ll({...m,paths:r,viewUpdateMode:f.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot",activityEnabled:f.previews.isEnabled(n,"agentActivityIndicators")});return new Promise(R=>{let h=e.terminal??gh,y=null,B=null,z=null,se=null,C=null,we=0,wt=!1,Je=new Map,Gr=new qr({minimumIntervalMs:(n.github?.watchIntervalSeconds??5)*1e3}),p,Ne=new Kr({resolutionMs:f.previews.isEnabled(n,"agentActivityIndicators")?150:_c,onError:(k,M)=>Wr(`heartbeat job "${k}"`,M,_(p))});p={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Wt(a,i)},get model(){return l.current},set model(k){l.current=k},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${f.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:h,ptyRuntime:T,resolve:R,render:()=>{},renderTaskNavigation:()=>!1,exit:k=>R(k),setAgentActivityEnabled:k=>{Ne.setResolutionMs(k?150:_c),p.ptyRuntime.setActivityEnabled?.(k)}},p.setAgentActivityEnabled(f.previews.isEnabled(n,"agentActivityIndicators")),c=k=>{p.state.mode==="main"&&(C=hh(C,k),p.ptyRenderTimer||(p.ptyRenderTimer=setTimeout(()=>{p.ptyRenderTimer=null;let M=C;if(C=null,p.state.mode==="main"){let J=Qe(p,p.state.shell);if(p.state={mode:"main",shell:J},!f.previews.isEnabled(p.config,"incrementalCenterPane")||!se||!B){p.render();return}let X=le(h.width,h.height),Tt={...se,terminal:J.terminal},Fe=zl(X,Tt,B,J.centerZoomed,M?.kind==="rows"?M.rowIndices:null);if(!Fe){p.render();return}Fe.output.length>0&&h.noFormat(Fe.output),se=Tt,B=Fe.region,z&&(z={...z,center:Fe.region}),y=null,h.hideCursor(!0)}},f.previews.isEnabled(p.config,"incrementalCenterPane")?0:50)))},d=k=>{p.state.mode==="main"&&f.previews.isEnabled(p.config,"agentActivityIndicators")&&Oe(k.tabId)&&Je.get(k.tabId)!==Vt(k.tabId,[k],Date.now())&&p.render()},u=k=>{p.state.mode==="main"&&f.previews.isEnabled(p.config,"agentActivityIndicators")&&Oe(k)&&Je.get(k)!=="idle"&&p.render()};let Te=k=>{let M=le(h.width,h.height),J=f.previews.isEnabled(p.config,"agentActivityIndicators"),de=J?p.ptyRuntime.getActivitySnapshots?.()??[]:[],X=Date.now(),Tt=Fl(g(p,k.shell),p.model,J?{snapshots:de,now:X,animationFrame:we}:void 0);if(Je.clear(),J)for(let Vc of p.model.tasks)for(let Hr of Vc.ptyTabs)Hr.kind==="agent"&&Je.set(Hr.id,Vt(Hr.id,de,X));let Fe=$a(M,Tt,{centerOnly:k.shell.centerZoomed,focusFlashActive:p.focusFlashUntil!==null&&Date.now()<p.focusFlashUntil});return{data:Tt,presentation:Fe}},Le=(k,M,J,de)=>{if(!z)return!1;let X=Yl(z,M.regions,J);return X?(X.output.length>0&&h.noFormat(X.output),se=k,z=X.regions,B=X.regions.center,y=de?M.frame:null,h.hideCursor(!0),!0):!1};p.renderTaskNavigation=()=>{if(p.state.mode!=="main"||p.pendingClear||!f.previews.isEnabled(p.config,"incrementalCenterPane"))return!1;ro(p),p.ptyRuntime.setViewedTab?.(kt(p,p.state.shell));let{data:k,presentation:M}=Te(p.state);return Le(k,M,["rail","left","center","footer"],!1)},p.render=()=>{ro(p);let k=p.state;p.ptyRuntime.setViewedTab?.(k.mode==="main"?kt(p,k.shell):null);let M=le(h.width,h.height),J,de=null;if(k.mode==="main"){let X=Te(k);if(de=X.presentation,J=de.frame,f.previews.isEnabled(p.config,"incrementalCenterPane")&&!p.pendingClear&&Le(X.data,de,["rail","left","center","right","footer"],!0))return;se=X.data,B=de.center}else J=k.variant==="boot"?Ea(M,{menuIndex:k.menuIndex,optionsMessage:k.optionsMessage,versionText:p.versionText,updateText:p.updateText}):k.variant==="pause"?Aa(M,{menuIndex:k.menuIndex,optionsMessage:k.optionsMessage,versionText:p.versionText,updateText:p.updateText}):k.variant==="options"?Er(M,{menuIndex:k.menuIndex,optionsMenuItems:Ms}):k.variant==="runners"?Er(M,{menuIndex:io(k).menuIndex,optionsMenuItems:Ns(p.config,io(k)),optionsMessage:Tl(io(k)),optionsSubtitle:"Runners"}):k.variant==="previews"?Er(M,{menuIndex:Uc(k).menuIndex,optionsMenuItems:Rl(p.config),optionsMessage:yl(Uc(k)),optionsSubtitle:"Feature Previews - Experimental"}):k.variant==="error-log"?Da(M,{errorLogPath:k.errorLog?.path??r.errorLogFile,errorLogLines:k.errorLog?.lines??[]}):xa(M),se=null,B=null,z=null;p.pendingClear&&(h.moveTo(1,1),h.eraseDisplayBelow(),p.pendingClear=!1,y=null),h.noFormat(Ja(J,y)),y=J,z=de?.regions??null,h.hideCursor(!0)};let Gt=k=>Nc(p,k),Ht=k=>Lc(p,k),zt=k=>Wc(p,k),Bc=()=>{process.stdout.off("resize",ao),process.off("SIGCONT",lo),h.removeListener("key",Gt),h.removeListener("unknown",Ht),h.removeListener("mouse",zt),p.scrollRenderTimer&&(clearTimeout(p.scrollRenderTimer),p.scrollRenderTimer=null),p.inspectionScrollRenderTimer&&(clearTimeout(p.inspectionScrollRenderTimer),p.inspectionScrollRenderTimer=null),p.leftNavInspectionTimer&&(clearTimeout(p.leftNavInspectionTimer),p.leftNavInspectionTimer=null),p.pendingTerminalKeySequence&&(clearTimeout(p.pendingTerminalKeySequence.timer),p.pendingTerminalKeySequence=null),p.ptyRenderTimer&&(clearTimeout(p.ptyRenderTimer),p.ptyRenderTimer=null),p.footerToastTimer&&(clearTimeout(p.footerToastTimer),p.footerToastTimer=null),p.focusFlashTimer&&(clearTimeout(p.focusFlashTimer),p.focusFlashTimer=null),Ne.stop(),p.ptyRuntime.disposeAll(),h.grabInput(!1),h.hideCursor(!1),h.fullscreen(!1)};p.exit=k=>{Bc(),R(k)};let ao=()=>{eo(p),p.state.mode==="main"&&p.state.shell.inputMode==="terminal"&&(p.ptyRuntime.resize($e(le(h.width,h.height))),p.state={mode:"main",shell:Qe(p,p.state.shell)}),p.render()},lo=()=>{eo(p),p.state.mode==="main"&&p.state.shell.inputMode==="terminal"&&(p.ptyRuntime.resize($e(le(h.width,h.height))),p.state={mode:"main",shell:Qe(p,p.state.shell)}),p.render()};process.stdout.on("resize",ao),process.on("SIGCONT",lo),h.grabInput(!0),p.inputCaptureMode="control",h.hideCursor(!0),h.fullscreen(!0),h.on("key",Gt),h.on("unknown",Ht),h.on("mouse",zt),Ne.register({id:"github.pull-requests",intervalMs:1e3,run:k=>Ec(p,Gr,k)}),Ne.register({id:"agent.activity-indicators",intervalMs:150,run:()=>{if(!f.previews.isEnabled(p.config,"agentActivityIndicators")){we=0,wt=!1;return}let k=Date.now(),M=Ol(p.model.tasks,p.ptyRuntime.getActivitySnapshots?.()??[],k);(M||wt)&&(we=(we+1)%6,p.state.mode==="main"&&p.render()),wt=M}}),Ne.start(),f.version.checkForUpdate().then(k=>{k.updateAvailable&&k.latest&&(p.updateText=`Update available: v${k.latest}`,p.render())}),p.bootHydrationReady=to(p).catch(()=>{}),p.render()})}async function kh(){try{if(process.argv[2]==="__craig-daemon"){let e=process.argv[3]??process.cwd(),t=ee(e);return await cl(t),0}if(process.argv[2]==="__craig-daemon-shutdown"){let e=process.argv[3]??process.cwd(),t=ee(e);return await dl(t),0}}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
|
|
123
|
+
`),1}return Zi({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),runInteractive:e=>qc({uiStateFile:ee(e).uiStateFile,workspaceRoot:e})})}var wh=await kh();process.exit(wh);
|