Skip to content

refactor(app): extract layout shell frame - #1042

Merged
Astro-Han merged 4 commits into
devfrom
codex/layout-shell-frame
Jun 1, 2026
Merged

refactor(app): extract layout shell frame#1042
Astro-Han merged 4 commits into
devfrom
codex/layout-shell-frame

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary

Refactors the next layout governance slice after #1036:

  • Groups registerLayoutCommands inputs into command-facing capabilities and actions instead of passing a broad layout-owned parameter bag.
  • Extracts the desktop shell JSX into LayoutShellFrame, keeping providers and state owners in layout.tsx.
  • Adds a layout command catalog unit test to lock command ids, keybinds, slash commands, and availability flags.

Why

This continues the layout.tsx owner extraction tracked by #606. PR #1036 moved command registration out of layout.tsx; this PR tightens that owner boundary and then moves the render shell into a focused frame component without changing workspace, session, or startup behavior.

Related Issue

Related: #606

Human Review Status

Pending

Review Focus

Please focus on whether the new LayoutShellFrame props are still a render-shell boundary rather than a leaked copy of layout.tsx internals, and whether the command capability groups keep command behavior unchanged.

Risk Notes

Visible shell geometry and settings takeover are touched. The PR intentionally does not move workspace CRUD, session window/prefetch ownership, boot effects, or the context providers.

How To Verify

bun install --frozen-lockfile: ok in the new worktree
bun run --cwd packages/app typecheck: ok
bun test --preload ./happydom.ts src/pages/layout/layout-commands.test.ts: 2 passed
bun test --preload ./happydom.ts src/shell-frame-contract.test.ts src/pages/layout/shell-navigation.test.ts: 15 passed
bun run --cwd packages/app snap app-shell: 1 passed, screenshot reviewed
bun run --cwd packages/app snap settings-shell: 1 passed, screenshot reviewed
PLAYWRIGHT_VIDEO=off bun run --cwd packages/app test:e2e -- e2e/app/palette.spec.ts: 6 passed
git diff --check: ok

Screenshots or Recordings

Snap grids reviewed locally:

  • docs/design/preview/screenshots/app-shell.png
  • docs/design/preview/screenshots/settings-shell.png

Checklist

  • Type label — this PR carries exactly one of bug, enhancement, task, documentation. Type labels are author-added; the labeler bot does NOT assign them. Add the label in the GitHub UI, then tick this.
  • Routing labels — this PR carries at least one of app, ui, platform, harness, ci. The labeler bot assigns these on PR open based on changed paths. Confirm the bot's choice (or override if wrong), then tick this.
  • Priority label — this PR carries exactly one of P0, P1, P2, P3. The priority-triage bot suggests one on PR open. Confirm or override, then tick this.
  • Human Review Status above is set to Pending, Approved by @<reviewer>, or Not required: <reason> (default is Pending; "not required" is restricted to bot-authored low-risk PRs).
  • I linked the related issue, or stated in Summary why there is no issue.
  • I described the review focus and any meaningful risks.
  • I replaced the example block in How To Verify with the real verification steps and the key result for each.
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
  • (conditional) I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
  • (conditional) I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
  • (conditional) I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant. Leave unticked only if none of those surfaces was touched.
  • I reviewed the final diff for unrelated changes and suspicious dependency changes.
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English.

Summary by CodeRabbit

  • New Features

    • Added ability to open the global configuration folder
  • Refactor

    • Redesigned desktop shell layout with enhanced sidebar resizing capabilities
    • Reorganized workspace creation and toggle commands
    • Restructured settings panel integration

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Astro-Han, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 54 minutes and 3 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a638ea27-05ed-4c13-881f-e91c691df136

📥 Commits

Reviewing files that changed from the base of the PR and between 20a589b and 948a55f.

📒 Files selected for processing (3)
  • packages/app/src/pages/layout/layout-shell-frame-geometry.ts
  • packages/app/src/pages/layout/layout-shell-frame.test.ts
  • packages/app/src/pages/layout/layout-shell-frame.tsx
📝 Walkthrough

Walkthrough

This PR refactors the desktop shell architecture by introducing a new LayoutShellFrame component to encapsulate shell rendering, and refactors layout command registration to use grouped action/capability contracts. The Layout page is updated to use the new component and extracted helper functions instead of inline shell JSX.

Changes

Shell architecture refactor

