Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 23 additions & 6 deletions docs/channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ frontend hot reload alone is not enough.

Settings independently enables/disables Channels and GitHub. Disabling GitHub
removes its link handler and open panel; shared channel data remains available.
Disabling Channels removes its page while the app-owned data survives.
Channels is required by the current host; optional page removal does not dispose
the app-owned sidebar or session data.

The broker uses the existing authorized Buzz identity in the OS secret store (macOS
Keychain, Linux secret service) and
Expand All @@ -45,7 +46,11 @@ This is not a new native login.
- `features/messages` owns reusable `ChannelTimeline`, `MessageRow`, `ThreadPanel`,
`MessageComposer`, delivery presentation, styles and reading geometry. They accept
ordinary props over the shared session; none owns a connection or outbox.
- `bundled/channels` owns page registration, channel selection/navigation, sidebar,
- `features/channel-navigation` owns the persistent sidebar and its scoped UI handoff
for session draft rows and preparing DMs. App composes it beside independent pages;
sidebar actions use the normal navigation controller. It reuses session capabilities
and existing sidebar components without another relay/cache or plugin registry.
- `bundled/channels` owns page registration, conversation selection/navigation,
diagnostics, layout and panel placement. `shared/view-state.ts` partitions persisted
drafts and view intent by community/viewer scope.
- `bundled/github` registers and implements the panel. Channels uses the panel
Expand All @@ -60,8 +65,9 @@ Keep page-specific navigation and arrangement in the plugin; compose shared mess
components rather than copying them. Session reconciliation, authorization, retained
reads and durable outbox recovery remain host-owned even if Channels is disabled.

The workspace React key includes community/viewer scope **and** connection
generation. This resets session-owned component state on switching or reconnecting;
The sidebar and Channels workspace React keys include community/viewer scope **and**
connection generation. This resets their session-owned state on switching or
reconnecting, not unrelated page drafts;
drafts, channel selection and reading geometry retain their stable scope keys.

Saved sidebar groups, ordering, assignments and stars live in the session's
Expand All @@ -74,13 +80,14 @@ preferences, not channel access grants: sidebar sections still intersect the
authorized roster. There is no new disk cache or automatic cross-device sync.

Collapsed section keys and sidebar scroll remain separate, scoped view intent.
They are saved on page exit and restored before paint when the roster and groups
They survive page switches in the same mounted sidebar, are saved when that
sidebar exits its session, and restore before paint when the roster and groups
are available; navigation history does not own them. Search lives in the top-bar
palette; legacy sidebar filters are ignored. The saved-groups
browser regression records every visible return frame and holds the redundant
decode path, so eventual restoration cannot conceal a fallback-group/scroll jump.

Channel row actions share one page-owned `ContextMenuRoot` / `MenuPopup`, labelled
Channel row actions share one sidebar-owned `ContextMenuRoot` / `MenuPopup`, labelled
`Actions for <channel>`. **New session** comes first; additional sidebar actions
should extend that popup, with a separator only when another action group follows.
`ChannelSidebarItem` owns the context trigger inside its memo boundary, using stable
Expand All @@ -96,6 +103,16 @@ derive the saved group id separately from `group:<id>` rather than conflating it
with rendered placement. Right-clicking the separate session disclosure remains
outside the parent menu trigger, as do child-session rows.

Sidebar create-channel dialogs and partial-setup recovery stay available on other
pages. Completion is fenced to the originating relay session and navigates to a
normal conversation destination. New-session intent uses the Channels version-1
page route `{ kind: "new-session", parentId }`; Channels checks parent access/type
and Sessions availability. Only parent intent, never draft text, enters history.
Preparing-DM suppression captures the pre-open roster and exact member set, hiding
only newly prepared DMs until confirmation; leaving New message or replacing the
session clears that handoff. Timeline readers and reading leases stay in visible
conversation content and unmount when leaving Messages.

## Starting a direct message

The **+** action in the DMs sidebar header opens **New message**, a routed empty
Expand Down
19 changes: 13 additions & 6 deletions docs/plugin-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Both experiences use real session capabilities. As AI integrations become availa

