Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
433 commits
Select commit Hold shift + click to select a range
6d8eefc
Merge remote-tracking branch 'origin/brennanb2025/acp-c1-timeline-ass…
brennanb2025 Oct 5, 2026
a46e8b8
End a running call as its turn's journal row ends
brennanb2025 Oct 5, 2026
cf9d0ee
Say why a Grok turn failed, and keep task rows in Grok's own words
brennanb2025 Oct 5, 2026
e88bbf0
Read a monitor from Grok's exact output prefix
brennanb2025 Oct 5, 2026
ad7678c
Word a failed Grok turn in Grok's own text, not as a refused message
brennanb2025 Oct 5, 2026
fdba83d
Settle a stopped turn's running call as its turn row ended after a re…
brennanb2025 Oct 5, 2026
70fd4ba
Keep the dead-generation settlement under the line cap
brennanb2025 Oct 5, 2026
7aa40a9
Register the ACP schema verify step in the PR preflight phase test
brennanb2025 Oct 5, 2026
19c8cb5
refactor(agent-session): one required agent registry; declarations ad…
brennanb2025 Oct 5, 2026
cc38107
Merge remote-tracking branch 'origin/brennanb2025/acp-d1-protocol' in…
brennanb2025 Oct 5, 2026
c4655b4
Read ACP permissions, session events and prompt errors through the pr…
brennanb2025 Oct 5, 2026
c5aaee8
refactor(agent-session): the router applies the declared rewind itself
brennanb2025 Oct 5, 2026
ae44163
Merge remote-tracking branch 'origin/brennanb2025/acp-a2-agent-regist…
brennanb2025 Oct 5, 2026
9e7b78a
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-a3-wire
brennanb2025 Oct 5, 2026
b494ed6
test(agent-session): register the agents the merged-in tests now need
brennanb2025 Oct 5, 2026
7591167
chore(agent-session): the registry is the one lookup; drop the test-o…
brennanb2025 Oct 5, 2026
288f72c
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-a2-a…
brennanb2025 Oct 5, 2026
e260b93
Merge remote-tracking branch 'origin/brennanb2025/acp-a2-agent-regist…
brennanb2025 Oct 5, 2026
65a967b
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-a3-wire
brennanb2025 Oct 5, 2026
4f32dc9
fix(agent-session): keep "dismiss all" restart offers dismissed for t…
brennanb2025 Oct 5, 2026
212af51
fix(agent-session): a changed agent definition never hides that agent…
brennanb2025 Oct 5, 2026
e23946f
refactor(agent-session): each agent's registration says where it runs…
brennanb2025 Oct 5, 2026
a83313b
test(agent-session): drop a duplicate registry key; keep fences out o…
brennanb2025 Oct 5, 2026
b557e5e
fix(agent-session): a scoped dismiss-all persists no per-session fence
brennanb2025 Oct 5, 2026
f0e695f
fix(agent-session): refuse an attach whose agent is not the session's…
brennanb2025 Oct 5, 2026
7b52fb5
fix(agent-session): offer to start a chat only when the start would a…
brennanb2025 Oct 5, 2026
38d510d
fix(agent-session): the model-catalog probe uses a record's account o…
brennanb2025 Oct 5, 2026
1a569b8
refactor(agent-session): the record store admits agent ids; comments …
brennanb2025 Oct 5, 2026
364f11f
docs(agent-session): the record store admits the registered agents' ids
brennanb2025 Oct 5, 2026
ad2b25a
Merge remote-tracking branch 'origin/brennanb2025/acp-a3-wire' (364f1…
brennanb2025 Oct 5, 2026
4fbeafa
Merge remote-tracking branch 'origin/brennanb2025/acp-a6-provider-lif…
brennanb2025 Oct 5, 2026
c064b28
Merge remote-tracking branch 'origin/brennanb2025/acp-c5-tool-interru…
brennanb2025 Oct 5, 2026
4edf2b2
Merge remote-tracking branch 'origin/brennanb2025/acp-d2-translation'…
brennanb2025 Oct 5, 2026
b7279d1
Merge remote-tracking branch 'origin/main' (d17351401d7) into brennan…
brennanb2025 Oct 5, 2026
57a7a29
refactor(native-chat): Grok's registration declares where it runs; AC…
brennanb2025 Oct 5, 2026
0fc5a72
fix(native-chat): Grok follows the ACP runtime's request contract and…
brennanb2025 Oct 5, 2026
1108280
fix(native-chat): a Grok chat Orca already holds resumes without writ…
brennanb2025 Oct 5, 2026
d2764bc
refactor(native-chat): a failed Grok reattach needs no window close o…
brennanb2025 Oct 5, 2026
cba2dfa
test(native-chat): D3's merged tests use the shipped declarations and…
brennanb2025 Oct 5, 2026
da34dda
fix(native-chat): typecheck fallout of the base merges; any agent's e…
brennanb2025 Oct 5, 2026
4b4febc
fix(native-chat): a Grok Stop ends the process once Grok settles its …
brennanb2025 Oct 5, 2026
f6f9d66
test(native-chat): a Grok Stop ends the process only after Grok answe…
brennanb2025 Oct 5, 2026
2245710
fix(native-chat): Steer on a Grok card cancels the running prompt, th…
brennanb2025 Oct 5, 2026
bca0c77
refactor(native-chat): a close or Stop cancels a start through the ac…
brennanb2025 Oct 5, 2026
a30a89e
fix(native-chat): a Grok crash that closes stdout before its exit sti…
brennanb2025 Oct 5, 2026
5d68d91
fix(native-chat): nothing Grok sends while a held chat reattaches is …
brennanb2025 Oct 5, 2026
586e6a6
test(native-chat): a Stop after a resume finds no turn an unmarked ol…
brennanb2025 Oct 5, 2026
651ab47
test(native-chat): a resumed Grok chat keeps its last context reading…
brennanb2025 Oct 5, 2026
e8d1e11
test(native-chat): a Grok background task a Stop ended reads as stopp…
brennanb2025 Oct 5, 2026
294fd0d
refactor(native-chat): quit's stop of each start answers through one …
brennanb2025 Oct 5, 2026
cd9a138
fix(native-chat): quit aborts every start the host has in flight befo…
brennanb2025 Oct 5, 2026
2c2731d
fix(native-chat): a Grok start's abort stops reaching its child once …
brennanb2025 Oct 5, 2026
418aa57
fix(native-chat): a close or Stop during any attach phase stops the s…
brennanb2025 Oct 5, 2026
a0c5bba
test(native-chat): a close during the attach's owner probe asks no ad…
brennanb2025 Oct 5, 2026
b63c9b5
test(native-chat): a close's re-ask closes a Claude or Codex child a …
brennanb2025 Oct 5, 2026
7a4ac2f
fix(native-chat): Steer during a turn Grok began itself cancels it an…
brennanb2025 Oct 5, 2026
0ff2585
test(native-chat): a steer whose cancel Grok never answers ends Grok …
brennanb2025 Oct 5, 2026
0baae44
fix(native-chat): a Grok crash stays a crash when a stop lands before…
brennanb2025 Oct 5, 2026
b0f1e33
test(native-chat): fixtures this PR's registered Grok and desktop cap…
brennanb2025 Oct 5, 2026
9931665
fix(native-chat): a start quit stops is not the queued message's star…
brennanb2025 Oct 5, 2026
ff08986
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-c1a-…
brennanb2025 Oct 5, 2026
06e664b
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-c1-t…
brennanb2025 Oct 5, 2026
98e7403
Merge origin/main into acp-d2-translation
brennanb2025 Oct 5, 2026
7346f41
fix(native-chat): a message sent after a Stop or close aborted a star…
brennanb2025 Oct 5, 2026
ad8ebbd
Merge remote-tracking branch 'origin/brennanb2025/acp-c1a-timeline-tr…
brennanb2025 Oct 5, 2026
77c16ec
test(native-chat): the message sent after an aborted start is answere…
brennanb2025 Oct 5, 2026
c4a96e1
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-c5-t…
brennanb2025 Oct 5, 2026
16eef12
Merge remote-tracking branch 'origin/brennanb2025/acp-c1-timeline-ass…
brennanb2025 Oct 5, 2026
c1f0c7a
Merge acp-c1-timeline-assembler (main merged) into acp-d2-translation
brennanb2025 Oct 5, 2026
75231a4
fix(native-chat): a Grok model pick Grok never answers no longer hold…
brennanb2025 Oct 5, 2026
27a9db0
fix(agent-launch): a phone's launch opens a terminal for an agent who…
brennanb2025 Oct 5, 2026
d2e32d1
fix(acp): strip every agent hook variable from the ACP child, from th…
brennanb2025 Oct 5, 2026
2776c80
refactor(native-chat): the mutation context carries the provider-wait…
brennanb2025 Oct 5, 2026
a24cd11
fix(agent-launch): agent.launch.v2 still vouches for Claude and Codex…
brennanb2025 Oct 5, 2026
879f74a
refactor(native-chat): drop saved-history adoption from the timeline …
brennanb2025 Oct 5, 2026
d012bc2
Merge remote-tracking branch 'origin/brennanb2025/acp-c1-timeline-ass…
brennanb2025 Oct 5, 2026
0f4be81
refactor(acp): drop session/load history adoption from the translator
brennanb2025 Oct 5, 2026
58c3dd5
refactor(native-chat): a pending input is only Orca's send now
brennanb2025 Oct 5, 2026
d40fd03
Merge remote-tracking branch 'origin/brennanb2025/acp-c1-timeline-ass…
brennanb2025 Oct 5, 2026
2802460
test(acp): keep the task-result status table on live frames
brennanb2025 Oct 5, 2026
d613623
test(acp): a frame helper for a shell command Grok is running
brennanb2025 Oct 5, 2026
03ca1d9
fix(acp): a Grok crash settles through the host's provider-exit batch…
brennanb2025 Oct 5, 2026
8854fe8
test(acp): a crash seen first leaves the host no Grok turn to revise
brennanb2025 Oct 5, 2026
459b8cb
refactor(native-chat): what a gone generation left unfinished gets it…
brennanb2025 Oct 5, 2026
ed63665
refactor(native-chat): a watched exit revises what its child left unv…
brennanb2025 Oct 5, 2026
ed9fadc
test(native-chat): drop the duplicate itemFence on the fake that alre…
brennanb2025 Oct 5, 2026
16e84d0
test(claude, codex): an exit whose stdout ended first still reports a…
brennanb2025 Oct 5, 2026
374e740
Merge origin/main into acp-a1-opaque-handle
brennanb2025 Oct 5, 2026
75ddbbe
fix(acp): reopen a chat with session/load, as the common pattern does
brennanb2025 Oct 5, 2026
22d3d85
Merge acp-a1-opaque-handle (with origin/main) into acp-a2-agent-registry
brennanb2025 Oct 5, 2026
ce62189
fix(acp): drop the 60 s handshake bound; an abort fails the start's w…
brennanb2025 Oct 5, 2026
275455d
fix(acp): a Stop naming an ended turn follows Claude's rule
brennanb2025 Oct 5, 2026
ace8822
Merge acp-a2-agent-registry (with origin/main) into acp-a3-wire
brennanb2025 Oct 5, 2026
c832af5
fix(native-chat): a close no longer re-asks a failed start's unproven…
brennanb2025 Oct 5, 2026
c2bfd63
Merge origin/main into acp-a6-provider-lifecycle
brennanb2025 Oct 5, 2026
fe8108c
fix(acp): a message sent during a turn the agent began itself goes at…
brennanb2025 Oct 5, 2026
6143fb4
test(native-chat): dismiss-all through a remote client's audience kee…
brennanb2025 Oct 5, 2026
d717abf
fix(acp): launch Grok as `grok agent stdio`, without the update and l…
brennanb2025 Oct 5, 2026
e996bb1
Merge origin/main into acp-c1a-timeline-transitions
brennanb2025 Oct 5, 2026
aa80392
fix(acp): an agent that ends its stdout, or answers unreadably, is no…
brennanb2025 Oct 5, 2026
fa8e969
fix(native-chat): a person's close joining a failed one still binds t…
brennanb2025 Oct 5, 2026
a59276f
Merge remote-tracking branch 'origin/brennanb2025/acp-c1a-timeline-tr…
brennanb2025 Oct 5, 2026
5c4a89f
Merge remote-tracking branch 'origin/brennanb2025/acp-c1-timeline-ass…
brennanb2025 Oct 5, 2026
a08bbef
test(native-chat): Grok opens as a chat only behind the structured-ch…
brennanb2025 Oct 5, 2026
557a602
docs(acp): generic ACP comments say what holds for every agent, not Grok
brennanb2025 Oct 5, 2026
3b7d680
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-d1-p…
brennanb2025 Oct 5, 2026
f5b6658
test(claude, codex): type the EOF-before-exit test's streams; the sup…
brennanb2025 Oct 5, 2026
76a91ab
feat(acp): a steer's cancel asks once and never ends the agent
brennanb2025 Oct 5, 2026
2a1cef2
chore(native-chat): keep the record store and recovery capsule under …
brennanb2025 Oct 5, 2026
58bb525
fix(acp): a repeated steer shares the cancel in flight; say what the …
brennanb2025 Oct 5, 2026
3b0c7ab
Merge origin/main into acp-a2-agent-registry (main #24862)
brennanb2025 Oct 5, 2026
42c2e2f
Merge acp-a2-agent-registry (main #24862) into acp-a3-wire
brennanb2025 Oct 5, 2026
636f6f1
Merge origin/main into acp-a6-provider-lifecycle (main #24862 landed)
brennanb2025 Oct 5, 2026
f77b590
Merge acp-c1-timeline-assembler into acp-c5-tool-interrupted
brennanb2025 Oct 5, 2026
105ba89
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-c5-t…
brennanb2025 Oct 5, 2026
162e973
Merge A3 #25159 (42c2e2fb532) into D3
brennanb2025 Oct 5, 2026
d3342e3
Merge A6 #25204 (636f6f1bdc4) into D3
brennanb2025 Oct 5, 2026
13f9ad8
Merge C5 #25181 (105ba896929) into D3
brennanb2025 Oct 5, 2026
75f36ac
Merge D2 #25090 (5c4a89f0613) into D3
brennanb2025 Oct 5, 2026
c862fe7
Merge D1 #24990 (58bb525f828) into D3
brennanb2025 Oct 5, 2026
3bc888b
Merge origin/main (e9ed75a5de1) into D3
brennanb2025 Oct 5, 2026
804c2bb
fix(native-chat): drop the stopDelivery the A3 merge doubled
brennanb2025 Oct 5, 2026
964db92
fix(acp): a steer's cancel asks Grok once and never ends it
brennanb2025 Oct 5, 2026
28b5036
fix(acp): a permission Grok asks with no prompt of Orca's running is …
brennanb2025 Oct 5, 2026
a6bd840
fix(acp): a Grok that dies while starting is reported with its own la…
brennanb2025 Oct 5, 2026
212d0d2
test: a Stop after a steer sends its own cancel; drop the import the …
brennanb2025 Oct 5, 2026
10673e9
test(native-chat): main's Stop-note test builds its turn context with…
brennanb2025 Oct 5, 2026
d47e26e
test(claude): say why the close test's fake child cast is safe
brennanb2025 Oct 5, 2026
bb082ea
Merge origin/main (a3bd6a6a1e7) into D3
brennanb2025 Oct 5, 2026
fc120f7
Merge origin/main into acp-a2-agent-registry (main squash of A1 #2499…
brennanb2025 Oct 5, 2026
fb8bcb8
test(native-chat): build the Stop-opened-turn test's identity and tur…
brennanb2025 Oct 5, 2026
7c4112f
Merge acp-a2-agent-registry (with origin/main d791421568c) into acp-a…
brennanb2025 Oct 5, 2026
f1e98c3
Merge origin/main into acp-a6-provider-lifecycle (main squash of #249…
brennanb2025 Oct 5, 2026
5c6a834
test(native-chat): build the Stop-opened-turn test's identity with th…
brennanb2025 Oct 5, 2026
e35bf18
test(ratchet): require src/main/provider-process now that it has landed
brennanb2025 Oct 5, 2026
0bb3919
Merge origin/main into acp-a2-agent-registry (main #25706, #25073)
brennanb2025 Oct 5, 2026
5f8deca
Merge brennanb2025/ratchet-provider-process-required (#25710) into ac…
brennanb2025 Oct 5, 2026
5b75928
test(native-chat): keep main's opaque-handle import in the Stop-opene…
brennanb2025 Oct 5, 2026
4e53819
Merge origin/main into acp-a6-provider-lifecycle (main #25706, #25073)
brennanb2025 Oct 5, 2026
1a5c70e
test(native-chat): keep main's opaque-handle import in the Stop-opene…
brennanb2025 Oct 5, 2026
ab066e6
Merge brennanb2025/ratchet-provider-process-required (#25710) into ac…
brennanb2025 Oct 5, 2026
a21812b
Merge acp-a2-agent-registry (main 9def4b9ba19 + ratchet fix #25710) i…
brennanb2025 Oct 5, 2026
1717828
Merge origin/main into acp-c5-tool-interrupted (main #25073 and the A…
brennanb2025 Oct 5, 2026
433c302
Merge brennanb2025/ratchet-provider-process-required (#25710) into ac…
brennanb2025 Oct 5, 2026
9dbd818
Merge origin/main into acp-a2-agent-registry (main's submission-posit…
brennanb2025 Oct 5, 2026
8e35d9a
Merge origin/main into acp-c5-tool-interrupted (main's submission-pos…
brennanb2025 Oct 5, 2026
5d011d7
Merge origin/main into acp-a6-provider-lifecycle (main's submission-p…
brennanb2025 Oct 5, 2026
547158c
Merge acp-a2-agent-registry (main e65bbc95cec) into acp-a3-wire
brennanb2025 Oct 5, 2026
1f7f7fa
feat(native-chat): record a fresh provider conversation that replaced…
brennanb2025 Oct 5, 2026
54c9f21
test(native-chat): build this stack's journal identities with main's …
brennanb2025 Oct 5, 2026
a6923e4
docs(acp): every reattach drops the agent's replay, not only for a ch…
brennanb2025 Oct 5, 2026
6312c30
Merge origin/main into acp-a2-agent-registry (main's duplicate-import…
brennanb2025 Oct 6, 2026
8e3331c
Merge acp-a2-agent-registry (main c6827fe02a5) into acp-a3-wire
brennanb2025 Oct 6, 2026
a26ef64
Merge origin/main into acp-a6-provider-lifecycle (main's duplicate-im…
brennanb2025 Oct 6, 2026
6130495
Merge origin/main into acp-c5-tool-interrupted (main's duplicate-impo…
brennanb2025 Oct 6, 2026
ab992ed
refactor(native-chat): store a replaced conversation flat; refuse it …
brennanb2025 Oct 6, 2026
ed9996e
Merge A3 #25159 (8e3331cd0e8) into D3
brennanb2025 Oct 6, 2026
528f256
Merge A6 #25204 (a26ef64fd9b) into D3
brennanb2025 Oct 6, 2026
c6ce409
Merge C5 #25181 (6130495f57b) into D3
brennanb2025 Oct 6, 2026
c95cc45
Merge origin/main (9756daeced4) into D3
brennanb2025 Oct 6, 2026
a31b528
refactor(native-chat): read hosts' structured agents from the app-she…
brennanb2025 Oct 6, 2026
2a57650
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-hand…
brennanb2025 Oct 6, 2026
5e84b09
Merge current main into agent registry branch
brennanb2025 Oct 6, 2026
6b1ed63
Merge 5e84b09c0d94 into acp-a3-wire
brennanb2025 Oct 6, 2026
e21865a
Merge 8127d9478218 into acp-a6-provider-lifecycle
brennanb2025 Oct 6, 2026
4dfc78f
Merge 8127d9478218 into acp-c5-tool-interrupted
brennanb2025 Oct 6, 2026
503e483
Merge 8127d9478218 into acp-c1a-timeline-transitions
brennanb2025 Oct 6, 2026
eba27a3
Use current provider handles in transition tests
brennanb2025 Oct 6, 2026
bbd96e1
Merge eba27a3c784e into acp-c1-timeline-assembler
brennanb2025 Oct 6, 2026
a7d8bcb
Use current provider handles in timeline fixtures
brennanb2025 Oct 6, 2026
63f79a9
Merge a7d8bcbb64fb into acp-d2-translation
brennanb2025 Oct 6, 2026
3b064e8
test(native-chat): prove replacement rows survive downgrade and re-up…
brennanb2025 Oct 6, 2026
503ebe4
Require the ACP directory in the runtime import check
brennanb2025 Oct 6, 2026
db71a89
Merge 08a970a3f117 into acp-a2-agent-registry
brennanb2025 Oct 6, 2026
a94f7ec
Merge db71a89d7438 into acp-a3-wire
brennanb2025 Oct 6, 2026
5df4db2
Merge 08a970a3f117 into acp-a6-provider-lifecycle
brennanb2025 Oct 6, 2026
85d1b66
Merge 08a970a3f117 into acp-c5-tool-interrupted
brennanb2025 Oct 6, 2026
383b0dc
Merge 08a970a3f117 into acp-c1a-timeline-transitions
brennanb2025 Oct 6, 2026
b5b0068
Merge 383b0dc2c420 into acp-c1-timeline-assembler
brennanb2025 Oct 6, 2026
bb93479
Merge b5b0068f885c into acp-d2-translation
brennanb2025 Oct 6, 2026
e7c0c5d
Merge origin/main (1b52be62550) into D3
brennanb2025 Oct 6, 2026
754fe5b
test(ratchet): require src/main/acp now that this PR lands it
brennanb2025 Oct 6, 2026
ba22513
Merge #25747 (3b064e88821) into D3
brennanb2025 Oct 6, 2026
541ecbd
Merge remote-tracking branch 'origin/main' into brennanb2025/acp-hand…
brennanb2025 Oct 6, 2026
b6f57c3
feat(acp): a saved session the agent cannot reopen continues in a new…
brennanb2025 Oct 6, 2026
df8468e
Merge #25747 (541ecbd6835) into D3
brennanb2025 Oct 6, 2026
dbeef45
chore(acp): rewrap the acquire header comment
brennanb2025 Oct 6, 2026
bcff300
test(acp): a start closed while the agent reopens fails without openi…
brennanb2025 Oct 6, 2026
93ec93f
Merge A3 #25159 (a94f7ecd33e) into D3
brennanb2025 Oct 6, 2026
42b61b1
Merge A6 #25204 (5df4db2900c) into D3
brennanb2025 Oct 6, 2026
bbd9694
Merge C5 #25181 (85d1b669941) into D3
brennanb2025 Oct 6, 2026
2ac670f
Merge D2 #25090 (bb93479f1a2) into D3
brennanb2025 Oct 6, 2026
cc22251
Merge origin/main (5f7c8483e9c) into D3
brennanb2025 Oct 6, 2026
67e12c3
Merge current main and landed protocol client into translation branch
brennanb2025 Oct 6, 2026
82baab3
Merge origin/main (4e64fa9940f) into D3
brennanb2025 Oct 6, 2026
798fc3b
Let ACP connections own their supervised agent process
brennanb2025 Oct 6, 2026
613ca21
Preserve ACP cleanup evidence and isolate exit observers
brennanb2025 Oct 6, 2026
20f7f8a
Expose ACP cleanup observations and type the permission fixture
brennanb2025 Oct 6, 2026
9bd27f9
Merge landed timeline assembler and current main into ACP translation…
brennanb2025 Oct 6, 2026
e7212b2
Merge origin/main (1de3aa405f7) into D3
brennanb2025 Oct 6, 2026
0ef6d21
refactor(native-chat): the registered-agents capability lives in its …
brennanb2025 Oct 6, 2026
2de0157
Merge origin/main (9905765e3b8) into D3
brennanb2025 Oct 6, 2026
aebc700
Merge ACP-ALIGN #25810 (20f7f8a9531) into D3
brennanb2025 Oct 6, 2026
eae097e
Merge D2 #25090 (9bd27f9d16b) into D3
brennanb2025 Oct 6, 2026
03584f0
refactor(acp): one connection owns the Grok process and its protocol
brennanb2025 Oct 6, 2026
c23d1ce
Merge origin/main (4de9f9f85a8) into D3
brennanb2025 Oct 6, 2026
fa957dc
fix(acp): Grok signs in on its own machine with its API key or cached…
brennanb2025 Oct 6, 2026
bb32fe8
fix(acp): the adapter decides which of Grok's requests reach the person
brennanb2025 Oct 6, 2026
dfaf049
feat(native-chat): add inactive Pi RPC transport foundation
brennanb2025 Oct 6, 2026
c6a4a29
Merge remote-tracking branch 'origin/main' into brennanb2025/native-c…
brennanb2025 Oct 6, 2026
9c7c2eb
fix(acp): a plan Grok proposes shows as a plan, with no approval card
brennanb2025 Oct 6, 2026
7b8bdaa
fix(orchestration): worker-start opens a Grok worker in a terminal, a…
brennanb2025 Oct 6, 2026
606d1f6
fix(acp): a prompt answer Orca can't read ends the turn instead of ha…
brennanb2025 Oct 6, 2026
ede3d6f
feat(native-chat): add bounded RPC reading control
brennanb2025 Oct 6, 2026
a652f15
fix(acp): send Grok's prompt-identity extension only to agents that e…
brennanb2025 Oct 6, 2026
06c7314
Merge origin/main (3ec38b8c6d1) into D3
brennanb2025 Oct 6, 2026
2f7da77
refactor(native-chat): the registered-agents capability lives in prot…
brennanb2025 Oct 6, 2026
b972838
test(acp): read the sign-in method with a schema, not a type assertion
brennanb2025 Oct 6, 2026
6aadfde
refactor(native-chat): composer transport and Stop control in their o…
brennanb2025 Oct 6, 2026
1c3f726
Merge origin/main (b75213100b5) into D3
brennanb2025 Oct 6, 2026
06dd7ea
test(native-chat): read registered agents by id, as main's structured…
brennanb2025 Oct 6, 2026
07f1461
Merge remote-tracking branch 'origin/main' into brennanb2025/native-c…
brennanb2025 Oct 6, 2026
5af35e4
Add Pi structured chat over its native RPC mode
brennanb2025 Oct 6, 2026
4663bea
Merge commit '06dd7eae3de' into brennanb2025/native-chat-pi-rpc
brennanb2025 Oct 6, 2026
20d14c9
Use shared provider spawn identity and base environment
brennanb2025 Oct 6, 2026
4de7f2b
Complete Pi startup ownership and prompt delivery safeguards
brennanb2025 Oct 6, 2026
aa403c8
Use generic failure copy for Pi RPC sessions
brennanb2025 Oct 6, 2026
e81bedd
Admit finalized Pi output before session eviction
brennanb2025 Oct 6, 2026
2401fd0
Apply Pi client capability checks to all chat routes
brennanb2025 Oct 6, 2026
fabf0e6
Merge current main into Pi structured chat
brennanb2025 Oct 6, 2026
0223c6e
Keep older Pi versions on terminal chat
brennanb2025 Oct 6, 2026
71709dc
Use supervised process support checks for Pi launches
brennanb2025 Oct 6, 2026
c410a3c
Complete the Pi location-test adapter fixture
brennanb2025 Oct 6, 2026
a636bc0
Merge remote-tracking branch 'origin/main' into brennanb2025/native-c…
brennanb2025 Oct 6, 2026
4bb3881
Retain the settled-work extraction in the main merge
brennanb2025 Oct 6, 2026
78d37e5
Use the settled-work module in the new reasoning sweep test
brennanb2025 Oct 6, 2026
717be71
Merge origin/main (Grok structured chat over ACP landed) into Pi over…
brennanb2025 Oct 7, 2026
1b10d1d
Test that Pi prompt alerts skip clients that cannot read Pi
brennanb2025 Oct 7, 2026
e935784
Pin why a timed-out write closes the agent connection only once it is…
brennanb2025 Oct 7, 2026
3d12804
Merge origin/main (main's lint fix #26079) into brennanb2025/native-c…
brennanb2025 Oct 7, 2026
f6d5438
Type the prompt-alert fixture as the wire's prompt attention
brennanb2025 Oct 7, 2026
e54c521
Run the Pi launch-resolution test in the Node runtime project
brennanb2025 Oct 7, 2026
a38aa64
Merge origin/main (main's web typecheck fix #26097) into brennanb2025…
brennanb2025 Oct 7, 2026
57ee8e9
Merge origin/main into brennanb2025/native-chat-pi-rpc
brennanb2025 Oct 7, 2026
55f8b26
Pin that a Pi chat reopened after a restart resumes its stored sessio…
brennanb2025 Oct 7, 2026
cb9d33a
Show an explicitly empty text answer as "Empty answer", not as unread…
brennanb2025 Oct 7, 2026
4c25ad0
Merge remote-tracking branch 'origin/main' into brennanb2025/native-c…
brennanb2025 Oct 7, 2026
b31f4fe
Merge origin/main into native-chat-pi-rpc
brennanb2025 Oct 7, 2026
88506a8
refactor(pi): check and resolve Pi's binary through the shared versio…
brennanb2025 Oct 7, 2026
f3be80a
feat(pi): run stable Pi from 0.84.0 in the structured chat, not only 1.x
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: 3 additions & 1 deletion config/scripts/check-runtime-electron-ratchet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export const STRUCTURED_CHAT_LANES = [
{ directory: ['src', 'shared'] },
{ directory: ['src', 'main', 'runtime'], basename: /^(?:structured-|agent-session-)/ },
{ directory: ['src', 'main', 'provider-process'] },
{ directory: ['src', 'main', 'acp'] }
{ directory: ['src', 'main', 'acp'] },
{ directory: ['src', 'main', 'jsonl-rpc'] },
{ directory: ['src', 'main', 'pi'], basename: /^rpc-/ }
]

export function collectStructuredChatEntryPoints(root = ROOT) {
Expand Down
32 changes: 27 additions & 5 deletions config/scripts/check-runtime-electron-ratchet.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ describe('structured chat coverage', () => {
'src/main/runtime/structured-agent-session-host.ts': 'export {}',
'src/main/provider-process/provider-process-teardown.ts': 'export {}',
'src/main/acp/acp-structured-session-adapter.ts': 'export {}',
'src/main/jsonl-rpc/peer.ts': 'export {}',
'src/main/pi/rpc-launch.ts': 'export {}',
'src/shared/agent-session-record.ts': 'export {}'
}

Expand All @@ -55,7 +57,8 @@ describe('structured chat coverage', () => {
'src/main/runtime/structured-agent-runtime-registrations.ts',
'src/main/runtime/rpc/methods/structured-agent-session-agents.ts',
'src/main/acp/adapter.ts',
'src/main/provider-process/worker.ts'
'src/main/provider-process/worker.ts',
'src/main/jsonl-rpc/nested/dialect.ts'
]
const excluded = [
'src/main/native-chat/reader.test.ts',
Expand All @@ -73,7 +76,10 @@ describe('structured chat coverage', () => {
'src/main/runtime/orca-runtime-tests/structured-agent-session-host.ts',
'src/shared/types.d.ts',
'src/main/runtime/other.ts',
'src/main/runtime/rpc/methods/browser.ts'
'src/main/runtime/rpc/methods/browser.ts',
'src/main/jsonl-rpc/peer.test.ts',
'src/main/pi/rpc-launch.test.ts',
'src/main/pi/titlebar-extension-service.ts'
]
const root = fixture(
Object.fromEntries([...sources, ...excluded].map((file) => [file, 'export {}']))
Expand All @@ -90,7 +96,9 @@ describe('structured chat coverage', () => {
Object.entries(requiredLanes).filter(([file]) => !file.startsWith(`${lane}/`))
)
expect(() => collectStructuredChatEntryPoints(fixture(without))).toThrow(`${lane} is missing`)
expect(collectStructuredChatEntryPoints(fixture(requiredLanes))).toHaveLength(7)
expect(collectStructuredChatEntryPoints(fixture(requiredLanes))).toHaveLength(
Object.keys(requiredLanes).length
)
}
)

Expand All @@ -101,6 +109,8 @@ describe('structured chat coverage', () => {
...requiredLanes,
'src/main/acp/adapter.ts': "import 'acp-desktop-package'",
'src/main/provider-process/worker.ts': "import 'provider-desktop-package'",
'src/main/jsonl-rpc/peer.ts': "import 'rpc-desktop-package'",
'src/main/pi/rpc-launch.ts': "import 'pi-desktop-package'",
'node_modules/acp-desktop-package/package.json': JSON.stringify({
main: 'index.js',
sideEffects
Expand All @@ -110,12 +120,24 @@ describe('structured chat coverage', () => {
main: 'index.js',
sideEffects
}),
'node_modules/provider-desktop-package/index.js': "require('electron')"
'node_modules/provider-desktop-package/index.js': "require('electron')",
'node_modules/rpc-desktop-package/package.json': JSON.stringify({
main: 'index.js',
sideEffects
}),
'node_modules/rpc-desktop-package/index.js': "require('electron')",
'node_modules/pi-desktop-package/package.json': JSON.stringify({
main: 'index.js',
sideEffects
}),
'node_modules/pi-desktop-package/index.js': "require('electron')"
})
const current = await collectElectronImporters(collectStructuredChatEntryPoints(root))
expect(current.map((file) => file.split('/node_modules/').pop())).toEqual([
'acp-desktop-package/index.js',
'provider-desktop-package/index.js'
'pi-desktop-package/index.js',
'provider-desktop-package/index.js',
'rpc-desktop-package/index.js'
])
}
)
Expand Down
1 change: 1 addition & 0 deletions config/scripts/vitest-sqlite-runtime-files.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export const SQLITE_RUNTIME_INCLUDE = [
'src/main/native-chat/agent-session-wire/structured-agent-session-wire-admission.test.ts',
'src/main/native-chat/agent-session-wire/structured-conversation-command.test.ts',
'src/main/orcad/orcad-automations.test.ts',
'src/main/pi/rpc-launch-resolution.test.ts',
'src/main/runtime/agent-session-conversation-clear-commit.test.ts',
'src/main/runtime/agent-session-conversation-name-store.test.ts',
'src/main/runtime/agent-session-death-evidence-persistence.test.ts',
Expand Down
67 changes: 67 additions & 0 deletions mobile/src/session/MobileNativeChatQuestion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,71 @@ describe('MobileNativeChatQuestion', () => {
await act(async () => cancel.props.onPress())
expect(onCancel).toHaveBeenCalledWith({ itemId: 'question-1', expectedRevision: 7 })
})

it('prefills an editor and sends its whitespace unchanged', async () => {
const onAnswer = vi.fn(async () => true)
await act(async () => {
renderer = create(
createElement(MobileNativeChatQuestion, {
question: {
question: 'Edit the draft',
options: [],
multiSelect: false,
optionTokens: [],
freeTextToken: 'editor-token',
freeTextInput: {
allowEmpty: true,
multiline: true,
initialValue: ' draft\n',
placeholder: 'Write here'
}
},
onAnswer
})
)
})

const input = renderer.root.findByType('TextInput')
expect(input.props).toMatchObject({
value: ' draft\n',
placeholder: 'Write here',
multiline: true
})
await act(async () => input.props.onChangeText(' \n '))
const send = renderer.root.findByProps({ accessibilityLabel: 'Send reply' })
expect(send.props.disabled).toBe(false)
await act(async () => send.props.onPress())
expect(onAnswer).toHaveBeenCalledWith(`editor-token:${encodeURIComponent(' \n ')}`)
})

it('sends an empty allowed answer and still disables an empty legacy answer', async () => {
const onAnswer = vi.fn(async () => true)
const question = {
question: 'Input',
options: [],
multiSelect: false,
optionTokens: [],
freeTextToken: 'input-token'
}
await act(async () => {
renderer = create(
createElement(MobileNativeChatQuestion, {
question: { ...question, freeTextInput: { allowEmpty: true, multiline: false } },
onAnswer
})
)
})
const send = renderer.root.findByProps({ accessibilityLabel: 'Send reply' })
expect(renderer.root.findByType('TextInput').props.multiline).toBe(false)
expect(send.props.disabled).toBe(false)
await act(async () => send.props.onPress())
expect(onAnswer).toHaveBeenCalledWith('input-token:')

await act(async () =>
renderer.update(createElement(MobileNativeChatQuestion, { question, onAnswer }))
)
expect(renderer.root.findByProps({ accessibilityLabel: 'Send reply' }).props.disabled).toBe(
true
)
})
})
24 changes: 14 additions & 10 deletions mobile/src/session/MobileNativeChatQuestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ export function MobileNativeChatQuestion({
onCollapse
}: Props): React.JSX.Element {
const [selectedOptionIndexes, setSelectedOptionIndexes] = useState<number[]>([])
const [freeText, setFreeText] = useState('')
const [freeText, setFreeText] = useState(() => question.freeTextInput?.initialValue ?? '')
const [sending, setSending] = useState(false)
const sendingRef = useRef(false)
const allowOther = question.allowOther !== false

const hasOptions = question.options.length > 0
const trimmedFreeText = freeText.trim()
const answerText = question.freeTextInput?.allowEmpty ? freeText : freeText.trim()

const toggle = (optionIndex: number): void => {
setSelectedOptionIndexes((prev) =>
Expand Down Expand Up @@ -72,29 +72,30 @@ export function MobileNativeChatQuestion({
return
}
const answer =
question.freeTextToken && trimmedFreeText.length > 0
? formatQuestionAnswerWithOtherByIndexes(question, selectedOptionIndexes, trimmedFreeText)
question.freeTextToken && answerText.length > 0
? formatQuestionAnswerWithOtherByIndexes(question, selectedOptionIndexes, answerText)
: formatQuestionAnswerByIndexes(question, selectedOptionIndexes)
if (await sendAnswer(answer)) {
setFreeText('')
}
}

const submitFreeText = async (): Promise<void> => {
if (trimmedFreeText.length === 0) {
if (!allowOther || (answerText.length === 0 && !question.freeTextInput?.allowEmpty)) {
return
}
const answer =
question.multiSelect && question.freeTextToken && selectedOptionIndexes.length > 0
? formatQuestionAnswerWithOtherByIndexes(question, selectedOptionIndexes, trimmedFreeText)
: formatQuestionFreeTextAnswer(question, trimmedFreeText)
? formatQuestionAnswerWithOtherByIndexes(question, selectedOptionIndexes, answerText)
: formatQuestionFreeTextAnswer(question, answerText)
if (await sendAnswer(answer)) {
setFreeText('')
}
}

const canSubmitMulti = selectedOptionIndexes.length > 0 && !sending
const canSendFreeText = allowOther && trimmedFreeText.length > 0 && !sending
const canSendFreeText =
allowOther && (answerText.length > 0 || question.freeTextInput?.allowEmpty === true) && !sending

// Stable keys for option rows even if an agent repeats a label.
const optionRows = useMemo(
Expand Down Expand Up @@ -178,12 +179,15 @@ export function MobileNativeChatQuestion({
style={mobileNativeChatInputStyles.freeInput}
value={freeText}
onChangeText={setFreeText}
placeholder={hasOptions ? 'Or type a reply…' : 'Type your reply…'}
placeholder={
question.freeTextInput?.placeholder ??
(hasOptions ? 'Or type a reply…' : 'Type your reply…')
}
placeholderTextColor={colors.textMuted}
selectionColor={colors.accentBlue}
onSubmitEditing={submitFreeText}
returnKeyType="send"
multiline
multiline={question.freeTextInput?.multiline ?? true}
/>
<Pressable
accessibilityLabel="Send reply"
Expand Down
15 changes: 15 additions & 0 deletions mobile/src/session/mobile-native-chat-question.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,21 @@ describe('formatQuestionAnswer', () => {
formatQuestionFreeTextAnswer({ ...numbered, freeTextToken: 'target' }, ' hi there ')
).toBe(`target:${encodeURIComponent('hi there')}`)
})

it('encodes empty and whitespace answers only when allowed', () => {
const withInput: MobileChatQuestion = {
...numbered,
freeTextToken: 'target',
freeTextInput: { allowEmpty: true }
}
expect(formatQuestionFreeTextAnswer(withInput, '')).toBe('target:')
expect(formatQuestionFreeTextAnswer(withInput, ' \n ')).toBe(
`target:${encodeURIComponent(' \n ')}`
)
expect(formatQuestionFreeTextAnswer({ ...withInput, freeTextInput: undefined }, ' \n ')).toBe(
''
)
})
})

describe('mobileChatQuestionKey', () => {
Expand Down
13 changes: 9 additions & 4 deletions mobile/src/session/mobile-native-chat-question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// have no structured signal, so we parse the text conservatively and only treat
// it as a question when a clear option list is present.

import type { AgentJournalFreeTextInput } from '../../../src/shared/agent-session-journal-types'

export type MobileChatQuestion = {
question: string
/** Structured prompt identity, present only for durable host prompts. */
Expand All @@ -19,6 +21,7 @@ export type MobileChatQuestion = {
optionDescriptions?: (string | undefined)[]
/** Opaque prefix used when free-text answers must target a specific prompt. */
freeTextToken?: string
freeTextInput?: AgentJournalFreeTextInput
}

export function mobileChatQuestionKey(question: MobileChatQuestion): string {
Expand Down Expand Up @@ -203,11 +206,13 @@ export function formatQuestionAnswer(question: MobileChatQuestion, selected: str
}

export function formatQuestionFreeTextAnswer(question: MobileChatQuestion, text: string): string {
const trimmed = text.trim()
if (trimmed.length === 0) {
const answer = question.freeTextInput?.allowEmpty ? text : text.trim()
if (answer.length === 0 && !question.freeTextInput?.allowEmpty) {
return ''
}
return question.freeTextToken
? `${question.freeTextToken}:${encodeURIComponent(trimmed)}`
: formatQuestionAnswer(question, [trimmed])
? `${question.freeTextToken}:${encodeURIComponent(answer)}`
: question.freeTextInput?.allowEmpty
? answer
: formatQuestionAnswer(question, [answer])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { describe, expect, it } from 'vitest'
import type { AgentJournalFreeTextInput } from '../../../src/shared/agent-session-journal-types'
import { formatQuestionFreeTextAnswer } from './mobile-native-chat-question'
import {
projectStructuredQuestion,
structuredQuestionResponseTarget,
type StructuredQuestionItem
} from './mobile-structured-agent-prompts'

function prompt(freeTextInput?: AgentJournalFreeTextInput): StructuredQuestionItem {
return {
itemId: 'item-1',
revision: 3,
sequence: 1,
observedAt: 1,
body: {
kind: 'question',
question: 'Edit the draft',
options: [],
freeTextQuestionId: 'q1',
...(freeTextInput ? { freeTextInput } : {}),
resolution: { state: 'pending', selectedOptionId: null, resolvedBy: null, resolvedAt: null }
}
}
}

describe('mobile structured free-text questions', () => {
it('projects editor input metadata onto the existing question card', () => {
const freeTextInput = {
allowEmpty: true,
multiline: true,
initialValue: 'draft',
placeholder: 'Edit here'
}
expect(projectStructuredQuestion(prompt(freeTextInput))?.freeTextInput).toEqual(freeTextInput)
expect(projectStructuredQuestion(prompt())?.freeTextInput).toBeUndefined()
})

it('accepts empty and whitespace text only for the matching allowed prompt', () => {
const current = prompt({ allowEmpty: true })
const projected = projectStructuredQuestion(current)!
for (const answer of ['', ' \n ']) {
const response = formatQuestionFreeTextAnswer(projected, answer)
expect(structuredQuestionResponseTarget(response, current)).toEqual({
itemId: 'item-1',
expectedRevision: 3,
answer: { questionId: 'q1', optionIds: [], other: answer }
})
expect(structuredQuestionResponseTarget(response, prompt())).toBeNull()
}
expect(
structuredQuestionResponseTarget(formatQuestionFreeTextAnswer(projected, ''), {
...current,
revision: 4
})
).toBeNull()
})

it('keeps legacy trimming for ordinary free-text answers', () => {
const current = prompt()
const projected = projectStructuredQuestion(current)!
expect(
structuredQuestionResponseTarget(
formatQuestionFreeTextAnswer(projected, ' draft '),
current
)
).toMatchObject({ answer: { other: 'draft' } })
expect(structuredQuestionResponseTarget('', current)).toBeNull()
})
})
Loading
Loading