craig-cli 0.6.5 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -90
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<pre>
|
|
3
|
-
|
|
3
|
+
▄████▄ ██▀███ ▄▄▄ ██▓ ▄████
|
|
4
4
|
▒██▀ ▀█ ▓██ ▒ ██▒▒████▄ ▓██▒ ██▒ ▀█▒
|
|
5
5
|
▒▓█ ▄ ▓██ ░▄█ ▒▒██ ▀█▄ ▒██▒▒██░▄▄▄░
|
|
6
6
|
▒▓▓▄ ▄██▒▒██▀▀█▄ ░██▄▄▄▄██ ░██░░▓█ ██▓
|
|
@@ -9,15 +9,26 @@
|
|
|
9
9
|
░ ▒ ░▒ ░ ▒░ ▒ ▒▒ ░ ▒ ░ ░ ░
|
|
10
10
|
░ ░░ ░ ░ ▒ ▒ ░░ ░ ░
|
|
11
11
|
░ ░ ░ ░ ░ ░ ░
|
|
12
|
-
░
|
|
13
12
|
|
|
14
13
|
crAIg is that you?
|
|
14
|
+
|
|
15
15
|
</pre>
|
|
16
|
+
|
|
17
|
+
**An agnostic agent orchestrator. For the people.**
|
|
18
|
+
|
|
19
|
+
[](https://www.npmjs.com/package/craig-cli)
|
|
20
|
+
[](LICENSE)
|
|
21
|
+
[](https://nodejs.org)
|
|
22
|
+
|
|
23
|
+
[craig.beer](https://craig.beer) · [Docs](https://craig.beer/docs) · [Quickstart](https://craig.beer/docs/quickstart)
|
|
24
|
+
|
|
16
25
|
</div>
|
|
17
26
|
|
|
18
|
-
|
|
27
|
+
---
|
|
19
28
|
|
|
20
|
-
Craig is a
|
|
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. Review diffs, run checks, and merge PRs without ever leaving Craig.
|
|
30
|
+
|
|
31
|
+
it's like a game, except the PRs are real.
|
|
21
32
|
|
|
22
33
|
## Install
|
|
23
34
|
|
|
@@ -25,41 +36,39 @@ Craig is a local terminal control plane for repo-backed agent work. The primary
|
|
|
25
36
|
npm install -g craig-cli
|
|
26
37
|
```
|
|
27
38
|
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
39
|
+
Requires Node 22+, `git`, and `gh` (authenticated). Bring your own agent CLI — Claude Code, Codex, or Cursor.
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
## Start
|
|
39
42
|
|
|
40
43
|
```bash
|
|
41
44
|
cd path/to/your/workspace
|
|
42
45
|
craig
|
|
43
46
|
```
|
|
44
47
|
|
|
45
|
-
The TUI opens with a boot overlay, then a workspace
|
|
48
|
+
The TUI opens with a boot overlay, then a three-panel workspace: task navigation on the left, live agent PTY in the center, file/diff/review inspector on the right.
|
|
46
49
|
|
|
47
|
-
Craig
|
|
50
|
+
Craig writes all local state under `.craig/` — worktrees, logs, task records, PR metadata. Don't commit it.
|
|
48
51
|
|
|
49
|
-
##
|
|
52
|
+
## Workflow
|
|
50
53
|
|
|
51
|
-
1.
|
|
52
|
-
2.
|
|
53
|
-
3. Press `
|
|
54
|
-
4.
|
|
55
|
-
5.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
1. Press `n` to create a task — type a prompt, pick a runner, press `Enter`.
|
|
55
|
+
2. Craig creates the branch, worktree, and agent tab automatically.
|
|
56
|
+
3. Press `Enter` on the task to attach its live PTY. `Ctrl+]` to return to control mode.
|
|
57
|
+
4. Use the **Files**, **Changes**, and **Review** inspector panels to check the diff and CI status.
|
|
58
|
+
5. `craig task pr <task-id> --watch` — creates the PR and waits for checks before merging.
|
|
59
|
+
|
|
60
|
+
## Polyrepo support
|
|
61
|
+
|
|
62
|
+
Point Craig at a directory containing multiple repos and it treats them as a single workspace. Create a task once — Craig provisions a worktree for each repo and runs the agent across all of them in one pass.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cd path/to/your/projects # contains repo-a/, repo-b/, repo-c/
|
|
66
|
+
craig
|
|
67
|
+
```
|
|
59
68
|
|
|
60
69
|
## TUI Keys
|
|
61
70
|
|
|
62
|
-
```
|
|
71
|
+
```
|
|
63
72
|
Global
|
|
64
73
|
? help
|
|
65
74
|
Esc pause / back
|
|
@@ -69,17 +78,13 @@ Global
|
|
|
69
78
|
|
|
70
79
|
Navigation
|
|
71
80
|
Up/Down, j/k move selection
|
|
72
|
-
Left/Right,
|
|
73
|
-
h/l switch tabs or inspector mode
|
|
81
|
+
Left/Right, h/l switch tabs or inspector mode
|
|
74
82
|
|
|
75
83
|
Tasks
|
|
76
84
|
n new task
|
|
77
85
|
Enter attach selected task PTY
|
|
78
86
|
X close selected task
|
|
79
87
|
|
|
80
|
-
Workspaces
|
|
81
|
-
X remove selected empty workspace
|
|
82
|
-
|
|
83
88
|
Center panel
|
|
84
89
|
Enter attach PTY
|
|
85
90
|
+ new tab
|
|
@@ -94,33 +99,25 @@ Review
|
|
|
94
99
|
|
|
95
100
|
Terminal mode
|
|
96
101
|
Ctrl+] return to control mode
|
|
97
|
-
Wheel,
|
|
98
|
-
PgUp/PgDn scroll terminal
|
|
102
|
+
Wheel, PgUp/PgDn scroll terminal
|
|
99
103
|
```
|
|
100
104
|
|
|
101
|
-
## Command
|
|
102
|
-
|
|
103
|
-
Use command mode when scripting, debugging, or working outside the TUI.
|
|
105
|
+
## Command mode
|
|
104
106
|
|
|
105
107
|
```bash
|
|
106
|
-
craig
|
|
107
|
-
|
|
108
108
|
craig repo add <path>
|
|
109
109
|
craig repo list
|
|
110
110
|
craig repo remove <repo-id>
|
|
111
111
|
|
|
112
112
|
craig workspace list
|
|
113
|
-
craig workspace list --archived
|
|
114
113
|
craig workspace archive <workspace-id>
|
|
115
114
|
craig workspace restore <workspace-id>
|
|
116
115
|
craig workspace remove <workspace-id>
|
|
117
116
|
|
|
118
117
|
craig task new --repo <repo-id> [--runner codex|cursor|claude] "<task>"
|
|
119
118
|
craig task list
|
|
120
|
-
craig task list --repo <repo-id>
|
|
121
119
|
craig task show <task-id>
|
|
122
120
|
craig task attach <task-id>
|
|
123
|
-
craig task open <task-id>
|
|
124
121
|
craig task logs <task-id>
|
|
125
122
|
craig task diff <task-id>
|
|
126
123
|
craig task check <task-id>
|
|
@@ -132,9 +129,9 @@ craig link add <task-id> <repo-id>
|
|
|
132
129
|
craig link list <task-id>
|
|
133
130
|
```
|
|
134
131
|
|
|
135
|
-
##
|
|
132
|
+
## Config
|
|
136
133
|
|
|
137
|
-
|
|
134
|
+
Optional workspace-local config at `.craig/config.json`:
|
|
138
135
|
|
|
139
136
|
```json
|
|
140
137
|
{
|
|
@@ -148,59 +145,28 @@ Craig reads optional workspace-local config from `.craig/config.json`.
|
|
|
148
145
|
},
|
|
149
146
|
"github": {
|
|
150
147
|
"mergeMethod": "squash",
|
|
151
|
-
"watchIntervalSeconds":
|
|
148
|
+
"watchIntervalSeconds": 5
|
|
152
149
|
}
|
|
153
150
|
}
|
|
154
151
|
```
|
|
155
152
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
## Local State
|
|
159
|
-
|
|
160
|
-
Craig writes local state under `.craig/`:
|
|
161
|
-
|
|
162
|
-
```text
|
|
163
|
-
.craig/
|
|
164
|
-
artifacts/
|
|
165
|
-
logs/
|
|
166
|
-
runtime/
|
|
167
|
-
tasks/
|
|
168
|
-
workspaces/
|
|
169
|
-
worktrees/
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Treat `.craig/` as private developer state. It can contain task prompts, terminal logs, local paths, branch names, PR metadata, runtime state, and worktrees. Do not commit `.craig/` or share it in public issues.
|
|
153
|
+
## Contributing
|
|
173
154
|
|
|
174
|
-
Craig
|
|
155
|
+
Craig is open source under MIT, but not a community-maintained project. Bug reports and focused questions are welcome. PRs should be discussed with the maintainer first — unsolicited PRs may be closed without review.
|
|
175
156
|
|
|
176
|
-
|
|
157
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md).
|
|
177
158
|
|
|
178
|
-
|
|
159
|
+
## Development
|
|
179
160
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
191
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
192
|
-
in the Software without restriction, including without limitation the rights
|
|
193
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
194
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
195
|
-
furnished to do so, subject to the following conditions:
|
|
196
|
-
|
|
197
|
-
The above copyright notice and this permission notice shall be included in all
|
|
198
|
-
copies or substantial portions of the Software.
|
|
161
|
+
```bash
|
|
162
|
+
pnpm install
|
|
163
|
+
pnpm test
|
|
164
|
+
pnpm typecheck
|
|
165
|
+
pnpm lint
|
|
166
|
+
pnpm build
|
|
167
|
+
pnpm build:npm
|
|
168
|
+
pnpm package:audit
|
|
169
|
+
pnpm package:smoke
|
|
170
|
+
```
|
|
199
171
|
|
|
200
|
-
|
|
201
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
202
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
203
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
204
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
205
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
206
|
-
SOFTWARE.
|
|
172
|
+
The npm package is published as `craig-cli` from `packages/cli`.
|
package/dist/cli.js
CHANGED
|
@@ -154,7 +154,7 @@ ${o.slice(-2e3)}`:""}`)}async function Ni(e){let t=await Cf(e).catch(()=>null);r
|
|
|
154
154
|
`)}function Yi(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=It(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)}${mn(T.text,l)}`,V=T.tone==="selected"?v.overlayMenuSelected:T.tone==="muted"?v.overlay:v.panelBg;s[I]=O(Pe(a,e.width),n,V)}return s.join(`
|
|
155
155
|
`)}function Ji(e,t,n={}){let r=n.color??!0,s=me.leftWidth,o=me.rightWidth,i=me.dividerWidth,c=n.centerOnly??!1,l=c?e.width:e.width-s-o-i*2,d=e.height-me.topRailHeight-1,f=`CRAIG | ${t.topRail.workspacePath} | ${t.topRail.agent}`,h=O(Pe(f,e.width),r,v.rail),R=Nf(t,s-dn-un,d,r),k=Wf(t,l,d,r),I=Bf(t,o,d,r),T=t.inputMode==="terminal",a=[];for(let q=0;q<d;q+=1){if(c){a.push(ln(k[q]??ee(),l,r,"center"));continue}let C=ln(R[q]??ee(),s,r,"left"),je=O("\u2502",r,v.divider),xe=ln(k[q]??ee(),l,r,"center"),ve=O("\u2502",r,v.divider),Ee=ln(I[q]??ee(),o,r,"right");a.push(`${C}${je}${xe}${ve}${Ee}`)}let V=T||t.modalInput?v.panelBg:v.panelMuted,F=Ff(t.footerText,t.footerToast,e.width,r,V);return[h,...a,F].join(`
|
|
156
156
|
`)}function Ff(e,t,n,r,s){let o=` ${e}`;if(!t)return O(Pe(o,n),r,s);let i=`${t.tone==="error"?"\u2717":"\u2713"} ${t.message}`,c=X(i),l=X(o),d=Math.max(1,n-l-c-2),f=l+d+c+2>n?mn(o,Math.max(0,n-c-3)):o,h=Math.max(1,n-X(f)-c-2),R=t.tone==="error"?ip(i,r,s):rt(i,r,s),k=`${f}${" ".repeat(h)}${R} `;return O(Pe(k,n),r,s)}function Dr(e,t){let n=new Array(e.height).fill(O(" ".repeat(e.width),t.color,v.overlay)),r=Er(),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=Zi(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-X(f)));n[e.height-1]=O(`${h}${Mr(f,t.color,v.overlay)}`,t.color,v.overlay)}return n.join(`
|
|
157
|
-
`)}function Nf(e,t,n,r){let s=Kf(e.runners),o=1,i=e.leftTree.map(l=>Uf(l,t,r));return[...It(i,n-o),s]}function Wf(e,t,n,r){let s=t-2,o=e.tabs.find(C=>C.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:rp(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?rt(l,r,v.panelBg):pn(l,r,v.panelMuted)}`,f=[`${pn(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"||!oi(h)?e.centerTranscript.map(C=>({...C})):_f(e),k=Vf(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?rt(`${I}\u25CF `,r,v.panelBg):"",V=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-X(k)-T)):"",q=[{text:e.inputMode==="terminal"?`${k}${V}${a}`:k},{text:d,tone:"muted"},{text:f},ee(),...R];return It(q,n)}function _f(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:na(r.segments),segments:r.segments,fullBleed:!0}))}function Bf(e,t,n,r){let s=e.rightInspection?qf(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):It([{text:"CONTEXT"},ee(),...e.rightContext.map(o=>Gf(o,r)),...e.actionMessage?[ee(),{text:e.actionMessage}]:[]],n);return It(s,n)}function qf(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:op(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Ui(c)),...r.slice(i,i+s).map(c=>Ui(c))]}function Ui(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 Uf(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${rt("\u25CF",n,e.selected?v.panelSelected:v.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+X(I.text),0):0,l=t-X(o)-X(s)-c,d=e.selected?e.text:e.focused?rt(e.text,n,v.panelBg):e.panelHeader?pn(e.text,n,v.panelMuted):e.text,f=Pe(`${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 Kf(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 Vf(e,t,n){return e.map(r=>r.active?n?rt(r.label,t,v.panelBg):pn(r.label,t,v.panelBg):Mr(r.label,t,v.panelBg)).join(" ")}function Gf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?Mr(e.value,t,v.panelBg):e.value}`}}function ln(e,t,n,r){let s=Hf(r,e.tone??"default"),o=zf(e,n,s);if(r==="left"){if(e.fullBleed)return O(Pe(o,t),n,s);let c=t-dn-un;if(e.rightAlign){let d=X(o),f=Math.max(0,c-d),h=`${" ".repeat(dn)}${" ".repeat(f)}${o}${" ".repeat(un)}`;return O(h,n,s)}let l=`${" ".repeat(dn)}${Pe(o,c)}${" ".repeat(un)}`;return O(l,n,s)}return r==="center"&&e.fullBleed?Yf(e,t,n,s):O(Pe(` ${o}`,t),n,s)}function Hf(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function It(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(ee());return n}function ee(){return{text:""}}function zf(e,t,n){return e.segments?e.segments.map(r=>Qi(r,t,n)).join(""):e.text}function Yf(e,t,n,r){let s=" ".repeat(fn),o=Math.max(0,t-fn*2);if(!e.segments)return O(`${s}${Pe(e.text,o)}${s}`,n,r);let i=Xf(e.segments,o),c=`${s}${i.map(l=>Qi(l,n,r)).join("")}${s}`;return O(c,n,r)}function Qi(e,t,n){let r=e.href?`${Xi(e.href)}${e.text}${Vi}`:Jf(e.text);return!t||!e.style?r:`${St(tp(e.style,n))}${np(e.style)}${r}${Ar}${St(n)}`}function Jf(e){return e.replace(Of,t=>{let[n,r]=Qf(t);return`${Xi(n)}${n}${Vi}${r}`})}function Qf(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function Xi(e){return`\x1B]8;;${e}\x1B\\`}function Xf(e,t){let n=Zf(e,t);return ep(n,t)}function Zf(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=X(s.text);if(o<=r){n.push(s),r-=o;continue}let i=mn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function ep(e,t){let n=X(na(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 tp(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 np(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 rp(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function Zi(e,t){let n=Math.max(0,t-X(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Pe(e,t){let n=X(e);return n>=t?sp(e,t):e+" ".repeat(t-n)}function sp(e,t){if(t<=0)return"";if(X(e)<=t)return e;let n=ta(e);return mn(n,Math.max(0,t-1))+"\u2026"}function X(e){let t=0;for(let n of Array.from(ta(e)))t+=ea(n);return t}function mn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=ea(s);if(r+o>t)break;n+=s,r+=o}return n}function ea(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?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 op(e,t,n){return Math.min(Math.max(e,t),n)}function ta(e){return e.replace(Lf,"").replace(Df,"")}function na(e){return e.map(t=>t.text).join("")}function O(e,t,n){if(!t)return e;let r=St(n),s=e.replace(Mf,`${Ar}${r}`);return`${r}${s}${Ar}`}function St(e){let t=[];return e.fg&&t.push(`38;2;${Ki(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Ki(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Ki(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function rt(e,t,n){return gn(e,t,v.success.fg,n)}function ip(e,t,n){return gn(e,t,v.error.fg,n)}function pn(e,t,n){return gn(e,t,v.accent.fg,n)}function Mr(e,t,n){return gn(e,t,v.mutedfg.fg,n)}function gn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${St(s)}${e}${St(r)}`}var ap="https://registry.npmjs.org/craig-cli/latest";var hn=null;function Lr(){try{return"0.6.5"}catch{return"unknown"}}async function ra(){let e=Lr(),t=Date.now();if(hn&&t-hn.cachedAt<36e5)return hn.result;let n=null;try{let s=await fetch(ap,{signal:AbortSignal.timeout(5e3)});s.ok&&(n=(await s.json()).version??null)}catch{}let r={current:e,latest:n,updateAvailable:n!==null&&n!==e&&cp(n,e)};return hn={result:r,cachedAt:t},r}function cp(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}le();var Or=["Runners","Error Log","Help"];function jr(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 oa(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 ia(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Or.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Fr(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function aa(e,t,n,r){if(e.pathEdit)return lp({...e,pathEdit:e.pathEdit},t,n);let s=jr(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(!Fr(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:dp(t,o,!i),state:{...e,message:`${Z(o).displayName} ${i?"disabled":"enabled"}.`}}}function lp(e,t,n){if(n==="ESCAPE")return{kind:"render",state:sa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Fr(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:up(t,r,s.length>0?s:null),state:sa({...e,message:s.length>0?`${Z(r).displayName} executable saved.`:`${Z(r).displayName} executable reset to default.`})}}return fp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function dp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function up(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function sa(e){let t={...e};return delete t.pathEdit,t}function Fr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
157
|
+
`)}function Nf(e,t,n,r){let s=Kf(e.runners),o=1,i=e.leftTree.map(l=>Uf(l,t,r));return[...It(i,n-o),s]}function Wf(e,t,n,r){let s=t-2,o=e.tabs.find(C=>C.active)?.label??"AGENT",i=e.inputMode==="terminal"?0:rp(e.tabs),c=e.inputMode==="terminal"?s:o.length+1,l="\u2500".repeat(Math.max(0,c)),d=`${" ".repeat(i)}${e.inputMode==="terminal"?rt(l,r,v.panelBg):pn(l,r,v.panelMuted)}`,f=[`${pn(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"||!oi(h)?e.centerTranscript.map(C=>({...C})):_f(e),k=Vf(e.tabs,r,e.focusedRegion==="center"),I=" engaged ",T=I.length+2,a=e.inputMode==="terminal"?rt(`${I}\u25CF `,r,v.panelBg):"",V=e.inputMode==="terminal"?" ".repeat(Math.max(0,s-X(k)-T)):"",q=[{text:e.inputMode==="terminal"?`${k}${V}${a}`:k},{text:d,tone:"muted"},{text:f},ee(),...R];return It(q,n)}function _f(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:na(r.segments),segments:r.segments,fullBleed:!0}))}function Bf(e,t,n,r){let s=e.rightInspection?qf(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):It([{text:"CONTEXT"},ee(),...e.rightContext.map(o=>Gf(o,r)),...e.actionMessage?[ee(),{text:e.actionMessage}]:[]],n);return It(s,n)}function qf(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:op(o-Math.floor(s/2),0,Math.max(0,r.length-s));return[...n.map(c=>Ui(c)),...r.slice(i,i+s).map(c=>Ui(c))]}function Ui(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 Uf(e,t,n){let r=" ".repeat(e.indent??0),s=e.accentDot?" \u25CF":"",o=e.status?` ${e.status}`:"",i=e.accentDot?` ${rt("\u25CF",n,e.selected?v.panelSelected:v.panelBg)}`:"",c=e.prBadge?e.prBadge.reduce((k,I)=>k+X(I.text),0):0,l=t-X(o)-X(s)-c,d=e.selected?e.text:e.focused?rt(e.text,n,v.panelBg):e.panelHeader?pn(e.text,n,v.panelMuted):e.text,f=Pe(`${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 Kf(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 Vf(e,t,n){return e.map(r=>r.active?n?rt(r.label,t,v.panelBg):pn(r.label,t,v.panelBg):Mr(r.label,t,v.panelBg)).join(" ")}function Gf(e,t){return{text:`${e.label.padEnd(8," ")} ${e.mutedValue?Mr(e.value,t,v.panelBg):e.value}`}}function ln(e,t,n,r){let s=Hf(r,e.tone??"default"),o=zf(e,n,s);if(r==="left"){if(e.fullBleed)return O(Pe(o,t),n,s);let c=t-dn-un;if(e.rightAlign){let d=X(o),f=Math.max(0,c-d),h=`${" ".repeat(dn)}${" ".repeat(f)}${o}${" ".repeat(un)}`;return O(h,n,s)}let l=`${" ".repeat(dn)}${Pe(o,c)}${" ".repeat(un)}`;return O(l,n,s)}return r==="center"&&e.fullBleed?Yf(e,t,n,s):O(Pe(` ${o}`,t),n,s)}function Hf(e,t){return t==="selected"||t==="focused"?v.panelSelected:t==="muted"?v.panelMuted:v.panelBg}function It(e,t){let n=e.slice(0,t);for(;n.length<t;)n.push(ee());return n}function ee(){return{text:""}}function zf(e,t,n){return e.segments?e.segments.map(r=>Qi(r,t,n)).join(""):e.text}function Yf(e,t,n,r){let s=" ".repeat(fn),o=Math.max(0,t-fn*2);if(!e.segments)return O(`${s}${Pe(e.text,o)}${s}`,n,r);let i=Xf(e.segments,o),c=`${s}${i.map(l=>Qi(l,n,r)).join("")}${s}`;return O(c,n,r)}function Qi(e,t,n){let r=e.href?`${Xi(e.href)}${e.text}${Vi}`:Jf(e.text);return!t||!e.style?r:`${St(tp(e.style,n))}${np(e.style)}${r}${Ar}${St(n)}`}function Jf(e){return e.replace(Of,t=>{let[n,r]=Qf(t);return`${Xi(n)}${n}${Vi}${r}`})}function Qf(e){let t=e.length;for(;t>0&&".,;:!?)]}".includes(e[t-1]??"");)t-=1;return[e.slice(0,t),e.slice(t)]}function Xi(e){return`\x1B]8;;${e}\x1B\\`}function Xf(e,t){let n=Zf(e,t);return ep(n,t)}function Zf(e,t){let n=[],r=t;for(let s of e){if(r<=0)break;let o=X(s.text);if(o<=r){n.push(s),r-=o;continue}let i=mn(s.text,r);i.length>0&&n.push({...s,text:i}),r=0}return n}function ep(e,t){let n=X(na(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 tp(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 np(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 rp(e){let t=0;for(let n of e){if(n.active)return t;t+=n.label.length+3}return 0}function Zi(e,t){let n=Math.max(0,t-X(e)),r=Math.floor(n/2),s=n-r;return`${" ".repeat(r)}${e}${" ".repeat(s)}`}function Pe(e,t){let n=X(e);return n>=t?sp(e,t):e+" ".repeat(t-n)}function sp(e,t){if(t<=0)return"";if(X(e)<=t)return e;let n=ta(e);return mn(n,Math.max(0,t-1))+"\u2026"}function X(e){let t=0;for(let n of Array.from(ta(e)))t+=ea(n);return t}function mn(e,t){let n="",r=0;for(let s of Array.from(e)){let o=ea(s);if(r+o>t)break;n+=s,r+=o}return n}function ea(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?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 op(e,t,n){return Math.min(Math.max(e,t),n)}function ta(e){return e.replace(Lf,"").replace(Df,"")}function na(e){return e.map(t=>t.text).join("")}function O(e,t,n){if(!t)return e;let r=St(n),s=e.replace(Mf,`${Ar}${r}`);return`${r}${s}${Ar}`}function St(e){let t=[];return e.fg&&t.push(`38;2;${Ki(e.fg).join(";")}`),e.bg&&t.push(`48;2;${Ki(e.bg).join(";")}`),`\x1B[${t.join(";")}m`}function Ki(e){return[Number.parseInt(e.slice(0,2),16),Number.parseInt(e.slice(2,4),16),Number.parseInt(e.slice(4,6),16)]}function rt(e,t,n){return gn(e,t,v.success.fg,n)}function ip(e,t,n){return gn(e,t,v.error.fg,n)}function pn(e,t,n){return gn(e,t,v.accent.fg,n)}function Mr(e,t,n){return gn(e,t,v.mutedfg.fg,n)}function gn(e,t,n,r){if(!t)return e;let s=r.bg?{fg:n,bg:r.bg}:{fg:n};return`${St(s)}${e}${St(r)}`}var ap="https://registry.npmjs.org/craig-cli/latest";var hn=null;function Lr(){try{return"0.6.7"}catch{return"unknown"}}async function ra(){let e=Lr(),t=Date.now();if(hn&&t-hn.cachedAt<36e5)return hn.result;let n=null;try{let s=await fetch(ap,{signal:AbortSignal.timeout(5e3)});s.ok&&(n=(await s.json()).version??null)}catch{}let r={current:e,latest:n,updateAvailable:n!==null&&n!==e&&cp(n,e)};return hn={result:r,cachedAt:t},r}function cp(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}le();var Or=["Runners","Error Log","Help"];function jr(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 oa(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 ia(e,t){return t==="UP"||t==="k"?{kind:"render",menuIndex:Math.max(0,e-1)}:t==="DOWN"||t==="j"?{kind:"render",menuIndex:Math.min(Or.length-1,e+1)}:t==="ESCAPE"?{kind:"back"}:Fr(t)?e===0?{kind:"runners"}:e===1?{kind:"error-log"}:{kind:"help"}:{kind:"noop",menuIndex:e}}function aa(e,t,n,r){if(e.pathEdit)return lp({...e,pathEdit:e.pathEdit},t,n);let s=jr(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(!Fr(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:dp(t,o,!i),state:{...e,message:`${Z(o).displayName} ${i?"disabled":"enabled"}.`}}}function lp(e,t,n){if(n==="ESCAPE")return{kind:"render",state:sa({...e,message:null})};if(n==="BACKSPACE")return{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:e.pathEdit.value.slice(0,-1)}}};if(Fr(n)){let r=e.pathEdit.runner,s=e.pathEdit.value.trim();return{kind:"save",config:up(t,r,s.length>0?s:null),state:sa({...e,message:s.length>0?`${Z(r).displayName} executable saved.`:`${Z(r).displayName} executable reset to default.`})}}return fp(n)?{kind:"render",state:{...e,pathEdit:{...e.pathEdit,value:`${e.pathEdit.value}${n}`}}}:{kind:"noop",state:e}}function dp(e,t,n){return{...e,runners:{...e.runners??{},[t]:{...e.runners?.[t]??{},enabled:n}}}}function up(e,t,n){let r={...e.runners?.[t]??{},...n?{path:n}:{}};return n||delete r.path,{...e,runners:{...e.runners??{},[t]:r}}}function sa(e){let t={...e};return delete t.pathEdit,t}function Fr(e){return e==="ENTER"||e==="RETURN"||e==="CTRL_M"||e==="\r"||e===`
|
|
158
158
|
`}function fp(e){return e.length===1&&e>=" "&&e!=="\x7F"}var hp=pp(import.meta.url),wp=hp("terminal-kit"),kp=wp.terminal;async function da(e={}){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Craig terminal shell requires a TTY.");let t=e.workspaceRoot??process.cwd(),n=be(t);await tt(t);let r=await we(n),s=Ye(r),o=e.uiStateFile?await de({uiStateFile:e.uiStateFile}):null,i=Promise.resolve(),c=Promise.resolve(),l=await Ct(t,void 0,s),d=en(ei(o,r),l);l=await Ct(t,d,s);let f=()=>{},h={workspaceRoot:t,onUpdate:()=>f(),resolveSessionSpec:(I,T)=>Pp(l,T,t)},R=e.ptyRuntime??await Oi({...h,paths:n}),k=I=>{if(!e.uiStateFile)return;o=ti(o,I);let T=o;i=i.then(()=>oe({uiStateFile:e.uiStateFile},T),()=>oe({uiStateFile:e.uiStateFile},T)),i.catch(()=>{})};return new Promise(I=>{let T=e.terminal??kp,a={mode:"overlay",variant:"boot",menuIndex:0,optionsMessage:null,shell:en(d,l)},V=!1,F=!1,q=null,C=0,je=0,xe=null,ve=null,Ee=null,Ae=null,Et=null,Rn=!1,Tn=null,Wr=`Craig v${Lr()}`,yn=null,Pn=0,G=!0,bn=null,y=()=>{},j=R;f=()=>{a.mode==="main"&&(a={mode:"main",shell:ot(a.shell)},Ee||(Ee=setTimeout(()=>{Ee=null,a.mode==="main"&&y()},50)))};function ot(m){return He(m,j.getViewState(_r(m)))}function _r(m){let u=it(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 ot(Rp(m,l))}function it(m){return l.tasks.find(u=>u.id===m.selectedTaskId)??null}async function Br(){let m=l.tasks.flatMap(u=>u.ptyTabs.map(p=>p.id));await j.pruneStale?.(m),await j.hydrateSessions?.(m)}function pa(){Br().catch(()=>{}).then(()=>{a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},y())})}async function ma(m){let u=P(m),p=it(u),g=_r(u);if(!p||!g||!p.ptyTabs.some(L=>L.id===g))return u;let w=j.getViewState(g);if(w.status!=="idle"||w.rows.length>0||w.error)return He(u,w);let S=await j.ensureSession(p.id,g,vt(Oe(T.width,T.height)));return He({...u,inputMode:"control"},S)}function qr(m,u){return Ae&&(clearTimeout(Ae),Ae=null),u?(Ae=setTimeout(()=>{Ae=null,!(a.mode!=="main"||a.shell.footerToast!==u)&&(a={mode:"main",shell:P({...a.shell,footerToast:null})},y())},3e3),{...m,footerToast:u}):{...m,footerToast:null}}function ga(m,u){return qr(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 rr(n,{context:m,message:g,details:w}),g}function H(m,u){return qr(m,{tone:"error",message:u})}function Fe(m){let u=c.then(m,m);return c=u.then(()=>{},()=>{}),u}function Ur(m){let u=it(m),p=l.inspection,g=p&&p.taskId===u?.id?p:null,w=Tp(g?.fileRows??[],m.collapsedFileTreePaths);return{leftItemIds:yp(l),centerTabIds:ai(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:Pi(m,u),pageRows:Math.max(5,Oe(T.width,T.height).height-me.topRailHeight-9),enabledRunnerIds:s,projectTargetIds:u?.repoTargets?.map(S=>S.repoId)??[]}}async function ha(m){await ts(n,m),r=m,s=Ye(r),l={...l,enabledRunnerIds:s},a.mode==="main"?a={mode:"main",shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:Ne(r)})}:a={...a,shell:P({...a.shell,selectedRunner:s.includes(a.shell.selectedRunner)?a.shell.selectedRunner:Ne(r)})}}async function wa(m){let u=m.selectedTaskId;u&&await Fe(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 te(){let m=(a.mode==="main",a.shell);l=await Ct(t,m,s),a.mode==="main"?a={mode:"main",shell:P(a.shell)}:a={...a,shell:P(a.shell)}}async function Kr(m){let u=++Pn,p=ua(l.tasks,m),g=l.inspection,w;if(p&&g?.taskId===p.id){let S={selectedFilePath:m.selectedFilePath,selectedDiffPath:m.selectedDiffPath},L=await Co(p,g,S);if(u!==Pn)return;w={...l,inspection:L}}else if(w=await Ct(t,m,s),u!==Pn)return;l=w,a.mode==="main"&&(a={mode:"main",shell:P(a.shell)},k(a.shell),y())}async function In(m){let u=await Lp(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 Vr(m){try{let u=P(m),p=it(u),g=u.selectedPtyTabId;if(p&&u.focusedRegion==="tasks"){let L=p.ptyTabs.find(ce=>ce.kind==="agent")??null;L?g=L.id:(p=await Gr(p),await te(),g=p.selectedPtyTabId)}p&&!g&&(p=await Gr(p),await te(),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:He({...w,inputMode:"terminal"},j.getViewState(g))},k(a.shell);let S=await j.ensureSession(w.selectedTaskId,g,vt(Oe(T.width,T.height)));F=Nr(g),q=null,a={mode:"main",shell:He({...w,inputMode:"terminal"},S)},k(a.shell)}catch(u){let p=U("attach PTY",u,"Failed to start PTY.");m.selectedTaskId&&m.selectedPtyTabId&&Nr(m.selectedPtyTabId)&&(await ka(m.selectedTaskId,p).catch(()=>{}),await te().catch(()=>{})),a={mode:"main",shell:H(ri(P(m),p),p)},k(a.shell)}y()}async function ka(m,u){await Fe(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 Ra(m,u,p){let g=P(m);if(!g.selectedTaskId)throw new Error("Select a task before creating a tab.");let w=await Fe(async()=>{let S=await _(n,g.selectedTaskId),L=u??Sp(S,g.activeTab,g.preferredPtyTabKind),ce=ca(S,L,p??void 0,r),at={...S,ptyTabs:[...S.ptyTabs,ce],selectedPtyTabId:ce.id};return await E(n,at),at});return await te(),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 Ta(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing a tab.");let{closedTab:p,nextSelectedTab:g}=await Fe(async()=>{let w=await _(n,u.selectedTaskId),S=w.ptyTabs.findIndex(xn=>xn.id===u.activeTab);if(S===-1)throw new Error("Only PTY tabs can be closed.");let L=w.ptyTabs[S],ce=w.ptyTabs.filter(xn=>xn.id!==L.id),at=ce[Math.min(S,ce.length-1)]??ce[S-1]??null;return await E(n,{...w,ptyTabs:ce,selectedPtyTabId:at?.id??null}),{closedTab:L,nextSelectedTab:at}});return j.disposeSession(p.id),await te(),P({...u,activeTab:g?.id??(u.openInspectionKind?"inspection":u.activeTab),selectedPtyTabId:g?.id??null,focusedRegion:"center",actionMessage:`Closed tab: ${p.title}`})}async function ya(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before refreshing PR checks.");let p=it(u),g=null,w=null;if(p?.type==="project"&&p.repoTargets?.length){let S=await Gt(n,u.selectedTaskId);await te();let L=S.synced+S.discovered+S.notFound;w=`Refreshed ${S.synced}/${L} targets`}else{let{disposition:S,task:L}=await Hn(n,u.selectedTaskId);await te(),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({...ga(u,w),focusedRegion:"inspector",inspectionMode:"review",selectedActionId:"refresh-checks",actionMessage:g})}async function Pa(){if(Rn||a.mode!=="main")return;let m=l.tasks;Rn=!0;try{if(await so(n,m),Tn=null,a.mode!=="main")return;l=await Ct(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!==Tn&&(Tn=p,rr(n,{context:"background PR polling",message:p,details:u instanceof Error?u.stack??u.message:String(u)}))}finally{Rn=!1}}async function ba(m){let u=P(m);if(!u.selectedTaskId)throw new Error("Select a task before closing it.");let{taskBeforeClose:p,task:g}=await Fe(async()=>{let w=await _(n,u.selectedTaskId),S=await jo(n,u.selectedTaskId);return{taskBeforeClose:w,task:S}});for(let w of p.ptyTabs)j.disposeSession(w.id);return await te(),P({...u,selectedActionId:"close-task",actionMessage:g.cleanup.preservedWorktree?`Archived task ${g.id}; worktree preserved`:`Archived task ${g.id}`})}async function Ia(m){let u=P(m);if(!u.selectedWorkspaceId)throw new Error("Select a workspace before removing it.");if((await Te(n,{workspaceId:u.selectedWorkspaceId,includeClosed:!0})).tasks.length>0)throw new Error(`Cannot remove workspace ${u.selectedWorkspaceId} while task records still reference it.`);await wt(n,u.selectedWorkspaceId);let g=await kt(n,u.selectedWorkspaceId);return await te(),P({...u,selectedWorkspaceId:null,selectedRepoId:null,selectedTaskId:null,selectedPtyTabId:null,selectedLeftItemId:null,actionMessage:`Removed workspace ${g.workspaceId}`})}async function Gr(m){let u=m.ptyTabs.find(w=>w.kind==="agent")??null;if(u){let w={...m,selectedPtyTabId:u.id};return await Fe(async()=>{let S=await _(n,m.id),L=S.ptyTabs.find(ce=>ce.kind==="agent")??null;L&&await E(n,{...S,selectedPtyTabId:L.id})}),w}let p=ca(m,"agent",void 0,r),g={...m,ptyTabs:[...m.ptyTabs,p],selectedPtyTabId:p.id};return await Fe(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=()=>{Sa();let m=Oe(T.width,T.height),u=a.mode==="main"?Ji(m,gi(P(a.shell),l),{centerOnly:a.shell.centerZoomed}):a.variant==="boot"?Gi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Wr,updateText:yn}):a.variant==="pause"?Hi(m,{menuIndex:a.menuIndex,optionsMessage:a.optionsMessage,versionText:Wr,updateText:yn}):a.variant==="options"?$r(m,{menuIndex:a.menuIndex,optionsMenuItems:Or}):a.variant==="runners"?$r(m,{menuIndex:xt(a).menuIndex,optionsMenuItems:jr(r,xt(a)),optionsMessage:oa(xt(a)),optionsSubtitle:"Runners"}):a.variant==="error-log"?Yi(m,{errorLogPath:a.errorLog?.path??n.errorLogFile,errorLogLines:a.errorLog?.lines??[]}):zi(m);G&&(T.moveTo(1,1),T.eraseDisplayBelow(),G=!1),T.noFormat(xp(u)),T.hideCursor(!0)};function Sa(){let m=a.mode==="main"&&a.shell.inputMode==="terminal"?"terminal":"control";m!==bn&&(bn=m,T.grabInput(m==="terminal"?{mouse:"button"}:!0))}let Ca=()=>{process.stdout.off("resize",Qr),process.off("SIGCONT",Xr),T.removeListener("key",Hr),T.removeListener("unknown",zr),T.removeListener("mouse",Yr),xe&&(clearTimeout(xe),xe=null),ve&&(clearTimeout(ve),ve=null),Ee&&(clearTimeout(Ee),Ee=null),Ae&&(clearTimeout(Ae),Ae=null),Et&&(clearInterval(Et),Et=null),j.disposeAll(),T.grabInput(!1),T.hideCursor(!1),T.fullscreen(!1)},Sn=m=>{Ca(),I(m)},xa=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 Cp(n,m.selectedRepoId,m.selectedWorkspaceId,u,m.selectedRunner),await te();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 j.ensureSession(p.id,g.selectedPtyTabId??fa(p,"agent"),vt(Oe(T.width,T.height)));F=Nr(g.selectedPtyTabId),a={mode:"main",shell:He(g,w)},k(a.shell)}catch(g){g instanceof wn&&(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 te().catch(()=>{})),a={mode:"main",shell:H(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()}},va=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(Ce(m)){xa();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:mr(u.selectedRunner,s),taskPromptError:null})},y();return}si(m)&&(a={mode:"main",shell:P({...u,taskPromptInput:`${u.taskPromptInput}${m}`,taskPromptError:null})},y())}},Ea=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"){In(st.dirname(u.cwd)).catch(p=>{let g=U("open parent workspace directory",p,"Failed to open parent directory.");a={mode:"main",shell:H(P({...a.shell,workspaceBrowser:{...u,error:g}}),g)},y()});return}if(m==="RIGHT"||m==="l"||Ce(m)){let p=u.entries[u.selectedIndex]??null;if(!p)return;if((m==="RIGHT"||m==="l")&&(p.kind==="directory"||p.kind==="repo")){In(p.path).catch(g=>{let w=U("open workspace directory",g,"Failed to open directory.");a={mode:"main",shell:H(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()});return}ht(n,p.path).then(async g=>{await te();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:H(P({...a.shell,workspaceBrowser:{...u,error:w}}),w)},y()})}}},Hr=m=>{let u=typeof m=="string"?m:"";if(a.mode==="main"&&a.shell.taskPromptInput!==null){va(u);return}if(a.mode==="main"&&a.shell.workspaceBrowser!==null){Ea(u);return}if(a.mode==="main"){let p=ni(a.shell,u,Ur(a.shell));if(p.exit){Sn(0);return}if(p.detachTerminal){j.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(F&&Ce(u)){F=!1;return}F&&(F=!1),q=Ep(u)?{key:u,at:Date.now()}:null;let g=Ap(u,a.shell.terminal.scrolledBack??!1);if(g!==0){Cn(g);return}j.writeKey(u);return}if(u==="CTRL_C"){Sn(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){In(t).catch(g=>{let w=U("browse workspaces",g,"Failed to browse workspaces.");a={mode:"main",shell:H(P({...p.state,workspaceBrowser:{cwd:t,entries:[],selectedIndex:0,error:w}}),w)},y()});return}if(p.createPtyTab){Ra(p.state,p.createPtyTabKind,p.createPtyTabRunner).then(g=>{Vr(g)}).catch(g=>{let w=U("create PTY tab",g,"Failed to create tab.");a={mode:"main",shell:H(P({...p.state,actionMessage:w}),w)},y()});return}if(p.closePtyTab){Ta(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:H(P({...p.state,actionMessage:w}),w)},y()});return}if(p.refreshPullRequestChecks){ya(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:H(P({...p.state,actionMessage:w}),w)},y()});return}if(p.closeTask){ba(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:H(P({...p.state,actionMessage:w}),w)},y()});return}if(p.removeWorkspace){Ia(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:H(P({...p.state,actionMessage:w}),w)},y()});return}if(p.attachTerminal){Vr(p.state);return}if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),Kr(a.shell).catch(g=>{let w=U("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:H(P({...a.shell,actionMessage:w}),w)},y()});return}p.changed&&(a={mode:"main",shell:P(p.state)},wa(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"){Aa(u);return}if(a.variant==="runners"){Da(u);return}if(a.variant==="error-log"){if(u==="ESCAPE"||Ce(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"||Ce(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(Ce(u)){if(a.menuIndex===0){let p=a.variant==="boot";a={mode:"main",shell:P({...a.shell,inputMode:"control"})},G=!0,y(),p?Oa.then(()=>{if(a.mode!=="main")return;let g=a.shell;ma(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:H(P(a.shell),S)},k(a.shell),y()})}):pa();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}Sn(0)}};function Aa(m){if(a.mode!=="overlay"||a.variant!=="options")return;let u=ia(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;$a(p)}}}async function $a(m){let u;try{u=await Io(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 Da(m){if(a.mode!=="overlay"||a.variant!=="runners")return;let u=aa(xt(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}ha(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=H(P(a.shell),g);a={...a,shell:w,runnerOptions:{...xt(a),message:g}},y()})}}let zr=m=>{let u=vp(m);if(a.mode!=="main"||a.shell.inputMode!=="terminal"||u.length===0)return;if(u.includes("")){j.detach(),F=!1,q=null,a={mode:"main",shell:P({...a.shell,inputMode:"control",actionMessage:null,focusedRegion:"center"})},k(a.shell),y();return}let p=$p(u);if(p!==0){Cn(p);return}let g=Dp(u);if(g){F=!1,q={key:g,at:Date.now()},j.writeKey(g);return}if(F&&u!=="\r"&&u!==`
|
|
159
159
|
`&&u!==`\r
|
|
160
160
|
`&&(F=!1),Mp(F,q,u)){F=!1;return}j.write(u)},Yr=m=>{if(a.mode!=="main")return;if(a.shell.inputMode==="control"){La(la(m));return}let u=la(m);u!==0&&Cn(u)};function Cn(m){C+=m,!xe&&(xe=setTimeout(()=>{xe=null;let u=C;C=0,u!==0&&(Ma(u),y())},16))}function Ma(m){j.scrollViewport(m),a={mode:"main",shell:ot(a.shell)}}function Jr(){G=!0,T.fullscreen(!0)}function La(m){m!==0&&(je+=m,!ve&&(ve=setTimeout(()=>{ve=null;let u=je;if(je=0,u===0||a.mode!=="main"||a.shell.inputMode!=="control")return;let p=Le(a.shell,u,Ur(a.shell));if(p.changed){if(p.refreshInspection){a={mode:"main",shell:P(p.state)},k(a.shell),y(),Kr(a.shell).catch(g=>{let w=U("refresh inspection",g,"Failed to refresh inspection.");a={mode:"main",shell:H(P({...a.shell,actionMessage:w}),w)},y()});return}a={mode:"main",shell:P(p.state)},k(a.shell),y()}},16)))}let Qr=()=>{Jr(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(j.resize(vt(Oe(T.width,T.height))),a={mode:"main",shell:ot(a.shell)}),y()},Xr=()=>{Jr(),a.mode==="main"&&a.shell.inputMode==="terminal"&&(j.resize(vt(Oe(T.width,T.height))),a={mode:"main",shell:ot(a.shell)}),y()};process.stdout.on("resize",Qr),process.on("SIGCONT",Xr),T.grabInput(!0),bn="control",T.hideCursor(!0),T.fullscreen(!0),T.on("key",Hr),T.on("unknown",zr),T.on("mouse",Yr),Et=setInterval(()=>{Pa()},(r.github?.watchIntervalSeconds??5)*1e3),ra().then(m=>{m.updateAvailable&&m.latest&&(yn=`Update available: v${m.latest}`,y())});let Oa=Br().catch(()=>{});y()})}async function Ct(e,t,n){let r=be(e),[s,o,i]=await Promise.all([Ke(r),fe(r),Te(r)]),c=ua(i.tasks,t),l=t?{selectedFilePath:t.selectedFilePath,selectedDiffPath:t.selectedDiffPath}:{},d=c?await xo(c,l):null;return{workspaceRoot:e,workspaces:o.filter(f=>f.status==="active"),repos:s,tasks:i.tasks,inspection:d,...n?{enabledRunnerIds:n}:{}}}function ua(e,t){return t?.selectedTaskId?e.find(n=>n.id===t.selectedTaskId)??null:null}function Rp(e,t){return en(e,t)}function Tp(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 yp(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 Pp(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"?Ip(s):[];return r?.type==="project"?{cwd:o,command:i,env:{GIT_CEILING_DIRECTORIES:bp(process.env.GIT_CEILING_DIRECTORIES,o)}}:{cwd:o,command:i}}function bp(e,t){let n=(e??"").split(st.delimiter).filter(r=>r.length>0);return n.includes(t)?n.join(st.delimiter):[...n,t].join(st.delimiter)}function Ip(e){return e.command.length>0?e.command:["codex"]}function xt(e){return e.runnerOptions??{menuIndex:e.menuIndex,message:e.optionsMessage}}function Sp(e,t,n){return e.ptyTabs.find(r=>r.id===t)?.kind??n}function ca(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"?Y(s,void 0,r):[],createdAt:h,updatedAt:h}}async function Cp(e,t,n,r,s){let o=await we(e);At(s,o);let i=n?await _t(e,n,r,{runner:s,config:o}):await ft(e,t??"",r,{runner:s,config:o});try{let d=qe();await x(Ue(vn(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 wn(f,h)}let c=fa(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 oe({uiStateFile:e.uiStateFile},{...await de({uiStateFile:e.uiStateFile})??Re(),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 wn=class extends Error{task;constructor(t,n){super(t),this.name="InteractiveTaskStartupError",this.task=n}};function fa(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 vt(e){return{columns:Math.max(20,e.width-me.leftWidth-me.rightWidth-me.dividerWidth-fn*2),rows:Math.max(5,e.height-me.topRailHeight-5)}}function xp(e){return e.split(`
|