| Area | Responsibility |
| --- | --- |
| Application host | Startup, plugin installation and activation, page navigation, Settings, and recovery. |
| Application host | Startup, plugin installation and activation, page navigation, persistent channel sidebar, Settings, and recovery. |
| Page plugin | Its complete React tree, local interaction state, internal navigation, and arrangement of panels. |
| Panel plugin | Recognizing a supported target and implementing the content and interactions for that target. |
| Shared capabilities | Session state, relay access, retained data, local agent controls, and eventually external connections. |
Expand All @@ -45,7 +45,8 @@ features/panels/ target resolution, launcher contract and reusable card/f
features/shortcuts/ in-app binding dispatch, focus rules and plugin ownership
features/relay/ shared channel data, queries, profiles and durable delivery
features/messages/ reusable timeline, message, thread and composer UI
bundled/channels/ Channels navigation, sidebar, page layout and panel placement
features/channel-navigation/ persistent sidebar, scoped draft handoff, Channels routes
bundled/channels/ conversation navigation, page layout and panel placement
bundled/projects/ repository/project pages, issue/PR details and Git views
features/projects/ entity route/data contracts and bounded Git read bridge
bundled/agents/ local control UI and read-only current-Buzz library page
Expand All @@ -54,6 +55,12 @@ bundled/github/ builtin GitHub panel plugin
bundled/bestie/ builtin companion panel and its snake launcher
```

The host composes one channel sidebar beside independently mounted pages. It reuses
session-owned roster, unread, creation and preferences capabilities; it does not
retain a hidden Channels page or message reader. Sidebar and page render errors
have separate boundaries. Sidebar presentation helpers currently remain importable
from `bundled/channels`; no public sidebar contribution contract is introduced.

Channels is the page-authoring example, not a thin registration wrapper over a
host-owned product page. Keep page-specific components, styles, interactions and tests
beside `bundled/channels/index.tsx`. New page plugins should do the same. At the
Expand Down Expand Up @@ -113,13 +120,13 @@ exact registration identity and mounted lifetime revoke callbacks on removal.

Templates & teams (`buzz.channel-templates`) is bundled **off by default** in both
browser and desktop catalogs. Explicit saved overrides win. Enable it under
Settings → Plugins, then manage recipes under Settings → Messages. Channels owns
Settings → Plugins, then manage recipes under Settings → Messages. The host sidebar owns
personal groups and the existing + creation buttons, independently of this plugin.

`ctx.channelTemplates.register({ id, title, editor, groupDefault, saveAs })` supplies
one optional composition provider. With zero or multiple active providers, no
optional controls are selected. This host-matched preview is not a workflow API:
Channels owns form/draft data and final dispatch; the session owns signing,
The sidebar owns creation form/draft data and final dispatch; the session owns signing,
membership, Canvas writes, exact receipts and partial-setup recovery. Settings and
provider components must check `active()` before accepting delayed work or starting
new writes; this lifecycle fence is not a sandbox or a replacement for access checks.
Expand Down Expand Up @@ -153,8 +160,8 @@ thread changes. The accessory remains usable on read-only connections.
Agent Activity is the first consumer. Plugin activation owns its telemetry lease;
multiple composers subscribe to the same session capability. No global selected
channel or activity-specific dependency is added to reusable message components.
Channels reads the same session activity snapshot for its quiet sidebar marker;
it owns that page presentation, not capture or an additional activity lease.
The persistent sidebar reads the same session activity snapshot for its quiet marker;
it owns presentation, not capture or an additional activity lease.
This is a host-matched preview addition, not cross-version capability negotiation.

### Channel-header launchers
Expand Down
29 changes: 20 additions & 9 deletions docs/shell-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,25 @@ semantic tokens, UI authoring rules and the local component reference.
Existing feature CSS variables remain available for incremental adoption.
- `src/app/shell/presentation.ts` owns page labels, icons and navigation ordering.
Messages comes first, then Projects; other contributed pages follow by
displayed label with a full contribution-key tie-breaker. Tabs and
displayed label with a full contribution-key tie-breaker. Sidebar navigation and
page search share this policy, independent of plugin activation/re-enable order.
Channels is presented as Messages. Legacy tone props are retained for
compatibility; all pages share the supplied gradient and repeating CSS dots.
Add recognized page presentation here without changing plugin contracts.
- `AppShell.tsx` owns the 56px header, scrollable centered navigation, contributed panel
launchers, Settings access, community switcher, and page frames. Equal-width
left/right header tracks center tabs on the window, not the leftover space.
Below 700px the tab pill moves to a centered second row to avoid collisions.
- `AppShell.tsx` owns the 56px header, vertical page navigation, contributed panel
launchers, Settings access, community rail, and page frames. Page navigation sits
above the persistent channel list on every page, using its saved sidebar width
and resize behavior. `App.tsx` composes `features/channel-navigation/ChannelSidebar`
through an ordinary render prop; there is no portal or plugin contract expansion.
Sidebar session state resets on scope/connection generation without remounting
unrelated pages. Its own error boundary keeps page navigation and Settings usable.
Page buttons use shared navigation rows and focus the main region on selection.
A scrollable page list leaves room for channels at short heights.
At widths up to 650px, Settings collapses this navigation behind the header’s
Show navigation button to preserve readable content at 200% text size. The
disclosure overlays Settings, supports Escape, and keeps sidebar state mounted.
Other pages and desktop Settings retain the visible sidebar.
The header keeps history and account/search actions, with no second navigation row.
Full-height pages get a 16px outer gutter (8px on narrow screens) and own their
card surfaces. The shell adds no white backing behind them. Document pages
scroll inside the remaining viewport.
Expand Down Expand Up @@ -63,7 +73,7 @@ motion with Tailwind's `motion-reduce` variant.

Tauri uses `titleBarStyle: Overlay` and `hiddenTitle` on macOS. Native traffic
lights have a reserved 104px left area before the community switcher only in the
macOS desktop runtime. This inset does not move the centered tabs. Web gets no
macOS desktop runtime. Web gets no
inset or imitation window controls. Other
platforms retain their native decorations. Drag regions are limited to the
header background; controls remain clickable. On macOS, double-clicking that
Expand Down Expand Up @@ -128,11 +138,12 @@ access in a built app.

## Messages

The Messages feature owns separate rounded sidebar, conversation and contributed
panel cards, with 16px gutters. A single right panel fills the conversation height;
The host owns the persistent rounded sidebar card; Messages owns conversation
and contributed panel cards, with 16px gutters. A single right panel fills the conversation height;
the right-column grid splits available height evenly between a local link card
and the launched companion card. Below 1000px
the right column overlays the conversation; below 650px it fills the page area.
the right column overlays the conversation; it also overlays when the content
pane is too narrow for two columns. Below 650px it fills the page area.
Each card contains its own overflow, keeping the composer and close control visible.
Channels opts into the reusable companion prop and owns both cards, including a
companion-only view without a selected channel or relay. Settings and legacy
Expand Down
Loading
Loading