cawdev-cli 1.0.4-beta → 1.0.6-beta

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/runner/README.md CHANGED
@@ -101,8 +101,8 @@ with the window — there `q` stops it, and asks first when sessions are live.
101
101
  machine is configured, most changes are smaller than that. **Inside the
102
102
  terminal, press `c`** (or type `/config`): a picker over what this machine does
103
103
  — add a project, add a workspace, each agent with its current state ("Disable
104
- claude", "Enable agy"), the console-rules switch, and the config itself with the
105
- token cut short. Every row is one of the shell commands below, driven through
104
+ claude", "Enable codex"), the console-rules switch, **Stop serving** each
105
+ project, and the config itself with the token cut short. Every row is one of the shell commands below, driven through
106
106
  the terminal's own line editor and picker; `esc` anywhere in a step changes
107
107
  nothing. The screen edits the file the daemon says it booted from (the hello
108
108
  carries `configPath` since R288), so an older daemon is told to restart rather
@@ -126,7 +126,8 @@ is for scripts and for a machine with no daemon to attach to:
126
126
  cawdev config a menu, the same Select widget as everywhere else
127
127
  cawdev config add-project serve one more project you can write to
128
128
  cawdev config add-workspace another checkout for a project already served
129
- cawdev config agent enable|disable <claude|agy>
129
+ cawdev config remove-project <slug> stop serving a project; its checkouts stay on disk
130
+ cawdev config agent enable|disable <claude|agy|codex>
130
131
  cawdev config rules on|off accept permission rules from the console — R126
131
132
  cawdev config show this machine's config, token redacted
132
133
  ```
@@ -230,7 +231,8 @@ removes.
230
231
  `/logout` forgets it along with the session.
231
232
 
232
233
  **A paste stays one line.** Paste four hundred lines and the input shows
233
- `[pasted, 342 lines]`; all of it is sent. A paste that scrolled the transcript
234
+ `[pasted, 342 lines]`; all of it is sent — into a prompt or into a command alike
235
+ (`/new plan <paste>`, `/card <paste>`), its line breaks kept (`commandWords`). A paste that scrolled the transcript
234
236
  away would bury the thing this program exists to keep.
235
237
 
236
238
  Under `NO_COLOR` it is the same terminal without the colour: the picker still
@@ -331,6 +333,274 @@ browser anywhere and the terminal collects the session when you approve.
331
333
  error — it is what an expired session looks like, and the answer is the same as
332
334
  having none.
333
335
 
336
+ ### Advanced mode: one window per session
337
+
338
+ `/advanced-mode` splits the terminal the way emacs does: **one window per
339
+ session** this machine is running — or ran since you attached — above **the
340
+ prompt, which stays at the bottom** the way a shell's does. Each window's title says what kind of
341
+ session it is (`plan`, `dev`, `review`, `ask`…), where it stands, the card and
342
+ the project, and its body is that session's output as it arrives. A frame's
343
+ colour is its session's state — **red while it runs, green once it finished**
344
+ (a plan planned, a dev developed), amber if it stopped any other way — and
345
+ the focused window is drawn in heavy lines; `tab` and `shift+tab` move the focus, `1`–`9`
346
+ jump to a window, and `enter` prompts the focused session exactly as it does
347
+ outside the mode. `/advanced-mode` again (or `/advanced-mode off`) leaves.
348
+
349
+ It is drawn on the terminal's **alternate screen**, like nano or emacs, and
350
+ holds still the way they do: auto-wrap is off, so nothing ever scrolls the
351
+ screen, and the wheel is sent to the program as arrow keys instead of sliding
352
+ the terminal up. The normal screen and its scrollback are exactly as you left
353
+ them — R81's reason
354
+ for printing into the scrollback still holds, and this mode is something you
355
+ ask for rather than the default. On the way out, what the watched session said
356
+ meanwhile is laid into the scrollback, so nothing was lost by watching it here.
357
+
358
+ **The PLANNED cards run across the top, grouped by project** — a line with
359
+ each project's name over its cards and a rule between two projects, every
360
+ project this machine serves included ("nothing planned" is an answer) — one
361
+ small box each, titled with the card and its status — `R3 (Planned)` — the cards of
362
+ every project this machine serves that are ready to be developed, read again
363
+ every thirty seconds. **`d`** lists them and develops the one you pick, on this
364
+ machine and on the card's own branch — except on a finished plan's window, where
365
+ it is that plan's `/develop` (below) with no list; `/new dev` with nothing after it does the
366
+ same anywhere, and `/new dev R3` goes straight to one. A full-width rule
367
+ under the strip separates the board from the session windows; it comes out of
368
+ the strip's own rows, never the windows'.
369
+
370
+ **`/refresh`** reads the cards again now rather than on the next tick, and
371
+ says what it found per project — `saasng: 5 considering · 2 planned · 1 in
372
+ development` — and which project could not be read, and why. A project that
373
+ cannot be read keeps its last cards and no other's: one unreadable slug used
374
+ to leave every column of every project at 0, silently.
375
+
376
+ **Four windows at most.** Past four, the rest are named on one line above the
377
+ prompt — number, kind, state, card, in the state's colour — and `tab` (or the
378
+ number) onto one brings it up in place of another. The focused session always
379
+ has a window, then the ones still running, then the ended ones, each most
380
+ recently looked at first.
381
+
382
+ A window stays up when its session ends, and its last line says what can be
383
+ done next:
384
+
385
+ - **`d`** or **`/develop`** on a finished plan — the window says `d develops R2
386
+ here, in place of this plan` — starts the development of its card, on
387
+ this machine (the branch is the card's own). `/develop R30` names another
388
+ card, `@slug` its project, and `--codex`/`--claude`/`--agy` the agent —
389
+ otherwise the agent that PLANNED the card when its finished plan has a
390
+ window here, else `/agent`'s choice, exactly as `/new dev R30` does, because
391
+ it IS that command. Once the development has started the plan's window
392
+ closes, and the development's window takes its focus when this machine
393
+ takes the run; a start the platform refused leaves the plan's window up.
394
+ - **`/pr`** on a finished session that wrote a branch opens its pull request
395
+ (`POST runs/{id}/pull-request` — through the card's work item, or from the
396
+ run itself for a session started from a sentence): this machine pushes the
397
+ branch if origin does not have it and runs `gh pr create` (so `gh` has to be
398
+ installed and signed in here). The POST answers with the workspace REQUEST,
399
+ and the terminal follows it (`GET /api/runners/{id}/workspace-requests/{id}`)
400
+ to its result: the URL — which the daemon confirms with `gh pr view` after
401
+ `gh pr create`, so "made" is the host's word and not gh's — or why there is
402
+ none, printed in full (no `gh` comes with its install line and the compare
403
+ link to open it by hand). It watched the run's `prUrl` before, which a
404
+ failure never writes, and said "asked for…" for as long as it was open.
405
+ A checkout cloned on demand is served like any other: the set of paths a
406
+ request may name is read per request, not taken at boot.
407
+ - **`/continue`** on a failed or stopped session is the console's *Carry on*,
408
+ on this machine (`POST runs/{id}/carry-on` with this runner): the same run
409
+ re-queued, its window coming back to life when the daemon takes it. A
410
+ session that stopped BEFORE this terminal attached — the daemon forgets a
411
+ run as it ends, so after a restart nothing here knew of it — is found on
412
+ attach and on sign-in (`findStopped`: the first page of each served
413
+ project's runs, kept when `carriesOnHere` — yours, `canCarryOn`, and its
414
+ checkout on this machine or none), listed in the scrollback, and given a
415
+ window that opens on why it stopped.
416
+ - **Finished, having built nothing** — a dev session that ended FINISHED
417
+ with no commit (IMPLEMENT stopped on a plan it would not follow, say) —
418
+ reads `finished · nothing built`, in amber rather than green, offers no
419
+ `/pr` but the re-plan instead, and its window shows its summary, where it
420
+ said why (`builtNothing`; the terminal reads the run's commits once it
421
+ ends, and claims nothing until it has).
422
+ - **`/open`** opens the pull request in your browser. It reads the run again
423
+ first — the runner records the link after the run is FINISHED, so the copy
424
+ taken at that moment has none — and falls back to the card's work item.
425
+ On a finished PLAN, which opens no pull request, it opens the card on cawdev
426
+ instead — `roadmap/R2?show=plan` (`issues/…` for an issue) — with the plan
427
+ of record unfolded and scrolled to: that plan is what the session produced.
428
+ - **`/drop`** deletes the checkout the session was cloned into, when it was one
429
+ made on demand (below): asked first, naming the path, and refused while a
430
+ run is in it or holds it, with uncommitted files, or with a commit origin
431
+ does not have. The checkouts in the config are never offered — a project
432
+ always keeps them.
433
+ - **`/close`** takes the window away.
434
+
435
+ **`/new`** starts a session from the prompt, aimed at this machine so its
436
+ window opens here: `/new plan R3`, `/new dev R3`, `/new ask <question>` — or a
437
+ task in words with no card: `/new plan add a CSV export of the invoices` writes
438
+ its card first and plans it (R150), and `/new dev fix the sort on the client
439
+ list` writes its card too (`cardTitleFor`: the sentence, cut between words
440
+ near a hundred characters, the whole text in the body) and then develops it
441
+ exactly as `/new dev R12` would — a number, a work item on the development
442
+ board, a branch of its own, and the card session's instruction to commit. It
443
+ was a manual session on a `task-…` branch with no card, which never reached
444
+ the board and was never told to commit. A card reference on its own is that card; anything
445
+ else is the task in words. **The project is always asked** — a list of what
446
+ this machine serves — unless the command names it with `@project`, or
447
+ advanced mode is narrowed to ONE project (`/projects`), which is a choice
448
+ already made rather than a guess. Never guessed from the focused window, nor
449
+ from a machine serving just one, since a session on the wrong project is a
450
+ card planned or a branch cut in the wrong repository. `/new dev` alone and `d` list the planned cards of every project,
451
+ each with its own, so they ask nothing more. A usage window over this machine's threshold is refused in a
452
+ sentence; `--anyway` starts it regardless, the same decision the console's
453
+ panel asks for. All four commands need you signed in (`/login`), and they work
454
+ outside advanced mode too, on the session you are watching.
455
+
456
+ **The prompt says which window it acts on.** In advanced mode the line at the
457
+ bottom leads with the focused window's number — `[2] cawdev ▸ /pr`, `[2]
458
+ enter prompts “…”` — and a command's answer keeps the number of the window it
459
+ was about (`[2] A session on … is running`), so a note left on screen after
460
+ the focus moved still says whose it was.
461
+
462
+ **A project deleted in the console is not offered.** The config on this
463
+ machine still names it, and nothing on the platform can change that file, so
464
+ the terminal asks: a served project whose roadmap read answers 404 — deleted,
465
+ or your access went — is left out of the picker, the strip, `/new` and `/card`,
466
+ and one line says so, once, after the mode is on screen. `c` → **Stop serving
467
+ ngsign** (`cawdev config remove-project ngsign`) takes it out of the config;
468
+ the checkouts stay where they are, and the daemon stops polling for it at its
469
+ next restart, because `projects` is read at boot.
470
+
471
+ **Which projects it shows is yours to pick.** `/advanced-mode` on a machine
472
+ serving several projects opens a picker with every one ticked — space (or a
473
+ digit) ticks and unticks, `a` all or none, enter confirms — and only the
474
+ projects ticked are drawn: their windows, their roadmap on top, and the ones
475
+ `/new` asks between. `/advanced-mode @saasng @ngsign` names them and asks
476
+ nothing; `/projects` asks again from inside the mode; `/reload` keeps the
477
+ pick. A prompt never talks to a session of a project that is not shown.
478
+
479
+ **↑ is history, as in a shell.** On a line nothing has been typed on yet —
480
+ empty, or the bare `/` a command line opens with — ↑ and ↓ walk what was
481
+ typed before (kept across launches, `history.mjs`); a command line walks only
482
+ the commands. Once something is typed, the arrows move in the list of
483
+ commands instead, and enter sends a recalled line as it is. Outside advanced
484
+ mode ↑ with no line open recalls the last entry onto the line it belongs to;
485
+ in advanced mode the wheel arrives as arrows, so there it is `/` or enter,
486
+ then ↑.
487
+
488
+ **`/view`** opens the focused session's page on cawdev — transcript, stages,
489
+ card — in the browser, on the console this terminal signed in to.
490
+
491
+ **`/view R29`** prints a card here instead: its status, section, tags, branch,
492
+ work item and pull request, who is coding or reviewing it, what it is related
493
+ to, its page on the web, and the first thirty lines of its body (`cardLines`,
494
+ pure). `/view <words>` finds it by its title among the cards of the projects on
495
+ screen and offers a list when several match; `@slug` names the project;
496
+ **`/view card`** is the focused session's own card.
497
+
498
+ **Which agent `/new` asks for.** `--claude`, `--codex` or `--agy` on a `/new`
499
+ names that session's agent (`/new dev R12 --codex`); `/agent codex` makes it
500
+ the terminal's choice for every `/new` after it, kept across launches
501
+ (`prefs.mjs`, `~/.cawdev/terminal.json`) and shown in advanced mode's prompt
502
+ title; `/agent default` hands the choice back to the project. A flag beats
503
+ `/agent`, and with neither nothing is named — the project's default decides,
504
+ as it always has. A name no runner spawns is refused, by `/agent` and by the
505
+ platform alike, rather than spawned as Claude Code; `/agent codex` on a
506
+ machine that does not list codex says so (`c` → Enable codex). The window's
507
+ `Codex · GPT-5-codex` line says which one actually ran.
508
+
509
+ **A stage asks rather than stops.** A decision that is the person's — a scope
510
+ the card leaves open, a plan the code has moved away from — is asked with
511
+ `ask_user`, and the stage carries on with the answer; PLAN asks before it
512
+ writes, so a plan never hands IMPLEMENT an open question, and IMPLEMENT asks
513
+ when its plan is wrong or incomplete instead of stopping (`ASK_DONT_STOP`).
514
+ Codex is given the time to: cawdev's MCP server gets `tool_timeout_sec` 660 on
515
+ its side, longer than `ask_user`'s ten-minute wait — Codex's own default of
516
+ 60 s cut every question off before anybody could answer it.
517
+
518
+ **Codex and Antigravity write only on a machine that allows everything.**
519
+ Neither has per-command permissions — Codex's sandbox is read-only, blocks the
520
+ network (no push) or is off — so a session of theirs that writes is refused,
521
+ unspawned, until the machine accepts console rules AND "Allow everything" is
522
+ ticked on it. The refusal says so in steps, for this machine
523
+ (`needsEverything`, lib/agents.mjs): which of the two is done, the Runners page
524
+ on this console, the command to start it again — and it is written on the
525
+ run's transcript as well as its summary, so the window shows it; a failed
526
+ window prints its run's summary (`sayWhyItFailed`) rather than just "failed".
527
+
528
+ **`/card <the idea in words>`** writes a card in **Considering** and starts
529
+ nothing — no session, no branch, nothing spent: the roadmap's first column
530
+ is where an idea waits to be decided on, and writing one down does not need
531
+ a model. Titled by its words (`cardTitleFor`), the whole text in its body;
532
+ the project chosen exactly as `/new` chooses it (`@project`, else advanced
533
+ mode narrowed to one, else asked).
534
+
535
+ **Across the top, the roadmap** (`roadmapStrip`): every project this machine
536
+ serves as a small board — Considering, Planned and In development side by
537
+ side, one line per card, `●` on a card with a session running now; Merged,
538
+ Shipped and Declined — work that is over, and only grows — are counts beside
539
+ the project's name (`1 merged · 2 shipped`), as the console's board folds its
540
+ own last columns. As tall as the fullest column, never more than a
541
+ third of the screen, and gone before the windows are on a short terminal.
542
+ When the room runs out it is SAID: a column ends in `+N more`, empty columns
543
+ go first when the width does, then whole columns (Considering, then Planned —
544
+ In development stays longest), named in the header as `considering 3
545
+ hidden`, then projects, counted as `+N projects`. Read every 30 s.
546
+
547
+ **A window says which agent and which model** — `Claude · Opus 5.5`,
548
+ `Codex · GPT-5-codex` — bold and underlined at the head of its second line
549
+ (`agentModelFor`, `modelLabel`). A live session's is the daemon's word, what
550
+ it actually spawned: the model asked for, replaced by the one Claude Code
551
+ announces on `init`, and per STAGE on a walked run, since each stage is its
552
+ own process. An ended one's is the platform's. No model named reads
553
+ `default model` — the CLI's own choice — rather than a guess.
554
+
555
+ **A window's project has a line of its own**, the second, under the title
556
+ (`subtitleFor`) — at the end of the title a long card name pushed it out of
557
+ sight. **A dev window adds where it is working**: the project and the absolute
558
+ path of the checkout — on a machine with `saasng` and its `-auto-N` clones, the
559
+ one directory to open. Cut from the left when narrow, so the end of the path
560
+ survives.
561
+
562
+ **The prompt shows what is open, not what was.** A question is the prompt's
563
+ banner alone, whole and wrapped between words, and it goes the moment it is
564
+ answered — here or in the console. A permission request's lines are tagged
565
+ with it (`sayAbout`) and leave when it is decided.
566
+
567
+ **A question says which window it came from.** With four sessions on screen,
568
+ "waiting for an answer" is not enough to know whose. A question or a
569
+ permission request names its session (`sessionTag`) — `2 · dev · R3 Client
570
+ mail… — saasng`: the window's number, its kind, its card and its project — in
571
+ the line announcing it, in the title of the picker that answers it, and above
572
+ the banner. The card is cut to 32 columns so the question itself still fits.
573
+
574
+ ### Checkouts made on demand: `autoWorkspaces`
575
+
576
+ `"autoWorkspaces": 3` in the machine's config lets the daemon CLONE up to three
577
+ more checkouts of a project by itself, when a coding run would otherwise wait
578
+ for "no free workspace" — so `/new dev R4` starts while R3 is still being
579
+ developed. Absent or 0 is none, as it has always been. The clone sits beside
580
+ the project's first checkout as `<first>-auto-2`, `-auto-3`…; it is a local
581
+ clone of the first (no credential, no download) with `origin` put back to the
582
+ project's remote. Nothing is written to the config: the daemon finds these by
583
+ their name at boot and on SIGHUP, so deleting one — `/drop`, or by hand — is
584
+ the whole of removing it. A clone and not a `git worktree`, on purpose: the
585
+ daemon's reset checks the default branch out, which git refuses in a second
586
+ worktree. Changed without a restart, like `agentCommands`.
587
+
588
+ ### `/reload`
589
+
590
+ Quitting and starting again, in one word — for when the client's code changed
591
+ on disk. The same command line runs again in a fresh process. When nothing is
592
+ running here the runner is stopped first (as `q` does), so the relaunch starts
593
+ it on the new code too; when sessions are live it is kept, and the terminal
594
+ says so — restarting it would end them. Under `runner.mjs --attach` the runner
595
+ is the terminal's own process, so `/reload` says to quit and start again.
596
+
597
+ It comes back **as you left it**: advanced mode if it was on, the same window
598
+ focused and the same session watched, the daemon's log shown or not, and the
599
+ windows of sessions that had ended — with their `/develop` and `/pr` — except
600
+ the ones you closed. The state travels to the new process in
601
+ `CAWDEV_RELOAD_STATE`, which that process reads once and removes, so nothing it
602
+ spawns inherits it.
603
+
334
604
  ### Where the socket is
335
605
 
336
606
  `~/.cawdev/run/<runner name>.sock`, in a `0700` directory, removed when the
@@ -370,6 +640,23 @@ How many coding runs go at once is `min(workspaces, maxSessions)`. A run that
370
640
  waits now says **"no free workspace in cawdev (2 here, all busy)"** instead of
371
641
  "that project already has a run here", which was a proxy for it.
372
642
 
643
+ **A free checkout with uncommitted work in it is not preferred over a clean
644
+ one** (R71/i258). A coding run with no pinned checkout and no free preferred
645
+ one now takes the first free checkout whose tree reads clean, checking each
646
+ free checkout in `workspaces` order until one does. It only falls back to a
647
+ free checkout somebody stranded work in — and today's *Start anyway* flow —
648
+ when every free checkout of that project is dirty; the log says so when it
649
+ happens. A *preferred* checkout (R212) is still taken whether it is clean or
650
+ not: it is the checkout the branch last ran in, so its uncommitted work is
651
+ plausibly that branch's own.
652
+
653
+ **Unless the run asked to wait for a clean one instead** (`waitForClean`,
654
+ R270). Then a preferred checkout is taken only when it reads clean, and when
655
+ nothing free reads clean the run is left queued — with a reason saying so —
656
+ rather than falling back to the first free checkout regardless. See "Prepares
657
+ the working copy" below for where that flag comes from and what the daemon
658
+ says about knowing it.
659
+
373
660
  **This number caps coding and nothing else** (R70). `ASK`, `ROADMAP`, `AUDIT`
374
661
  and `SCOPE` runs take no workspace, so a project whose checkouts are all busy
375
662
  still starts a question, an entry-writing session, an audit and a scoping
@@ -599,7 +886,24 @@ files at all. R47 removes the need for this by giving each run a workspace.
599
886
  uncommitted before the run is started, and the decision arrives with the
600
887
  claim as `allowDirty`. Without it the runner still refuses, with the file
601
888
  list, and fails the run saying so: a run that arrives with no flag is one
602
- nobody was warned about.
889
+ nobody was warned about. **Except when the dirt is the branch's own**: the
890
+ platform NAMED the checkout (a carried-on run's held workspace, R80, or a
891
+ pinned work item's next run, R86) and it is already on the run's branch.
892
+ Then the work is kept and not cleaned — refusing it made every *Carry on*
893
+ a second failure about work the run itself had written.
894
+
895
+ **Or the run may have said, before it got this far, to wait instead**
896
+ (`waitForClean`, R270) — the console's third way out of the dirty-checkout
897
+ panel, alongside *Start anyway* and *Cancel*. That is decided earlier, in
898
+ `pickWorkspace`, at poll time: with `waitForClean` set, the preferred
899
+ checkout is taken only when it reads clean, and when nothing free reads
900
+ clean the run is left queued with a reason rather than claimed at all — so
901
+ by the time a claim reaches this step, the checkout it names is already
902
+ clean and this whole paragraph does not apply. The daemon says
903
+ `waitForClean: true` in its capabilities, the same way it says
904
+ `baseBranches: true`, and an older daemon that does not is not offered such
905
+ a run — the platform tells it apart rather than letting it take a dirty
906
+ checkout the person explicitly asked it not to.
603
907
 
604
908
  With it, the edits are **carried onto the branch** — stashed, checked out,
605
909
  popped (R57). `git checkout` refuses outright when a locally modified file
@@ -659,6 +963,19 @@ files at all. R47 removes the need for this by giving each run a workspace.
659
963
  writes to git: no merging, no branch deletion, no pushing. (A project's own
660
964
  rules can ask for all three — see below — but that is a queued action with a
661
965
  name on it, not something the survey does in passing.)
966
+ 7b. **A stage is not done while its commands are still running.** A stage is
967
+ one turn, closed the moment the turn ends, so a test suite started with
968
+ `run_in_background` and never waited for is a result lost. The daemon
969
+ follows the session's background shells (`lib/background-shells.mjs`:
970
+ `Bash` with `run_in_background`, `BashOutput`, `KillShell`); a stage whose
971
+ turn ends with one still running, or finished and never read, is reported
972
+ FAILED with the commands named, and the run fails with it — keeping its
973
+ checkout and its session (R80), so **`/continue` picks it up**. Where it
974
+ resumes is the platform's (R263: the claim's lifecycle starts at the first
975
+ stage not DONE, with what the DONE ones said); what the daemon adds is WHY
976
+ the stage stopped — the re-run is handed that and told to run its commands
977
+ in the foreground. IMPLEMENT and TEST are also told up front to
978
+ wait for every command, and TEST to commit — no stage after it writes code.
662
979
  8. **Reports the lifecycle back** and, if the session dies without saying
663
980
  anything, ends the run rather than leaving it `RUNNING` forever.
664
981
 
@@ -729,12 +1046,34 @@ that reaches the server by another name than the platform does (a LAN
729
1046
  hostname), and `timeoutSeconds` (600) bounding the scan and the wait.
730
1047
 
731
1048
  **Community Edition.** A server that refuses `sonar.branch.name` — every
732
- Community Edition — is *skipped by default*: the reading carries an error
733
- saying so, and nothing is analysed. `"whenBranchesRefused": "main"` in the
734
- block opts into the fallback, which analyses the branch as the project's
735
- **main** analysis and marks the reading `MAIN` with a warning. Understand what
736
- that trades: the project's own dashboard, and the platform's project reading
737
- with it, then describe whichever branch scanned last. Nothing opts in for you.
1049
+ Community Edition without the plugin below — is *skipped by default*: the
1050
+ reading carries an error saying so, and nothing is analysed.
1051
+ `"whenBranchesRefused"` in the block opts into one of two fallbacks; `skip`
1052
+ stays the default and nothing opts in for you.
1053
+
1054
+ - `"main"` re-scans the branch as the project's **main** analysis and marks
1055
+ the reading `MAIN` with a warning. Understand what that trades: the
1056
+ project's own dashboard, and the platform's project reading with it, then
1057
+ describe whichever branch scanned last.
1058
+ - `"project"` scans the branch as its **own scratch SonarQube project**
1059
+ instead — `<key>:branch:<branch>-<hash>`, overwritten on each run of the
1060
+ branch, and never touching the project's own dashboard. A fresh project has
1061
+ no new-code period, so "new" is redefined as *on a line this branch
1062
+ changed*; the reading is marked `PROJECT`, its gate is always `NONE`
1063
+ (nothing to gate a scratch project on), and there is no new-code coverage.
1064
+ This needs the scanner's token to hold **Create Projects** on the server —
1065
+ check its default project visibility too, since *public* would publish the
1066
+ code. cawdev never deletes these scratch projects; cleaning them up is the
1067
+ operator's own housekeeping.
1068
+
1069
+ The project itself can say which of these it needs: its Settings →
1070
+ SonarQube card offers *Developer Edition or above (or Community with the
1071
+ [sonarqube-community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin)
1072
+ installed)*, *Community Edition*, or *Not sure — find out on the first scan*.
1073
+ Set correctly, the daemon skips the doomed branch attempt and goes straight
1074
+ to the chosen fallback; left at "not sure", behaviour is exactly as above.
1075
+ **Restart the daemon after upgrading it to use `"project"`**: an older
1076
+ runner does not know the value and refuses to boot with it in its config.
738
1077
 
739
1078
  **A failed scan never fails a run.** A machine with no block scans nothing and
740
1079
  says nothing. A machine with a block and a project with no key logs `not
@@ -1096,3 +1435,42 @@ the prompt.
1096
1435
  The prompt deliberately teaches the **method**, not the task. The task is in the
1097
1436
  roadmap entry, which the agent reads for itself with `task_current` — putting it
1098
1437
  in the prompt too would be a second copy that can disagree with the entry.
1438
+
1439
+ ### Codex CLI
1440
+
1441
+ `codex` in `agentCommands` (`cawdev config agent enable codex`) lets a run name
1442
+ `codex` as its agent. It is spawned by `spawnCodex`, one `codex exec --json`
1443
+ per turn like Antigravity, and every flag it is given is in
1444
+ `../lib/codex.mjs` with what was checked against the real CLI (0.155). Sign in
1445
+ once with `codex login`; the run uses that sign-in and **not** your
1446
+ `~/.codex/config.toml` (`--ignore-user-config`, this CLI's `--setting-sources
1447
+ ''`), so a model or MCP server you configured for yourself does not reach it.
1448
+
1449
+ Codex has a sandbox the operating system enforces, and that decides what it
1450
+ may do:
1451
+
1452
+ - **A run that must change nothing** — ASK, AUDIT, SCOPE, REVIEW, PLAN, and the
1453
+ PLAN, VERIFY and MEMORY stages of any run — gets `--sandbox read-only`. Its
1454
+ shell reads and cannot write, and it needs nothing from the machine. Only
1455
+ cawdev's server is attached, narrowed with `enabled_tools` to the list Claude
1456
+ Code would be handed, and no stage ever holds `report`.
1457
+ - **A run that writes** — CODE, INTERVIEW, MERGE, RELEASE and their IMPLEMENT
1458
+ and TEST — must commit and push, which the sandbox refuses, and Codex has no
1459
+ allow-list for its shell. So it runs with
1460
+ `--dangerously-bypass-approvals-and-sandbox`, and **only on a machine that
1461
+ allows everything** (R126); anywhere else the run fails before anything is
1462
+ spawned, saying so.
1463
+
1464
+ Every MCP server is marked `default_tools_approval_mode = "approve"` — in `exec`
1465
+ the approval policy is *never*, and without it every call to cawdev is refused.
1466
+ The run's token reaches cawdev's server through `env_vars`, never the command
1467
+ line, and is blanked for the model's own commands
1468
+ (`shell_environment_policy.set`).
1469
+
1470
+ Not reached on Codex: experts (the session is told it cannot delegate), a
1471
+ project's tool rules and R51's permission prompt (both are Claude Code's
1472
+ `--allowedTools` grammar and its `approve` handler), the command half of R110's
1473
+ shield (the transcript half — secrets taken out of a result — runs in the daemon
1474
+ and applies), and live prompting (the process ends with its turn; a follow-up is
1475
+ `codex exec resume`). Skills are inlined whole, as for Antigravity. No usage
1476
+ windows are read: Codex has no `-p /usage`.