Skip to content

feat(native): complete TV-SIDECHAT and TV-LINEAGE parity - #365

Merged
rynfar merged 4 commits into
nativefrom
nw/243-tv-sidechat-lineage
Nov 14, 2026
Merged

rynfar merged 4 commits into
nativefrom
nw/243-tv-sidechat-lineage

Conversation

@rynfar

@rynfar rynfar commented Nov 14, 2026 •

Copy link
Copy Markdown
Owner

Native client side chat and thread lineage were missing capability checks, post-fork removal recovery, unlisted parent/child title fetching, workflow phase/elapsed parity, linked-environment lineage rows, live session detach, and legacy ultracode/selectable-model/Claude-version badge handling present on web. This brings TV-SIDECHAT and TV-LINEAGE to parity with web and marks both rows done in apps/native/parity/LEDGER.md.

Ref #243 · Closes #287 · Closes #283 · Ref #296

Changes

  • TV-SIDECHAT (Closes #287, upstream pingdotgg/t3code#31114):
    • Omit forced runtimeMode override on first_message_command.
    • Gate side-chat offering, open (fork_command), failed-start discard, closed cleanup (delete_command), bring-back, delete, and post mutations on orchestration:operate scope (AppState::can_operate_threads, side_chat::Parent::can_operate, side_chat::offered, bring_back_blocked_reason).
    • Guard continue_side_chat_start against side-chat threads removed after fork creation ("The side chat is no longer available." + discard cleanup).
  • TV-LINEAGE (Closes #283, upstream pingdotgg/t3code#29000):
    • Exclude omitted family mounts and snapshot.archived_threads from listed_set before computing unlisted_title_ids, filter hidden threads and hidden unloaded relations, and prefer getThreadTitles resolved titles over shell node titles for rows and merge targets.
    • Fetch unlisted parent/child titles via orchestration.getThreadTitles in ThreadTitlesFeed keyed by (connection, unlisted_ids, removed_at), clearing active_key alongside in_flight on failure with bounded backoff retry (allow_retry() on AppEvent), and forwarding this.card_open from DetailsView so closed details cards do not fire RPCs.
    • Preserve groups.related, groups.active, and groups.previous ("Previous agents", collapsed by default), update workflow edge status before group_relationships, render Lineage · N running / Side chats · N running headings, and keep Lineage visible (has_lineage() / lineage_len()) when only unlinked running subagents, delegated_from, remote_subagents, or can_detach && !side_chats.is_empty() exist.
    • Add AgentTiming and LiveAgentElapsed (AgentElapsed.tsx full 1m 05s and compact 1m/1.5h/12h formats) on subagent rows (deriving non-workflow timing from agent.current(node)), workflow member rows, and workflow phase headers; wrap Entity<LiveAgentElapsed> inside window.use_keyed_state with deferred refresh so 1s ticks redraw only the timer view without notifying DetailsView mid-render; auto-open workflow phases on Pending -> Running via Option<bool> state; show Failed destructive labels, {settled}/{total} agent(s) counts, phase elapsed, and "No agents yet" empty workflow placeholders.
    • Add DelegatedFromRow, RemoteSubagentRow, linked-environment target navigation (open_linked_thread), and "More thread actions" -> "Disconnect agent session" (can_detach_provider_session / detach_session_commands, gated on orchestration:operate).
    • Gate merge/stop/child-approval/detach actions behind orchestration:operate.
  • Subagent & Child Traits (Ref #296, upstream pingdotgg/t3code#27034 — keeping #296 open for CO-TRAITS):
    • Handle legacy ultracode -> xhigh effort fallback and resolved-slug matching, resolve_selectable_model fallback, and collapse_claude_minor_version badge collapsing in ComposerLineage::read_bar.

Verification (6411dd79bd)

  • cargo test -p t3-core -p t3-client: t3-core 1343 unit + 8 conformance passed; t3-client 108 unit passed.
  • cargo test -p t3-native --features snapshot -- side_chat:: lineage:: thread_details:: --test-threads=1: 12 passed, 0 failed (172 filtered out).
  • cargo clippy --workspace --all-targets -- -D warnings: passed (0 errors/warnings).
  • cargo build -p t3-native --bin t3-native --features snapshot: passed.
  • node --test apps/native/parity/sync.test.ts: 42/42 passed.
  • Note: vp fmt --check and pnpm-backed conformance --check / gen-theme --check were not run directly inside this worktree (vp i skipped); theme inputs and conformance fixtures were untouched (t3-core conformance suite passed 8/8).

Snapshots (1440x900)

Surface Dark Light
Thread Details + Lineage (Previous agents expanded, AgentElapsed) Dark Light
Open SideChatPane right-panel tab Dark Light
ComposerLineage (ProviderSubagentBar) Dark Light

Model: Gemini 3.1 Pro (Antigravity)

Bring TV-SIDECHAT and TV-LINEAGE to parity with web and mark both rows done in LEDGER.md (Ref #243).

- Side chat (Closes #287, upstream `pingdotgg#31114`): stop forcing runtimeMode on initial side-chat message commands, reject bring-back/delete/post when connection lacks orchestration:operate scope, and guard post-fork send against removed side-chat threads with discard cleanup.
- Lineage relationships & unlisted titles (Closes #283, upstream `pingdotgg#29000`): fetch unlisted parent/child titles via orchestration.getThreadTitles keyed on (connection, unlisted_ids, removed_at), prune deleted forks after settlement, preserve fresh titles, and gate merge/stop/child-approval actions behind orchestration:operate.
- Subagent/child traits parity (Ref #296, upstream `pingdotgg#27034`): handle legacy ultracode effort fallback/matching, selectable model slug fallback, and Claude minor-version badge collapsing in ComposerLineage without closing #296 (CO-TRAITS remains open).

Implemented with Gemini / Antigravity.
Fix unlisted/archived title fetch and resolved precedence, gate side-chat mutations behind orchestration:operate, clear ThreadTitlesFeed active_key on error with backoff and respect closed DetailsView cards, and restore related/active/previous lineage groups with workflow expansion and running counts.

Model: Gemini 3.1 Pro (Antigravity)
… parity

Keep the Lineage section visible for unlinked running subagents, remote subagents, delegated parents, and live session detach actions; add auto-opening workflow phases with counts, failed labels, elapsed timers, and empty placeholders; render AgentElapsed on subagent and member rows; and wire linked-environment navigation and provider-session detach.

Model: Gemini 3.1 Pro (Antigravity)
Derive non-workflow subagent elapsed timing from agent.current(node) so resumed child threads update timing, and store Entity<LiveAgentElapsed> inside window.use_keyed_state with deferred refresh instead of synchronous mid-render cx.notify().

Model: Gemini 3.1 Pro (Antigravity)
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.

1 participant