Skip to content

feat(desktop): add channel-first project Canvas POC - #6974

Draft
matt2e wants to merge 48 commits into
mainfrom
jitter/channel-project-features-on-thomas
Draft

feat(desktop): add channel-first project Canvas POC#6974
matt2e wants to merge 48 commits into
mainfrom
jitter/channel-project-features-on-thomas

Conversation

@matt2e

@matt2e matt2e commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • make project channels the primary project workspace and add a project Canvas view
  • move Canvas presentation into a locally editable external package with manifest-declared widgets, styles, data, and assets
  • serve immutable package snapshots through an offline custom protocol and run one opaque-origin allow-scripts iframe behind a bounded MessageChannel data bridge
  • add local-only buzz canvas notify --change data|presentation handoff: data updates keep the iframe and widget root mounted for animation, while presentation updates use the existing validated last-known-good reload gate
  • persist pending update revisions across Desktop and Canvas restarts, preserve newer data across presentation commits, and expose the package directory through a machine-readable index

Validation

  • cargo test -p buzz-cli (416/416)
  • env -u BUZZ_ACP_ALLOWED_RESPOND_TO cargo test -p buzz-acp -- --test-threads=1 (840/840 across unit and integration tests)
  • pnpm -C desktop test (5,783/5,783)
  • cargo test --workspace --manifest-path desktop/src-tauri/Cargo.toml (full Tauri workspace; 3,004 desktop tests plus integration crates)
  • root and Tauri Clippy with warnings denied, Rust formatting, Desktop TypeScript, and Desktop checks
  • external Canvas package contracts (7/7) and isolated Canvas Playwright workflow (7/7)
  • repository pre-push gate, including differential file-size checks and full Desktop/Rust lanes

POC boundary

The native Canvas runtime fails closed outside macOS. A hostile raw-Tauri-IPC probe must still pass in the packaged macOS app before treating this as a production security boundary. Real project/channel/review data remains read-only inside the Canvas; agents mutate the local package through the filesystem and notify the running Desktop. Package storage is not synced.

thomaspblock and others added 30 commits August 25, 2026 15:43
Give agents bounded project-home context and project-aware CLI operations while keeping channel matching client-filtered through the existing relay query surface.

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
## Summary
- create explicit NIP-MP projects with a home channel and default
repository
- preserve standalone repository folding, project deletion, and
deterministic repository selection
- restore Template, Team, visibility, and agent settings in the project
creation flow

This is Part 2 of the channel-first Projects stack, following #6590. It
is independently based on `main`; Part 3 adds the project-home channel
surface.

## Testing
- focused project collection, creation, channel, and model tests: 38/38
passed
- Desktop unit suite: 5,415/5,415 passed
- TypeScript, Biome, and differential file-size checks passed
- full pre-push gate passed

## Post-Deploy Monitoring & Validation
- create listed and unlisted projects with and without templates in the
first staging Desktop session
- healthy signals: one home channel, one default repository, stable
project coordinates, and no duplicate legacy card
- failure signals: partial project creation, duplicate projects, missing
default repository, or stale sidebar entries; mitigate by reverting this
PR

---------

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
- classify and render project-home channels through the shared channel
glyph and lifecycle helpers
- let the normal channel pane host a project idle auxiliary surface and
focus drawer
- align channel management, headers, member bars, and empty-channel
actions with project channel semantics

This is Part 3 of the channel-first Projects stack, based on #6591. Part
4 adds the project-home navigation and context experience.

- focused channel lifecycle, pane helper, and project-home channel
tests: 7/7 passed
- Desktop unit suite: 5,422/5,422 passed
- E2E-mode Desktop build passed
- TypeScript, Biome, and differential file-size checks passed
- full pre-push gate passed

- open normal, temporary, private, and project-home channels in the
first staging Desktop session
- healthy signals: normal channels retain their existing composer/thread
behavior and project homes use the project glyph and auxiliary slot
- failure signals: missing composer, incorrect channel kind, stuck focus
drawer, or project chrome on a normal channel; mitigate by reverting
this PR

---------

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
## Summary
- render an explicit project's home channel through the normal channel
timeline and composer
- add a resizable project context rail with codebase, channel, people,
and workspace navigation
- keep project agent conversations bounded to the project home and
preserve repository/detail routes

This is Part 4 of the channel-first Projects stack, based on #6594. The
final part contains overview and workspace completion polish.

## Testing
- focused project conversation, route, summary, workspace-sheet, and
related-channel tests: 39/39 passed
- Desktop unit suite: 5,439/5,439 passed
- E2E-mode Desktop build passed
- TypeScript, Biome, and differential file-size checks passed
- full pre-push gate passed

## Post-Deploy Monitoring & Validation
- open project homes from project and channel entry points in the first
staging Desktop session
- healthy signals: one channel timeline/composer, stable repository
context, bounded project agent history, and reversible workspace sheets
- failure signals: duplicate channel surfaces, stale repository
selection, unrelated DM history, or sheets replacing the channel route;
mitigate by reverting this PR

Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Open project homes consistently from channel and project routes, preserve file/work-item deep links, and let agents request owner-reviewed project channels.

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Co-authored-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
## Summary
- make the Projects overview follow the active section with consistent
context, empty states, and row alignment
- add an animated section-local search that preserves sort and
responsive tab behavior
- simplify sidebar and list controls while keeping large project
collections incrementally mounted

