cawdev-cli 1.0.5-beta → 1.0.7-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/lib/agents.mjs +38 -0
- package/lib/background-shells.mjs +108 -0
- package/lib/codex.mjs +5 -0
- package/lib/roadmap-format.mjs +52 -0
- package/mcp/server.mjs +62 -11
- package/package.json +1 -1
- package/runner/README.md +191 -22
- package/runner/attach.mjs +708 -69
- package/runner/cawdev.mjs +17 -2
- package/runner/configure.mjs +34 -0
- package/runner/input.mjs +26 -9
- package/runner/prefs.mjs +52 -0
- package/runner/restart.mjs +191 -0
- package/runner/runner.mjs +323 -27
- package/runner/sign-in.mjs +11 -0
- package/runner/split.mjs +109 -16
package/runner/README.md
CHANGED
|
@@ -68,6 +68,13 @@ page and waits for you to approve a code; after that it is remembered, and
|
|
|
68
68
|
`/login` does it again on demand. No password is ever typed into the terminal —
|
|
69
69
|
that belongs on a page your browser has told you the origin of.
|
|
70
70
|
|
|
71
|
+
When the platform stops honouring that session — it expired, you signed out in
|
|
72
|
+
the console, or your account went — the first request answered 401 says so
|
|
73
|
+
once, the footer pins `session expired — /login to sign in again`, and the
|
|
74
|
+
terminal drops to watching only until `/login` succeeds. The polls pick up again
|
|
75
|
+
on their own after it. In advanced mode `/login` stays in advanced mode: the URL
|
|
76
|
+
and the code are printed in the prompt window.
|
|
77
|
+
|
|
71
78
|
```
|
|
72
79
|
cawdev the runner here, starting one if there is none
|
|
73
80
|
cawdev --runner <name> when this machine runs more than one
|
|
@@ -101,8 +108,8 @@ with the window — there `q` stops it, and asks first when sessions are live.
|
|
|
101
108
|
machine is configured, most changes are smaller than that. **Inside the
|
|
102
109
|
terminal, press `c`** (or type `/config`): a picker over what this machine does
|
|
103
110
|
— add a project, add a workspace, each agent with its current state ("Disable
|
|
104
|
-
claude", "Enable codex"), the console-rules switch,
|
|
105
|
-
token cut short. Every row is one of the shell commands below, driven through
|
|
111
|
+
claude", "Enable codex"), the console-rules switch, **Stop serving** each
|
|
112
|
+
project, and the config itself with the token cut short. Every row is one of the shell commands below, driven through
|
|
106
113
|
the terminal's own line editor and picker; `esc` anywhere in a step changes
|
|
107
114
|
nothing. The screen edits the file the daemon says it booted from (the hello
|
|
108
115
|
carries `configPath` since R288), so an older daemon is told to restart rather
|
|
@@ -126,6 +133,7 @@ is for scripts and for a machine with no daemon to attach to:
|
|
|
126
133
|
cawdev config a menu, the same Select widget as everywhere else
|
|
127
134
|
cawdev config add-project serve one more project you can write to
|
|
128
135
|
cawdev config add-workspace another checkout for a project already served
|
|
136
|
+
cawdev config remove-project <slug> stop serving a project; its checkouts stay on disk
|
|
129
137
|
cawdev config agent enable|disable <claude|agy|codex>
|
|
130
138
|
cawdev config rules on|off accept permission rules from the console — R126
|
|
131
139
|
cawdev config show this machine's config, token redacted
|
|
@@ -221,7 +229,10 @@ move through the command list while one is open.
|
|
|
221
229
|
| `/quit` | leave |
|
|
222
230
|
|
|
223
231
|
**Typing `/` filters that list as you go**, each row with its description; arrows
|
|
224
|
-
and `enter` pick one and `tab` completes as far as the matches agree
|
|
232
|
+
and `enter` pick one and `tab` completes as far as the matches agree — then
|
|
233
|
+
moves down the list, so `/lo` `tab` `tab` reaches `/login` past `/log`. A name
|
|
234
|
+
typed in full is the first row, so `/log` `enter` runs `/log`. Advanced mode
|
|
235
|
+
draws the same list above its prompt, six rows at a time. Guessing a
|
|
225
236
|
command name and being told `no such command` is a step, and it is the step this
|
|
226
237
|
removes.
|
|
227
238
|
|
|
@@ -230,7 +241,8 @@ removes.
|
|
|
230
241
|
`/logout` forgets it along with the session.
|
|
231
242
|
|
|
232
243
|
**A paste stays one line.** Paste four hundred lines and the input shows
|
|
233
|
-
`[pasted, 342 lines]`; all of it is sent
|
|
244
|
+
`[pasted, 342 lines]`; all of it is sent — into a prompt or into a command alike
|
|
245
|
+
(`/new plan <paste>`, `/card <paste>`), its line breaks kept (`commandWords`). A paste that scrolled the transcript
|
|
234
246
|
away would bury the thing this program exists to keep.
|
|
235
247
|
|
|
236
248
|
Under `NO_COLOR` it is the same terminal without the colour: the picker still
|
|
@@ -359,8 +371,17 @@ project this machine serves included ("nothing planned" is an answer) — one
|
|
|
359
371
|
small box each, titled with the card and its status — `R3 (Planned)` — the cards of
|
|
360
372
|
every project this machine serves that are ready to be developed, read again
|
|
361
373
|
every thirty seconds. **`d`** lists them and develops the one you pick, on this
|
|
362
|
-
machine and on the card's own branch
|
|
363
|
-
|
|
374
|
+
machine and on the card's own branch — except on a finished plan's window, where
|
|
375
|
+
it is that plan's `/develop` (below) with no list; `/new dev` with nothing after it does the
|
|
376
|
+
same anywhere, and `/new dev R3` goes straight to one. A full-width rule
|
|
377
|
+
under the strip separates the board from the session windows; it comes out of
|
|
378
|
+
the strip's own rows, never the windows'.
|
|
379
|
+
|
|
380
|
+
**`/refresh`** reads the cards again now rather than on the next tick, and
|
|
381
|
+
says what it found per project — `saasng: 5 considering · 2 planned · 1 in
|
|
382
|
+
development` — and which project could not be read, and why. A project that
|
|
383
|
+
cannot be read keeps its last cards and no other's: one unreadable slug used
|
|
384
|
+
to leave every column of every project at 0, silently.
|
|
364
385
|
|
|
365
386
|
**Four windows at most.** Past four, the rest are named on one line above the
|
|
366
387
|
prompt — number, kind, state, card, in the state's colour — and `tab` (or the
|
|
@@ -371,8 +392,15 @@ recently looked at first.
|
|
|
371
392
|
A window stays up when its session ends, and its last line says what can be
|
|
372
393
|
done next:
|
|
373
394
|
|
|
374
|
-
- **`/develop`** on a finished plan
|
|
375
|
-
this
|
|
395
|
+
- **`d`** or **`/develop`** on a finished plan — the window says `d develops R2
|
|
396
|
+
here, in place of this plan` — starts the development of its card, on
|
|
397
|
+
this machine (the branch is the card's own). `/develop R30` names another
|
|
398
|
+
card, `@slug` its project, and `--codex`/`--claude`/`--agy` the agent —
|
|
399
|
+
otherwise the agent that PLANNED the card when its finished plan has a
|
|
400
|
+
window here, else `/agent`'s choice, exactly as `/new dev R30` does, because
|
|
401
|
+
it IS that command. Once the development has started the plan's window
|
|
402
|
+
closes, and the development's window takes its focus when this machine
|
|
403
|
+
takes the run; a start the platform refused leaves the plan's window up.
|
|
376
404
|
- **`/pr`** on a finished session that wrote a branch opens its pull request
|
|
377
405
|
(`POST runs/{id}/pull-request` — through the card's work item, or from the
|
|
378
406
|
run itself for a session started from a sentence): this machine pushes the
|
|
@@ -395,7 +423,18 @@ done next:
|
|
|
395
423
|
project's runs, kept when `carriesOnHere` — yours, `canCarryOn`, and its
|
|
396
424
|
checkout on this machine or none), listed in the scrollback, and given a
|
|
397
425
|
window that opens on why it stopped.
|
|
398
|
-
-
|
|
426
|
+
- **Finished, having built nothing** — a dev session that ended FINISHED
|
|
427
|
+
with no commit (IMPLEMENT stopped on a plan it would not follow, say) —
|
|
428
|
+
reads `finished · nothing built`, in amber rather than green, offers no
|
|
429
|
+
`/pr` but the re-plan instead, and its window shows its summary, where it
|
|
430
|
+
said why (`builtNothing`; the terminal reads the run's commits once it
|
|
431
|
+
ends, and claims nothing until it has).
|
|
432
|
+
- **`/open`** opens the pull request in your browser. It reads the run again
|
|
433
|
+
first — the runner records the link after the run is FINISHED, so the copy
|
|
434
|
+
taken at that moment has none — and falls back to the card's work item.
|
|
435
|
+
On a finished PLAN, which opens no pull request, it opens the card on cawdev
|
|
436
|
+
instead — `roadmap/R2?show=plan` (`issues/…` for an issue) — with the plan
|
|
437
|
+
of record unfolded and scrolled to: that plan is what the session produced.
|
|
399
438
|
- **`/drop`** deletes the checkout the session was cloned into, when it was one
|
|
400
439
|
made on demand (below): asked first, naming the path, and refused while a
|
|
401
440
|
run is in it or holds it, with uncommitted files, or with a commit origin
|
|
@@ -424,6 +463,21 @@ sentence; `--anyway` starts it regardless, the same decision the console's
|
|
|
424
463
|
panel asks for. All four commands need you signed in (`/login`), and they work
|
|
425
464
|
outside advanced mode too, on the session you are watching.
|
|
426
465
|
|
|
466
|
+
**The prompt says which window it acts on.** In advanced mode the line at the
|
|
467
|
+
bottom leads with the focused window's number — `[2] cawdev ▸ /pr`, `[2]
|
|
468
|
+
enter prompts “…”` — and a command's answer keeps the number of the window it
|
|
469
|
+
was about (`[2] A session on … is running`), so a note left on screen after
|
|
470
|
+
the focus moved still says whose it was.
|
|
471
|
+
|
|
472
|
+
**A project deleted in the console is not offered.** The config on this
|
|
473
|
+
machine still names it, and nothing on the platform can change that file, so
|
|
474
|
+
the terminal asks: a served project whose roadmap read answers 404 — deleted,
|
|
475
|
+
or your access went — is left out of the picker, the strip, `/new` and `/card`,
|
|
476
|
+
and one line says so, once, after the mode is on screen. `c` → **Stop serving
|
|
477
|
+
ngsign** (`cawdev config remove-project ngsign`) takes it out of the config;
|
|
478
|
+
the checkouts stay where they are, and the daemon stops polling for it at its
|
|
479
|
+
next restart, because `projects` is read at boot.
|
|
480
|
+
|
|
427
481
|
**Which projects it shows is yours to pick.** `/advanced-mode` on a machine
|
|
428
482
|
serving several projects opens a picker with every one ticked — space (or a
|
|
429
483
|
digit) ticks and unticks, `a` all or none, enter confirms — and only the
|
|
@@ -432,16 +486,73 @@ projects ticked are drawn: their windows, their roadmap on top, and the ones
|
|
|
432
486
|
nothing; `/projects` asks again from inside the mode; `/reload` keeps the
|
|
433
487
|
pick. A prompt never talks to a session of a project that is not shown.
|
|
434
488
|
|
|
489
|
+
**↑ is history, as in a shell.** On a line nothing has been typed on yet —
|
|
490
|
+
empty, or the bare `/` a command line opens with — ↑ and ↓ walk what was
|
|
491
|
+
typed before (kept across launches, `history.mjs`); a command line walks only
|
|
492
|
+
the commands. Once something is typed, the arrows move in the list of
|
|
493
|
+
commands instead, and enter sends a recalled line as it is. Outside advanced
|
|
494
|
+
mode ↑ with no line open recalls the last entry onto the line it belongs to;
|
|
495
|
+
in advanced mode the wheel arrives as arrows, so there it is `/` or enter,
|
|
496
|
+
then ↑.
|
|
497
|
+
|
|
498
|
+
**`/view`** opens the focused session's page on cawdev — transcript, stages,
|
|
499
|
+
card — in the browser, on the console this terminal signed in to.
|
|
500
|
+
|
|
501
|
+
**`/view R29`** prints a card here instead: its status, section, tags, branch,
|
|
502
|
+
work item and pull request, who is coding or reviewing it, what it is related
|
|
503
|
+
to, its page on the web, and the first thirty lines of its body (`cardLines`,
|
|
504
|
+
pure). `/view <words>` finds it by its title among the cards of the projects on
|
|
505
|
+
screen and offers a list when several match; `@slug` names the project;
|
|
506
|
+
**`/view card`** is the focused session's own card.
|
|
507
|
+
|
|
508
|
+
**Which agent `/new` asks for.** `--claude`, `--codex` or `--agy` on a `/new`
|
|
509
|
+
names that session's agent (`/new dev R12 --codex`); `/agent codex` makes it
|
|
510
|
+
the terminal's choice for every `/new` after it, kept across launches
|
|
511
|
+
(`prefs.mjs`, `~/.cawdev/terminal.json`) and shown in advanced mode's prompt
|
|
512
|
+
title; `/agent default` hands the choice back to the project. A flag beats
|
|
513
|
+
`/agent`, and with neither nothing is named — the project's default decides,
|
|
514
|
+
as it always has. A name no runner spawns is refused, by `/agent` and by the
|
|
515
|
+
platform alike, rather than spawned as Claude Code; `/agent codex` on a
|
|
516
|
+
machine that does not list codex says so (`c` → Enable codex). The window's
|
|
517
|
+
`Codex · GPT-5-codex` line says which one actually ran.
|
|
518
|
+
|
|
519
|
+
**A stage asks rather than stops.** A decision that is the person's — a scope
|
|
520
|
+
the card leaves open, a plan the code has moved away from — is asked with
|
|
521
|
+
`ask_user`, and the stage carries on with the answer; PLAN asks before it
|
|
522
|
+
writes, so a plan never hands IMPLEMENT an open question, and IMPLEMENT asks
|
|
523
|
+
when its plan is wrong or incomplete instead of stopping (`ASK_DONT_STOP`).
|
|
524
|
+
Codex is given the time to: cawdev's MCP server gets `tool_timeout_sec` 660 on
|
|
525
|
+
its side, longer than `ask_user`'s ten-minute wait — Codex's own default of
|
|
526
|
+
60 s cut every question off before anybody could answer it.
|
|
527
|
+
|
|
528
|
+
**Codex and Antigravity write only on a machine that allows everything.**
|
|
529
|
+
Neither has per-command permissions — Codex's sandbox is read-only, blocks the
|
|
530
|
+
network (no push) or is off — so a session of theirs that writes is refused,
|
|
531
|
+
unspawned, until the machine accepts console rules AND "Allow everything" is
|
|
532
|
+
ticked on it. The refusal says so in steps, for this machine
|
|
533
|
+
(`needsEverything`, lib/agents.mjs): which of the two is done, the Runners page
|
|
534
|
+
on this console, the command to start it again — and it is written on the
|
|
535
|
+
run's transcript as well as its summary, so the window shows it; a failed
|
|
536
|
+
window prints its run's summary (`sayWhyItFailed`) rather than just "failed".
|
|
537
|
+
|
|
538
|
+
**`/card <the idea in words>`** writes a card in **Considering** and starts
|
|
539
|
+
nothing — no session, no branch, nothing spent: the roadmap's first column
|
|
540
|
+
is where an idea waits to be decided on, and writing one down does not need
|
|
541
|
+
a model. Titled by its words (`cardTitleFor`), the whole text in its body;
|
|
542
|
+
the project chosen exactly as `/new` chooses it (`@project`, else advanced
|
|
543
|
+
mode narrowed to one, else asked).
|
|
544
|
+
|
|
435
545
|
**Across the top, the roadmap** (`roadmapStrip`): every project this machine
|
|
436
|
-
serves as a small board — Considering, Planned
|
|
437
|
-
|
|
438
|
-
Shipped and Declined,
|
|
439
|
-
|
|
546
|
+
serves as a small board — Considering, Planned and In development side by
|
|
547
|
+
side, one line per card, `●` on a card with a session running now; Merged,
|
|
548
|
+
Shipped and Declined — work that is over, and only grows — are counts beside
|
|
549
|
+
the project's name (`1 merged · 2 shipped`), as the console's board folds its
|
|
550
|
+
own last columns. As tall as the fullest column, never more than a
|
|
440
551
|
third of the screen, and gone before the windows are on a short terminal.
|
|
441
552
|
When the room runs out it is SAID: a column ends in `+N more`, empty columns
|
|
442
|
-
go first when the width does, then whole columns (
|
|
443
|
-
|
|
444
|
-
|
|
553
|
+
go first when the width does, then whole columns (Considering, then Planned —
|
|
554
|
+
In development stays longest), named in the header as `considering 3
|
|
555
|
+
hidden`, then projects, counted as `+N projects`. Read every 30 s.
|
|
445
556
|
|
|
446
557
|
**A window says which agent and which model** — `Claude · Opus 5.5`,
|
|
447
558
|
`Codex · GPT-5-codex` — bold and underlined at the head of its second line
|
|
@@ -451,16 +562,25 @@ announces on `init`, and per STAGE on a walked run, since each stage is its
|
|
|
451
562
|
own process. An ended one's is the platform's. No model named reads
|
|
452
563
|
`default model` — the CLI's own choice — rather than a guess.
|
|
453
564
|
|
|
454
|
-
**A
|
|
455
|
-
the
|
|
456
|
-
|
|
457
|
-
|
|
565
|
+
**A window's project has a line of its own**, the second, under the title
|
|
566
|
+
(`subtitleFor`) — at the end of the title a long card name pushed it out of
|
|
567
|
+
sight. **A dev window adds where it is working**: the project and the absolute
|
|
568
|
+
path of the checkout — on a machine with `saasng` and its `-auto-N` clones, the
|
|
569
|
+
one directory to open. Cut from the left when narrow, so the end of the path
|
|
570
|
+
survives.
|
|
458
571
|
|
|
459
572
|
**The prompt shows what is open, not what was.** A question is the prompt's
|
|
460
573
|
banner alone, whole and wrapped between words, and it goes the moment it is
|
|
461
574
|
answered — here or in the console. A permission request's lines are tagged
|
|
462
575
|
with it (`sayAbout`) and leave when it is decided.
|
|
463
576
|
|
|
577
|
+
**A question says which window it came from.** With four sessions on screen,
|
|
578
|
+
"waiting for an answer" is not enough to know whose. A question or a
|
|
579
|
+
permission request names its session (`sessionTag`) — `2 · dev · R3 Client
|
|
580
|
+
mail… — saasng`: the window's number, its kind, its card and its project — in
|
|
581
|
+
the line announcing it, in the title of the picker that answers it, and above
|
|
582
|
+
the banner. The card is cut to 32 columns so the question itself still fits.
|
|
583
|
+
|
|
464
584
|
### Checkouts made on demand: `autoWorkspaces`
|
|
465
585
|
|
|
466
586
|
`"autoWorkspaces": 3` in the machine's config lets the daemon CLONE up to three
|
|
@@ -853,6 +973,19 @@ files at all. R47 removes the need for this by giving each run a workspace.
|
|
|
853
973
|
writes to git: no merging, no branch deletion, no pushing. (A project's own
|
|
854
974
|
rules can ask for all three — see below — but that is a queued action with a
|
|
855
975
|
name on it, not something the survey does in passing.)
|
|
976
|
+
7b. **A stage is not done while its commands are still running.** A stage is
|
|
977
|
+
one turn, closed the moment the turn ends, so a test suite started with
|
|
978
|
+
`run_in_background` and never waited for is a result lost. The daemon
|
|
979
|
+
follows the session's background shells (`lib/background-shells.mjs`:
|
|
980
|
+
`Bash` with `run_in_background`, `BashOutput`, `KillShell`); a stage whose
|
|
981
|
+
turn ends with one still running, or finished and never read, is reported
|
|
982
|
+
FAILED with the commands named, and the run fails with it — keeping its
|
|
983
|
+
checkout and its session (R80), so **`/continue` picks it up**. Where it
|
|
984
|
+
resumes is the platform's (R263: the claim's lifecycle starts at the first
|
|
985
|
+
stage not DONE, with what the DONE ones said); what the daemon adds is WHY
|
|
986
|
+
the stage stopped — the re-run is handed that and told to run its commands
|
|
987
|
+
in the foreground. IMPLEMENT and TEST are also told up front to
|
|
988
|
+
wait for every command, and TEST to commit — no stage after it writes code.
|
|
856
989
|
8. **Reports the lifecycle back** and, if the session dies without saying
|
|
857
990
|
anything, ends the run rather than leaving it `RUNNING` forever.
|
|
858
991
|
|
|
@@ -1077,6 +1210,39 @@ A run **`WAITING_ON_USER` is never swept.** That is the one state where nothing
|
|
|
1077
1210
|
happening is correct: it is stalled on a person, who may reasonably take a day.
|
|
1078
1211
|
Nor is a `PAUSED` or `USAGE_LIMITED` one (below) — there is no process to lose.
|
|
1079
1212
|
|
|
1213
|
+
### When the daemon itself was killed (R339)
|
|
1214
|
+
|
|
1215
|
+
A daemon that dies and is restarted — by systemd, by `cawdev`, by hand — comes
|
|
1216
|
+
back with nothing in its hands, and the platform could only infer that five
|
|
1217
|
+
minutes later, as "its runner is alive but stopped driving it". So the daemon
|
|
1218
|
+
keeps a note of the runs it is driving (`~/.cawdev/driving/<runner id>.json`,
|
|
1219
|
+
rewritten when the set changes), and on boot the next one reads it: every run
|
|
1220
|
+
the dead daemon was driving that the platform still believes in is failed **at
|
|
1221
|
+
once** as `DAEMON_RESTARTED`, with the old and new pids and where to look for the
|
|
1222
|
+
cause. A session the old daemon left running is stopped first — only when its
|
|
1223
|
+
pid still runs the command it was spawned with. The workspace is held exactly as
|
|
1224
|
+
for a vanished runner, and a machine with **auto-resume** on carries such a run
|
|
1225
|
+
on by itself **once**; a second restart on the same run waits for a person,
|
|
1226
|
+
because a test suite that killed the daemon twice will kill it a third time.
|
|
1227
|
+
|
|
1228
|
+
The usual cause on a small Linux box is memory: the session runs a test suite,
|
|
1229
|
+
the kernel's OOM killer picks the biggest process, and that is sometimes the
|
|
1230
|
+
daemon. `journalctl -k | grep -i "killed process"` says so. Two fixes, both on
|
|
1231
|
+
the machine:
|
|
1232
|
+
|
|
1233
|
+
- **`"sessionMemoryMax": "6G"`** in `runner.config.json` spawns each agent
|
|
1234
|
+
session under `systemd-run --scope -p MemoryMax=…` (a size systemd reads —
|
|
1235
|
+
`6G`, `512M`, `75%`). A session that blows through it is killed on its own,
|
|
1236
|
+
the ordinary "agent was terminated" failure, and the daemon stays up. Linux
|
|
1237
|
+
only, and it needs a systemd manager for the user (`loginctl enable-linger
|
|
1238
|
+
<user>` on a box with nobody logged in) or a daemon running as root; the
|
|
1239
|
+
daemon probes once at boot and says in its log whether it applied. Needs a
|
|
1240
|
+
restart to change.
|
|
1241
|
+
- **Protect the daemon and give the box room**: in the daemon's systemd unit,
|
|
1242
|
+
`OOMScoreAdjust=-800` makes the kernel pick a test worker over the daemon;
|
|
1243
|
+
and add swap (`fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap
|
|
1244
|
+
/swapfile && swapon /swapfile`, plus its `/etc/fstab` line).
|
|
1245
|
+
|
|
1080
1246
|
## When the usage limit hits (R73)
|
|
1081
1247
|
|
|
1082
1248
|
Claude Code stops with a message naming the window — the five-hour one or the
|
|
@@ -1186,8 +1352,11 @@ your inbox and on the run, and waits for an answer. Allow it once, or allow it
|
|
|
1186
1352
|
always here — which writes a rule on the project that every runner serving it
|
|
1187
1353
|
inherits.
|
|
1188
1354
|
|
|
1189
|
-
Nobody answering is a decision too: after
|
|
1190
|
-
|
|
1355
|
+
Nobody answering is a decision too: after the project's wait — fifteen minutes
|
|
1356
|
+
unless its Rules page says otherwise, and possibly never (R339) — the request
|
|
1357
|
+
expires and the session is told to carry on without it. Allowing it later still
|
|
1358
|
+
works: the grant lasts the rest of the run and the session is sent a message to
|
|
1359
|
+
try again. A stage gate never expires.
|
|
1191
1360
|
|
|
1192
1361
|
You can still say in advance what a project may do, and for anything a session
|
|
1193
1362
|
needs on every run that is the better answer — with `allowedTools`, which
|