craig-cli 0.2.0 → 0.2.1
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 +117 -15
- package/dist/cli.js +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<pre>
|
|
3
|
+
▄████▄ ██▀███ ▄▄▄ ██▓ ▄████
|
|
4
|
+
▒██▀ ▀█ ▓██ ▒ ██▒▒████▄ ▓██▒ ██▒ ▀█▒
|
|
5
|
+
▒▓█ ▄ ▓██ ░▄█ ▒▒██ ▀█▄ ▒██▒▒██░▄▄▄░
|
|
6
|
+
▒▓▓▄ ▄██▒▒██▀▀█▄ ░██▄▄▄▄██ ░██░░▓█ ██▓
|
|
7
|
+
▒ ▓███▀ ░░██▓ ▒██▒ ▓█ ▓██▒░██░░▒▓███▀▒
|
|
8
|
+
░ ░▒ ▒ ░░ ▒▓ ░▒▓░ ▒▒ ▓▒█░░▓ ░▒ ▒
|
|
9
|
+
░ ▒ ░▒ ░ ▒░ ▒ ▒▒ ░ ▒ ░ ░ ░
|
|
10
|
+
░ ░░ ░ ░ ▒ ▒ ░░ ░ ░
|
|
11
|
+
░ ░ ░ ░ ░ ░ ░
|
|
12
|
+
░
|
|
13
|
+
|
|
14
|
+
crAIg is that you?
|
|
15
|
+
</pre>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
1
18
|
# Craig
|
|
2
19
|
|
|
3
|
-
Craig is a local terminal control plane for repo-backed agent work.
|
|
20
|
+
Craig is a local terminal control plane for repo-backed agent work. The primary interface is the full-screen terminal UI launched with `craig`; command-mode entry points are available for automation and debugging.
|
|
4
21
|
|
|
5
22
|
## Install
|
|
6
23
|
|
|
@@ -10,42 +27,105 @@ npm install -g craig-cli
|
|
|
10
27
|
|
|
11
28
|
Craig requires Node 22 or newer.
|
|
12
29
|
|
|
13
|
-
|
|
30
|
+
External tools:
|
|
31
|
+
|
|
32
|
+
- `git` for repo, branch, and worktree operations
|
|
33
|
+
- `gh` authenticated with GitHub for PR, check, and merge flows
|
|
34
|
+
- an agent CLI such as Codex, Cursor, or Claude
|
|
35
|
+
|
|
36
|
+
## Start Craig
|
|
14
37
|
|
|
15
|
-
Run Craig from
|
|
38
|
+
Run Craig from the workspace where you want `.craig/` state to live:
|
|
16
39
|
|
|
17
40
|
```bash
|
|
18
|
-
cd path/to/your/
|
|
41
|
+
cd path/to/your/workspace
|
|
19
42
|
craig
|
|
20
43
|
```
|
|
21
44
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
The TUI opens with a boot overlay, then a workspace shell with task navigation, center work tabs, and an inspector panel.
|
|
46
|
+
|
|
47
|
+
Craig stores task records, worktrees, runtime UI state, logs, and review metadata under `.craig/`.
|
|
48
|
+
|
|
49
|
+
## TUI Workflow
|
|
50
|
+
|
|
51
|
+
1. Launch `craig`.
|
|
52
|
+
2. Add or select a workspace/repo from the left side. You can also pre-register one with `craig repo add <path>`.
|
|
53
|
+
3. Press `n` to create a task from the TUI.
|
|
54
|
+
4. Type the task prompt and press `Enter`.
|
|
55
|
+
5. Craig creates the branch, task worktree, and agent tab.
|
|
56
|
+
6. Press `Enter` on an agent or terminal tab to attach the live PTY.
|
|
57
|
+
7. Use `Ctrl+]` to return from terminal mode to Craig control mode.
|
|
58
|
+
8. Use the Files, Changes, and Review inspector modes to inspect work without leaving Craig.
|
|
59
|
+
|
|
60
|
+
## TUI Keys
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
Global
|
|
64
|
+
? help
|
|
65
|
+
Esc pause / back
|
|
66
|
+
Tab, ] next panel
|
|
67
|
+
Shift+Tab, [ previous panel
|
|
68
|
+
q quit
|
|
69
|
+
|
|
70
|
+
Navigation
|
|
71
|
+
Up/Down, j/k move selection
|
|
72
|
+
Left/Right,
|
|
73
|
+
h/l switch tabs or inspector mode
|
|
74
|
+
|
|
75
|
+
Tasks
|
|
76
|
+
n new task
|
|
77
|
+
Enter attach selected task PTY
|
|
78
|
+
X close selected task
|
|
79
|
+
|
|
80
|
+
Center panel
|
|
81
|
+
Enter attach PTY
|
|
82
|
+
+ new tab
|
|
83
|
+
a new agent tab
|
|
84
|
+
t new terminal tab
|
|
85
|
+
x close tab
|
|
86
|
+
z zoom center panel
|
|
87
|
+
|
|
88
|
+
Review
|
|
89
|
+
R sync PR / refresh checks
|
|
90
|
+
X close task
|
|
91
|
+
|
|
92
|
+
Terminal mode
|
|
93
|
+
Ctrl+] return to control mode
|
|
94
|
+
Wheel,
|
|
95
|
+
PgUp/PgDn scroll terminal
|
|
96
|
+
```
|
|
29
97
|
|
|
30
|
-
|
|
31
|
-
- `gh` authenticated with GitHub for PR, check, and merge flows
|
|
98
|
+
## Command Mode
|
|
32
99
|
|
|
33
|
-
|
|
100
|
+
Use command mode when scripting, debugging, or working outside the TUI.
|
|
34
101
|
|
|
35
102
|
```bash
|
|
36
103
|
craig
|
|
104
|
+
|
|
37
105
|
craig repo add <path>
|
|
38
106
|
craig repo list
|
|
39
107
|
craig repo remove <repo-id>
|
|
108
|
+
|
|
40
109
|
craig workspace list
|
|
41
|
-
craig
|
|
110
|
+
craig workspace list --archived
|
|
111
|
+
craig workspace archive <workspace-id>
|
|
112
|
+
craig workspace restore <workspace-id>
|
|
113
|
+
|
|
114
|
+
craig task new --repo <repo-id> [--runner codex|cursor|claude] "<task>"
|
|
42
115
|
craig task list
|
|
116
|
+
craig task list --repo <repo-id>
|
|
43
117
|
craig task show <task-id>
|
|
118
|
+
craig task attach <task-id>
|
|
119
|
+
craig task open <task-id>
|
|
44
120
|
craig task logs <task-id>
|
|
45
121
|
craig task diff <task-id>
|
|
46
122
|
craig task check <task-id>
|
|
123
|
+
craig task commit <task-id>
|
|
47
124
|
craig task pr <task-id> [--watch]
|
|
48
125
|
craig task merge <task-id> [--preserve-worktree]
|
|
126
|
+
|
|
127
|
+
craig link add <task-id> <repo-id>
|
|
128
|
+
craig link list <task-id>
|
|
49
129
|
```
|
|
50
130
|
|
|
51
131
|
## Configuration
|
|
@@ -68,3 +148,25 @@ Craig reads optional workspace-local config from `.craig/config.json`.
|
|
|
68
148
|
}
|
|
69
149
|
}
|
|
70
150
|
```
|
|
151
|
+
|
|
152
|
+
`checks.commands` defines commands for `craig task check`. `runners.<id>` controls whether Codex, Cursor, or Claude appears as a task runner and can override that runner's executable path. Runner path changes apply to newly created task sessions.
|
|
153
|
+
|
|
154
|
+
## Local State
|
|
155
|
+
|
|
156
|
+
Craig writes local state under `.craig/`:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
.craig/
|
|
160
|
+
artifacts/
|
|
161
|
+
logs/
|
|
162
|
+
runtime/
|
|
163
|
+
tasks/
|
|
164
|
+
workspaces/
|
|
165
|
+
worktrees/
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Treat `.craig/` as private developer state. It can contain task prompts, logs, local paths, PR metadata, and worktrees.
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
Craig is proprietary software. All rights reserved.
|
package/dist/cli.js
CHANGED
|
@@ -94,7 +94,7 @@ ${y.slice(-2e3)}`:""}`)}async function Tn(e){let t=await Ld(e).catch(()=>null);r
|
|
|
94
94
|
`)}function On(e,t,r={}){let i=r.color??!0,a=Ee.leftWidth,y=Ee.rightWidth,T=Ee.dividerWidth,n=r.centerOnly??!1,h=n?e.width:e.width-a-y-T*2,p=e.height-Ee.topRailHeight,S=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent} ${jn(`\u25CF ${t.topRail.liveLabel}`,i,se.rail)}`,o=le(nt(S,e.width),i,se.rail),w=qd(t,a-Qt-Jt,p,i),c=Kd(t,h,p,i),g=Vd(t,y,p,i),_=[];for(let s=0;s<p;s+=1){if(n){let v=s===p-1?{text:t.footerText,tone:"muted",fullBleed:!0}:c[s]??Be();_.push(Yt(v,h,i,"center"));continue}let f=Yt(w[s]??Be(),a,i,"left"),d=le("\u2502",i,se.divider),l=Yt(c[s]??Be(),h,i,"center"),u=le("\u2502",i,se.divider),m=Yt(g[s]??Be(),y,i,"right");_.push(`${f}${d}${l}${u}${m}`)}return[o,..._].join(`
|
|
95
95
|
`)}function es(e,t){let r=new Array(e.height).fill(le(" ".repeat(e.width),t.color,se.overlay)),i=Qr(),a=Math.max(...t.menuItems.map(p=>p.length)),y=t.menuItems.map((p,S)=>`${S===t.menuIndex?">":" "} ${p.padEnd(a)}`),T=t.optionsMessage?["",t.optionsMessage]:[],n=[...i,"",t.subtitle,"",...y,...T],h=Math.max(1,Math.floor((e.height-n.length)/2));for(let p=0;p<n.length;p+=1){let S=Nn(n[p]??"",e.width);if(p<i.length){r[h+p]=le(S,t.color,se.overlayLogo);continue}if(p===i.length+1){r[h+p]=le(S,t.color,se.overlaySubtitle);continue}let o=p-(i.length+3),c=o>=0&&o<t.menuItems.length&&o===t.menuIndex?se.overlayMenuSelected:se.overlay;r[h+p]=le(S,t.color,c)}return r.join(`
|
|
96
96
|
`)}function qd(e,t,r,i){let a=Yd(e.runners),y=2,T=e.leftTree.map(h=>Xd(h,t,i));return[...er(T,r-y),a,{text:e.footerText,tone:"muted",fullBleed:!0}]}function Kd(e,t,r,i){let a=e.tabs.find(o=>o.active)?.label??"AGENT",y=lu(e.tabs),T=`${" ".repeat(y)}${tr("\u2500".repeat(a.length+1),i,se.panelMuted)}`,n=[`${tr(e.centerHeader.tabLabel,i,se.panelBg)} ${e.centerHeader.taskId}`,e.centerHeader.repo].join(" \xB7 "),h=e.tabs.find(o=>o.active)?.id??"agent",p=e.centerHeader.tabLabel==="BROWSER"||!Yi(h)?e.centerTranscript.map(o=>({...o})):zd(e),S=[{text:Qd(e.tabs,i)},{text:T,tone:"muted"},{text:n},Be(),...p];return er(S,r)}function zd(e){if(e.terminal.error)return[{text:"terminal \u25B8 PTY unavailable"},Be(),{text:e.terminal.error},Be(),{text:"Fix the native dependency setup, then re-enter terminal mode."}];let t=e.tabs.find(i=>i.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(i=>({text:Wn(i.segments),segments:i.segments,fullBleed:!0}))}function Vd(e,t,r,i){let a=e.rightInspection?Gd(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):er([{text:Bn("CONTEXT",e.focusedRegion==="tasks",i,se.panelBg)},Be(),...e.rightContext.map(y=>Jd(y,i)),...e.actionMessage?[Be(),{text:e.actionMessage}]:[]],r);return er(a,r)}function Gd(e,t){let r=e.slice(0,2),i=e.slice(2),a=Math.max(0,t-r.length),y=i.findIndex(n=>n.focused||n.selected),T=y===-1?0:uu(y-Math.floor(a/2),0,Math.max(0,i.length-a));return[...r.map(n=>xn(n)),...i.slice(T,T+a).map(n=>xn(n))]}function xn(e){let t=e.focused?"\u25B8 ":e.selected?"\u2022 ":" ",r=e.focused||e.selected?"selected":e.muted?"muted":"default",i=`${t}${e.text}`;if(e.segments)return{text:i,segments:[{text:t},...e.segments],tone:r};if(e.accentPrefix&&!e.muted){let a=e.text.indexOf(" "),y=a===-1?e.text:e.text.slice(0,a),T=a===-1?"":e.text.slice(a);return{text:i,segments:[{text:t},{text:y,style:{fg:"7aa2f7"}},{text:T}],tone:r}}return e.color?{text:i,segments:[{text:t},{text:e.text,style:{fg:e.color}}],tone:r}:{text:i,tone:r}}function Xd(e,t,r){let i=" ".repeat(e.indent??0),a=e.accentDot?" \u25CF":"",y=e.status?` ${e.status}`:"",T=e.accentDot?` ${jn("\u25CF",r,e.selected?se.panelSelected:se.panelBg)}`:"",n=t-ze(y)-ze(a),h=e.focused&&!e.selected?Bn(e.text,!0,r,se.panelBg):e.text,S=`${nt(`${i}${h}`,Math.max(0,n))}${y}${T}`;return e.selected?{text:S,tone:"selected"}:e.muted?{text:S,tone:"muted"}:{text:S}}function Yd(e){let t=e.map(i=>{let a=i.health>=1,y=parseInt(i.count,10),T=y>1?` (${y})`:"";return{text:`${a?"\u25CF":"\u25CB"} ${i.name}${T}`,active:a}}),r=[];for(let i=0;i<t.length;i++){let a=t[i];i>0&&r.push({text:" "}),a.active?r.push({text:a.text,style:{fg:se.success.fg}}):r.push({text:a.text,style:{fg:se.panelMuted.fg}})}return{text:t.map(i=>i.text).join(" "),segments:r,tone:"muted"}}function Qd(e,t){return e.map(r=>r.active?tr(r.label,t,se.panelBg):Un(r.label,t,se.panelBg)).join(" ")}function Jd(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?Un(e.value,t,se.panelBg):e.value}`}}function Bn(e,t,r,i){return t?tr(e,r,i):e}function Yt(e,t,r,i){let a=Zd(i,e.tone??"default"),y=eu(e,r,a);if(i==="left"){if(e.fullBleed)return le(nt(y,t),r,a);let n=t-Qt-Jt;if(e.rightAlign){let p=ze(y),S=Math.max(0,n-p),o=`${" ".repeat(Qt)}${" ".repeat(S)}${y}${" ".repeat(Jt)}`;return le(o,r,a)}let h=`${" ".repeat(Qt)}${nt(y,n)}${" ".repeat(Jt)}`;return le(h,r,a)}return i==="center"&&e.fullBleed?tu(e,t,r,a):le(nt(` ${y}`,t),r,a)}function Zd(e,t){return t==="selected"||t==="focused"?se.panelSelected:t==="muted"?se.panelMuted:se.panelBg}function er(e,t){let r=e.slice(0,t);for(;r.length<t;)r.push(Be());return r}function Be(){return{text:""}}function eu(e,t,r){return e.segments?e.segments.map(i=>Fn(i,t,r)).join(""):e.text}function tu(e,t,r,i){let a=" ".repeat(Zt),y=Math.max(0,t-Zt*2);if(!e.segments)return le(`${a}${nt(e.text,y)}${a}`,r,i);let T=iu(e.segments,y),n=`${a}${T.map(h=>Fn(h,r,i)).join("")}${a}`;return le(n,r,i)}function Fn(e,t,r){let i=e.href?`${$n(e.href)}${e.text}${An}`:ru(e.text);return!t||!e.style?i:`${Tt(au(e.style,r))}${cu(e.style)}${i}${Jr}${Tt(r)}`}function ru(e){return e.replace(jd,t=>{let[r,i]=su(t);return`${$n(r)}${r}${An}${i}`})}function su(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function $n(e){return`\x1B]8;;${e}\x1B\\`}function iu(e,t){let r=nu(e,t);return ou(r,t)}function nu(e,t){let r=[],i=t;for(let a of e){if(i<=0)break;let y=ze(a.text);if(y<=i){r.push(a),i-=y;continue}r.push({...a,text:a.text.slice(0,i)}),i=0}return r}function ou(e,t){let r=ze(Wn(e));if(r>=t)return e;let i=e.at(-1)?.style;return i?.bg?[...e,{text:" ".repeat(t-r),style:i}]:[...e,{text:" ".repeat(t-r)}]}function au(e,t){let r=e.inverse?e.bg??t.bg:e.fg,i=e.inverse?e.fg??t.fg:e.bg,a={},y=r??t.fg,T=i??t.bg;return y&&(a.fg=y),T&&(a.bg=T),a}function cu(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 lu(e){let t=0;for(let r of e){if(r.active)return t;t+=r.label.length+3}return 0}function Nn(e,t){let r=Math.max(0,t-ze(e)),i=Math.floor(r/2),a=r-i;return`${" ".repeat(i)}${e}${" ".repeat(a)}`}function nt(e,t){let r=ze(e);return r>=t?du(e,t):e+" ".repeat(t-r)}function du(e,t){return ze(e)<=t?e:Hn(e).slice(0,Math.max(0,t-1))+"\u2026"}function ze(e){return Hn(e).length}function uu(e,t,r){return Math.min(Math.max(e,t),r)}function Hn(e){return e.replace(Wd,"").replace(Nd,"")}function Wn(e){return e.map(t=>t.text).join("")}function le(e,t,r){if(!t)return e;let i=Tt(r),a=e.replace(Hd,`${Jr}${i}`);return`${i}${a}${Jr}`}function Tt(e){let t=[];return e.fg&&t.push(`38;2;${En(e.fg).join(";")}`),e.bg&&t.push(`48;2;${En(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function En(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function jn(e,t,r){return ts(e,t,se.success.fg,r)}function tr(e,t,r){return ts(e,t,se.accent.fg,r)}function Un(e,t,r){return ts(e,t,se.mutedfg.fg,r)}function ts(e,t,r,i){if(!t)return e;let a=i.bg?{fg:r,bg:i.bg}:{fg:r};return`${Tt(a)}${e}${Tt(i)}`}var rs=["Runners","Help"];function ss(e,t){return de.map(r=>{let i=pe(r),a=e.runners?.[r]?.enabled!==!1,y=e.runners?.[r]?.path?.trim(),T=t.pathEdit?.runner===r?`${t.pathEdit.value}_`:y&&y.length>0?y:`default (${i.executable})`;return`${i.displayName} ${a?"enabled":"disabled"} ${T}`})}function Kn(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 zn(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(rs.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:is(t)?e===0?{kind:"runners"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function Vn(e,t,r,i){if(e.pathEdit)return hu({...e,pathEdit:e.pathEdit},t,r);let a=ss(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(a-1,e.menuIndex+1),message:null}};if(r==="ESCAPE")return{kind:"back",state:e};if(r==="e"){let n=de[e.menuIndex]??"codex";return{kind:"render",state:{...e,message:null,pathEdit:{runner:n,value:t.runners?.[n]?.path??""}}}}if(!is(r))return{kind:"noop",state:e};let y=de[e.menuIndex]??"codex",T=t.runners?.[y]?.enabled!==!1;return T&&i.length<=1?{kind:"render",state:{...e,message:"At least one runner must stay enabled."}}:{kind:"save",config:fu(t,y,!T),state:{...e,message:`${pe(y).displayName} ${T?"disabled":"enabled"}.`}}}function hu(e,t,r){if(r==="ESCAPE")return{kind:"render",state:qn({...e,message:null})};if(r==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(is(r)){let i=e.pathEdit.runner,a=e.pathEdit.value.trim();return{kind:"save",config:pu(t,i,a.length>0?a:null),state:qn({...e,message:a.length>0?`${pe(i).displayName} executable saved.`:`${pe(i).displayName} executable reset to default.`})}}return gu(r)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${r}`}}}:{kind:"noop",state:e}}function fu(e,t,r){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:r}}}}function pu(e,t,r){let i={...e.runners?.[t]??{},...r?{path:r}:{}};return r||delete i.path,{...e,runners:{...e.runners??{},[t]:i}}}function qn(e){let t={...e};return delete t.pathEdit,t}function is(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
97
|
-
`}function gu(e){return e.length===1&&e>=" "&&e!=="\x7F"}var bu=mu(import.meta.url),yu=bu("terminal-kit"),Su=yu.terminal;async function Yn(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=$e(t);await dt(t);let i=await _e(r),a=ot(i),y=e.uiStateFile?await Pe({uiStateFile:e.uiStateFile}):null,T=Promise.resolve(),n=Promise.resolve(),h=await Ct(t,void 0,a),p=Ut(Ki(y,i),h);h=await Ct(t,p,a);let S=()=>{},o={workspaceRoot:t,onUpdate:()=>S(),resolveSessionSpec:(g,_)=>Ru(h,_,t)},w=e.ptyRuntime??await Sn({...o,paths:r}),c=g=>{if(!e.uiStateFile)return;y=zi(y,g);let _=y;T=T.then(()=>ve({uiStateFile:e.uiStateFile},_),()=>ve({uiStateFile:e.uiStateFile},_)),T.catch(()=>{})};return new Promise(g=>{let _=e.terminal??Su,s={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Ut(p,h)},f=!1,d=!1,l=null,u=0,m=0,v=null,I=null,E=null,N=null,O=!1,A=!0,D=null,C=()=>{},j=w;S=()=>{s.mode==="main"&&(s={mode:"main",shell:z(s.shell)},E||(E=setTimeout(()=>{E=null,s.mode==="main"&&C()},50)))};function z($){return vt($,j.getViewState($.selectedPtyTabId))}function W($){return z(ku($,h))}function G($){return h.tasks.find(M=>M.id===$.selectedTaskId)??null}async function q(){await j.hydrateSessions?.(h.tasks.flatMap($=>$.ptyTabs.map(M=>M.id)))}function b(){q().catch(()=>{}).then(()=>{s.mode==="main"&&(s={mode:"main",shell:z(s.shell)},C())})}function P($){let M=n.then($,$);return n=M.then(()=>{},()=>{}),M}function k($){let M=G($),L=h.inspection,H=L&&L.taskId===M?.id?L:null,V=Tu(H?.fileRows??[],$.collapsedFileTreePaths);return{leftItemIds:Cu(h),centerTabIds:Ji(M,$),ptyTabIds:M?.ptyTabs.map(re=>re.id)??[],filePathIds:H?.filePaths??[],fileTreeRowIds:V.map(re=>re.path),fileTreeFileIds:V.filter(re=>re.kind==="file").map(re=>re.path),fileTreeDirectoryIds:V.filter(re=>re.kind==="directory").map(re=>re.path),diffPathIds:H?.diffPaths??[],diffPathRanges:Wr(H),fileLineCount:H?.selectedFile.lines.length??0,diffLineCount:an(H),pageRows:Math.max(5,ut(_.width,_.height).height-Ee.topRailHeight-8),enabledRunnerIds:a}}async function R($){await gs(r,$),i=$,a=ot(i),h={...h,enabledRunnerIds:a},s.mode==="main"?s={mode:"main",shell:W({...s.shell,selectedRunner:a.includes(s.shell.selectedRunner)?s.shell.selectedRunner:Ge(i)})}:s={...s,shell:W({...s.shell,selectedRunner:a.includes(s.shell.selectedRunner)?s.shell.selectedRunner:Ge(i)})}}async function F($){let M=$.selectedTaskId;M&&await P(async()=>{let L=await Se(r,M);!L.ptyTabs.some(H=>H.id===$.activeTab)||L.selectedPtyTabId===$.activeTab||await te(r,{...L,selectedPtyTabId:$.activeTab})})}async function B(){let $=(s.mode==="main",s.shell);h=await Ct(t,$,a),s.mode==="main"?s={mode:"main",shell:W(s.shell)}:s={...s,shell:W(s.shell)}}async function U($){h=await Ct(t,$,a),s.mode==="main"&&(s={mode:"main",shell:W($)}),c(s.shell),C()}async function K($){let M=await Ou($);s.mode==="main"&&(s={mode:"main",shell:W({...s.shell,workspaceBrowser:M,activeTab:s.shell.selectedPtyTabId??s.shell.activeTab,actionMessage:null})},C())}async function ee($){try{let M=W($),L=G(M),H=M.selectedPtyTabId;if(L&&M.focusedRegion==="tasks"){let be=L.ptyTabs.find(Ce=>Ce.kind==="agent")??null;be?H=be.id:(L=await Ae(L),await B(),H=L.selectedPtyTabId)}L&&!H&&(L=await Ae(L),await B(),H=L.selectedPtyTabId);let V=W({...M,activeTab:H??M.activeTab,selectedPtyTabId:H});if(!V.selectedTaskId||!H){s={mode:"main",shell:V},C();return}s={mode:"main",shell:vt({...V,inputMode:"terminal"},j.getViewState(H))},c(s.shell);let re=await j.ensureSession(V.selectedTaskId,H,ns(ut(_.width,_.height)));d=os(H),l=null,s={mode:"main",shell:vt({...V,inputMode:"terminal"},re)},c(s.shell)}catch(M){let L=M instanceof Error?M.message:"Failed to start PTY.";$.selectedTaskId&&$.selectedPtyTabId&&os($.selectedPtyTabId)&&(await x($.selectedTaskId,L).catch(()=>{}),await B().catch(()=>{})),s={mode:"main",shell:Gi(W($),L)},c(s.shell)}C()}async function x($,M){await P(async()=>{let L=await Se(r,$);await te(r,{...L,status:L.status==="running"?"draft":L.status,runnerSession:{...L.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:M})})}async function Q($,M,L){let H=W($);if(!H.selectedTaskId)throw new Error("Select a task before creating a tab.");let V=await P(async()=>{let re=await Se(r,H.selectedTaskId),be=M??Iu(re,H.activeTab,H.preferredPtyTabKind),Ce=Gn(re,be,L??void 0,i),ft={...re,ptyTabs:[...re.ptyTabs,Ce],selectedPtyTabId:Ce.id};return await te(r,ft),ft});return await B(),W({...H,activeTab:V.selectedPtyTabId??H.activeTab,selectedPtyTabId:V.selectedPtyTabId,preferredPtyTabKind:V.ptyTabs.at(-1)?.kind??H.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${V.ptyTabs.at(-1)?.title??"tab"}`})}async function Y($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:L,nextSelectedTab:H}=await P(async()=>{let V=await Se(r,M.selectedTaskId),re=V.ptyTabs.findIndex(or=>or.id===M.activeTab);if(re===-1)throw new Error("Only PTY tabs can be closed.");let be=V.ptyTabs[re],Ce=V.ptyTabs.filter(or=>or.id!==be.id),ft=Ce[Math.min(re,Ce.length-1)]??Ce[re-1]??null;return await te(r,{...V,ptyTabs:Ce,selectedPtyTabId:ft?.id??null}),{closedTab:be,nextSelectedTab:ft}});return j.disposeSession(L.id),await B(),W({...M,activeTab:H?.id??(M.openInspectionKind?"inspection":M.activeTab),selectedPtyTabId:H?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${L.title}`})}async function Z($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before creating or syncing a PR.");let L=await bt(r,M.selectedTaskId,{watch:!1});await B();let H=L.disposition==="created"?"Created PR":L.disposition==="discovered"?"Discovered PR":"Synced PR";return W({...M,focusedRegion:"inspector",inspectionMode:"review",actionMessage:`${H}: #${L.prNumber} ${L.url}`})}async function he($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let{disposition:L,task:H}=await yr(r,M.selectedTaskId);await B();let V=L==="not_found"?`No PR found for ${H.branch}`:L==="discovered"?`Discovered PR: #${H.pullRequest.number} ${H.pullRequest.url??""}`:`Refreshed checks: ${H.pullRequest.requiredChecks.length} reported`;return W({...M,focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:V})}async function fe(){if(O||s.mode!=="main"||!s.shell.selectedTaskId)return;let $=s.shell.selectedTaskId,L=!!(h.tasks.find(H=>H.id===$)??null)?.pullRequest.number;O=!0;try{let{disposition:H,task:V}=await yr(r,$);if(s.mode!=="main"||s.shell.selectedTaskId!==$)return;h=await Ct(t,s.shell,a),s={mode:"main",shell:W({...s.shell,actionMessage:H==="discovered"&&!L?`Discovered PR: #${V.pullRequest.number} ${V.pullRequest.url??""}`:s.shell.actionMessage})},C()}catch{}finally{O=!1}}async function He($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before merging a PR.");let L=await yt(r,M.selectedTaskId,{preserveWorktree:!0});return await B(),W({...M,focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"merge",actionMessage:`Merged PR #${L.prNumber}; worktree preserved`})}async function Te($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before closing it.");let L=await Se(r,M.selectedTaskId),H=await Pi(r,M.selectedTaskId);for(let V of L.ptyTabs)j.disposeSession(V.id);return await B(),W({...M,selectedActionId:"close-task",actionMessage:H.cleanup.preservedWorktree?`Archived task ${H.id}; worktree preserved`:`Archived task ${H.id}`})}async function Ae($){let M=$.ptyTabs.find(V=>V.kind==="agent")??null;if(M){let V={...$,selectedPtyTabId:M.id};return await P(async()=>{let re=await Se(r,$.id),be=re.ptyTabs.find(Ce=>Ce.kind==="agent")??null;be&&await te(r,{...re,selectedPtyTabId:be.id})}),V}let L=Gn($,"agent",void 0,i),H={...$,ptyTabs:[...$.ptyTabs,L],selectedPtyTabId:L.id};return await P(async()=>{let V=await Se(r,$.id),re=V.ptyTabs.find(be=>be.kind==="agent")??null;if(re){await te(r,{...V,selectedPtyTabId:re.id});return}await te(r,{...V,ptyTabs:[...V.ptyTabs,L],selectedPtyTabId:L.id})}),H}C=()=>{Ve();let $=ut(_.width,_.height),M=s.mode==="main"?On($,on(W(s.shell),h),{centerOnly:s.shell.centerZoomed}):s.variant==="boot"?Dn($,{menuIndex:s.menuIndex,optionsMessage:s.optionsMessage}):s.variant==="pause"?Ln($,{menuIndex:s.menuIndex,optionsMessage:s.optionsMessage}):s.variant==="options"?Zr($,{menuIndex:s.menuIndex,optionsMenuItems:rs}):s.variant==="runners"?Zr($,{menuIndex:Rt(s).menuIndex,optionsMenuItems:ss(i,Rt(s)),optionsMessage:Kn(Rt(s)),optionsSubtitle:"Runners"}):Mn($);_.moveTo(1,1),A&&(_.eraseDisplayBelow(),A=!1),_.noFormat(M)};function Ve(){let $=s.mode==="main"&&s.shell.inputMode==="terminal"?"terminal":"control";$!==D&&(D=$,_.grabInput($==="terminal"?{mouse:"button"}:!0))}let Jn=()=>{process.stdout.off("resize",us),_.removeListener("key",cs),_.removeListener("unknown",ls),_.removeListener("mouse",ds),v&&(clearTimeout(v),v=null),I&&(clearTimeout(I),I=null),E&&(clearTimeout(E),E=null),N&&(clearInterval(N),N=null),j.disposeAll(),_.grabInput(!1),_.hideCursor(!1),_.fullscreen(!1)},ir=$=>{Jn(),g($)},Zn=async()=>{if(s.mode!=="main"||f)return;let $=s.shell,M=$.taskPromptInput?.trim()??"";if(!$.selectedRepoId){s={mode:"main",shell:W({...$,taskPromptError:"Select a repo first."})},C();return}if(M.length===0){s={mode:"main",shell:W({...$,taskPromptError:"Task prompt cannot be empty."})},C();return}f=!0,s={mode:"main",shell:W({...$,actionMessage:`Creating ${$.selectedRunner} task in ${$.selectedRepoId}...`})},C();let L=null;try{L=await xu(r,$.selectedRepoId,M,$.selectedRunner),await B();let H=W({...s.shell,selectedRepoId:L.repoId,selectedTaskId:L.id,selectedPtyTabId:L.selectedPtyTabId,selectedLeftItemId:`task:${L.id}`,activeTab:L.selectedPtyTabId??"agent",inputMode:"terminal",taskPromptInput:null,taskPromptError:null,actionMessage:null}),V=await j.ensureSession(L.id,H.selectedPtyTabId??Qn(L,"agent"),ns(ut(_.width,_.height)));d=os(H.selectedPtyTabId),s={mode:"main",shell:vt(H,V)},c(s.shell)}catch(H){H instanceof rr&&(L=H.task);let V=H instanceof Error?H.message:"Failed to create task.";L&&(await te(r,{...L,status:"draft",runnerSession:{...L.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:V}).catch(()=>{}),await B().catch(()=>{})),s={mode:"main",shell:W({...s.shell,inputMode:"control",selectedTaskId:L?.id??s.shell.selectedTaskId,selectedPtyTabId:L?.selectedPtyTabId??s.shell.selectedPtyTabId,selectedLeftItemId:L?`task:${L.id}`:s.shell.selectedLeftItemId,activeTab:L?.selectedPtyTabId??s.shell.activeTab,taskPromptInput:L?null:"",taskPromptError:V,actionMessage:null})}}finally{f=!1,C()}},eo=$=>{if(s.mode!=="main")return;let M=s.shell;if(M.taskPromptInput!==null){if($==="ESCAPE"){s={mode:"main",shell:W({...M,taskPromptInput:null,taskPromptError:null,actionMessage:null})},C();return}if(Ke($)){Zn();return}if($==="BACKSPACE"){s={mode:"main",shell:W({...M,taskPromptInput:M.taskPromptInput.slice(0,-1),taskPromptError:null})},C();return}if($==="CTRL_R"){s={mode:"main",shell:W({...M,selectedRunner:Fr(M.selectedRunner,a),taskPromptError:null})},C();return}Xi($)&&(s={mode:"main",shell:W({...M,taskPromptInput:`${M.taskPromptInput}${$}`,taskPromptError:null})},C())}},to=$=>{if(s.mode!=="main")return;let M=s.shell.workspaceBrowser;if(M){if($==="ESCAPE"){s={mode:"main",shell:W({...s.shell,workspaceBrowser:null,actionMessage:null})},C();return}if($==="UP"||$==="k"){s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,selectedIndex:Math.max(0,M.selectedIndex-1),error:null}})},C();return}if($==="DOWN"||$==="j"){let L=Math.max(0,M.entries.length-1);s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,selectedIndex:Math.min(L,M.selectedIndex+1),error:null}})},C();return}if($==="LEFT"||$==="h"){K(as.dirname(M.cwd)).catch(L=>{let H=L instanceof Error?L.message:"Failed to open parent directory.";s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,error:H}})},C()});return}if($==="RIGHT"||$==="l"||Ke($)){let L=M.entries[M.selectedIndex]??null;if(!L)return;if(L.kind==="directory"||($==="RIGHT"||$==="l")&&L.kind==="repo"){K(L.path).catch(H=>{let V=H instanceof Error?H.message:"Failed to open directory.";s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,error:V}})},C()});return}$t(r,L.path).then(async H=>{await B(),s={mode:"main",shell:W({...s.shell,workspaceBrowser:null,selectedLeftItemId:`repo:${H.repo.id}`,selectedRepoId:H.repo.id,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${H.repo.name}`})},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to add workspace.";s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,error:V}})},C()})}}},cs=$=>{let M=typeof $=="string"?$:"";if(s.mode==="main"&&s.shell.taskPromptInput!==null){eo(M);return}if(s.mode==="main"&&s.shell.workspaceBrowser!==null){to(M);return}if(s.mode==="main"){let L=Vi(s.shell,M,k(s.shell));if(L.exit){ir(0);return}if(L.detachTerminal){j.detach(),s={mode:"main",shell:W(L.state)},c(s.shell),C();return}if(s.shell.inputMode==="terminal"){if(L.changed){s={mode:"main",shell:W(L.state)},c(s.shell),C();return}if(d&&Ke(M)){d=!1;return}d&&(d=!1),l=Au(M)?{key:M,at:Date.now()}:null;let H=Du(M,s.shell.terminal.scrolledBack??!1);if(H!==0){nr(H);return}j.writeKey(M);return}if(M==="CTRL_C"){ir(0);return}if(M==="?"&&s.shell.inputMode==="control"){s={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:s.shell},A=!0,C();return}if(L.pause){s={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:W(L.state)},A=!0,C();return}if(L.beginTaskPrompt){s={mode:"main",shell:W(L.state)},c(s.shell),C();return}if(L.openWorkspaceBrowser){K(t).catch(H=>{let V=H instanceof Error?H.message:"Failed to browse workspaces.";s={mode:"main",shell:W({...L.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:V}})},C()});return}if(L.createPtyTab){Q(L.state,L.createPtyTabKind,L.createPtyTabRunner).then(H=>{ee(H)}).catch(H=>{let V=H instanceof Error?H.message:"Failed to create tab.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.closePtyTab){Y(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to close tab.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.syncPullRequest){Z(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to create or sync PR.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.refreshPullRequestChecks){he(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to refresh PR checks.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.mergeTask){He(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to merge PR.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.closeTask){Te(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to close task.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.attachTerminal){ee(L.state);return}if(L.refreshInspection){U(L.state).catch(H=>{let V=H instanceof Error?H.message:"Failed to refresh inspection.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}L.changed&&(s={mode:"main",shell:W(L.state)},F(s.shell).catch(()=>{}),c(s.shell),C());return}if(s.variant==="help"){s.viaOptions&&s.parentVariant?s={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:s.shell,parentVariant:s.parentVariant}:s.parentVariant?s={mode:"overlay",variant:s.parentVariant,menuIndex:1,optionsMessage:null,shell:s.shell}:s={mode:"main",shell:W(s.shell)},A=!0,C();return}if(s.variant==="options"){ro(M);return}if(s.variant==="runners"){so(M);return}if(s.optionsMessage){(M==="ESCAPE"||Ke(M))&&(s={...s,optionsMessage:null},C());return}if(M==="UP"||M==="k"){s={...s,menuIndex:Math.max(0,s.menuIndex-1)},C();return}if(M==="DOWN"||M==="j"){s={...s,menuIndex:Math.min(2,s.menuIndex+1)},C();return}if(M==="ESCAPE"){s.variant==="pause"&&(s={mode:"main",shell:W(s.shell)},A=!0,C());return}if(Ke(M)){if(s.menuIndex===0){s={mode:"main",shell:W({...s.shell,inputMode:"control"})},A=!0,C(),b();return}if(s.menuIndex===1){let L=s.variant==="boot"||s.variant==="pause"?s.variant:void 0;s={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:s.shell,...L!==void 0?{parentVariant:L}:{}},A=!0,C();return}ir(0)}};function ro($){if(s.mode!=="overlay"||s.variant!=="options")return;let M=zn(s.menuIndex,$);if(M.kind!=="noop"){if(M.kind==="render"){s={...s,menuIndex:M.menuIndex},C();return}if(M.kind==="back"){s.parentVariant&&(s={mode:"overlay",variant:s.parentVariant,menuIndex:1,optionsMessage:null,shell:s.shell},A=!0,C());return}if(M.kind==="help"){let L=s.parentVariant;s={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:s.shell,viaOptions:!0,...L!==void 0?{parentVariant:L}:{}},A=!0,C();return}if(M.kind==="runners"){let L=s.parentVariant;s={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:s.shell,...L!==void 0?{parentVariant:L}:{}},A=!0,C()}}}function so($){if(s.mode!=="overlay"||s.variant!=="runners")return;let M=Vn(Rt(s),i,$,a);if(M.kind!=="noop"){if(M.kind==="back"){let L=s.parentVariant;s={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:s.shell,...L!==void 0?{parentVariant:L}:{}},A=!0,C();return}if(M.kind==="render"){s={...s,runnerOptions:M.state},C();return}R(M.config).then(()=>{s.mode!=="overlay"||s.variant!=="runners"||(s={...s,runnerOptions:M.state},C())}).catch(L=>{if(s.mode!=="overlay"||s.variant!=="runners")return;let H=L instanceof Error?L.message:"Failed to save runner option.";s={...s,runnerOptions:{...Rt(s),message:H}},C()})}}let ls=$=>{let M=Eu($);if(s.mode!=="main"||s.shell.inputMode!=="terminal"||M.length===0)return;if(M.includes("")){j.detach(),d=!1,l=null,s={mode:"main",shell:W({...s.shell,inputMode:"control",actionMessage:null})},c(s.shell),C();return}let L=Lu(M);if(L!==0){nr(L);return}if(d&&M!=="\r"&&M!==`
|
|
97
|
+
`}function gu(e){return e.length===1&&e>=" "&&e!=="\x7F"}var bu=mu(import.meta.url),yu=bu("terminal-kit"),Su=yu.terminal;async function Yn(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),r=$e(t);await dt(t);let i=await _e(r),a=ot(i),y=e.uiStateFile?await Pe({uiStateFile:e.uiStateFile}):null,T=Promise.resolve(),n=Promise.resolve(),h=await Ct(t,void 0,a),p=Ut(Ki(y,i),h);h=await Ct(t,p,a);let S=()=>{},o={workspaceRoot:t,onUpdate:()=>S(),resolveSessionSpec:(g,_)=>Ru(h,_,t)},w=e.ptyRuntime??await Sn({...o,paths:r}),c=g=>{if(!e.uiStateFile)return;y=zi(y,g);let _=y;T=T.then(()=>ve({uiStateFile:e.uiStateFile},_),()=>ve({uiStateFile:e.uiStateFile},_)),T.catch(()=>{})};return new Promise(g=>{let _=e.terminal??Su,s={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:Ut(p,h)},f=!1,d=!1,l=null,u=0,m=0,v=null,I=null,E=null,N=null,O=!1,A=!0,D=null,C=()=>{},j=w;S=()=>{s.mode==="main"&&(s={mode:"main",shell:z(s.shell)},E||(E=setTimeout(()=>{E=null,s.mode==="main"&&C()},50)))};function z($){return vt($,j.getViewState($.selectedPtyTabId))}function W($){return z(ku($,h))}function G($){return h.tasks.find(M=>M.id===$.selectedTaskId)??null}async function q(){await j.hydrateSessions?.(h.tasks.flatMap($=>$.ptyTabs.map(M=>M.id)))}function b(){q().catch(()=>{}).then(()=>{s.mode==="main"&&(s={mode:"main",shell:z(s.shell)},C())})}function P($){let M=n.then($,$);return n=M.then(()=>{},()=>{}),M}function k($){let M=G($),L=h.inspection,H=L&&L.taskId===M?.id?L:null,V=Tu(H?.fileRows??[],$.collapsedFileTreePaths);return{leftItemIds:Cu(h),centerTabIds:Ji(M,$),ptyTabIds:M?.ptyTabs.map(re=>re.id)??[],filePathIds:H?.filePaths??[],fileTreeRowIds:V.map(re=>re.path),fileTreeFileIds:V.filter(re=>re.kind==="file").map(re=>re.path),fileTreeDirectoryIds:V.filter(re=>re.kind==="directory").map(re=>re.path),diffPathIds:H?.diffPaths??[],diffPathRanges:Wr(H),fileLineCount:H?.selectedFile.lines.length??0,diffLineCount:an(H),pageRows:Math.max(5,ut(_.width,_.height).height-Ee.topRailHeight-8),enabledRunnerIds:a}}async function R($){await gs(r,$),i=$,a=ot(i),h={...h,enabledRunnerIds:a},s.mode==="main"?s={mode:"main",shell:W({...s.shell,selectedRunner:a.includes(s.shell.selectedRunner)?s.shell.selectedRunner:Ge(i)})}:s={...s,shell:W({...s.shell,selectedRunner:a.includes(s.shell.selectedRunner)?s.shell.selectedRunner:Ge(i)})}}async function F($){let M=$.selectedTaskId;M&&await P(async()=>{let L=await Se(r,M);!L.ptyTabs.some(H=>H.id===$.activeTab)||L.selectedPtyTabId===$.activeTab||await te(r,{...L,selectedPtyTabId:$.activeTab})})}async function B(){let $=(s.mode==="main",s.shell);h=await Ct(t,$,a),s.mode==="main"?s={mode:"main",shell:W(s.shell)}:s={...s,shell:W(s.shell)}}async function U($){h=await Ct(t,$,a),s.mode==="main"&&(s={mode:"main",shell:W($)}),c(s.shell),C()}async function K($){let M=await Ou($);s.mode==="main"&&(s={mode:"main",shell:W({...s.shell,workspaceBrowser:M,activeTab:s.shell.selectedPtyTabId??s.shell.activeTab,actionMessage:null})},C())}async function ee($){try{let M=W($),L=G(M),H=M.selectedPtyTabId;if(L&&M.focusedRegion==="tasks"){let be=L.ptyTabs.find(Ce=>Ce.kind==="agent")??null;be?H=be.id:(L=await Ae(L),await B(),H=L.selectedPtyTabId)}L&&!H&&(L=await Ae(L),await B(),H=L.selectedPtyTabId);let V=W({...M,activeTab:H??M.activeTab,selectedPtyTabId:H});if(!V.selectedTaskId||!H){s={mode:"main",shell:V},C();return}s={mode:"main",shell:vt({...V,inputMode:"terminal"},j.getViewState(H))},c(s.shell);let re=await j.ensureSession(V.selectedTaskId,H,ns(ut(_.width,_.height)));d=os(H),l=null,s={mode:"main",shell:vt({...V,inputMode:"terminal"},re)},c(s.shell)}catch(M){let L=M instanceof Error?M.message:"Failed to start PTY.";$.selectedTaskId&&$.selectedPtyTabId&&os($.selectedPtyTabId)&&(await x($.selectedTaskId,L).catch(()=>{}),await B().catch(()=>{})),s={mode:"main",shell:Gi(W($),L)},c(s.shell)}C()}async function x($,M){await P(async()=>{let L=await Se(r,$);await te(r,{...L,status:L.status==="running"?"draft":L.status,runnerSession:{...L.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:M})})}async function Q($,M,L){let H=W($);if(!H.selectedTaskId)throw new Error("Select a task before creating a tab.");let V=await P(async()=>{let re=await Se(r,H.selectedTaskId),be=M??Iu(re,H.activeTab,H.preferredPtyTabKind),Ce=Gn(re,be,L??void 0,i),ft={...re,ptyTabs:[...re.ptyTabs,Ce],selectedPtyTabId:Ce.id};return await te(r,ft),ft});return await B(),W({...H,activeTab:V.selectedPtyTabId??H.activeTab,selectedPtyTabId:V.selectedPtyTabId,preferredPtyTabKind:V.ptyTabs.at(-1)?.kind??H.preferredPtyTabKind,focusedRegion:"center",actionMessage:`Created tab: ${V.ptyTabs.at(-1)?.title??"tab"}`})}async function Y($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:L,nextSelectedTab:H}=await P(async()=>{let V=await Se(r,M.selectedTaskId),re=V.ptyTabs.findIndex(or=>or.id===M.activeTab);if(re===-1)throw new Error("Only PTY tabs can be closed.");let be=V.ptyTabs[re],Ce=V.ptyTabs.filter(or=>or.id!==be.id),ft=Ce[Math.min(re,Ce.length-1)]??Ce[re-1]??null;return await te(r,{...V,ptyTabs:Ce,selectedPtyTabId:ft?.id??null}),{closedTab:be,nextSelectedTab:ft}});return j.disposeSession(L.id),await B(),W({...M,activeTab:H?.id??(M.openInspectionKind?"inspection":M.activeTab),selectedPtyTabId:H?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${L.title}`})}async function Z($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before creating or syncing a PR.");let L=await bt(r,M.selectedTaskId,{watch:!1});await B();let H=L.disposition==="created"?"Created PR":L.disposition==="discovered"?"Discovered PR":"Synced PR";return W({...M,focusedRegion:"inspector",inspectionMode:"review",actionMessage:`${H}: #${L.prNumber} ${L.url}`})}async function he($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let{disposition:L,task:H}=await yr(r,M.selectedTaskId);await B();let V=L==="not_found"?`No PR found for ${H.branch}`:L==="discovered"?`Discovered PR: #${H.pullRequest.number} ${H.pullRequest.url??""}`:`Refreshed checks: ${H.pullRequest.requiredChecks.length} reported`;return W({...M,focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:V})}async function fe(){if(O||s.mode!=="main"||!s.shell.selectedTaskId)return;let $=s.shell.selectedTaskId,L=!!(h.tasks.find(H=>H.id===$)??null)?.pullRequest.number;O=!0;try{let{disposition:H,task:V}=await yr(r,$);if(s.mode!=="main"||s.shell.selectedTaskId!==$)return;h=await Ct(t,s.shell,a),s={mode:"main",shell:W({...s.shell,actionMessage:H==="discovered"&&!L?`Discovered PR: #${V.pullRequest.number} ${V.pullRequest.url??""}`:s.shell.actionMessage})},C()}catch{}finally{O=!1}}async function He($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before merging a PR.");let L=await yt(r,M.selectedTaskId,{preserveWorktree:!0});return await B(),W({...M,focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"merge",actionMessage:`Merged PR #${L.prNumber}; worktree preserved`})}async function Te($){let M=W($);if(!M.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:L,task:H}=await P(async()=>{let V=await Se(r,M.selectedTaskId),re=await Pi(r,M.selectedTaskId);return{taskBeforeClose:V,task:re}});for(let V of L.ptyTabs)j.disposeSession(V.id);return await B(),W({...M,selectedActionId:"close-task",actionMessage:H.cleanup.preservedWorktree?`Archived task ${H.id}; worktree preserved`:`Archived task ${H.id}`})}async function Ae($){let M=$.ptyTabs.find(V=>V.kind==="agent")??null;if(M){let V={...$,selectedPtyTabId:M.id};return await P(async()=>{let re=await Se(r,$.id),be=re.ptyTabs.find(Ce=>Ce.kind==="agent")??null;be&&await te(r,{...re,selectedPtyTabId:be.id})}),V}let L=Gn($,"agent",void 0,i),H={...$,ptyTabs:[...$.ptyTabs,L],selectedPtyTabId:L.id};return await P(async()=>{let V=await Se(r,$.id),re=V.ptyTabs.find(be=>be.kind==="agent")??null;if(re){await te(r,{...V,selectedPtyTabId:re.id});return}await te(r,{...V,ptyTabs:[...V.ptyTabs,L],selectedPtyTabId:L.id})}),H}C=()=>{Ve();let $=ut(_.width,_.height),M=s.mode==="main"?On($,on(W(s.shell),h),{centerOnly:s.shell.centerZoomed}):s.variant==="boot"?Dn($,{menuIndex:s.menuIndex,optionsMessage:s.optionsMessage}):s.variant==="pause"?Ln($,{menuIndex:s.menuIndex,optionsMessage:s.optionsMessage}):s.variant==="options"?Zr($,{menuIndex:s.menuIndex,optionsMenuItems:rs}):s.variant==="runners"?Zr($,{menuIndex:Rt(s).menuIndex,optionsMenuItems:ss(i,Rt(s)),optionsMessage:Kn(Rt(s)),optionsSubtitle:"Runners"}):Mn($);_.moveTo(1,1),A&&(_.eraseDisplayBelow(),A=!1),_.noFormat(M)};function Ve(){let $=s.mode==="main"&&s.shell.inputMode==="terminal"?"terminal":"control";$!==D&&(D=$,_.grabInput($==="terminal"?{mouse:"button"}:!0))}let Jn=()=>{process.stdout.off("resize",us),_.removeListener("key",cs),_.removeListener("unknown",ls),_.removeListener("mouse",ds),v&&(clearTimeout(v),v=null),I&&(clearTimeout(I),I=null),E&&(clearTimeout(E),E=null),N&&(clearInterval(N),N=null),j.disposeAll(),_.grabInput(!1),_.hideCursor(!1),_.fullscreen(!1)},ir=$=>{Jn(),g($)},Zn=async()=>{if(s.mode!=="main"||f)return;let $=s.shell,M=$.taskPromptInput?.trim()??"";if(!$.selectedRepoId){s={mode:"main",shell:W({...$,taskPromptError:"Select a repo first."})},C();return}if(M.length===0){s={mode:"main",shell:W({...$,taskPromptError:"Task prompt cannot be empty."})},C();return}f=!0,s={mode:"main",shell:W({...$,actionMessage:`Creating ${$.selectedRunner} task in ${$.selectedRepoId}...`})},C();let L=null;try{L=await xu(r,$.selectedRepoId,M,$.selectedRunner),await B();let H=W({...s.shell,selectedRepoId:L.repoId,selectedTaskId:L.id,selectedPtyTabId:L.selectedPtyTabId,selectedLeftItemId:`task:${L.id}`,activeTab:L.selectedPtyTabId??"agent",inputMode:"terminal",taskPromptInput:null,taskPromptError:null,actionMessage:null}),V=await j.ensureSession(L.id,H.selectedPtyTabId??Qn(L,"agent"),ns(ut(_.width,_.height)));d=os(H.selectedPtyTabId),s={mode:"main",shell:vt(H,V)},c(s.shell)}catch(H){H instanceof rr&&(L=H.task);let V=H instanceof Error?H.message:"Failed to create task.";L&&(await te(r,{...L,status:"draft",runnerSession:{...L.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:V}).catch(()=>{}),await B().catch(()=>{})),s={mode:"main",shell:W({...s.shell,inputMode:"control",selectedTaskId:L?.id??s.shell.selectedTaskId,selectedPtyTabId:L?.selectedPtyTabId??s.shell.selectedPtyTabId,selectedLeftItemId:L?`task:${L.id}`:s.shell.selectedLeftItemId,activeTab:L?.selectedPtyTabId??s.shell.activeTab,taskPromptInput:L?null:"",taskPromptError:V,actionMessage:null})}}finally{f=!1,C()}},eo=$=>{if(s.mode!=="main")return;let M=s.shell;if(M.taskPromptInput!==null){if($==="ESCAPE"){s={mode:"main",shell:W({...M,taskPromptInput:null,taskPromptError:null,actionMessage:null})},C();return}if(Ke($)){Zn();return}if($==="BACKSPACE"){s={mode:"main",shell:W({...M,taskPromptInput:M.taskPromptInput.slice(0,-1),taskPromptError:null})},C();return}if($==="CTRL_R"){s={mode:"main",shell:W({...M,selectedRunner:Fr(M.selectedRunner,a),taskPromptError:null})},C();return}Xi($)&&(s={mode:"main",shell:W({...M,taskPromptInput:`${M.taskPromptInput}${$}`,taskPromptError:null})},C())}},to=$=>{if(s.mode!=="main")return;let M=s.shell.workspaceBrowser;if(M){if($==="ESCAPE"){s={mode:"main",shell:W({...s.shell,workspaceBrowser:null,actionMessage:null})},C();return}if($==="UP"||$==="k"){s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,selectedIndex:Math.max(0,M.selectedIndex-1),error:null}})},C();return}if($==="DOWN"||$==="j"){let L=Math.max(0,M.entries.length-1);s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,selectedIndex:Math.min(L,M.selectedIndex+1),error:null}})},C();return}if($==="LEFT"||$==="h"){K(as.dirname(M.cwd)).catch(L=>{let H=L instanceof Error?L.message:"Failed to open parent directory.";s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,error:H}})},C()});return}if($==="RIGHT"||$==="l"||Ke($)){let L=M.entries[M.selectedIndex]??null;if(!L)return;if(L.kind==="directory"||($==="RIGHT"||$==="l")&&L.kind==="repo"){K(L.path).catch(H=>{let V=H instanceof Error?H.message:"Failed to open directory.";s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,error:V}})},C()});return}$t(r,L.path).then(async H=>{await B(),s={mode:"main",shell:W({...s.shell,workspaceBrowser:null,selectedLeftItemId:`repo:${H.repo.id}`,selectedRepoId:H.repo.id,selectedTaskId:null,selectedPtyTabId:null,actionMessage:`Registered workspace: ${H.repo.name}`})},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to add workspace.";s={mode:"main",shell:W({...s.shell,workspaceBrowser:{...M,error:V}})},C()})}}},cs=$=>{let M=typeof $=="string"?$:"";if(s.mode==="main"&&s.shell.taskPromptInput!==null){eo(M);return}if(s.mode==="main"&&s.shell.workspaceBrowser!==null){to(M);return}if(s.mode==="main"){let L=Vi(s.shell,M,k(s.shell));if(L.exit){ir(0);return}if(L.detachTerminal){j.detach(),s={mode:"main",shell:W(L.state)},c(s.shell),C();return}if(s.shell.inputMode==="terminal"){if(L.changed){s={mode:"main",shell:W(L.state)},c(s.shell),C();return}if(d&&Ke(M)){d=!1;return}d&&(d=!1),l=Au(M)?{key:M,at:Date.now()}:null;let H=Du(M,s.shell.terminal.scrolledBack??!1);if(H!==0){nr(H);return}j.writeKey(M);return}if(M==="CTRL_C"){ir(0);return}if(M==="?"&&s.shell.inputMode==="control"){s={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:s.shell},A=!0,C();return}if(L.pause){s={mode:"overlay",variant:"pause",menuIndex:0,optionsMessage:null,shell:W(L.state)},A=!0,C();return}if(L.beginTaskPrompt){s={mode:"main",shell:W(L.state)},c(s.shell),C();return}if(L.openWorkspaceBrowser){K(t).catch(H=>{let V=H instanceof Error?H.message:"Failed to browse workspaces.";s={mode:"main",shell:W({...L.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:V}})},C()});return}if(L.createPtyTab){Q(L.state,L.createPtyTabKind,L.createPtyTabRunner).then(H=>{ee(H)}).catch(H=>{let V=H instanceof Error?H.message:"Failed to create tab.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.closePtyTab){Y(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to close tab.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.syncPullRequest){Z(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to create or sync PR.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.refreshPullRequestChecks){he(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to refresh PR checks.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.mergeTask){He(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to merge PR.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.closeTask){Te(L.state).then(H=>{s={mode:"main",shell:H},c(s.shell),C()}).catch(H=>{let V=H instanceof Error?H.message:"Failed to close task.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}if(L.attachTerminal){ee(L.state);return}if(L.refreshInspection){U(L.state).catch(H=>{let V=H instanceof Error?H.message:"Failed to refresh inspection.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}L.changed&&(s={mode:"main",shell:W(L.state)},F(s.shell).catch(()=>{}),c(s.shell),C());return}if(s.variant==="help"){s.viaOptions&&s.parentVariant?s={mode:"overlay",variant:"options",menuIndex:1,optionsMessage:null,shell:s.shell,parentVariant:s.parentVariant}:s.parentVariant?s={mode:"overlay",variant:s.parentVariant,menuIndex:1,optionsMessage:null,shell:s.shell}:s={mode:"main",shell:W(s.shell)},A=!0,C();return}if(s.variant==="options"){ro(M);return}if(s.variant==="runners"){so(M);return}if(s.optionsMessage){(M==="ESCAPE"||Ke(M))&&(s={...s,optionsMessage:null},C());return}if(M==="UP"||M==="k"){s={...s,menuIndex:Math.max(0,s.menuIndex-1)},C();return}if(M==="DOWN"||M==="j"){s={...s,menuIndex:Math.min(2,s.menuIndex+1)},C();return}if(M==="ESCAPE"){s.variant==="pause"&&(s={mode:"main",shell:W(s.shell)},A=!0,C());return}if(Ke(M)){if(s.menuIndex===0){s={mode:"main",shell:W({...s.shell,inputMode:"control"})},A=!0,C(),b();return}if(s.menuIndex===1){let L=s.variant==="boot"||s.variant==="pause"?s.variant:void 0;s={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:s.shell,...L!==void 0?{parentVariant:L}:{}},A=!0,C();return}ir(0)}};function ro($){if(s.mode!=="overlay"||s.variant!=="options")return;let M=zn(s.menuIndex,$);if(M.kind!=="noop"){if(M.kind==="render"){s={...s,menuIndex:M.menuIndex},C();return}if(M.kind==="back"){s.parentVariant&&(s={mode:"overlay",variant:s.parentVariant,menuIndex:1,optionsMessage:null,shell:s.shell},A=!0,C());return}if(M.kind==="help"){let L=s.parentVariant;s={mode:"overlay",variant:"help",menuIndex:0,optionsMessage:null,shell:s.shell,viaOptions:!0,...L!==void 0?{parentVariant:L}:{}},A=!0,C();return}if(M.kind==="runners"){let L=s.parentVariant;s={mode:"overlay",variant:"runners",menuIndex:0,optionsMessage:null,shell:s.shell,...L!==void 0?{parentVariant:L}:{}},A=!0,C()}}}function so($){if(s.mode!=="overlay"||s.variant!=="runners")return;let M=Vn(Rt(s),i,$,a);if(M.kind!=="noop"){if(M.kind==="back"){let L=s.parentVariant;s={mode:"overlay",variant:"options",menuIndex:0,optionsMessage:null,shell:s.shell,...L!==void 0?{parentVariant:L}:{}},A=!0,C();return}if(M.kind==="render"){s={...s,runnerOptions:M.state},C();return}R(M.config).then(()=>{s.mode!=="overlay"||s.variant!=="runners"||(s={...s,runnerOptions:M.state},C())}).catch(L=>{if(s.mode!=="overlay"||s.variant!=="runners")return;let H=L instanceof Error?L.message:"Failed to save runner option.";s={...s,runnerOptions:{...Rt(s),message:H}},C()})}}let ls=$=>{let M=Eu($);if(s.mode!=="main"||s.shell.inputMode!=="terminal"||M.length===0)return;if(M.includes("")){j.detach(),d=!1,l=null,s={mode:"main",shell:W({...s.shell,inputMode:"control",actionMessage:null})},c(s.shell),C();return}let L=Lu(M);if(L!==0){nr(L);return}if(d&&M!=="\r"&&M!==`
|
|
98
98
|
`&&M!==`\r
|
|
99
99
|
`&&(d=!1),Mu(d,l,M)){d=!1;return}j.write(M)},ds=$=>{if(s.mode!=="main")return;if(s.shell.inputMode==="control"){no(Xn($));return}let M=Xn($);M!==0&&nr(M)};function nr($){u+=$,!v&&(v=setTimeout(()=>{v=null;let M=u;u=0,M!==0&&(io(M),C())},16))}function io($){j.scrollViewport($),s={mode:"main",shell:z(s.shell)}}function no($){$!==0&&(m+=$,!I&&(I=setTimeout(()=>{I=null;let M=m;if(m=0,M===0||s.mode!=="main"||s.shell.inputMode!=="control")return;let L=qe(s.shell,M,k(s.shell));if(L.changed){if(L.refreshInspection){U(L.state).catch(H=>{let V=H instanceof Error?H.message:"Failed to refresh inspection.";s={mode:"main",shell:W({...L.state,actionMessage:V})},C()});return}s={mode:"main",shell:W(L.state)},c(s.shell),C()}},16)))}let us=()=>{A=!0,s.mode==="main"&&s.shell.inputMode==="terminal"&&(j.resize(ns(ut(_.width,_.height))),s={mode:"main",shell:z(s.shell)}),C()};process.stdout.on("resize",us),_.grabInput(!0),D="control",_.hideCursor(!0),_.fullscreen(!0),_.on("key",cs),_.on("unknown",ls),_.on("mouse",ds),N=setInterval(()=>{fe()},(i.github?.watchIntervalSeconds??10)*1e3),C()})}async function Ct(e,t,r){let i=$e(e),[a,y]=await Promise.all([gt(i),et(i)]),T=vu(y.tasks,t),n=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},h=T?await vi(T,n):null;return{workspaceRoot:e,repos:a,tasks:y.tasks,inspection:h,...r?{enabledRunnerIds:r}:{}}}function vu(e,t){return t?.selectedTaskId?e.find(r=>r.id===t.selectedTaskId)??null:null}function ku(e,t){return Ut(e,t)}function Tu(e,t){let r=new Set(t);return e.filter(i=>{let a=i.path.split("/");for(let y=1;y<a.length;y+=1)if(r.has(a.slice(0,y).join("/")))return!1;return!0})}function Cu(e){let t=[];for(let r of e.repos){t.push(`repo:${r.id}`);for(let i of e.tasks.filter(a=>a.repoId===r.id))t.push(`task:${i.id}`);t.push(`new-task:${r.id}`)}return t.push("new-workspace"),t}function Ru(e,t,r){let i=e.tasks.find(y=>y.ptyTabs.some(T=>T.id===t))??null,a=i?.ptyTabs.find(y=>y.id===t)??null;return{cwd:i?.worktreePath??r,command:a?.kind==="agent"?Pu(a):[]}}function Pu(e){return e.command.length>0?e.command:["codex"]}function Rt(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function Iu(e,t,r){return e.ptyTabs.find(i=>i.id===t)?.kind??r}function Gn(e,t,r,i={}){let a=r??e.runner,y=pe(a),T=t==="agent"?y.defaultAgentTitle:"Terminal",n=t==="agent"&&r&&r!==e.runner?`${e.id}:${r}`:`${e.id}:${t}`,h=new Set(e.ptyTabs.map(c=>c.id)),p=1,S=n;for(;h.has(S);)p+=1,S=`${n}-${p}`;let o=new Date().toISOString(),w=r&&r!==e.runner?r:void 0;return{id:S,kind:t,...w?{runner:w}:{},title:p===1?T:`${T} ${p}`,command:t==="agent"?ge(a,void 0,i):[],createdAt:o,updatedAt:o}}async function xu(e,t,r,i){let a=await _e(e);Pt(i,a);let y=await Bt(e,t,r,{runner:i,config:a});try{let h=Qe();await J(Je(ar(i,a).executable,{cwd:y.repoRoot,env:h}),["--help"],{cwd:y.repoRoot,env:h})}catch(h){let p=h instanceof Error?h.message:"Failed to start runner.",S={...y.task,status:"draft",runnerSession:{...y.task.runnerSession,lastKnownState:"failed",exitedAt:new Date().toISOString()},lastFailureReason:p};throw await te(e,S),new rr(p,S)}let T=Qn(y.task,"agent"),n={...y.task,status:"running",selectedPtyTabId:T,runnerSession:{...y.task.runnerSession,startedAt:new Date().toISOString(),lastKnownState:"running"}};return await te(e,n),await ve({uiStateFile:e.uiStateFile},{...await Pe({uiStateFile:e.uiStateFile})??Le(),version:1,selectedRepoId:n.repoId,selectedWorkspaceId:n.workspaceId,selectedTaskId:n.id,selectedPtyTabId:n.selectedPtyTabId,inputMode:"control",focusedRegion:"center",activeTab:n.selectedPtyTabId??"agent",selectedActionId:"commit",updatedAt:new Date().toISOString()}),n}var rr=class extends Error{task;constructor(t,r){super(t),this.name="InteractiveTaskStartupError",this.task=r}};function Qn(e,t){let r=e.ptyTabs.find(i=>i.kind===t);if(!r)throw new Error(`Task ${e.id} is missing its ${t} PTY tab.`);return r.id}function ns(e){return{columns:Math.max(20,e.width-Ee.leftWidth-Ee.rightWidth-Ee.dividerWidth-Zt*2),rows:Math.max(5,e.height-Ee.topRailHeight-4)}}function Eu(e){return typeof e=="string"?e:Buffer.isBuffer(e)?e.toString("utf8"):""}function Au(e){return e.length===1||Ke(e)||e==="BACKSPACE"||e==="TAB"}function os(e){return typeof e=="string"&&/:agent(?:-\d+)?$/.test(e)}function Du(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 Xn(e){return e==="MOUSE_WHEEL_UP"?-3:e==="MOUSE_WHEEL_DOWN"?3:0}function Lu(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 Mu(e,t,r){return r.length===0?!1:e&&(r==="\r"||r===`
|
|
100
100
|
`||r===`\r
|