Repository navigation
Conversation
…p starts The sidebar's layout read once at connect; a failed read left the default showing for the launch, and the next change saved the default over the stored file. The read is now tried again (lib/poll, and at once on a reconnect) until it arrives, and nothing can change the layout before then: Customize sidebar… waits with a note, and other changes are refused with the same note. A change also keeps the place of pinned or hidden places that aren't available (a plugin off or still loading), and saves run one at a time, so a write that fails can't roll back a later one. The verify skill gains sidebar-layout-reload (mock) and sidebar-layout-restart.sh, which restarts a real laptop agent as the app asks for the layout and checks sidebar.json is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@Stener1 is attempting to deploy a commit to the seanbrydonio's projects Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
Author
|
Stener1 can't add labels here: could a maintainer add |
This branch has not been deployed
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.
Summary
After an update, the sidebar sometimes came back as the default layout: Customize sidebar's arrangement looked lost. The layout is read once, at connect, from the laptop agent (
GET /v1/app/sidebar). If that read failed, for example because the agent was restarting while the updated app started, the app kept the default for the whole launch and marked it loaded. The next change then saved the default oversidebar.json, which made the reset permanent.A failed read is now tried again until the stored layout arrives, and nothing can change the layout before that. More's Customize sidebar… is disabled with a note. Any other change shows the same note as a toast.
The PR also fixes two smaller problems on the same write path:
placeandmovesaved only the ids available at that moment. A pinned plugin that was off or still loading lost its place the next time anything else changed. Those ids now stay at their stored index.The file format doesn't change, and no Go code changes.
Same shape elsewhere, not changed here:
loadProjects(lib/project-groups.ts) also marks itself loaded after a failed read and never retries, so project sections can be missing for one launch. It can't overwrite the file the way the sidebar did, becausesaveProjectsre-reads the document before it writes. Its fallback "write what this window has" only applies when that re-read also fails, and then the PUT almost certainly fails too. A shared/v1/app/<key>sync could cover both later.Evidence
Real agent (
scripts/sidebar-layout-restart.sh). The script seedssidebar.jsonwith Kits pinned and Automations hidden. It runs a laptop agent of this checkout with an empty box, and stops the agent the moment the app sendsGET /v1/app/sidebar. The agent starts again 2 s later.origin/main's build): after the restart the app stays on the default layout. Kits isn't pinned and Automations is back.sidebar layout: The app lost its connection to the agent on this computer…in the console). It is tried again, and the stored layout appears.sidebar.jsonis byte-identical afterwards:{"ok":true,"sidebar_json_before":"4f21c652…af48","sidebar_json_after":"4f21c652…af48"}This reproduces the failure on a real agent restart that I timed into the read. That an update's restart actually lands in that window on a Mac is still the likely trigger, not a proven one: it is intermittent, and the app's other first reads succeeded in the reported launch.
Before the layout has loaded (mock,
drive.mjs sidebar-layout-reload,?failapp=sidebar).Tests:
e2e/sidebar-layout-load.spec.ts, new, passing): a pin survives a reload. The route fails, so the default shows, Customize is blocked and a change is refused. The route recovers, the stored layout appears and Customize opens.plugin-nav-badgesandrailstill pass.nav-core.test.ts, 15 tests):arrangeandmigrate. A save with a plugin id unavailable keeps that id's place. A save before a successful load is refused and writes nothing. A missing file counts as loaded. Saves run in turn, so an earlier failed write can't undo a later one.Checks run:
pnpm test(643),tsc,tsc -p e2e,check:titles,check:type,check:grid,check:csp,pnpm buildand the docs build. Not run:go vet/go test(no Go changes) andcargo check(no Rust changes).Verify skill:
features/sidebar-nav.mdgainsnav-layout-load.sidebar-layout-reloadandsidebar-layout-restart-live.scripts/agent-box.sh(a laptop agent with an empty box, on ports 9467/9468/7546) andscripts/sidebar-layout-restart.sh.?failapp=sidebarfails it until__mockApp.recover("sidebar").Merge Danger
Door: two-way
The only side effect is
~/.berth/app/sidebar.json, and its format is unchanged, so reverting leaves a valid file. Ids kept for unavailable plugins are already skipped byarrange()at render.Blast Radius: sidebar
The changes are all in the sidebar's places: the list, the rail and zen's switcher. Customize sidebar can't be used until the layout loads; if the agent never answers, it stays disabled with a note while the app keeps retrying. A first-run user with no file isn't affected: a missing file counts as loaded.
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.