Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
249 commits
Select commit Hold shift + click to select a range
d4981a0
test(native-chat): a Stop over a card sent now into the running turn …
brennanb2025 Sep 30, 2026
943bbe4
fix(native-chat): a Stop's queue pause holds a card whose hand-off is…
brennanb2025 Sep 30, 2026
071e2c0
test(native-chat): the Claude re-send case fails on its diff, inside …
brennanb2025 Sep 30, 2026
7de5fca
test(native-chat): a pause held by an unanswered hand-off ends on eve…
brennanb2025 Sep 30, 2026
c07320f
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Sep 30, 2026
6ce9464
fix(native-chat): narrow the pause's settled hand-off, and assert the…
brennanb2025 Sep 30, 2026
d9e9b97
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Sep 30, 2026
2af16ab
refactor(native-chat): derive the queue's pause from Stop and Resume …
brennanb2025 Sep 30, 2026
438240a
fix(native-chat): a card queued after a Stop sends normally, never ah…
brennanb2025 Sep 30, 2026
6de6b32
fix(native-chat): the queue's own send re-checks the no-overtake rule…
brennanb2025 Sep 30, 2026
340f4a6
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Sep 30, 2026
d8b9e48
fix(native-chat): stop creating the unused queue pause table
brennanb2025 Sep 30, 2026
44e5184
fix(native-chat): a Stop's pause never hides the restart pause
brennanb2025 Sep 30, 2026
a90bd87
test(native-chat): pin the Stop's no-resend, lift and held-card rules
brennanb2025 Sep 30, 2026
fbd56c6
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Sep 30, 2026
99589e9
refactor(native-chat): a Stop writes one Stop event with its reason, …
brennanb2025 Sep 30, 2026
e0087ee
test(native-chat): a rewind keeps a lifted /clear pause lifted and re…
brennanb2025 Sep 30, 2026
e447899
test(native-chat): pin that Stop and Resume rows never reach apps or …
brennanb2025 Sep 30, 2026
60500d8
test(native-chat): only a person's Stop event pauses the queue
brennanb2025 Sep 30, 2026
839f6f4
test(native-chat): pin that a Stop's event precedes the interrupt and…
brennanb2025 Sep 30, 2026
d5b48ef
test(native-chat): a card held at a starting agent is checked before …
brennanb2025 Sep 30, 2026
5689a9d
test(native-chat): a released build keeps and folds a journal holding…
brennanb2025 Sep 30, 2026
8c5523e
style(native-chat): format the Stop event changes
brennanb2025 Sep 30, 2026
5c38ea6
test(native-chat): type the released build's exports through one chec…
brennanb2025 Sep 30, 2026
a12b65a
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Sep 30, 2026
26e9419
fix(native-chat): the Stop/Resume row guard narrows to those tombston…
brennanb2025 Sep 30, 2026
977d500
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Sep 30, 2026
806765b
test(native-chat): run the Stop-event downgrade test in CI, and cover…
brennanb2025 Sep 30, 2026
8ec0fbf
fix(native-chat): a Stop that stops nothing new writes no Stop event
brennanb2025 Sep 30, 2026
722e964
test(native-chat): pin that a later host, eviction or close Stop neve…
brennanb2025 Sep 30, 2026
74adc16
chore(native-chat): put each Stop-row doc on its own declaration, and…
brennanb2025 Sep 30, 2026
4750645
fix(native-chat): any later Stop event ends a person's Stop pause
brennanb2025 Sep 30, 2026
c0d9689
fix(native-chat): a second Stop press is a repeat even when the first…
brennanb2025 Sep 30, 2026
989f90b
fix(native-chat): the queue's pause ignores a Stop or Resume row hold…
brennanb2025 Oct 1, 2026
be2be9f
fix(native-chat): a Stop still reads as yours after Orca restarts bef…
brennanb2025 Oct 1, 2026
935d24a
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Oct 1, 2026
cc32533
refactor(native-chat): a stop no longer carries its cause; the turn's…
brennanb2025 Oct 1, 2026
93e2f55
test(native-chat): a turn a later send opened is no Stop's that named…
brennanb2025 Oct 1, 2026
4be2b8b
test(native-chat): the restart test's death proof carries its detail
brennanb2025 Oct 1, 2026
c98b280
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Oct 1, 2026
8276989
Merge #24072's branch (with #24235) into stop-event part B
brennanb2025 Oct 1, 2026
20852ee
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Oct 1, 2026
d388b9c
refactor(native-chat): a refused Stop leaves no record; a Stop only e…
brennanb2025 Oct 1, 2026
f85a984
fix(native-chat): a Stop pressed before any turn showed stops only th…
brennanb2025 Oct 1, 2026
2ba34a9
fix(native-chat): an older Claude's error end after a Stop pressed be…
brennanb2025 Oct 1, 2026
4fdd9ad
fix(native-chat): a person's Stop and /clear each name why they end t…
brennanb2025 Oct 1, 2026
98ee326
fix(native-chat): a host stop judges whether it ends work after the p…
brennanb2025 Oct 1, 2026
d0e4cfc
fix(native-chat): a Claude Stop naming a turn that just ended still m…
brennanb2025 Oct 1, 2026
771ad35
fix(native-chat): the idle sweep reads working by the same rule as a …
brennanb2025 Oct 1, 2026
a51a1ee
test(native-chat): an aborted eviction's injected drain failure lands…
brennanb2025 Oct 1, 2026
eb27559
fix(native-chat): the idle sweep's rest writes no Stop event; it evic…
brennanb2025 Oct 1, 2026
693583d
fix(native-chat): stopping a start that carries no send writes no Sto…
brennanb2025 Oct 1, 2026
3b8c6e7
test(native-chat): a Stop's pause across a restart is tested with a r…
brennanb2025 Oct 1, 2026
506c4fa
Merge remote-tracking branch 'origin/main' into brennanb2025/queue-st…
brennanb2025 Oct 1, 2026
37ed748
fix(native-chat): a host stop of a turn a person's Stop is still endi…
brennanb2025 Oct 1, 2026
69b4dec
fix(native-chat): an older Claude's error on a later turn keeps its e…
brennanb2025 Oct 1, 2026
ac4a987
Merge remote-tracking branch 'origin/brennanb2025/queue-stop-keeps-st…
brennanb2025 Oct 1, 2026
5ead1f6
fix(native-chat): a Stop of a start that never landed binds no later …
brennanb2025 Oct 1, 2026
aa7f3a7
test(native-chat): a rewind's restated turnless Stop binds no turn op…
brennanb2025 Oct 1, 2026
a5960f7
fix(native-chat): a relaunch settles a person's stopped turn with no …
brennanb2025 Oct 1, 2026
78369ee
test(native-chat): the unexpected-exit settle's journal fake answers …
brennanb2025 Oct 1, 2026
e9c8af8
fix(native-chat): a host stop whose sink drain fails reads the journa…
brennanb2025 Oct 1, 2026
8550aa1
fix(native-chat): a Stop that named no turn applies only to a turn a …
brennanb2025 Oct 1, 2026
ee54861
fix(native-chat): a host stop whose sink drain runs long reads the ag…
brennanb2025 Oct 1, 2026
bd16848
test(native-chat): a host stop with no turn running defers only while…
brennanb2025 Oct 1, 2026
ec0533b
fix(native-chat): a slow sink drain reads working only while an accep…
brennanb2025 Oct 1, 2026
3fba742
test(native-chat): the host-stop control keeps the stopped send unans…
brennanb2025 Oct 1, 2026
6a1f65b
fix(native-chat): a steer is no send owed a turn when a slow drain ju…
brennanb2025 Oct 1, 2026
e644e58
feat(native-chat): a chat reads Stopping from the person's Stop until…
brennanb2025 Oct 1, 2026
42964ad
test(native-chat): pin Stopping on the phone and across mixed versions
brennanb2025 Oct 1, 2026
79f661c
test: give touched fake journals and mocks their SAFETY notes
brennanb2025 Oct 1, 2026
c2bd622
test(native-chat): a turn waiting on the person reads attention, neve…
brennanb2025 Oct 1, 2026
fbca7ee
test(native-chat): the sidebar row follows Stopping when it is the on…
brennanb2025 Oct 1, 2026
f4b3942
test(mobile): the phone reads Stopping from its own Stop until the re…
brennanb2025 Oct 1, 2026
8f32fc2
test(mobile): type the held Stop request instead of casting it
brennanb2025 Oct 1, 2026
dd8836d
chore: keep the base lockfile (a local pnpm run rewrote it)
brennanb2025 Oct 1, 2026
fe5ed91
fix(native-chat): narrow the Stop note's optional failure; type the p…
brennanb2025 Oct 1, 2026
b10fb50
test(native-chat): type the Stop test envelope's fields narrowly
brennanb2025 Oct 1, 2026
3ca4853
Merge remote-tracking branch 'origin/brennanb2025/stop-event-b' into …
brennanb2025 Oct 1, 2026
3d10733
fix(native-chat): a Stop the agent declined, or whose child end faile…
brennanb2025 Oct 1, 2026
5042f69
fix(native-chat): Stopping holds while any press of the Stop took
brennanb2025 Oct 1, 2026
552a4ad
fix(native-chat): keep Stop enabled while the host says Stopping
brennanb2025 Oct 1, 2026
28a4de4
fix(sidebar): every agent row says Stopping in place of its tool line
brennanb2025 Oct 1, 2026
cd44de4
fix(mobile): the worktree list sees Stopping change on its own
brennanb2025 Oct 1, 2026
514a216
refactor(native-chat): fold the status feed in src/shared for both cl…
brennanb2025 Oct 1, 2026
6b65121
feat(mobile): let phones read the structured session status stream
brennanb2025 Oct 1, 2026
e6b8632
feat(mobile): the phone chat reads Stopping from the host, like the d…
brennanb2025 Oct 1, 2026
d59d573
test: give the new fakes checked types or a SAFETY reason
brennanb2025 Oct 1, 2026
bc5dcad
revert(native-chat): drop the refused-named-turn rewrite of a Stop's …
brennanb2025 Oct 1, 2026
287c86c
fix(mobile): release the status stream when the host ends it; refusal…
brennanb2025 Oct 1, 2026
feeb589
perf(native-chat): read the live turn's opener from its record when d…
brennanb2025 Oct 1, 2026
c9ba088
refactor(mobile): move the method-unavailable check into transport
brennanb2025 Oct 1, 2026
0c36f02
test(native-chat): a send after a Stop reads Working before its turn …
brennanb2025 Oct 1, 2026
6dc89f6
fix(sidebar): the compact row leads with Stopping so a narrow sidebar…
brennanb2025 Oct 1, 2026
3bf1013
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-eve…
brennanb2025 Oct 1, 2026
fc600d3
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-eve…
brennanb2025 Oct 1, 2026
32c945f
test(native-chat): the retry of a close whose exit was unproven write…
brennanb2025 Oct 1, 2026
c39f2ad
Merge remote-tracking branch 'origin/brennanb2025/stop-event-b' into …
brennanb2025 Oct 1, 2026
eee56e6
fix(native-chat): read and write a Stop's answer by the turn its even…
brennanb2025 Oct 1, 2026
528d56a
refactor(native-chat): read a Stop's target once for its event and it…
brennanb2025 Oct 1, 2026
3764929
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 1, 2026
03d1fcc
fix(native-chat): the host never steers a message into a turn a Stop …
brennanb2025 Oct 2, 2026
723fa84
feat(native-chat): while Stopping, the composer says a message runs a…
brennanb2025 Oct 2, 2026
b32f574
refactor(native-chat): the chat pane's Stop controls live in their ow…
brennanb2025 Oct 2, 2026
bc4f09c
fix(native-chat): hold a send at its handover, reading the feed's own…
brennanb2025 Oct 2, 2026
5f44ff7
fix(native-chat): drop the queue-paused header and Resume button
brennanb2025 Oct 2, 2026
dc181bc
test(native-chat): type the unknown hold reason a newer host may publish
brennanb2025 Oct 2, 2026
8d4f441
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 2, 2026
289a345
fix(native-chat): a held card offers Send, not Steer, when no turn runs
brennanb2025 Oct 2, 2026
faaefcc
fix(native-chat): the queue sends past held cards instead of stalling…
brennanb2025 Oct 2, 2026
1699657
refactor(native-chat): one display status decides Stopping on every s…
brennanb2025 Oct 2, 2026
aff5849
fix(native-chat): Stopping holds until the stopped turn ends, whateve…
brennanb2025 Oct 2, 2026
486a4aa
fix(native-chat): a Stop binds only the turn it actually stopped
brennanb2025 Oct 2, 2026
338180b
Merge #24864 (a Stop binds only the turn it stopped) into the Stoppin…
brennanb2025 Oct 2, 2026
4d5e13e
fix(native-chat): keep the person's queue pause and close binding aft…
brennanb2025 Oct 2, 2026
bfc51ce
Merge #24864's review fixes into the Stopping state
brennanb2025 Oct 2, 2026
4ed011b
fix(native-chat): keep a failed Stop's turn display-only, and settle …
brennanb2025 Oct 2, 2026
8447d44
Merge origin/main into stop-binds-at-settle
brennanb2025 Oct 2, 2026
a7a9551
Merge #24864 (with main) into the Stopping state
brennanb2025 Oct 2, 2026
f91c1ae
fix(native-chat): the queue's send of a card is the person's turn, so…
brennanb2025 Oct 2, 2026
9f61404
fix(native-chat): a Codex Stop agrees on both presses when a turn is …
brennanb2025 Oct 2, 2026
78eda4a
Merge #24864's final fixes into the Stopping state
brennanb2025 Oct 2, 2026
c2f54be
fix(native-chat): a Stop that failed before its turn showed still rea…
brennanb2025 Oct 2, 2026
34acafa
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-bin…
brennanb2025 Oct 3, 2026
67a06b8
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-bin…
brennanb2025 Oct 3, 2026
057e364
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-bin…
brennanb2025 Oct 3, 2026
06261d0
test(native-chat): a Stop whose event row failed binds no turn to an …
brennanb2025 Oct 3, 2026
60572cc
test(native-chat): name the settle, not a stream drain, in the Stop's…
brennanb2025 Oct 3, 2026
5fdc221
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-bin…
brennanb2025 Oct 3, 2026
3a3b7f6
Merge origin/brennanb2025/stop-binds-at-settle (#24864 with main's on…
brennanb2025 Oct 3, 2026
0855e21
test(native-chat): a Codex Stop answered before Codex ends the turn r…
brennanb2025 Oct 3, 2026
f7c08df
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 3, 2026
8b526b7
test(native-chat): Stopping ends with a Codex turn whose interrupt is…
brennanb2025 Oct 3, 2026
bd95932
fix(native-chat): a Codex Stop interrupts a turn Codex answered but h…
brennanb2025 Oct 3, 2026
ffd8d6a
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-bin…
brennanb2025 Oct 3, 2026
a7b2a5a
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 3, 2026
c120cb0
fix(mobile): name how the phone's status stream is released in the su…
brennanb2025 Oct 3, 2026
980f0e7
fix(native-chat): every Codex Stop waits for an answered turn to star…
brennanb2025 Oct 3, 2026
f7594b6
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 3, 2026
0138f0b
fix(codex): never steer a turn whose interrupt Codex answered
brennanb2025 Oct 3, 2026
8a46f7c
fix(native-chat): a message sent while Stopping is queued as a card, …
brennanb2025 Oct 3, 2026
3bdb4de
fix(native-chat): a message queued while Stopping is a card at once, …
brennanb2025 Oct 3, 2026
a2ba0c5
fix(native-chat): a Codex Stop that ends the child before any turn op…
brennanb2025 Oct 3, 2026
a6b8185
fix(native-chat): derive the withdrawal of a Codex send whose turn ne…
brennanb2025 Oct 3, 2026
6622a37
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 3, 2026
910989f
fix(native-chat): a card queued while Stopping runs past the cards th…
brennanb2025 Oct 3, 2026
78da557
fix(native-chat): a paused queue labels only the cards it holds
brennanb2025 Oct 3, 2026
497098d
revert(native-chat): defer the per-card queue pause label to the queu…
brennanb2025 Oct 3, 2026
84f7a5f
fix(native-chat): while Stopping, say and show what a send does where…
brennanb2025 Oct 3, 2026
70601f5
fix(native-chat): keep a send in doubt when a turn was open for it
brennanb2025 Oct 3, 2026
e1d45a1
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 3, 2026
980bf93
fix(native-chat): restore the per-card queue pause label
brennanb2025 Oct 3, 2026
6186504
fix(native-chat): draw only a send made while Stopping after the Stop…
brennanb2025 Oct 3, 2026
8e3240e
fix(native-chat): withdraw a Codex send by whether it started its own…
brennanb2025 Oct 3, 2026
3c7222a
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 3, 2026
a66d22b
refactor(native-chat): move queue-while-stopping to its own follow-up
brennanb2025 Oct 3, 2026
94e5509
fix(native-chat): queue a message sent while Stopping, where the host…
brennanb2025 Oct 3, 2026
5b60057
fix(native-chat): leave no Stop row when the Stop took back a send th…
brennanb2025 Oct 3, 2026
4888740
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 3, 2026
974cf8f
Merge remote-tracking branch 'origin/brennanb2025/stopping-state-on-b…
brennanb2025 Oct 3, 2026
7a28cd5
Merge remote-tracking branch 'origin/main' into brennanb2025/chat-que…
brennanb2025 Oct 4, 2026
4ef532e
fix(native-chat): a queued card carries its author, so the queue's se…
brennanb2025 Oct 4, 2026
0809787
docs(native-chat): state why an unrecorded card author reads as a per…
brennanb2025 Oct 4, 2026
ccbe202
fix(native-chat): a restart holds only cards written before it, and a…
brennanb2025 Oct 4, 2026
b47e696
fix(native-chat): count a send whose answer was lost when a Stop take…
brennanb2025 Oct 4, 2026
385dd20
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 4, 2026
b801c2d
Merge remote-tracking branch 'origin/brennanb2025/stopping-state-on-b…
brennanb2025 Oct 4, 2026
bf82077
fix(native-chat): the host publishes which pause holds each queued card
brennanb2025 Oct 4, 2026
71d7c62
test(native-chat): Resume needs the queue capability and is disabled …
brennanb2025 Oct 4, 2026
4c3a31d
docs(native-chat): describe per-card holds in the queue contract and …
brennanb2025 Oct 4, 2026
34d5ba9
fix(native-chat): the composer goes from Resume straight to Stop, and…
brennanb2025 Oct 4, 2026
22d2271
test(native-chat): pin which sends a Stop's child end can take back
brennanb2025 Oct 4, 2026
fdbc922
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 4, 2026
838456b
Merge remote-tracking branch 'origin/brennanb2025/stopping-state-on-b…
brennanb2025 Oct 4, 2026
d6b5c5e
fix(native-chat): the host names the card its queue sends next, so th…
brennanb2025 Oct 4, 2026
5cf6eba
test(native-chat): the queue's next card survives the coalescer, the …
brennanb2025 Oct 4, 2026
31995e4
test(native-chat): build the snapshot that names the next card throug…
brennanb2025 Oct 4, 2026
2daeeea
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-bin…
brennanb2025 Oct 4, 2026
5b4c595
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 4, 2026
ff02198
fix(native-chat): read the host's Stopping beside main's startup phase
brennanb2025 Oct 4, 2026
ae8944c
Merge remote-tracking branch 'origin/brennanb2025/stopping-state-on-b…
brennanb2025 Oct 4, 2026
a78ff91
feat(native-chat): a held queue keeps its header row, and a new messa…
brennanb2025 Oct 4, 2026
8ef6ea4
fix(native-chat): the paused row goes while your own message is on it…
brennanb2025 Oct 4, 2026
dfe1738
fix(native-chat): a "Send message?" choice is taken once, and a faile…
brennanb2025 Oct 4, 2026
9f8f45a
Merge remote-tracking branch 'origin/main' into brennanb2025/chat-que…
brennanb2025 Oct 4, 2026
818ec9a
fix(native-chat): Clear queue's message goes out once, and keeps text…
brennanb2025 Oct 4, 2026
f0c185e
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-bin…
brennanb2025 Oct 5, 2026
d8422dd
test(native-chat): read the outbox reconcile from where main moved it
brennanb2025 Oct 5, 2026
6b2f194
Merge remote-tracking branch 'origin/brennanb2025/stop-binds-at-settl…
brennanb2025 Oct 5, 2026
eb76da2
fix(native-chat): a retried message no longer waits behind a later Stop
brennanb2025 Oct 5, 2026
7d137d5
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 5, 2026
b36a22f
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 5, 2026
e278b7a
fix(native-chat): word a send after a Stop by whether this send will …
brennanb2025 Oct 5, 2026
c6f9699
test(native-chat): one test per case for the words of a send after a …
brennanb2025 Oct 5, 2026
14b3522
Merge remote-tracking branch 'origin/main' into brennanb2025/chat-que…
brennanb2025 Oct 5, 2026
a299ee4
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 5, 2026
7603054
refactor(native-chat): the dictation hook owns the composer's dictati…
brennanb2025 Oct 5, 2026
af021db
fix(native-chat): the queue carries on after any turn, in order, and …
brennanb2025 Oct 5, 2026
4acb3df
refactor(native-chat): name the dictation hook for what it owns now
brennanb2025 Oct 5, 2026
8252a23
fix(native-chat): after a restart no queue pause shows, and a card wr…
brennanb2025 Oct 5, 2026
8f5f49f
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 5, 2026
7a61051
fix(native-chat): a quit hands no queued card off, and the paused row…
brennanb2025 Oct 5, 2026
d1170f3
refactor(native-chat): the host's paused-row-while-a-turn-is-on-its-w…
brennanb2025 Oct 5, 2026
b0ea254
fix(native-chat): a Stop's note says it took once a joined close prov…
brennanb2025 Oct 5, 2026
a9191b0
Merge commit 'a3bd6a6a1e7209c8a870724df3557f0813a4573c' into brennanb…
brennanb2025 Oct 5, 2026
7c561ee
refactor(native-chat): the composer's queue Resume rides the structur…
brennanb2025 Oct 5, 2026
9224f99
fix(native-chat): a proven turn end says a Stop's unconfirmed note took
brennanb2025 Oct 5, 2026
a5429e8
test(native-chat): a Stop's unconfirmed note says it took when the ag…
brennanb2025 Oct 5, 2026
bbee774
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 5, 2026
6503268
test(native-chat): name the Codex handle as main's opaque handle does
brennanb2025 Oct 5, 2026
b740069
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 5, 2026
a353cc6
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 6, 2026
c8a5ac8
test: restore the provider handle import the main merge dropped
brennanb2025 Oct 6, 2026
4b50771
Merge remote-tracking branch 'origin/main' into brennanb2025/chat-que…
brennanb2025 Oct 6, 2026
439545e
fix(native-chat): the "Send message?" choice ends with the pause it a…
brennanb2025 Oct 6, 2026
f803bb0
fix: derive Stop note wording from interrupted turns
brennanb2025 Oct 6, 2026
ac624ba
Merge commit 'bfd1e9c579e4f442059bf99951af22b28292787a' into brennanb…
brennanb2025 Oct 6, 2026
3700e2d
test: name the raw replay case for what it covers
brennanb2025 Oct 6, 2026
35b6b72
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 6, 2026
53ae708
refactor(native-chat): move the waiting-slot split into its own hook
brennanb2025 Oct 6, 2026
533c535
Merge origin/main 670c59d23a1 into brennanb2025/chat-queue-continues-…
brennanb2025 Oct 6, 2026
738270b
Merge origin/main 4de9f9f85a8 into brennanb2025/chat-queue-continues-…
brennanb2025 Oct 6, 2026
e58e9f8
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 6, 2026
a7a5492
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 6, 2026
970c6a1
test: follow main's chat font-size rename in the stopping tests
brennanb2025 Oct 6, 2026
7cc68c2
Merge origin/main 5b8a982f8f7 into brennanb2025/chat-queue-continues-…
brennanb2025 Oct 6, 2026
2fd4ad3
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 6, 2026
082ffca
test: follow main's single live-line value in the Stopping tests
brennanb2025 Oct 6, 2026
0291a43
test: give the android live-line fixtures the stopping field
brennanb2025 Oct 6, 2026
0516948
chore: keep the session host under its line limit after the main merge
brennanb2025 Oct 6, 2026
7c4be11
Merge remote-tracking branch 'origin/main' into brennanb2025/stopping…
brennanb2025 Oct 6, 2026
5dce67a
chore: keep the composer test and the phone chat view under their lin…
brennanb2025 Oct 6, 2026
64961aa
Merge origin/main 468e4e1167b into brennanb2025/chat-queue-continues-…
brennanb2025 Oct 6, 2026
6393661
Merge remote-tracking branch 'origin/brennanb2025/stopping-state-on-b…
brennanb2025 Oct 6, 2026
ada3419
Merge remote-tracking branch 'origin/main' into brennanb2025/stop-que…
brennanb2025 Oct 6, 2026
c253154
Merge remote-tracking branch 'origin/brennanb2025/chat-queue-continue…
brennanb2025 Oct 6, 2026
ed5a16a
test(native-chat): give the composer's Stopping test the primary acti…
brennanb2025 Oct 6, 2026
1a04c3d
revert(native-chat): drop heldByPause, a card field the Stop's pause …
brennanb2025 Oct 6, 2026
fa7e030
fix(native-chat): a person's Stop holds every card while in force; or…
brennanb2025 Oct 6, 2026
9facff6
fix(native-chat): a message sent while Stopping is a card at the end …
brennanb2025 Oct 6, 2026
65018ff
fix(native-chat): drop the Stopping placeholder that promised a queue…
brennanb2025 Oct 6, 2026
b01d6bb
test(native-chat): a desktop send while Stopping follows the queue se…
brennanb2025 Oct 6, 2026
d1d0bb1
fix(native-chat): only mail passes the cards a person's Stop holds, w…
brennanb2025 Oct 6, 2026
954187a
Merge origin/main 83cf7cf5e28 into brennanb2025/chat-queue-continues-…
brennanb2025 Oct 6, 2026
70a37e3
test(mobile): a host-kept card's test stands in a Stop's pause, as th…
brennanb2025 Oct 6, 2026
2ea5456
Merge #24586 (70a37e35820) into brennanb2025/stop-queue-after-stop
brennanb2025 Oct 6, 2026
d7768c3
test(native-chat): the restart-hold test queues mail, which a person'…
brennanb2025 Oct 6, 2026
173e953
feat(native-chat): each queued card names its sender's kind, so a per…
brennanb2025 Oct 6, 2026
2d950ca
Merge origin/main (0c96550ee9a, #24586 squashed) into brennanb2025/st…
brennanb2025 Oct 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mobile/src/session/MobileNativeChatView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ describe('MobileNativeChatView', () => {
})

it.each([
['queue', 'Queue a message to run after the stop'],
['queue', 'Message, @files, /commands'],
['send', 'Send a message to run after the stop']
] as const)(
'tells the composer a message sent now runs after the stop (%s)',
'tells the composer whether a message sent now runs after the stop (%s)',
async (afterStop, placeholder) => {
await render({
structuredActivityUi: true,
Expand Down
31 changes: 28 additions & 3 deletions mobile/src/session/mobile-structured-queued-message-cards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
QUEUED_MESSAGE_PAUSED_SEND_FAILED
} from '../../../src/shared/agent-session-wire'
import type { AgentSessionQueuedMessage } from '../../../src/shared/agent-session-wire'
import type { AgentMessageSource } from '../../../src/shared/agent-session-message-source'
import {
mobileQueueHasResumableCard,
mobileQueuePauseLabel,
Expand All @@ -19,6 +20,15 @@ function returnedAs(fact: Parameters<typeof agentSessionFailureWords>[0]) {
return { state: 'returned' as const, returnedReason: reason, returnedRejection: rejection }
}

/** Another agent's message, which names its sender on its body. */
const AGENT_FROM: AgentMessageSource = {
kind: 'agent',
senders: [],
orchestration: { message: 'mail-notice', mailbox: 'run:r1', dispatchId: null, messages: [] }
}

const STOPPED = { reason: 'stopped' } as const

function draft(overrides: Partial<AgentSessionQueuedMessage> & { messageId: string }) {
return {
position: 1,
Expand All @@ -32,6 +42,11 @@ function draft(overrides: Partial<AgentSessionQueuedMessage> & { messageId: stri
}
}

function mailDraft(messageId: string, position: number) {
const base = draft({ messageId, position })
return { ...base, body: { ...base.body, from: AGENT_FROM } }
}

describe('mobileQueuedMessageCards', () => {
it('renders nothing without a published list', () => {
expect(mobileQueuedMessageCards(null, [], { pendingPrompt: false })).toEqual([])
Expand Down Expand Up @@ -63,21 +78,31 @@ describe('mobileQueuedMessageCards', () => {
it('captions nothing on a waiting card of a paused queue; its pause row explains', () => {
const [card] = mobileQueuedMessageCards([draft({ messageId: 'a' })], [], {
pendingPrompt: false,
queuePaused: true
queuePause: STOPPED
})
expect(card?.caption).toBeNull()
expect(card?.paused).toBe(false)
expect(card?.needsAttention).toBe(false)
})

// Another agent's mail runs when the stop lands: only a person's card waits on the Stop's pause.
it("captions mail as an ordinary waiting card under a person's Stop", () => {
const cards = mobileQueuedMessageCards(
[draft({ messageId: 'typed' }), mailDraft('mail', 2)],
[],
{ pendingPrompt: true, queuePause: STOPPED }
)
expect(cards.map((card) => card.caption)).toEqual([null, 'Waiting for your answer'])
})

it("keeps a card's own failed send and reads a prompt's wait as queued under a paused queue", () => {
const cards = mobileQueuedMessageCards(
[
draft({ messageId: 'a', paused: true, pausedReason: QUEUED_MESSAGE_PAUSED_SEND_FAILED }),
draft({ messageId: 'b', position: 2 })
],
[],
{ pendingPrompt: true, queuePaused: true }
{ pendingPrompt: true, queuePause: STOPPED }
)
expect(cards.map((card) => card.caption)).toEqual(["Couldn't send — tap Send to retry", null])
expect(cards[0]?.paused).toBe(true)
Expand All @@ -86,7 +111,7 @@ describe('mobileQueuedMessageCards', () => {
it('finds something for Resume to send only in a waiting card with no hold, ahead of a returned one', () => {
const resumable = (drafts: AgentSessionQueuedMessage[]) =>
mobileQueueHasResumableCard(
mobileQueuedMessageCards(drafts, [], { pendingPrompt: false, queuePaused: true })
mobileQueuedMessageCards(drafts, [], { pendingPrompt: false, queuePause: STOPPED })
)
const returned = draft({
messageId: 'r',
Expand Down
5 changes: 3 additions & 2 deletions mobile/src/session/mobile-structured-queued-message-cards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { structuredAgentSessionAttemptFailureParts } from '../../../src/shared/s
import {
QUEUED_MESSAGE_PAUSED_KEPT,
QUEUED_MESSAGE_PAUSED_SEND_FAILED,
queuePauseHoldsCard,
type AgentSessionQueuedMessage,
type AgentSessionQueuePause
} from '../../../src/shared/agent-session-wire'
Expand Down Expand Up @@ -99,7 +100,7 @@ export function mobileQueuePauseLabel(pause: Pick<AgentSessionQueuePause, 'reaso
export function mobileQueuedMessageCards(
queuedMessages: readonly AgentSessionQueuedMessage[] | null,
submissions: readonly Pick<AgentJournalSubmission, 'queuedMessageId' | 'dispatchState'>[],
facts: { pendingPrompt: boolean; queuePaused?: boolean }
facts: { pendingPrompt: boolean; queuePause?: AgentSessionQueuePause | null }
): MobileQueuedMessageCard[] {
if (!queuedMessages || queuedMessages.length === 0) {
return []
Expand All @@ -125,7 +126,7 @@ export function mobileQueuedMessageCards(
? pausedCaption(draft.pausedReason)
: behindReturned
? 'Waiting — a message ahead needs attention'
: facts.queuePaused
: queuePauseHoldsCard(facts.queuePause, draft)
? // The pause row says why and offers Resume; the card promises no send time.
null
: facts.pendingPrompt
Expand Down
12 changes: 7 additions & 5 deletions mobile/src/session/use-mobile-native-chat-input-lease.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,18 @@ describe('useSettledMobileNativeChatInputLock', () => {
})

describe("the phone chat composer's placeholder", () => {
it('says a message runs after the stop while the chat reads Stopping', () => {
expect(mobileNativeChatComposerPlaceholder(null, 'queue')).toBe(
'Queue a message to run after the stop'
)
// Where the host does not queue sends, it holds the message until the stop lands.
// Where the host does not queue sends, it holds the message until the stop lands.
it('says a message runs after the stop while the chat reads Stopping and sends are not queued', () => {
expect(mobileNativeChatComposerPlaceholder(null, 'send')).toBe(
'Send a message to run after the stop'
)
})

// A queued one is a card the Stop holds until Resume: nothing promises it runs after the stop.
it('reads as usual while Stopping where a send is queued', () => {
expect(mobileNativeChatComposerPlaceholder(null, 'queue')).toBe('Message, @files, /commands')
})

it('reads as usual otherwise', () => {
expect(mobileNativeChatComposerPlaceholder(null, undefined)).toBe('Message, @files, /commands')
})
Expand Down
9 changes: 4 additions & 5 deletions mobile/src/session/use-mobile-native-chat-input-lease.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export function useSettledMobileNativeChatInputLock(
}

/** What the composer says while the input lease blocks it, else that a message sent now runs
* after a Stop the chat reads as stopping, else its normal prompt. */
* after a Stop the chat reads as stopping, else its normal prompt. A queued one is a card the
* Stop holds until Resume, so it gets the normal prompt. */
export function mobileNativeChatComposerPlaceholder(
lockReason: MobileNativeChatInputLockReason | null,
/** While stopping: whether a message sent now is queued, or sent for the host to hold. */
Expand All @@ -107,10 +108,8 @@ export function mobileNativeChatComposerPlaceholder(
if (lockReason === 'waiting') {
return 'Waiting for terminal…'
}
if (afterStop) {
return afterStop === 'queue'
? NATIVE_CHAT_TURN_STATUS_COPY.queueAfterStop
: NATIVE_CHAT_TURN_STATUS_COPY.sendAfterStop
if (afterStop === 'send') {
return NATIVE_CHAT_TURN_STATUS_COPY.sendAfterStop
}
return 'Message, @files, /commands'
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,32 @@ describe('mobile structured queued messages', () => {
)
})

// Nothing is left to steer into while a Stop ends the turn: the send runs after it, as a card.
it('queues a send made while this phone reads Stopping', async () => {
sendRequest.mockImplementation(async (method) => {
if (method === 'agentSession.cancel') {
return new Promise<RpcResponse>(() => {})
}
if (method === 'agentSession.send') {
return mutationOk({
clientMessageId: 'client-1',
queued: { messageId: 'client-1', position: 1, state: 'waiting' }
})
}
return method === 'agentSession.options' ? ok({ models: [], current: {} }) : ok({})
})
await mountSession(CAPABLE, snapshotEvent({ runningTurn: true }))
act(() => hook!.cancel())
await vi.waitFor(() => expect(hook!.turnIndicator.stopping).toBe(true))

await act(async () => {
expect(await hook!.sendWithOutcome('run this after the stop')).toBe('queued')
})

expect(calls('agentSession.send')).toHaveLength(1)
expect(requestOf('agentSession.send').params.delivery).toBe('queue-if-active')
})

it('keeps today’s request exactly against an incapable host', async () => {
sendRequest.mockImplementation(async (method) => {
if (method === 'agentSession.send') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function useMobileStructuredQueuedMessageControls(args: {
() =>
mobileQueuedMessageCards(queuedMessages, submissions, {
pendingPrompt,
queuePaused: queuePause !== null
queuePause
}),
[pendingPrompt, queuePause, queuedMessages, submissions]
)
Expand Down
Loading
Loading