craig-cli 0.7.1 → 0.7.2
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 +40 -16
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
Craig is a full-screen TUI that lets you run multiple AI agents across multiple repos at the same time — each in its own isolated git worktree, each with a live PTY, all from one terminal. Spin up Claude, Codex, and Cursor simultaneously. Watch them cook.
|
|
29
|
+
Craig is a full-screen TUI that lets you run multiple AI agents across multiple repos at the same time — each in its own isolated git worktree, each with a live PTY, all from one terminal. Spin up Claude, Codex, and Cursor simultaneously. Watch them cook. Inspect diffs and review state while the agent handles repo actions from its PTY.
|
|
30
30
|
|
|
31
31
|
it's like a game, except the PRs are real.
|
|
32
32
|
|
|
@@ -51,11 +51,11 @@ Craig writes all local state under `.craig/` — worktrees, logs, task records,
|
|
|
51
51
|
|
|
52
52
|
## Workflow
|
|
53
53
|
|
|
54
|
-
1. Press `n` to create a task — type a
|
|
55
|
-
2. Craig creates the branch, worktree, and agent tab automatically.
|
|
54
|
+
1. Press `n` to create a task — type a short task description, pick a runner, press `Enter`.
|
|
55
|
+
2. Craig creates the task record, branch, worktree, and agent tab automatically.
|
|
56
56
|
3. Press `Enter` on the task to attach its live PTY. `Ctrl+]` to return to control mode.
|
|
57
|
-
4.
|
|
58
|
-
5.
|
|
57
|
+
4. Give the runner its instructions in the agent PTY. The task description is Craig metadata; it is not pasted into the runner automatically.
|
|
58
|
+
5. Use the **Files**, **Changes**, and read-only **Review** inspector panels to check the diff, PR state, checks, and comments.
|
|
59
59
|
|
|
60
60
|
## Polyrepo support
|
|
61
61
|
|
|
@@ -71,31 +71,51 @@ craig
|
|
|
71
71
|
```
|
|
72
72
|
Global
|
|
73
73
|
? help
|
|
74
|
-
Esc pause
|
|
74
|
+
Esc pause
|
|
75
75
|
Tab, ] next panel
|
|
76
76
|
Shift+Tab, [ previous panel
|
|
77
|
+
Up/Down, j/k move selection
|
|
78
|
+
PgUp/PgDn, Wheel scroll focused inspection or terminal view
|
|
79
|
+
z zoom center panel
|
|
80
|
+
n new task
|
|
77
81
|
q quit
|
|
78
82
|
|
|
79
83
|
Navigation
|
|
80
|
-
Up/Down, j/k move selection
|
|
81
84
|
Left/Right, h/l switch tabs or inspector mode
|
|
82
85
|
|
|
83
86
|
Tasks
|
|
84
|
-
|
|
85
|
-
Enter
|
|
86
|
-
|
|
87
|
+
Enter on + New Task open task prompt
|
|
88
|
+
Enter on + New Workspace open workspace browser
|
|
89
|
+
Enter on task attach selected task PTY
|
|
90
|
+
r on + New Task cycle runner for next task
|
|
91
|
+
X on task close selected task
|
|
92
|
+
X on workspace remove selected workspace
|
|
87
93
|
|
|
88
94
|
Center panel
|
|
89
95
|
Enter attach PTY
|
|
90
|
-
+
|
|
96
|
+
+ create preferred tab kind
|
|
91
97
|
a new agent tab
|
|
92
98
|
t new terminal tab
|
|
99
|
+
r cycle runner for next agent tab
|
|
93
100
|
x close tab
|
|
94
|
-
z zoom center panel
|
|
95
101
|
|
|
96
102
|
Review
|
|
97
|
-
|
|
98
|
-
|
|
103
|
+
Enter refresh status or close task, depending on selected action
|
|
104
|
+
R refresh read-only PR/check state
|
|
105
|
+
o open tracked PR URL
|
|
106
|
+
X close task record
|
|
107
|
+
|
|
108
|
+
Task prompt
|
|
109
|
+
Ctrl+R cycle runner
|
|
110
|
+
Enter create task
|
|
111
|
+
Esc cancel
|
|
112
|
+
|
|
113
|
+
Workspace browser
|
|
114
|
+
Up/Down, j/k move selection
|
|
115
|
+
Right, l open directory
|
|
116
|
+
Left, h parent directory
|
|
117
|
+
Enter add selected path
|
|
118
|
+
Esc cancel
|
|
99
119
|
|
|
100
120
|
Terminal mode
|
|
101
121
|
Ctrl+] return to control mode
|
|
@@ -109,21 +129,25 @@ craig repo add <path>
|
|
|
109
129
|
craig repo list
|
|
110
130
|
craig repo remove <repo-id>
|
|
111
131
|
|
|
132
|
+
craig workspace add <path>
|
|
112
133
|
craig workspace list
|
|
134
|
+
craig workspace list --archived
|
|
113
135
|
craig workspace archive <workspace-id>
|
|
114
136
|
craig workspace restore <workspace-id>
|
|
115
137
|
craig workspace remove <workspace-id>
|
|
116
138
|
|
|
117
139
|
craig task new --repo <repo-id> [--runner codex|cursor|claude] "<task>"
|
|
140
|
+
craig task new --workspace <workspace-id> [--runner codex|cursor|claude] "<task>"
|
|
118
141
|
craig task list
|
|
142
|
+
craig task list --repo <repo-id>
|
|
119
143
|
craig task show <task-id>
|
|
120
144
|
craig task attach <task-id>
|
|
145
|
+
craig task focus <task-id>
|
|
146
|
+
craig task open <task-id>
|
|
121
147
|
craig task logs <task-id>
|
|
122
148
|
craig task diff <task-id>
|
|
123
149
|
craig task check <task-id>
|
|
124
150
|
craig task commit <task-id>
|
|
125
|
-
craig task pr <task-id> [--watch]
|
|
126
|
-
craig task merge <task-id> [--preserve-worktree]
|
|
127
151
|
|
|
128
152
|
craig link add <task-id> <repo-id>
|
|
129
153
|
craig link list <task-id>
|
package/dist/cli.js
CHANGED
|
@@ -154,7 +154,7 @@ ${o.slice(-2e3)}`:""}`)}async function Ui(e){let t=await Ef(e).catch(()=>null);r
|
|
|
154
154
|
`)}function Xi(e,t={}){let n=t.color??!0,r=v.overlay,s=new Array(e.height).fill(O(" ".repeat(e.width),n,r)),o="Error Log",i=t.errorLogPath??"",c=t.errorLogLines??[],l=Math.max(20,e.width-8),d=Math.max(0,Math.floor((e.width-l)/2)),f=[{text:o,tone:"selected"},{text:i,tone:"muted"},ee(),...c.length>0?c.map(k=>({text:k})):[{text:"No Craig errors have been logged.",tone:"muted"}],ee(),{text:"Esc returns to Options.",tone:"muted"}],h=xt(f,e.height-2),R=Math.max(1,Math.floor((e.height-h.length)/2));for(let k=0;k<h.length;k+=1){let I=R+k;if(I>=e.height)break;let T=h[k]??ee(),a=`${" ".repeat(d)}${hn(T.text,l)}`,V=T.tone==="selected"?v.overlayMenuSelected:T.tone==="muted"?v.overlay:v.panelBg;s[I]=O(Se(a,e.width),n,V)}return s.join(`
|
|
155
155
|
`)}function Zi(e,t,n={}){let r=n.color??!0,s=he.leftWidth,o=he.rightWidth,i=he.dividerWidth,c=n.centerOnly??!1,l=c?e.width:e.width-s-o-i*2,d=e.height-he.topRailHeight-1,f=n.focusFlashActive??!1,h={bg:v.divider.bg,fg:"9ece6a"},R=f&&(t.focusedRegion==="tasks"||t.focusedRegion==="center")?h:v.divider,k=f&&(t.focusedRegion==="center"||t.focusedRegion==="inspector")?h:v.divider,I=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,T=O(Se(I,e.width),r,v.rail),a=Bf(t,s-fn-pn,d,r),V=Uf(t,l,d,r),j=Kf(t,o,d,r),te=t.inputMode==="terminal",C=[];for(let X=0;X<d;X+=1){if(c){C.push(un(V[X]??ee(),l,r,"center"));continue}let $e=un(a[X]??ee(),s,r,"left"),we=O("\u2502",r,R),De=un(V[X]??ee(),l,r,"center"),ne=O("\u2502",r,k),Qe=un(j[X]??ee(),o,r,"right");C.push(`${$e}${we}${De}${ne}${Qe}`)}let Ne=te||t.modalInput?v.panelBg:v.panelMuted,Ae=_f(t.footerText,t.footerToast,e.width,r,Ne);return[T,...C,Ae].join(`
|
|
156
156
|
`)}function _f(e,t,n,r,s){let o=` ${e}`;if(!t)return O(Se(o,n),r,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,c=Q(i),l=Q(o),d=Math.max(1,n-l-c-2),f=l+d+c+2>n?hn(o,Math.max(0,n-c-3)):o,h=Math.max(1,n-Q(f)-c-2),R=t.tone==="error"?lp(i,r,s):at(i,r,s),k=`${f}${" ".repeat(h)}${R} `;return O(Se(k,n),r,s)}function Fr(e,t){let n=new Array(e.height).fill(O(" ".repeat(e.width),t.color,v.overlay)),r=Dr(),s=Math.max(...t.menuItems.map(d=>d.length)),o=t.menuItems.map((d,f)=>`${f===t.menuIndex?">":" "} ${d.padEnd(s)}`),i=t.optionsMessage?["",t.optionsMessage]:[],c=[...r,"",t.subtitle,"",...o,...i],l=Math.max(1,Math.floor((e.height-c.length)/2));for(let d=0;d<c.length;d+=1){let f=na(c[d]??"",e.width);if(d<r.length){n[l+d]=O(f,t.color,v.overlayLogo);continue}if(d===r.length+1){n[l+d]=O(f,t.color,v.overlaySubtitle);continue}let h=d-(r.length+3),k=h>=0&&h<t.menuItems.length&&h===t.menuIndex?v.overlayMenuSelected:v.overlay;n[l+d]=O(f,t.color,k)}if(t.versionText){let d=t.updateText?" (update available)":"",f=`${t.versionText}${d} `,h=" ".repeat(Math.max(0,e.width-Q(f)));n[e.height-1]=O(`${h}${jr(f,t.color,v.overlay)}`,t.color,v.overlay)}return n.join(`
|
|
157
|
-
`)}function Bf(e,t,n,r){let s=Hf(e.runners),o=1,i=e.leftTree.map(l=>Gf(l,t,r));return[...xt(i,n-o),s]}function Uf(e,t,n,r){let s=t-2,o=e.tabs.find(C=>C.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:ip(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?at(l,r,v.panelBg):gn(l,r,v.panelMuted)}`,f=[`${gn(e.centerHeader.tabLabel,r,v.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(C=>C.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!li(h)?e.centerTranscript.map(C=>({...C})):qf(e),k=zf(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?at(`${I}\u25CF `,r,v.panelBg):"",V=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-Q(k)-T)):"",te=[{text:e.inputMode==="terminal"?`${k}${V}${a}`:k},{text:d,tone:"muted"},{text:f},ee(),...R];return xt(te,n)}function qf(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},ee(),{text:e.terminal.error},ee(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(r=>r.active)?.id??"",n=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${n.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(r=>({text:oa(r.segments),segments:r.segments,fullBleed:!0}))}function Kf(e,t,n,r){let s=e.rightInspection?Vf(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,n):xt([{text:"CONTEXT"},ee(),...e.rightContext.map(o=>Yf(o,r)),...e.actionMessage?[ee(),{text:e.actionMessage}]:[]],n);return xt(s,n)}function Vf(e,t){let n=e.slice(0,2),r=e.slice(2),s=Math.max(0,t-n.length),o=r.findIndex(c=>c.focused||c.selected),i=o===-1?0:cp(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Hi(c)),...r.slice(i,i+s).map(c=>Hi(c))]}function Hi(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",n=e.focused||e.selected?"selected":e.muted?"muted":"default",r=`${t}${e.text}`;if(e.segments)return{text:r,segments:[{text:t},...e.segments],tone:n};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:r,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:n}}return e.color?{text:r,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:n}:{text:r,tone:n}}function Gf(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${at("\u25CF",n,e.selected?v.panelSelected:v.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+Q(I.text),0):0,l=t-Q(o)-Q(s)-c,d=e.selected?e.text:e.focused?at(e.text,n,v.panelBg):e.panelHeader?gn(e.text,n,v.panelMuted):e.text,f=Se(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${f}${o}${i}`},...e.prBadge];return{text:`${f}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${f}${o}${i}`,tone:h}}function Hf(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:v.success.fg}}):n.push({text:s.text,style:{fg:v.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function zf(e,t,n){return e.map(r=>r.active?n?at(r.label,t,v.panelBg):gn(r.label,t,v.panelBg):jr(r.label,t,v.panelBg)).join(" ")}function Yf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?jr(e.value,t,v.panelBg):e.value}`}}function un(e,t,n,r){let s=Jf(r,e.tone??"default"),o=Qf(e,n,s);if(r==="left"){if(e.fullBleed)return O(Se(o,t),n,s);let c=t-fn-pn;if(e.rightAlign){let d=Q(o),f=Math.max(0,c-d),h=`${" ".repeat(fn)}${" ".repeat(f)}${o}${" ".repeat(pn)}`;return O(h,n,s)}let l=`${" ".repeat(fn)}${Se(o,c)}${" ".repeat(pn)}`;return O(l,n,s)}return r==="center"&&e.fullBleed?Xf(e,t,n,s):O(Se(` ${o}`,t),n,s)}function Jf(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function xt(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(ee());return n}function ee(){return{text:""}}function Qf(e,t,n){return e.segments?e.segments.map(r=>ea(r,t,n)).join(""):e.text}function Xf(e,t,n,r){let s=" ".repeat(mn),o=Math.max(0,t-mn*2);if(!e.segments)return O(`${s}${Se(e.text,o)}${s}`,n,r);let i=tp(e.segments,o),c=`${s}${i.map(l=>ea(l,n,r)).join("")}${s}${n?Lr:""}`;return O(c,n,r)}function ea(e,t,n){let r=e.href?`${ta(e.href)}${e.text}${Lr}`:Zf(e.text);return!t||!e.style?r:`${vt(sp(e.style,n))}${op(e.style)}${r}${Mr}${vt(n)}`}function Zf(e){return e.replace(Nf,t=>{let[n,r]=ep(t);return`${ta(n)}${n}${Lr}${r}`})}function ep(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ta(e){return`\x1B]8;;${e}\x1B\\`}function tp(e,t){let n=np(e,t);return rp(n,t)}function np(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=Q(s.text);if(o<=r){n.push(s),r-=o;continue}let i=hn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function rp(e,t){let n=Q(oa(e));if(n>=t)return e;let r=e.at(-1)?.style;return r?.bg?[...e,{text:" ".repeat(t-n),style:r}]:[...e,{text:" ".repeat(t-n)}]}function sp(e,t){let n=e.inverse?e.bg??t.bg:e.fg,r=e.inverse?e.fg??t.fg:e.bg,s={},o=n??t.fg,i=r??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function op(e){let t=[];return e.bold&&t.push("1"),e.dim&&t.push("2"),e.italic&&t.push("3"),e.underline&&t.push("4"),t.length>0?`\x1B[${t.join(";")}m`:""}function ip(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function na(e,t){let n=Math.max(0,t-Q(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Se(e,t){let n=Q(e);return n>=t?ap(e,t):e+" ".repeat(t-n)}function ap(e,t){if(t<=0)return"";if(Q(e)<=t)return e;let n=sa(e);return hn(n,Math.max(0,t-1))+"\u2026"}function Q(e){let t=0;for(let n of Array.from(sa(e)))t+=ra(n);return t}function hn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=ra(s);if(r+o>t)break;n+=s,r+=o}return n}function ra(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function cp(e,t,n){return Math.min(Math.max(e,t),n)}function sa(e){return e.replace(jf,"").replace(Of,"")}function oa(e){return e.map(t=>t.text).join("")}function O(e,t,n){if(!t)return e;let r=vt(n),s=e.replace(Ff,`${Mr}${r}`);return`${r}${s}${Mr}`}function vt(e){let t=[];return e.fg&&t.push(`38;2;${zi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${zi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function zi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function at(e,t,n){return wn(e,t,v.success.fg,n)}function lp(e,t,n){return wn(e,t,v.error.fg,n)}function gn(e,t,n){return wn(e,t,v.accent.fg,n)}function jr(e,t,n){return wn(e,t,v.mutedfg.fg,n)}function wn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${vt(s)}${e}${vt(r)}`}var dp="https://registry.npmjs.org/craig-cli/latest";var kn=null;function Nr(){try{return"0.7.1"}catch{return"unknown"}}async function ia(){let e=Nr(),t=Date.now();if(kn&&t-kn.cachedAt<36e5)return kn.result;let n=null;try{let s=await fetch(dp,{signal:AbortSignal.timeout(5e3)});s.ok&&(n=(await s.json()).version??null)}catch{}let r={current:e,latest:n,updateAvailable:n!==null&&n!==e&&up(n,e)};return kn={result:r,cachedAt:t},r}function up(e,t){let n=d=>d.split(".").map(Number),[r=0,s=0,o=0]=n(e),[i=0,c=0,l=0]=n(t);return r!==i?r>i:s!==c?s>c:o>l}ue();var Wr=["Runners","Error Log","Help"];function _r(e,t){return N.map(n=>{let r=Z(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function ca(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function la(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Wr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Br(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function da(e,t,n,r){if(e.pathEdit)return fp({...e,pathEdit:e.pathEdit},t,n);let s=_r(t,e).length;if(n==="UP"||n==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(n==="DOWN"||n==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(n==="ESCAPE")return{kind:"back",state:e};if(n==="e"){let c=N[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!Br(n))return{kind:"noop",state:e};let o=N[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&r.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:pp(t,o,!i),state:{...e,message:`${Z(o).displayName} ${i?"disabled":"enabled"}.`}}}function fp(e,t,n){if(n==="ESCAPE")return{kind:"render",state:aa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Br(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:mp(t,r,s.length>0?s:null),state:aa({...e,message:s.length>0?`${Z(r).displayName} executable saved.`:`${Z(r).displayName} executable reset to default.`})}}return gp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function pp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function mp(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function aa(e){let t={...e};return delete t.pathEdit,t}function Br(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
157
|
+
`)}function Bf(e,t,n,r){let s=Hf(e.runners),o=1,i=e.leftTree.map(l=>Gf(l,t,r));return[...xt(i,n-o),s]}function Uf(e,t,n,r){let s=t-2,o=e.tabs.find(C=>C.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:ip(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?at(l,r,v.panelBg):gn(l,r,v.panelMuted)}`,f=[`${gn(e.centerHeader.tabLabel,r,v.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(C=>C.active)?.id??"agent",R=e.centerHeader.tabLabel==="BROWSER"||!li(h)?e.centerTranscript.map(C=>({...C})):qf(e),k=zf(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?at(`${I}\u25CF `,r,v.panelBg):"",V=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-Q(k)-T)):"",te=[{text:e.inputMode==="terminal"?`${k}${V}${a}`:k},{text:d,tone:"muted"},{text:f},ee(),...R];return xt(te,n)}function qf(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},ee(),{text:e.terminal.error},ee(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(r=>r.active)?.id??"",n=t==="agent"||/:agent(?:-\d+)?$/.test(t)?"agent":"terminal";return e.terminal.rows.length===0?[{text:`Press Enter on the ${n.toUpperCase()} tab to attach a PTY.`}]:e.terminal.rows.map(r=>({text:oa(r.segments),segments:r.segments,fullBleed:!0}))}function Kf(e,t,n,r){let s=e.rightInspection?Vf(e.actionMessage?[...e.rightInspection.rows.slice(0,2),{id:"action-message",text:e.actionMessage},{id:"action-message-spacer",text:""},...e.rightInspection.rows.slice(2)]:e.rightInspection.rows,n):xt([{text:"CONTEXT"},ee(),...e.rightContext.map(o=>Yf(o,r)),...e.actionMessage?[ee(),{text:e.actionMessage}]:[]],n);return xt(s,n)}function Vf(e,t){let n=e.slice(0,2),r=e.slice(2),s=Math.max(0,t-n.length),o=r.findIndex(c=>c.focused||c.selected),i=o===-1?0:cp(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Hi(c)),...r.slice(i,i+s).map(c=>Hi(c))]}function Hi(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",n=e.focused||e.selected?"selected":e.muted?"muted":"default",r=`${t}${e.text}`;if(e.segments)return{text:r,segments:[{text:t},...e.segments],tone:n};if(e.accentPrefix&&!e.muted){let s=e.text.indexOf(" "),o=s===-1?e.text:e.text.slice(0,s),i=s===-1?"":e.text.slice(s);return{text:r,segments:[{text:t},{text:o,style:{fg:"7aa2f7"}},{text:i}],tone:n}}return e.color?{text:r,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:n}:{text:r,tone:n}}function Gf(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${at("\u25CF",n,e.selected?v.panelSelected:v.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+Q(I.text),0):0,l=t-Q(o)-Q(s)-c,d=e.selected?e.text:e.focused?at(e.text,n,v.panelBg):e.panelHeader?gn(e.text,n,v.panelMuted):e.text,f=Se(`${r}${d}`,Math.max(0,l)),h=e.selected?"selected":e.muted?"muted":"default";if(e.prBadge){let k=[{text:`${f}${o}${i}`},...e.prBadge];return{text:`${f}${o}${e.prBadge.map(T=>T.text).join("")}`,segments:k,tone:h}}return{text:`${f}${o}${i}`,tone:h}}function Hf(e){let t=e.map(r=>{let s=r.health>=1,o=parseInt(r.count,10),i=o>1?` (${o})`:"";return{text:`${s?"\u25CF":"\u25CB"} ${r.name}${i}`,active:s}}),n=[];for(let r=0;r<t.length;r++){let s=t[r];r>0&&n.push({text:" "}),s.active?n.push({text:s.text,style:{fg:v.success.fg}}):n.push({text:s.text,style:{fg:v.panelMuted.fg}})}return{text:t.map(r=>r.text).join(" "),segments:n,tone:"muted"}}function zf(e,t,n){return e.map(r=>r.active?n?at(r.label,t,v.panelBg):gn(r.label,t,v.panelBg):jr(r.label,t,v.panelBg)).join(" ")}function Yf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?jr(e.value,t,v.panelBg):e.value}`}}function un(e,t,n,r){let s=Jf(r,e.tone??"default"),o=Qf(e,n,s);if(r==="left"){if(e.fullBleed)return O(Se(o,t),n,s);let c=t-fn-pn;if(e.rightAlign){let d=Q(o),f=Math.max(0,c-d),h=`${" ".repeat(fn)}${" ".repeat(f)}${o}${" ".repeat(pn)}`;return O(h,n,s)}let l=`${" ".repeat(fn)}${Se(o,c)}${" ".repeat(pn)}`;return O(l,n,s)}return r==="center"&&e.fullBleed?Xf(e,t,n,s):O(Se(` ${o}`,t),n,s)}function Jf(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function xt(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(ee());return n}function ee(){return{text:""}}function Qf(e,t,n){return e.segments?e.segments.map(r=>ea(r,t,n)).join(""):e.text}function Xf(e,t,n,r){let s=" ".repeat(mn),o=Math.max(0,t-mn*2);if(!e.segments)return O(`${s}${Se(e.text,o)}${s}`,n,r);let i=tp(e.segments,o),c=`${s}${i.map(l=>ea(l,n,r)).join("")}${s}${n?Lr:""}`;return O(c,n,r)}function ea(e,t,n){let r=e.href?`${ta(e.href)}${e.text}${Lr}`:Zf(e.text);return!t||!e.style?r:`${vt(sp(e.style,n))}${op(e.style)}${r}${Mr}${vt(n)}`}function Zf(e){return e.replace(Nf,t=>{let[n,r]=ep(t);return`${ta(n)}${n}${Lr}${r}`})}function ep(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function ta(e){return`\x1B]8;;${e}\x1B\\`}function tp(e,t){let n=np(e,t);return rp(n,t)}function np(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=Q(s.text);if(o<=r){n.push(s),r-=o;continue}let i=hn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function rp(e,t){let n=Q(oa(e));if(n>=t)return e;let r=e.at(-1)?.style;return r?.bg?[...e,{text:" ".repeat(t-n),style:r}]:[...e,{text:" ".repeat(t-n)}]}function sp(e,t){let n=e.inverse?e.bg??t.bg:e.fg,r=e.inverse?e.fg??t.fg:e.bg,s={},o=n??t.fg,i=r??t.bg;return o&&(s.fg=o),i&&(s.bg=i),s}function op(e){let t=[];return e.bold&&t.push("1"),e.dim&&t.push("2"),e.italic&&t.push("3"),e.underline&&t.push("4"),t.length>0?`\x1B[${t.join(";")}m`:""}function ip(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function na(e,t){let n=Math.max(0,t-Q(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Se(e,t){let n=Q(e);return n>=t?ap(e,t):e+" ".repeat(t-n)}function ap(e,t){if(t<=0)return"";if(Q(e)<=t)return e;let n=sa(e);return hn(n,Math.max(0,t-1))+"\u2026"}function Q(e){let t=0;for(let n of Array.from(sa(e)))t+=ra(n);return t}function hn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=ra(s);if(r+o>t)break;n+=s,r+=o}return n}function ra(e){let t=e.codePointAt(0);return t===void 0||t===0||t<32||t>=127&&t<160||t>=768&&t<=879||t>=6832&&t<=6911||t>=7616&&t<=7679||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=8203&&t<=8207||t>=8288&&t<=8292||t===65279?0:t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=129791||t>=131072&&t<=262141)?2:1}function cp(e,t,n){return Math.min(Math.max(e,t),n)}function sa(e){return e.replace(jf,"").replace(Of,"")}function oa(e){return e.map(t=>t.text).join("")}function O(e,t,n){if(!t)return e;let r=vt(n),s=e.replace(Ff,`${Mr}${r}`);return`${r}${s}${Mr}`}function vt(e){let t=[];return e.fg&&t.push(`38;2;${zi(e.fg).join(";")}`),e.bg&&t.push(`48;2;${zi(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function zi(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function at(e,t,n){return wn(e,t,v.success.fg,n)}function lp(e,t,n){return wn(e,t,v.error.fg,n)}function gn(e,t,n){return wn(e,t,v.accent.fg,n)}function jr(e,t,n){return wn(e,t,v.mutedfg.fg,n)}function wn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${vt(s)}${e}${vt(r)}`}var dp="https://registry.npmjs.org/craig-cli/latest";var kn=null;function Nr(){try{return"0.7.2"}catch{return"unknown"}}async function ia(){let e=Nr(),t=Date.now();if(kn&&t-kn.cachedAt<36e5)return kn.result;let n=null;try{let s=await fetch(dp,{signal:AbortSignal.timeout(5e3)});s.ok&&(n=(await s.json()).version??null)}catch{}let r={current:e,latest:n,updateAvailable:n!==null&&n!==e&&up(n,e)};return kn={result:r,cachedAt:t},r}function up(e,t){let n=d=>d.split(".").map(Number),[r=0,s=0,o=0]=n(e),[i=0,c=0,l=0]=n(t);return r!==i?r>i:s!==c?s>c:o>l}ue();var Wr=["Runners","Error Log","Help"];function _r(e,t){return N.map(n=>{let r=Z(n),s=e.runners?.[n]?.enabled!==!1,o=e.runners?.[n]?.path?.trim(),i=t.pathEdit?.runner===n?`${t.pathEdit.value}_`:o&&o.length>0?o:`default (${r.executable})`;return`${r.displayName} ${s?"enabled":"disabled"} ${i}`})}function ca(e){return e.message?e.message:e.pathEdit?"Type an executable path. Enter saves. Empty resets to default. Esc cancels.":"Enter toggles. E edits the executable path."}function la(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Wr.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Br(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function da(e,t,n,r){if(e.pathEdit)return fp({...e,pathEdit:e.pathEdit},t,n);let s=_r(t,e).length;if(n==="UP"||n==="k")return{kind:"render",state:{...e,menuIndex:Math.max(0,e.menuIndex-1),message:null}};if(n==="DOWN"||n==="j")return{kind:"render",state:{...e,menuIndex:Math.min(s-1,e.menuIndex+1),message:null}};if(n==="ESCAPE")return{kind:"back",state:e};if(n==="e"){let c=N[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:c,value:t.runners?.[c]?.path??""}}}}if(!Br(n))return{kind:"noop",state:e};let o=N[e.menuIndex]??"codex",i=t.runners?.[o]?.enabled!==!1;return i&&r.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:pp(t,o,!i),state:{...e,message:`${Z(o).displayName} ${i?"disabled":"enabled"}.`}}}function fp(e,t,n){if(n==="ESCAPE")return{kind:"render",state:aa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Br(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:mp(t,r,s.length>0?s:null),state:aa({...e,message:s.length>0?`${Z(r).displayName} executable saved.`:`${Z(r).displayName} executable reset to default.`})}}return gp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function pp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function mp(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function aa(e){let t={...e};return delete t.pathEdit,t}function Br(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
158
158
|
`}function gp(e){return e.length===1&&e>=" "&&e!=="\x7F"}var Rp=hp(import.meta.url),Tp=Rp("terminal-kit"),yp=Tp.terminal;async function pa(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=Ce(t);await ot(t);let r=await Te(n),s=Ze(r),o=e.uiStateFile?await fe({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await Et(t,void 0,s),d=nn(si(o,r),l);l=await Et(t,d,s);let f=()=>{},h={workspaceRoot:t,onUpdate:()=>f(),resolveSessionSpec:(I,T)=>Sp(l,T,t)},R=e.ptyRuntime??await Wi({...h,paths:n}),k=I=>{if(!e.uiStateFile)return;o=oi(o,I);let T=o;i=i.then(()=>ae({uiStateFile:e.uiStateFile},T),()=>ae({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(I=>{let T=e.terminal??yp,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:nn(d,l)},V=!1,j=!1,te=null,C=0,Ne=0,Ae=null,X=null,$e=null,we=null,De=null,ne=null,Qe=null,yn=!1,Pn=null,qr=`Craig v${Nr()}`,bn=null,In=0,G=!0,Sn=null,y=()=>{},F=R;f=()=>{a.mode==="main"&&(a={mode:"main",shell:lt(a.shell)},$e||($e=setTimeout(()=>{$e=null,a.mode==="main"&&y()},50)))};function lt(m){return Ye(m,F.getViewState(Kr(m)))}function Kr(m){let u=Xe(m);return u?u.ptyTabs.some(p=>p.id===m.activeTab)?m.activeTab:m.activeTab==="agent"||m.activeTab==="terminal"?u.ptyTabs.find(p=>p.kind===m.activeTab)?.id??m.selectedPtyTabId:m.selectedPtyTabId:m.selectedPtyTabId}function P(m){return lt(Pp(m,l))}function Xe(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function Vr(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(p=>p.id));await F.pruneStale?.(m),await F.hydrateSessions?.(m)}function ha(){Vr().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function wa(m){let u=P(m),p=Xe(u),g=Kr(u);if(!p||!g||!p.ptyTabs.some(L=>L.id===g))return u;let w=F.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return Ye(u,w);let S=await F.ensureSession(p.id,g,$t(je(T.width,T.height)));return Ye({...u,inputMode:"control"},S)}function Gr(m,u){return we&&(clearTimeout(we),we=null),u?(we=setTimeout(()=>{we=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},600),{...m,footerToast:u}):{...m,footerToast:null}}function ka(m,u){return Gr(m,u?{tone:"success",message:u}:null)}function U(m,u,p){let g=u instanceof Error?u.message:p,w=u instanceof Error?u.stack??u.message:String(u);return ir(n,{context:m,message:g,details:w}),g}function q(m,u){return Gr(m,{tone:"error",message:u})}function We(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function Hr(m){let u=Xe(m),p=l.inspection,g=p&&p.taskId===u?.id?p:null,w=bp(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:Ip(l),centerTabIds:ui(u,m),ptyTabIds:u?.ptyTabs.map(S=>S.id)??[],filePathIds:g?.filePaths??[],fileTreeRowIds:w.map(S=>S.path),fileTreeFileIds:w.filter(S=>S.kind==="file").map(S=>S.path),fileTreeDirectoryIds:w.filter(S=>S.kind==="directory").map(S=>S.path),diffPathIds:g?.diffPaths??[],diffPathRanges:[],fileLineCount:g?.selectedFile.lines.length??0,diffLineCount:g?.selectedDiff.lines.length??0,reviewRowCount:Ci(m,u),pageRows:Math.max(5,je(T.width,T.height).height-he.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(S=>S.repoId)??[]}}async function Ra(m){await os(n,m),r=m,s=Ze(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:_e(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:_e(r)})}}async function Ta(m){let u=m.selectedTaskId;u&&await We(async()=>{let p=await _(n,u);!p.ptyTabs.some(g=>g.id===m.activeTab)||p.selectedPtyTabId===m.activeTab||await E(n,{...p,selectedPtyTabId:m.activeTab})})}async function re(){let m=(a.mode==="main",a.shell);l=await Et(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function zr(m){let u=++In,p=ma(l.tasks,m),g=l.inspection,w;if(p&&g?.taskId===p.id){let S={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},L=await Ao(p,g,S);if(u!==In)return;w={...l,inspection:L}}else if(w=await Et(t,m,s),u!==In)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function Cn(m){let u=await jp(m);a.mode==="main"&&(a={mode:"main",shell:P({...a.shell,workspaceBrowser:u,activeTab:a.shell.selectedPtyTabId??a.shell.activeTab,actionMessage:null})},y())}async function Yr(m){try{let u=P(m),p=Xe(u),g=u.selectedPtyTabId;if(p&&u.focusedRegion==="tasks"){let L=p.ptyTabs.find(de=>de.kind==="agent")??null;L?g=L.id:(p=await Jr(p),await re(),g=p.selectedPtyTabId)}p&&!g&&(p=await Jr(p),await re(),g=p.selectedPtyTabId);let w=P({...u,activeTab:g??u.activeTab,selectedPtyTabId:g,focusedRegion:g?"center":u.focusedRegion});if(!w.selectedTaskId||!g){a={mode:"main",shell:w},y();return}a={mode:"main",shell:Ye({...w,inputMode:"terminal"},F.getViewState(g))},k(a.shell);let S=await F.ensureSession(w.selectedTaskId,g,$t(je(T.width,T.height)));j=Ur(g),te=null,a={mode:"main",shell:Ye({...w,inputMode:"terminal"},S)},k(a.shell)}catch(u){let p=U("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Ur(m.selectedPtyTabId)&&(await ya(m.selectedTaskId,p).catch(()=>{}),await re().catch(()=>{})),a={mode:"main",shell:q(ai(P(m),p),p)},k(a.shell)}y()}async function ya(m,u){await We(async()=>{let p=await _(n,m);await E(n,{...p,status:p.status==="running"?"draft":p.status,runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:u})})}async function Pa(m,u,p){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await We(async()=>{let S=await _(n,g.selectedTaskId),L=u??vp(S,g.activeTab,g.preferredPtyTabKind),de=ua(S,L,p??void 0,r),dt={...S,ptyTabs:[...S.ptyTabs,de],selectedPtyTabId:de.id};return await E(n,dt),dt});return await re(),P({...g,activeTab:w.selectedPtyTabId??g.activeTab,selectedPtyTabId:w.selectedPtyTabId,preferredPtyTabKind:w.ptyTabs.at(-1)?.kind??g.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${w.ptyTabs.at(-1)?.title??"tab"}`})}async function ba(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:p,nextSelectedTab:g}=await We(async()=>{let w=await _(n,u.selectedTaskId),S=w.ptyTabs.findIndex(En=>En.id===u.activeTab);if(S===-1)throw new Error("Only PTY tabs can be closed.");let L=w.ptyTabs[S],de=w.ptyTabs.filter(En=>En.id!==L.id),dt=de[Math.min(S,de.length-1)]??de[S-1]??null;return await E(n,{...w,ptyTabs:de,selectedPtyTabId:dt?.id??null}),{closedTab:L,nextSelectedTab:dt}});return F.disposeSession(p.id),await re(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${p.title}`})}async function Ia(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let p=Xe(u),g=null,w=null;if(p?.type==="project"&&p.repoTargets?.length){let S=await zt(n,u.selectedTaskId);await re();let L=S.synced+S.discovered+S.notFound;w=`Refreshed ${S.synced}/${L} targets`}else{let{disposition:S,task:L}=await Jn(n,u.selectedTaskId);await re(),g=S==="not_found"?`No PR found for ${L.branch}`:null,S!=="not_found"&&(w=`Refreshed checks: ${K(L)?.requiredChecks.length??0} reported`)}return P({...ka(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function Sa(){if(yn||a.mode!=="main")return;let m=l.tasks;yn=!0;try{if(await co(n,m),Pn=null,a.mode!=="main")return;l=await Et(t,a.shell,s),a={mode:"main",shell:P(a.shell)},y()}catch(u){let p=u instanceof Error?u.message:"Background PR discovery failed.";p!==Pn&&(Pn=p,ir(n,{context:"background PR polling",message:p,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{yn=!1}}async function Ca(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:p,task:g}=await We(async()=>{let w=await _(n,u.selectedTaskId),S=await _o(n,u.selectedTaskId);return{taskBeforeClose:w,task:S}});for(let w of p.ptyTabs)F.disposeSession(w.id);return await re(),P({...u,selectedActionId:"close-task",actionMessage:g.cleanup.preservedWorktree?`Archived task ${g.id}; worktree preserved`:`Archived task ${g.id}`})}async function xa(m){let u=P(m);if(!u.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await be(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await Tt(n,u.selectedWorkspaceId);let g=await yt(n,u.selectedWorkspaceId);return await re(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function Jr(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await We(async()=>{let S=await _(n,m.id),L=S.ptyTabs.find(de=>de.kind==="agent")??null;L&&await E(n,{...S,selectedPtyTabId:L.id})}),w}let p=ua(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,p],selectedPtyTabId:p.id};return await We(async()=>{let w=await _(n,m.id),S=w.ptyTabs.find(L=>L.kind==="agent")??null;if(S){await E(n,{...w,selectedPtyTabId:S.id});return}await E(n,{...w,ptyTabs:[...w.ptyTabs,p],selectedPtyTabId:p.id})}),g}y=()=>{va();let m=je(T.width,T.height),u=a.mode==="main"?Zi(m,Ri(P(a.shell),l),{centerOnly:a.shell.centerZoomed,focusFlashActive:De!==null&&Date.now()<De}):a.variant==="boot"?Yi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:qr,updateText:bn}):a.variant==="pause"?Ji(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:qr,updateText:bn}):a.variant==="options"?Or(m,{menuIndex:a.menuIndex,optionsMenuItems:Wr}):a.variant==="runners"?Or(m,{menuIndex:At(a).menuIndex,optionsMenuItems:_r(r,At(a)),optionsMessage:ca(At(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Xi(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):Qi(m);G&&(T.moveTo(1,1),T.eraseDisplayBelow(),G=!1),T.noFormat(Ap(u)),T.hideCursor(!0)};function va(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==Sn&&(Sn=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let Ea=()=>{process.stdout.off("resize",ts),process.off("SIGCONT",ns),T.removeListener("key",Qr),T.removeListener("unknown",Xr),T.removeListener("mouse",Zr),Ae&&(clearTimeout(Ae),Ae=null),X&&(clearTimeout(X),X=null),$e&&(clearTimeout($e),$e=null),we&&(clearTimeout(we),we=null),ne&&(clearTimeout(ne),ne=null),Qe&&(clearInterval(Qe),Qe=null),F.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},xn=m=>{Ea(),I(m)},Aa=async()=>{if(a.mode!=="main"||V)return;let m=a.shell,u=m.taskPromptInput?.trim()??"";if(!m.selectedRepoId&&!m.selectedWorkspaceId){a={mode:"main",shell:P({...m,taskPromptError:"Select a workspace first."})},y();return}if(u.length===0){a={mode:"main",shell:P({...m,taskPromptError:"Task prompt cannot be empty."})},y();return}V=!0,a={mode:"main",shell:P({...m,actionMessage:`Creating ${m.selectedRunner} task in ${m.selectedWorkspaceId??m.selectedRepoId}...`})},y();let p=null;try{p=await Ep(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await re();let g=P({...a.shell,selectedRepoId:p.repoId,selectedWorkspaceId:p.workspaceId,selectedTaskId:p.id,selectedPtyTabId:p.selectedPtyTabId,selectedLeftItemId:`task:${p.id}`,activeTab:p.selectedPtyTabId??"agent",inputMode:"terminal",focusedRegion:"center",taskPromptInput:null,taskPromptError:null,actionMessage:null}),w=await F.ensureSession(p.id,g.selectedPtyTabId??ga(p,"agent"),$t(je(T.width,T.height)));j=Ur(g.selectedPtyTabId),a={mode:"main",shell:Ye(g,w)},k(a.shell)}catch(g){g instanceof Rn&&(p=g.task);let w=U("create task",g,"Failed to create task.");p&&(await E(n,{...p,status:"draft",runnerSession:{...p.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:w}).catch(()=>{}),await re().catch(()=>{})),a={mode:"main",shell:q(P({...a.shell,inputMode:"control",selectedTaskId:p?.id??a.shell.selectedTaskId,selectedPtyTabId:p?.selectedPtyTabId??a.shell.selectedPtyTabId,selectedLeftItemId:p?`task:${p.id}`:a.shell.selectedLeftItemId,activeTab:p?.selectedPtyTabId??a.shell.activeTab,taskPromptInput:p?null:"",taskPromptError:w,actionMessage:null}),w)}}finally{V=!1,y()}},$a=m=>{if(a.mode!=="main")return;let u=a.shell;if(u.taskPromptInput!==null){if(m==="ESCAPE"){a={mode:"main",shell:P({...u,taskPromptInput:null,taskPromptError:null,actionMessage:null})},y();return}if(Ee(m)){Aa();return}if(m==="BACKSPACE"){a={mode:"main",shell:P({...u,taskPromptInput:u.taskPromptInput.slice(0,-1),taskPromptError:null})},y();return}if(m==="CTRL_R"){a={mode:"main",shell:P({...u,selectedRunner:wr(u.selectedRunner,s),taskPromptError:null})},y();return}ci(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},Da=m=>{if(a.mode!=="main")return;let u=a.shell.workspaceBrowser;if(u){if(m==="ESCAPE"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,actionMessage:null})},y();return}if(m==="UP"||m==="k"){a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.max(0,u.selectedIndex-1),error:null}})},y();return}if(m==="DOWN"||m==="j"){let p=Math.max(0,u.entries.length-1);a={mode:"main",shell:P({...a.shell,workspaceBrowser:{...u,selectedIndex:Math.min(p,u.selectedIndex+1),error:null}})},y();return}if(m==="LEFT"||m==="h"){Cn(ct.dirname(u.cwd)).catch(p=>{let g=U("open parent workspace directory",p,"Failed to open parent directory.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Ee(m)){let p=u.entries[u.selectedIndex]??null;if(!p)return;if((m==="RIGHT"||m==="l")&&(p.kind==="directory"||p.kind==="repo")){Cn(p.path).catch(g=>{let w=U("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}Rt(n,p.path).then(async g=>{await re();let w=g.repos[0]??null;a={mode:"main",shell:P({...a.shell,workspaceBrowser:null,selectedLeftItemId:`workspace:${g.workspace.id}`,selectedWorkspaceId:g.workspace.id,selectedRepoId:w?.id??null,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${g.workspace.name??g.workspace.id}`})},k(a.shell),y()}).catch(g=>{let w=U("add workspace",g,"Failed to add workspace.");a={mode:"main",shell:q(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},Qr=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){$a(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){Da(u);return}if(a.mode==="main"&&a.shell.inputMode==="control"){if(u==="F"){Fa(),y();return}De!==null&&(De=null,ne&&(clearTimeout(ne),ne=null))}if(a.mode==="main"){let p=ii(a.shell,u,Hr(a.shell));if(p.exit){xn(0);return}if(p.detachTerminal){F.detach(),a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(a.shell.inputMode==="terminal"){if(p.changed){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(j&&Ee(u)){j=!1;return}j&&(j=!1),te=Dp(u)?{key:u,at:Date.now()}:null;let g=Mp(u,a.shell.terminal.scrolledBack??!1);if(g!==0){vn(g);return}F.writeKey(u);return}if(u==="CTRL_C"){xn(0);return}if(u==="?"&&a.shell.inputMode==="control"){a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell},G=!0,y();return}if(p.pause){a={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:P(p.state)},G=!0,y();return}if(p.beginTaskPrompt){a={mode:"main",shell:P(p.state)},k(a.shell),y();return}if(p.openWorkspaceBrowser){Cn(t).catch(g=>{let w=U("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:q(P({...p.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(p.createPtyTab){Pa(p.state,p.createPtyTabKind,p.createPtyTabRunner).then(g=>{Yr(g)}).catch(g=>{let w=U("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.closePtyTab){ba(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("close PTY tab",g,"Failed to close tab.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.refreshPullRequestChecks){Ia(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("refresh PR checks",g,"Failed to refresh PR checks.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.openPrUrl){let g=Xe(p.state),w=g?K(g)?.url??null:null;w?Np(w).catch(S=>{let L=U("open PR URL",S,"Failed to open PR in browser.");a={mode:"main",shell:q(P(p.state),L)},y()}):(a={mode:"main",shell:q(P(p.state),"No PR URL available.")},y());return}if(p.closeTask){Ca(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("close task",g,"Failed to close task.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.removeWorkspace){xa(p.state).then(g=>{a={mode:"main",shell:g},k(a.shell),y()}).catch(g=>{let w=U("remove workspace",g,"Failed to remove workspace.");a={mode:"main",shell:q(P({...p.state,actionMessage:w}),w)},y()});return}if(p.attachTerminal){Yr(p.state);return}if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),zr(a.shell).catch(g=>{let w=U("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:q(P({...a.shell,actionMessage:w}),w)},y()});return}p.changed&&(a={mode:"main",shell:P(p.state)},Ta(a.shell).catch(()=>{}),k(a.shell),y());return}if(a.variant==="help"){a.viaOptions&&a.parentVariant?a={mode:"overlay",variant:"options",menuIndex:2,optionsMessage:null,shell:a.shell,parentVariant:a.parentVariant}:a.parentVariant?a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell}:a={mode:"main",shell:P(a.shell)},G=!0,y();return}if(a.variant==="options"){Ma(u);return}if(a.variant==="runners"){Oa(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Ee(u)){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y()}return}if(a.optionsMessage){(u==="ESCAPE"||Ee(u))&&(a={...a,optionsMessage:null},y());return}if(u==="UP"||u==="k"){a={...a,menuIndex:Math.max(0,a.menuIndex-1)},y();return}if(u==="DOWN"||u==="j"){a={...a,menuIndex:Math.min(2,a.menuIndex+1)},y();return}if(u==="ESCAPE"){a.variant==="pause"&&(a={mode:"main",shell:P(a.shell)},G=!0,y());return}if(Ee(u)){if(a.menuIndex===0){let p=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},G=!0,y(),p?Wa.then(()=>{if(a.mode!=="main")return;let g=a.shell;wa(g).then(w=>{a.mode!=="main"||a.shell!==g||(a={mode:"main",shell:w},k(a.shell),y())}).catch(w=>{if(a.mode!=="main"||a.shell!==g)return;let S=U("warm selected PTY",w,"Failed to start selected PTY.");a={mode:"main",shell:q(P(a.shell),S)},k(a.shell),y()})}):ha();return}if(a.menuIndex===1){let p=a.variant==="boot"||a.variant==="pause"?a.variant:void 0;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}xn(0)}};function Ma(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=la(a.menuIndex,m);if(u.kind!=="noop"){if(u.kind==="render"){a={...a,menuIndex:u.menuIndex},y();return}if(u.kind==="back"){a.parentVariant&&(a={mode:"overlay",variant:a.parentVariant,menuIndex:1,optionsMessage:null,shell:a.shell},G=!0,y());return}if(u.kind==="help"){let p=a.parentVariant;a={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:a.shell,viaOptions:!0,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="runners"){let p=a.parentVariant;a={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="error-log"){let p=a.parentVariant;La(p)}}}async function La(m){let u;try{u=await vo(n)}catch(p){let g=U("open error log",p,"Failed to read Craig error log.");u={path:n.errorLogFile,lines:[`Unable to read error log: ${g}`],empty:!1}}a.mode==="overlay"&&(a={mode:"overlay",variant:"error-log",menuIndex:0,optionsMessage:null,shell:a.shell,errorLog:u,...m!==void 0?{parentVariant:m}:{}},G=!0,y())}function Oa(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=da(At(a),r,m,s);if(u.kind!=="noop"){if(u.kind==="back"){let p=a.parentVariant;a={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:a.shell,...p!==void 0?{parentVariant:p}:{}},G=!0,y();return}if(u.kind==="render"){a={...a,runnerOptions:u.state},y();return}Ra(u.config).then(()=>{a.mode!=="overlay"||a.variant!=="runners"||(a={...a,runnerOptions:u.state},y())}).catch(p=>{if(a.mode!=="overlay"||a.variant!=="runners")return;let g=U("save runner option",p,"Failed to save runner option."),w=q(P(a.shell),g);a={...a,shell:w,runnerOptions:{...At(a),message:g}},y()})}}function Fa(){De=Date.now()+600,ne&&clearTimeout(ne),ne=setTimeout(()=>{De=null,ne=null,y()},600)}let Xr=m=>{let u=$p(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){F.detach(),j=!1,te=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let p=Lp(u);if(p!==0){vn(p);return}let g=Op(u);if(g){j=!1,te={key:g,at:Date.now()},F.writeKey(g);return}if(j&&u!=="\r"&&u!==`
|
|
159
159
|
`&&u!==`\r
|
|
160
160
|
`&&(j=!1),Fp(j,te,u)){j=!1;return}F.write(u)},Zr=m=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){Na(fa(m));return}let u=fa(m);u!==0&&vn(u)};function vn(m){C+=m,!Ae&&(Ae=setTimeout(()=>{Ae=null;let u=C;C=0,u!==0&&(ja(u),y())},16))}function ja(m){F.scrollViewport(m),a={mode:"main",shell:lt(a.shell)}}function es(){G=!0,T.fullscreen(!0)}function Na(m){m!==0&&(Ne+=m,!X&&(X=setTimeout(()=>{X=null;let u=Ne;if(Ne=0,u===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let p=Fe(a.shell,u,Hr(a.shell));if(p.changed){if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),zr(a.shell).catch(g=>{let w=U("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:q(P({...a.shell,actionMessage:w}),w)},y()});return}a={mode:"main",shell:P(p.state)},k(a.shell),y()}},16)))}let ts=()=>{es(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(F.resize($t(je(T.width,T.height))),a={mode:"main",shell:lt(a.shell)}),y()},ns=()=>{es(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(F.resize($t(je(T.width,T.height))),a={mode:"main",shell:lt(a.shell)}),y()};process.stdout.on("resize",ts),process.on("SIGCONT",ns),T.grabInput(!0),Sn="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",Qr),T.on("unknown",Xr),T.on("mouse",Zr),Qe=setInterval(()=>{Sa()},(r.github?.watchIntervalSeconds??5)*1e3),ia().then(m=>{m.updateAvailable&&m.latest&&(bn=`Update available: v${m.latest}`,y())});let Wa=Vr().catch(()=>{});y()})}async function Et(e,t,n){let r=Ce(e),[s,o,i]=await Promise.all([Ge(r),me(r),be(r)]),c=ma(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=c?await $o(c,l):null;return{workspaceRoot:e,workspaces:o.filter(f=>f.status==="active"),repos:s,tasks:i.tasks,inspection:d,...n?{enabledRunnerIds:n}:{}}}function ma(e,t){return t?.selectedTaskId?e.find(n=>n.id===t.selectedTaskId)??null:null}function Pp(e,t){return nn(e,t)}function bp(e,t){let n=new Set(t);return e.filter(r=>{let s=r.path.split("/");for(let o=1;o<s.length;o+=1)if(n.has(s.slice(0,o).join("/")))return!1;return!0})}function Ip(e){let t=[];if(e.workspaces?.length)for(let n of e.workspaces){t.push(`workspace:${n.id}`);for(let r of e.tasks.filter(s=>s.workspaceId===n.id))t.push(`task:${r.id}`);n.kind==="project"&&t.push(`new-task-workspace:${n.id}`),n.kind==="repo"&&t.push(`new-task:${n.primaryRepoId}`)}else for(let n of e.repos){t.push(`repo:${n.id}`);for(let r of e.tasks.filter(s=>s.repoId===n.id))t.push(`task:${r.id}`);t.push(`new-task:${n.id}`)}return t.push("new-workspace"),t}function Sp(e,t,n){let r=e.tasks.find(c=>c.ptyTabs.some(l=>l.id===t))??null,s=r?.ptyTabs.find(c=>c.id===t)??null,o=r?.worktreePath??n,i=s?.kind==="agent"?xp(s):[];return r?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:Cp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function Cp(e,t){let n=(e??"").split(ct.delimiter).filter(r=>r.length>0);return n.includes(t)?n.join(ct.delimiter):[...n,t].join(ct.delimiter)}function xp(e){return e.command.length>0?e.command:["codex"]}function At(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function vp(e,t,n){return e.ptyTabs.find(r=>r.id===t)?.kind??n}function ua(e,t,n,r={}){let s=n??e.runner,o=Z(s),i=t==="agent"?o.defaultAgentTitle:"Terminal",c=t==="agent"&&n&&n!==e.runner?`${e.id}:${n}`:`${e.id}:${t}`,l=new Set(e.ptyTabs.map(k=>k.id)),d=1,f=c;for(;l.has(f);)d+=1,f=`${c}-${d}`;let h=new Date().toISOString(),R=n&&n!==e.runner?n:void 0;return{id:f,kind:t,...R?{runner:R}:{},title:d===1?i:`${i} ${d}`,command:t==="agent"?z(s,void 0,r):[],createdAt:h,updatedAt:h}}async function Ep(e,t,n,r,s){let o=await Te(e);Dt(s,o);let i=n?await Ut(e,n,r,{runner:s,config:o}):await gt(e,t??"",r,{runner:s,config:o});try{let d=Ke();await x(Ve(An(s,o).executable,{cwd:i.repoRoot,env:d}),["--help"],{cwd:i.repoRoot,env:d})}catch(d){let f=d instanceof Error?d.message:"Failed to start runner.",h={...i.task,status:"draft",runnerSession:{...i.task.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:f};throw await E(e,h),new Rn(f,h)}let c=ga(i.task,"agent"),l={...i.task,status:"running",selectedPtyTabId:c,runnerSession:{...i.task.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await E(e,l),await ae({uiStateFile:e.uiStateFile},{...await fe({uiStateFile:e.uiStateFile})??Pe(),version:1,selectedRepoId:l.repoId,selectedWorkspaceId:l.workspaceId,selectedTaskId:l.id,selectedPtyTabId:l.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:l.selectedPtyTabId??"agent",selectedActionId:"commit",updatedAt:new Date().toISOString()}),l}var Rn=class extends Error{task;constructor(t,n){super(t),this.name="InteractiveTaskStartupError",this.task=n}};function ga(e,t){let n=e.ptyTabs.find(r=>r.kind===t);if(!n)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return n.id}function $t(e){return{columns:Math.max(20,e.width-he.leftWidth-he.rightWidth-he.dividerWidth-mn*2),rows:Math.max(5,e.height-he.topRailHeight-5)}}function Ap(e){return e.split(`
|