craig-cli 0.8.6 → 0.8.7
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 +54 -79
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`;await s.writeFile(o,"utf8"),await s.sync(),await s.close(),await
|
|
4
|
-
`)};var
|
|
2
|
+
var fc=Object.defineProperty;var Vt=(e,t)=>{for(var r in t)fc(e,r,{get:t[r],enumerable:!0})};import{readFile as yc}from"node:fs/promises";import{randomUUID as gc}from"node:crypto";import{open as hc,readFile as vg,rename as wc,rm as kc}from"node:fs/promises";import Ur from"node:path";async function _(e,t){let r=Ur.dirname(e),n=Ur.join(r,`.${Ur.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 wc(n,e)}catch(o){throw await s.close().catch(()=>{}),await kc(n,{force:!0}).catch(()=>{}),o}}async function Je(e){try{let t=await yc(e.uiStateFile,"utf8"),r=JSON.parse(t);return Tc(r,e.uiStateFile)}catch(t){if(bc(t))return null;throw t}}async function Se(e,t){await _(e.uiStateFile,{...t,updatedAt:new Date().toISOString()})}function Ht(){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 Tc(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")||!Qe(e,"inputMode")||!Qe(e,"focusedRegion")||!Qe(e,"activeTab")||!Qe(e,"inspectorSection")||!Qe(e,"inspectionMode")||!Kt(e,"openInspectionKind")||!Kt(e,"selectedFileTreePath")||!Kt(e,"selectedFilePath")||!Kt(e,"selectedDiffPath")||!Rc(e,"collapsedFileTreePaths")||!Qe(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 Qe(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||typeof e[t]=="string")}function Kt(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||e[t]===null||typeof e[t]=="string")}function Rc(e,t){return typeof e=="object"&&e!==null&&(!(t in e)||Array.isArray(e[t])&&e[t].every(r=>typeof r=="string"))}function bc(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var qr={};Vt(qr,{RUNNER_IDS:()=>$,assertEnabled:()=>Zs,buildCommand:()=>ro,getConfiguredProfile:()=>Gt,getDefault:()=>Xs,getDisplayName:()=>to,getEnabled:()=>zt,getProfile:()=>Xe,isRunnerType:()=>Yt,parse:()=>eo,setRunnerEnabled:()=>no,setRunnerPath:()=>so});var $=["codex","cursor","claude"];var Js={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 Xe=e=>Js[e];var Gt=(e,t={})=>{let r=Xe(e),n=t.runners?.[e]?.path?.trim();return{...r,executable:n&&n.length>0?n:r.executable}};var zt=(e={})=>$.filter(t=>e.runners?.[t]?.enabled!==!1);var Xs=(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 Zs=(e,t={})=>{if(t.runners?.[e]?.enabled===!1)throw new Error(`Runner "${e}" is disabled in .craig/config.json.`)};var Yt=e=>$.includes(e);var eo=e=>{if(!e||e.length===0)return"codex";if(!Yt(e))throw new Error(`Unsupported runner "${e}". Expected one of: ${$.join(", ")}.`);return e};var to=e=>Xe(e).displayName;var ro=(e,t,r={})=>{let n=[Gt(e,r).executable];return t&&t.length>0&&n.push(t),n};var no=(e,t,r)=>({...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}});var so=(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 Vr={};Vt(Vr,{PREVIEW_FEATURE_IDS:()=>le,isEnabled:()=>oo,setEnabled:()=>io});var le=["incrementalCenterPane","agentActivityIndicators"];function oo(e,t){return e.previews?.[t]===!0}function io(e,t,r){return{...e,previews:{...e.previews,[t]:r}}}import{mkdir as Pc,readFile as Sc,writeFile as Ic}from"node:fs/promises";import vc from"node:path";var Cc=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",ao=async e=>{try{return await Sc(e,"utf8")}catch(t){if(Cc(t))return null;throw t}},lo=async(e,t)=>{await Pc(vc.dirname(e),{recursive:!0}),await Ic(e,t,"utf8")};var Qt=(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(!$.includes(n))throw new Error(`Craig config at ${t} is invalid. "runners.${n}" is not supported. Expected one of: ${$.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(!le.includes(n))throw new Error(`Craig config at ${t} is invalid. "previews.${n}" is not supported. Expected one of: ${le.join(", ")}.`);if(typeof s!="boolean")throw new Error(`Craig config at ${t} is invalid. "previews.${n}" must be a boolean.`)}}return r};var Kr=async(e,t={readConfigFile:ao})=>{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 Qt(n,e.configFile)};var Hr=async(e,t,r={writeConfigFile:lo})=>{Qt(t,e.configFile),await r.writeConfigFile(e.configFile,`${JSON.stringify(t,null,2)}
|
|
4
|
+
`)};var Gr={};Vt(Gr,{checkForUpdate:()=>co,getCurrent:()=>Jt});var Jt=()=>{try{return"0.8.7"}catch{return"unknown"}};var Ec="https://registry.npmjs.org/craig-cli/latest",Ac=3600*1e3,xc={value:null},Dc=(e,t)=>{let r=d=>d.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},co=async(e={fetch:globalThis.fetch,getCurrent:Jt,cache:xc})=>{let t=e.getCurrent(),r=Date.now();if(e.cache.value&&r-e.cache.value.cachedAt<Ac)return e.cache.value.result;let n=null;try{let o=await e.fetch(Ec,{signal:AbortSignal.timeout(5e3)});o.ok&&(n=(await o.json()).version??null)}catch{}let s={current:t,latest:n,updateAvailable:n!==null&&n!==t&&Dc(n,t)};return e.cache.value={result:s,cachedAt:r},s};var f={load:Kr,save:Hr,previews:Vr,runners:qr,version:Gr};function uo(e){let t=[...e];for(;t[0]==="--";)t.shift();if(t.length===0)return{mode:"interactive"};if(t.length>=3&&t[0]==="repo"&&t[1]==="add"){let r=t.slice(2).join(" ").trim();if(r.length===0)throw new Error(`Repo path cannot be empty.
|
|
5
5
|
|
|
6
|
-
`+
|
|
6
|
+
`+Q());return{mode:"command",command:{kind:"addRepo",path:r}}}if(t.length>=3&&t[0]==="workspace"&&t[1]==="add"){let r=t.slice(2).join(" ").trim();if(r.length===0)throw new Error(`Workspace path cannot be empty.
|
|
7
7
|
|
|
8
|
-
`+
|
|
8
|
+
`+Q());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
9
|
|
|
10
|
-
${
|
|
10
|
+
${Q()}`);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
11
|
|
|
12
|
-
`+
|
|
12
|
+
`+Q());if(r!==-1&&n!==-1)throw new Error(`Task creation accepts either '--repo' or '--workspace', not both.
|
|
13
13
|
|
|
14
|
-
`+
|
|
14
|
+
`+Q());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
15
|
|
|
16
|
-
`+
|
|
16
|
+
`+Q());if(i!==void 0&&i.length===0)throw new Error(`Workspace id cannot be empty.
|
|
17
17
|
|
|
18
|
-
`+
|
|
18
|
+
`+Q());if(d.length===0)throw new Error(`Task prompt cannot be empty.
|
|
19
19
|
|
|
20
|
-
`+
|
|
20
|
+
`+Q());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
21
|
|
|
22
|
-
${
|
|
22
|
+
${Q()}`)}if(t.length===3&&t[0]==="task"&&t[1]==="attach")return{mode:"command",command:{kind:"attachTask",taskId:pe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="show")return{mode:"command",command:{kind:"showTask",taskId:pe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="logs")return{mode:"command",command:{kind:"streamTaskLogs",taskId:pe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="diff")return{mode:"command",command:{kind:"showTaskDiff",taskId:pe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="focus")return{mode:"command",command:{kind:"focusTask",taskId:pe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="open")return{mode:"command",command:{kind:"openTask",taskId:pe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="check")return{mode:"command",command:{kind:"runChecks",taskId:pe(t[2])}};if(t.length===3&&t[0]==="task"&&t[1]==="commit")return{mode:"command",command:{kind:"commitTask",taskId:pe(t[2])}};if(t.length===4&&t[0]==="link"&&t[1]==="add")return{mode:"command",command:{kind:"addTaskLink",taskId:pe(t[2]),repoId:$c(t[3])}};if(t.length===3&&t[0]==="link"&&t[1]==="list")return{mode:"command",command:{kind:"listTaskLinks",taskId:pe(t[2])}};throw new Error(`Unsupported command: ${t.join(" ")}
|
|
23
23
|
|
|
24
|
-
${
|
|
25
|
-
`)}function
|
|
24
|
+
${Q()}`)}function Q(){return["Craig commands:"," craig Show the Craig phase 0 placeholder"," craig repo add Register a repo in the current Craig workspace"," craig workspace add <path> Register a repo or parent-directory workspace"," craig repo list List registered repos"," craig repo remove Remove a registered repo"," craig workspace list List active workspaces"," craig workspace list --archived List archived workspaces"," craig workspace archive Archive a workspace"," craig workspace restore Restore an archived workspace"," craig workspace remove Remove an archived workspace"," craig task new --repo <repo-id> [--runner codex|cursor|claude] <prompt> Create a new Craig repo task"," craig task new --workspace <workspace-id> [--runner codex|cursor|claude] <prompt> Create a new Craig workspace task"," craig task list [--repo <repo-id>] List known Craig tasks"," craig task show Show details for a Craig task"," craig task logs Stream Craig-managed logs for a task"," craig task diff Show the current worktree diff for a task"," craig task attach Attach to a live task session"," craig task focus Focus the tmux pane for a task"," craig task open Open the task worktree or print its path"," craig task check Run configured checks for a task"," craig task commit Commit all task worktree changes"," craig link add Add a linked repo to a task"," craig link list List linked repos for a task"].join(`
|
|
25
|
+
`)}function pe(e){let t=e.trim();if(t.length===0)throw new Error(`Task id cannot be empty.
|
|
26
26
|
|
|
27
|
-
${
|
|
27
|
+
${Q()}`);return t}function $c(e){let t=e.trim();if(t.length===0)throw new Error(`Repo id cannot be empty.
|
|
28
28
|
|
|
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})
|
|
29
|
+
${Q()}`);return t}var q=(e,t)=>{let r=zr(e);if(!Lc(r))throw new Error(`Craig task record at ${t} is invalid. Remove or repair the file before rerunning Craig.`);return r},zr=e=>{if(typeof e!="object"||e===null)return e;let t=e;return{...t,runner:Yr(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:jc(t),bundlePath:typeof t.bundlePath=="string"||t.bundlePath===null?t.bundlePath:null,selectedRepoTargetId:typeof t.selectedRepoTargetId=="string"||t.selectedRepoTargetId===null?t.selectedRepoTargetId:null,repoTargets:Oc(t.repoTargets),runnerSession:t.runnerSession??Mc(t),checks:Vc(t),lastCommit:t.lastCommit??null,prs:Kc(t),artifacts:Yc(t),cleanup:Qc(t)}},Mc=e=>{if(typeof e.title!="string")return null;let t=Yr(e.runner);return{command:f.runners.buildCommand(t,e.title),pid:null,startedAt:null,lastKnownState:e.status==="running"?"running":"starting",exitCode:null,exitedAt:null}},Lc=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id=="string"&&typeof t.title=="string"&&typeof t.slug=="string"&&(t.type==="repo"||t.type==="project")&&typeof t.status=="string"&&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"&&mo(t.ptyTabs)&&(t.bundlePath===void 0||t.bundlePath===null||typeof t.bundlePath=="string")&&(t.selectedRepoTargetId===void 0||t.selectedRepoTargetId===null||typeof t.selectedRepoTargetId=="string")&&(t.repoTargets===void 0||Fc(t.repoTargets))&&Wc(t.runnerSession)&&_c(t.prompt)&&fo(t.checks)&&go(t.lastCommit)&&Uc(t.prs)&&qc(t.artifacts)&&wo(t.cleanup)&&(t.lastFailureReason===void 0||t.lastFailureReason===null||typeof t.lastFailureReason=="string")&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"},Oc=e=>{if(Array.isArray(e))return e.filter(po)},Fc=e=>Array.isArray(e)&&e.every(po),po=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)&&fo(t.checks)&&go(t.lastCommit)&&ho(t.pullRequest)&&wo(t.cleanup)},jc=e=>{if(mo(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 Nc(e.id,e.title,t,Yr(e.runner))},Nc=(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}]},Yr=e=>e&&f.runners.isRunnerType(e)?e:"codex",mo=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"),Wc=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),_c=e=>typeof e=="object"&&e!==null&&(e.source==="inline"||e.source==="file")&&typeof e.value=="string",fo=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"),go=e=>e===null||typeof e=="object"&&e!==null&&typeof e.sha=="string"&&typeof e.message=="string"&&typeof e.committedAt=="string",ho=e=>typeof e=="object"&&e!==null&&e.provider==="github"&&Bc(e.requiredChecks),Bc=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)),Uc=e=>Array.isArray(e)&&e.every(ho),qc=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),Vc=e=>e.checks?{...e.checks,results:e.checks.results??[]}:{source:{type:"repo_config",path:".craig/config.json"},lastRunAt:null,status:"not_run",commands:[],results:[]},Kc=e=>{if(Array.isArray(e.prs))return e.prs.map(Hc);let t=e.pullRequest;return!t||!t.number?[]:[{provider:"github",owner:null,repo:null,number:t.number,url:t.url??null,title:null,status:ko(t.status),draft:!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:null,requiredChecks:yo(t.requiredChecks),comments:[],createdAt:null,updatedAt:null,mergedAt:null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}]},Hc=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:ko(t.status),draft:t.draft??!1,baseBranch:t.baseBranch??null,headBranch:t.headBranch??null,mergeable:t.mergeable??!1,mergeStateStatus:t.mergeStateStatus??null,reviewDecision:Gc(t.reviewDecision),requiredChecks:yo(t.requiredChecks),comments:zc(t.comments),createdAt:t.createdAt??null,updatedAt:t.updatedAt??null,mergedAt:t.mergedAt??null,lastSyncedAt:t.lastSyncedAt??null,lastSyncedHeadSha:t.lastSyncedHeadSha??null}},ko=e=>e==="open"||e==="closed"||e==="merged"||e==="draft"?e:null,Gc=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,zc=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}]}):[],yo=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})):[],Yc=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 yd}from"node:fs/promises";import{readFile as Jc,readdir as Xc,rm as Zc}from"node:fs/promises";import To from"node:path";var Qr=(e,t)=>To.join(e.workspacesDir,`${t}.json`),ed=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"):[]}},Ro=(e,t)=>{let r=ed(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},Fe=async(e,t)=>{let r=Qr(e,t),n=await Jc(r,"utf8");return Ro(JSON.parse(n),r)},je=async(e,t)=>{await _(Qr(e,t.id),{...t,updatedAt:new Date().toISOString()})},ne=async e=>{let t=await Xc(e.workspacesDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>Fe(e,To.basename(n.name,".json"))))).sort((n,s)=>n.id.localeCompare(s.id))},bo=async(e,t)=>{await Zc(Qr(e,t),{force:!0})};import{readFile as td,readdir as rd,rm as nd}from"node:fs/promises";import Po from"node:path";var Jr=(e,t)=>Po.join(e.reposDir,`${t}.json`),So=(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},ie=async(e,t)=>{let r=Jr(e,t),n=await td(r,"utf8");return So(JSON.parse(n),r)},Xr=async(e,t)=>{await _(Jr(e,t.id),{...t,updatedAt:new Date().toISOString()})},wt=async e=>{let t=await rd(e.reposDir,{withFileTypes:!0});return(await Promise.all(t.filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>ie(e,Po.basename(n.name,".json"))))).sort((n,s)=>n.name.localeCompare(s.name)||n.id.localeCompare(s.id))},Io=async(e,t)=>{await nd(Jr(e,t),{force:!0})};import{readFile as sd}from"node:fs/promises";var od=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"},Xt=(e,t,r)=>{if(!od(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},J=async e=>{let t=await sd(e.indexFile,"utf8");return Xt(JSON.parse(t),e.workspaceRoot,e.indexFile)},ye=async(e,t)=>{await _(e.indexFile,{...t,workspaceRoot:e.workspaceRoot,updatedAt:new Date().toISOString()})};import{readdir as dd,stat as ud}from"node:fs/promises";import et from"node:path";import{realpath as Eo}from"node:fs/promises";import Ao from"node:path";import{execFile as id}from"node:child_process";import{promisify as ad}from"node:util";var vo=ad(id);async function S(e,t,r={}){try{let n=await vo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr}}catch(n){if(Co(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 vo(e,t,{cwd:r.cwd,env:r.env});return{stdout:n.stdout,stderr:n.stderr,exitCode:0}}catch(n){if(Co(n))return{stdout:n.stdout??"",stderr:n.stderr??"",exitCode:typeof n.code=="number"?n.code:null};throw n}}function Co(e){return e instanceof Error}var Zr=async e=>{try{let r=(await S("git",["rev-parse","--show-toplevel"],{cwd:e})).stdout.trim(),[n,s]=await Promise.all([Eo(r).catch(()=>Ao.resolve(r)),Eo(e).catch(()=>Ao.resolve(e))]);return n===s}catch{return!1}},en=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 S("git",["branch","--show-current"],{cwd:e})).stdout.trim();return s.length>0?s:"HEAD"};import{mkdir as fe,readFile as ld}from"node:fs/promises";import X from"node:path";function me(e){let t=X.join(e,".craig");return{workspaceRoot:e,repoRoot:e,craigDir:t,indexFile:X.join(t,"index.json"),reposDir:X.join(t,"repos"),workspacesDir:X.join(t,"workspaces"),sessionsDir:X.join(t,"sessions"),runtimeDir:X.join(t,"runtime"),uiStateFile:X.join(t,"runtime","ui-state.json"),tasksDir:X.join(t,"tasks"),jobsDir:X.join(t,"jobs"),logsDir:X.join(t,"logs"),errorLogFile:X.join(t,"logs","errors.log"),artifactsDir:X.join(t,"artifacts"),worktreesDir:X.join(t,"worktrees"),configFile:X.join(t,"config.json")}}var cd=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT",Ze=async e=>{let t=me(e);await fe(t.craigDir,{recursive:!0}),await Promise.all([fe(t.reposDir,{recursive:!0}),fe(t.workspacesDir,{recursive:!0}),fe(t.sessionsDir,{recursive:!0}),fe(t.runtimeDir,{recursive:!0}),fe(t.tasksDir,{recursive:!0}),fe(t.jobsDir,{recursive:!0}),fe(t.logsDir,{recursive:!0}),fe(t.artifactsDir,{recursive:!0}),fe(t.worktreesDir,{recursive:!0})]);try{let s=await ld(t.indexFile,"utf8"),o=JSON.parse(s);return Xt(o,e,t.indexFile)}catch(s){if(!cd(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 _(t.indexFile,n),n};var xo=(e,t,r)=>{let n=new Date().toISOString();return{id:pd(e,et.basename(t)),name:et.basename(t),rootPath:t,defaultBranch:r,createdAt:n,updatedAt:n}},Do=(e,t)=>e.defaultBranch===t?e:{...e,defaultBranch:t,updatedAt:new Date().toISOString()},pd=(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},md=(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},$o=async(e,t)=>{let r=await J(e);await ye(e,{...r,repoIds:[...new Set([...r.repoIds,...t.repoIds])],workspaceIds:[...new Set([...r.workspaceIds,...t.workspaceIds])]})},fd=async(e,t)=>{let r=await dd(t,{withFileTypes:!0}),n=await wt(e),s=[];for(let o of r){if(!o.isDirectory()||o.name.startsWith("."))continue;let i=et.join(t,o.name);if(!await Zr(i))continue;let a=n.find(d=>d.rootPath===i)??s.find(d=>d.rootPath===i),l=await en(i);s.push(a?Do(a,l):xo([...n,...s],i,l))}return s.sort((o,i)=>o.name.localeCompare(i.name)||o.id.localeCompare(i.id))},gd=async(e,t)=>{let r=await en(t),n=await wt(e),s=n.find(u=>u.rootPath===t)??null,o=s?Do(s,r):xo(n,t,r),i=`workspace_${o.id}`,l=(await ne(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 Xr(e,o),l||await je(e,c),await $o(e,{repoIds:[o.id],workspaceIds:[c.id]}),{kind:"createWorkspace",workspace:c,repos:[o],created:!l}},hd=async(e,t)=>{let r=await fd(e,t);if(r.length===0)throw new Error(`Workspace path does not contain direct child Git repos: ${t}`);let n=await ne(e),s=md(n,et.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:et.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=>Xr(e,d))),await je(e,l),await $o(e,{repoIds:a,workspaceIds:[l.id]}),{kind:"createWorkspace",workspace:l,repos:r,created:!o}},kt=async(e,t)=>{await Ze(e.workspaceRoot);let r=et.resolve(e.workspaceRoot,t);if(!(await ud(r).catch(()=>null))?.isDirectory())throw new Error(`Workspace path does not exist: ${r}`);return await Zr(r)?gd(e,r):hd(e,r)};var tn=async(e,t,r={listWorkspaceRecords:ne,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 rn=async(e,t,r={readWorkspace:Fe,writeWorkspace:je})=>{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 nn=async(e,t)=>{let n={...await Fe(e,t),status:"active",archivedAt:null};await je(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 Ne=async(e,t,r={deleteWorkspace:bo,readCraigIndex:J,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 sn=async(e,t,r)=>{let n=await Fe(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 Ne(e,t),{kind:"removeWorkspace",workspaceId:n.id,rootPath:n.rootPath??""}};var on={};Vt(on,{addRepo:()=>Mo,listRegisteredRepos:()=>Lo,removeRepo:()=>Oo});import wd from"node:path";import{stat as kd}from"node:fs/promises";var Mo=async(e,t)=>{let r=wd.resolve(e.workspaceRoot,t);if(!(await kd(r).catch(()=>null))?.isDirectory())throw new Error(`Repo path does not exist: ${r}`);let s=await kt(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 Lo=async(e,t={listRepos:wt,ensureCraigState:Ze})=>(await t.ensureCraigState(e.workspaceRoot),{kind:"listRepos",repos:await t.listRepos(e)});var Oo=async(e,t,r)=>{let n=await ie(e,t),o=(await ne(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=>Ne(e,d.id))),await Io(e,t);let l=await J(e);return await ye(e,{...l,repoIds:l.repoIds.filter(d=>d!==t)}),{kind:"removeRepo",repoId:n.id,rootPath:n.rootPath}};var Z={addWorkspace:kt,listWorkspaces:tn,archiveWorkspace:rn,restoreWorkspace:nn,removeWorkspace:sn,removeWorkspaceRecord:Ne,repos:on};var ee=async(e,t)=>{let r=await yd(ln(e,t),"utf8");return JSON.parse(r)},se=async(e,t)=>{let r=await ee(e,t);return q(r,ln(e,t))},P=async(e,t)=>{let r={...t,updatedAt:new Date().toISOString()};await _(ln(e,t.id),r)},an=async(e,t)=>{let r=await J(e);r.taskIds.includes(t)||await ye(e,{...r,taskIds:[...r.taskIds,t]})},ln=(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,Ie=e=>e.status==="merged"||e.status==="closed",tt=(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}},yt=e=>{if(e.length===0)return"checked";let t=[...e].reverse().find(r=>r.status!=="merged"&&r.status!=="closed")??e[e.length-1];return er(t)?"merge_ready":t.status==="merged"?"merged":t.status==="open"?"pr_open":"checked"},er=e=>e.mergeable&&!Td(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"),Td=e=>e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED",cn=e=>e.requiredChecks.length===0?"no required checks":e.requiredChecks.map(t=>`${t.name}:${t.status}`).join(", "),Tt=(e,t)=>{let r=e.isDraft??!1,n=Rd(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:bd(e.reviewDecision??null),requiredChecks:Rt(e.statusCheckRollup),comments:e.comments===void 0?t?.comments??[]:vd(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}},Rd=(e,t)=>t?"draft":e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,bd=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Rt=e=>{let t=e.map(n=>Pd(n)).filter(n=>n!==null),r=new Map;for(let n of t){let s=r.get(n.name);(!s||Sd(s,n))&&r.set(n.name,n)}return[...r.values()].map(n=>({name:n.name,status:n.status,conclusion:n.conclusion}))},Pd=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:jo(n??null,t.conclusion??null),conclusion:t.conclusion??null,sortTime:Id(t)}:null},Sd=(e,t)=>e.sortTime!==null||t.sortTime!==null?(t.sortTime??0)>=(e.sortTime??0):Zt(e)&&!Zt(t)?!0:!Zt(e)&&Zt(t)?!1:Fo(t.status)>=Fo(e.status),Zt=e=>e.conclusion?.toUpperCase()==="CANCELLED",Fo=e=>{switch(e){case"pending":return 5;case"failed":return 4;case"success":return 3;case"skipped":return 2;default:return 1}},Id=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},vd=e=>{let t=Array.isArray(e)?e:e?.nodes;return Array.isArray(t)?t.map(Cd).filter(r=>r!==null).slice(-4):[]},Cd=e=>{if(typeof e!="object"||e===null)return null;let t=e,r=Ed(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},Ed=e=>e.replace(/\s+/g," ").trim(),jo=(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?jo(n,n):"unknown"};var ge=class extends Error{constructor(t){super(t),this.name="GitHubRateLimitError"}};import{access as Ad}from"node:fs/promises";import No from"node:path";var v=async(e,t,r={readRawTask:ee,validateTaskRecord:q})=>{try{let n=await r.readRawTask(e,t);return r.validateTaskRecord(n,`${e.tasksDir}/${t}.json`)}catch(n){throw Ld(n)?new Error(`Craig task "${t}" was not found.`):n}},V=async e=>{if(!await dn(e.worktreePath))throw new Error(`Task ${e.id} worktree does not exist at ${e.worktreePath}. Repair or recreate the task before retrying.`)},rt=(e,t)=>t.artifacts.logPath?No.isAbsolute(t.artifacts.logPath)?t.artifacts.logPath:No.join(e.workspaceRoot,t.artifacts.logPath):null,bt=async(e,t)=>{let r=await dn(t.worktreePath),n=rt(e,t),s=n?await dn(n):!1;return{worktreeExists:r,logExists:s,recentFailureReason:t.lastFailureReason??null,runnerCommandText:t.runnerSession.command.join(" "),checksSummary:xd(t),lastCommitSummary:Dd(t),prSummary:$d(t),cleanupSummary:Md(t)}},dn=async e=>{try{return await Ad(e),!0}catch{return!1}},xd=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}`},Dd=e=>e.lastCommit?`${e.lastCommit.sha.slice(0,7)} ${e.lastCommit.message}`:"not committed",$d=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})
|
|
30
30
|
${o.join(`
|
|
31
|
-
`)}`}let t=D(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})`},
|
|
32
|
-
`);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}},
|
|
31
|
+
`)}`}let t=D(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})`},Md=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",Ld=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var Wo=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.")},un=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 Od(e,s);await S("git",["worktree","add","-b",t,r,i],{cwd:e})},Od=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,tr=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},_o=async e=>{await S("git",["add","-A"],{cwd:e})},Bo=async(e,t)=>{await S("git",["commit","-m",t],{cwd:e})},Uo=async e=>{let t=await S("git",["show","-s","--format=%H%n%s","HEAD"],{cwd:e}),[r="",n=""]=t.stdout.trim().split(`
|
|
32
|
+
`);if(!r||!n)throw new Error("Unable to read git HEAD commit metadata.");return{sha:r,message:n}},qo=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 Vo=async(e,t)=>{await S("git",["worktree","remove","--force",t],{cwd:e})};var pn=async e=>nt(e,e.repoRoot),nt=async(e,t)=>{let r=await J(e),n=Ko(new Date),s=Ho(r.taskIds,n);for(;;){let o=`task_${n}_${String(s).padStart(2,"0")}`,i=`craig/${o}`;if(!await Wo(t,i))return o;s+=1}},Pt=async e=>{let t=await J(e),r=Ko(new Date),n=Ho(t.taskIds,r);return`task_${r}_${String(n).padStart(2,"0")}`},Ko=e=>{let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${t}${r}${n}`},Ho=(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 mn=async(e,t,r={readRawTask:ee,validateTaskRecord:q})=>{let n=await J(e),s=[],o=[];await Promise.all(n.taskIds.map(async l=>{try{let d=await r.readRawTask(e,l);s.push(r.validateTaskRecord(d,`${e.tasksDir}/${l}.json`))}catch(d){if(Fd(d)){o.push(l);return}throw d}}));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(d=>d.repoId===t.repoId)));return a.sort((l,d)=>l.id.localeCompare(d.id)),o.sort(),{kind:"listTasks",tasks:a,missingTaskIds:o,repoId:t?.repoId??null}},Fd=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";var Go=["merge_ready","pr_open","checked","review","running","draft"],fn=e=>[...e].sort((t,r)=>t.id.localeCompare(r.id)),gn=(e,t)=>t&&e.some(n=>n.id===t)?t:e.length===0?null:[...e].sort(jd)[0]?.id??null,jd=(e,t)=>{let r=zo(e.status),n=zo(t.status);return r!==n?r-n:t.updatedAt.localeCompare(e.updatedAt)},zo=e=>{let t=Go.indexOf(e);return t>=0?t:Go.length};import Yo from"node:path";var We=(e,t)=>t?Yo.isAbsolute(t)?t:Yo.join(e.repoRoot,t):null;import{mkdir as St,rm as Nd,writeFile as rr}from"node:fs/promises";import A from"node:path";var Jo=["AGENTS","md"].join("."),st=async(e,t,r,n={})=>{let s=await ie(e,t),[o,i]=await Promise.all([qd(e,s.id),nt(e,s.rootPath)]),a=n.sessionId??null,l=`craig/${i}`,d=A.join(e.worktreesDir,s.id,i),c=A.join(e.logsDir,`${i}.log`),u=A.join(e.artifactsDir,i);await Promise.all([St(A.dirname(d),{recursive:!0}),St(u,{recursive:!0}),rr(c,"","utf8")]);let m=Wd(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:d});return await P(e,m),await an(e,i),await un(s.rootPath,l,d,s.defaultBranch),{repoId:s.id,repoRoot:s.rootPath,sessionId:a,workspaceId:o.id,task:m}},It=async(e,t,r,n={})=>{let s=(await ne(e)).find(I=>I.id===t&&I.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 I=await st(e,s.primaryRepoId,r,n);return{...I,bundlePath:I.task.worktreePath,repoTargets:[]}}let o=s.discoveredRepoIds??[];if(o.length===0)throw new Error(`Project workspace ${t} has no discovered repos.`);let i=await Pt(e),a=new Date().toISOString(),l=n.runner??"codex",d=n.sessionId??null,c=`craig/${i}`,u=A.join(e.craigDir,"task-bundles",i),m=A.join(e.logsDir,`${i}.log`),y=A.join(e.artifactsDir,i);await St(u,{recursive:!0}),await St(y,{recursive:!0}),await rr(m,"","utf8");let T=await Promise.all(o.map(I=>ie(e,I))),h=Bd(T),R=await Promise.all(T.map(I=>_d(e,I,i,c,A.join(u,h.get(I.id))))),U=R.find(I=>I.status==="ready")??R[0];if(!R.some(I=>I.status==="ready"))throw await Nd(u,{recursive:!0,force:!0}),new Error(`No project repo targets could be provisioned for ${t}: ${R.map(I=>`${I.repoId}: ${I.failureReason??"unknown error"}`).join("; ")}`);await rr(A.join(u,"manifest.json"),JSON.stringify({taskId:i,workspaceId:t,prompt:r,repos:R.map(I=>({repoId:I.repoId,repoName:T.find(we=>we.id===I.repoId)?.name??I.repoId,path:A.relative(u,I.worktreePath),status:I.status,worktreePath:I.worktreePath,failureReason:I.failureReason}))},null,2),"utf8"),await rr(A.join(u,Jo),Ud({taskId:i,workspaceId:t,prompt:r,repos:T,repoTargets:R,bundlePath:u}),"utf8");let K=vt(i,r,a,l,n.config??{}),re={id:i,title:r,slug:Xo(r),type:"project",status:"draft",runner:l,repoId:U.repoId,workspaceId:s.id,sessionId:d,selectedPtyTabId:K[0]?.id??null,linkedRepoIds:o.filter(I=>I!==U.repoId),repoRoot:u,worktreePath:u,branch:c,bundlePath:u,selectedRepoTargetId:U.repoId,repoTargets:R,ptyTabs:K,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:U.checks,lastCommit:null,prs:[],artifacts:{logPath:A.relative(e.workspaceRoot,m),checkSummaryPath:A.relative(e.workspaceRoot,A.join(y,"check-summary.json")),prDraftPath:null,prStatusPath:A.relative(e.workspaceRoot,A.join(y,"pr-status.json"))},cleanup:nr(),lastFailureReason:R.every(I=>I.status==="unavailable")?"No project repo targets could be provisioned.":null,createdAt:a,updatedAt:a};return await P(e,re),await an(e,i),{repoId:U.repoId,repoRoot:u,sessionId:d,workspaceId:s.id,task:re,bundlePath:u,repoTargets:R}},vt=(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}]},Wd=(e,t)=>{let r=new Date().toISOString(),n=vt(t.taskId,t.prompt,r,t.runner,t.config);return{id:t.taskId,title:t.prompt,slug:Xo(t.prompt),type:"repo",status:"draft",runner:t.runner,repoId:t.repoId,workspaceId:t.workspaceId,sessionId:t.sessionId,selectedPtyTabId:n[0]?.id??null,linkedRepoIds:[],repoRoot:t.repoRoot,worktreePath:t.worktreePath,branch:t.branch,ptyTabs:n,runnerSession:{command: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:{...hn(A.relative(e.workspaceRoot,e.configFile))},lastCommit:null,prs:[],artifacts:{logPath:A.relative(e.workspaceRoot,A.join(e.logsDir,`${t.taskId}.log`)),checkSummaryPath:A.relative(e.workspaceRoot,A.join(e.artifactsDir,t.taskId,"check-summary.json")),prDraftPath:null,prStatusPath:A.relative(e.workspaceRoot,A.join(e.artifactsDir,t.taskId,"pr-status.json"))},cleanup:nr(),lastFailureReason:null,createdAt:r,updatedAt:r}},_d=async(e,t,r,n,s)=>{await St(A.dirname(s),{recursive:!0});try{return await un(t.rootPath,n,s,t.defaultBranch),{repoId:t.id,branch:n,repoRoot:t.rootPath,worktreePath:s,status:"ready",failureReason:null,checks:hn(A.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Qo(),cleanup:nr()}}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:hn(A.relative(e.workspaceRoot,e.configFile)),lastCommit:null,pullRequest:Qo(),cleanup:nr()}}},Bd=e=>{let t=new Set(["manifest.json",Jo]),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},Ud=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=A.relative(e.bundlePath,n.worktreePath),i=n.status==="ready"?"ready":`unavailable: ${n.failureReason??"unknown error"}`;return`- \`${o}/\` - ${s} (${n.repoId}, ${i})`}).join(`
|
|
33
33
|
`);return["# Craig Project Task Bundle","","This directory is a Craig project task bundle. Repo work must happen inside the child repo worktrees listed below.","","Run repo Git commands from a repo worktree directory, not from the bundle root. Use `manifest.json` as the machine-readable source of truth for this bundle.","",`Task: \`${e.taskId}\``,`Workspace: \`${e.workspaceId}\``,`Prompt: ${e.prompt}`,"","## Repo Worktrees","",r,""].join(`
|
|
34
|
-
`)},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=>`
|
|
34
|
+
`)},hn=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}),nr=()=>({paneClosedAt:null,worktreeRemovedAt:null,preservedWorktree:!1,warning:null}),qd=async(e,t)=>{let n=(await ne(e)).find(s=>s.kind!=="project"&&s.primaryRepoId===t&&s.status==="active");if(!n)throw new Error(`Repo ${t} does not have an active workspace.`);return n},Xo=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-");import ci from"node:path";import{readFile as Vd,rm as Kk}from"node:fs/promises";import Kd from"node:path";var ve=async(e,t)=>{let r=await Vd(wn(e,t),"utf8"),n=JSON.parse(r);return Hd(n,wn(e,t))},_e=async(e,t)=>{await _(wn(e,t.id),{...t,updatedAt:new Date().toISOString()})};var wn=(e,t)=>Kd.join(e.sessionsDir,`${t}.json`);function Hd(e,t){let r=Yd(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")||!zd(r.attach)||!Gd(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 Gd(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 zd(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 Yd(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 Jd}from"node:crypto";import Xd from"node:path";function sr(e){return`'${e.replace(/'/g,"'\\''")}'`}var Zd="craig",Zo=async(e,t,r)=>{let n=kn(e,t),s=tu(),o=await S("tmux",["new-session","-d","-P","-F","#{session_name} #{window_id} #{pane_id}","-s",n,"-n","runner",...s,"-c",r],{cwd:e}),i=nu(o.stdout);return await eu(e,n),i};var eu=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 S("tmux",n,{cwd:e})},ei=async(e,t,r)=>{await S("tmux",["resize-window","-t",t,"-x",`${r.columns}`,"-y",`${r.rows}`],{cwd:e})},ti=async(e,t,r)=>{await S("tmux",["send-keys","-t",e,t,"C-m"],{cwd:r})};var ri=async(e,t,r)=>{await S("tmux",["pipe-pane","-o","-t",e,`cat >> ${sr(t)}`],{cwd:r})},or=async(e,t,r,n)=>{let s=n??si(e);if(r?await S("tmux",["select-window","-t",r],{cwd:e}):await S("tmux",["select-window","-t",t],{cwd:e}),await S("tmux",["select-pane","-t",t],{cwd:e}),process.env.TMUX){await S("tmux",["switch-client","-t",s],{cwd:e});return}await ou(e,["attach-session","-t",s])};var ni=async(e,t)=>{await S("tmux",["kill-session","-t",t],{cwd:e})};var si=e=>{let r=Xd.basename(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"repo",n=Jd("sha1").update(e).digest("hex").slice(0,8);return`${Zd}-${r}-${n}`},kn=(e,t)=>`${si(e)}-${t.toLowerCase()}`,tu=()=>{let e=ru();return e?["-x",`${e.columns}`,"-y",`${e.rows}`]:[]},ru=()=>{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},nu=e=>{let t=su(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]}},su=e=>e.split(/\s+/).map(t=>t.trim()).filter(t=>t.length>0),ou=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 iu,constants as au}from"node:fs";import{homedir as oi}from"node:os";import Ce from"node:path";var lu=[Ce.join(oi(),".local","bin"),Ce.join(oi(),".cursor","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function ai(e=process.env){return cu([...(e.PATH??"").split(Ce.delimiter).filter(t=>t.length>0),...e.CRAIG_DISABLE_COMMAND_PATH_FALLBACKS==="1"?[]:lu])}function Be(e=process.env){return{...e,PATH:ai(e).join(Ce.delimiter)}}function yn(e,t={}){if(e.includes(Ce.sep)){let r=Ce.isAbsolute(e)?e:Ce.resolve(t.cwd??process.cwd(),e);return ii(r)?r:null}for(let r of ai(t.env)){let n=Ce.join(r,e);if(ii(n))return n}return null}function Ue(e,t={}){let r=yn(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 ii(e){try{return iu(e,au.X_OK),!0}catch{return!1}}function cu(e){return[...new Set(e)]}var Ct={async create(e,t){let r=await Zo(t.repoRoot,t.taskId,t.worktreePath);t.logPath&&await ri(r.paneId,t.logPath,t.repoRoot);let n=await li({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||kn(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 _e(e,s),s},async attach(e,t,r){let n=await Ct.snapshot(t,r);if(!n.alive)throw new Error(`Session ${t.id} is no longer live and cannot be attached.`);await or(r,t.paneId,t.windowTarget,t.sessionName);let s={...t,status:"running",lastAttachedAt:new Date().toISOString(),snapshot:n};return await _e(e,s),s},async resize(e,t,r,n){await ei(n,t.sessionName,r);let s={...t,attach:{...t.attach,lastSize:r}};return await _e(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 _e(e,n),n},async snapshot(e,t){return du(e,t)}},Tn={async prepare(e,t){let n=e.runnerSession.command[0],s=Be();Ue(n,{cwd:t.repoRoot,env:s})},async launch(e,t){let r=e.runnerSession.command,n=Ue(r[0],{cwd:e.worktreePath,env:Be()});await ti(t.session.paneId,[n,...r.slice(1)].map(s=>sr(s)).join(" "),t.repoRoot)},async status(e){return e.runnerSession.lastKnownState},async stop(){},async collectArtifacts(){}},du=async(e,t)=>{let r=await x("tmux",["list-panes","-F","#{pane_id}","-t",e.paneId],{cwd:t});return li({paneId:e.paneId,windowTarget:e.windowTarget,alive:r.exitCode===0&&r.stdout.split(/\s+/).some(n=>n.trim()===e.paneId)})},li=async e=>({paneId:e.paneId,windowTarget:e.windowTarget,alive:e.alive,capturedAt:new Date().toISOString()});var Rn=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 It(e,n.workspaceId,s,{runner:i,config:o}):await st(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?ci.resolve(e.workspaceRoot,l.artifacts.logPath):ci.join(e.logsDir,`${l.id}.log`);try{await Tn.prepare(l,{repoRoot:a.repoRoot});let m=await Ct.create(e,{sessionId:c,taskId:l.id,repoId:a.repoId,workspaceId:a.workspaceId,repoRoot:a.repoRoot,worktreePath:l.worktreePath,logPath:u,command:d});await Tn.launch(l,{repoRoot:a.repoRoot,session:m});let y=new Date().toISOString();m={...m,status:"running",startedAt:y,command:d};let T={...l,status:"running",runner:i,sessionId:m.id,selectedPtyTabId:l.selectedPtyTabId,runnerSession:{command:m.command,pid:null,startedAt:y,lastKnownState:"running",exitCode:null,exitedAt:null}};return await P(e,T),await _e(e,m),{kind:"createTask",taskId:T.id,repoId:T.repoId,workspaceId:T.workspaceId,sessionId:m.id,status:T.status,branch:T.branch,worktreePath:T.worktreePath,runner:T.runner}}catch(m){let y={...l,sessionId:null,status:"draft",runnerSession:{...l.runnerSession,lastKnownState:"failed"},lastFailureReason:m instanceof Error?m.message:"Unknown Craig error"};throw await P(e,y),m}};import{mkdir as gu}from"node:fs/promises";import hu from"node:path";var ot=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 di=async(e,t,r)=>{let n=r==="merge"?"--merge":r==="rebase"?"--rebase":"--squash";await S("gh",["pr","merge",String(t),n,"--delete-branch=false"],{cwd:e})},ir=async(e,t)=>{let r=await S("gh",mi(e),{cwd:t});return JSON.parse(r.stdout)},it=async(e,t)=>{let r=await x("gh",mi(e),{cwd:t});return r.exitCode!==0?null:JSON.parse(r.stdout)},ui=async(e,t,r)=>{if(r.length===0)return[];let n=mu(r),s;try{s=await S("gh",["api","graphql","-f",`query=${n}`,"-F",`owner=${t.owner}`,"-F",`name=${t.name}`])}catch(a){throw uu(a)?new ge(a instanceof Error?a.message:String(a)):a}let i=JSON.parse(s.stdout).data?.repository??{};return r.map((a,l)=>{let d=i[`item${l}`],c=fu(d);return{id:a.id,found:c!==null,view:c}})},pi=async e=>{let t=await x("git",["remote","get-url","origin"],{cwd:e});return t.exitCode!==0?null:pu(t.stdout.trim())},uu=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")},mi=e=>["pr","view",e,"--json","number,url,baseRefName,headRefName,headRefOid,state,isDraft,title,createdAt,updatedAt,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments"],pu=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},mu=e=>`
|
|
35
35
|
query CraigPullRequestBatch($owner: String!, $name: String!) {
|
|
36
36
|
repository(owner: $owner, name: $name) {
|
|
37
37
|
${e.map((r,n)=>{let s=`item${n}`;return r.mode==="number"?`${s}: pullRequest(number: ${Number(r.selector)}) { ...PrFields }`:`${s}: pullRequests(headRefName: ${JSON.stringify(r.selector)}, states: OPEN, first: 1, orderBy: { field: UPDATED_AT, direction: DESC }) { nodes { ...PrFields } }`}).join(`
|
|
@@ -73,31 +73,6 @@ fragment PrFields on PullRequest {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
}
|
|
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
76
|
comments(last: 4) {
|
|
102
77
|
nodes {
|
|
103
78
|
author {
|
|
@@ -110,58 +85,58 @@ fragment PrFields on PullRequest {
|
|
|
110
85
|
}
|
|
111
86
|
}
|
|
112
87
|
}
|
|
113
|
-
`,
|
|
88
|
+
`,fu=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 qe=async(e,t)=>{let r=We(e,t.artifacts.prStatusPath);r&&(await gu(hu.dirname(r),{recursive:!0}),await _(r,{taskId:t.id,prs:t.prs}))},Et=async(e,t,r,n,s={readRawTask:ee,validateTaskRecord:q,writeTask:P,writePrStatusArtifact:qe})=>{let o=Tt(r,n),i=tt(t,o),a=yt(i.prs),l={...i,status:a};await s.writePrStatusArtifact(e,l);let d=await s.readRawTask(e,t.id),c=s.validateTaskRecord(d,`${e.tasksDir}/${t.id}.json`),u=c.status==="closed"?c.status:a,m=tt({...c,status:u},o);return await s.writeTask(e,m),m},At=async(e,t)=>{let r=D(t),n=r?.number?String(r.number):t.branch,s=await ir(n,t.worktreePath);return Et(e,t,s,r)},xt=async(e,t)=>{for(let r of await bn(t)){let n=await it(r,t.worktreePath);if(!n)continue;return{discovered:!0,task:await Et(e,t,n,null)}}return{discovered:!1,task:t}},bn=async e=>{let t=await qo(e.worktreePath).catch(()=>null);return[...new Set([t,e.branch].filter(r=>!!r))]};var at=async(e,t,r)=>{let n=r.pullRequest.number?String(r.pullRequest.number):r.branch;if(r.pullRequest.number){let i=await ir(n,r.worktreePath),a=gi(i);return r.pullRequest=a,await fi(e,t,r.repoId,a),"synced"}let s=await it(n,r.worktreePath);if(!s)return"not_found";let o=gi(s);return r.pullRequest=o,await fi(e,t,r.repoId,o),"discovered"},fi=async(e,t,r,n)=>{let s=await ee(e,t.id),o=q(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},gi=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:wu(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:ku(e.reviewDecision??null),requiredChecks:Rt(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),wu=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,ku=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null;var Dt=async(e,t)=>{let r=await v(e,t),n=D(r);return n?.number?(await ot(r.worktreePath),Ie(n)?(await xt(e,r)).task:At(e,r)):r},Sn=async(e,t)=>{let r=await v(e,t);if(r.type==="project"&&r.repoTargets?.length)return await lt(e,t),v(e,t);let n=D(r);if(await V(r),await ot(r.worktreePath),!n?.number||Ie(n)){let o=await xt(e,r);if(!o.discovered&&!n?.number)throw new Error(`No PR found for ${r.branch}.`);return await qe(e,o.task),o.task}let s=await At(e,r);return await qe(e,s),s},lt=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 ot(a.worktreePath);let l=a.pullRequest.number?await at(e,r,a):await at(e,r,a).catch(()=>"not_found");s[l==="not_found"?"notFound":l]++}let o=await ee(e,r.id),i=q(o,`${e.tasksDir}/${r.id}.json`);return i.status!=="closed"&&(i.status=wi(i),await P(e,i)),s},In=async(e,t)=>{let r=new Map,n=new Map;for(let s of t){let o=Pn(r,s);if(s.type==="project"&&s.repoTargets?.length){for(let c of s.repoTargets.filter(u=>u.status==="ready")){let u={id:`${s.id}:${c.repoId}`,task:s,targetRepoId:c.repoId,worktreePath:c.worktreePath,selector:c.pullRequest.number?String(c.pullRequest.number):c.branch,mode:c.pullRequest.number?"number":"head",fallbackSelectors:[]};await hi(n,u).catch(async()=>{try{let m=c.pullRequest.number?await at(e,s,c):await at(e,s,c).catch(()=>"not_found");ar(o,m,c.pullRequest.number??null,c.pullRequest.url??null)}catch{}})}continue}let i=D(s),a=i?.number&&!Ie(i),l=a?[]:await bn(s),d={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 hi(n,d).catch(async()=>{try{let{disposition:c,task:u}=await lr(e,s.id),m=D(u);ar(o,c,m?.number??null,m?.url??null)}catch{}})}for(let s of n.values())try{await ot(s.worktreePath);let o=await ui(s.worktreePath,s.repository,s.items),i=new Map(o.map(a=>[a.id,a]));for(let a of s.items){let l=Pn(r,a.task),c=i.get(a.id)?.view??await Pu(s.worktreePath,a);if(!c){ar(l,"not_found",null,null);continue}if(a.targetRepoId){let u=await ee(e,a.task.id),m=q(u,`${e.tasksDir}/${a.task.id}.json`);await yu(e,m,a.targetRepoId,c)}else{let u=await ee(e,a.task.id),m=q(u,`${e.tasksDir}/${a.task.id}.json`);await Et(e,m,c,a.mode==="number"?D(m):null)}ar(l,a.mode==="number"?"synced":"discovered",c.number,c.url)}}catch(o){if(o instanceof ge)throw o}for(let s of t.filter(o=>o.type==="project"&&o.repoTargets?.length)){let o=await ee(e,s.id),i=q(o,`${e.tasksDir}/${s.id}.json`);i.status!=="closed"&&(i.status=wi(i),await P(e,i))}return t.map(s=>Pn(r,s))},lr=async(e,t)=>{let r=await v(e,t);await V(r),await ot(r.worktreePath);let n=D(r);if(n?.number&&!Ie(n))return{disposition:"synced",task:await At(e,r)};let s=await xt(e,r);return{disposition:s.discovered?"discovered":"not_found",task:s.task}},wi=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(Su)?"merge_ready":r.some(n=>n.status==="open")?"pr_open":"checked"},yu=async(e,t,r,n)=>{let s=Tu(n),o=(t.repoTargets??[]).map(a=>a.repoId===r?{...a,pullRequest:s}:a),i={...t,repoTargets:o};return await P(e,i),i},Tu=e=>({provider:"github",number:e.number,url:e.url,baseBranch:e.baseRefName,headBranch:e.headRefName,status:Ru(e.state),draft:e.isDraft??!1,mergeable:e.mergeable==="MERGEABLE",mergeStateStatus:e.mergeStateStatus,reviewDecision:bu(e.reviewDecision??null),requiredChecks:Rt(e.statusCheckRollup),comments:[],lastSyncedAt:new Date().toISOString(),lastSyncedHeadSha:e.headRefOid??null}),Ru=e=>e==="OPEN"?"open":e==="MERGED"?"merged":e==="CLOSED"?"closed":null,bu=e=>e==="APPROVED"||e==="CHANGES_REQUESTED"||e==="REVIEW_REQUIRED"?e:null,Pu=async(e,t)=>{if(t.mode!=="head")return null;for(let r of t.fallbackSelectors){let n=await it(r,e);if(n)return n}return null},hi=async(e,t)=>{let r=await pi(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]})},Pn=(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):!!D(t)?.number,firstDiscoveredPrNumber:null,firstDiscoveredPrUrl:null};return e.set(t.id,n),n},ar=(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},Su=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 vn=async(e,t)=>{let r=await v(e,t);try{r.type==="project"&&r.repoTargets?.length?(await lt(e,t),r=await v(e,t)):r.prs.some(o=>o.number)&&(r=await Dt(e,t))}catch{}let n=await bt(e,r),s=r.sessionId?await ve(e,r.sessionId).catch(()=>null):null;return{kind:"showTask",task:r,inspection:n,session:s}};var Cn=async(e,t)=>{let r=await v(e,t);if(await V(r),(await S("git",["status","--short"],{cwd:r.worktreePath})).stdout.trim().length===0)return{kind:"showTaskDiff",taskId:r.id,diffText:"",isEmpty:!0};let s=await Iu(r.worktreePath);return{kind:"showTaskDiff",taskId:r.id,diffText:s,isEmpty:!1}},Iu=async e=>{let t=[],r=await S("git",["diff","--stat","--patch","HEAD"],{cwd:e});r.stdout.trim().length>0&&t.push(r.stdout.trimEnd());let n=await vu(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
89
|
|
|
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(`
|
|
90
|
+
`)},vu=async e=>(await S("git",["ls-files","--others","--exclude-standard"],{cwd:e})).stdout.split(`
|
|
91
|
+
`).map(r=>r.trim()).filter(r=>r.length>0);import{spawn as Cu}from"node:child_process";import{access as Eu}from"node:fs/promises";var En=async(e,t)=>{let r=await v(e,t),n=rt(e,r);if(!n)throw new Error(`Task ${r.id} does not have a Craig-managed log path.`);try{await Eu(n)}catch{throw new Error(`Task ${r.id} log file does not exist yet at ${n}.`)}return{kind:"streamTaskLogs",taskId:r.id,logPath:n}},An=async e=>{await new Promise((t,r)=>{let n=!1,s=Cu("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 Au}from"node:fs/promises";import xu from"node:path";var xn=async(e,t)=>{let r=await v(e,t);if(await V(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 tr(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}),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 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=We(e,t.artifacts.checkSummaryPath);r&&(await Au(xu.dirname(r),{recursive:!0}),await _(r,{taskId:t.id,status:t.checks.status,lastRunAt:t.checks.lastRunAt,commands:t.checks.commands,results:t.checks.results}))};var Dn=async(e,t)=>{let r=await v(e,t);await V(r);let n=await tr(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 _o(r.worktreePath),await Bo(r.worktreePath,s);let o=await Uo(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 Du}from"node:fs/promises";var $n=async(e,t)=>{let r=await v(e,t),n=await $u(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},$u=async e=>{try{return await Du(e),!0}catch{return!1}};var Mn=async(e,t,r)=>{let n=[];try{if(t.sessionId){let s=await ve(e,t.sessionId);await ni(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 Vo(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 Ln=async(e,t,r)=>{let[n,s]=await Promise.all([v(e,t),ie(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}},On=async(e,t)=>{let r=await v(e,t),n=await Promise.all(r.linkedRepoIds.map(s=>ie(e,s)));return{kind:"listTaskLinks",taskId:r.id,repos:n}};var Fn=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([ie(e,r.repoId),ve(e,r.sessionId)]),o=await Ct.attach(e,s,n.rootPath);return{kind:"attachTask",taskId:r.id,sessionId:o.id,disposition:"attached"}};var jn=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 ve(e,r.sessionId).catch(s=>{throw Mu(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 or(e.repoRoot,n.paneId,n.windowTarget,n.sessionName),{kind:"focusTask",taskId:r.id,tmuxTarget:n.paneId}},Mu=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT";import{spawn as Lu}from"node:child_process";var Nn=async(e,t)=>{let r=await v(e,t);await V(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 Ou(o,e.repoRoot),{kind:"openTask",taskId:r.id,worktreePath:r.worktreePath,launched:!0,command:o}},Ou=async(e,t)=>{await new Promise((r,n)=>{let[s,...o]=e,i=Lu(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 Wn=async(e,t,r)=>{let n=await se(e,t);await P(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 se(e,t),s={...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:r};return await P(e,s),s},Bn=async(e,t)=>{let r=await se(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};var Un=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 di(s.worktreePath,o,r)};var C={listTasks:mn,getTask:v,provisionTask:st,provisionProjectTask:It,createTask:Rn,showTask:vn,showTaskDiff:Cn,prepareTaskLogs:En,streamTaskLogs:An,runChecks:xn,commitTask:Dn,closeTask:$n,cleanupTask:Mn,addTaskLink:Ln,listTaskLinks:On,sortTasksForDisplay:fn,resolveSelectedTaskId:gn,allocateTaskId:pn,allocateTaskIdForRepo:nt,allocateProjectTaskId:Pt,createDefaultTaskPtyTabs:vt,assertTaskWorktreeExists:V,resolveTaskLogPath:rt,buildTaskInspection:bt,resolveArtifactPath:We,attachTask:Fn,focusTask:jn,openTask:Nn,markRunnerFailed:Wn,recordStartupFailure:_n,markTaskStarted:Bn,prs:{refresh:Dt,refreshChecks:Sn,discoverOrRefresh:lr,discoverOrRefreshAll:lt,discoverOrRefreshMany:In,merge:Un,getPrimaryPr:D,isPrTerminal:Ie,isMergeReady:er,deriveTaskStatus:yt,upsertPr:tt,normalizePr:Tt,summarizeRequiredChecks:cn,writePrStatusArtifact:qe}};async function yi(e,t){switch(e.kind){case"addWorkspace":{let r=await Z.addWorkspace(t.paths,e.path),n=r.workspace.kind==="project"?r.workspace.discoveredRepoIds?.[0]??null:r.repos[0]?.id??null;return await qn(t.paths,r.workspace.id,n),r}case"addRepo":{let r=await Z.repos.addRepo(t.paths,e.path);return await qn(t.paths,r.workspaceId,r.repo.id),r}case"listRepos":return Z.repos.listRegisteredRepos(t.paths);case"removeRepo":{let r=await Je({uiStateFile:t.paths.uiStateFile}),n=r?.selectedWorkspaceId?(await ne(t.paths)).filter(o=>o.primaryRepoId===e.repoId).map(o=>o.id):[],s=await Z.repos.removeRepo(t.paths,e.repoId,{listTasks:C.listTasks});if(r){let o=n.includes(r.selectedWorkspaceId??""),i=r.selectedRepoId===e.repoId;o?await Se({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null,selectedWorkspaceId:null,selectedTaskId:null}):i&&await Se({uiStateFile:t.paths.uiStateFile},{...r,selectedRepoId:null})}return s}case"listWorkspaces":return Z.listWorkspaces(t.paths,{archived:e.archived});case"archiveWorkspace":{let r=await Z.archiveWorkspace(t.paths,e.workspaceId);return await Fu(t.paths,e.workspaceId),r}case"restoreWorkspace":{let r=await Z.restoreWorkspace(t.paths,e.workspaceId);return await qn(t.paths,e.workspaceId,r.primaryRepoId),r}case"removeWorkspace":return Z.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,Ve(t,"show"));case"streamTaskLogs":return C.prepareTaskLogs(t.paths,e.taskId);case"streamSelectedTaskLogs":return C.prepareTaskLogs(t.paths,Ve(t,"logs"));case"showTaskDiff":return C.showTaskDiff(t.paths,e.taskId);case"showSelectedTaskDiff":return C.showTaskDiff(t.paths,Ve(t,"diff"));case"focusTask":return C.focusTask(t.paths,e.taskId);case"focusSelectedTask":return C.focusTask(t.paths,Ve(t,"focus"));case"openTask":return C.openTask(t.paths,e.taskId);case"openSelectedTask":return C.openTask(t.paths,Ve(t,"open"));case"runChecks":return C.runChecks(t.paths,e.taskId);case"runSelectedTaskChecks":return C.runChecks(t.paths,Ve(t,"check"));case"commitTask":return C.commitTask(t.paths,e.taskId);case"commitSelectedTask":return C.commitTask(t.paths,Ve(t,"commit"));case"help":return{kind:"help",text:Q()};case"exit":return{kind:"exit"};default:return ju(e)}}async function qn(e,t,r){let n=await Je({uiStateFile:e.uiStateFile})??Ht();await Se({uiStateFile:e.uiStateFile},{...n,selectedWorkspaceId:t,selectedRepoId:r,selectedTaskId:null})}async function Fu(e,t){let r=await Je({uiStateFile:e.uiStateFile});r?.selectedWorkspaceId===t&&await Se({uiStateFile:e.uiStateFile},{...r,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null})}function ju(e){throw new Error(`Unsupported command: ${JSON.stringify(e)}`)}function Ve(e,t){if(e.selectedTaskId)return e.selectedTaskId;throw new Error(`No task selected. Create a task with 'task new --repo <repo-id> <prompt>' or use '${t} <id>'.`)}function Ti(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
92
|
`);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
93
|
`);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
94
|
`);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
95
|
`);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
96
|
`);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}`,...
|
|
97
|
+
`);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} ${_u(t)} ${Bu(t)} ${t.title}`)].join(`
|
|
98
|
+
`);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}`,...Nu(e)].join(`
|
|
124
99
|
`);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
|
-
`).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
|
|
127
|
-
`)){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
|
|
128
|
-
`),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return H(t,s,"missing",t,null)}}async function
|
|
129
|
-
${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let a=await
|
|
130
|
-
${a.stdout.trimEnd()}`)}if(o.includes("unstaged")){let a=await
|
|
131
|
-
${a.stdout.trimEnd()}`)}if(o.includes("untracked")){let a=await x("git",["diff","--no-index","--stat","--patch",`--unified=${
|
|
100
|
+
`);default:return Wu(e)}}function Nu(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 Wu(e){throw new Error(`Unsupported result: ${JSON.stringify(e)}`)}function _u(e){return e.checks.status}function Bu(e){if(e.type==="project"&&e.repoTargets?.length){let r=e.repoTargets.filter(s=>s.pullRequest.number);if(r.length===0)return"-";let n=r.reduce((s,o)=>{let i=o.pullRequest.status??"unknown";return s[i]=(s[i]??0)+1,s},{});return Object.entries(n).map(([s,o])=>`${o} ${s}`).join(", ")}let t=e.prs[0];return t?.number?`#${t.number}:${t.status??"unknown"}`:"-"}import{createRequire as hg}from"node:module";import{readFile as Uu,stat as qu}from"node:fs/promises";import Vn from"node:path";var Vu=200*1024,Ku=500*1024,cr="100000";async function bi(e,t,r){if(e.type==="project"&&e.repoTargets?.length)return Hu(e,t,r);try{let n=Ee(r.selectedFilePath??null,t.filePaths),s=Ee(r.selectedDiffPath??null,t.diffPaths),o=s?await $t(e.worktreePath):null,[i,a]=await Promise.all([ur(e.worktreePath,n),s?Kn(e.worktreePath,s,t.diffRows,o):Promise.resolve(H("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 Hu(e,t,r){let n=Ee(r.selectedFilePath??null,t.filePaths),s=Ee(r.selectedDiffPath??null,t.diffPaths),[o,i]=await Promise.all([Si(e,n),(async()=>{if(!s)return H("No diff selected","No local changes found.","empty");let l=dr(e,s),d=l?await $t(l.target.worktreePath).catch(()=>null):null;return Ii(e,s,t.diffRows,d)})()]),a=s?{[s]:i}:{};return{...t,selectedFilePath:n,selectedDiffPath:s,diffContents:a,selectedFile:o,selectedDiff:i}}async function Pi(e,t={}){if(e.type==="project"&&e.repoTargets?.length)return Gu(e,t);try{await V(e);let r=await $t(e.worktreePath),[n,s]=await Promise.all([vi(e.worktreePath),Ci(e.worktreePath,r)]),o=[...new Set(s.map(u=>u.path))],i=Ee(t.selectedFilePath??null,n),a=Ee(t.selectedDiffPath??null,o),[l,d]=await Promise.all([ur(e.worktreePath,i),a?Kn(e.worktreePath,a,s,r):Promise.resolve(H("No diff selected","No local changes found.","empty"))]),c=a?{[a]:d}:{};return{taskId:e.id,fileRows:xi(n),filePaths:n,diffRows:s,diffPaths:o,diffContents:c,selectedFilePath:i,selectedDiffPath:a,selectedFile:l,selectedDiff:d,error:null}}catch(r){let n=r instanceof Error?r.message:"Unable to inspect task worktree.";return{taskId:e.id,fileRows:[],filePaths:[],diffRows:[],diffPaths:[],diffContents:{},selectedFilePath:null,selectedDiffPath:null,selectedFile:H("Files unavailable",n,"error"),selectedDiff:H("Diff unavailable",n,"error"),error:n}}}async function Gu(e,t){let r=(e.repoTargets??[]).filter(m=>m.status==="ready"),n=await Promise.all(r.map(async m=>{let y=await $t(m.worktreePath).catch(()=>null),[T,h]=await Promise.all([vi(m.worktreePath).catch(()=>[]),Ci(m.worktreePath,y).catch(()=>[])]);return{target:m,baseRef:y,targetFiles:T,targetDiffRows:h}})),s=[],o=[];for(let{target:m,targetFiles:y,targetDiffRows:T}of n)s.push(...y.map(h=>`${m.repoId}/${h}`)),o.push(...T.map(h=>({...h,path:`${m.repoId}/${h.path}`})));let i=[...new Set(o.map(m=>m.path))].sort(),a=Ee(t.selectedFilePath??null,s),l=Ee(t.selectedDiffPath??null,i),[d,c]=await Promise.all([Si(e,a),(async()=>{if(!l)return H("No diff selected","No local changes found.","empty");let m=dr(e,l),y=m?n.find(T=>T.target.repoId===m.target.repoId):null;return Ii(e,l,o,y?.baseRef??null)})()]),u=l?{[l]:c}:{};return{taskId:e.id,fileRows:xi(s),filePaths:s,diffRows:o,diffPaths:i,diffContents:u,selectedFilePath:a,selectedDiffPath:l,selectedFile:d,selectedDiff:c,error:null}}async function Si(e,t){let r=dr(e,t);if(!r)return H("No file selected","No Git-visible files found.","empty");let n=await ur(r.target.worktreePath,r.relativePath);return{...n,path:t,title:t??n.title}}async function Ii(e,t,r,n=null){let s=dr(e,t);return s?{...await Kn(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}:H(t,"Repo target is unavailable.","error",t)}function dr(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 vi(e){let t=await S("git",["ls-files","--cached","--others","--exclude-standard"],{cwd:e});return Di(t.stdout)}async function Ci(e,t){let[r,n,s,o]=await Promise.all([zu(e,t),Ri(e,"staged"),Ri(e,"unstaged"),Yu(e)]);return[...r,...n,...s,...o]}async function zu(e,t){if(!t)return[];let[r,n]=await Promise.all([S("git",["diff","--name-status",`${t}...HEAD`],{cwd:e}),S("git",["diff","--numstat",`${t}...HEAD`],{cwd:e})]),s=Ei(r.stdout),o=Ai(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 Ri(e,t){let r=t==="staged"?["diff","--cached"]:["diff"],[n,s]=await Promise.all([S("git",[...r,"--name-status"],{cwd:e}),S("git",[...r,"--numstat"],{cwd:e})]),o=Ei(n.stdout),i=Ai(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 Yu(e){let t=await S("git",["ls-files","--others","--exclude-standard"],{cwd:e}),r=Di(t.stdout);return await Promise.all(r.map(async s=>{let o=await ur(e,s),i=o.status==="ready"?Qu(o.lines):null;return{group:"untracked",path:s,status:"A",additions:i,deletions:0}}))}function Ei(e){return e.split(`
|
|
101
|
+
`).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 Ai(e){let t=new Map;for(let r of e.split(`
|
|
102
|
+
`)){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 $t(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 ur(e,t){if(!t)return H("No file selected","No Git-visible files found.","empty");let r=Ju(e,t);try{let n=await qu(r);if(n.size>Vu)return H(t,`File is ${n.size} bytes, above the 200 KB inline preview limit.`,"too_large",t,n.size);let s=await Uu(r);return Xu(s)?H(t,"Binary file preview is not available in Craig.","binary",t,s.byteLength):{path:t,status:"ready",title:t,lines:s.toString("utf8").split(`
|
|
103
|
+
`),byteLength:s.byteLength}}catch(n){let s=n instanceof Error?n.message:"Unable to read file.";return H(t,s,"missing",t,null)}}async function Kn(e,t,r,n=null){if(!t)return H("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 $t(e);if(a){let l=await S("git",["diff","--stat","--patch",`--unified=${cr}`,`${a}...HEAD`,"--",t],{cwd:e});l.stdout.trim().length>0&&s.push(`branch
|
|
104
|
+
${l.stdout.trimEnd()}`)}}if(o.includes("staged")){let a=await S("git",["diff","--cached","--stat","--patch",`--unified=${cr}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`staged
|
|
105
|
+
${a.stdout.trimEnd()}`)}if(o.includes("unstaged")){let a=await S("git",["diff","--stat","--patch",`--unified=${cr}`,"--",t],{cwd:e});a.stdout.trim().length>0&&s.push(`unstaged
|
|
106
|
+
${a.stdout.trimEnd()}`)}if(o.includes("untracked")){let a=await x("git",["diff","--no-index","--stat","--patch",`--unified=${cr}`,"--","/dev/null",t],{cwd:e});a.stdout.trim().length>0&&s.push(`untracked
|
|
132
107
|
${a.stdout.trimEnd()}`)}let i=s.join(`
|
|
133
108
|
|
|
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
|
|
109
|
+
`);return i.length>Ku?H(t,"Diff is above the 500 KB inline preview limit.","too_large",t,i.length):i.includes("\0")?H(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(`
|
|
110
|
+
`):["No diff for this file."],byteLength:i.length}}function xi(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 Ee(e,t){return e&&t.includes(e)?e:t[0]??null}function Qu(e){return e.length===1&&e[0]===""?0:e.at(-1)===""?e.length-1:e.length}function Di(e){return[...new Set(e.split(`
|
|
111
|
+
`).map(t=>t.trim()).filter(t=>t.length>0))].sort((t,r)=>t.localeCompare(r))}function Ju(e,t){let r=Vn.resolve(e,t),n=Vn.resolve(e);if(r!==n&&!r.startsWith(`${n}${Vn.sep}`))throw new Error(`File path escapes task worktree: ${t}`);return r}function Xu(e){return e.subarray(0,Math.min(e.byteLength,8e3)).includes(0)}function H(e,t,r,n=null,s=null){return{path:n,status:r,title:e,lines:[t],byteLength:s}}var Zu=["tasks","center","inspector","actions"],$i=["agent","terminal"],Mi=[],E="inspection",KR=[...$i,...Mi],Hn=["commit","push","refresh-checks","close-task"],Li=["refresh-checks","close-task"],Oi=["task","checks","pr","setup-run","actions","next-action"],Gn=["files","review"];function Fi(e,t={}){let r=e?.activeTab==="files"?"file":e?.activeTab==="diff"?"diff":null,n=op(e?.openInspectionKind)??r,s=f.runners.getEnabled(t);return{inputMode:ap(e?.inputMode),focusedRegion:np(e?.focusedRegion),selectedRepoId:Te(e?.selectedRepoId),selectedWorkspaceId:Te(e?.selectedWorkspaceId),selectedTaskId:Te(e?.selectedTaskId),selectedPtyTabId:Te(e?.selectedPtyTabId),selectedLeftItemId:mp(Te(e?.selectedTaskId)),activeTab:r?E:Te(e?.activeTab)??"agent",preferredPtyTabKind:ip(e?.preferredPtyTabKind),inspectorSection:Mt(e?.inspectorSection,Oi,"task"),inspectionMode:sp(e?.inspectionMode,r==="diff"?"review":"files"),openInspectionKind:n,selectedFileTreePath:Te(e?.selectedFileTreePath),selectedFilePath:Te(e?.selectedFilePath),selectedDiffPath:Te(e?.selectedDiffPath),collapsedFileTreePaths:Array.isArray(e?.collapsedFileTreePaths)?e.collapsedFileTreePaths:[],fileScrollOffset:0,diffScrollOffset:0,reviewScrollOffset:0,selectedActionId:Mt(e?.selectedActionId,Hn,"commit"),selectedProjectTargetId:null,selectedRunner:lp(e?.selectedRunner,s,f.runners.getDefault(t)),centerTabRunner:null,actionMessage:null,footerToast:null,taskPromptInput:null,taskPromptError:null,fileSearchQuery:null,workspaceBrowser:null,terminal:ep(),centerZoomed:!1}}function ep(){return{status:"idle",rows:[],error:null,scrolledBack:!1}}function ji(e,t){return{...e??Ht(),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 Lt(e,t,r={}){let n=pp(e,t),s=Yn(n),o=(s?.kind==="workspace"?t.workspaces?.find(c=>c.id===s.id)??null:null)??(s?.kind==="task"?t.workspaces?.find(c=>c.id===t.tasks.find(u=>u.id===s.id)?.workspaceId)??null:null)??t.workspaces?.find(c=>c.id===e.selectedWorkspaceId)??t.workspaces?.[0]??null,a=((s?.kind==="repo"?t.repos.find(c=>c.id===s.id)??null:s?.kind==="task"?t.repos.find(c=>c.id===t.tasks.find(u=>u.id===s.id)?.repoId)??null:null)??(o?.kind==="project"?t.repos.find(c=>c.id===e.selectedRepoId&&o.discoveredRepoIds?.includes(c.id))??null:null)??(o?.kind!=="project"?t.repos.find(c=>c.id===o?.primaryRepoId)??null:null)??t.repos.find(c=>c.id===e.selectedRepoId)??t.repos[0]??null)?.id??null,l=o?t.tasks.filter(c=>c.workspaceId===o.id):a?t.tasks.filter(c=>c.repoId===a):[],d=(s?.kind==="task"?l.find(c=>c.id===s.id)??null:null)??l.find(c=>c.id===e.selectedTaskId)??l[0]??null;return{...e,inputMode:r.resetInputMode?"control":e.inputMode,selectedLeftItemId:n,selectedWorkspaceId:o?.id??null,selectedRepoId:a,selectedTaskId:d?.id??null,...cp(d,e.activeTab,e.selectedPtyTabId),selectedFilePath:rp(e,t,d?.id??null),...dp(e,t,d?.id??null),selectedDiffPath:tp(e,t,d?.id??null),inspectorSection:Mt(e.inspectorSection,Oi,"task")}}function Re(e,t){return{...e,terminal:t}}function Ni(e,t){return{...e,inputMode:"control",terminal:{status:"failed",rows:[],error:t}}}function Wi(e){return e===""||e==="CTRL_]"||e==="CTRL_RIGHT_BRACKET"}function ce(e){return e==="ENTER"||e==="KP_ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
112
|
+
`}function _i(e){return e.length===1&&e>=" "&&e!=="\x7F"}function zn(e){return Ui(e)||ct(e)!==null}function Bi(e){return Mi.includes(e)}function Ui(e){return $i.includes(e)}function qi(e,t){return[...e?.ptyTabs.map(r=>r.id)??[],...t?.openInspectionKind?[E]:[]]}function tp(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedDiffPath&&(t.inspection.diffPaths??[]).includes(e.selectedDiffPath)?e.selectedDiffPath:t.inspection.selectedDiffPath}function rp(e,t,r){return!t.inspection||t.inspection.taskId!==r||e.selectedFilePath&&(t.inspection.filePaths??[]).includes(e.selectedFilePath)?e.selectedFilePath:t.inspection.selectedFilePath}function Mt(e,t,r){return t.includes(e??"")?e:r}function np(e){return e==="tabs"?"center":Mt(e,Zu,"tasks")}function sp(e,t){return e==="checks"||e==="actions"||e==="diff"||e==="review"?"review":Mt(e,Gn,t)}function op(e){return e==="file"||e==="diff"?e:null}function ip(e){return e==="terminal"?"terminal":"agent"}function ap(e){return e==="terminal"?"terminal":"control"}function lp(e,t=[...$],r="codex"){return e&&f.runners.isRunnerType(e)&&t.includes(e)?e:r}function pr(e,t=$){let r=t.length>0?t:$,n=r.indexOf(e);return r[(n+1)%r.length]??r[0]??"codex"}function ct(e){let t=$.join("|");return new RegExp(`:(?:agent|${t})(?:-\\d+)?$`).test(e)?"agent":/:terminal(?:-\d+)?$/.test(e)?"terminal":null}function cp(e,t,r){if(!e)return{activeTab:t===E?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(Ui(t)){let l=e.ptyTabs.find(d=>d.kind===t)??null??s??n??e.ptyTabs[0]??null;return{activeTab:l?.id??E,selectedPtyTabId:l?.id??null}}if(t===E)return{activeTab:E,selectedPtyTabId:n?.id??s?.id??e.ptyTabs[0]?.id??null};let i=s??n??e.ptyTabs[0]??null;return{activeTab:i?.id??E,selectedPtyTabId:i?.id??null}}function dp(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?up(t.inspection.fileRows??[],t.inspection.selectedFilePath):e.collapsedFileTreePaths;return{selectedFileTreePath:n,collapsedFileTreePaths:s}}function up(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 pp(e,t){let r=Ke(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 Ke(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 Yn(e){return e?e.startsWith("workspace:")?{kind:"workspace",id:e.slice(10)}:e.startsWith("repo:")?{kind:"repo",id:e.slice(5)}:e.startsWith("task:")?{kind:"task",id:e.slice(5)}:null:null}function Te(e){return typeof e=="string"?e:null}function mp(e){return e?`task:${e}`:null}function Ot(e){return typeof e=="string"&&e.startsWith("task:")}function mr(e){return typeof e=="string"&&e.startsWith("new-task:")}function fr(e){return typeof e=="string"&&e.startsWith("new-task-workspace:")}function Vi(e){return typeof e=="string"&&e.startsWith("workspace:")}function Qn(e){return mr(e)?e.slice(9):null}function Jn(e){return fr(e)?e.slice(19):null}async function Ae(e,t,r){let n=me(e),[s,o]=await Promise.all([Z.repos.listRegisteredRepos(n),Z.listWorkspaces(n,{archived:!1})]),i=await C.listTasks(n),a=Xn(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=a?await Pi(a,l):null;return{workspaceRoot:e,workspaces:o.workspaces,repos:s.repos,tasks:i.tasks,inspection:d,...r?{enabledRunnerIds:r}:{}}}function Xn(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function Ki(e,t){return Lt(e,t)}import ls from"node:path";import eb from"picocolors";var fp=[" \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 Zn(){return[...fp]}var gr={width:120,height:36},L={leftWidth:42,rightWidth:36,dividerWidth:1,topRailHeight:1};function oe(e,t){return{width:Math.max(e??gr.width,gr.width),height:Math.max(t??gr.height,gr.height)}}var gp=["Start","Options","Exit"],hp=["Resume","Options","Exit"],wr=2,kr=2,yr=2,wp=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),kp=new RegExp("\x1B\\[(?:0)?m","g"),yp=new RegExp("\x1B\\]8;;[^\x1B]*\x1B\\\\","g"),Tp=/https?:\/\/[^\s<>"']+/g,ts="\x1B[0m",rs="\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"}},es=["3d59a1","506eb8","6386d0","7aa2f7","6386d0","506eb8"];function zi(e,t={}){return ss(e,{subtitle:"crAIg is that you?",menuItems:gp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}function Yi(e,t={}){return ss(e,{subtitle:"Control mode is paused.",menuItems:hp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0,versionText:t.versionText??null,updateText:t.updateText??null})}var hr=[" 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."],Rp=["Help"],bp=5;function br(e,t={}){return ss(e,{subtitle:t.optionsSubtitle??"Configuration",menuItems:t.optionsMenuItems??Rp,menuIndex:t.menuIndex??0,optionsMessage:t.optionsMessage??null,color:t.color??!0})}function Qi(e,t={}){let r=t.color??!0,n=b.overlay,s=new Array(e.height).fill(F(" ".repeat(e.width),r,n)),o=Zn(),i=Math.max(1,Math.floor((e.height-o.length-2-hr.length)/2));for(let c=0;c<o.length&&!(i+c>=e.height);c+=1)s[i+c]=F(oa(o[c]??"",e.width),r,b.overlayLogo);let a=Math.max(...hr.map(c=>c.length)),l=Math.max(0,Math.floor((e.width-a)/2)),d=i+o.length+2;for(let c=0;c<hr.length;c+=1){let u=d+c;if(u>=e.height)break;let m=hr[c]??"";s[u]=F(he(" ".repeat(l)+m,e.width),r,n)}return s.join(`
|
|
113
|
+
`)}function Ji(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),d=Math.max(0,Math.floor((e.width-l)/2)),c=[{text:o,tone:"selected"},{text:i,tone:"muted"},de(),...a.length>0?a.map(y=>({text:y})):[{text:"No Craig errors have been logged.",tone:"muted"}],de(),{text:"Esc returns to Options.",tone:"muted"}],u=Ft(c,e.height-2),m=Math.max(1,Math.floor((e.height-u.length)/2));for(let y=0;y<u.length;y+=1){let T=m+y;if(T>=e.height)break;let h=u[y]??de(),R=`${" ".repeat(d)}${Pr(h.text,l)}`,U=h.tone==="selected"?b.overlayMenuSelected:h.tone==="muted"?b.overlay:b.panelBg;s[T]=F(he(R,e.width),r,U)}return s.join(`
|
|
114
|
+
`)}function Xi(e,t,r={}){let n=r.color??!0,s=L.leftWidth,o=L.rightWidth,i=r.centerOnly??!1,a=e.height-L.topRailHeight-1,l=r.focusFlashActive??!1,d={bg:b.divider.bg,fg:"9ece6a"},c=l&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?d:b.divider,u=l&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?d:b.divider,m=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,y=F(he(m,e.width),n,b.rail),T=Sp(t,s-wr-kr,a,n),h=ns(e,t,{color:n,centerOnly:i}),R=Cp(t,o,a,n),U=t.inputMode==="terminal",K=[],re=[];for(let ke=0;ke<a;ke+=1)if(!i){let Le=Tr(T[ke]??de(),s,n,"left"),Bt=F("\u2502",n,c),Ut=F("\u2502",n,u),qt=Tr(R[ke]??de(),o,n,"right");K.push(`${Le}${Bt}`),re.push(`${Ut}${qt}`)}let I=U||t.modalInput?b.panelBg:b.panelMuted,we=Pp(t.footerText,t.footerToast,e.width,n,I),gt={row:1,column:1,width:e.width,rows:[y]},Ye=i?null:{row:L.topRailHeight+1,column:1,width:s+L.dividerWidth,rows:K},_r=i?null:{row:L.topRailHeight+1,column:h.column+h.width,width:L.dividerWidth+o,rows:re},p={row:e.height,column:1,width:e.width,rows:[we]},Me=i?h.rows:h.rows.map((ke,Le)=>`${K[Le]??""}${ke}${re[Le]??""}`);return{frame:[y,...Me,we].join(`
|
|
115
|
+
`),center:h,regions:{rail:gt,left:Ye,center:h,right:_r,footer:p}}}function ns(e,t,r={}){let n=r.color??!0,s=ea(e,r.centerOnly??!1),o=Ip(t,s.width,s.rowCount,n);return{row:s.row,column:s.column,width:s.width,rows:o.map(i=>Tr(i,s.width,n,"center"))}}function Zi(e,t,r,n={}){let s=t.tabs.find(d=>d.active)?.id??"";if(!zn(s)||t.centerHeader.tabLabel==="BROWSER"||t.terminal.error||t.terminal.rows.length===0||r.some(d=>d<0||d>=t.terminal.rows.length))return null;let o=n.color??!0,i=ea(e,n.centerOnly??!1),a=ta(t,i.width,o).length,l=[...new Set(r)].map(d=>({terminalIndex:d,index:a+d})).filter(({index:d})=>d<i.rowCount).map(({terminalIndex:d,index:c})=>({index:c,row:Tr(ra(t.terminal.rows[d]),i.width,o,"center")}));return{...i,rows:l}}function ea(e,t){return{row:L.topRailHeight+1,column:t?1:L.leftWidth+L.dividerWidth+1,width:t?e.width:e.width-L.leftWidth-L.rightWidth-L.dividerWidth*2,rowCount:e.height-L.topRailHeight-1}}function Pp(e,t,r,n,s){let o=` ${e}`;if(!t)return F(he(o,r),n,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,a=te(i),l=te(o),d=Math.max(1,r-l-a-2),c=l+d+a+2>r?Pr(o,Math.max(0,r-a-3)):o,u=Math.max(1,r-te(c)-a-2),m=t.tone==="error"?Hp(i,n,s):dt(i,n,s),y=`${c}${" ".repeat(u)}${m} `;return F(he(y,r),n,s)}function ss(e,t){let r=new Array(e.height).fill(F(" ".repeat(e.width),t.color,b.overlay)),n=Zn(),s=t.menuItems.map((d,c)=>`${c===t.menuIndex?">":" "} ${d}`),o=t.optionsMessage?["",t.optionsMessage]:[],i=[...s,...o];for(;i.length<bp;)i.push("");let a=[...n,"",t.subtitle,"",...i],l=Math.max(1,Math.floor((e.height-a.length)/2));for(let d=0;d<a.length;d+=1){let c=oa(a[d]??"",e.width);if(d<n.length){r[l+d]=F(c,t.color,b.overlayLogo);continue}if(d===n.length+1){r[l+d]=F(c,t.color,b.overlaySubtitle);continue}let u=d-(n.length+3),y=u>=0&&u<t.menuItems.length&&u===t.menuIndex?b.overlayMenuSelected:b.overlay;r[l+d]=F(c,t.color,y)}if(t.versionText){let d=t.updateText?" (update available)":"",c=`${t.versionText}${d} `,u=" ".repeat(Math.max(0,e.width-te(c)));r[e.height-1]=F(`${u}${as(c,t.color,b.overlay)}`,t.color,b.overlay)}return r.join(`
|
|
116
|
+
`)}function Sp(e,t,r,n){let s=xp(e.runners),o=1,i=e.leftTree.map(l=>Ap(l,t,n));return[...Ft(i,r-o),s]}function Ip(e,t,r,n){let s=e.tabs.find(i=>i.active)?.id??"agent",o=e.centerHeader.tabLabel==="BROWSER"||!zn(s)?e.centerTranscript.map(i=>({...i})):vp(e);return Ft([...ta(e,t,n),...o],r)}function ta(e,t,r){let n=t-2,s=e.tabs.find(R=>R.active)?.label??"AGENT",o=e.inputMode==="terminal"?0:qp(e.tabs),i=e.inputMode==="terminal"?n:s.length+1,a="\u2500".repeat(Math.max(0,i)),l=`${" ".repeat(o)}${e.inputMode==="terminal"?dt(a,r,b.panelBg):Rr(a,r,b.panelMuted)}`,d=[`${Rr(e.centerHeader.tabLabel,r,b.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),c=Dp(e.tabs,r,e.focusedRegion==="center"),u=" engaged ",m=u.length+2,y=e.inputMode==="terminal"?dt(`${u}\u25CF `,r,b.panelBg):"",T=e.inputMode==="terminal"?" ".repeat(Math.max(0,n-te(c)-m)):"";return[{text:e.inputMode==="terminal"?`${c}${T}${y}`:c},{text:l,tone:"muted"},{text:d},de()]}function vp(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},de(),{text:e.terminal.error},de(),{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(ra)}function ra(e){return{text:is(e.segments),segments:e.segments,fullBleed:!0}}function Cp(e,t,r,n){let s=e.rightInspection?Ep(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):Ft([{text:"CONTEXT"},de(),...e.rightContext.map(o=>$p(o,n)),...e.actionMessage?[de(),{text:e.actionMessage}]:[]],r);return Ft(s,r)}function Ep(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:Kp(o-Math.floor(s/2),0,Math.max(0,n.length-s));return[...r.map(a=>Hi(a)),...n.slice(i,i+s).map(a=>Hi(a))]}function Hi(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 Ap(e,t,r){let n=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${dt("\u25CF",r,e.selected?b.panelSelected:b.panelBg)}`:"",a=e.prBadge?e.prBadge.reduce((T,h)=>T+te(h.text),0):0,l=t-te(o)-te(s)-a,d=e.activity?`${e.selected?"\u25B8":" "} \u25CF `:"",c=e.selected?e.text:e.focused?dt(e.text,r,b.panelBg):e.panelHeader?Rr(e.text,r,b.panelMuted):e.text,u=he(`${n}${d}${c}`,Math.max(0,l)),m=e.selected?"selected":e.muted?"muted":"default";if(e.activity){let T=`${n}${e.selected?"\u25B8":" "} `,h=u.slice(T.length+2),R=[{text:T},na(e.activity,e.activityAnimationFrame??0),{text:` ${h}${o}${i}`},...e.prBadge??[]];return{text:is(R),segments:R,tone:m}}if(e.prBadge){let T=[{text:`${u}${o}${i}`},...e.prBadge];return{text:`${u}${o}${e.prBadge.map(R=>R.text).join("")}`,segments:T,tone:m}}return{text:`${u}${o}${i}`,tone:m}}function xp(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 Dp(e,t,r){return e.map(n=>{let s=n.active?r?dt(n.label,t,b.panelBg):Rr(n.label,t,b.panelBg):as(n.label,t,b.panelBg),o=n.activity?os(na(n.activity,n.activityAnimationFrame??0),t,b.panelBg):"";return`${s}${o?` ${o}`:""}`}).join(" ")}function na(e,t){return{text:"\u25CF",style:{fg:e==="working"?es[t%es.length]??es[0]:e==="ready"?b.success.fg:e==="error"?b.error.fg:b.panelMuted.fg}}}function $p(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?as(e.value,t,b.panelBg):e.value}`}}function Tr(e,t,r,n){let s=Mp(n,e.tone??"default"),o=Lp(e,r,s);if(n==="left"){if(e.fullBleed)return F(he(o,t),r,s);let a=t-wr-kr;if(e.rightAlign){let d=te(o),c=Math.max(0,a-d),u=`${" ".repeat(wr)}${" ".repeat(c)}${o}${" ".repeat(kr)}`;return F(u,r,s)}let l=`${" ".repeat(wr)}${he(o,a)}${" ".repeat(kr)}`;return F(l,r,s)}return n==="center"&&e.fullBleed?Op(e,t,r,s):F(he(` ${o}`,t),r,s)}function Mp(e,t){return t==="selected"||t==="focused"?b.panelSelected:t==="muted"?b.panelMuted:b.panelBg}function Ft(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(de());return r}function de(){return{text:""}}function Lp(e,t,r){return e.segments?e.segments.map(n=>os(n,t,r)).join(""):e.text}function Op(e,t,r,n){let s=" ".repeat(yr),o=Math.max(0,t-yr*2);if(!e.segments)return F(`${s}${he(e.text,o)}${s}`,r,n);let i=Np(e.segments,o),a=`${s}${i.map(l=>os(l,r,n)).join("")}${s}${r?rs:""}`;return F(a,r,n)}function os(e,t,r){let n=e.href?`${sa(e.href)}${e.text}${rs}`:Fp(e.text);return!t||!e.style?n:`${jt(Bp(e.style,r))}${Up(e.style)}${n}${ts}${jt(r)}`}function Fp(e){return e.replace(Tp,t=>{let[r,n]=jp(t);return`${sa(r)}${r}${rs}${n}`})}function jp(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function sa(e){return`\x1B]8;;${e}\x1B\\`}function Np(e,t){let r=Wp(e,t);return _p(r,t)}function Wp(e,t){let r=[],n=t;for(let s of e){if(n<=0)break;let o=te(s.text);if(o<=n){r.push(s),n-=o;continue}let i=Pr(s.text,n);i.length>0&&r.push({...s,text:i}),n=0}return r}function _p(e,t){let r=te(is(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 Bp(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 Up(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 qp(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 oa(e,t){let r=Math.max(0,t-te(e)),n=Math.floor(r/2),s=r-n;return`${" ".repeat(n)}${e}${" ".repeat(s)}`}function he(e,t){let r=te(e);return r>=t?Vp(e,t):e+" ".repeat(t-r)}function Vp(e,t){if(t<=0)return"";if(te(e)<=t)return e;let r=aa(e);return Pr(r,Math.max(0,t-1))+"\u2026"}function te(e){let t=0;for(let r of Array.from(aa(e)))t+=ia(r);return t}function Pr(e,t){let r="",n=0;for(let s of Array.from(e)){let o=ia(s);if(n+o>t)break;r+=s,n+=o}return r}function ia(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 Kp(e,t,r){return Math.min(Math.max(e,t),r)}function aa(e){return e.replace(yp,"").replace(wp,"")}function is(e){return e.map(t=>t.text).join("")}function F(e,t,r){if(!t)return e;let n=jt(r),s=e.replace(kp,`${ts}${n}`);return`${n}${s}${ts}`}function jt(e){let t=[];return e.fg&&t.push(`38;2;${Gi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Gi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Gi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function dt(e,t,r){return Sr(e,t,b.success.fg,r)}function Hp(e,t,r){return Sr(e,t,b.error.fg,r)}function Rr(e,t,r){return Sr(e,t,b.accent.fg,r)}function as(e,t,r){return Sr(e,t,b.mutedfg.fg,r)}function Sr(e,t,r,n){if(!t)return e;let s=n.bg?{fg:r,bg:n.bg}:{fg:r};return`${jt(s)}${e}${jt(n)}`}function la(e,t,r){let n=e.tasks.find(a=>a.ptyTabs.some(l=>l.id===t))??null,s=n?.ptyTabs.find(a=>a.id===t)??null,o=n?.worktreePath??r,i=s?.kind==="agent"?zp(s):[];return n?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:Gp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function Gp(e,t){let r=(e??"").split(ls.delimiter).filter(n=>n.length>0);return r.includes(t)?r.join(ls.delimiter):[...r,t].join(ls.delimiter)}function zp(e){return e.command.length>0?e.command:["codex"]}function ca(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 xe(e){return{columns:Math.max(20,e.width-L.leftWidth-L.rightWidth-L.dividerWidth-yr*2),rows:Math.max(5,e.height-L.topRailHeight-5)}}function da(e){return e.length===1||ce(e)||e==="BACKSPACE"||e==="TAB"}function De(e){return typeof e=="string"&&new RegExp(`:(?:agent|${$.join("|")})(?:-\\d+)?$`).test(e)}function ua(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 cs(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function pa(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 Nt(e){return fa.includes(e)?"SHIFT_ENTER":null}function ds(e){return fa.some(t=>t.startsWith(e))}function ma(e){return e==="ESCAPE"?"\x1B":e.length===1?e:null}var fa=["\x1B[13;2u","\x1B[13;2~","\x1B[27;2;13~","\x1B[27;2;10~"];function ga(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
|
|
142
117
|
`||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
|
|
118
|
+
`)?!0:!t||Date.now()-t.at>=30?!1:r===t.key?!0:r.length<=4&&r.split("").every(n=>n===t.key)}function ha(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function wa(e,t=null){let r=t?.split(`
|
|
144
119
|
`)??[];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 ${
|
|
120
|
+
`).map((n,s)=>r[s]===n?"":`\x1B[${s+1};1H${n}`).join("")}function Ir(e,t,r,n){return e.map((s,o)=>t?.[o]===s?"":`\x1B[${r+o};${n}H${s}`).join("")}import{spawn as km}from"node:child_process";import{createHash as ym}from"node:crypto";import{createServer as Tm,createConnection as va}from"node:net";import{openSync as Rm}from"node:fs";import{mkdir as bm,readFile as ws,rm as Ge,writeFile as Pm}from"node:fs/promises";import{tmpdir as Sm}from"node:os";import ut from"node:path";import{createRequire as sm}from"node:module";import Yp from"@xterm/headless";var Qp=1e3,Jp=["000000","cd3131","0dbc79","e5e510","2472c8","bc3fbc","11a8cd","e5e5e5","666666","f14c4c","23d18b","f5f543","3b8eea","d670d6","29b8db","ffffff"];function ya(e){return new Yp.Terminal({allowProposedApi:!0,cols:e.columns,rows:e.rows,scrollback:Qp,theme:{foreground:"#e6e6e6",background:"#0a0a0a"}})}function Ta(e,t){(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function ps(e,t){return new Promise(r=>{e.write(t,r)})}function Ra(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 d=[];for(let c=0;c<e.cols;c+=1){let u=l.getCell(c,s);!u||u.getWidth()===0||d.push({text:u.getChars()||" ",style:em(u,i+a===o&&c===r.cursorX)})}n.push({segments:Xp(Zp(d))})}return n}function Xp(e){let t=[];for(let r of e){let n=t.at(-1);if(n&&nm(n.style,r.style)){n.text+=r.text;continue}let s={text:r.text};ba(r.style)||(s.style=r.style),t.push(s)}return t}function Zp(e){let t=e.length;for(;t>0;){let r=e[t-1];if(!r||r.text!==" "||!ba(r.style))break;t-=1}return e.slice(0,t)}function em(e,t){let r={},n=ka(e,"fg"),s=ka(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 ka(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"):Jp[s]??tm(s)}function tm(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(rm).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 rm(e){return e===0?0:55+e*40}function nm(e,t){return us(e)===us(t)}function us(e){return e?[e.fg??"",e.bg??"",e.bold?"b":"",e.dim?"d":"",e.italic?"i":"",e.underline?"u":"",e.inverse?"v":""].join("|"):""}function ba(e){return us(e)===""}var om=sm(import.meta.url),im=/^CTRL_([A-Z])$/,am="\x1B[6n",lm="\x1B[c",cm="\x1B[?u",dm={ENTER:"\r",KP_ENTER:"\r",SHIFT_ENTER:`
|
|
121
|
+
`,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:""},vr=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")ms(o),this.sessions.delete(r);else return this.attachedTabId=r,o.scrollbackLines=0,Pa(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(`
|
|
122
|
+
`))&&this.touchActivity(r))}writeKey(t){let r=um(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&&Pa(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&&(ms(r),this.sessions.delete(t)),this.removeActivity(t),this.attachedTabId===t&&(this.attachedTabId=null)}disposeAll(){for(let t of this.sessions.values())ms(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:pm(r),error:r.error,scrolledBack:r.scrollbackLines>0}:{status:"idle",rows:[],error:null,scrolledBack:!1}}createSession(t,r,n,s){let o=this.spawn??fm().spawn,i=ya(n),a=s??this.resolveSessionSpec(t,r),l=Be({...this.env,...a.env??{}}),{executable:d,args:c}=gm(this.shell,a.command,{cwd:a.cwd,env:l}),u=o(d,c,{name:"xterm-256color",cols:n.columns,rows:n.rows,cwd:a.cwd,env:hm(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(y=>{this.touchActivity(m),wm(u,y),ps(m.terminal,y).then(()=>{m.screenDirty=!0,this.onUpdate?.({tabId:m.tabId,kind:"full"})})})),m.disposables.push(u.onExit(y=>{m.status="exited",m.exitCode=y.exitCode,m.lastActivityAt=Date.now(),this.notifyActivity(m),ps(m.terminal,`\r
|
|
123
|
+
[process exited ${y.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 um(e){if(e.length===1)return e;let t=dm[e];if(t!==void 0)return t;let r=im.exec(e);return r?.[1]?String.fromCharCode(r[1].charCodeAt(0)-64):null}function Pa(e,t){mm(e.pty,t),Ta(e.terminal,t),e.screenDirty=!0}function pm(e){return(e.screenDirty||e.renderedScrollbackLines!==e.scrollbackLines)&&(e.rows=Ra(e.terminal,e.scrollbackLines),e.renderedScrollbackLines=e.scrollbackLines,e.screenDirty=!1),e.rows}function ms(e){for(let t of e.disposables)t.dispose();e.terminal.dispose(),e.pty.kill()}function mm(e,t){t.columns>0&&t.rows>0&&(e.cols!==t.columns||e.rows!==t.rows)&&e.resize(t.columns,t.rows)}function fm(){return om("node-pty")}function gm(e,t,r){if(t.length===0)return{executable:e,args:[]};let s=`${[Ue(t[0],r),...t.slice(1)].map(Sa).join(" ")}; exec ${Sa(e)} -l`;return{executable:e,args:["-lc",s]}}function Sa(e){return`'${e.replaceAll("'","'\\''")}'`}function hm(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 wm(e,t){for(let r=0;r<fs(t,am);r+=1)e.write("\x1B[1;1R");for(let r=0;r<fs(t,lm);r+=1)e.write("\x1B[?1;2c");for(let r=0;r<fs(t,cm);r+=1)e.write("\x1B[?0u")}function fs(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 Ca=6,Im=new Set([Ca]),vm=16,Cm=250;async function Ea(e){let t=ks(e.paths);await Dm(t,e.paths,e.spawnDaemon);let r=await Oa(t.socketPath),n=new gs(r,e);return await n.ready(),n}async function Aa(e,t={}){let r=ks(e);await bm(e.runtimeDir,{recursive:!0}),await Ge(r.socketPath,{force:!0});let n=new hs(e,t),s=Tm(o=>n.handleConnection(o));await jm(s,r.socketPath),await Pm(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 Ge(r.socketPath,{force:!0}),await Ge(r.pidPath,{force:!0}),n.disposeAll()}async function xa(e){let t=ks(e);return await Er(t.socketPath)?(await Ma(t.socketPath),!0):!1}var gs=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(!$a(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
124
|
`);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
125
|
`);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=
|
|
126
|
+
`)}}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=xm(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)}}},hs=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 vr({...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
127
|
`);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
|
|
128
|
+
`)}});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{He(t,{id:-1,ok:!1,error:"Malformed daemon request."});return}try{let s=this.handleRequest(t,n);He(t,{id:n.id,ok:!0,...n.type==="ping"?{protocolVersion:Ca}:{},...n.type==="getActivitySnapshots"?{activities:this.runtime.getActivitySnapshots()}:{},...s?{view:s}:{}})}catch(s){let o=s instanceof Error?s.message:String(s);He(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 Nm(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(Cr)}),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(Cr)}),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),He(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)},Cm))}}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&&He(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&&He(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)},vm))}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=Em(s,r),i=Am(s.view,r);s.view=r,s.rowKeys=r.rows.map(Cr),(o.rows.length>0||i)&&He(n,{type:"update",tabId:t,patch:o})}}};function Em(e,t){let r=[];for(let n=0;n<t.rows.length;n+=1){let s=t.rows[n];e.rowKeys[n]!==Cr(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 Am(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 xm(e,t){return e.status!==t.status||e.error!==t.error||(e.scrolledBack??!1)!==t.scrolledBack||e.rows.length!==t.rowCount}function Cr(e){return JSON.stringify(e)}function ks(e){let t=ym("sha256").update(e.workspaceRoot).digest("hex").slice(0,16);return{socketPath:ut.join(Sm(),`craig-${t}.sock`),pidPath:ut.join(e.runtimeDir,"pty-daemon.pid")}}async function Dm(e,t,r){if(await $m(e.socketPath,1e3))return;await Er(e.socketPath)&&(await Ma(e.socketPath),await Ia(e.socketPath,1e3)),await Er(e.socketPath)&&(await Om(e),await Ia(e.socketPath,1e3)),await Lm(e);let n=t.workspaceRoot;if(r)r(n);else{let{command:i,args:a}=Mm(n),l=Rm(ut.join(t.runtimeDir,"pty-daemon.log"),"a");km(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 Da(e.socketPath))return;await ys(50)}let o=await ws(ut.join(t.runtimeDir,"pty-daemon.log"),"utf8").catch(()=>"");throw new Error(`Craig PTY daemon did not start.${o?`
|
|
129
|
+
${o.slice(-2e3)}`:""}`)}async function Da(e){let t=await Fm(e).catch(()=>null);return t?.ok===!0&&$a(t.protocolVersion)}function $a(e){return e!==void 0&&Im.has(e)}async function $m(e,t){let r=Date.now();for(;Date.now()-r<t;){if(await Da(e))return!0;await ys(50)}return!1}function Mm(e){let t=process.argv[1];if(t?.endsWith(".ts")){let n=ut.resolve(ut.dirname(t),"..","node_modules",".bin","tsx");return{command:yn("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 Lm(e){let t=await ws(e.pidPath,"utf8").catch(()=>null);if(t){let r=Number(t.trim());if(Number.isInteger(r)&&r>0&&Fa(r))return}await Ge(e.socketPath,{force:!0}),await Ge(e.pidPath,{force:!0})}async function Er(e){let t=await Oa(e).catch(()=>null);return t?(t.end(),!0):!1}async function Ma(e){await La(e,{id:1,type:"shutdown"}).catch(()=>null)}async function Om(e){let t=await ws(e.pidPath,"utf8").catch(()=>null),r=Number(t?.trim());if(!Number.isInteger(r)||r<=0||!Fa(r)){await Ge(e.socketPath,{force:!0});return}try{process.kill(r,"SIGTERM")}catch{await Ge(e.socketPath,{force:!0})}}async function Fm(e){return La(e,{id:1,type:"ping"})}function La(e,t){return new Promise((r,n)=>{let s=va(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)}
|
|
155
130
|
`)),s.once("error",l=>{a(),n(l)}),s.on("data",l=>{o+=String(l);let d=o.indexOf(`
|
|
156
|
-
`);if(d===-1)return;let c=o.slice(0,d);a(),s.end();try{r(JSON.parse(c))}catch(u){n(u instanceof Error?u:new Error(String(u)))}}),s.once("close",()=>a())})}async function
|
|
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(
|
|
131
|
+
`);if(d===-1)return;let c=o.slice(0,d);a(),s.end();try{r(JSON.parse(c))}catch(u){n(u instanceof Error?u:new Error(String(u)))}}),s.once("close",()=>a())})}async function Ia(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!await Er(e))return;await ys(50)}}function Oa(e){return new Promise((t,r)=>{let n=va(e);n.once("connect",()=>t(n)),n.once("error",r)})}function jm(e,t){return new Promise((r,n)=>{e.once("error",n),e.listen(t,r)})}function He(e,t){if(!e.destroyed)try{e.write(`${JSON.stringify(t)}
|
|
132
|
+
`)}catch{}}function Fa(e){try{return process.kill(e,0),!0}catch{return!1}}function ys(e){return new Promise(t=>setTimeout(t,e))}function Nm(e){throw new Error(`Unhandled daemon request: ${JSON.stringify(e)}`)}var Ts=["Runners","Feature Previews","Error Log","Help"],Na={incrementalCenterPane:"Incremental center pane",agentActivityIndicators:"Agent activity indicators"};function Rs(e,t){return $.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 Wa(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 _a(e){return le.map(t=>`${f.previews.isEnabled(e,t)?"[x]":"[ ]"} ${Na[t]}`)}function Ba(e){return e.message??"Experimental features may change or be removed. Enter toggles."}function Ua(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Ts.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Ar(t)?e===0?{kind:"runners"}:e===1?{kind:"previews"}:e===2?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function qa(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(le.length-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(!Ar(r))return{kind:"noop",state:e};let n=le[e.menuIndex]??le[0],s=!f.previews.isEnabled(t,n);return{kind:"save-enabled",feature:n,enabled:s,state:{...e,message:`${Na[n]} ${s?"enabled":"disabled"}.`}}}function Va(e,t,r,n){if(e.pathEdit)return Wm({...e,pathEdit:e.pathEdit},t,r);let s=Rs(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=$[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:a,value:t.runners?.[a]?.path??""}}}}if(!Ar(r))return{kind:"noop",state:e};let 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 Wm(e,t,r){if(r==="ESCAPE")return{kind:"render",state:ja({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Ar(r)){let n=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save-path",runner:n,path:s.length>0?s:null,state:ja({...e,message:s.length>0?`${f.runners.getProfile(n).displayName} executable saved.`:`${f.runners.getProfile(n).displayName} executable reset to default.`})}}return _m(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function ja(e){let t={...e};return delete t.pathEdit,t}function Ar(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
133
|
+
`}function _m(e){return e.length===1&&e>=" "&&e!==""}import _t from"node:path";function Ka(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 Ha="\u{F024B} ",Ga="\u{F0DCF} ",za="\u25CB",bs="\uEA64",Ya="\uEAFE",Qa="\uEBDA",Ps="\u25CB",Ss="\u25CF",Is="\u2713",vs="\u2715";function Ja(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 Xa={idle:0,working:1,ready:2,error:3};function Wt(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 Cs(e,t,r,n){let s=e.ptyTabs.find(i=>i.kind==="agent")?.id,o=t===s&&e.runnerSession?.lastKnownState==="failed"?"error":"idle";return Wt(t,r,n,o)}function Es(e,t,r){let n="idle";for(let s of e.ptyTabs){if(s.kind!=="agent")continue;let o=Cs(e,s.id,t,r);Xa[o]>Xa[n]&&(n=o)}return n}function Za(e,t,r){return e.some(n=>n.ptyTabs.some(s=>s.kind==="agent"&&Wt(s.id,t,r)==="working"))}var Dr="empty",B={lineNumber:"3b4261",gutter:"3b4261",keyword:"9d7cd8",string:"9ece6a",literal:"ff9e64",comment:"565f89",markup:"f7768e",diffAdd:"9ece6a",diffDelete:"f7768e",diffMeta:"565f89",diffHunk:"565f89"};function nl(e,t,r){let n=qm(t,e),s=t.repos.find(R=>R.id===e.selectedRepoId)??t.repos[0]??null,o=n?t.tasks.filter(R=>R.workspaceId===n.id):t.tasks,i=n?.kind==="project"?o:s?o.filter(R=>R.repoId===s.id):[],a=i.find(R=>R.id===e.selectedTaskId)??i[0]??null,l=a?.type==="project",d=Sf(t.tasks),c=Hm(e,a),u=Km(e,a,c,r),m=u.find(R=>R.id===c)??u[0]??{id:"agent",label:"CODEX"},y=t.inspection?.taskId===a?.id?t.inspection:null,T=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`:Ot(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:_t.relative(process.env.HOME??"",t.workspaceRoot).length>0?`~/${_t.relative(process.env.HOME??"",t.workspaceRoot)}`:t.workspaceRoot,agent:h},leftTree:Bm(e,t,r),runners:(t.enabledRunnerIds??["codex","cursor","claude"]).map(R=>If(R,d[R])),centerHeader:{tabLabel:e.workspaceBrowser?"BROWSER":m.label,taskId:e.workspaceBrowser?"new workspace":a?.id??"no task",repo:T,agent:h},centerTranscript:Vm(c,e,s,a,e.workspaceBrowser,y,n),tabs:u,rightContext:Pf(s,a),rightInspection:of(e,a,y)}}function Bm(e,t,r){let n=[{text:"WORKSPACES",muted:!0,panelHeader:!0,focused:e.focusedRegion==="tasks"}];if(!t.workspaces)return Um(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}`,m=c.title.length>28?`${c.title.slice(0,25)}\u2026`:c.title,y={id:`task:${c.id}`,taskId:c.id,text:r?m:`${u?"\u25B8":"\u2022"} ${m}`,indent:2,selected:u,focused:u&&e.focusedRegion==="tasks",...r?{activity:Es(c,r.snapshots,r.now),activityAnimationFrame:r.animationFrame}:{}},T=ol(c);T&&(y.prBadge=T),n.push(y)}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(m=>m.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 Um(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}`,y=u.title.length>28?`${u.title.slice(0,25)}\u2026`:u.title,T={id:`task:${u.id}`,taskId:u.id,text:s?y:`${m?"\u25B8":"\u2022"} ${y}`,indent:2,selected:m,focused:m&&t.focusedRegion==="tasks",...s?{activity:Es(u,s.snapshots,s.now),activityAnimationFrame:s.animationFrame}:{}},h=ol(u);h&&(T.prBadge=h),e.push(T)}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 qm(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 Vm(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,m)=>{let y=m===s.selectedIndex?"\u25B8":" ",T=u.kind==="repo"?" [git repo]":"/";return`${y} ${u.name}${T}`}),c=s.query!==null?`Search: ${s.query}\u2588`:"";return ue(["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 ue(["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 ue([`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"?ue([`${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."]):ue([`${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"?Ym(n,o,t.fileScrollOffset):e===E&&t.openInspectionKind==="diff"?Qm(n,o,t.diffScrollOffset):n.ptyTabs.length===0&&!t.openInspectionKind?ue(["No task tabs open.","","Press a to create an agent tab, t to create a Terminal tab, or + to create the preferred tab kind."]):ue(["No center tab selected.","","Choose a task PTY tab or open an inspection item from the right panel."])}function Km(e,t,r,n){let s=t?.ptyTabs.map(i=>({id:i.id,label:Gm(i),...i.kind==="agent"&&n&&t?{activity:Cs(t,i.id,n.snapshots,n.now),activityAnimationFrame:n.animationFrame}:{}}))??[];if(!t)return[{id:Dr,label:"EMPTY",active:r===Dr,focused:e.focusedRegion==="center"&&r===Dr}];let o=e.openInspectionKind||r===E?[{id:E,label:zm(e)}]:[];return[...s,...o].map(i=>({...i,active:i.id===r,focused:e.focusedRegion==="center"&&i.id===r}))}function Hm(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:Dr}function Gm(e){return e.title.toUpperCase()}function zm(e){let t=e.openInspectionKind==="diff"?e.selectedDiffPath:e.selectedFilePath,r=t?_t.basename(t):e.inspectionMode.toUpperCase();return e.openInspectionKind==="diff"?`${r} \u0394`:r}function Ym(e,t,r){if(!e)return ue(["No task selected.","","Select or create a task to inspect files."]);if(!t||t.error)return ue(["Files unavailable.","",t?.error??"Craig has not loaded file inspection for this task yet."]);let n=t.selectedFile,s=sl(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:""},...Jm(n.lines,r,s)]}function Qm(e,t,r){if(!e)return ue(["No task selected.","","Select or create a task to inspect diffs."]);if(!t||t.error)return ue(["Diff unavailable.","",t?.error??"Craig has not loaded diff inspection for this task yet."]);let n=t.selectedDiff,s=sl(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:""},...Xm(n.lines,r,s)]}function ue(e){return e.map(t=>({text:t}))}function Jm(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:B.lineNumber}},{text:" \u2502 ",style:{fg:B.gutter}},...As(o,r)],tone:"default"}})}function Xm(e,t,r){let n=Zm(e),s=Math.max(0,Math.min(t,Math.max(0,n.length-1)));return n.slice(s).map(o=>ef(o,r))}function Zm(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 ef(e,t){let r=el(e.oldNumber),n=el(e.newNumber),s=e.kind==="delete"?r:n,o=e.kind==="delete"?{bg:"2a1111",fallbackFg:B.diffDelete}:e.kind==="add"?{bg:"10210f",fallbackFg:B.diffAdd}:null,i=`${s} \u2502 ${e.text}`,a=o?rf(As(e.text,t),o.bg,o.fallbackFg):As(e.text,t),l=o?{fg:B.lineNumber,bg:o.bg}:{fg:B.lineNumber},d=o?{fg:B.gutter,bg:o.bg}:{fg:B.gutter};return{text:i,segments:[{text:s,style:l},{text:" \u2502 ",style:d},...a],fullBleed:o!==null}}function el(e){return e===null?" ":String(e).padStart(4," ")}function sl(e){let t=_t.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 As(e,t){return t==="diff"?tf(e):t==="markdown"?nf(e):t==="json"?xs(e,/("(?:\\.|[^"\\])*")(\s*:)?|\b(true|false|null)\b|-?\b\d+(?:\.\d+)?\b/g):t==="javascript"||t==="css"?xs(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 tf(e){return e.startsWith("+")&&!e.startsWith("+++")?[{text:e,style:{fg:B.diffAdd}}]:e.startsWith("-")&&!e.startsWith("---")?[{text:e,style:{fg:B.diffDelete}}]:e.startsWith("@@")?[{text:e,style:{fg:B.diffHunk}}]:e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("+++ ")||e.startsWith("--- ")?[{text:e,style:{fg:B.diffMeta}}]:[{text:e}]}function rf(e,t,r){return e.map(n=>({text:n.text,style:{...n.style??{fg:r},bg:t}}))}function nf(e){return/^#{1,6}\s/.test(e)?[{text:e,style:{fg:B.markup,bold:!0}}]:xs(e,/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\([^)]+\))/g)}function xs(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:sf(o)}),n=i+o.length}return n<e.length&&r.push({text:e.slice(n)}),r.length>0?r:[{text:e}]}function sf(e){return e.startsWith("//")||e.startsWith("/*")?{fg:B.comment,italic:!0}:e.startsWith('"')||e.startsWith("'")||e.startsWith("`")?{fg:B.string}:/^-?\d/.test(e)||e==="true"||e==="false"||e==="null"||e==="undefined"?{fg:B.literal}:e.startsWith("**")||e.startsWith("[")||e.startsWith("`")?{fg:B.markup}:{fg:B.keyword}}function of(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"?il(t.repoTargets??[]):s?.pullRequest??(t?D(t):null),i=[af(e,o),{id:"mode-spacer",text:"",muted:!0}];if(e.inspectionMode==="review"){let a=cl(e,t),l=Ds(e,r),d=pf([{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,...Tf(e,r)]}:{title:"",rows:[...i,...Ds(e,r)]}}function af(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=$s(t),i=Ms(t);return s.push({text:" "},o,{text:" "},i),{id:"inspection-mode",text:s.map(l=>l.text).join(""),segments:s}}function tl(e){return[{text:" "},$s(e),{text:" "},Ms(e)]}function ol(e){if(e.type==="project"&&e.repoTargets?.length){let r=il(e.repoTargets);return r?tl(r):null}let t=D(e);return t?.number?tl(t):null}function il(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=cf(r);return{number:-1,status:lf(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 lf(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 cf(e){let t=e.map(r=>al(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 $s(e){return!e||!e.number?{text:za,style:{fg:"565f89"}}:e.status==="merged"?{text:Ya,style:{fg:"9d7cd8"}}:e.status==="closed"?{text:Qa,style:{fg:"f7768e"}}:e.status==="draft"||e.draft?{text:bs,style:{fg:"565f89"}}:{text:bs,style:{fg:"9ece6a"}}}function Ms(e){return e?.aggregateReadiness?rl(e.aggregateReadiness):rl(al(e))}function rl(e){return e==="failed"?{text:vs,style:{fg:"f7768e"}}:e==="pending"?{text:Ss,style:{fg:"e0af68"}}:e==="success"?{text:Is,style:{fg:"9ece6a"}}:{text:Ps,style:{fg:"565f89"}}}function al(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")?ll(e)?"failed":df(e)?"success":"pending":"pending"}function df(e){return!!(e.mergeable&&!e.draft&&!ll(e)&&e.requiredChecks.length>0&&e.requiredChecks.every(t=>t.status==="success"||t.status==="skipped"))}function ll(e){return e.reviewDecision==="REVIEW_REQUIRED"||e.reviewDecision==="CHANGES_REQUESTED"||e.mergeStateStatus==="REVIEW_REQUIRED"}function cl(e,t){if(!t)return[{id:"review-empty",text:"No task selected.",muted:!0}];if(t.type==="project"&&t.repoTargets?.length)return uf(e,t);let r=D(t),n=ul("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 xr=32;function uf(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,m=xr-u.length-1,y=d.length>m?d.slice(0,m-1)+"\u2026":d,T=xr-y.length-u.length;r.push({id:`project-review:${i.repoId}`,text:y+" ".repeat(Math.max(1,T))+u,selected:a,focused:l,muted:!0})}else{let c=$s(i.pullRequest),u=Ms(i.pullRequest),m=`${c.text} ${u.text}`,y=xr-m.length-1,T=d.length>y?d.slice(0,y-1)+"\u2026":d,h=xr-T.length-m.length,R=T+" ".repeat(Math.max(1,h));r.push({id:`project-review:${i.repoId}`,text:R+m,selected:a,focused:l,segments:[{text:R},{...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(...ul("target",o.branch,o.pullRequest))),r}function dl(e,t,r=null){return 3+cl(e,t).length+Ds(e,r).length}function ul(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=mf(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:ff(r.reviewDecision,r.mergeStateStatus)}}]}):s.push({id:n("pr-merge"),text:d,muted:!0}),s.push({id:n("pr-synced"),text:`synced ${pl(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(gf)):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,m)=>hf(u,n(`comment:${m}`))))),s}function pf(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 mf(e,t){return e==="CHANGES_REQUESTED"?"review changes requested":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"review required":e==="APPROVED"?"review approved":null}function ff(e,t){return e==="CHANGES_REQUESTED"?"f7768e":e==="APPROVED"?"9ece6a":e==="REVIEW_REQUIRED"||t==="REVIEW_REQUIRED"?"e0af68":"565f89"}function pl(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 gf(e){let{icon:t,color:r}=kf(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," ")} ${yf(e.status)}`,color:r,muted:!1}}function hf(e,t){let r=e.author??"unknown",n=e.createdAt?` \xB7 ${pl(e.createdAt)}`:"",s=wf(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 wf(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 kf(e){switch(e){case"success":return{icon:Is,color:"9ece6a"};case"pending":return{icon:Ss,color:"e0af68"};case"failed":return{icon:vs,color:"f7768e"};case"skipped":return{icon:Ps,color:"565f89"};default:return{icon:"?",color:"565f89"}}}function yf(e){return e==="success"?"passing":e==="failed"?"failing":e}function Tf(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=Ls(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)?Ha:Ga:Ka(l.label),m=l.kind==="directory"?"7aa2f7":Ja(l.label),y=" ".repeat(l.depth),T=m?{text:u,style:{fg:m}}:{text:u},h=l.kind==="directory"?{text:l.label,style:{fg:"7aa2f7"}}:c?{text:l.label,style:{fg:c}}:{text:l.label},R=[{text:y},T,h];return{id:l.path,text:`${y}${u}${l.label}`,selected:l.path===a,focused:l.path===a&&e.focusedRegion==="inspector",segments:R}})]}function Ls(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 Ds(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(Rf(t))return bf(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=>ml(o,e,t))))}return r}function Rf(e){return e.filePaths.some(t=>t.startsWith("repo_"))||e.diffRows.some(t=>t.path.startsWith("repo_"))}function bf(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=>ml(d,e,t,s.length+1))))}}return r}function ml(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 Pf(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:_t.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 Sf(e){return e.reduce((t,r)=>(t[r.runner]+=1,t),{codex:0,cursor:0,claude:0})}function If(e,t){return{name:f.runners.getDisplayName(e).toLowerCase(),health:t>0?1:0,count:String(t)}}function fl(e,t,r,n,s=null){if(s)return vf(e,t,r,n,s);let o=ns(e,t,{centerOnly:n});return Cf(r,o)?{output:Ir(o.rows,r.rows,o.row,o.column),region:o}:null}function vf(e,t,r,n,s){let o=Zi(e,t,s,{centerOnly:n});if(!o||!Ef(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 Cf(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rows.length}function Ef(e,t){return e.row===t.row&&e.column===t.column&&e.width===t.width&&e.rows.length===t.rowCount}function gl(e,t,r){let n={...e},s="";for(let o of r){let i=e[o],a=t[o];if(!Af(i,a))return null;!i||!a||(s+=Ir(a.rows,i.rows,a.row,a.column),n[o]=a)}return{output:s,regions:n}}function Af(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}import{appendFile as xf,mkdir as Df,readFile as $f}from"node:fs/promises";import Mf from"node:path";var hl=80,Os=async(e,t)=>{await Df(Mf.dirname(e.errorLogFile),{recursive:!0}),await xf(e.errorLogFile,Lf(t),"utf8")},wl=async(e,t)=>{try{await Os(e,t)}catch{}},Fs=async(e,t=hl)=>{try{let n=(await $f(e.errorLogFile,"utf8")).trimEnd().split(`
|
|
134
|
+
`).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(Of(r))return{path:e.errorLogFile,lines:[],empty:!0};throw r}},kl=async(e,t=hl)=>Fs(e,t);function Lf(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
135
|
`).map(n=>` ${n}`))),`${r.join(`
|
|
161
136
|
`)}
|
|
162
137
|
|
|
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!==`
|
|
138
|
+
`}function Of(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"&&e.code==="ENOENT"}var pt={appendErrorLog:Os,appendErrorLogBestEffort:wl,readErrorLog:Fs,readRecentErrorLines:kl};var Ff=["tasks","center","inspector"];function jf(e,t,r){if(t==="ESCAPE")return k({state:{...e,fileSearchQuery:null},changed:!0});if(t==="BACKSPACE"||t==="DELETE"){let n=e.fileSearchQuery??"";return k({state:{...e,fileSearchQuery:n.slice(0,-1)},changed:!0})}if(t==="UP"||t==="k"||t==="DOWN"||t==="j")return Ns(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 k({state:{...e,fileSearchQuery:n},changed:!0})}return k({state:e})}function _s(e,t,r={leftItemIds:[]}){if(e.inputMode==="terminal")return Wi(t)?k({state:{...e,inputMode:"control",centerZoomed:!1,actionMessage:null,focusedRegion:"center"},changed:!0,detachTerminal:!0}):k({state:e});if(e.fileSearchQuery!==null)return jf(e,t,r);if(t==="/"&&e.focusedRegion==="inspector"&&e.inspectionMode==="files")return k({state:{...e,fileSearchQuery:""},changed:!0});if(t==="q"||t==="Q")return k({state:e,exit:!0});if(t==="ESCAPE")return k({state:{...e,actionMessage:null},changed:e.actionMessage!==null,pause:!0});if(t==="n"||t==="N")return k({state:{...e,focusedRegion:"tasks",actionMessage:null,taskPromptInput:"",taskPromptError:null},changed:!0,beginTaskPrompt:!0});if((t==="r"||t==="R")&&e.focusedRegion==="tasks"&&(mr(e.selectedLeftItemId)||fr(e.selectedLeftItemId)))return k({state:{...e,selectedRunner:pr(e.selectedRunner,r.enabledRunnerIds),actionMessage:null,taskPromptError:null},changed:!0});if(t==="TAB"||t==="]")return yl(e,1);if(t==="SHIFT_TAB"||t==="[")return yl(e,-1);if(t==="z"||t==="Z")return k({state:{...e,centerZoomed:!e.centerZoomed,actionMessage:null},changed:!0});if(t==="UP"||t==="k")return e.focusedRegion==="center"&&e.activeTab===E?$e(e,-1,r):Ns(e,-1,r);if(t==="DOWN"||t==="j")return e.focusedRegion==="center"&&e.activeTab===E?$e(e,1,r):Ns(e,1,r);if(t==="PAGE_UP")return $e(e,-(r.pageRows??10),r);if(t==="PAGE_DOWN")return $e(e,r.pageRows??10,r);if(t==="MOUSE_WHEEL_UP")return $e(e,-3,r);if(t==="MOUSE_WHEEL_DOWN")return $e(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 k({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=Kf(e,t);return k({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 k({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0});if(t==="o"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review"&&e.selectedTaskId)return k({state:e,openPrUrl:!0});if(t==="X"&&e.focusedRegion==="inspector"&&e.inspectionMode==="review")return k({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Ot(e.selectedLeftItemId)&&e.selectedTaskId)return k({state:{...e,selectedActionId:"close-task",actionMessage:null},changed:!0,closeTask:!0});if(t==="X"&&e.focusedRegion==="tasks"&&Vi(e.selectedLeftItemId)&&e.selectedWorkspaceId)return k({state:{...e,actionMessage:null},changed:!0,removeWorkspace:!0});if(t==="x"&&e.focusedRegion==="center"&&bl(e.activeTab,r.ptyTabIds??[]))return k({state:{...e,actionMessage:null},changed:!0,closePtyTab:!0});if(t==="LEFT"||t==="h"){if(e.focusedRegion==="center")return js(e,-1,r.centerTabIds);if(e.focusedRegion==="inspector")return Tl(e,-1)}if(t==="RIGHT"||t==="l"){if(e.focusedRegion==="center")return js(e,1,r.centerTabIds);if(e.focusedRegion==="inspector")return Tl(e,1)}if(ce(t)){if(e.focusedRegion==="tasks"&&(mr(e.selectedLeftItemId)||fr(e.selectedLeftItemId))){let n=Qn(e.selectedLeftItemId),s=Jn(e.selectedLeftItemId);return k({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 k({state:{...e,actionMessage:null},changed:!0,openWorkspaceBrowser:!0});if(e.focusedRegion==="tasks"&&Ot(e.selectedLeftItemId)&&e.selectedTaskId){let n=e.selectedPtyTabId??e.activeTab;return k({state:{...e,inputMode:"terminal",focusedRegion:"center",activeTab:n,selectedPtyTabId:n,preferredPtyTabKind:ct(n)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0})}if(e.focusedRegion==="center"&&bl(e.activeTab,r.ptyTabIds??[])&&e.selectedTaskId)return k({state:{...e,inputMode:"terminal",selectedPtyTabId:e.activeTab,preferredPtyTabKind:ct(e.activeTab)??e.preferredPtyTabKind,actionMessage:null},changed:!0,attachTerminal:!0});if(e.focusedRegion==="center"&&e.activeTab===E)return k({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 k({state:_f({...e,selectedFileTreePath:n}),changed:!0});let s=n&&(r.fileTreeFileIds??[]).includes(n)?n:e.selectedFilePath;return k({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?k({state:{...e,selectedDiffPath:n,activeTab:E,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.selectedActionId==="close-task"&&!r.projectTargetIds?.length?k({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):k({state:{...e,selectedActionId:"refresh-checks",actionMessage:null},changed:!0,refreshPullRequestChecks:!0})}return e.focusedRegion!=="actions"?k({state:e}):e.selectedActionId==="refresh-checks"?k({state:{...e,actionMessage:null},changed:!0,refreshPullRequestChecks:!0}):e.selectedActionId==="close-task"?k({state:{...e,actionMessage:null},changed:!0,closeTask:!0}):k({state:{...e,actionMessage:`Action queued: ${e.selectedActionId} (inspection surfaces land in phase 4.1).`},changed:!0})}return k({state:e})}function $e(e,t,r){if(t===0)return k({state:e});if(e.focusedRegion==="inspector")return e.inspectionMode==="files"?Pl(e,t,r):e.inspectionMode==="review"?Rl(e,"reviewScrollOffset",t,r.reviewRowCount??100,r.pageRows):k({state:e});if(e.focusedRegion==="center"&&e.activeTab===E){if(e.openInspectionKind==="file")return Rl(e,"fileScrollOffset",t,r.fileLineCount??0,r.pageRows);if(e.openInspectionKind==="diff")return Bf(e,t,r)}return k({state:e})}function yl(e,t){return $r(e,"focusedRegion",Ff,t)}function js(e,t,r){let n=$r(e,"activeTab",r&&r.length>0?r:Hf(e),t);return!n.changed||Bi(n.state.activeTab)?n:{...n,state:{...n.state,selectedPtyTabId:n.state.activeTab,preferredPtyTabKind:ct(n.state.activeTab)??n.state.preferredPtyTabKind}}}function Ns(e,t,r){if(e.focusedRegion==="tasks")return Nf(e,t,r.leftItemIds);if(e.focusedRegion==="center")return js(e,t,r.centerTabIds);if(e.focusedRegion==="inspector"){if(e.inspectionMode==="files")return Pl(e,t,r);if(r.projectTargetIds?.length){let s=Ws(e,"selectedProjectTargetId",r.projectTargetIds,t);return s.changed?{...s,state:{...s.state,reviewScrollOffset:0,selectedActionId:"refresh-checks"}}:s}let n=Ws(e,"selectedDiffPath",r.diffPathIds??[],t,!0);return n.changed?{...n,state:{...n.state,activeTab:E,openInspectionKind:"diff",diffScrollOffset:0},refreshInspection:!0}:$r(e,"selectedActionId",Li,t)}return $r(e,"selectedActionId",Hn,t)}function Nf(e,t,r){let n=Ws(e,"selectedLeftItemId",r,t);if(!n.changed)return n;let s=Yn(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=Qn(n.state.selectedLeftItemId);if(o)return{...n,state:{...n.state,selectedRepoId:o}};let i=Jn(n.state.selectedLeftItemId);return i?{...n,state:{...n.state,selectedWorkspaceId:i}}:n}function Wf(e,t){if(e.inspectionMode===t)return k({state:e});let r=t==="files"?"file":e.openInspectionKind,n=t==="files"?E:e.activeTab;return k({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 Tl(e,t){return Wf(e,Vf(e.inspectionMode,Gn,t))}function Pl(e,t,r){let n=r.fileTreeRowIds&&r.fileTreeRowIds.length>0?r.fileTreeRowIds:r.filePathIds??[];if(n.length===0)return k({state:e});let s=e.selectedFileTreePath??e.selectedFilePath??n[0]??null,o=n.indexOf(s??""),i=be(o===-1?0:o+t,0,n.length-1),a=n[i]??null;if(a===e.selectedFileTreePath)return k({state:e});let l=a!==null&&(r.fileTreeFileIds??r.filePathIds??[]).includes(a);return k({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 _f(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 Rl(e,t,r,n,s=10){let o=Math.max(0,n-Math.max(1,s)),i=be(e[t]+r,0,o);return i===e[t]?k({state:e}):k({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Bf(e,t,r){if(r.diffPathRanges&&r.diffPathRanges.length>0)return Uf(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=be(i,0,o);return c===e.diffScrollOffset?k({state:e}):k({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}let l=a.indexOf(e.selectedDiffPath);if(l===-1){let c=be(i,0,o);return c===e.diffScrollOffset?k({state:e}):k({state:{...e,diffScrollOffset:c,actionMessage:null},changed:!0})}if(t>0&&i>o){let c=a[l+1]??null;return c?k({state:{...e,selectedDiffPath:c,activeTab:E,openInspectionKind:"diff",diffScrollOffset:0,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===o?k({state:e}):k({state:{...e,diffScrollOffset:o,actionMessage:null},changed:!0})}if(t<0&&i<0){let c=a[l-1]??null;return c?k({state:{...e,selectedDiffPath:c,activeTab:E,openInspectionKind:"diff",diffScrollOffset:Number.MAX_SAFE_INTEGER,actionMessage:null},changed:!0,refreshInspection:!0}):e.diffScrollOffset===0?k({state:e}):k({state:{...e,diffScrollOffset:0,actionMessage:null},changed:!0})}let d=be(i,0,o);return d===e.diffScrollOffset?k({state:e}):k({state:{...e,diffScrollOffset:d,actionMessage:null},changed:!0})}function Uf(e,t,r){let n=r.diffLineCount??0,s=r.pageRows??10,o=Math.max(0,n-Math.max(1,s)),i=be(e.diffScrollOffset+t,0,o),a=qf(r.diffPathRanges??[],i)??e.selectedDiffPath;return i===e.diffScrollOffset&&a===e.selectedDiffPath?k({state:e}):k({state:{...e,diffScrollOffset:i,selectedDiffPath:a,actionMessage:null},changed:!0})}function qf(e,t){return e.find(r=>t>=r.start&&t<r.end)?.path??e.at(-1)?.path??null}function $r(e,t,r,n){let s=r.indexOf(e[t]),o=be(s+n,0,r.length-1),i=r[o];return!i||i===e[t]?k({state:e}):k({state:{...e,[t]:i,actionMessage:null},changed:!0})}function Ws(e,t,r,n,s=!1){if(r.length===0)return k({state:e});let o=r.indexOf(e[t]??r[0]??""),i=be(o===-1?0:o+n,0,r.length-1),a=r[i]??null;return a===e[t]?k({state:e}):k({state:{...e,[t]:a,actionMessage:null},changed:!0,refreshInspection:s})}function Vf(e,t,r){let n=t.indexOf(e);return t[be(n+r,0,t.length-1)]??e}function k(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 bl(e,t){return t.includes(e)}function Kf(e,t){return t==="a"||t==="A"?"agent":t==="t"||t==="T"?"terminal":ct(e.activeTab)??e.preferredPtyTabKind}function Hf(e){return[e.selectedPtyTabId,e.openInspectionKind?E:null].filter(t=>typeof t=="string")}function be(e,t,r){return Math.min(r,Math.max(t,e))}var Sl=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 se(n.paths,e.selectedTaskId),i=t??Gf(o,e.activeTab,e.preferredPtyTabKind),a=El(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"}`}}},Il=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 se(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 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}`}}},vl=async(e,t)=>{let r=e.selectedTaskId;r&&await t.queueTaskMutation(async()=>{let n=await se(t.paths,r);!n.ptyTabs.some(s=>s.id===e.activeTab)||n.selectedPtyTabId===e.activeTab||await P(t.paths,{...n,selectedPtyTabId:e.activeTab})})},Cl=async(e,t)=>{let r=e.ptyTabs.find(s=>s.kind==="agent")??null;if(r)return await t.queueTaskMutation(async()=>{let s=await se(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=El(e,"agent",void 0,t.config);return await t.queueTaskMutation(async()=>{let s=await se(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 Gf(e,t,r){return e.ptyTabs.find(n=>n.id===t)?.kind??r}function El(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(y=>y.id)),d=1,c=a;for(;l.has(c);)d+=1,c=`${a}-${d}`;let u=new Date().toISOString(),m=r&&r!==e.runner?r:void 0;return{id:c,kind:t,...m?{runner:m}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?f.runners.buildCommand(s,void 0,n):[],createdAt:u,updatedAt:u}}var mt=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}},Al=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();Ue(f.runners.getConfiguredProfile(n,s.config).executable,{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 mt(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}},xl=async(e,t,r)=>{await r.queueTaskMutation(async()=>{await r.taskService.markRunnerFailed(r.paths,e,t)})},Dl=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 se(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}`}}},$l=async(e,t)=>{await t.taskService.prs.discoverOrRefreshMany(t.paths,e)},Mr=async(e,t,r)=>{let n=t instanceof Error?t.message:String(t);await pt.appendErrorLogBestEffort(r.paths,{context:e,message:n,details:t instanceof Error?t.stack??t.message:String(t)})};var Ml=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 Ll=async(e,t,r)=>{let n=f.runners.setRunnerEnabled(r.config,e,t);return await f.save(r.paths,n),n},Ol=async(e,t,r)=>{let n=f.runners.setRunnerPath(r.config,e,t);return await f.save(r.paths,n),n},Fl=async(e,t,r)=>{let n=f.previews.setEnabled(r.config,e,t);return await f.save(r.paths,n),n};var zf=250;function Pe(e,t){return e.find(r=>r.id===t.selectedTaskId)??null}function ze(e,t){return Re(t,e.ptyRuntime.getViewState(ft(e,t)))}function ft(e,t){let r=Pe(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 ze(e,Ki(t,e.model))}function jl(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 Nl(e,t,r){return jl(e,t,r?{tone:"success",message:r}:null)}function j(e,t,r){return jl(e,t,{tone:"error",message:r})}function N(e,t,r,n){let s=r instanceof Error?r.message:n,o=r instanceof Error?r.stack??r.message:String(r);return pt.appendErrorLogBestEffort(e.paths,{context:t,message:s,details:o}),s}function O(e,t){if(!e.uiStateFile)return;e.runtimeState=ji(e.runtimeState,t);let r=e.runtimeState;e.persistQueue=e.persistQueue.then(()=>Se({uiStateFile:e.uiStateFile},r),()=>Se({uiStateFile:e.uiStateFile},r)),e.persistQueue.catch(()=>{})}function Yf(e,t){let r=e.taskMutationQueue.then(t,t);return e.taskMutationQueue=r.then(()=>{},()=>{}),r}function W(e){return{paths:e.paths,config:e.config,taskService:C,workspaceService:Z,queueTaskMutation:t=>Yf(e,t)}}function Bs(e,t){let r=Pe(e.model.tasks,t),n=e.model.inspection,s=n&&n.taskId===r?.id?n:null,i=t.focusedRegion==="inspector"||t.activeTab==="inspection"?Ls(s?.fileRows??[],t.collapsedFileTreePaths):[];return{leftItemIds:Ke(e.model),centerTabIds:qi(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:dl(t,r,s),pageRows:Math.max(5,oe(e.activeTerminal.width,e.activeTerminal.height).height-L.topRailHeight-9),enabledRunnerIds:e.enabledRunnerIds,projectTargetIds:r?.repoTargets?.map(a=>a.repoId)??[]}}async function Wl(e,t){await vl(t,W(e))}async function G(e){e.model=await Ae(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 _l(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 Lr(e,t){let r=++e.inspectionRefreshSequence,n=Xn(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 bi(n,s,a);if(r!==e.inspectionRefreshSequence)return;i={...e.model,inspection:l}}else if(i=await Ae(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)},O(e,e.state.shell),e.render())}function Bl(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)&&Lr(e,r).catch(n=>{let s=N(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()})},zf))}function Ul(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=$e(e.state.shell,r,Bs(e,e.state.shell));if(n.changed){if(n.refreshInspection){e.state={mode:"main",shell:g(e,n.state)},O(e,e.state.shell),e.render(),Lr(e,e.state.shell).catch(s=>{let o=N(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)},O(e,e.state.shell),e.render()}},16)))}function Us(e){e.pendingClear=!0,e.activeTerminal.fullscreen(!0)}async function qs(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 Vl(e){qs(e).catch(()=>{}).then(()=>{e.state.mode==="main"&&(e.state={mode:"main",shell:g(e,e.state.shell)},e.render())})}async function Kl(e,t){let r=g(e,t),n=Pe(e.model.tasks,r),s=ft(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 Re(r,o);let i=await e.ptyRuntime.ensureSession(n.id,s,xe(oe(e.activeTerminal.width,e.activeTerminal.height)));return Re({...r,inputMode:"control"},i)}function Vs(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 Ks(e,t){try{let r=g(e,t),n=Pe(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 ql(e,n),await G(e),s=n.selectedPtyTabId)}n&&!s&&(n=await ql(e,n),await G(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:Re({...o,inputMode:"terminal"},e.ptyRuntime.getViewState(s))},O(e,e.state.shell);let i=await e.ptyRuntime.ensureSession(o.selectedTaskId,s,xe(oe(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=De(s),e.lastTerminalKey=null,e.state={mode:"main",shell:Re({...o,inputMode:"terminal"},i)},O(e,e.state.shell)}catch(r){let n=N(e,"attach PTY",r,"Failed to start PTY.");t.selectedTaskId&&t.selectedPtyTabId&&De(t.selectedPtyTabId)&&(await Qf(e,t.selectedTaskId,n).catch(()=>{}),await G(e).catch(()=>{})),e.state={mode:"main",shell:j(e,Ni(g(e,t),n),n)},O(e,e.state.shell)}e.render()}async function Qf(e,t,r){await xl(t,r,W(e))}async function Hl(e,t,r,n){let s=g(e,t),{nextShell:o}=await Sl(s,r,n,W(e));return await G(e),g(e,{...s,...o})}async function Gl(e,t){let r=g(e,t),{closedTab:n,nextShell:s}=await Il(r,W(e));return e.ptyRuntime.disposeSession(n.id),await G(e),g(e,{...r,...s})}async function zl(e,t){let r=g(e,t),n=Ke(e.model),s=n.indexOf(r.selectedLeftItemId??""),{closedTabIds:o,nextShell:i}=await Dl(r,W(e));for(let a of o)e.ptyRuntime.disposeSession(a);return await G(e),g(e,{...r,...i,selectedLeftItemId:Jf(n,Ke(e.model),s)})}async function Yl(e,t){let r=g(e,t),{nextShell:n}=await Ml(r,W(e));return await G(e),g(e,{...r,...n})}async function ql(e,t){return Cl(t,W(e))}function Or(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:ze(e,e.state.shell)},e.render())},16))}function Jf(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 Jl(e,t,r){if(r?.aborted||e.state.mode!=="main")return;let n=Ql(e),s=t.takeDueTasks(e.model.tasks,n);if(s.length!==0)try{if(await $l(s,W(e)),r?.aborted||(e.lastBackgroundPrPollError=null,e.state.mode!=="main"))return;let o=await Ae(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),Ql(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,Mr("background PR polling",o,W(e)))}}function Ql(e){return e.state.mode!=="main"?{selectedTaskId:null,reviewVisible:!1}:{selectedTaskId:e.state.shell.selectedTaskId,reviewVisible:e.state.shell.inspectionMode==="review"}}async function Xl(e,t){let r=g(e,t),n=Pe(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 G(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 G(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,{...Nl(e,r,o),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:s})}var Xf={pendingForegroundMs:5e3,pendingBackgroundMs:15e3,stableForegroundMs:3e4,stableBackgroundMs:6e4,discoveryForegroundMs:6e4,discoveryBackgroundMs:18e4,rateLimitBaseMs:6e4,rateLimitMaxMs:15*6e4},Fr=class{scheduledTasks=new Map;now;intervals;minimumIntervalMs;rateLimitFailures=0;notBefore=0;constructor(t={}){this.minimumIntervalMs=Math.max(1e3,t.minimumIntervalMs??5e3),this.intervals={...Xf,...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 ge,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=Zf(t),s=t.id===r.selectedTaskId&&r.reviewVisible;if(n.length>0){let o=n.some(eg);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 Zf(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 eg(e){return e.requiredChecks.some(t=>t.status==="pending"||t.status==="unknown")}import og from"node:path";import{readdir as tg,stat as rg}from"node:fs/promises";import Zl from"node:path";async function ng(e){let t=await tg(e,{withFileTypes:!0}),r=[];for(let n of t){if(!n.isDirectory())continue;let s=Zl.join(e,n.name);r.push({name:n.name,path:s,kind:await sg(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 ec(e){if(!e.query)return e.entries;let t=e.query.toLowerCase();return e.entries.filter(r=>r.name.toLowerCase().includes(t))}async function tc(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 jr(e,t){let r=await ng(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 sg(e){let t=Zl.join(e,".git");return await rg(t).catch(()=>null)!==null}function rc(e){let t=e.state;return t.runnerOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}function nc(e){let t=e.state;return t.previewOptions??{menuIndex:t.menuIndex,message:t.optionsMessage}}async function ig(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 Al(t.selectedRepoId,t.selectedWorkspaceId,r,t.selectedRunner,W(e));n=s.task,_l(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??ca(n,"agent"),xe(oe(e.activeTerminal.width,e.activeTerminal.height)));e.suppressTerminalEnterOnAttach=De(o.selectedPtyTabId),e.state={mode:"main",shell:Re(o,i)},O(e,e.state.shell)}catch(s){s instanceof mt&&(n=s.task);let o=N(e,"create task",s,"Failed to create task.");n&&!(s instanceof mt)?(await P(e.paths,{...n,status:"draft",runnerSession:{...n.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:o}).catch(()=>{}),await G(e).catch(()=>{})):n&&(await P(e.paths,{...n,lastFailureReason:o}).catch(()=>{}),await G(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 ag(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(ce(t)){ig(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:pr(r.selectedRunner,e.enabledRunnerIds),taskPromptError:null})},e.render();return}_i(t)&&(e.state={mode:"main",shell:g(e,{...r,taskPromptInput:`${r.taskPromptInput}${t}`,taskPromptError:null})},e.render())}}function lg(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=ec(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"){jr(e,og.dirname(r.cwd)).catch(s=>{let o=N(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"||ce(t)){let s=n[r.selectedIndex]??null;if(!s)return;if((t==="RIGHT"||t==="l")&&(s.kind==="directory"||s.kind==="repo")){jr(e,s.path).catch(i=>{let a=N(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}=W(e);o.addWorkspace(e.paths,s.path).then(async i=>{await G(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},O(e,e.state.shell),e.render()}).catch(i=>{let a=N(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 cg(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="options")return;let r=Ua(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;dg(e,n)}}}async function dg(e,t){let r;try{r=await pt.readRecentErrorLines(e.paths)}catch(n){let s=N(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 ug(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="runners")return;let r=Va(rc(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"?Ll(r.runner,r.enabled,W(e)):Ol(r.runner,r.path,W(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=N(e,"save runner option",s,"Failed to save runner option.");e.state={...e.state,shell:j(e,g(e,e.state.shell),o),runnerOptions:{...rc(e),message:o}},e.render()})}function pg(e,t){if(e.state.mode!=="overlay"||e.state.variant!=="previews")return;let r=qa(nc(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}Fl(r.feature,r.enabled,W(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=N(e,"save feature preview",n,"Failed to save feature preview.");e.state={...e.state,shell:j(e,g(e,e.state.shell),s),previewOptions:{...nc(e),message:s}},e.render()})}}function sc(e,t){let r=typeof t=="string"?t:"";if(e.state.mode==="main"&&e.state.shell.taskPromptInput!==null){ag(e,r);return}if(e.state.mode==="main"&&e.state.shell.workspaceBrowser!==null){lg(e,r);return}if(e.state.mode==="main"&&e.state.shell.inputMode==="control"){if(r==="F"){fg(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,Bs(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)},O(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)},O(e,e.state.shell),e.render();return}if(e.suppressTerminalEnterOnAttach&&ce(r)){e.suppressTerminalEnterOnAttach=!1;return}e.suppressTerminalEnterOnAttach&&(e.suppressTerminalEnterOnAttach=!1);let s=Nt(r);if(s){e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s);return}if(mg(e,r))return;e.lastTerminalKey=da(r)?{key:r,at:Date.now()}:null;let o=ua(r,e.state.shell.terminal.scrolledBack??!1);if(o!==0){Or(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)},O(e,e.state.shell),e.render();return}if(n.openWorkspaceBrowser){jr(e,e.workspaceRoot).catch(s=>{let o=N(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){Hl(e,n.state,n.createPtyTabKind,n.createPtyTabRunner).then(s=>{Ks(e,s)}).catch(s=>{let o=N(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){Gl(e,n.state).then(s=>{e.state={mode:"main",shell:s},O(e,e.state.shell),e.render()}).catch(s=>{let o=N(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){Xl(e,n.state).then(s=>{e.state={mode:"main",shell:s},O(e,e.state.shell),e.render()}).catch(s=>{let o=N(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=Pe(e.model.tasks,n.state),o=s?D(s)?.url??null:null;o?tc(o).catch(i=>{let a=N(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){zl(e,n.state).then(s=>{e.state={mode:"main",shell:s},O(e,e.state.shell),e.render()}).catch(s=>{let o=N(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){Yl(e,n.state).then(s=>{e.state={mode:"main",shell:s},O(e,e.state.shell),e.render()}).catch(s=>{let o=N(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){Ks(e,n.state);return}if(n.refreshInspection){if(e.state={mode:"main",shell:g(e,n.state)},O(e,e.state.shell),(e.state.shell.focusedRegion!=="tasks"||!e.renderTaskNavigation())&&e.render(),e.state.shell.focusedRegion==="tasks"){Bl(e,e.state.shell);return}Lr(e,e.state.shell).catch(s=>{let o=N(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)},Wl(e,e.state.shell).catch(()=>{}),O(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"){cg(e,r);return}if(e.state.variant==="runners"){ug(e,r);return}if(e.state.variant==="previews"){pg(e,r);return}if(e.state.variant==="error-log"){if(r==="ESCAPE"||ce(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"||ce(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(ce(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;Kl(e,s).then(o=>{e.state.mode!=="main"||e.state.shell!==s||(e.state={mode:"main",shell:o},O(e,e.state.shell),e.render())}).catch(o=>{if(e.state.mode!=="main"||e.state.shell!==s)return;let i=N(e,"warm selected PTY",o,"Failed to start selected PTY.");e.state={mode:"main",shell:j(e,g(e,e.state.shell),i)},O(e,e.state.shell),e.render()})}):Vl(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 oc(e,t){let r=ha(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=Nt(o);if(i){ac(e),e.suppressTerminalEnterOnAttach=!1,e.lastTerminalKey={key:i,at:Date.now()},e.ptyRuntime.writeKey(i);return}if(ds(o)){e.pendingTerminalKeySequence.raw=o,ic(e);return}Nr(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"})},O(e,e.state.shell),e.render();return}let n=pa(r);if(n!==0){Or(e,n);return}let s=Nt(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
139
|
`&&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}
|
|
140
|
+
`&&(e.suppressTerminalEnterOnAttach=!1),ga(e.suppressTerminalEnterOnAttach,e.lastTerminalKey,r)){e.suppressTerminalEnterOnAttach=!1;return}e.ptyRuntime.write(r)}function mg(e,t){if(e.pendingTerminalKeySequence){let r=ma(t);if(r!==null){let n=`${e.pendingTerminalKeySequence.raw}${r}`,s=Nt(n);if(s)return ac(e),e.lastTerminalKey={key:s,at:Date.now()},e.ptyRuntime.writeKey(s),!0;if(ds(n))return e.pendingTerminalKeySequence.raw=n,ic(e),!0}return Nr(e),!1}return t!=="ESCAPE"?!1:(e.pendingTerminalKeySequence={raw:"\x1B",timer:setTimeout(()=>Nr(e),30)},!0)}function ic(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence.timer=setTimeout(()=>Nr(e),30))}function Nr(e){if(!e.pendingTerminalKeySequence)return;let t=e.pendingTerminalKeySequence;e.pendingTerminalKeySequence=null,clearTimeout(t.timer),e.ptyRuntime.write(t.raw)}function ac(e){e.pendingTerminalKeySequence&&(clearTimeout(e.pendingTerminalKeySequence.timer),e.pendingTerminalKeySequence=null)}function lc(e,t){if(e.state.mode!=="main")return;if(e.state.shell.inputMode==="control"){Ul(e,cs(t));return}let r=cs(t);r!==0&&Or(e,r)}function fg(e){e.focusFlashUntil=Date.now()+600,e.focusFlashTimer&&clearTimeout(e.focusFlashTimer),e.focusFlashTimer=setTimeout(()=>{e.focusFlashUntil=null,e.focusFlashTimer=null,e.render()},600)}var Wr=class{jobs=new Map;resolutionMs;now;onError;timer=null;abortController=null;constructor(t){this.resolutionMs=Hs(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:Hs(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=Hs(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 Hs(e,t){if(!Number.isFinite(e)||e<=0)throw new Error(`${t} must be a positive number.`);return e}var cc=1e3,wg=hg(import.meta.url),kg=wg("terminal-kit"),yg=kg.terminal;function zs(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function dc(e){return e.previewOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function Tg(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 uc(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=me(t),n=await f.load(r),s=f.runners.getEnabled(n),o=e.uiStateFile?await Je({uiStateFile:e.uiStateFile}):null,i=await Ae(t,void 0,s),a=Lt(Fi(o,n),i);i=await Ae(t,a,s);let l={current:i},d=()=>{},c=()=>{},u=()=>{},m={workspaceRoot:t,onUpdate:T=>d(T),onActivity:T=>c(T),onActivityRemoved:T=>u(T),resolveSessionSpec:(T,h)=>la(l.current,h,t)},y=e.ptyRuntime??await Ea({...m,paths:r,viewUpdateMode:f.previews.isEnabled(n,"incrementalCenterPane")?"incremental":"snapshot",activityEnabled:f.previews.isEnabled(n,"agentActivityIndicators")});return new Promise(T=>{let h=e.terminal??yg,R=null,U=null,K=null,re=null,I=null,we=0,gt=!1,Ye=new Map,_r=new Fr({minimumIntervalMs:(n.github?.watchIntervalSeconds??5)*1e3}),p,Me=new Wr({resolutionMs:f.previews.isEnabled(n,"agentActivityIndicators")?150:cc,onError:(w,M)=>Mr(`heartbeat job "${w}"`,M,W(p))});p={state:{mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Lt(a,i)},get model(){return l.current},set model(w){l.current=w},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:y,resolve:T,render:()=>{},renderTaskNavigation:()=>!1,exit:w=>T(w),setAgentActivityEnabled:w=>{Me.setResolutionMs(w?150:cc),p.ptyRuntime.setActivityEnabled?.(w)}},p.setAgentActivityEnabled(f.previews.isEnabled(n,"agentActivityIndicators")),d=w=>{p.state.mode==="main"&&(I=Tg(I,w),p.ptyRenderTimer||(p.ptyRenderTimer=setTimeout(()=>{p.ptyRenderTimer=null;let M=I;if(I=null,p.state.mode==="main"){let z=ze(p,p.state.shell);if(p.state={mode:"main",shell:z},!f.previews.isEnabled(p.config,"incrementalCenterPane")||!re||!U){p.render();return}let Y=oe(h.width,h.height),ht={...re,terminal:z.terminal},Oe=fl(Y,ht,U,z.centerZoomed,M?.kind==="rows"?M.rowIndices:null);if(!Oe){p.render();return}Oe.output.length>0&&h.noFormat(Oe.output),re=ht,U=Oe.region,K&&(K={...K,center:Oe.region}),R=null,h.hideCursor(!0)}},f.previews.isEnabled(p.config,"incrementalCenterPane")?0:50)))},c=w=>{p.state.mode==="main"&&f.previews.isEnabled(p.config,"agentActivityIndicators")&&De(w.tabId)&&Ye.get(w.tabId)!==Wt(w.tabId,[w],Date.now())&&p.render()},u=w=>{p.state.mode==="main"&&f.previews.isEnabled(p.config,"agentActivityIndicators")&&De(w)&&Ye.get(w)!=="idle"&&p.render()};let ke=w=>{let M=oe(h.width,h.height),z=f.previews.isEnabled(p.config,"agentActivityIndicators"),ae=z?p.ptyRuntime.getActivitySnapshots?.()??[]:[],Y=Date.now(),ht=nl(g(p,w.shell),p.model,z?{snapshots:ae,now:Y,animationFrame:we}:void 0);if(Ye.clear(),z)for(let mc of p.model.tasks)for(let Br of mc.ptyTabs)Br.kind==="agent"&&Ye.set(Br.id,Wt(Br.id,ae,Y));let Oe=Xi(M,ht,{centerOnly:w.shell.centerZoomed,focusFlashActive:p.focusFlashUntil!==null&&Date.now()<p.focusFlashUntil});return{data:ht,presentation:Oe}},Le=(w,M,z,ae)=>{if(!K)return!1;let Y=gl(K,M.regions,z);return Y?(Y.output.length>0&&h.noFormat(Y.output),re=w,K=Y.regions,U=Y.regions.center,R=ae?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;Vs(p),p.ptyRuntime.setViewedTab?.(ft(p,p.state.shell));let{data:w,presentation:M}=ke(p.state);return Le(w,M,["rail","left","center","footer"],!1)},p.render=()=>{Vs(p);let w=p.state;p.ptyRuntime.setViewedTab?.(w.mode==="main"?ft(p,w.shell):null);let M=oe(h.width,h.height),z,ae=null;if(w.mode==="main"){let Y=ke(w);if(ae=Y.presentation,z=ae.frame,f.previews.isEnabled(p.config,"incrementalCenterPane")&&!p.pendingClear&&Le(Y.data,ae,["rail","left","center","right","footer"],!0))return;re=Y.data,U=ae.center}else z=w.variant==="boot"?zi(M,{menuIndex:w.menuIndex,optionsMessage:w.optionsMessage,versionText:p.versionText,updateText:p.updateText}):w.variant==="pause"?Yi(M,{menuIndex:w.menuIndex,optionsMessage:w.optionsMessage,versionText:p.versionText,updateText:p.updateText}):w.variant==="options"?br(M,{menuIndex:w.menuIndex,optionsMenuItems:Ts}):w.variant==="runners"?br(M,{menuIndex:zs(w).menuIndex,optionsMenuItems:Rs(p.config,zs(w)),optionsMessage:Wa(zs(w)),optionsSubtitle:"Runners"}):w.variant==="previews"?br(M,{menuIndex:dc(w).menuIndex,optionsMenuItems:_a(p.config),optionsMessage:Ba(dc(w)),optionsSubtitle:"Feature Previews - Experimental"}):w.variant==="error-log"?Ji(M,{errorLogPath:w.errorLog?.path??r.errorLogFile,errorLogLines:w.errorLog?.lines??[]}):Qi(M),re=null,U=null,K=null;p.pendingClear&&(h.moveTo(1,1),h.eraseDisplayBelow(),p.pendingClear=!1,R=null),h.noFormat(wa(z,R)),R=z,K=ae?.regions??null,h.hideCursor(!0)};let Bt=w=>sc(p,w),Ut=w=>oc(p,w),qt=w=>lc(p,w),pc=()=>{process.stdout.off("resize",Ys),process.off("SIGCONT",Qs),h.removeListener("key",Bt),h.removeListener("unknown",Ut),h.removeListener("mouse",qt),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),Me.stop(),p.ptyRuntime.disposeAll(),h.grabInput(!1),h.hideCursor(!1),h.fullscreen(!1)};p.exit=w=>{pc(),T(w)};let Ys=()=>{Us(p),p.state.mode==="main"&&p.state.shell.inputMode==="terminal"&&(p.ptyRuntime.resize(xe(oe(h.width,h.height))),p.state={mode:"main",shell:ze(p,p.state.shell)}),p.render()},Qs=()=>{Us(p),p.state.mode==="main"&&p.state.shell.inputMode==="terminal"&&(p.ptyRuntime.resize(xe(oe(h.width,h.height))),p.state={mode:"main",shell:ze(p,p.state.shell)}),p.render()};process.stdout.on("resize",Ys),process.on("SIGCONT",Qs),h.grabInput(!0),p.inputCaptureMode="control",h.hideCursor(!0),h.fullscreen(!0),h.on("key",Bt),h.on("unknown",Ut),h.on("mouse",qt),Me.register({id:"github.pull-requests",intervalMs:1e3,run:w=>Jl(p,_r,w)}),Me.register({id:"agent.activity-indicators",intervalMs:150,run:()=>{if(!f.previews.isEnabled(p.config,"agentActivityIndicators")){we=0,gt=!1;return}let w=Date.now(),M=Za(p.model.tasks,p.ptyRuntime.getActivitySnapshots?.()??[],w);(M||gt)&&(we=(we+1)%6,p.state.mode==="main"&&p.render()),gt=M}}),Me.start(),f.version.checkForUpdate().then(w=>{w.updateAvailable&&w.latest&&(p.updateText=`Update available: v${w.latest}`,p.render())}),p.bootHydrationReady=qs(p).catch(()=>{}),p.render()})}async function Rg(){try{if(process.argv[2]==="__craig-daemon"){let i=process.argv[3]??process.cwd(),a=me(i);return await Aa(a),0}if(process.argv[2]==="__craig-daemon-shutdown"){let i=process.argv[3]??process.cwd(),a=me(i);return await xa(a),0}let e=uo(process.argv.slice(2)),t=process.cwd(),r=me(t),n={paths:r};if(e.mode==="interactive")return await uc({uiStateFile:r.uiStateFile,workspaceRoot:r.workspaceRoot});if(!e.command)throw new Error("Command mode requires a command.");let s=await yi(e.command,n),o=Ti(s);return o.length>0&&process.stdout.write(`${o}
|
|
166
141
|
`),0}catch(e){let t=e instanceof Error?e.message:"Unknown Craig error";return process.stderr.write(`${t}
|
|
167
|
-
`),1}}var
|
|
142
|
+
`),1}}var bg=await Rg();process.exit(bg);
|