This is Part 6 of the channel-first Projects stack, based on #6597. The
final part contains project workspace aggregation and the default
project-home template.

## Testing
- focused search, activity digest, agent selection, related-channel, and
overview-context tests: 26/26 passed
- Desktop unit suite: 5,451/5,451 passed
- E2E-mode Desktop build passed
- TypeScript, Biome, and differential file-size checks passed
- full pre-push gate passed

## Post-Deploy Monitoring & Validation
- exercise every Projects overview section, search transition, selection
state, and right context rail in staging Desktop
- healthy signals: stable tabs, aligned rows, correct section context,
and responsive large-list interaction
- failure signals: search flicker, stale context, wrapped toolbar rows,
missing empty actions, or input lag; mitigate by reverting this PR

---------

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
- seed new project homes with a built-in operational canvas while
preserving custom templates and None
- make category create actions open the matching project-aware modal and
keep selection presentation type-specific
- aggregate Tasks and Commits across every repository with responsive
project/repository grouping and a repository Overview tab

This is the final part of the channel-first Projects stack, based on

- focused project template, work-item aggregation, and overview-context
tests: 16/16 passed
- Desktop unit suite: 5,455/5,455 passed
- E2E-mode Desktop build passed
- TypeScript, Biome, and differential file-size checks passed
- full pre-push gate passed

- create a project, inspect its canvas, and exercise Tasks/Commits
across a project with several repositories
- healthy signals: populated project canvas, one chronological commit
list with repository attribution, and complete task aggregation
- failure signals: missing canvas, single-repository-only counts,
duplicate repository groups, or category actions opening the wrong flow;
mitigate by reverting this PR

---------

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Co-authored-by: Wrench <0eabe6ea5758c1e4c5b68cea4ac42b32c479072883cb28da8110b4a47c32b9a1@buzz.block.builderlab.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Two pre-existing crashes surfaced in the dev console, both independent of
the projects work on this branch.

SelectionFormattingTray read `editor.view.dom` on mount. A tiptap v3 Editor
outlives its ProseMirror view, and while the view is detached `editor.view`
is a proxy that throws for every key it does not stub. When React reconnected
the effect for a hidden composer subtree the view was already torn down, so
the read threw, crashed the component, and escaped to the router's root catch
boundary. Track the mounted view as state synced from tiptap's mount/unmount
events, and route every view access through a `getMountedView` guard.

The huddle listeners called Tauri's unlisten function directly. `listen()`
resolves with its event id as soon as the backend command returns, but the
backend publishes that id into the webview through a separate eval, so an
unlisten issued in that gap throws from `unregisterListener` before it reaches
`plugin:event|unlisten`. That left the backend listener registered and still
firing its handler after unmount, on top of the unhandled rejection. Add
`safeUnlisten`, which retries with backoff until the teardown actually lands.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
matt2e added 17 commits August 26, 2026 11:36
…t-features-on-thomas

Signed-off-by: Matt Toohey <contact@matttoohey.com>

# Conflicts:
#	desktop/src/features/channels/ui/ChannelPane.tsx
#	desktop/src/features/channels/ui/ChannelScreen.tsx
#	desktop/src/features/messages/ui/SelectionFormattingTray.tsx
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
…t-features-on-thomas

Signed-off-by: Matt Toohey <contact@matttoohey.com>

# Conflicts:
#	crates/buzz-acp/src/lib.rs
#	crates/buzz-acp/src/pool.rs
#	crates/buzz-acp/src/queue.rs
#	crates/buzz-cli/src/commands/projects.rs
#	desktop/src/app/routes/ChannelRouteScreen.tsx
#	desktop/src/features/channels/ui/ChannelPane.helpers.test.mjs
#	desktop/src/features/channels/ui/ChannelPane.helpers.ts
#	desktop/src/features/channels/ui/ChannelPane.tsx
#	desktop/src/features/channels/ui/ChannelScreen.tsx
#	desktop/src/features/channels/ui/FocusThreadDrawer.tsx
#	desktop/src/features/projects/createProject.ts
#	desktop/src/features/projects/lib/projectHomeChannel.test.mjs
#	desktop/src/features/projects/lib/projectHomeChannel.ts
#	desktop/src/features/projects/ui/ProjectChannelHome.tsx
#	desktop/src/features/projects/ui/ProjectChannelRequestDialog.tsx
#	desktop/src/features/projects/ui/ProjectDetailScreen.tsx
#	desktop/src/features/projects/ui/ProjectHomeContextPanel.tsx
#	desktop/src/features/projects/ui/ProjectRepositoryManagement.tsx
#	desktop/src/features/projects/useCreateProject.ts
#	desktop/src/features/projects/useProjectChannelRequests.ts
#	desktop/src/features/sidebar/ui/AppSidebar.tsx
#	desktop/tests/e2e/project-commit-detail.spec.ts
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
…t-features-on-thomas

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
…t-features-on-thomas

Signed-off-by: Matt Toohey <contact@matttoohey.com>

# Conflicts:
#	desktop/src/features/projects/ui/ProjectChannelHome.tsx
#	desktop/src/features/projects/ui/ProjectDetailScreen.tsx
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is b49675894b39f87215e4dfc8c1ad4a3c28c6097e...17f8339007c83b47b8bb612f41979681e8fd0479.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review 17f8339007c83b47b8bb612f41979681e8fd0479 to authorize a new review.
Any previous review applies only to its recorded range.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
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.

2 participants