Skip to content

refactor: simplify app sidebar boundary#88

Open
ALX99 wants to merge 4 commits into
masterfrom
refactor-simplify-app-sidebar-boundary
Open

refactor: simplify app sidebar boundary#88
ALX99 wants to merge 4 commits into
masterfrom
refactor-simplify-app-sidebar-boundary

Conversation

@ALX99

@ALX99 ALX99 commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Simplification

Inline the single-use Sidebar component into App and remove pi-web/src/web/components/sidebar.tsx.

Why the current design is overcomplicated

Sidebar only had one caller: App. It did not own state, effects, memoization, lifecycle behavior, styling logic, data transformation, or an independent public contract. It only unpacked the same state and actions objects from App and forwarded their fields to the real sidebar child components.

That added an extra ownership boundary and file to inspect without providing a reuse point or isolating behavior. Keeping the sidebar structure directly in App makes the top-level layout visible where the bridge state is read, while preserving the existing specialized child components.

Behavioral contract

The following behavior must remain unchanged:

  • App still calls useBridge() once and uses the same state and actions values.
  • The rendered top-level order remains sidebar, chat, composer, toast.
  • The sidebar still renders <aside id="sidebar"> with the same children in the same order.
  • ConnectionStatus still receives state.connected and state.reconnectAttempt.
  • SessionList still receives sessions, current path, new-session action, and switch-session action unchanged.
  • ModelPicker still receives the same models, selected model, search term, search setter, and model setter.
  • ThinkingPicker still receives the same thinking level, streaming-disabled state, and thinking setter.
  • Chat, Composer, and Toast props and conditional toast rendering are unchanged.
  • No protocol, persistence, configuration, logging, metrics, or external API behavior changes.

Before and after

Before:

  • App called useBridge() and passed the whole state and actions objects into Sidebar.
  • Sidebar immediately unpacked those objects and forwarded individual fields to ConnectionStatus, SessionList, ModelPicker, and ThinkingPicker.
  • Reviewers had to inspect both app.tsx and components/sidebar.tsx to see the top-level UI layout.

After:

  • App calls useBridge() and renders the same <aside id="sidebar"> directly.
  • The child component props are the same values previously passed by Sidebar.
  • pi-web/src/web/components/sidebar.tsx is removed.

Specific evidence:

  • Removed one pass-through component file: pi-web/src/web/components/sidebar.tsx.
  • Removed the Sidebar import from pi-web/src/web/app.tsx.
  • Preserved the same child component boundaries for connection status, sessions, model selection, and thinking level.
  • Reduced one component boundary and one prop-forwarding layer without changing DOM structure or event handlers.

Validation

Commands run:

  • git clone --depth 1 https://github.com/ALX99/dotfiles.git /tmp/dotfiles — failed in this environment because github.com could not be resolved by the shell environment.
  • GitHub repository inspection — passed.
  • Open PR search — passed; no existing open PR covered this App / Sidebar boundary.
  • Code search for Sidebar — passed; only app.tsx, components/sidebar.tsx, and CSS references were found.
  • Static diff review — passed; the JSX subtree from Sidebar was moved into App with the same child order and same prop expressions.
  • Branch fetch of pi-web/src/web/app.tsx — passed; confirmed the inlined sidebar structure is present.
  • Branch fetch of pi-web/src/web/components/sidebar.tsx — returned 404 as expected after deletion.

Because local dependency installation and test execution were unavailable from this runtime, I did not claim npm run typecheck, npm run build, or npm test results.

Risk assessment

The behavior-sensitive area is the top-level pi-web layout. The change is safe because it does not alter component implementations, state updates, reducer behavior, WebSocket bridge behavior, command dispatch, protocol guards, CSS selectors, or any persisted/configured data. The same aside#sidebar element and the same child components remain, with the same props and callbacks.

The main possible risk is an import/typecheck issue from manual editing. This is mitigated by keeping the imported component set exactly aligned with the moved JSX and by deleting only the now-unused pass-through component.

Scope

Intentionally not simplified:

  • ConnectionStatus, SessionList, ModelPicker, and ThinkingPicker; each still owns a distinct UI responsibility and keeping them separate avoids a broader rewrite.
  • Chat, Composer, and toast rendering; they are not part of the sidebar pass-through boundary.
  • Web bridge, reducer, protocol, and server logic; nearby areas already have open simplification or bug PRs and were left untouched.
  • CSS selectors; aside#sidebar is preserved, so no styling change is needed.

@ALX99 ALX99 force-pushed the master branch 4 times, most recently from 5cf571d to dd748db Compare July 10, 2026 12:22
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.

1 participant