@viraatdas/rudder 1.0.5 → 1.0.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.
Files changed (45) hide show
  1. package/README.md +369 -23
  2. package/dist/agent-attention.d.ts +5 -0
  3. package/dist/agent-attention.js +54 -0
  4. package/dist/agent-attention.js.map +1 -0
  5. package/dist/backends.js +58 -10
  6. package/dist/backends.js.map +1 -1
  7. package/dist/brain.js +3 -3
  8. package/dist/brain.js.map +1 -1
  9. package/dist/cloud.d.ts +9 -0
  10. package/dist/cloud.js +2255 -0
  11. package/dist/cloud.js.map +1 -0
  12. package/dist/main.js +112 -2
  13. package/dist/main.js.map +1 -1
  14. package/dist/migration.d.ts +82 -0
  15. package/dist/migration.js +174 -0
  16. package/dist/migration.js.map +1 -0
  17. package/dist/native/rudder-native +0 -0
  18. package/dist/native-agents.d.ts +1 -0
  19. package/dist/native-agents.js +126 -8
  20. package/dist/native-agents.js.map +1 -1
  21. package/dist/plan-mode.d.ts +2 -0
  22. package/dist/plan-mode.js +22 -0
  23. package/dist/plan-mode.js.map +1 -0
  24. package/dist/repl.js +11 -3
  25. package/dist/repl.js.map +1 -1
  26. package/dist/run-manager.d.ts +11 -1
  27. package/dist/run-manager.js +164 -19
  28. package/dist/run-manager.js.map +1 -1
  29. package/dist/state.d.ts +10 -1
  30. package/dist/state.js +51 -1
  31. package/dist/state.js.map +1 -1
  32. package/dist/task-summary.d.ts +5 -0
  33. package/dist/task-summary.js +128 -0
  34. package/dist/task-summary.js.map +1 -0
  35. package/dist/tmux-dashboard.js +248 -64
  36. package/dist/tmux-dashboard.js.map +1 -1
  37. package/dist/tmux.js +1 -0
  38. package/dist/tmux.js.map +1 -1
  39. package/dist/tui.js +228 -46
  40. package/dist/tui.js.map +1 -1
  41. package/dist/types.d.ts +23 -0
  42. package/dist/util.d.ts +1 -0
  43. package/dist/util.js +23 -1
  44. package/dist/util.js.map +1 -1
  45. package/package.json +4 -2