Layer / File(s) Summary
LayoutShellFrame component and debug infrastructure
packages/app/src/pages/layout/layout-shell-frame.tsx, packages/app/src/pages/layout/layout-shell-frame-debug.ts, packages/app/src/pages/layout/layout-shell-frame.test.ts
New LayoutShellFrame component renders titlebars, resizable sidebar, main content with settings overlay toggle, and conditional debug bar. shouldShowLayoutDebugBar() helper safely checks dev environment and browser availability before rendering debug UI; includes test coverage for non-browser execution.
Layout commands refactoring with action delegation
packages/app/src/pages/layout/layout-commands.ts, packages/app/src/pages/layout/layout-commands.test.ts
registerLayoutCommands input contract refactored from flat SDK/state dependencies to grouped contracts: copy, appearance, and action groups (viewActions, navigationActions, settingsActions, workspaceActions, systemActions). All command handlers rewired to delegate behavior to these actions instead of performing logic inline. Test coverage verifies command catalog ordering and capability-driven disabling.
Layout page: shell extraction and helpers
packages/app/src/pages/layout.tsx
Imports reorganized: removed shell UI components, added LayoutShellFrame. State initialization simplified by removing nav element. New helpers: openGlobalConfigFolder() resolves config path via SDK and opens with platform.openPath; createCurrentWorkspace() and toggleCurrentWorkspace() for workspace actions; handleSidebarResize() debounced state/API updates. Large inline shell JSX replaced with LayoutShellFrame configuration providing sidebar, main, and settings slots with resize/overlay wiring.
Shell frame contract validation
packages/app/src/shell-frame-contract.test.ts
Shell frame contract tests extended to validate LayoutShellFrame: verifies --shell-titlebar-current-height CSS variable presence, correct shellAttrs() and isMacShell() usage. New component added to "visual shell files" guard list, ensuring platform identity is not used for appearance keying.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Astro-Han/pawwork#346: Overlapping sidebar layout wiring refactoring—one PR replaces sidebar shell rendering with LayoutShellFrame and centralized resize handling, the other removes extra sidebar mode state machine in favor of docked/hidden modes.
  • Astro-Han/pawwork#417: Aligned on desktop shell contract updates—both modify shell frame contract expectations and shellAttrs/titlebar CSS variable assertions for E2E consistency.
  • Astro-Han/pawwork#951: Both update desktop Layout settings takeover wiring to use new SettingsShell/SettingsTab flow controlled by the updated layout shell overlay.

Poem

🐰 A frame for the shell, a home for the UI,
Commands now delegate, no logic to spy,
Sidebar resizes with grace, settings slide free,
Desktop refactored—as tidy as can be!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor(app): extract layout shell frame' clearly and concisely summarizes the main change: extracting the desktop shell JSX into a LayoutShellFrame component. It directly reflects the primary refactoring objective.
Description check ✅ Passed The PR description is comprehensive and follows the template well. It includes a clear summary of changes, explains the motivation (continuation of #606 and #1036), links the related issue, provides human review status, articulates review focus, documents risks, includes detailed verification steps with results, and confirms all checklist items are completed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/layout-shell-frame

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Astro-Han Astro-Han added task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work app Application behavior and product flows ui Design system and user interface P2 Medium priority labels Jun 1, 2026
@github-actions github-actions Bot added the ui Design system and user interface label Jun 1, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested priority: P2 (includes user-path files (packages/app/src/pages/layout.tsx, packages/app/src/pages/layout/layout-commands.test.ts, packages/app/src/pages/layout/layout-commands.ts, packages/app/src/pages/layout/layout-shell-frame.tsx, packages/app/src/shell-frame-contract.test.ts)).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the desktop layout by extracting the shell frame JSX into a new LayoutShellFrame component and decoupling the layout commands registration from specific context hooks via structured action callbacks. It also adds unit tests for the layout commands. The review feedback correctly points out a potential ReferenceError when accessing window directly during render in LayoutShellFrame, which could cause crashes in SSR or test environments, and suggests a defensive check.

Comment thread packages/app/src/pages/layout/layout-shell-frame.tsx Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/pages/layout/layout-shell-frame.tsx`:
- Around line 37-41: Compute a single normalized sidebar width and reuse it
everywhere instead of calling props.sidebar.width() directly: create a
normalized value that clamps the visible width between props.sidebar.minWidth
and props.sidebar.maxWidth (and yields 0 when props.sidebar.visible() is false),
use that normalized value to set the CSS variable "--dialog-left-margin" and to
provide the createMemo "side" value so all geometry paths share the same clamped
width and cannot overflow when restoring persisted state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 499f6be7-615f-41fa-af00-d148fe585312

📥 Commits

Reviewing files that changed from the base of the PR and between 05d8ba1 and 20a589b.

📒 Files selected for processing (7)
  • packages/app/src/pages/layout.tsx
  • packages/app/src/pages/layout/layout-commands.test.ts
  • packages/app/src/pages/layout/layout-commands.ts
  • packages/app/src/pages/layout/layout-shell-frame-debug.ts
  • packages/app/src/pages/layout/layout-shell-frame.test.ts
  • packages/app/src/pages/layout/layout-shell-frame.tsx
  • packages/app/src/shell-frame-contract.test.ts

Comment thread packages/app/src/pages/layout/layout-shell-frame.tsx Outdated
@Astro-Han
Astro-Han merged commit 3ade93a into dev Jun 1, 2026
39 of 40 checks passed
@Astro-Han
Astro-Han deleted the codex/layout-shell-frame branch June 1, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Application behavior and product flows P2 Medium priority task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant