Skip to content

Add opt-in Canvas-backed channel Todos - #222

Merged
wesbillman merged 10 commits into
mainfrom
carl/canvas-todos
Sep 24, 2026
Merged

wesbillman merged 10 commits into
mainfrom
carl/canvas-todos

Conversation

@wesbillman

@wesbillman wesbillman commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds Todos, an opt-in bundled plugin, disabled by default in browser and native catalogs. Enable it in Settings → Plugins, then use the channel-header ListChecks button to open the right-side panel.

  • Canvas is the only shared store: ordinary Markdown checkboxes under one ## Todos heading, automatic save after Add/check/assignment and explicit Refresh, open/completed grouping, and scoped local recovery drafts. Source-range edits preserve surrounding content; duplicate sections and unsafe edits are rejected. Disabling removes the UI, not the saved data; Channel settings → Canvas remains editable.
  • Assign tasks to channel members using readable · Assignee: [Name](nostr:npub...) suffixes. Only the exact emitted link grammar is recognized; title/angle-bracket variants remain prose. Shared identity labels distinguish namesakes, missing profiles and former members. Missing rosters disable assignment; selection rechecks current membership, while former assignees remain identifiable and clearable when the roster is available.
  • Keep task rows in two columns with a small right-aligned ghost Select. Closed values show only the name (or canonical-key fallback / Unassigned), the native hover hint carries the full npub, and opened choices keep identity-qualified labels. Long values truncate without hiding the chevron; compact rows remain usable at narrow widths and enlarged text.
  • Reuse the existing companion column, shared Panel, and session/Canvas/outbox owners. The panel contribution contract gains optional, runtime-validated channelPlacement: "bottom" | "side"; omitted placement stays bottom, including Terminal. Preserve panel retirement, focus restoration, popup/panel Escape behavior, settings coexistence and narrow/enlarged-text usability.

Autosave pauses task actions while one save is in flight, but keeps the next-item input editable and preserves its current text, waits once for Canvas’s next permitted second, and retains failures/recovered drafts for explicit Retry. Typing an unfinished item stays local. Closing cancels an unstarted wait; accepted outbox operations remain session-owned. No dedicated backend, database, polling, background retry loop, delete/reorder feature, or concurrency overhaul. Plugin architecture documentation includes the Canvas format and placement contract.

Validation

Pushed head: 61d580966e2cd7e11ab490cabe3f0adce4295042. This remediation changes only TodosPanel, its colocated tests, and one documentation sentence. All four outstanding review threads are answered and resolved: cache unchanged Canvas parsing (two duplicate findings), preserve next-item typing during save, and await assignee popup mounting.

Snapshot Evidence
61d58096 Full bin/pnpm exec vitest run: 273 files / 2,875 tests passed. Five new regression cases failed against e4053128 before the fix, then passed. Cache tests cover results/errors and content invalidation; deferred-save tests cover typing across success, failure/retry, and close/reopen, with duplicate Add/save blocked.
61d58096 Mandatory commit/push hooks passed: TypeScript, selected Vitest 88 files / 947 tests, design types/guards, formatting/lint/security checks. All PR commits audited for DCO.
61d58096 Offline Chromium and WebKit preview passed: typing/focus through a deliberately held save, retained input after completion/reopen, subsequent Add, checkbox/assignment autosave, keyboard select/Escape/focus, name/npub hints, light/dark/narrow/enlarged-text geometry, and long-value ellipsis. Uses production panel plus fake Canvas with an explicit test gate and same-second guard; no relay reads/writes or server/app launches.
Precommit patch, identical production code Independent read-only review found no substantive blockers in input ordering, persistence, lifecycle fences, parse memoization or deterministic gates. Hook changed only test formatting. This is not required GitHub code-owner approval.
e4053128 Previous head hosted JavaScript, Rust/tool integration, browser measurements, all Chromium/WebKit shards, CI required, DCO, Semgrep and zizmor passed. Not evidence for new-head CI.

Fetched main is 5015556a; branch merge base is 82bb3a63. The single incoming commit changes profile activity, not Todos or the repaired contracts; left it to merged-tree CI rather than adding an unrelated merge. New-head hosted checks were inspected once after delivery, not watched. Existing approval remains APPROVED; branch rules do not dismiss it on push. Required current-head CI is still a merge gate.

