Skip to content

P401: discover session owners through a screen-free scope - #1115

Merged
trissim merged 59 commits into
mainfrom
fix/p401-session-scope
Oct 23, 2026
Merged

trissim merged 59 commits into
mainfrom
fix/p401-session-scope

Conversation

@trissim

@trissim trissim commented Oct 21, 2026 •

Copy link
Copy Markdown

Session navigation, transcript reads and launch state currently depend on concrete screens and optional agent data. P401 puts those responsibilities on SessionScope, typed launch bindings and transcript scopes; mounted views implement the capabilities, and consumers use them directly. Authored versus thread-following titles are distinct SessionName members, and Flash owns feedback without a forwarding method.

Merged Toad main b971751330 into the branch. Core now uses branch = "main"; pyproject.toml and uv.lock exactly match main. Removed the old Core-head pin, obsolete workflow/documentation changes, and the old qualification narrative.

Conflict resolutions (all 53 files):

Files Resolution
pyproject.toml, uv.lock Keep main, including its Core dependency and lock.
src/toad/acp/{agent_session,comms_updates,transcript_reader}.py Keep current Core service/owner APIs; retain P401's typed read results and transcript scopes. No deleted send or private-bootstrap API returns.
src/toad/{comms_root,conversation_kind,transcript_preparation,transcript_state}.py, src/toad/widgets/{session_details,session_tabs}.py Keep main's owners; discard superseded branch implementations.
src/toad/{conversation_comms_handlers,conversation_submission,delivery_failure_view}.py, src/toad/widgets/prompt.py Keep main's committed-send/failure and draft-restoration behavior; expose feedback through the existing Flash widget. P401 clears submitted text before publishing the submission.
src/toad/{navigation_target,target_commands,session_entry,session_navigation,session_observation,session_presentation,session_tracker}.py, src/toad/screens/comms.py, src/toad/widgets/{channel_activity,conversation}.py Retain P401's session capabilities, typed connection/launch states, entry-owned SessionDetails and title members. Preserve main's lifecycle changes, stable incarnation targets and single transcript-history owner.
src/toad/transcript_publication.py, src/toad/widgets/{comms_chat,transcript_history,wire_history}.py, src/toad/wire_history.py Keep main's ConversationHistory renderer, source replacement and coverage contracts; query SessionScope instead of a concrete screen.
tests/native/{test_native_client_requests,test_native_goal_bar}.py, tests/support/{native,native_steps,routes}.py, tests/textual/{test_conversation_kind,test_conversation_value,test_hidden_session_retirement,test_historical_notification_source,test_key_bursts_move_focus_to_the_editor,test_plan_display,test_prompt_completion}.py Keep current main fixtures/APIs, adapting only capability imports, typed launch bindings and connection names where needed.
tests/native/test_thread_open_during_slow_load.py, tests/support/{agents,observed_app,workspace}.py, tests/textual/{test_channel_updates_and_returns,test_initial_prompt_handoff}.py Preserve real provider/UI fixtures and current launch-root/event setup; retain P401's explicit binding. Remove retired bootstrap calls and the self-patching construction case.
tests/support/failed_close_app.py, tests/textual/{test_close_tab,test_default_route_flip,test_interrupted_send,test_stale_route_writes}.py Delete fake failure/close/send/read interception. Keep the two real route-change cases in stale_route_writes.

Deleted 17 tests that patched or intercepted project behavior, including the conflict-side cases above and the affected binding-change, queued-send, navigation-read, shutdown and transcript-fencing cases. Removed dead helpers/imports; provider protocol substitutes and unrelated main database tests remain.

Source relationships were checked with AST inventories and semantic reads of the shared owners and consumers. Interpreter-imported all 50 changed production modules and 52 surviving changed test/support modules against Core main 051fe6b617; all imported. The concrete screens and conversation classes remain concrete. No pytest run.

Assumed:

  • Current Toad main owns rendering, stable thread targets, committed sends and resource teardown where older P401 code differs.
  • Core tracks main; no separate P434 head is required. The Core symbols used by the production change exist on current main.
  • Tests that replace our implementation are removed; real UI/protocol fixtures remain.

Review correction: SessionScope now answers matches_launch directly (false by default, native binding override). Deleted WorkspaceSessions.native_origins and its own-class isinstance filter; launch lookup uses the existing views. Migrated the three test assertions that referred to the deleted property. All three changed production modules import with Core main and the requested db2a3b39e runtime. One isinstance call deleted, none added; raw AST total is 109, equal to main (110 at the reviewed head).

@trissim
trissim marked this pull request as ready for review October 21, 2026 12:30
Copilot AI balanced review requested due to automatic review settings October 21, 2026 12:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@trissim
trissim marked this pull request as draft October 21, 2026 13:27
Keep main's retained transcript renderer, source replacement, stable thread targets and committed-send owners. Apply P401's launch binding and screen-independent SessionScope to their consumers. Restore Core's main dependency and matching lock; remove the retired qualification workflow changes and tests that intercept project methods.
@trissim
trissim marked this pull request as ready for review October 23, 2026 10:37
# Conflicts:
#	src/toad/acp/comms_updates.py
#	src/toad/widgets/conversation.py
…rors

Every parameter the PR added in src/toad now carries the type its
callers pass: SessionScope's abstract methods and both overrides
(CoordinationAccess, Conversation, TranscriptCursor | None,
TranscriptPublicationState, UserInputSubmitted, type[DmConversation],
the presented callback), with **bounds spelled out as the four keywords
acp/transcript_reader.py passes. rows_in takes SidebarGroup[CommsRow];
workspace visible_target/target_for_mode take root: Path | None and
identity: str.

NoTarget's menu_context/show_menu overrides are deleted: NoTarget.rows_in
returns (), so no row ever carries it, and both are reached only through
a row's target.

cli.get_agent_binding no longer turns AgentReadError into NoAgent(). Its
only caller is `toad run -a NAME`; a user who asked for an agent whose
definitions cannot be read now sees the read error instead of a session
silently launched without the agent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants