feat(workspace-rail): a persistent resizable rail of project tabs - #3
Draft
andreiverdes wants to merge 5 commits into
Draft
feat(workspace-rail): a persistent resizable rail of project tabs#3andreiverdes wants to merge 5 commits into
andreiverdes wants to merge 5 commits into
Conversation
setWorkspaceLabel's SINGLE_EMOJI required an \p{Extended_Pictographic}
base. A keycap is an ASCII digit, "#" or "*" followed by U+FE0F and
U+20E3, so "1️⃣" / "#️⃣" / "*️⃣" were rejected as "Icon must be a single
emoji." — while workspace-tab-dialog.tsx documents its free-text field
as accepting whatever the OS emoji picker produces, and the macOS
picker offers keycaps.
Adds a keycap alternative to the pattern. U+20E3 stays mandatory, so a
bare "1" or "#" is still rejected.
Found by case A5 of docs/testing/workspace-rail-test-plan.md.
…rface Adding a workspace on /workspaces left the rail unchanged; the tab only appeared after opening a project and waiting. A registry write raises no bd change signal, so the rail had three ways to learn anything: its mount fetch, the workspace cookie (which updates only the active highlight, not the list), and useSubscriptionChangeSignal — a bd poll. That poll was the wait. The rail's own add button worked only because workspace-rail-panel.tsx called refresh() in its own handler; the dashboard's handler updated its own cards, and the two share no state. Labels already hit this wall and solved it with a propagation channel (lib/workspace-labels.ts). Membership changes had no equivalent, so this adds the sibling channel and publishes from every membership mutation: both add dialogs (one wrapper covers the local, server and local-to- server paths), a successful bd init, and unregisterWorkspace, which covers removal from all three surfaces that offer it. The rail and workspaces-page both subscribe and re-read the registry. Subscribing the dashboard closes the mirror-image bug: an add or removal driven from the rail left its cards stale. The panel's own refresh() calls are gone so the channel is the single mechanism — no add path can be wired up while forgetting to announce. The event carries no payload, so consumers cannot drift from what a fresh read returns.
Every case ran. A1-A5 pass, B1-B6 and B8-B10 pass, and the pre-PR gates are green apart from C5, which is a no-op by configuration. B7 fails on a defect that reproduces byte-identically at the merge base, so it is not this change set's to block on. Records the evidence per case (timings, drill outcomes, the quantified cross-process lost updates) and writes up the three defects the plan surfaced: the keycap rejection and the stale rail, both now fixed, and B7's vanished-workspace-reads-as-empty, left documented with its root cause and the bdExec choke point a fix would use. Also notes why B4-B9 could not be automated: the client throws RpcUnavailableError without a Tauri runtime, and Tauri's macOS WKWebView is not CDP-attachable.
…mo gif The screenshot predated the rail, so the README described "a resizable rail of project tabs on the left" above an image with no rail in it. Replaces it with a capture of three workspaces (orbit, atlas, pulse) and adds a GIF underneath showing what a still cannot: switching projects, the warm switch keeping its view across Beads and Activity, and renaming a tab with an emoji. The demo workspaces are synthetic and their paths are mocked, so no local directory names ship in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Layer 3 of 3. Base:
pr2-workspace-switch(#2).A persistent rail of project tabs on the left: click to switch, current view preserved (browser-tab semantics — switching from Activity lands on Activity). Local
.beads/projects andserver://Dolt connections both appear. Tabs can be renamed and given an emoji, stored in the registry alongside the entry. Resizable 180–420px, collapses to icons, persists both, hidden below 768px where the layout is single-panel.It renders outside the startup gate deliberately, so it stays on screen while the gate re-checks during a switch instead of vanishing behind a spinner.
Testing
bun run testgreen at 407 server + 298 client. Beyond that, a plan covering what unit tests cannot observe — realbddata, real files, concurrency, scale, UI surfaces — is recorded indocs/testing/workspace-rail-test-plan.md. It found three defects unit coverage missed; two are fixed here:SINGLE_EMOJIrequired anExtended_Pictographicbase, but a keycap's base is an ASCII digit, so1️⃣/#️⃣/*️⃣were refused — while the dialog documents its field as accepting whatever the OS emoji picker produces. Fixed with a keycap alternative that still requires the enclosing U+20E3, so a bare1stays rejected.bdchange signal and membership changes had no propagation channel (labels already had one), so the tab appeared only when abdpoll fired. Fixed withlib/workspace-registry-events.ts, published from every membership mutation and consumed by both list-holding surfaces.Scale: a 100-workspace registry lists in 3.6ms with zero
bdspawns; 500 beads / 20 epics load in 388ms; the client LRU holds at most 6 payloads.Also replaces
docs/screenshot.png, which predated the rail, and adds a demo GIF.