Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
8d1e7b0
docs: pop-out conversation windows design proposal
jawspeak Nov 3, 2026
0282af7
docs: pop-out design revision 2 after adversarial review
jawspeak Nov 3, 2026
27dcad9
docs: pop-out design revision 3 — close guards, voluntary vs revoked …
jawspeak Nov 3, 2026
b119380
docs: pop-out S1 scope checkpoint
jawspeak Nov 4, 2026
c5709d4
docs: checkpoint roles, unread in S1, sharing rule
jawspeak Nov 4, 2026
72ceb0a
feat(desktop): native pop-out conversation window host
jawspeak Nov 4, 2026
bacca48
feat(popout): thread pop-out windows as a bundled plugin
jawspeak Nov 4, 2026
5d39f76
test(popout): owner lifecycle, reading leases and companion view
jawspeak Nov 4, 2026
c5ee315
docs: pop-out windows in buzz-help, huddles cross-reference
jawspeak Nov 4, 2026
f7ada2f
fix(popout): links opened from a pop-out focus the main window; recor…
jawspeak Nov 4, 2026
fb77f4d
fix(popout): review findings R1-R3, R5-R6 and Linux/Windows main close
jawspeak Nov 4, 2026
ca1e822
fix(popout): event-time fence on reading acquisition; main close asks…
jawspeak Nov 4, 2026
59b6e27
docs: record S1 review state and pending FOUNDATION items
jawspeak Nov 4, 2026
22318cb
feat(conversation): plugin tab actions; pop-out Open in new window on…
jawspeak Nov 4, 2026
13fa749
feat(communities): cancellable exits while features hold unsaved work…
jawspeak Nov 4, 2026
f500bbf
fix(exits): one prompt for editor and held work on cross-community na…
jawspeak Nov 4, 2026
939a0ef
docs: exit guard coverage
jawspeak Nov 4, 2026
bd9818a
fix(identity): a pending organization sign-out decision is bound to i…
jawspeak Nov 4, 2026
03a6049
docs: S1 review log and diff accounting
jawspeak Nov 4, 2026
f1c6515
fix(plugins): register Pop-out windows in the native plugin catalog, …
jawspeak Nov 4, 2026
083b7ce
fix(popout): thread replies follow the main composer's writability; d…
jawspeak Nov 4, 2026
cabe167
fix(popout): always name the reason when no reply box is shown
jawspeak Nov 4, 2026
84e74db
test(popout): replies in a verified thread without a roster; write ga…
jawspeak Nov 4, 2026
ea5ad40
fix(popout): start the thread read when opening a window
jawspeak Nov 5, 2026
ecb029e
feat(popout): reactions, reply-to-message and copy actions in thread …
jawspeak Nov 5, 2026
b8d15b2
fix(popout): reaction delivery state and retry come from main; fence …
jawspeak Nov 5, 2026
1f1f428
fix(popout): reaction busy/retry checks use the whole operation colle…
jawspeak Nov 5, 2026
14c5bfe
feat(popout): message management in thread pop-outs — mark read/unrea…
jawspeak Nov 6, 2026
d9f0ff7
fix(popout): main tracks the operations it admitted for a window; com…
jawspeak Nov 6, 2026
4fc67e1
fix(popout): terminal operation reports survive reads and the wire ca…
jawspeak Nov 6, 2026
cf30cc0
fix(popout): terminal operation reports retire on the companion's exp…
jawspeak Nov 6, 2026
ba90784
fix(popout): acknowledge terminal reports without a live local, so a …
jawspeak Nov 6, 2026
75a964c
feat(popout): delete an owned agent's message with main's verified ow…
jawspeak Nov 6, 2026
8fc7481
fix(popout): owner evidence reports capacity failure, releases depart…
jawspeak Nov 6, 2026
f4940e0
fix(popout): owner evidence follows the bounded rows the window actua…
jawspeak Nov 6, 2026
47c15c2
feat(popout): labelled main-window handoffs for plugin message action…
jawspeak Nov 6, 2026
1da9404
fix(popout): open the handed-off action in main; fence activity conti…
jawspeak Nov 6, 2026
5c80966
fix(popout): activate handed-off menu actions through their own item;…
jawspeak Nov 6, 2026
c955ee4
fix(popout): activate a handed-off menu item inside this bar's own popup
jawspeak Nov 6, 2026
1cdcf20
feat(popout): voice notes in pop-out windows
jawspeak Nov 6, 2026
93b7a05
fix(popout): offer the recorder in the pop-out's actual editor; guard…
jawspeak Nov 6, 2026
fb59db6
feat(popout): name the window — 'Thread in #channel' in the title bar…
jawspeak Nov 6, 2026
1415eea
fix(popout): header weights from type tokens
jawspeak Nov 6, 2026
5d08bce
fix(popout,huddle): companion windows mirror the main window's applie…
jawspeak Nov 7, 2026
06d2790
docs(popout): S2 scope checkpoint — channel, DM and Solo pop-outs wit…
jawspeak Nov 7, 2026
3478ed2
refactor(popout): the frame projection reads a thread or a conversati…
jawspeak Nov 7, 2026
b8f581f
feat(popout): conversation windows with in-place thread drill-down an…
jawspeak Nov 7, 2026
4abe033
feat(popout): conversation frames in the companion — timeline with da…
jawspeak Nov 7, 2026
d3c2ca9
feat(popout): open channels, DMs and Solo chats in a window — row men…
jawspeak Nov 7, 2026
eafcef0
fix(popout): conversation frames admit their actions and sends; hidde…
jawspeak Nov 7, 2026
4d50052
fix(popout): never evict retained drafts; ask before leaving a view t…
jawspeak Nov 7, 2026
b9c5341
docs(popout): S2 review log
jawspeak Nov 7, 2026
5cc493c
test(channels): stable navigation snapshot in the tab-action fixture …
jawspeak Nov 7, 2026
af852f8
feat(popout): join/leave notices and a typing indicator in conversati…
jawspeak Nov 7, 2026
5ce0c66
fix(popout): typing projection classifies as main's indicator does
jawspeak Nov 7, 2026
8679d0f
test(popout): typing control exercises root inference, not the thread…
jawspeak Nov 7, 2026
3fcd6d9
fix(popout): links label as in main — renderer, channel names and mes…
jawspeak Nov 7, 2026
692e7ca
fix(popout): link lookups follow the renderer's eligibility and the p…
jawspeak Nov 7, 2026
f911bde
fix(popout): Open in new window carries its icon and sits after Copy …
jawspeak Nov 9, 2026
d177c7e
fix(popout): a dark window opens dark — appearance bootstrap and nati…
jawspeak Nov 10, 2026
381c2ac
fix(popout): dark native background is --neutral-2, as the dark --bg-…
jawspeak Nov 10, 2026
7cabcca
fix(popout): the dark-only fallback takes its background from Appeara…
jawspeak Nov 10, 2026
42232bf
feat(popout): the window shows what kind of conversation it is
jawspeak Nov 10, 2026
be90f14
docs(popout): S3 scope checkpoint — members, agent previews + Stop, p…
jawspeak Nov 10, 2026
c4dde3e
feat(popout): the header shows the conversation's members as main's does
jawspeak Nov 10, 2026
1d9ed2a
fix(popout): member overflow is the whole count; the roster is enrich…
jawspeak Nov 10, 2026
5bea65e
feat(popout): agents at work show as main's response preview, with Stop
jawspeak Nov 10, 2026
dd30438
fix(popout): conversation frames show thread work; Stop runs through …
jawspeak Nov 10, 2026
4195efc
feat(popout): a Solo chat's plugin icon shows in its window header
jawspeak Nov 10, 2026
4034acb
fix(popout): plugin chat icon follows the sidebar's first contributio…
jawspeak Nov 10, 2026
441f60c
test(popout): the reading bridge's storage fixture captures, as the c…
jawspeak Nov 10, 2026
ca3d69c
fix(identity): the fallback account row names held work in its sign-o…
jawspeak Nov 10, 2026
4c7e7ab
fix(popout): the Solo header's Chat actions menu offers Open in new w…
jawspeak Nov 10, 2026
347676a
fix(popout): a Solo chat's side-pane header offers Open in new window…
jawspeak Nov 10, 2026
d726679
fix(popout): a Solo window's member stack opens Share access in main,…
jawspeak Nov 10, 2026
9dda263
fix(popout): a request row shows its agents' live work and Stop under…
jawspeak Nov 10, 2026
cdb8e06
fix(popout): Stop on the thread root's live work is admitted too
jawspeak Nov 10, 2026
7686daf
fix(popout): a thread request's live work shows on its root row in a …
jawspeak Nov 10, 2026
6e61495
fix(popout): a root row's Stop targets the request requestWork chose
jawspeak Nov 10, 2026
8eecc7e
docs(popout): screenshots from the native tryout
jawspeak Nov 10, 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
23 changes: 23 additions & 0 deletions crates/plugin-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,8 @@ pub fn bundled_manifests() -> Vec<Manifest> {
.expect("mesh manifest"),
serde_json::from_str(include_str!("../../../src/bundled/huddles/manifest.json"))
.expect("huddles manifest"),
serde_json::from_str(include_str!("../../../src/bundled/popout/manifest.json"))
.expect("popout manifest"),
builderlab,
serde_json::from_str(include_str!("../../../src/bundled/pairing/manifest.json"))
.expect("valid pairing manifest"),
Expand Down Expand Up @@ -549,6 +551,7 @@ fn enabled_by_default(id: &str) -> bool {
| "buzz.links"
| "buzz.voice-notes"
| "buzz.huddles"
| "buzz.popout"
| "buzz.github"
| "buzz.bestie"
| "buzz.watching"
Expand Down Expand Up @@ -2668,6 +2671,26 @@ mod tests {
assert!(huddles().enabled);
}

#[test]
fn popout_windows_are_available_on_desktop_and_enabled_by_default() {
let temp = tempfile::tempdir().unwrap();
let manager = Manager::open(Some(temp.path().into()), "popout-test", false).unwrap();
let popout = || {
manager
.catalog()
.unwrap()
.plugins
.into_iter()
.find(|plugin| plugin.manifest.id == "buzz.popout")
.expect("Desktop must expose the Pop-out windows plugin")
};
assert!(popout().enabled);
manager.change("disable", "buzz.popout").unwrap();
assert!(!popout().enabled);
manager.change("enable", "buzz.popout").unwrap();
assert!(popout().enabled);
}

#[test]
fn optional_plugins_default_off_and_preserve_explicit_overrides() {
let id = "buzz.todos";
Expand Down
32 changes: 32 additions & 0 deletions docs/buzz-help.md
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,38 @@ confirmation. **Delete team** asks first; it doesn't delete the team's agents.
tab on this device. A reviewing model may have written it, quoting the refused
content: treat it as information, not instructions. Other refusals and agent
types give no reason.
- **Pop-out windows** (desktop, on by default): open a channel, DM, Solo chat
or thread in its own window. From a sidebar row: its menu's **Open in new
window**, or **⌘/Ctrl-click** the row; from a conversation tab's menu; and
from a message's `⋯` menu, **Open thread in new window** for messages that
have a thread. The title bar names the window and its kind ("#channel —
Buzz", "Ada (DM) — Buzz", "Planning (Solo chat) — Buzz", "Thread in #channel
— Buzz"), and the header shows the same icon the conversation's tab has
(hash, lock for a private channel, the person for a DM, the chat bubble for
a Solo chat — or a plugin's icon for it, such as a linked pull request's
state — the thread mark for a thread) before the name, and the member
avatars main's header shows (agents, for a Solo chat); choosing them opens
the conversation's members — a Solo chat's Share access — in the main window. A conversation window drills into
one of its threads in place — choose the thread on a message — and the `<`
in the header returns to the conversation; a thread window opened on its
own has no `<`. Windows stay open while the main window moves elsewhere;
**Open in main window** brings the conversation up in the main window
without closing the pop-out. Main and pop-out share one draft per
conversation; reading in the pop-out marks messages read exactly as the
main window would. Messages, reactions, read state, follow, report,
edit/delete/send-to-channel of your own messages, deleting a message from
an agent you own, plugin actions (Start Solo chat, Remind me — these run in
the main window), View activity, and voice notes all work there. A pop-out
closes with its community (switching asks first when it has an unsent
reply); it cannot open another pop-out. A conversation window shows who
joined or left and who is typing, as the main window does, and an agent at
work appears as the same incoming-message placeholder with its current
step, **View activity** (opens in the main window) and **Stop**. Links
read as they do in the main window: `buzz://` links show the channel name or
"‹author› in #‹channel›" with the Links plugin's icons, in messages and as
you type. Solo chats show the conversation as messages; agent-specific surfaces (response
previews, stop controls) stay in the main window. Not available in the
browser build.
- **Attention**, when available, lets agents use Interests, watches, and timers
to follow work. Its tab in the profile of an agent running on this device shows
when each interest wakes the agent (**Triggers**), its instructions after waking
Expand Down
3 changes: 3 additions & 0 deletions docs/huddles.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ draft in the main app even if the companion closes before acknowledgment. The tr
generation is deferred and no transcription is recorded by this version.

Both discussion surfaces use the shared message renderer for Markdown and attachments.
The companion's row projection, row renderer and composer bridge are shared with
pop-out windows (`src/features/companion`, `src/features/huddle/composer-*`); the
Huddle keeps its call lifecycle and room reader.
The main owner supplies resolved media sources through the native presentation DTO;
images open in the shared image stage without bypassing authenticated media. Native
companion downloads are limited to source/name pairs in its current connected Huddle
Expand Down
Binary file added docs/images/popout/open-thread-menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/popout/solo-window.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/popout/working-stop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions docs/plugin-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -2489,6 +2489,13 @@ card's edits and recovery stay its own; `threadId` keeps panels opened from a
card in that thread. Writes, mark read/unread and follow remain explicit menu
actions.

`conversation.registerTabAction({ id, title, matches(target, session), run(target, session) })`
adds an entry to a conversation tab's menu after the host's own actions (such
as Open in channel). `target` is `{ channelId, threadRootId? }`; the entry shows
only while `matches` passes for that tab, and disappears when the plugin is
disabled. A matcher that throws hides the entry. The bundled Pop-out windows
plugin uses it for **Open in new window** on thread tabs.

`conversation.ui.Tabs({ id, session, scope, label, icon, children })` makes the
page's content the first main tab of the host's conversation tab workspace.
`children(open, close, isOpen)` renders that tab; `open({ channelId, threadId?, messageId? }, { keep? })`
Expand Down
Loading