Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
225 commits
Select commit Hold shift + click to select a range
c867bd2
refactor(native-chat): remove the unused terminal handoff
brennanb2025 Sep 25, 2026
eab4ef1
fix(native-chat): never let the pre-stop snapshot hold a chat's stop
brennanb2025 Sep 25, 2026
abafbbc
refactor(native-chat): drop helpers only the terminal handoff called
brennanb2025 Sep 25, 2026
3cbf6b5
docs(native-chat): stop citing the removed handoff in lifecycle comments
brennanb2025 Sep 25, 2026
e048579
test(native-chat): type the stalled snapshot drain without a cast
brennanb2025 Sep 25, 2026
b50c574
test(native-chat): pin that a start dead before proving owes no settl…
brennanb2025 Sep 25, 2026
12efdef
fix(native-chat): keep the owner-status read behind an in-flight attach
brennanb2025 Sep 25, 2026
42d10ee
refactor(terminal): remove the agent-session PTY write gate
brennanb2025 Sep 25, 2026
0483915
refactor(native-chat): drop the transcript helpers only the handoff c…
brennanb2025 Sep 25, 2026
d0f4dae
fix(native-chat): stop calling a starting chat "mid-handoff"
brennanb2025 Sep 25, 2026
faecece
test(native-chat): type the stand-in roster decoder without a cast
brennanb2025 Sep 25, 2026
250250e
refactor(codex): name the pinned rollout lookup for what it does
brennanb2025 Sep 25, 2026
b588185
refactor(native-chat): type the owner-status reply as the host sends it
brennanb2025 Sep 25, 2026
35742fd
refactor(native-chat): normalize terminal-handoff lease values once a…
brennanb2025 Sep 25, 2026
54ce5fc
refactor(native-chat): stop threading the owner kind through a reserv…
brennanb2025 Sep 25, 2026
713b126
test(native-chat): pin the legacy-lease rewrite with a transaction th…
brennanb2025 Sep 25, 2026
44d7977
fix(native-chat): name a chat write by its target, not the owner gene…
brennanb2025 Sep 25, 2026
6dad39a
fix(native-chat): every journal append reaches the chats that are open
brennanb2025 Sep 25, 2026
97bf3bb
test(native-chat): an epoch replacement reaches the open chat
brennanb2025 Sep 25, 2026
427dc8d
test(native-chat): each row reaches an open chat once, and a live han…
brennanb2025 Sep 25, 2026
2bd44f5
test(native-chat): give the legacy-lease store test a tab id so the b…
brennanb2025 Sep 25, 2026
f79eb9b
test(worktree-activation): restore the OMP surfaced-agent resume test
brennanb2025 Sep 25, 2026
50d2e33
perf(native-chat): a publish behind a delivered commit reads nothing
brennanb2025 Sep 25, 2026
bd72b13
test(native-chat): state why the teardown test's fake journal is safe…
brennanb2025 Sep 25, 2026
fa9b76a
docs(native-chat): say mutation admission checks only the writer lease
brennanb2025 Sep 25, 2026
5435973
docs(native-chat): drop the send rebase from comments that still desc…
brennanb2025 Sep 25, 2026
8fd4558
Merge #22811 into the PR 1 base
brennanb2025 Sep 25, 2026
12dde37
Merge #22812 into the PR 1 base
brennanb2025 Sep 25, 2026
c753e8a
fix(native-chat): a message is accepted, then delivered
brennanb2025 Sep 25, 2026
82f9bfd
fix(native-chat): settle queued messages only for the child that ended
brennanb2025 Sep 25, 2026
f3e52d2
fix(native-chat): an adoption that fails to import keeps the conversa…
brennanb2025 Sep 25, 2026
29a340b
perf(native-chat): the recovering open reads the journal once
brennanb2025 Sep 25, 2026
c7a652f
fix(native-chat): an attach that fails after indexing its child leave…
brennanb2025 Sep 25, 2026
34d0bb0
fix(native-chat): a withdrawn message shows no error, and a rejection…
brennanb2025 Sep 25, 2026
46b6472
fix(orchestration): a structured worker whose agent outlasts the prea…
brennanb2025 Sep 25, 2026
283819d
fix(native-chat): a message rejected while its chat was closed reads …
brennanb2025 Sep 25, 2026
40dabe8
test(orchestration): name why the readiness settlement fakes are cast
brennanb2025 Sep 25, 2026
31444bf
fix(native-chat): keep each pane's own fence on frames so a failed re…
brennanb2025 Sep 25, 2026
494d8c7
docs(native-chat): drop the fence from the admission the send effects…
brennanb2025 Sep 25, 2026
0e74529
docs(native-chat): give the fence move on release the reason that sti…
brennanb2025 Sep 25, 2026
6c16f35
docs(native-chat): stop citing a write fence check in launch and mail…
brennanb2025 Sep 25, 2026
d2f646b
refactor(native-chat): the provider child is its own record
brennanb2025 Sep 25, 2026
25fa38a
Merge remote-tracking branch 'origin/main' into brennanb2025/chat-wri…
brennanb2025 Sep 25, 2026
aa56b50
fix(native-chat): the delivery loop alone settles a message its start…
brennanb2025 Sep 25, 2026
d23cca4
Merge #22812 and main into PR 1
brennanb2025 Sep 25, 2026
4993696
refactor(native-chat): a stopped child ends on the one reading of its…
brennanb2025 Sep 25, 2026
a2ad8f2
feat(native-chat): the host says it accepts a send before any agent h…
brennanb2025 Sep 25, 2026
48def96
refactor(native-chat): an attach never opens a journal of its own
brennanb2025 Sep 25, 2026
da65d57
fix(native-chat): a moved fence resends nothing on a host that accept…
brennanb2025 Sep 25, 2026
0184a3d
refactor(native-chat): a child's end says whether the user or the hos…
brennanb2025 Sep 25, 2026
12577d8
fix(native-chat): a chat whose only work is a queued message is not o…
brennanb2025 Sep 25, 2026
a59eed9
test(native-chat): type the queued-message fixtures in the resume-off…
brennanb2025 Sep 25, 2026
ccaf412
fix(native-chat): a start that dies while a message waits on it is th…
brennanb2025 Sep 25, 2026
0efca93
docs(native-chat): say what an attach's open conversation and unconfi…
brennanb2025 Sep 25, 2026
74d6506
test(native-chat): pin what a failed start settles, and what a resume…
brennanb2025 Sep 25, 2026
9c671f1
test(native-chat): the failed-start pins fail on what the message bec…
brennanb2025 Sep 25, 2026
80ccb33
test(orchestration): the preamble's host stub is typed, not cast
brennanb2025 Sep 25, 2026
227e135
fix(native-chat): a Stop that names no turn stops what the conversati…
brennanb2025 Sep 26, 2026
6fdeb89
fix(native-chat): Stop is there from the moment a message is sent
brennanb2025 Sep 26, 2026
6ceaa52
fix(native-chat): Stop before a turn is gated on its own host capability
brennanb2025 Sep 26, 2026
9de2655
test(native-chat): a build advertises conversation stop exactly where…
brennanb2025 Sep 26, 2026
e6dadd1
Merge main into PR 1
brennanb2025 Sep 26, 2026
6374f35
Merge main into PR 1
brennanb2025 Sep 27, 2026
724b961
Merge main into PR 1
brennanb2025 Sep 27, 2026
c39151d
fix(native-chat): a view never restarts a chat whose last start failed
brennanb2025 Sep 27, 2026
9613178
test(native-chat): start the child the loop waits on with an attach, …
brennanb2025 Sep 27, 2026
0224459
fix(native-chat): settle a gone generation's turn wherever a conversa…
brennanb2025 Sep 27, 2026
2276cef
test(native-chat): prove the next child's start settles the turn an e…
brennanb2025 Sep 27, 2026
9275869
test(native-chat): count a failed start's rows by row, not by text
brennanb2025 Sep 27, 2026
158ca0a
test(native-chat): give the failed-start and stale-turn waits a loade…
brennanb2025 Sep 27, 2026
8f66a25
test(native-chat): pin the open's and the send's start and row counts…
brennanb2025 Sep 27, 2026
ad04c3b
fix(native-chat): settle a gone generation's turn at every open but a…
brennanb2025 Sep 27, 2026
05b8b93
test(native-chat): hold the create's start open until the views bind
brennanb2025 Sep 27, 2026
0477775
Merge PR 1 into S
brennanb2025 Sep 27, 2026
d5716f3
Merge main into PR 1
brennanb2025 Sep 27, 2026
c263d83
fix(native-chat): Stop reads the one working rule every session list …
brennanb2025 Sep 27, 2026
ad5bfa3
test(native-chat): a rate-limit retry pins only that no turn opens, n…
brennanb2025 Sep 27, 2026
f13f6cc
Merge PR 1 into S
brennanb2025 Sep 27, 2026
d5b3a4f
fix(native-chat): Stop leaves a message waiting on its Retry, and doe…
brennanb2025 Sep 27, 2026
5f1f71f
test(native-chat): the chat's Stop and a session list read the main a…
brennanb2025 Sep 27, 2026
ccde2c9
refactor(mobile): the chat reads the main agent's working state throu…
brennanb2025 Sep 27, 2026
f75fe04
fix(codex): a Stop naming no turn never interrupts an earlier turn
brennanb2025 Sep 27, 2026
db36d0a
fix(native-chat): a Stop naming no turn never says a turn had already…
brennanb2025 Sep 27, 2026
740ed1f
Merge main into PR 1
brennanb2025 Sep 28, 2026
8276562
Merge PR 1 into S
brennanb2025 Sep 28, 2026
27a3398
fix(native-chat): one Stop the host could not settle no longer refuse…
brennanb2025 Sep 28, 2026
7002b1b
refactor(native-chat): drop the composer's second error formatter
brennanb2025 Sep 28, 2026
cb5ce82
test(native-chat): pin the reason on a message rejected while its cha…
brennanb2025 Sep 28, 2026
ed6ab4b
Merge PR 1 into S
brennanb2025 Sep 28, 2026
a322c8a
test(native-chat): read Stop operation ids without a cast
brennanb2025 Sep 28, 2026
20402c8
fix(native-chat): a Stop whose answer was lost no longer swallows the…
brennanb2025 Sep 28, 2026
c6e5e65
refactor(native-chat): a Stop naming no target keeps its operation id…
brennanb2025 Sep 28, 2026
cc20a86
test(native-chat): read the Stop fences without a cast
brennanb2025 Sep 28, 2026
61f99b8
test(native-chat): pin the new id for a named cancel the host could n…
brennanb2025 Sep 28, 2026
cf106f1
fix(native-chat): a Stop pressed after a new message stops it, even w…
brennanb2025 Sep 28, 2026
f2e5b04
fix(native-chat): Stop no longer blinks off as Claude opens the turn …
brennanb2025 Sep 28, 2026
04c0885
Merge main into S
brennanb2025 Sep 28, 2026
e207887
fix(native-chat): a message a Stop withdrew comes back to its sender'…
brennanb2025 Sep 28, 2026
1431167
fix(native-chat): withdrawn text put back during an IME composition i…
brennanb2025 Sep 28, 2026
2b49021
test(native-chat): pin that only a withdrawn message comes back to th…
brennanb2025 Sep 28, 2026
c4ddc1f
test(native-chat): set up the composer's window API for every describ…
brennanb2025 Sep 28, 2026
badb424
docs(native-chat): note that the withdrawn check reads the legacy rea…
brennanb2025 Sep 28, 2026
2489cdd
test(native-chat): pin that text put back mid-composition shows once,…
brennanb2025 Sep 28, 2026
1f89467
Merge main into S
brennanb2025 Sep 28, 2026
ba56ccd
feat(native-chat): host-owned queued-message draft store in the sessi…
brennanb2025 Sep 28, 2026
7f7290a
feat(native-chat): queued-messages wire contract, dark capability, an…
brennanb2025 Sep 28, 2026
76f9037
feat(native-chat): queue a capable mid-turn send as a draft, drain it…
brennanb2025 Sep 28, 2026
77aea97
test(native-chat): pin mid-turn queueing against the real host
brennanb2025 Sep 28, 2026
fdc3a48
test(native-chat): read the queued receipt ids before the wait closures
brennanb2025 Sep 28, 2026
6932694
chore(native-chat): SAFETY rationales on the sqlite row casts and a c…
brennanb2025 Sep 28, 2026
0c8c7c8
fix(native-chat): queued-draft bookkeeping never costs a publish, an …
brennanb2025 Sep 28, 2026
45f091d
fix(native-chat): a Stop that withdraws a consumed draft's send gives…
brennanb2025 Sep 28, 2026
3bb4a69
perf(native-chat): the queued-draft drain takes no serialized step wh…
brennanb2025 Sep 28, 2026
f916070
fix(native-chat): a clear withdraws queued text only for a caller tha…
brennanb2025 Sep 28, 2026
3eb7abb
fix(native-chat): a draft pause that commits no journal row still rea…
brennanb2025 Sep 28, 2026
fbbaec3
fix(native-chat): a failed clear wakes the queued drain, a failed Sto…
brennanb2025 Sep 28, 2026
c33375c
refactor(native-chat): the draft store notifies through the journal's…
brennanb2025 Sep 28, 2026
cedee2c
fix(native-chat): a Stop with no drafts writes nothing, and a failed …
brennanb2025 Sep 28, 2026
ddeb509
fix(native-chat): a capable Stop with no drafts writes nothing
brennanb2025 Sep 28, 2026
6e8023f
refactor(native-chat): Stop and /clear never withdraw queued drafts; …
brennanb2025 Sep 28, 2026
3a58616
feat(native-chat): a restart hold lifts like a Stop's, and paused car…
brennanb2025 Sep 28, 2026
6414f7d
fix(native-chat): only a client's own send lifts a Stop's queue pause
brennanb2025 Sep 28, 2026
b8c3d64
fix(native-chat): a Stop's queue pause lifts when the user's send sta…
brennanb2025 Sep 28, 2026
5d2a3c5
fix(native-chat): a consumed draft's turn starting lifts a Stop's que…
brennanb2025 Sep 28, 2026
f740887
fix(native-chat): queue a capable send behind a /compact and re-scope…
brennanb2025 Sep 28, 2026
3c5c205
feat(mobile): render host-queued drafts as cards with Send-now/Edit/D…
brennanb2025 Sep 28, 2026
ea9ffef
feat(mobile): /clear withdraws queued drafts on capable hosts, and re…
brennanb2025 Sep 28, 2026
f951077
fix(mobile): an empty queued-draft publication never churns the held …
brennanb2025 Sep 28, 2026
c85083a
fix(mobile): relaunch recovery replays results only — a persisted Sto…
brennanb2025 Sep 28, 2026
fc3256f
fix(mobile): a relaunch never reissues a Stop or /clear, a lost withd…
brennanb2025 Sep 28, 2026
6344f73
fix(mobile): a lost-answer queued send never reads as unconfirmed, th…
brennanb2025 Sep 28, 2026
16f4462
fix(mobile): withdrawn queued text reaches its pane even after the sc…
brennanb2025 Sep 28, 2026
1b70cb4
refactor(mobile): queued drafts stay host-owned — Stop and /clear nev…
brennanb2025 Sep 28, 2026
9ee1641
fix(mobile): only a 'stopped' hold promises "sends after your next me…
brennanb2025 Sep 28, 2026
8d0b27d
fix(mobile): a paused queued card's action reads Send, not Send now
brennanb2025 Sep 28, 2026
76401ca
test(mobile): find the queued card's Text nodes by name so the test t…
brennanb2025 Sep 28, 2026
892c9f2
fix(mobile): retire a replayed send the host refuses by shape; 44pt q…
brennanb2025 Sep 28, 2026
ac0ef0f
fix(mobile): a waiting queued card's action reads Steer, as on desktop
brennanb2025 Sep 28, 2026
38b2285
fix(mobile): focus the composer after Edit moves a queued message int…
brennanb2025 Sep 28, 2026
097425a
fix(mobile): only a schema rejection retires an in-doubt send; an aut…
brennanb2025 Sep 28, 2026
8a6f0d7
Merge origin/main (with #23026 squash-merged) into mid-turn-queue-host
brennanb2025 Sep 29, 2026
0d61b63
Merge the rebuilt mid-turn-queue-host (main with #23026) into mid-tur…
brennanb2025 Sep 29, 2026
a7d6903
fix(native-chat): a returned queued card carries the typed rejection …
brennanb2025 Sep 29, 2026
de12b3d
Merge commit 'a7d690335cf' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
0598a54
fix(native-chat): fit the queue to main's typed rejections and compac…
brennanb2025 Sep 29, 2026
961bc8c
fix(mobile): a returned queued card reads its typed rejection like a …
brennanb2025 Sep 29, 2026
f371548
Merge commit '0598a54620d' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
5ea2737
fix(mobile): a returned queued card is worded as the desktop card wor…
brennanb2025 Sep 29, 2026
977da8f
fix(mobile): a returned card with a fact this build cannot place show…
brennanb2025 Sep 29, 2026
5527f12
fix(native-chat): draft bookkeeping can never roll back the journal r…
brennanb2025 Sep 29, 2026
0f34ce8
fix(mobile): a returned card's reason reads whole, and Edit never del…
brennanb2025 Sep 29, 2026
1298f51
fix(mobile): a queued send's replay never vanishes or paints an unret…
brennanb2025 Sep 29, 2026
9f3fc17
fix(mobile): a queued card hides once its message arrives, and a fail…
brennanb2025 Sep 29, 2026
5b234d4
fix(native-chat): a draft a Stop or restart took back waits again ins…
brennanb2025 Sep 29, 2026
e2b11bd
fix(native-chat): Delete and Send on a queued card answer at once dur…
brennanb2025 Sep 29, 2026
fd8ad79
fix(native-chat): a re-sent returned card drops the refusal it came b…
brennanb2025 Sep 29, 2026
5d077cb
perf(native-chat): the queue gate reads pending prompts without rende…
brennanb2025 Sep 29, 2026
5868371
fix(native-chat): a Stop that fails leaves the queued cards as it fou…
brennanb2025 Sep 29, 2026
348a8c9
docs(native-chat): confirmed cancellation is no longer a queue rollou…
brennanb2025 Sep 29, 2026
9ee2441
docs(native-chat): the Claude fold receipt and turn-owner bars have l…
brennanb2025 Sep 29, 2026
4a1d16d
Merge commit '9ee2441655a' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
6734983
test(mobile): compare the queued card's Text nodes by name so the tes…
brennanb2025 Sep 29, 2026
fa3befa
fix(mobile): a draft a Stop requeued stays visible beside its rejecte…
brennanb2025 Sep 29, 2026
6f9f220
fix(mobile): a send record storage will not clear never blocks sendin…
brennanb2025 Sep 29, 2026
2f191d1
fix(mobile): a send record whose draft went out under another id is s…
brennanb2025 Sep 29, 2026
3a92694
fix(native-chat): Send on a queued card during a /compact is refused …
brennanb2025 Sep 29, 2026
4f8deb3
fix(native-chat): a Stop that fails after reaching the agent keeps th…
brennanb2025 Sep 29, 2026
0b1fa80
fix(native-chat): a skipped draft settlement heals on the next drain …
brennanb2025 Sep 29, 2026
b9229ac
fix(native-chat): one id is never recorded as a submission twice
brennanb2025 Sep 29, 2026
a9b2d39
fix(native-chat): a waiting draft whose first send the agent echoed i…
brennanb2025 Sep 29, 2026
3316172
feat(native-chat): a submission names the queued draft it hands off
brennanb2025 Sep 29, 2026
f2efb10
refactor(native-chat): every queued draft goes out under a fresh subm…
brennanb2025 Sep 29, 2026
00fa3a9
Merge commit 'f2efb102bd3' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
8140ba2
fix(mobile): relate a queued draft to its hand-off only through queue…
brennanb2025 Sep 29, 2026
88e4398
fix(native-chat): an echo withdraws a draft only if its rejected hand…
brennanb2025 Sep 29, 2026
5863757
fix(mobile): a replay the host answers with its draft's hand-off spen…
brennanb2025 Sep 29, 2026
108edd0
fix(mobile): a resend past an uncleared send record replays its own i…
brennanb2025 Sep 29, 2026
8441381
fix(native-chat): a skipped echo withdrawal is re-derived before the …
brennanb2025 Sep 29, 2026
b05dcaf
fix(native-chat): a rolled-back journal append leaves no draft state …
brennanb2025 Sep 29, 2026
0aa2b6d
fix(native-chat): a replay of a deleted queued card answers withdrawn…
brennanb2025 Sep 29, 2026
3141184
Merge commit '0aa2b6dcca7' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
2737b2b
Merge remote-tracking branch 'origin/main' into mid-turn-queue-host
brennanb2025 Sep 29, 2026
09513df
test(mobile): a withdrawn replay of a pruned deleted card, position 0…
brennanb2025 Sep 29, 2026
9a85e1b
Merge commit '2737b2bd25b' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
1111b0d
fix(mobile): a bypassed resend's id survives storage recovering, and …
brennanb2025 Sep 29, 2026
63456cf
refactor(native-chat): name the queue's pause-lift for what it releases
brennanb2025 Sep 29, 2026
8295255
refactor(mobile): name a schema-refused replay for what the host decided
brennanb2025 Sep 29, 2026
0b2a926
chore(native-chat): one import of the mutation helpers
brennanb2025 Sep 29, 2026
7a1bc5a
Merge commit '0b2a926205e' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
7e6b5dd
refactor(mobile): build the queued-card slot outside the chat view
brennanb2025 Sep 29, 2026
15727bd
test(mobile): say why the overlay test's partial controller is safe
brennanb2025 Sep 29, 2026
aca86ec
feat(native-chat): a Stop pauses the whole queue, derived from the jo…
brennanb2025 Sep 29, 2026
f0e1e90
Merge commit 'aca86ecd388' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
900bb7e
feat(native-chat): a /clear's replacement queue reads paused because …
brennanb2025 Sep 29, 2026
32570b4
feat(mobile): a paused queue shows one header row with Resume, and it…
brennanb2025 Sep 29, 2026
11c873e
Merge commit '900bb7e758d' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
302d693
test(mobile): the paused-queue header words the host's 'cleared' reason
brennanb2025 Sep 29, 2026
8558232
test(mobile): import the subscribe-event type the queued hook test names
brennanb2025 Sep 29, 2026
386d3d0
fix(native-chat): a queue pause covers only the cards it paused
brennanb2025 Sep 29, 2026
f7aa956
fix(mobile): the paused-queue row keeps Resume's whole target and is …
brennanb2025 Sep 29, 2026
432e7da
perf(native-chat): the queue's pause reads the latest person's turn i…
brennanb2025 Sep 29, 2026
d9ca984
fix(native-chat): a card handed off after a restart belongs to the pr…
brennanb2025 Sep 29, 2026
98ed5a7
fix(native-chat): a queue pause shows only while Resume would send so…
brennanb2025 Sep 29, 2026
dc064a3
Merge commit '98ed5a718c5' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
3aa767e
fix(mobile): the paused-queue header shows only while Resume would se…
brennanb2025 Sep 29, 2026
00007c9
fix(native-chat): a queue pause counts only cards Resume would actual…
brennanb2025 Sep 29, 2026
7d4b0c3
fix(native-chat): a returned card that blocks the paused cards hides …
brennanb2025 Sep 29, 2026
289f6d6
Merge commit '7d4b0c3a9d9' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
248333f
fix(native-chat): a Stop pauses a card its withdrawal sent back even …
brennanb2025 Sep 29, 2026
ce5b984
test(native-chat): pin the per-row hook's pause retirement; skip the …
brennanb2025 Sep 29, 2026
38f0696
Merge commit 'ce5b9840b3a' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
465a501
Merge origin/main (#23059 and 12 more) into mid-turn-queue-host
brennanb2025 Sep 29, 2026
5e16277
Merge remote-tracking branch 'origin/main' into mid-turn-queue-host
brennanb2025 Sep 29, 2026
026e09b
test(native-chat): match main's append and dispatch shapes in the que…
brennanb2025 Sep 29, 2026
e7abf50
Merge commit '026e09b2c39' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
7f7df31
fix(native-chat): read a compaction's settled submission through the …
brennanb2025 Sep 29, 2026
32c1288
test(mobile): a queued card's Steer groups under the running turn
brennanb2025 Sep 29, 2026
368f4d2
Merge commit '7f7df31bad4' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
e493ea6
Merge remote-tracking branch 'origin/main' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
a164348
Merge remote-tracking branch 'origin/main' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
5234bfa
feat(mobile): queued messages sit in one compact box, as on desktop
brennanb2025 Sep 29, 2026
f161f7e
Merge remote-tracking branch 'origin/main' into mid-turn-queue-mobile
brennanb2025 Sep 29, 2026
9c45df5
test(mobile): stub the queue's action sheet in the chat view tests
brennanb2025 Sep 29, 2026
40cdcb6
test(mobile): move the chat view's turn-status wiring tests to their …
brennanb2025 Sep 29, 2026
c2d7871
Merge remote-tracking branch 'origin/main' into mid-turn-queue-mobile
brennanb2025 Sep 30, 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
24 changes: 22 additions & 2 deletions mobile/src/session/MobileNativeChatComposer.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createElement, StrictMode, type ComponentProps } from 'react'
import { createElement, createRef, StrictMode, type ComponentProps } from 'react'
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
import { Keyboard } from 'react-native'
import { Keyboard, type TextInput } from 'react-native'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { radii, spacing } from '../theme/mobile-theme'
import { MobileNativeChatComposer as NativeChatComposer } from './MobileNativeChatComposer'
Expand Down Expand Up @@ -284,6 +284,26 @@ describe('MobileNativeChatComposer', () => {
expect(sendButton().props).toMatchObject({ disabled: true })
})

it('hands its owner the text field, so Edit can focus it', async () => {
const focus = vi.fn()
const inputRef = createRef<TextInput>()
await act(async () => {
renderer = create(
createElement(MobileNativeChatComposer, {
inputRef,
value: '',
onChangeText: vi.fn(),
onSend: vi.fn().mockResolvedValue(true),
sendSurfaceId: 'tab-a',
getSendCompletionGeneration: getCurrentSendCompletionGeneration
}),
{ createNodeMock: (element) => (element.type === 'TextInput' ? { focus } : null) }
)
})
inputRef.current?.focus()
expect(focus).toHaveBeenCalledTimes(1)
})

it('renders a removable thumbnail for each pending image attachment', async () => {
const onRemoveAttachment = vi.fn()
await act(async () => {
Expand Down
4 changes: 4 additions & 0 deletions mobile/src/session/MobileNativeChatComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const NO_FILE_PATHS: string[] = []
const NO_ATTACHMENTS: PendingNativeChatImage[] = []

type Props = {
/** Lets the owner focus the field, e.g. after Edit moves a queued message into it. */
inputRef?: React.Ref<TextInput>
structuredCommands?: readonly AgentSessionConversationCommand[]
/** Controlled composer text — owned by the parent so dictation can write to it. */
value: string
Expand Down Expand Up @@ -71,6 +73,7 @@ type Props = {
}

export function MobileNativeChatComposer({
inputRef,
value,
onChangeText,
onSend,
Expand Down Expand Up @@ -249,6 +252,7 @@ export function MobileNativeChatComposer({
<View style={styles.composerInset} testID="native-chat-composer-inset">
<View style={styles.bar} testID="native-chat-composer">
<TextInput
ref={inputRef}
style={mobileNativeChatInputStyles.input}
value={value}
onChangeText={handleChange}
Expand Down
13 changes: 12 additions & 1 deletion mobile/src/session/MobileNativeChatOverlay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ vi.mock('react-native', () => ({
}))

vi.mock('./MobileNativeChatView', () => ({ MobileNativeChatView: 'ChatView' }))
vi.mock('./MobileNativeChatQueuedMessages', () => ({ MobileNativeChatQueuedMessages: 'Queued' }))

function assistantTurn(id: string, text: string): NativeChatMessage {
return { id, role: 'assistant', blocks: [{ type: 'text', text }], timestamp: 0, source: 'hook' }
Expand All @@ -27,6 +28,7 @@ type Tick = {
}

function overlayElement(tick: Tick): ReturnType<typeof createElement> {
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the overlay reads only these controller members; the rest of the controller is unreachable from it.
const controller = {
showNativeChat: tick.show ?? true,
nativeChatSession: { messages: tick.messages ?? [], status: 'ready' },
Expand All @@ -38,7 +40,16 @@ function overlayElement(tick: Tick): ReturnType<typeof createElement> {
chatPending: [],
chatImagePreviewsByMessageId: {},
chatComposerText: '',
setChatComposerText: vi.fn()
setChatComposerText: vi.fn(),
nativeChatQueued: {
cards: [],
send: vi.fn(),
delete: vi.fn(),
edit: vi.fn(),
pause: null,
resume: vi.fn(),
sessionKey: 'session-a'
}
} as unknown as MobileNativeChatController
return createElement(MobileNativeChatOverlay, {
controller,
Expand Down
12 changes: 12 additions & 0 deletions mobile/src/session/MobileNativeChatOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { foldMobileNativeChatMessages } from './mobile-native-chat-render-data'
import type { MobileNativeChatImageAttachments } from './use-mobile-native-chat-image-attachments'
import type { MobileNativeChatController } from './use-mobile-native-chat-controller'
import { useMobileNativeChatStreamingBubble } from './use-mobile-native-chat-streaming-bubble'
import { useMobileNativeChatQueuedSlot } from './use-mobile-native-chat-queued-slot'

type Props = {
controller: MobileNativeChatController
Expand Down Expand Up @@ -59,6 +60,16 @@ export function MobileNativeChatOverlay({
controller.nativeChatStreamScopeKey,
controller.nativeChatStreamLive
)
const queued = controller.nativeChatQueued
const queuedSlot = useMobileNativeChatQueuedSlot({
cards: queued.cards,
onSend: queued.send,
onDelete: queued.delete,
onEdit: queued.edit,
pause: queued.pause,
onResume: queued.resume,
sessionKey: queued.sessionKey
})
if (!controller.showNativeChat) {
return null
}
Expand Down Expand Up @@ -89,6 +100,7 @@ export function MobileNativeChatOverlay({
onAnswerQuestion={controller.handleNativeChatQuestionAnswer}
permission={controller.nativeChatPermission}
onRespondPermission={controller.handleNativeChatRespondPermission}
queuedSlot={queuedSlot}
onOpenFile={onOpenFile}
hasMore={session.hasMore}
loadingEarlier={session.loadingEarlier}
Expand Down
Loading
Loading