Skip to content

feat: add dynamic right-panel shell tabs#110

Merged
Astro-Han merged 6 commits into
devfrom
codex/dynamic-shell-tabs
Apr 22, 2026
Merged

feat: add dynamic right-panel shell tabs#110
Astro-Han merged 6 commits into
devfrom
codex/dynamic-shell-tabs

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Apr 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add dynamic shell tab state for the session right panel, with Status pinned and Review, Files, Terminal, and Context opened on demand.
  • Migrate legacy right-panel state into the new shell-tab model while preserving existing active review and file-tab behavior.
  • Render dynamic shell tabs with close, reorder, and add-tab controls, and route callers through the shell-tab API.

Why

The right panel previously showed fixed shell tabs even when a user only needed one surface. Dynamic shell tabs make the panel match the active workflow while keeping old persisted layouts compatible.

Related Issue

None.

How To Verify

cd packages/app
bun run typecheck
bun run test:unit

Local screenshot smoke was also run with a temporary E2E spec. The captured screenshot is available in the Codex session at /tmp/pawwork-dynamic-shell-tabs-e2e.png.

Screenshots or Recordings

Local E2E screenshot reviewed in Codex session: /tmp/pawwork-dynamic-shell-tabs-e2e.png.

Checklist

  • I ran the relevant verification steps
  • I tested visible changes manually when needed
  • I am targeting the dev branch

Summary by CodeRabbit

  • New Features

    • Draggable/reorderable right‑panel tabs (status stays pinned), plus an "Add tab" menu and new "context" tab; middle‑click/menu tab close support; improved desktop terminal toggle.
  • Bug Fixes

    • More consistent side‑panel/tab behavior when opening files, comments, or toggling terminals; improved tab selection fallbacks.
  • Refactor

    • Simplified tab/panel management and persisted-state migration; added i18n key for "Add tab" and a small record-type utility.
  • Tests

    • Expanded unit and e2e coverage for tab migration, behavior, and side‑panel flows.

@Astro-Han Astro-Han added enhancement New feature or request P2 Medium priority app Application behavior and product flows ui Design system and user interface labels Apr 21, 2026
@coderabbitai

coderabbitai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@Astro-Han has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 33 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 33 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8f9a01ab-533b-4e62-a173-7a1d3cb31679

📥 Commits

Reviewing files that changed from the base of the PR and between 7123ba4 and 0c47281.

📒 Files selected for processing (32)
  • packages/app/e2e/app/home.spec.ts
  • packages/app/e2e/files/file-tree.spec.ts
  • packages/app/src/components/dialog-select-file.tsx
  • packages/app/src/components/prompt-input.tsx
  • packages/app/src/components/session-context-usage.tsx
  • packages/app/src/components/session/index.ts
  • packages/app/src/components/session/session-sortable-shell-tab.tsx
  • packages/app/src/context/global-sync.tsx
  • packages/app/src/context/global-sync/bootstrap.ts
  • packages/app/src/context/layout.shell-tabs.test.ts
  • packages/app/src/context/layout.test.ts
  • packages/app/src/context/layout.tsx
  • packages/app/src/i18n/en.ts
  • packages/app/src/i18n/parity.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/pages/session.tsx
  • packages/app/src/pages/session/close-session-tab.test.ts
  • packages/app/src/pages/session/close-session-tab.ts
  • packages/app/src/pages/session/file-tab-scroll.test.ts
  • packages/app/src/pages/session/file-tab-scroll.ts
  • packages/app/src/pages/session/helpers.test.ts
  • packages/app/src/pages/session/helpers.ts
  • packages/app/src/pages/session/migrate-session-view.test.ts
  • packages/app/src/pages/session/migrate-session-view.ts
  • packages/app/src/pages/session/right-panel-tabs.test.ts
  • packages/app/src/pages/session/right-panel-tabs.ts
  • packages/app/src/pages/session/session-side-panel.test.tsx
  • packages/app/src/pages/session/session-side-panel.tsx
  • packages/app/src/pages/session/terminal-shell-tab.ts
  • packages/app/src/pages/session/use-session-commands.test.ts
  • packages/app/src/pages/session/use-session-commands.tsx
  • packages/app/src/utils/is-record.ts