package/README.md CHANGED
@@ -11,9 +11,14 @@
11
11
  [![Node >=20](https://img.shields.io/badge/node-%3E%3D20-43853d.svg)](https://nodejs.org/)
12
12
  [![Website](https://img.shields.io/badge/site-rudder.viraat.dev-111111.svg)](https://rudder.viraat.dev)
13
13
 
14
- Rudder is a terminal command center for running local coding agents. It opens a
15
- native three-pane dashboard, creates an isolated git worktree for each task, and
16
- runs real Claude Code or Codex processes in the worker pane.
14
+ Rudder leans into how coding agents should be used: massively parallel,
15
+ isolated, reviewable, and easy to merge. It opens a native three-pane dashboard,
16
+ creates an isolated git worktree for each task, and runs real Claude Code or
17
+ Codex processes in the worker pane.
18
+
19
+ Rudder Cloud lives behind `/login`, `/cloud`, and `/sail`. It keeps the same
20
+ local dashboard and worktree flow, with an optional Fly Machines worker path for
21
+ tasks that should continue away from your laptop.
17
22
 
18
23
  ## Install
19
24
 
@@ -66,6 +71,252 @@ does not require API keys when you already use Claude Code or Codex login.
66
71
  Config is written to `~/.rudder/config.json`. Mirrored auth metadata is written
67
72
  to `~/.rudder/auth-profiles.json`.
68
73
 
74
+ ## Rudder Cloud
75
+
76
+ Rudder Cloud is the hosted worker mode for Rudder. The local app remains the
77
+ control surface: you start in your repo, choose a task, and decide whether it
78
+ should run locally or be handed to a cloud worker.
79
+
80
+ ```bash
81
+ rudder login
82
+ rudder cloud
83
+ rudder cloud list
84
+ rudder cloud byoc rudder-workstation
85
+ rudder cloud onload
86
+ rudder cloud onload <runId>
87
+ rudder cloud logs <id>
88
+ rudder cloud migration-lab
89
+ rudder sail staging-worker
90
+ ```
91
+
92
+ By default the CLI points at the hosted Rudder Cloud control plane:
93
+ `https://rudder-cloud-control.fly.dev`. Set `RUDDER_CLOUD_URL` to
94
+ override it for local development or another deployment.
95
+
96
+ Inside the dashboard, `/login` starts browser auth and `/cloud list` lists
97
+ cloud workers after you are logged in. `/cloud` opens a confirmation pane before
98
+ anything launches. The highlighted default option onloads the current Rudder
99
+ workspace to the cloud, including the repo snapshot, selected HOME auth/config
100
+ paths, `RUDDER.md`, and saved `.rudder/runs/*/run.json` metadata. Press Down to
101
+ choose a scratch Fly microVM in a fresh cloud directory, then Enter to start.
102
+ `/cloud <name>` uses the same prompt but gives the scratch worker a specific
103
+ name. `/cloud help` shows the cloud command reference.
104
+
105
+ Cloud workers use Fly Machines by default. To bring your own workstation or
106
+ server instead, add it to `~/.ssh/config` and run:
107
+
108
+ ```bash
109
+ rudder cloud byoc rudder-workstation
110
+ ```
111
+
112
+ That SSH host should use key-based auth and have Docker available to your SSH
113
+ user. Rudder checks the host and stores it in `~/.rudder/cloud.json`.
114
+ After setup, `rudder cloud vm <task>` prepares a BYOC run and Rudder tries to
115
+ start it on that host over SSH. Dashboard `/cloud` and `/sail` always use Fly
116
+ for their scratch cloud-worker path so the main cloud shortcut behaves
117
+ consistently. Use `rudder cloud runtime [fly|byoc]` to inspect or change the
118
+ saved CLI runtime.
119
+ Set `RUDDER_BYOC_AUTOSTART=0` if you always want Rudder to print the Docker
120
+ command instead of starting it over SSH.
121
+
122
+ `rudder login` connects this machine to Rudder Cloud by opening the browser for
123
+ the control plane's Better Auth login. If that browser login endpoint is
124
+ unavailable, Rudder falls back to local GitHub CLI auth and then GitHub's
125
+ browser device flow. It is separate from Claude Code and Codex login: provider
126
+ auth still belongs to the official CLIs unless you explicitly configure
127
+ otherwise.
128
+
129
+ Cloud admins can attach existing OAuth clients without redeploying the control
130
+ plane:
131
+
132
+ ```bash
133
+ rudder cloud login
134
+ rudder cloud setup-github <github-client-id>
135
+ rudder cloud setup-google <google-client-id>
136
+ ```
137
+
138
+ Both setup commands prompt for the client secret without echoing it and persist
139
+ the provider credentials into Rudder Cloud's S3-backed state. For automation,
140
+ use `RUDDER_GITHUB_CLIENT_ID`, `RUDDER_GITHUB_CLIENT_SECRET`,
141
+ `RUDDER_GOOGLE_CLIENT_ID`, and `RUDDER_GOOGLE_CLIENT_SECRET`.
142
+
143
+ `rudder cloud list` will show cloud-capable runs and remote workers. `rudder
144
+ cloud onload` uploads the current Rudder workspace. `rudder cloud onload
145
+ <runId>` keeps the older single-run path for moving one local run to the cloud
146
+ from the same task context. `rudder cloud logs <id>` currently shows worker
147
+ status while full cloud log streaming is being wired up.
148
+
149
+ Cloud onload is designed around Rudder's existing worktree model. If a task is
150
+ already in a worktree, that worktree is the unit Rudder prepares for the cloud.
151
+ If a task is still in the main checkout, Rudder prepares a worktree first so the
152
+ cloud run does not mutate your local branch directly. Completed cloud work comes
153
+ back through the same review and merge path as local work.
154
+
155
+ Rudder includes selected HOME config paths in the launch snapshot so cloud
156
+ workers can behave like your local environment where that is useful: Claude,
157
+ Codex, GitHub CLI, git config, npm, Vercel, and Hunk config are considered. It
158
+ filters obvious high-risk material such as AWS credentials, `.env` files, SSH
159
+ keys, Docker auth, kube config, and private key directories.
160
+
161
+ The cloud control plane code lives in `cloud/`. It uses Better Auth for
162
+ Google/GitHub login, stores launch snapshots in an encrypted S3 bucket, and
163
+ starts Fly Machines workers with one-hour presigned snapshot URLs. The local CLI
164
+ package stays small; cloud state and worker orchestration run in the separate
165
+ control plane.
166
+
167
+ ## Architecture
168
+
169
+ Rudder has three layers:
170
+
171
+ ```text
172
+ ┌────────────────────────────────────────────────────────────┐
173
+ │ Local Rudder CLI │
174
+ │ native OpenTUI dashboard, task input, panes, worktrees │
175
+ ├────────────────────────────────────────────────────────────┤
176
+ │ Agent Process Layer │
177
+ │ real claude or codex terminals, not mocked transcript UIs │
178
+ ├────────────────────────────────────────────────────────────┤
179
+ │ Optional Rudder Cloud │
180
+ │ Better Auth, S3 snapshots, Fly Machines, BYOC Docker runs │
181
+ └────────────────────────────────────────────────────────────┘
182
+ ```
183
+
184
+ ### Local Dashboard
185
+
186
+ `rudder` starts the native dashboard. The native binary owns the terminal, draws
187
+ the three-pane UI, creates PTYs for workers, and routes keyboard and mouse input.
188
+
189
+ ```text
190
+ ┌───────────────┬────────────────────────────────────────────┐
191
+ │ agents │ worker │
192
+ │ task list │ live Claude Code or Codex PTY │
193
+ │ status/model │ scrollback, review view, copy selection │
194
+ ├───────────────┴────────────────────────────────────────────┤
195
+ │ task input: new tasks, slash commands, cloud launch prompts │
196
+ └────────────────────────────────────────────────────────────┘
197
+ ```
198
+
199
+ The worker pane is an actual terminal process. When you focus it, keystrokes go
200
+ to Claude Code or Codex. Rudder only intercepts global controls such as
201
+ `Ctrl-C`, pane focus, review mode, merge, and delete.
202
+
203
+ ### Worktrees And Context
204
+
205
+ Each normal task gets its own git worktree so agents do not compete inside the
206
+ same checkout.
207
+
208
+ ```text
209
+ main checkout
210
+ ├─ .rudder/runs/<run-id>/run.json local run metadata
211
+ ├─ RUDDER.md current agent map, gitignored
212
+ └─ ~/.rudder-worktrees/<repo>/<run-id> isolated agent checkout
213
+ ```
214
+
215
+ `RUDDER.md` is regenerated as agents start, finish, restart, or delete. Rudder
216
+ injects a short prompt telling each agent to read it, so a new agent can see
217
+ what other agents are doing without Rudder rewriting the user task.
218
+
219
+ Merging is intentionally git-native:
220
+
221
+ ```text
222
+ agent worktree -> optional commit -> git merge --no-ff -> main checkout
223
+ ```
224
+
225
+ If a merge conflicts, Rudder leaves the merge in place and offers to start an
226
+ AI resolver in the main checkout. It does not hide the conflicted git state.
227
+
228
+ ### Review Flow
229
+
230
+ Review mode uses Hunk when available, with git diff as the fallback path.
231
+
232
+ ```text
233
+ selected run worktree
234
+ └─ hunk diff --watch
235
+ └─ embedded PTY in the worker/review pane
236
+ ```
237
+
238
+ The review pane is also a real terminal. Mouse wheel and trackpad events scroll
239
+ Rudder's captured scrollback first; if there is no Rudder scrollback to move,
240
+ events can pass through to the inner TUI.
241
+
242
+ ### Cloud Auth
243
+
244
+ Rudder Cloud auth is separate from Claude Code and Codex auth.
245
+
246
+ ```text
247
+ /login or rudder login
248
+ -> browser opens Rudder Cloud
249
+ -> Better Auth handles Google or GitHub
250
+ -> control plane issues a Rudder CLI token
251
+ -> local CLI writes ~/.rudder/cloud.json
252
+ ```
253
+
254
+ Claude Code and Codex credentials stay in their normal locations such as
255
+ `~/.claude`, `~/.codex`, Keychain, or existing environment variables. Cloud
256
+ workers receive a filtered snapshot of useful HOME config, excluding obvious
257
+ high-risk material such as SSH keys, AWS credentials, Docker auth, kube config,
258
+ and `.env` files.
259
+
260
+ ### Fly Cloud Path
261
+
262
+ Dashboard `/cloud` always uses the Fly path for a fresh cloud worker. This keeps
263
+ the shortcut predictable even if the CLI default runtime was changed to BYOC.
264
+
265
+ ```text
266
+ task pane /cloud
267
+ -> confirmation pane
268
+ highlighted: onload current Rudder workspace to cloud
269
+ Down: start scratch in a fresh cloud directory
270
+ -> local CLI creates repo snapshot
271
+ -> control plane stores snapshot in S3
272
+ -> control plane creates Fly Machine
273
+ -> worker downloads snapshot and starts Rudder
274
+ ```
275
+
276
+ The cloud indicator in the agents pane shows whether the local dashboard is
277
+ connected to Rudder Cloud.
278
+
279
+ ### BYOC Path
280
+
281
+ BYOC is for a server you own, reachable through SSH.
282
+
283
+ ```text
284
+ rudder cloud byoc <ssh-host>
285
+ -> read ~/.ssh/config
286
+ -> verify SSH and Docker
287
+ -> save host in ~/.rudder/cloud.json
288
+
289
+ rudder cloud vm "task"
290
+ -> upload snapshot to Rudder Cloud
291
+ -> receive docker run bootstrap command
292
+ -> run it over SSH with nohup
293
+ ```
294
+
295
+ On ARM hosts, the bootstrap command switches from
296
+ `public.ecr.aws/exla/rudder-worker:latest` to
297
+ `public.ecr.aws/exla/rudder-worker:arm64`, so Jetson-style machines do not try
298
+ to run an amd64 worker image.
299
+
300
+ ### Control Plane
301
+
302
+ The hosted control plane is in `cloud/`.
303
+
304
+ ```text
305
+ cloud/src/server.ts
306
+ ├─ Better Auth pages and API routes
307
+ ├─ /api/rudder/sail launch/list/pause/resume/onload/bootstrap
308
+ ├─ S3 snapshot storage and persisted state
309
+ ├─ Fly Machines API client
310
+ └─ BYOC bootstrap command generation
311
+
312
+ cloud/worker/entrypoint.sh
313
+ ├─ download snapshot
314
+ ├─ restore selected HOME config
315
+ ├─ initialize git baseline if needed
316
+ ├─ run Rudder/Codex task
317
+ └─ heartbeat completion back to the control plane
318
+ ```
319
+
69
320
  ## Dashboard
70
321
 
71
322
  Start the native dashboard:
@@ -86,29 +337,80 @@ writes the current agent context to `RUDDER.md`, and starts the selected backend
86
337
  inside the worker pane.
87
338
 
88
339
  When the worker pane is focused, your keystrokes go directly to Claude Code or
89
- Codex. Their slash commands, cursor movement, copy/paste, interrupts, and
90
- terminal UI continue to work normally.
91
-
92
- ## Keys
340
+ Codex. Their slash commands, cursor movement, copy/paste, and terminal UI
341
+ continue to work normally. `Ctrl-C` is reserved by Rudder and leaves the
342
+ dashboard from any pane.
343
+
344
+ Rudder owns mouse input inside the dashboard. Wheel or trackpad scrolling is
345
+ routed to the pane under the pointer. Over the worker or review pane, it scrolls
346
+ Rudder's captured pane output, not the underlying Claude Code, Codex, or Hunk
347
+ chat. Use the worker's up and down arrow keys when you want to move through the
348
+ agent's own prompt history or menus. Drag selection inside the worker pane
349
+ copies selected text, including when you drag upward past the top of the pane.
350
+ For full-screen alternate-screen workers, Rudder keeps its own pane history so
351
+ trackpad scrolling moves the pane instead of depending on the child app. If the
352
+ pane has no Rudder scrollback to move and the inner TUI has explicitly requested
353
+ mouse input, Rudder passes the wheel event through so Claude Code, Codex, Hunk,
354
+ or another full-screen app can scroll its own view.
355
+
356
+ ## Dashboard Shortcuts
93
357
 
94
358
  | Key | Action |
95
359
  | --- | --- |
96
360
  | `Enter` | Start the typed task, or focus the selected worker when the task input is empty |
97
361
  | `Tab` / `Shift+Tab` | Cycle focus across agents, worker, and task panes |
98
- | `Alt-1` / `Alt-2` / `Alt-3` | Focus agents, worker, or task directly |
362
+ | `Option-1` / `Option-2` / `Option-3` | Focus agents, worker, or task directly |
99
363
  | `Ctrl-G` | Toggle Rudder nav mode while focused inside a worker |
364
+ | `Alt-v` | Toggle the selected agent's review view from any pane |
365
+ | `Shift+Enter` | Insert a new line in the focused worker prompt |
366
+ | `PageUp` / `PageDown` | Scroll the focused worker pane by roughly one page |
100
367
  | `j` / `k` or arrows | Move through agents when the agents pane is focused |
101
- | `/model` | Open the provider-first model picker |
102
- | `/help` | Show the short command hint |
103
- | `v` | Open the selected agent's Hunk review view |
368
+ | `Up` / `Down` | Browse task history when the task pane is focused |
369
+ | `Alt-Left` / `Alt-Right` | Move by word in the task pane and in supported worker prompts |
370
+ | `Alt-Backspace` / `Ctrl-W` | Delete the previous word in the task pane and in supported worker prompts |
371
+ | `Cmd-C` / `Meta-C` | Copy the active Rudder text selection without forwarding `c` to the worker |
372
+ | `Ctrl-C` | Leave Rudder from any pane |
373
+ | `v` | Toggle the selected agent's review view |
374
+ | `Esc` | Leave the review view when it is focused |
375
+ | `r` | Restart the selected stopped agent in its worktree |
104
376
  | `m` | Merge the selected completed worktree |
105
377
  | `M` | Merge all completed worktrees |
106
- | `d` | Delete the selected agent; if its worktree has changes, Rudder asks you to merge or confirm discard |
378
+ | `dd` | Delete the selected agent and remove its worktree; if it has changes, Rudder gives you a merge chance first |
107
379
  | `q` | Quit when the worker is not consuming input |
108
380
 
381
+ ## Task Pane Commands
382
+
383
+ Type `/` in the task pane to open command suggestions. Use `Up`/`Down` to move
384
+ through suggestions and `Enter` to choose one.
385
+
386
+ | Command | Action |
387
+ | --- | --- |
388
+ | `/model` | Open the provider-first model picker: choose Claude or Codex, then model, then effort when supported |
389
+ | `/plan` | Toggle Rudder's read-only plan mode for task pane submissions |
390
+ | `/plan <task>` | Start one read-only planning session without toggling plan mode |
391
+ | `/run <task>` | Start an implementation run even when plan mode is on |
392
+ | `/login` | Open browser login for Rudder Cloud |
393
+ | `/cloud` | Ask whether to onload the current Rudder workspace or start a fresh Fly worker |
394
+ | `/cloud <name>` | Ask the same question, using the name for the fresh Fly worker |
395
+ | `/cloud byoc <ssh-host>` | Use an SSH host from `~/.ssh/config` for BYOC cloud workers |
396
+ | `/cloud runtime [fly\|byoc]` | Show or set the saved cloud runtime |
397
+ | `/cloud list` | List cloud workers |
398
+ | `/cloud logs <id>` | Show cloud worker status while log streaming is pending |
399
+ | `/cloud help` | Show cloud command help |
400
+ | `/sail <name or task>` | Short alias for starting a cloud worker |
401
+ | `/help` | Show the short command hint |
402
+
109
403
  Use `Ctrl-G` before a Rudder shortcut if the worker pane is focused and you want
110
404
  the key handled by Rudder instead of by Claude Code or Codex.
111
405
 
406
+ If trackpad scrolling does not behave as expected, run
407
+ `rudder mouse-test parsed` to confirm your terminal is sending `ScrollUp` and
408
+ `ScrollDown` events. For lower-level escape bytes, run `rudder mouse-test raw`.
409
+ To inspect live dashboard routing, start Rudder with `RUDDER_MOUSE_DEBUG=1`.
410
+ Rudder scrolls three terminal rows per wheel event by default, matching common
411
+ terminal scrollback behavior. Override with `RUDDER_WHEEL_SCROLL_ROWS=<n>` if
412
+ your terminal is configured differently.
413
+
112
414
  ## Models
113
415
 
114
416
  Run `/model` in the task pane. Rudder first asks for the provider, then the
@@ -121,6 +423,10 @@ model, then the effort level supported by that model.
121
423
  `gpt-5.4-codex`, and other discovered GPT-5/Codex models.
122
424
  - `auto` effort means Rudder does not pass an effort override.
123
425
 
426
+ Rudder saves the last selected provider and model, plus effort when chosen, in
427
+ `~/.rudder/config.json`, so the same defaults are used when you open a new
428
+ dashboard or shell session.
429
+
124
430
  Rudder refreshes model metadata from `https://models.dev/api.json` before the
125
431
  dashboard starts and caches it in `~/.rudder/models-dev.json`. If the network is
126
432
  unavailable, it falls back to local Claude session history and Codex's local
@@ -133,13 +439,17 @@ Native dashboard workers launch the official CLIs directly.
133
439
  Claude Code:
134
440
 
135
441
  ```bash
136
- claude --permission-mode bypassPermissions --model <model> --effort <effort> "<task>"
442
+ CLAUDE_CODE_NO_FLICKER=0 claude \
443
+ --permission-mode bypassPermissions \
444
+ --model <model> \
445
+ --effort <effort> "<task>"
137
446
  ```
138
447
 
139
448
  Codex:
140
449
 
141
450
  ```bash
142
- codex --ask-for-approval never --sandbox danger-full-access \
451
+ codex --no-alt-screen \
452
+ --dangerously-bypass-approvals-and-sandbox \
143
453
  -c model_reasoning_summary="detailed" \
144
454
  -c model_supports_reasoning_summaries=true \
145
455
  -c model_reasoning_effort="<effort>" \
@@ -148,15 +458,38 @@ codex --ask-for-approval never --sandbox danger-full-access \
148
458
 
149
459
  The exact model and effort flags are omitted when set to `auto`.
150
460
 
461
+ ## Plan Mode
462
+
463
+ Type `/plan` to toggle planning on or off. While it is on, pressing `Enter`
464
+ starts a planner instead of an
465
+ implementation run. You can also use `/plan <task>` for a one-off plan, or
466
+ `/run <task>` to bypass plan mode and start a normal worktree agent.
467
+
468
+ Planning sessions use the currently selected Claude or Codex model and lean on
469
+ the backend's native planning/read-only controls:
470
+
471
+ - The planner runs in the current checkout instead of creating a worktree.
472
+ - Codex planners launch with `--sandbox read-only`, `--ask-for-approval never`,
473
+ and `--search`, so filesystem writes are blocked and the native Responses
474
+ `web_search` tool is available.
475
+ - Claude planners launch with Claude Code's native `--permission-mode plan`.
476
+ - Rudder only prefixes the task with a short planning request; it no longer
477
+ injects a custom planner contract.
478
+ - Normal implementation runs are unchanged: they still create worktrees and use
479
+ the full-permission worker launch described above.
480
+
151
481
  ## Worktrees And Merging
152
482
 
153
483
  Every dashboard task runs in its own git worktree under
154
484
  `~/.rudder-worktrees/...`, so parallel agents do not edit the same checkout.
485
+ Run records are saved under `.rudder/runs/`. If you exit Rudder, live worker
486
+ processes stop, but the agents remain listed next time you open Rudder in the
487
+ same repo.
155
488
 
156
489
  Press `m` to merge the selected completed agent back into the original branch.
157
- Press `M` to merge all completed agents. Rudder uses normal git merge semantics;
158
- clean merges become merge commits, and conflicts are left in git's standard
159
- conflict state for you to resolve.
490
+ Press `M` to merge all completed agents. Rudder asks for confirmation before
491
+ merging. Clean merges become merge commits; if git reports conflicts, Rudder can
492
+ open an agent in the main checkout to help resolve them.
160
493
 
161
494
  Command-line equivalents:
162
495
 
@@ -177,18 +510,31 @@ or fails, Rudder plays the bundled completion sound.
177
510
 
178
511
  ## Review
179
512
 
180
- Press `v` on an agent to open Hunk against that agent's worktree:
513
+ Press `v` on an agent to toggle a review view for that agent's worktree:
181
514
 
182
515
  ```bash
183
516
  hunk diff --watch
184
517
  ```
185
518
 
186
519
  Hunk provides the multi-file review UI, sidebar navigation, mouse support,
187
- watch mode, and untracked-file handling. If `hunk` is not installed, Rudder
188
- installs it with `npm install -g hunkdiff@latest` before opening the review.
189
-
190
- While focused in the review pane, keys go to Hunk. Press `Ctrl-G`, then `v`, to
191
- return to the live Claude Code or Codex worker.
520
+ watch mode, inline agent notes, and untracked-file handling. Rudder forwards
521
+ keyboard input into Hunk while the review pane is focused and keeps wheel or
522
+ trackpad scrolling on Rudder's review scrollback. Press `v` or `Esc` to return
523
+ to the live Claude Code or Codex worker.
524
+
525
+ Rudder writes a per-worktree `.hunk/config.toml` in Hunk's light mode and
526
+ ignores that config through git's local info exclude, so it does not get merged.
527
+ Set `RUDDER_HUNK_THEME=paper` or another Hunk theme name to override it.
528
+
529
+ On dashboard startup, Rudder installs `hunkdiff@latest` automatically if neither
530
+ `hunk` nor `hunkdiff` is available. If the install fails, or if you set
531
+ `RUDDER_REVIEW_TOOL=git`, the review pane falls back to a live `git diff` view
532
+ instead of downloading anything when you first press `v`.
533
+
534
+ Rudder also injects Hunk review guidance into `RUDDER.md` and the worker prompt.
535
+ Agents are told to run `hunk skill path`, load the Hunk review skill, and use
536
+ `hunk session review --repo . --json` plus `hunk session comment ...` commands
537
+ against the live review.
192
538
 
193
539
  ## One-Shot Commands
194
540
 
@@ -0,0 +1,5 @@
1
+ export type AgentAttention = {
2
+ needsPermission: boolean;
3
+ summary?: string;
4
+ };
5
+ export declare function permissionAttentionFromOutput(output: string): AgentAttention;
@@ -0,0 +1,54 @@
1
+ const PERMISSION_WORD = /\b(permission|approval|approve|allow|authorize|authorization|confirmation|proceed|deny)\b/i;
2
+ const PERMISSION_PATTERNS = [
3
+ /\b(do you want|would you like|are you sure)\b[\s\S]{0,180}\b(allow|approve|run|execute|continue|proceed)\b/i,
4
+ /\b(allow|approve|authorize)\b[\s\S]{0,120}\b(command|tool|edit|write|file|access|execution|network|shell|operation)\b/i,
5
+ /\b(permission|approval|authorization|confirmation)\b[\s\S]{0,160}\b(required|need(?:ed)?|request(?:ed|ing)?|waiting|prompt)\b[\s\S]{0,160}\b(approve|allow|deny|yes|no|enter|return|press)\b/i,
6
+ /\b(approve|allow|deny|yes|no|enter|return|press)\b[\s\S]{0,160}\b(permission|approval|authorization|confirmation)\b/i,
7
+ /\bpress\b[\s\S]{0,80}\b(y|yes|enter|return)\b[\s\S]{0,120}\b(allow|approve|continue|proceed)\b/i,
8
+ /\b(yes|no)\b[\s\S]{0,100}\b(approve|deny|allow|permission)\b/i,
9
+ ];
10
+ export function permissionAttentionFromOutput(output) {
11
+ const recentLines = recentTerminalLines(output, 60);
12
+ const recentText = recentLines.join("\n");
13
+ if (!PERMISSION_WORD.test(recentText)) {
14
+ return { needsPermission: false };
15
+ }
16
+ if (!PERMISSION_PATTERNS.some((pattern) => pattern.test(recentText))) {
17
+ return { needsPermission: false };
18
+ }
19
+ return {
20
+ needsPermission: true,
21
+ summary: summarizePermissionPrompt(recentLines),
22
+ };
23
+ }
24
+ function summarizePermissionPrompt(lines) {
25
+ const line = [...lines]
26
+ .reverse()
27
+ .find((candidate) => PERMISSION_WORD.test(candidate));
28
+ if (!line) {
29
+ return undefined;
30
+ }
31
+ return truncate(line.replace(/\s+/g, " ").trim(), 120);
32
+ }
33
+ function recentTerminalLines(output, maxLines) {
34
+ return stripTerminalControls(output)
35
+ .replace(/\r/g, "\n")
36
+ .split("\n")
37
+ .map((line) => line.trim())
38
+ .filter(Boolean)
39
+ .slice(-maxLines);
40
+ }
41
+ function stripTerminalControls(value) {
42
+ return value
43
+ .replace(/\x1b\][^\u0007]*(?:\u0007|\x1b\\)/g, "")
44
+ .replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "")
45
+ .replace(/\x1b[()][A-Za-z0-9]/g, "")
46
+ .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, "");
47
+ }
48
+ function truncate(value, width) {
49
+ if (value.length <= width) {
50
+ return value;
51
+ }
52
+ return `${value.slice(0, Math.max(0, width - 3))}...`;
53
+ }
54
+ //# sourceMappingURL=agent-attention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-attention.js","sourceRoot":"","sources":["../src/agent-attention.ts"],"names":[],"mappings":"AAKA,MAAM,eAAe,GAAG,4FAA4F,CAAC;AACrH,MAAM,mBAAmB,GAAG;IAC1B,6GAA6G;IAC7G,wHAAwH;IACxH,+LAA+L;IAC/L,sHAAsH;IACtH,iGAAiG;IACjG,+DAA+D;CAChE,CAAC;AAEF,MAAM,UAAU,6BAA6B,CAAC,MAAc;IAC1D,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACrE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IACD,OAAO;QACL,eAAe,EAAE,IAAI;QACrB,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAe;IAChD,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC;SACpB,OAAO,EAAE;SACT,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc,EAAE,QAAgB;IAC3D,OAAO,qBAAqB,CAAC,MAAM,CAAC;SACjC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC;SACpB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC;SACf,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,KAAK;SACT,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC;SACjD,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC;SACvC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;SACnC,OAAO,CAAC,iDAAiD,EAAE,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACxD,CAAC"}