Repository navigation
Connect legacy agents from DMs and channel mentions - #2423
Conversation
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3b2d135e4c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (const type of types) { | ||
| if (type.remote) continue; | ||
| const config = type.importShared?.({ ...saved, model: saved.model ?? "" }); |
There was a problem hiding this comment.
Derive settings from the identity source actually taken
The draft is derived from the harness copy returned by list, but OldStores::take explicitly falls back to an Installed or Development copy when that harness credential is gone. If those copies have different runtimes or saved model/provider settings, Connect imports the fallback identity while staging the stale harness copy's type and config. Return or revalidate the connection metadata from the copy actually taken before saving the reviewed configuration.
Useful? React with 👍 / 👎.
Wait for complete agent-choice evidence before offering local import. Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5776781149
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const staged = { ...defaults(pubkey, kind), config }; | ||
| const text = recordText(staged); | ||
| const kept = await this.storage.add(recordKey(pubkey), text); |
There was a problem hiding this comment.
Remove staged settings when identity import fails
When native.port rejects before installing the identity—for example because the legacy credential is unavailable—this newly added record remains in storage. An unchanged retry happens to pass because its serialized text matches, but changing the harness, model, or provider produces different text and is rejected as “already has saved setup,” so the inline recovery flow cannot use the revised settings. Remove the still-matching staged record when the native import fails before installation, while retaining it for failures after installation.
AGENTS.md reference: AGENTS.md:L140-L143
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8ad0cfbe79
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| channel?.channelType === "dm" && | ||
| !channel.archived && | ||
| channel.viewerRole !== "guest" && |
There was a problem hiding this comment.
Require fresh writable DM membership before offering import
When a DM is restored from cached membership or otherwise marked readOnly, this peer test still accepts its stale members and viewerRole; ChannelSummary.cached explicitly defines that roster as display-only pending relay confirmation. Opening such a DM can therefore import the legacy identity even though the viewer may no longer have a writable two-party conversation, leaving no usable composer for the promised continuation. Gate this branch on !channel.cached && !channel.readOnly, as the stream/forum branch already does.
AGENTS.md reference: AGENTS.md:L101-L104
Useful? React with 👍 / 👎.
| if (made.strict) | ||
| throw new Error( | ||
| "The identity was imported, but its settings could not be saved. Open Agents → Settings to finish setup.", | ||
| { cause: error }, | ||
| ); |
There was a problem hiding this comment.
Refresh imports before reporting a settings failure
When native.port succeeds but applying carried settings makes this.change fail, this strict branch throws before the this.refresh() below. The identity is installed natively but remains absent from the service inventory, while the error directs the user to Settings; the card instead returns to retry and Settings cannot show the agent until an unrelated refresh or restart occurs. Refresh the native list in this failure path before reporting the incomplete import.
AGENTS.md reference: AGENTS.md:L140-L143
Useful? React with 👍 / 👎.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Carl, an automated reviewer, commenting via Wes's GitHub account. Reviewed by the Royal Court (UI, persistence, security/identity lanes) at 8ad0cfbe7.
Verdict: not safe to merge yet. The identity and security boundary holds: admission requires the exact local key, signed owner evidence and complete inventory. Other authors and delegated signers can't trigger it. The native projection exports only runtime/model/provider/effort, never commands or env. Follow-ups go only to [peer]. The blocker is in failure recovery: when saving settings fails after install, the imported agent can end up running unreviewed defaults, which is exactly what the staging step was added to prevent.
Merge criteria
- Fix the blocking thread at
service.ts:3301, and cover it with a service-level journey test throughport({config}). - Address or explicitly decline the should-fix threads: staging race/retry, the card hiding its own error, Send again wording, and effort controls leaking into existing pickers plus the Claude effort reset.
- Exercise one real legacy DM import and one channel import + Send again in the native app, as the PR notes these are unverified.
Validation: locally at 8ad0cfbe7: tsc clean; the related Vitest files (agents, ModelPicker, service, claude-code/codex/goose tabs, bundled agents) pass, 1025 tests. The persistence defects were reproduced with targeted probes through the existing service fixture and are not committed. Hosted CI beyond DCO had not run at review time. Native import was not exercised.
| const staged = { ...defaults(pubkey, kind), config }; | ||
| const text = recordText(staged); | ||
| const kept = await this.storage.add(recordKey(pubkey), text); | ||
| if (kept !== text) |
There was a problem hiding this comment.
🤖 Should-fix. When native.port fails, the staged record stays behind. The card returns to idle and offers retry. A retry with the same choices succeeds, but changing the harness or model first is rejected here with "already has saved setup", before the native import even runs. The user can recover through Agents → Import, but the inline flow can't. Fix: when the staged text is this flow's own unfinished draft for an identity that isn't installed, let a retry replace it, or remove it on failure. Keep the guard for settings that some other path wrote.
There was a problem hiding this comment.
🤖 Leaving this nonblocking suggestion open in this blocking-feedback repair. I prototyped deleting the failed draft, but independent review caught that AgentStore.get reads a process-local cache: another app may already have changed or started using the shared record. Existing storage has atomic add-if-absent but no conditional replacement/deletion ownership. The repair preserves the staged record and covers preservation through later refresh. Same-choice retry and Agents → Import/Settings remain available; safe editable retry needs a separate shared-storage ownership change.
| </> | ||
| ); | ||
| } | ||
| if (!peer || !isAgent(peer)) return null; |
There was a problem hiding this comment.
🤖 Optional: the card has no dismiss. It stays at the end of every DM, and every channel where you mentioned an owned, offline legacy agent, and it hides .emptyConversation. Someone who keeps running that agent in old Buzz can't remove it. Product call for the author/Wes.
| {renderReplies(undefined)} | ||
| </ol> | ||
| {!preview && !positioning && composerRoot && ( | ||
| <AgentConnectionSetup |
There was a problem hiding this comment.
🤖 Optional: thread rows include the root, so a root message that mentions the agent produces two independent cards, this one and ChannelTimeline.tsx:1588. Their state is separate, and connecting from both is the path to the service.ts:3071 race.
| config: draft.config, | ||
| scope, | ||
| }); | ||
| if (result.notes.length) setError(result.notes.join(" ")); |
There was a problem hiding this comment.
🤖 Optional: informational result.notes from a successful import appear in the red role="alert" error style. Separately, if choices.complete or presence flips briefly while the user is editing (L198), the form unmounts and their draft is lost.
Serialize connection attempts, retain recovery feedback, and clarify the targeted follow-up action. Remove unrelated creation effort controls and reset incompatible saved Claude effort on model changes. Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Retain staged settings for a later successful native listing without exposing uninstalled drafts to orphan cleanup. Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a3a78f8545
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| saved.effort && | ||
| typeof config === "object" && | ||
| config !== null && | ||
| "effort" in config | ||
| ? { ...config, effort: saved.effort } |
There was a problem hiding this comment.
Validate saved effort before importing it
When a legacy Claude agent has a saved effort that its saved model no longer supports—for example medium on a current Haiku model—this copies the value into the import without checking the current catalog, while the connection form deliberately hides effort controls. Claude's runtime then refuses ordinary turns using that synced effort until the user repairs it in Settings. Preserve the effort only when the selected type/model confirms it is compatible, or clear it during import.
Useful? React with 👍 / 👎.
Retain both Claude effort compatibility and review sign-in regression tests. Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
loganj
left a comment
There was a problem hiding this comment.
🤖 Larry: an independent adversarial review of a25d072c7. Source review only: I did not run a real legacy import or the native channel follow-up (the PR body lists both as unverified too).
Verdict: approve. The identity gate (exact local key, signed owner evidence, offline, not managed or messageable, complete agent-choice evidence), the staged-record recovery after native install, the reclaim guard and the [peer]-only follow-up all read correctly. connection.rs exports only bounded selectors, never commands, arguments or environment values.
CI: the one red check, JavaScript (1/4), fails src/features/agent-harness/kit.test.ts > refuses a mention from anyone else. That test fails the same way on the last 3 failed main CI runs, and this PR does not touch it. It is not from this change.
Two open Codex findings still apply at this head. Both are cheap; please fix or answer them before merge:
- question (
AgentConnectionSetup.tsx:28, Codex P2 "Validate saved effort before importing it"):connectionDraftcopiessaved.effortwithout checking it against the selected model, and the card hides effort, so the user cannot see or fix it before Connect. Clear it when the model does not list it, as the ClaudeCreateModelchange already does when the model changes. - advice (
AgentConnectionSetup.tsx:82, Codex P2 "Require fresh writable DM membership"): the DM branch still acceptscachedandreadOnlychannels. The stream/forum branch already checks!channel.cached && !channel.readOnly; use the same check here.
One new finding is inline.
| }} | ||
| /> | ||
| )} | ||
| {!groupByFamily && onEffortChange && efforts && efforts.length > 1 && ( |
There was a problem hiding this comment.
🤖 advice (in scope, cheap): after b92cf17 removed the Claude and Codex effort callers, production code does not reach this effort Select. The only ModelPicker hosts that pass onEffortChange (claude-code tabs.tsx:437, codex tabs.tsx:510, goose tabs.tsx:1133) all set groupByFamily, and no CreateModelChoices host passes onEffortChange. Only ModelPicker.test.tsx uses it. Please remove it with its test, the effort/effortLabel/onEffortChange props added to CreateModelChoices.tsx:44, and the new wrapper classes at L247. That wrapper change turns every ModelPicker host into a wrapping flex row, and it exists only to lay out this unused control.
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ce517c35b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .or_else(|| definition.and_then(|row| row["runtime"].as_str())) | ||
| .unwrap_or("buzz-agent") | ||
| }; | ||
| let runtime = if record["backend"]["type"].as_str() == Some("provider") { |
There was a problem hiding this comment.
Read the hosted marker from harness imports
When a legacy harness record represents a provider-backed agent, the persisted schema puts this marker under imported.record.backend (as demonstrated by crates/agent-controller/src/legacy/tests.rs:31-32), but this branch checks only the top-level record.backend. Such an agent is therefore classified as its harness command or custom instead of hosted; when the completed agentChoices snapshot no longer lists the stale provider agent as messageable, the connection card can offer a local import and, if its credential remains, transfer it into a local harness despite the hosted-agent exclusion. Read the backend from the harness record's imported payload. The fresh evidence beyond the earlier hosted-choice finding is this nested persisted marker, which bypasses the new completeness guard.
Useful? React with 👍 / 👎.
…-nip-fi * origin/main: feat(inbox): preview recent Inbox activity when hovering the sidebar row (#2347) Add collapsible Solo and Team sidebar sections (#2296) fix(codex): open long Codex transcripts a page of items at a time (#2259) Keep Solo model and effort choices per chat (#2342) feat(sidebar): smooth channel reordering with bounded motion (#2108) Connect legacy agents from DMs and channel mentions (#2423) fix: exclude muted channels from sidebar unread scroll indicators (#2335) fix(claude-code): open long Claude transcripts a page at a time (#2428) feat(solo): share chats as view only (#2375) # Conflicts: # src/app/shell/PrimarySidebar.tsx
…-clone-auth-ab8b97 * origin/main: (38 commits) feat(identity): decide a missing backup choice from community membership (block#2378) Offer Builderlab decisions in FI builds (block#2227) feat(inbox): preview recent Inbox activity when hovering the sidebar row (block#2347) Add collapsible Solo and Team sidebar sections (block#2296) fix(codex): open long Codex transcripts a page of items at a time (block#2259) Keep Solo model and effort choices per chat (block#2342) feat(sidebar): smooth channel reordering with bounded motion (block#2108) Connect legacy agents from DMs and channel mentions (block#2423) fix: exclude muted channels from sidebar unread scroll indicators (block#2335) fix(claude-code): open long Claude transcripts a page at a time (block#2428) feat(solo): share chats as view only (block#2375) fix(inbox): show Solo responses under All, read live replies in the open conversation, describe toolbar badges (block#2275) AIDA-2434: Show saved teams in mentions (block#2339) AIDA-2455: Restore channel scrollbar dragging beside threads (block#2436) feat(agent-protection): show the owner why a protection provider denied input (block#2105) fix(search): show slow lookups beside their section headings (block#2442) Align Bestie DM layout and unread state; speed up thinking shimmer (block#2418) Send Claude, Pi and Goose history as exact records (block#2088) fix(agent-activity): align the stopped note and show it after the agent's reply (block#2441) fix(agents): stop orphaned Attention commands and prevent duplicate runs (block#2448) ... Signed-off-by: damienrj <damien@squareup.com>
* origin/main: (38 commits) fix(browser): load scheme-less address input over https, falling back to http (#2467) fix(identity): stop one-click key unlinks and show the linked backed-up key (#2486) fix(test): observe coordination transition events (#2297) fix(profiles): keep the next view's profile reads through a shrink (#2395) fix(channels): show Add and Send message errors above the Manage members list (#2421) fix(threads): keep reply hooks off agent activity bubbles (#2422) fix(channels): offer only Copy link in a not-joined preview's sidebar actions (#2425) test: scope row menu placement checks to active section rows (#2493) feat(relay): detach channel windows to a point in history (#2042) feat(identity): decide a missing backup choice from community membership (#2378) Offer Builderlab decisions in FI builds (#2227) feat(inbox): preview recent Inbox activity when hovering the sidebar row (#2347) Add collapsible Solo and Team sidebar sections (#2296) fix(codex): open long Codex transcripts a page of items at a time (#2259) Keep Solo model and effort choices per chat (#2342) feat(sidebar): smooth channel reordering with bounded motion (#2108) Connect legacy agents from DMs and channel mentions (#2423) fix: exclude muted channels from sidebar unread scroll indicators (#2335) fix(claude-code): open long Claude transcripts a page at a time (#2428) feat(solo): share chats as view only (#2375) ...
…r-load-perf * origin/main: (31 commits) test: fix invitation and coordination checks on main (#2517) perf(search): name searched people from the profile search response (#2353) Use the merge queue for pull requests that require it (#2452) fix(browser): load scheme-less address input over https, falling back to http (#2467) fix(identity): stop one-click key unlinks and show the linked backed-up key (#2486) fix(test): observe coordination transition events (#2297) fix(profiles): keep the next view's profile reads through a shrink (#2395) fix(channels): show Add and Send message errors above the Manage members list (#2421) fix(threads): keep reply hooks off agent activity bubbles (#2422) fix(channels): offer only Copy link in a not-joined preview's sidebar actions (#2425) test: scope row menu placement checks to active section rows (#2493) feat(relay): detach channel windows to a point in history (#2042) feat(identity): decide a missing backup choice from community membership (#2378) Offer Builderlab decisions in FI builds (#2227) feat(inbox): preview recent Inbox activity when hovering the sidebar row (#2347) Add collapsible Solo and Team sidebar sections (#2296) fix(codex): open long Codex transcripts a page of items at a time (#2259) Keep Solo model and effort choices per chat (#2342) feat(sidebar): smooth channel reordering with bounded motion (#2108) Connect legacy agents from DMs and channel mentions (#2423) ...
* origin/main: (31 commits) test: fix invitation and coordination checks on main (#2517) perf(search): name searched people from the profile search response (#2353) Use the merge queue for pull requests that require it (#2452) fix(browser): load scheme-less address input over https, falling back to http (#2467) fix(identity): stop one-click key unlinks and show the linked backed-up key (#2486) fix(test): observe coordination transition events (#2297) fix(profiles): keep the next view's profile reads through a shrink (#2395) fix(channels): show Add and Send message errors above the Manage members list (#2421) fix(threads): keep reply hooks off agent activity bubbles (#2422) fix(channels): offer only Copy link in a not-joined preview's sidebar actions (#2425) test: scope row menu placement checks to active section rows (#2493) feat(relay): detach channel windows to a point in history (#2042) feat(identity): decide a missing backup choice from community membership (#2378) Offer Builderlab decisions in FI builds (#2227) feat(inbox): preview recent Inbox activity when hovering the sidebar row (#2347) Add collapsible Solo and Team sidebar sections (#2296) fix(codex): open long Codex transcripts a page of items at a time (#2259) Keep Solo model and effort choices per chat (#2342) feat(sidebar): smooth channel reordering with bounded motion (#2108) Connect legacy agents from DMs and channel mentions (#2423) ... Signed-off-by: Michael Neale <michael.neale@gmail.com>
**Category:** fix **User Impact:** In an agent's settings, the Model picker sits on the right edge of its row and shows the full model name again, lined up with Harness and Thinking. **Problem:** Since #2423 (`844368d26`), the Model trigger in agent settings floats mid-row and truncates the model name (for example, "G. · Default"), while the rows around it keep their triggers on the right. **Solution:** That change wrapped every `ModelPicker` in a flex container so compact pickers could share a line with the effort control. In a Settings group that wrapper shrinks the preference row to fit its content. Only compact pickers use the flex wrapper now; Settings rows stack at full width, as they did before. Originating thread: [Buzz](buzz://message?channel=7c37f701-cfda-46b6-b57d-3249fabc0694&id=cf2b7d5df31a6398ba629a87c3f6f83c93e6f864cf69334745bb972a29be62bc). <details> <summary>File changes</summary> **src/features/agents/ModelPicker.tsx** Apply the flex wrapper only to compact pickers, so a preference row keeps the full width of its Settings group. **tests/browser/model-picker-row.fixture.tsx, tests/browser/model-picker-row.html** Render the real `ModelPicker` above a Thinking `Select` inside a `SettingsGroup`, matching the harness settings layout. **tests/browser/model-picker-row.spec.mjs** Assert that the Model trigger ends at its row's right edge, aligned with Thinking and not truncated. jsdom can't measure layout, so this runs in the browser suite. Without the fix it fails in Chromium and WebKit (the row measures 257px instead of 503px). </details> ## Reproduction steps 1. Open an agent that uses the Codex harness and go to its Identity settings. 2. Look at the Model row: its trigger should end on the right edge, in line with Harness and Thinking, and show the full model name. ## Screenshots These come from the layout test fixture, which renders the real `ModelPicker` and `Select` in a Settings group. They are not full-app captures. | | Light | Dark | | --- | --- | --- | | Before |  |  | | After |  |  | 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Princess Donut <0366ccd5ee09c2779a9d6bd6683daa17c16a508a51f6a7e7314018dab8fdc49b@feedback.communities.buzz.xyz>
Old-agent DMs and channel mentions can look usable after moving to the new app even though the agent has not been imported. Add an inline Connect [agent] card at the end of eligible conversations, using the agent’s squircle avatar, enabled Harness choices and compatible saved model/provider settings. Effort stays out of this flow; compatible saved values are preserved.
The import retains the identity and conversation, saves reviewed settings before installation, and uses existing harness setup dialogs. Detection requires the exact local identity and signed ownership evidence; managed or online agents are excluded.
Channel/thread mentions from your own delivered messages reuse these checks and show one local card per agent. After import, Ask [agent name] to respond explicitly queues a follow-up addressed only to that agent in the original message’s thread; no request is automatically replayed.
Reviewed settings are retained in memory after native installation, including delayed recovery when installation reports failure and native listing temporarily fails. Connect attempts for one identity are serialized. Recovery errors stay visible in a host-owned toast after the card disappears, and the follow-up action previews its exact message. Claude model changes clear incompatible saved effort; unrelated creation effort controls were removed.
Validation: complete agent-service, connection UI, Claude and Codex test files pass; TypeScript and the synthetic channel interaction/resize check pass. Required pre-push checks passed at
a3a78f854: TypeScript/related tests, design-system checks and Rust Clippy. The preceding head passed hosted CI; fresh CI for this repair is pending. No automated browser journeys were added; regression coverage is colocated.Remaining: real legacy import and native channel import/follow-up remain unverified. Wes's nonblocking changed-settings retry suggestion remains open: failed imports preserve shared staged settings, so changing the setup before retry requires Agents → Import/Settings. Safe replacement requires atomic ownership of shared state; cached comparisons cannot safely delete another app's settings. The separate P2 and optional suggestions remain open.
Light/dark snapshots below use synthetic data and the real setup component; they are UI previews, not proof of a completed import.
After connecting, sending remains explicit (simulated import):