The full-app browser journey was not rerun locally during this remediation, respecting the no-server/no-desktop-start boundary. This does not claim a complete local pnpm test, native-package run, or live-relay concurrency test.

Test-layer accounting

Adds one browser scenario, run in Chromium and WebKit; removes none. It proves Settings enable → actual side panel → add/check/assign → automatic saves through the real outbox and fixture-signed receipt → reopen → disable → assignment remains in editable Canvas. Browser-only checks cover keyboard focus, popup/panel Escape, side geometry, themes and narrow/enlarged text. Parser/recovery/roster permutations stay in colocated Vitest tests. Autosave adds deterministic coverage for timestamp waiting/cancellation, failed-draft retry without reopening writes, and member-scoped naming against out-of-channel namesakes. Review remediation adds five colocated cases for parse caching and pending-save input retention; no additional committed browser scenarios. Uses the existing minimal app fixture plus an ephemeral signing helper.

Mutation evidence: removing checkbox focus restoration made both engines fail toBeFocused(); restoring it passed. The focused command omits measurement dependencies and makes no channel-opening/scroll performance claim.

Limits and remaining gates

  • Whole-document Canvas saves are not atomic. Existing optimistic checks catch observed conflicts, not every simultaneous write; the UI warns accordingly.
  • Existing Canvas writes also need host capability 9007 for membership refresh/confirmation, not only 40100. Partial-capability hosts report failure and retain the draft; shared-host remediation is out of scope.
  • Initial hostile-Markdown parsing cost is not removed by caching and was not remeasured at this head. Caching prevents unrelated input/profile/status renders from repeating unchanged-content parsing.
  • Required current-head CI and code-owner approval remain merge gates. Previous-head hosted CI passed; new-head results must be evaluated separately. Packaged native UI and live-relay cross-window simultaneous writes were not exercised. Native catalog changes require rebuild/restart.

Safe manual preview: /tests/fixtures/todos.html on the running dev server uses local fake Canvas data.

Originating Buzz channel: 9b0b1a4c-bb27-4b93-beb5-c55557161067 (cheap-todo-plugin), thread 7150a350f8f2466f46c1882cdfae61ff6d826c7c5708f63d0e7cae7230454130.

Carl added 2 commits September 24, 2026 10:20
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
@wesbillman
wesbillman requested review from a team and comp615 as code owners September 24, 2026 16:23
Carl added 3 commits September 24, 2026 10:39
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Comment thread src/bundled/todos/TodosPanel.tsx Outdated
Carl added 4 commits September 24, 2026 11:19
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
@wesbillman

Copy link
Copy Markdown
Collaborator Author
Screenshot 2026-09-24 at 11 33 47 AM Screenshot 2026-09-24 at 11 34 15 AM

@kalvinnchau kalvinnchau left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Approved at Kalvin's explicit direction, accepting the outstanding findings below. This approval does not mean the findings are fixed or the missing validation has passed.

Comment thread src/bundled/todos/TodosPanel.tsx Outdated
Comment thread src/bundled/todos/TodosPanel.tsx
Comment thread src/bundled/todos/TodosPanel.test.tsx
Signed-off-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
@wesbillman
wesbillman merged commit 842c1d3 into main Sep 24, 2026
12 checks passed
@wesbillman
wesbillman deleted the carl/canvas-todos branch September 24, 2026 19:15
morgmart pushed a commit that referenced this pull request Sep 24, 2026
…rs-support

* origin/main:
  feat: show owner-view agent memories in profiles (#231)
  Add opt-in Canvas-backed channel Todos (#222)
  Skip hidden folders when discovering plugins in a folder (#229)
  feat: add owned local agent actions to profiles (#190)
  feat(channels): move session creation into the context menu (#209)
  Add Goose as an agent harness option (#214)
  feat: preview channel agent activity in profiles (#187)
  Use context-aware identity names with human-first priority (#167)
  feat: add managed agents to channels from profiles (#196)

Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>

# Conflicts:
#	src/features/relay/outbox.ts
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