📝 Walkthrough

Walkthrough

Adds a shell-tab system for the right-side panel: new "context" tab, sortable shell-tab components, shell-tab state primitives and migration logic, updated side-panel APIs (openTab/closeTab/moveTab/toggleTab), and call-site updates plus tests and i18n for an "Add tab" UI.

Changes

Cohort / File(s) Summary
Shell tab components
packages/app/src/components/session/session-sortable-shell-tab.tsx, packages/app/src/components/session/index.ts
New ShellTab and SortableShellTab components; re-exported from session index.
Right-panel tab types & helpers
packages/app/src/pages/session/right-panel-tabs.ts, packages/app/src/pages/session/right-panel-tabs.test.ts
Add "context" tab, metadata/constants, type-guard/coercion, and shell-tab APIs: normalizeShellTabs, openShellTab, closeShellTab, toggleShellTab, moveShellTab; tests added.
Layout / side-panel state
packages/app/src/context/layout.tsx, packages/app/src/context/layout.shell-tabs.test.ts
Persist openShellTabs, add migration helpers, expose sidePanel.openTabs/openTab/closeTab/moveTab, and switch tab operations to shell-tab primitives; tests for shell-tab transitions.
Session migration
packages/app/src/pages/session/migrate-session-view.ts, packages/app/src/pages/session/migrate-session-view.test.ts
New migration pipeline to convert legacy sessionView/sessionTabs to shell-tab shape with many edge-case tests and idempotency checks.
Session UI & interactions
packages/app/src/pages/session/session-side-panel.tsx, packages/app/src/pages/session/session-side-panel.test.tsx
Render tabs from openTabs()/metadata, add sortable reordering, "Add tab" dropdown that calls view().sidePanel.openTab(...), update icon rendering and tab control flow; tests/mocks updated.
Session command & terminal helpers
packages/app/src/pages/session/use-session-commands.tsx, packages/app/src/pages/session/terminal-shell-tab.ts, packages/app/src/pages/session/use-session-commands.test.ts
Introduce toggleDesktopTerminal, delegate close/toggle flows to closeSessionTab/toggleDesktopTerminal, use sidePanel.openTab for terminal/review.
Close-tab utility & tests
packages/app/src/pages/session/close-session-tab.ts, packages/app/src/pages/session/close-session-tab.test.ts
New canCloseSessionTab and closeSessionTab to centralize session tab-closing logic; tests added.
Helpers & scroll sync
packages/app/src/pages/session/helpers.ts, packages/app/src/pages/session/helpers.test.ts, packages/app/src/pages/session/file-tab-scroll.ts, packages/app/src/pages/session/file-tab-scroll.test.ts
Remove legacy context fallback from active/closable tab logic and context-dependent scroll behavior; adjust tests accordingly.
Dialog / prompt / page updates
packages/app/src/components/dialog-select-file.tsx, packages/app/src/components/prompt-input.tsx, packages/app/src/pages/session.tsx, packages/app/src/components/session-context-usage.tsx
Replace conditional open+setTab sequences with view().sidePanel.openTab(...)/toggleTab(...); remove contextOpen gating where applicable.
I18n
packages/app/src/i18n/en.ts, packages/app/src/i18n/zh.ts, packages/app/src/i18n/parity.test.ts
Add "session.panel.addTab" translations and parity test entry.
Tests & e2e updates
packages/app/src/**/*.test.*, packages/app/e2e/*
Add/adjust many unit tests for migration, shell-tab behavior, command flows; e2e selectors changed to use accessible roles for right-panel.
Utilities / query changes
packages/app/src/utils/is-record.ts, packages/app/src/context/global-sync.tsx, packages/app/src/context/global-sync/bootstrap.ts
New isRecord type-guard; replace skipToken usage with an inactiveQueryFn + enabled: false in several query configs.

Sequence Diagram

sequenceDiagram
    actor User
    participant SessionSidePanel as Session<br/>Side Panel
    participant DropdownMenu as Dropdown<br/>Menu
    participant View as View<br/>API
    participant ShellTabs as Shell Tabs<br/>State
    participant ShellTab as ShellTab<br/>Component

    rect rgba(100, 150, 255, 0.5)
    Note over User,ShellTabs: Open existing shell tab (review)
    User->>SessionSidePanel: Click "review" tab
    SessionSidePanel->>View: openTab("review")
    View->>ShellTabs: openShellTab(state, "review")
    ShellTabs-->>View: updated state with "review"
    View-->>SessionSidePanel: tab updated
    SessionSidePanel-->>User: "review" tab shown
    end

    rect rgba(150, 200, 100, 0.5)
    Note over User,DropdownMenu: Add new tab via dropdown
    User->>SessionSidePanel: Click "Add tab"
    SessionSidePanel->>DropdownMenu: Render available tabs
    User->>DropdownMenu: Select "context"
    DropdownMenu->>View: openTab("context")
    View->>ShellTabs: openShellTab(state, "context")
    ShellTabs-->>View: "context" added
    end

    rect rgba(200, 100, 150, 0.5)
    Note over User,ShellTab: Reorder tabs via drag
    User->>ShellTab: Drag "files"
    ShellTab->>View: moveTab("files", 2)
    View->>ShellTabs: moveShellTab(state, "files", 2)
    ShellTabs-->>View: reordered tabs
    View-->>ShellTab: order updated
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

P2

Poem

🐰 I hopped in fast to sort the stacks,

Tabs that wobble now find their tracks.
Drag, drop, migrate — new tabs to add,
Review and Context, no longer sad.
A tiny leap; the shell's ironclad!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% 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 PR title 'feat: add dynamic right-panel shell tabs' clearly and concisely describes the main change—introducing dynamic shell tab functionality to the right panel, following Conventional Commits format.
Description check ✅ Passed The PR description includes all major template sections: a clear summary of changes, explanation of why the changes were made, related issue reference, comprehensive verification steps with specific commands, and a completed checklist confirming the author ran verification and tested changes manually.
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/dynamic-shell-tabs

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

@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 introduces a new shell tab system for the right utility panel, allowing for multiple manageable tabs including Status, Files, Review, Terminal, and Context. The implementation includes new UI components for sortable tabs, a dropdown menu for adding tabs, and comprehensive migration logic for legacy session states. Feedback identifies a logic error in the toggleShellTab function that prevents the panel from closing when an active tab is toggled, and a regression in openReviewPanel where the 'review' tab is not explicitly activated.

Comment thread packages/app/src/pages/session/right-panel-tabs.ts
Comment thread packages/app/src/pages/session/session-side-panel.tsx

@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: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app/src/context/layout.tsx`:
- Around line 223-227: The current migratedRightPanel falls through to undefined
for older layouts because it returns non-record rightPanel values as-is; change
the logic so when rightPanel is null/undefined you return an object that
preserves the legacy open state by calling legacyRightPanelOpened(review,
fileTree) (i.e., set opened to legacyRightPanelOpened(review, fileTree) and
merge with the default/rightPanel shape), while still keeping the existing
branches: if isRecord(rightPanel) migrate its opened field, and if rightPanel is
a boolean return it unchanged.

In `@packages/app/src/pages/session/migrate-session-view.ts`:
- Around line 90-95: The nested ternary that computes activeCandidate is hard to
read; extract this logic into a small helper (e.g., computeActiveTab or
resolveActiveCandidate) that takes the entry (or entry.sessionTabsRaw,
entry.migratedSidePanelTab, entry.reviewInSessionTabs) and returns "context" |
"review" | undefined using clear if/return branches. Replace the inline ternary
with a call to that helper (e.g., const activeCandidate =
resolveActiveCandidate(entry)) and keep the same precedence: prefer "context" if
sessionTabsRaw.active === "context", then map "changes" or "review" to "review",
otherwise fall back to migratedSidePanelTab or reviewInSessionTabs -> "review".

In `@packages/app/src/pages/session/right-panel-tabs.ts`:
- Around line 134-142: The moveShellTab function doesn't validate the
destination index and can move tabs before the pinned "status" tab; update
moveShellTab (and its use of ShellTabState.openShellTabs and normalizeShellTabs)
to clamp the incoming to index into the valid range so the tab never lands
before the pinned tab: compute a clampedTo = Math.min(Math.max(to, 1),
state.openShellTabs.length - 1) (or equivalent) before performing the splice and
use clampedTo in place of to; leave the early returns for target === "status"
and from === -1 unchanged.

In `@packages/app/src/pages/session/session-side-panel.tsx`:
- Around line 119-121: openReviewPanel currently only opens the side panel but
doesn't activate the "review" tab, so newly opened files are hidden under the
Tabs.Content value="review" branch; modify openReviewPanel to first select the
"review" panel/tab via the sidePanel selector (e.g. call
view().sidePanel.select("review") or the equivalent select method on sidePanel)
and then ensure the panel is opened (open it only if not already opened) so the
review shell is active before file tabs are opened.

In `@packages/app/src/pages/session/terminal-shell-tab.ts`:
- Around line 16-21: The toggleDesktopTerminal function currently calls
view.sidePanel.toggleTab("terminal") and then directly calls
terminal.open()/terminal.close(), which duplicates the state update performed by
the createEffect in session-side-panel (which also syncs terminal state based on
the side panel tab); if the immediate-call is intentional for UI responsiveness,
add a brief clarifying comment above toggleDesktopTerminal explaining that
terminal.open()/close() are called immediately to provide instant feedback while
the createEffect in session-side-panel.tsx ensures global synchronization and is
idempotent, otherwise remove the direct terminal.open()/close() calls and rely
solely on the createEffect to manage terminal 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: abd5611a-9c1a-4868-b2ec-5917342c569b

📥 Commits

Reviewing files that changed from the base of the PR and between 63a8a52 and d23bcdf.

📒 Files selected for processing (27)
  • packages/app/src/components/dialog-select-file.tsx
  • packages/app/src/components/prompt-input.tsx
  • packages/app/src/components/session-context-usage.tsx
  • packages/app/src/components/session/index.ts
  • packages/app/src/components/session/session-sortable-shell-tab.tsx
  • packages/app/src/context/layout.shell-tabs.test.ts
  • packages/app/src/context/layout.test.ts
  • packages/app/src/context/layout.tsx
  • packages/app/src/i18n/en.ts
  • packages/app/src/i18n/parity.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/pages/session.tsx
  • packages/app/src/pages/session/close-session-tab.test.ts
  • packages/app/src/pages/session/close-session-tab.ts
  • packages/app/src/pages/session/file-tab-scroll.test.ts
  • packages/app/src/pages/session/file-tab-scroll.ts
  • packages/app/src/pages/session/helpers.test.ts
  • packages/app/src/pages/session/helpers.ts
  • packages/app/src/pages/session/migrate-session-view.test.ts
  • packages/app/src/pages/session/migrate-session-view.ts
  • packages/app/src/pages/session/right-panel-tabs.test.ts
  • packages/app/src/pages/session/right-panel-tabs.ts
  • packages/app/src/pages/session/session-side-panel.test.tsx
  • packages/app/src/pages/session/session-side-panel.tsx
  • packages/app/src/pages/session/terminal-shell-tab.ts
  • packages/app/src/pages/session/use-session-commands.test.ts
  • packages/app/src/pages/session/use-session-commands.tsx
💤 Files with no reviewable changes (1)
  • packages/app/src/pages/session/file-tab-scroll.test.ts

Comment thread packages/app/src/context/layout.tsx Outdated
Comment thread packages/app/src/pages/session/migrate-session-view.ts Outdated
Comment thread packages/app/src/pages/session/right-panel-tabs.ts
Comment thread packages/app/src/pages/session/session-side-panel.tsx
Comment thread packages/app/src/pages/session/terminal-shell-tab.ts

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Nitpick Review

All CI checks pass. I addressed the low-risk consistency items that were worth folding into this PR:

  • migrate-session-view.ts now reuses same() instead of keeping a local arraysEqual helper.
  • right-panel-tabs.ts now documents why coerceLegacySidePanelTab can return undefined while migrateLegacyRightPanelTab returns a concrete fallback.

Remaining observations are intentionally left as follow-up-level cleanup, not blockers:

  • isPlainObject could eventually be consolidated with other local isRecord helpers, but introducing a shared utility would broaden this PR.
  • RightPanelShellIconName is a small convenience alias. Keeping it is clearer than inlining the union everywhere.
  • resolveActiveCandidate remains private and is covered through migrateSessionView behavior tests. Exporting it only for direct tests would expand the module API without much value.

The implementation is ready to merge.

@Astro-Han

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Astro-Han Astro-Han force-pushed the codex/dynamic-shell-tabs branch from c74b11f to 64c8806 Compare April 22, 2026 07:11
Comment thread packages/app/src/pages/session/migrate-session-view.ts Outdated
Comment thread packages/app/src/pages/session/migrate-session-view.ts
Comment thread packages/app/src/pages/session/session-side-panel.tsx
Comment thread packages/app/src/pages/session/terminal-shell-tab.ts
Comment thread packages/app/src/pages/session/helpers.ts
Comment thread packages/app/src/pages/session/right-panel-tabs.ts
Comment thread packages/app/src/pages/session/close-session-tab.ts
Comment thread packages/app/src/pages/session/migrate-session-view.test.ts
Comment thread packages/app/src/pages/session/migrate-session-view.ts Outdated
Comment thread packages/app/src/pages/session/right-panel-tabs.ts
@Astro-Han Astro-Han force-pushed the codex/dynamic-shell-tabs branch from 64c8806 to e0170da Compare April 22, 2026 08:13
@Astro-Han Astro-Han added P3 Low priority and removed P2 Medium priority labels Apr 22, 2026

@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: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app/e2e/files/file-tree.spec.ts`:
- Around line 16-18: The test currently uses page.getByRole("tablist").first()
(stored in shellTabList) which can grab the wrong tablist; instead scope the
lookup to the right utility panel before selecting the tablist: locate the
right-utility panel via a stable semantic selector (e.g., a
data-component/data-action attribute or a named landmark/role) and call
getByRole("tablist") or locator("role=tablist") on that panel element, then
click the last button and select the "Review" menu item; update references to
shellTabList to use this scoped panel.getByRole("tablist") to avoid ordering
flakiness.

In `@packages/app/src/components/prompt-input.tsx`:
- Around line 206-216: The side-panel openTab("review") call is duplicated;
hoist view().sidePanel.openTab("review") before the wantsReview branch so it's
executed once, then inside the branch only call
view().sidePanel.explorer.setTab("changes"), tabs().setActive("review"), and
queueCommentFocus(), and in the else branch only call
view().sidePanel.explorer.setTab("all") to avoid repeating openTab; use the
existing wantsReview variable to control which explorer tab and follow-up
actions run.

In `@packages/app/src/context/layout.tsx`:
- Around line 209-216: The code currently returns a bare boolean for legacy
rightPanel values which loses the stored open state; change the boolean branch
in migratedRightPanel to return an object instead (e.g., return { width:
DEFAULT_RIGHT_PANEL_WIDTH, opened: rightPanel }) so consumers expecting { width,
opened } see the correct opened value; keep the other branches using
legacyRightPanelOpened(rightPanel, review, fileTree), isRecord, and the existing
opened merge logic intact.

In `@packages/app/src/pages/session/migrate-session-view.ts`:
- Around line 99-114: The current validity check (activeIsValidInnerTab) allows
any file:// active value even if that file isn't present in rawAll, preventing
cleanup; update activeIsValidInnerTab to require that a file:// active also
exists in the rawAll list (i.e., rawActive === undefined || rawActive ===
"review" || (rawActive.startsWith("file://") && rawAll.includes(rawActive))).
Keep the later normalization using fileTabsOnly(rawAll) and the computed active
assignment (which already guards with all.includes(rawActive)), but change the
initial guard so entries with orphaned rawActive values fall into the cleanup
branch that sets sessionTabs[key] and toggles tabsShapeChanged.

In `@packages/app/src/pages/session/session-side-panel.tsx`:
- Around line 217-227: The handler handleShellDragOver computes the drop index
incorrectly for shell tabs: get fromIndex =
view().sidePanel.openTabs().indexOf(from) and toIndex =
view().sidePanel.openTabs().indexOf(to), then if fromIndex < toIndex decrement
toIndex by 1 (i.e. toIndex = toIndex - 1) before calling
view().sidePanel.moveTab(from, toIndex) so the splice-based moveTab inserts at
the hovered position the same way file tabs do; keep the existing guards
(isRightPanelTab checks and -1 checks).
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b14a9608-b435-43ca-81f5-50f23a39f4b6

📥 Commits

Reviewing files that changed from the base of the PR and between d23bcdf and e0170da.

📒 Files selected for processing (32)
  • packages/app/e2e/app/home.spec.ts
  • packages/app/e2e/files/file-tree.spec.ts
  • packages/app/src/components/dialog-select-file.tsx
  • packages/app/src/components/prompt-input.tsx
  • packages/app/src/components/session-context-usage.tsx
  • packages/app/src/components/session/index.ts
  • packages/app/src/components/session/session-sortable-shell-tab.tsx
  • packages/app/src/context/global-sync.tsx
  • packages/app/src/context/global-sync/bootstrap.ts
  • packages/app/src/context/layout.shell-tabs.test.ts
  • packages/app/src/context/layout.test.ts
  • packages/app/src/context/layout.tsx
  • packages/app/src/i18n/en.ts
  • packages/app/src/i18n/parity.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/pages/session.tsx
  • packages/app/src/pages/session/close-session-tab.test.ts
  • packages/app/src/pages/session/close-session-tab.ts
  • packages/app/src/pages/session/file-tab-scroll.test.ts
  • packages/app/src/pages/session/file-tab-scroll.ts
  • packages/app/src/pages/session/helpers.test.ts
  • packages/app/src/pages/session/helpers.ts
  • packages/app/src/pages/session/migrate-session-view.test.ts
  • packages/app/src/pages/session/migrate-session-view.ts
  • packages/app/src/pages/session/right-panel-tabs.test.ts
  • packages/app/src/pages/session/right-panel-tabs.ts
  • packages/app/src/pages/session/session-side-panel.test.tsx
  • packages/app/src/pages/session/session-side-panel.tsx
  • packages/app/src/pages/session/terminal-shell-tab.ts
  • packages/app/src/pages/session/use-session-commands.test.ts
  • packages/app/src/pages/session/use-session-commands.tsx
  • packages/app/src/utils/is-record.ts
💤 Files with no reviewable changes (1)
  • packages/app/src/pages/session/file-tab-scroll.test.ts

Comment thread packages/app/e2e/files/file-tree.spec.ts Outdated
Comment thread packages/app/src/components/prompt-input.tsx
Comment thread packages/app/src/context/layout.tsx
Comment thread packages/app/src/pages/session/migrate-session-view.ts
Comment thread packages/app/src/pages/session/session-side-panel.tsx
@Astro-Han Astro-Han force-pushed the codex/dynamic-shell-tabs branch from e0170da to 7123ba4 Compare April 22, 2026 09:37

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app/src/pages/session/close-session-tab.ts`:
- Around line 11-29: Replace the hardcoded "status" checks with the canonical
closability metadata from RIGHT_PANEL_TAB_META: import RIGHT_PANEL_TAB_META and
use RIGHT_PANEL_TAB_META[tab].closable (or equivalent) in both
canCloseSessionTab and closeSessionTab instead of comparing sidePanelTab() ===
"status"; when closing a shell tab call input.closeShellTab(shellTab) only if
RIGHT_PANEL_TAB_META[shellTab].closable is true, and return true after closing;
ensure you still prefer closing file tabs via input.closeFileTab(fileTab) first
and reference the same RIGHT_PANEL_TAB_META lookup in both functions so
enablement and behavior stay in sync.

In `@packages/app/src/pages/session/helpers.ts`:
- Around line 60-66: The normalized active tab (from input.normalizeTab(active))
is returned as long as it looks like a file tab, but it may be stale; update the
logic in the helper that computes the active/closable tab so that after
computing normalizedActive and verifying input.pathFromTab(normalizedActive),
you also check openedTabs().includes(normalizedActive) (or equivalent
membership) before returning it; this ensures input.tabs().active() entries are
guarded against orphaned/stale tabs the same way activeTab()/openedTabs() are
used elsewhere.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2ca61dbf-d0f6-4ea9-b7db-5c8e9dded31d

📥 Commits

Reviewing files that changed from the base of the PR and between e0170da and 7123ba4.

📒 Files selected for processing (32)
  • packages/app/e2e/app/home.spec.ts
  • packages/app/e2e/files/file-tree.spec.ts
  • packages/app/src/components/dialog-select-file.tsx
  • packages/app/src/components/prompt-input.tsx
  • packages/app/src/components/session-context-usage.tsx
  • packages/app/src/components/session/index.ts
  • packages/app/src/components/session/session-sortable-shell-tab.tsx
  • packages/app/src/context/global-sync.tsx
  • packages/app/src/context/global-sync/bootstrap.ts
  • packages/app/src/context/layout.shell-tabs.test.ts
  • packages/app/src/context/layout.test.ts
  • packages/app/src/context/layout.tsx
  • packages/app/src/i18n/en.ts
  • packages/app/src/i18n/parity.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/pages/session.tsx
  • packages/app/src/pages/session/close-session-tab.test.ts
  • packages/app/src/pages/session/close-session-tab.ts
  • packages/app/src/pages/session/file-tab-scroll.test.ts
  • packages/app/src/pages/session/file-tab-scroll.ts
  • packages/app/src/pages/session/helpers.test.ts
  • packages/app/src/pages/session/helpers.ts
  • packages/app/src/pages/session/migrate-session-view.test.ts
  • packages/app/src/pages/session/migrate-session-view.ts
  • packages/app/src/pages/session/right-panel-tabs.test.ts
  • packages/app/src/pages/session/right-panel-tabs.ts
  • packages/app/src/pages/session/session-side-panel.test.tsx
  • packages/app/src/pages/session/session-side-panel.tsx
  • packages/app/src/pages/session/terminal-shell-tab.ts
  • packages/app/src/pages/session/use-session-commands.test.ts
  • packages/app/src/pages/session/use-session-commands.tsx
  • packages/app/src/utils/is-record.ts
💤 Files with no reviewable changes (1)
  • packages/app/src/pages/session/file-tab-scroll.test.ts

Comment thread packages/app/src/pages/session/close-session-tab.ts
Comment thread packages/app/src/pages/session/helpers.ts
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 enhancement New feature or request P3 Low priority ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant