## Summary
- move **Channel templates** from Communities to Personal settings
- always expose the template picker in New Channel, using **None** as
the no-template value
- create a channel template directly from the picker and select it on
return
- preview the selected template's current visibility, canvas, agents,
and teams
- order the channel-creation controls as **Type / Visibility /
Template** and mark Template **Optional**
- cover populated and empty libraries, inline creation, selection,
visibility overrides, mixed agent/team inventory, field order, optional
labeling, and settings navigation in Playwright
## Validation
Validated at desktop-only tip `76442270c88aa1d533ddca5de9f87cd615183919`
with a clean worktree:
- focused channel-template Playwright: 2/2 passed
- Type / Visibility / Template ordering and muted Optional treatment
visually inspected in the replacement screenshot
- `git diff --check origin/main...HEAD` passed
- PR diff contains exactly nine Desktop files and no Mobile files
The pre-push hook was bypassed only for the corrected history push
because the inherited Mobile test `keeps follow mode off while a tall
newest message stays visible` passes in Linux CI but fails on macOS
because its offscreen-child mounting assertion is platform-sensitive. No
Mobile code or tests are changed by this PR.
## Screenshot

Originating Buzz channel: `efba7343-e147-48b7-a2aa-15a5f04abc57`
---------
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
## Why
Hack-day feedback exposed a dangerous mismatch between the UI and the
underlying access model. The `Anyone` respond-to mode appeared as a
neutral dropdown choice, while a Buzz agent may act with the files,
accounts, and tools available on the machine where it runs.
People reasonably read this as sharing a bot in a channel. The current
UI did not explain that it can also share the agent's available access.
## What
- Reframes `respond-to` as **agent access** in user-facing UI.
- Uses plain audience labels: **Only me**, **Anyone**, and **Selected
people**.
- Warns for **both** sharing modes, not just `Anyone` — `Selected
people` also hands host access to someone other than the owner, so only
the audience phrase differs:
> Anyone can use this agent to access your computer, including files,
accounts, and connected tools.
> Selected people can use this agent to access your computer, including
files, accounts, and connected tools.
- Names the machine the agent actually runs on. A provider-backed
(remote) agent reads:
> Anyone can use this agent to access the server it runs on, including
any accounts and tools available there.
The remote wording deliberately omits the owner's files — those aren't
theirs to describe on a host they don't own.
- Places the warning below the selector for `Anyone`, but **after** the
people picker for `Selected people`, so it never sits between the user
and the selection they came to make.
- Removes Nostr, harness, pubkey, and `!shutdown` jargon from the
primary decision copy. Direct pubkey entry remains available as an
advanced path.
- Replaces the green open-access avatar dot with an amber warning marker
and accessible text. Selected access uses a separate blue status.
- Aligns the sidebar action and profile field with the same language.
- Records the shared-field disclosure contract in
`desktop/src/features/agents/AGENTS.md` so future surfaces do not
silently omit it.
## Design decisions
**Persistent inline warning, not a confirmation modal.** The setting
does not autosave; the consequence remains visible beside the selection
until the person chooses **Save access**. This gives the information
before commitment without adding a dismiss-and-confirm ritual that would
repeat in every create/edit surface.
**An unknown run location falls back to the local wording.** It does not
hedge with "computer or server". A remote host requires an installed
`buzz-backend-*` provider, and without one `WhereToRunSection` never
renders — so "server" would name a concept the owner has never been
shown. When it *is* remote, they picked that host from the selector
themselves. Surfaces never synthesize a run location they don't have.
**One resolution site, published through context.** `AgentDialog`
resolves the run location (`runLocationForBackend` from
`ManagedAgent.backend`, `runLocationForRunOn` from the create flow's
`WhereToRunDraft`) and publishes it via `AgentRunLocationContext`. It is
not threaded as a prop through `AgentDefinitionDialog` (1047 lines) or
`AgentInstanceEditDialog` (1228 lines) — neither uses the value, and
both are already over the file-size ceiling. Surfaces outside that tree
(`EditRespondToDialog`) pass the prop directly.
The copy follows the writing system's guidance for high-sensitivity
decisions: lead with the material consequence, use plain actor/action
language, keep helper text adjacent and persistent, and never rely on
color alone.
## Scope
Desktop only. The web and mobile clients do not currently expose this
setting. No protocol, gate, runtime, persistence, or backend behavior
changes.
This does not add team-scoped remote agents. It makes the current
local-or-remote access model honest while that product work remains
separate.
## Validation
- `pnpm exec biome check` and `pnpm exec tsc --noEmit` — clean
- `lib/agentAccessWarning.test.mjs` (8/8) — every mode × run-location
copy variant, both resolvers, unknown-reads-as-local, blank `runOn` is
not a provider
- `ui/respondToFieldContract.test.mjs` (8/8) — plain labels, both
warning positions, source-order guard that the `allowlist` warning
follows the picker, helper-not-inline-copy guard
- `agent-access-warning.spec.ts` (3/3) — native local, provider-backed
remote (asserts the server sentence and *not* "your computer"),
persona-backed edit; includes a bounding-box check that the `Selected
people` warning renders below the picker
---------
Signed-off-by: David Hamilton <daveh@squareup.com>
Signed-off-by: Clay Delk <clay.delk@gmail.com>
Co-authored-by: Clay Delk <clay.delk@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
## Why
The Inbox mixed overlapping feed categories with personal work queues,
so **All** was not actually comprehensive and several filters did not
make it clear why an item appeared. Threads and DMs could produce one
row per event instead of one row per conversation, drafts were hidden
until selected, and reminders appeared through multiple competing
presentations.
This refactor makes the **Inbox** a focused, conversation-oriented place
to catch up on work relevant to you. It is intentionally not a mirror of
every unread event in every channel.
## What changed
- Keep the destination named **Inbox** and use the standard Lucide bell
icon.
- Refocus **All** on DMs, mentions, thread replies, needs-action items,
replies from agents the user owns or controls, due reminders, and active
drafts.
- Exclude generic top-level channel traffic and updates from agents the
user does not own or control.
- Group each thread or DM into one row, sorted by latest activity.
- Resume an unread conversation at its oldest unread message while
opening the full thread or DM in the detail pane.
- Reuse the existing **New** divider at the unread boundary.
- Make the detail title a direct link to the canonical conversation.
- Give Reminders and Drafts the same list/detail interaction and
location metadata as conversation rows.
- Separate Reminders and Drafts from message filters with a subtle
divider, without adding another labeled section.
- Put reminder and draft counts beside their corresponding filter labels
instead of on the generic filter button.
- Preserve the selected conversation when switching filters if it
remains valid; otherwise select a valid replacement without flashing
stale detail.
- Use filter-specific empty states and rename the options toggle to
**Show unread only**.
- Ship the focused behavior directly. The earlier experiment gate,
Custom view, and default-view controls have been removed from this PR to
keep the first pass focused.
## Filter model
| Filter | What appears |
| --- | --- |
| **All** | One row per personally relevant conversation, plus due
reminders and active drafts. Includes DMs, mentions, thread replies,
explicit needs-action items, and replies from agents the current user
owns or controls. Excludes generic top-level channel traffic, other
agents' updates, and reminders that are not due yet. |
| **Mentions** | Conversations containing a direct mention. Each
conversation appears once and opens with full context. |
| **Threads** | Conventional threaded replies, grouped to one row per
thread. Broadcast replies are not treated as conventional thread
replies. |
| **Needs action** | Feed items explicitly classified as requiring
action. |
| **Agents** | Conversations whose representative response was authored
by an agent the current user owns or controls, including top-level DM
responses. If a human replies afterward, the conversation leaves this
filter until an owned agent responds again. |
| **Reminders** | All pending reminders, including upcoming reminders
that stay out of **All** until they are due. |
| **Drafts** | Active drafts, ordered by their last real edit time. |
## Grouping, ordering, and state
- A thread or DM creates one Inbox row rather than one row per event.
- An unread conversation resumes at its oldest unread message so
intervening context is not skipped.
- Conversation rows still sort by their latest activity.
- The detail pane opens the full available conversation and shows the
shared **New** divider before the first unread message.
- Upcoming reminders appear only in **Reminders**.
- When a reminder becomes due, it enters **All** at its trigger time. If
its source conversation is already represented, the reminder state
merges into that row instead of creating a duplicate; otherwise it
appears as a standalone reminder row.
- A due reminder can enrich a row in another relative filter when that
conversation already qualifies for the filter. Reminder lifecycle
remains separate from message read state.
- Drafts appear in **All** by their last real edit time. Opening an
unchanged draft does not move it to the top.
- Reminder and draft rows show their location as `In #channel` or `In DM
with <name>`.
- **Show unread only** hides reminder and draft work queues because they
do not share message unread semantics.
## Removed or narrowed
- **Remove the old Activity filter.** It overlapped with All while still
omitting items All now includes.
- **Narrow Agents.** It no longer gathers every agent participating in a
shared thread or subsequent human follow-ups.
- **Remove duplicate reminder presentations.** The aggregate
pending-reminders jump and duplicate generic feed rows are replaced by
one list/detail model.
- **Remove Custom and default-view settings from this pass.** They added
considerable state and UI before the core model had been validated.
- **Do not add section labels for Reminders and Drafts.** A divider
communicates the distinction without creating another hierarchy in the
menu.
## Risk assessment
Medium implementation risk because this changes composition, grouping,
ordering, read behavior, and personal queues in a primary desktop view.
The implementation is scoped to the desktop UI and its local feed
projection; it does not change relay schemas or public APIs.
## Testing
- Desktop formatting, lint, file-size, text-size, and TypeScript checks
passed.
- Desktop unit suite: **3,663 passed, 0 failed**.
- Desktop E2E production build passed.
- Playwright smoke coverage across every spec touching this surface
(`channels`, `smoke`, `profile`, `project-inbox`, `community-rail`,
`integration`, `drafts-screenshots`): **118 passed, 0 failed**.
- Full Playwright smoke project: **732 passed, 1 skipped**. Three local
failures were investigated and cleared — `community-rail` keyboard
reorder passed on re-run (flaky), while `relay-reconnect:97` and
`video-attachment:223` are untouched by this commit (the only change to
shared `tests/helpers/bridge.ts` is a comment) and pass in CI.
- Unit coverage includes focused All matching, owned-agent filtering,
conversation grouping, oldest-unread selection, selection stability,
chronological reminder/draft composition, trigger-time reminder
ordering, and duplicate reminder suppression.
## Update: July 27, 2026
The naming decision is settled: the surface stays **Inbox**. An earlier
pass in this branch had renamed it to **Activity**; that rename has been
reverted in `9c00d2d6e`, which is naming-only and changes no behavior.
The revert covers file names, component/hook/type/constant identifiers,
the sidebar label and tooltip, the `Inbox options` and `Filter inbox:`
aria-labels, and the corresponding test names, test ids, and fixture
ids.
Three things were deliberately left as `activity`:
- **The feed API contract** — the `activity` / `agent_activity`
categories, the `feed.activity` and `feed.agentActivity` keys, and the
`types=` query parameter. These are the server's names, not the
surface's.
- **Plain-noun usage** — empty states such as "No activity yet", plus
`latestActivityAt` and `PROJECT_ACTIVITY_KINDS`.
- **Pre-existing agent, project, and profile activity code**, which
refers to a different concept entirely.
The earlier experiment-gate approach has also been dropped, so
`tests/helpers/bridge.ts` no longer claims that an Activity preview
feature exists — `preview-features.json` has no such entry and the seed
helper enables every desktop feature.
Generated with Codex
---------
Signed-off-by: Clay Delk <clay.delk@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
**Category:** improvement
**User Impact:** Users can understand, install, authenticate, and manage
agent runtimes from one progressively disclosed Agents settings
experience.
**Problem:** Runtime health and custom harness management were split
across overlapping settings surfaces, exposing low-level configuration
too early while leaving setup and authentication states hard to
understand. **Solution:** Consolidate those operations into one stable
runtime list and an Add runtimes catalog, with task-oriented state
labels, direct setup actions, and custom configuration contained in a
dedicated form.
<details>
<summary>File changes</summary>
**desktop/playwright.config.ts**
Registers the visual coverage needed for the redesigned runtime catalog.
**desktop/public/harness-logos/CREDITS.md**
Documents bundled runtime-mark provenance and the decision not to ship
the withdrawn OpenAI mark.
**desktop/public/runtime-icons/codex.png**
Removes the obsolete Codex bitmap in favor of the neutral fallback.
**desktop/public/runtime-icons/goose.svg**
Removes the old Goose asset now replaced by the theme-adaptive mark.
**desktop/src-tauri/src/managed_agents/discovery.rs**
Aligns runtime discovery guidance with the new task-oriented setup
language.
**desktop/src-tauri/src/managed_agents/discovery/runtime_metadata.rs**
Updates runtime metadata used by the redesigned settings states.
**desktop/src/features/agents/ui/runtimeAvailabilityWarning.test.mjs**
Updates availability-warning expectations for the revised runtime
guidance.
**desktop/src/features/onboarding/assets/harness-logos/chatgpt.png**
Removes the redundant bitmap from the unified runtime icon pipeline.
**desktop/src/features/onboarding/assets/harness-logos/goose.png**
Removes the redundant Goose bitmap.
**desktop/src/features/onboarding/ui/HarnessMarks.tsx**
Adds theme-adaptive bundled runtime marks with safe fallbacks.
**desktop/src/features/onboarding/ui/RuntimeIcon.tsx**
Centralizes runtime logo rendering so settings and catalog rows cannot
drift.
**desktop/src/features/onboarding/ui/SetupStep.tsx**
Aligns onboarding runtime setup copy with the settings terminology.
**desktop/src/features/onboarding/ui/presetLogos.test.mjs**
Guards bundled-logo behavior and prevents the withdrawn Codex mark from
returning.
**desktop/src/features/settings/ui/CustomHarnessForm.tsx**
Reworks custom runtime creation and editing into a clear, dedicated
catalog form.
**desktop/src/features/settings/ui/HarnessCatalogDialog.tsx**
Introduces the Add runtimes master-detail catalog, grouped setup states,
loading treatment, and pinned actions.
**desktop/src/features/settings/ui/HarnessManagementCard.tsx**
Removes the superseded standalone custom-harness management surface.
**desktop/src/features/settings/ui/HarnessRow.tsx**
Provides stable operational runtime rows with install, update,
authentication, edit, and delete behavior.
**desktop/src/features/settings/ui/HarnessesSettingsPanel.tsx**
Consolidates runtime health and custom management into one Agents
settings panel.
**desktop/src/features/settings/ui/SettingsPanels.tsx**
Wires the consolidated panel into Agents settings.
**desktop/src/features/settings/ui/harnessCatalogCopy.ts**
Adds restrained, source-annotated runtime descriptions and setup
guidance.
**desktop/src/features/settings/ui/harnessCatalogLogic.test.mjs**
Covers grouping, state labels, stable row order, actions, and adapter
warnings.
**desktop/src/features/settings/ui/harnessCatalogLogic.ts**
Centralizes catalog grouping, actions, status labels, and runtime-safe
warning copy.
**desktop/src/features/settings/ui/harnessGalleryLogic.test.mjs**
Removes obsolete gallery-only tests after consolidation.
**desktop/src/features/settings/ui/harnessGalleryLogic.ts**
Retains only the shared custom-runtime safety logic needed by the new
surface.
**desktop/src/shared/ui/config-nudge-attachment.tsx**
Points configuration nudges to Agent runtimes with matching terminology.
**desktop/src/testing/e2eBridge.ts**
Adds deterministic runtime states for authentication and catalog E2E
coverage.
**desktop/tests/e2e/doctor-states.spec.ts**
Verifies ready, setup-required, node-gated, authentication, loading, and
error contracts.
**desktop/tests/e2e/harness-catalog-screenshots.spec.ts**
Captures whole-pane visual states for the runtime catalog experience.
**desktop/tests/e2e/harness-management.spec.ts**
Exercises catalog actions and custom runtime create, edit,
authentication, and deletion flows.
**desktop/tests/e2e/onboarding-agent-defaults.spec.ts**
Updates default-runtime expectations for the consolidated experience.
**desktop/tests/e2e/profile.spec.ts**
Aligns profile navigation assertions with the new settings surface.
</details>
## Reproduction steps
1. Open Settings → Agents and inspect Agent runtimes; ready, signed-out,
installable, and setup-required runtimes should have stable rows and
explicit actions.
2. Open Add runtimes and browse the Setup and Installed groups; select
entries to see sourced guidance and a pinned Install or Setup guide
action.
3. Select Custom harness, create a runtime, then edit and delete it;
verify required-field gating and the blast-radius confirmation.
4. Exercise a signed-out runtime and connect it; the row should move
from Sign-in needed to Ready without reordering.
5. Resize the window and switch themes to verify responsive layout and
adaptive bundled marks.
## Screenshots
| Mixed runtime states | Goose not installed | Sign-in needed |
|---|---|---|
| <img width="980" height="1000" alt="image"
src="https://github.com/user-attachments/assets/28705b39-1d91-440a-a954-fb2d7d8ee759"
/> | <img width="980" height="1000" alt="image"
src="https://github.com/user-attachments/assets/e65ce8e1-8c85-4272-afb5-e6001b94d560"
/> | <img width="980" height="1000" alt="image"
src="https://github.com/user-attachments/assets/3987f355-960d-4744-8c26-b3746944a33c"
/> |
| Add runtimes catalog | Custom runtime | Setup guide |
|---|---|---|
| <img width="896" height="672" alt="image"
src="https://github.com/user-attachments/assets/a2f32c8a-4dff-4929-af96-b07346933335"
/> | <img width="896" height="672" alt="image"
src="https://github.com/user-attachments/assets/b2e85a0c-3940-4875-a138-4035423c9de7"
/> | <img width="896" height="672" alt="image"
src="https://github.com/user-attachments/assets/5a690c1c-368e-4ee3-98b9-ffefdc3cf804"
/> |
Full 13-state screenshot matrix and review evidence:
https://buzz.block.builderlab.xyz/channels/c5af9e3e-4317-4853-b3e3-ed9c15bc511d?event=ec88f6e472f2b08d6318ae76fd754fd4f218385f67cfe59b73034c4bc34c9252
---------
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>