Repository navigation
feat(web): Lazurio shell slot (rail, column head, Buddy) - #37
Conversation
4c2c427 to
1879147
Compare
agentrozjedemeai
left a comment
There was a problem hiding this comment.
Reviewed the exact head 1879147 independently. The v1 shell interface matches the loader, elements, active="chat", and rail-width property. The :defined containment confines the fixed desktop sidebar only when the rail exists; the React 19 ref/ResizeObserver path measures the column head and moves the open desktop toggle, with a zero-height fallback when the shell/observer is absent. The upstream brand and routes remain untouched.
Local git diff --check and the release-contract suite passed (12/12). Lazurio Fork CI and archive checks completed successfully on this SHA. The three Greptile conversations are resolved after checking the two fixes and the withdrawn width finding. I did not independently repeat the browser screenshots or the 203 web tests; those are author evidence.
Integration note, not a code objection: current main includes #36, and the PR now conflicts in the workflow, release contract, and runbook. This approval is only for the pinned head. Resolve the conflicts without broadening scope, then rerun exact-head review/checks/conversation gates on the resulting new head before any merge. No merge performed here.
Place the Lazurio shell in the web client, as OpenMausBot #20 does for MausBot. The shell itself (/.lazurio/shell.js, Web Components with Shadow DOM) is served by the Environment's Launchpad; outside Lazurio the script is absent, the elements stay undefined and the client behaves as upstream. - index.html: the same-origin loader (vite-ignore), <lazurio-rail> before #root, <lazurio-buddy> after it, and #root padding-left by --lazurio-rail-width. T3's sidebar and its toggle are position: fixed, so with the rail defined the sidebar wrapper becomes their containing block and they sit beside the rail instead of under it. - AppSidebarLayout.tsx: <lazurio-column-head active="chat"> as the first child of the sidebar, above the upstream top row (thread, legacy and settings sidebars alike); the fixed sidebar toggle moves down with that row while the desktop sidebar is open. - Both files join allowed_upstream_changes; the release contract test keeps the slot across rebuilds on new upstream tags; the runbook describes it. Closes #33 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1879147 to
0827ac7
Compare
agentrozjedemeai
left a comment
There was a problem hiding this comment.
Exact-head re-review of 0827ac7 after #35 landed on main. The slot source blobs (apps/web/index.html and AppSidebarLayout.tsx) are identical to the previously approved 1879147 head. The rebase retains both overlays in the CI allowlist, release-contract suite, and runbook (one entry each); the shell slot remains the sole PR delta against current main. Local git diff --check and the contract suite pass (13/13). All three review conversations are resolved; no reviewer is pending. Web dependencies were not installed in this isolated clone, so I did not repeat tsc, formatting, or browser verification. At this review, the server/web compatibility and darwin-arm64 archive CI checks are still running; approval is for the code on this exact commit, not a claim that CI/merge gates are green. No merge performed.
Closes #33.
Why
Chat, Apps and Automate share one Lazurio shell: the rail of spaces on the left, and at the top of each app's own left column the Environment picker, the Settings gear and the switch Chat · Apps · Automate. Buddy's bubble comes later. The shell is one library in LazurioPlatform (decision F36), served by the Environment's Launchpad at
/.lazurio/shell.json every origin of the Environment. This fork only places the elements and fetches no data, so a new rail, picker or data source never needs a fork release. It mirrors Lazurio/OpenMausBot#20, which did the same for MausBot.What changes (two upstream files)
apps/web/index.html:<script type="module" src="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/.lazurio/shell.js" vite-ignore>. Vite leaves the tag in place (it drops only thevite-ignoreattribute) and bundles nothing. Checked with a realvite build.<lazurio-rail>before#root,<lazurio-buddy>after it.#root { box-sizing: border-box; padding-left: var(--lazurio-rail-width, 0px); }. Padding, not margin.ui/sidebar.tsx) and its toggle areposition: fixedagainst the window, so padding alone left them under the rail. That showed up in the first visual check. When the rail is defined, the sidebar wrapper becomes their containing block:lazurio-rail:defined ~ #root [data-slot="sidebar-wrapper"] { contain: layout paint; }. Without the shell the selector never matches.apps/web/src/components/AppSidebarLayout.tsx:createElement("lazurio-column-head", { active: "chat", ref })is the first child of the left sidebar, above the upstream top row (the toggle and the "T3 Code" brand). The brand and all controls stay (root decision 0179 point 6; placement clarified on Lazurio shell slot: load /.lazurio/shell.js and place the rail, the app switch and Buddy (upstream look stays) #33). Placing it here rather than inSidebar.tsxcovers the thread sidebar, the legacy sidebar and the Settings nav from one spot.SidebarControl) is alsoposition: fixedat the top edge, so it would cover the column head. While the desktop sidebar is open, the toggle moves down by the column head's measured height (aResizeObserveron the element). With the shell absent (or withoutResizeObserver) the height is 0 and nothing moves. The mobile sheet has its own toggle and is unaffected.allowed_upstream_changesgets both files as separate lines under one reason comment.ui/sidebar.tsxstill hasdata-slot="sidebar-wrapper"), the rail, Buddy, the column head as the sidebar's first child (exactly once), its measurement and the toggle'stopoffset. A rebuild on a new upstream tag that loses any of these fails CI. I confirmed this by reverting each file locally: the test fails.docs/operations/lazurio-fork-release.md): the "Lazurio shell" section describes the slot as built, and the overlay table gets a row for this commit.What does not change
/.lazurio/shell.js. The T3 server's SPA fallback (and the desktop protocol handler) answers withindex.html, the browser refuses it as a module and logs one console error. The elements stay undefined, the rail width is 0, the column head has height 0, the containment rule doesn't apply, and the layout is pixel-identical to upstream (measured: toggle at (13,12), brand at (52,12), same as before).langis not set.overflowcannot clip it. That belongs to the shell library, not this fork.Verification
node --test scripts/lazurio-release-contract.test.mjs: 12/12 pass.lazurio-fork-ci.yml, run locally against upstreamv0.0.45(6c8fed35): no unexpected upstream changes.vp fmt --check: clean.tsc --noEmitinapps/web: ok.vp lintonAppSidebarLayout.tsx: one pre-existing upstream warning (set-state-in-effectat the fullscreen effect), nothing new.vp test run src/themeBoot.test.ts src/bundledDev.test.ts src/components/Sidebar.logic.test.ts src/components/SidebarStageBackdrop.test.tsx(the index.html and sidebar tests): 4 files, 203 tests pass.vp buildof@t3tools/web: the builtindex.htmlkeeps<script type="module" src="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/.lazurio/shell.js">, the rail, Buddy and the style. There is no.lazuriooutput indist.channel: "chrome"):node apps/server/src/bin.ts serve, isolated--base-dir, a throwaway git project) served the built web UI./.lazurio/shell.jswas answered by a route stub that defines a 64 px fixed rail (sets--lazurio-rail-width: 64px, z-index 40 like the Platform rail) and a 96 px block column head.#rootpadding-left is 64px. The sidebar starts at x=64. The column head is at (64,0), 96 px tall, and is the first child ofsidebar-inner. The upstream top row is at y=96, with the toggle at (77,108) and the brand at (116,108). Document, body and#rootscroll widths all equal 1512, so there is no horizontal overflow./settings: the column head is at the top of the Settings nav, the same way.body) opens over the rail, with the column head at its top above the sheet's own top row.Depends on
/.lazurio/*on thet3code.origin.src/shell/interface.ts).Notes / risks
allowed_upstream_changes, the contract test and the runbook. Whichever merges second needs a trivial rebase.-lazurio.Nor preview release frommainfollows the runbook once this is merged.🤖 Generated with Claude Code