feat(app): redesign Status panel with Git and Artifact sections#1013
feat(app): redesign Status panel with Git and Artifact sections#1013Astro-Han wants to merge 21 commits into
Conversation
Remove "files" from RightPanelStaticTab and its metadata, command palette entry, and keybind. Legacy persisted "files" values map to "status" via coerceLegacySidePanelTab and migrateLegacyRightPanelTab. Register the new "changes" icon (Imagen → Potrace pipeline, portrait 14×18 keyshape, document with +/− marks) for the Git environment section that replaces the standalone Files tab. Add i18n keys for the new Git and Artifact sections in en/zh.
Restructure the Status panel from two sections (Progress + Sources) to four (Progress → Git → Artifact → Sources). Git section shows three interactive rows: - Diff stats (+N/−N from session aggregate, click → Review panel) - Branch name (from sync.data.vcs, chevron for future branch picker) - Worktree indicator (tooltip with name/branch/location, click opens directory) — migrated from the titlebar PawworkWorktreeBadge which is removed from session-header.tsx Artifact section replaces the deleted Files tab with a compact list of session-produced files (filename + open/reveal buttons, hover + focus-within visibility). The Git section is conditionally hidden when not in a git repository. Artifact data flows from session-side-panel via SessionStatusPanel props as Accessor<FilesTabEntry[]>.
Adapt shell-tab, right-panel-tabs, helpers, migrate-session-view, command-palette, side-panel, and use-session-commands tests to the removal of the "files" static tab. Key changes: - Legacy "files" values in normalize/coerce/migrate tests now expect "status" fallback instead of passthrough - planShellTabReorder test uses review→context instead of the removed files→review pair - command-palette default items test drops fileTree.toggle - Type assertion test-d.ts marks "files" as @ts-expect-error - Add normalizeShellTabs legacy-files-to-status regression test
|
Warning Review limit reached
More reviews will be available in 3 minutes and 36 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 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 configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
📝 WalkthroughWalkthroughPR consolidates the legacy "files" right-panel tab into a new "status" tab, removes the worktree badge from the session header, and enhances the status panel with Git repository information (diff stats, active worktree) and artifact file listings alongside simplified directory opening. ChangesRight-panel tab migration and status panel enhancement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Suggested priority: P2 (includes user-path files (packages/app/src/components/command-palette/command-palette-default-items.test.ts, packages/app/src/components/command-palette/command-palette-default-items.ts, packages/app/src/components/session/session-header.tsx, packages/app/src/components/session/session-status-panel.tsx, packages/app/src/components/session/session-status-summary.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/zh.ts, packages/app/src/pages/session/helpers.test.ts, packages/app/src/pages/session/migrate-session-view.test.ts, packages/app/src/pages/session/right-panel-tab-strip.tsx, packages/app/src/pages/session/right-panel-tabs.test-d.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/use-session-commands.test.ts, packages/app/src/pages/session/use-session-commands.tsx)).
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.
There was a problem hiding this comment.
Code Review
This pull request refactors the session side panel by merging the legacy "files" tab into the "status" panel, removing the separate files tab, and updating associated commands, tests, and types. Additionally, it integrates Git status (changes, branch, worktree) and artifact file listings directly into the status summary. Feedback on these changes highlights opportunities to improve accessibility by conditionally disabling non-interactive buttons, localizing hardcoded strings in the Git worktree tooltip, and ensuring cross-platform path compatibility for Windows environments when extracting filenames.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/app/src/pages/session/right-panel-tabs.ts (1)
11-14: 💤 Low valueStale comment still references the removed
filesslot.Line 5 was updated to "status / review / context", but this block still describes terminal tabs as "sibling of files/review/context". Worth aligning since
"files"no longer exists.📝 Suggested wording tweak
- * Pre-flatten, "terminal" was a fixed slot containing an internal multi-terminal - * strip. After flatten (Area B, 2026-05-25) each terminal is its own outer tab, - * sibling of files/review/context. Legacy persistence with "terminal" as a fixed - * slot is dropped via migrateLegacyRightPanelTab / coerceLegacySidePanelTab. + * Pre-flatten, "terminal" was a fixed slot containing an internal multi-terminal + * strip. After flatten (Area B, 2026-05-25) each terminal is its own outer tab, + * sibling of status/review/context. Legacy persistence with "terminal" as a fixed + * slot is dropped via migrateLegacyRightPanelTab / coerceLegacySidePanelTab.🤖 Prompt for 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. In `@packages/app/src/pages/session/right-panel-tabs.ts` around lines 11 - 14, Update the stale comment that still mentions the removed "files" slot: change the phrase describing terminal tabs as "sibling of files/review/context" to the current naming "sibling of status/review/context" (or whichever current slots are accurate), keeping the rest of the note about legacy persistence and the references to migrateLegacyRightPanelTab and coerceLegacySidePanelTab intact so the comment reflects the current tab layout.packages/app/src/components/session/session-status-summary.tsx (1)
64-86: 💤 Low valueConsider stricter typing for icon names.
Line 79 uses
as anyto bypass icon name type checking. While this may be necessary for the icon system's flexibility, it prevents catching invalid icon names at compile time.If the Icon component supports a union of valid icon names, consider typing
props.iconas that union instead ofstringto eliminate the need for the type assertion.🤖 Prompt for 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. In `@packages/app/src/components/session/session-status-summary.tsx` around lines 64 - 86, The GitRow component currently types props.icon as string and uses an unsafe cast (as any) when passing to Icon, which hides invalid icon names; update GitRow's prop type for icon to the Icon component's exact icon-name union/type (e.g., IconName or the IconProps['name'] type exported by the Icon module) and remove the as any cast, importing that type from the Icon file and using it in the props declaration so the compiler enforces valid icon names when calling GitRow.
🤖 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/components/session/session-status-summary.tsx`:
- Around line 101-116: The tooltip component function worktreeTooltip (accepting
ActiveWorktree) uses hardcoded English strings; replace the literal labels
("Worktree", "Branch", "Location") and fallback text ("Not available") with i18n
lookups (e.g., t('status.summary.git.worktree.tooltip.worktree') etc.), and add
the corresponding keys to the locale files (en.ts and zh.ts) for those four
entries; ensure you import/use the same translation function used elsewhere in
this file/component so the tooltip text is localized at render time.
---
Nitpick comments:
In `@packages/app/src/components/session/session-status-summary.tsx`:
- Around line 64-86: The GitRow component currently types props.icon as string
and uses an unsafe cast (as any) when passing to Icon, which hides invalid icon
names; update GitRow's prop type for icon to the Icon component's exact
icon-name union/type (e.g., IconName or the IconProps['name'] type exported by
the Icon module) and remove the as any cast, importing that type from the Icon
file and using it in the props declaration so the compiler enforces valid icon
names when calling GitRow.
In `@packages/app/src/pages/session/right-panel-tabs.ts`:
- Around line 11-14: Update the stale comment that still mentions the removed
"files" slot: change the phrase describing terminal tabs as "sibling of
files/review/context" to the current naming "sibling of status/review/context"
(or whichever current slots are accurate), keeping the rest of the note about
legacy persistence and the references to migrateLegacyRightPanelTab and
coerceLegacySidePanelTab intact so the comment reflects the current tab layout.
🪄 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: 831a049e-6cf6-46bc-b5ff-dedf061e823d
📒 Files selected for processing (21)
packages/app/src/components/command-palette/command-palette-default-items.test.tspackages/app/src/components/command-palette/command-palette-default-items.tspackages/app/src/components/session/session-header.tsxpackages/app/src/components/session/session-status-panel.tsxpackages/app/src/components/session/session-status-summary.tsxpackages/app/src/context/layout.shell-tabs.test.tspackages/app/src/context/layout.test.tspackages/app/src/context/layout.tsxpackages/app/src/i18n/en.tspackages/app/src/i18n/zh.tspackages/app/src/pages/session/helpers.test.tspackages/app/src/pages/session/migrate-session-view.test.tspackages/app/src/pages/session/right-panel-tab-strip.tsxpackages/app/src/pages/session/right-panel-tabs.test-d.tspackages/app/src/pages/session/right-panel-tabs.test.tspackages/app/src/pages/session/right-panel-tabs.tspackages/app/src/pages/session/session-side-panel.test.tsxpackages/app/src/pages/session/session-side-panel.tsxpackages/app/src/pages/session/use-session-commands.test.tspackages/app/src/pages/session/use-session-commands.tsxpackages/ui/src/components/icon.tsx
💤 Files with no reviewable changes (4)
- packages/app/src/pages/session/right-panel-tab-strip.tsx
- packages/app/src/pages/session/use-session-commands.tsx
- packages/app/src/components/command-palette/command-palette-default-items.test.ts
- packages/app/src/components/session/session-header.tsx
- Translate section titles to Chinese (环境/产出物) and fix English (Artifacts) - Align GitRow to interactive row sizing (min-h 30px, px-2, conditional hover) - Remove non-functional branch chevron (backend has no branch-switch API yet) - Make changes row always clickable to navigate to review panel
Use grid layout (30px height, 16px icon + 1fr path + actions), IconButton with Tooltip, folder-add-left icon, and row-hover-overlay/row-active-overlay tokens matching session-turn-change-row CSS.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/app/src/components/session/session-status-summary.tsx (1)
287-295:⚠️ Potential issue | 🟠 Major | ⚡ Quick winGate artifact
openFile/revealFileon local-server mode
openWorktreeDirectorygates oncanOpenLocalPath(platform) && server.isLocal(), butArtifactSectioncallsonOpenFile(file.path)/onRevealFile(file.path)andopenFile/revealFileonly check the platform method. Thefile.pathvalues come from the server’ssession.artifactsendpoint (Artifact.fileis returned asfile.path), so in remote-server mode this can pass remote filesystem paths to desktop shell APIs (platform.openPath/platform.showItemInFolder). Add the sameserver.isLocal()gating used for worktree directory.const openFile = (path: string) => { - if (!platform.openPath) return + if (!canOpenLocalPath(platform) || !server.isLocal() || !platform.openPath) return void platform.openPath(path).catch(() => {}) } const revealFile = (path: string) => { - if (!platform.showItemInFolder) return + if (!canOpenLocalPath(platform) || !server.isLocal() || !platform.showItemInFolder) return void platform.showItemInFolder(path).catch(() => {}) }🤖 Prompt for 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. In `@packages/app/src/components/session/session-status-summary.tsx` around lines 287 - 295, openFile and revealFile only check platform methods and can be passed remote paths from ArtifactSection via onOpenFile/onRevealFile; mirror the gating used in openWorktreeDirectory by requiring canOpenLocalPath(platform) && server.isLocal() before calling platform.openPath or platform.showItemInFolder. Update the openFile(path: string) and revealFile(path: string) helpers to return early if !canOpenLocalPath(platform) or !server.isLocal(), then call the platform methods and retain the existing .catch(() => {}) behavior.
🤖 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.
Outside diff comments:
In `@packages/app/src/components/session/session-status-summary.tsx`:
- Around line 287-295: openFile and revealFile only check platform methods and
can be passed remote paths from ArtifactSection via onOpenFile/onRevealFile;
mirror the gating used in openWorktreeDirectory by requiring
canOpenLocalPath(platform) && server.isLocal() before calling platform.openPath
or platform.showItemInFolder. Update the openFile(path: string) and
revealFile(path: string) helpers to return early if !canOpenLocalPath(platform)
or !server.isLocal(), then call the platform methods and retain the existing
.catch(() => {}) behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 52688ce0-ea4a-45b4-a942-e278570d0e32
📒 Files selected for processing (3)
packages/app/src/components/session/session-status-summary.tsxpackages/app/src/i18n/en.tspackages/app/src/i18n/zh.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/app/src/i18n/en.ts
- packages/app/src/i18n/zh.ts
zh: 工作区 / 改动文件 (confirmed via DeepSeek + Codex consensus) en: Workspace / Changed files
Unlike turn-change-row which sits inside a bordered container, artifact rows are exposed directly in the status panel section.
Align GitRow and ArtifactRow with sidebar/settings convention: rounded-md border-radius, hover:bg-surface-raised.
TodoRow, SourceRow, ArtifactRow now all use min-h-[30px] consistent with GitRow, ensuring uniform vertical rhythm across all sections.
Dense information rows (todos, sources) should be shorter than interactive rows (git, artifact) which use min-h-[30px].
createMemo on a store proxy object does reference-equality comparison, but the proxy reference never changes when setStore replaces the value. Use a plain accessor instead so SolidJS tracks property access at the consumption site (e.g. props.vcs()?.branch in the Show component).
When a session runs inside a worktree, sync.data.vcs.branch reflects the main workspace, not the worktree. Use activeWorktree.branch as the primary source with vcs.branch as fallback.
The Status panel was passively waiting for vcs.branch.updated SSE events which may not arrive reliably. Now listen for file.watcher.updated events (same mechanism the review panel uses) and re-fetch vcs.get() to update the branch display when .git/HEAD changes.
Reverts actively refreshing vcs on file.watcher.updated, worktree branch fallback, and createMemo removal. The branch not updating after git checkout needs deeper root cause analysis.
- Add i18n keys for worktree tooltip strings (Worktree/Branch/Location/Not available) - Gate openFile/revealFile on canOpenLocalPath + isLocal (CodeRabbit major) - Add disabled attr to GitRow when not clickable (accessibility) - Show workspace section on detached HEAD (check vcs existence, not branch) - Handle Windows backslashes in artifact filename split - Fix stale "files" reference in right-panel-tabs.ts docblock
Address three P0 deviations from docs/DESIGN.md L434-L449 spec: - GitRow / ArtifactRow hover bg switched from `bg-surface-raised` to `var(--row-hover-overlay)`. In light theme `--surface-raised` resolves to `#FFFFFF` which equals the right panel `--bg-base`, so the prior token produced no visible hover state. Picker contract token is the intended source for this overlay. - ArtifactRow trailing slot adopts the turn-change pattern: rest shows `+N -N` diff stats in mono-small (success / error, tabular nums) and hover/focus fades them out behind the open + reveal IconButtons. The spec calls for diff stats on every row; the previous implementation surfaced only the action icons. SessionStatusPanel now derives a per-path map from the same aggregate it already used for the section total so no extra fetch is needed. - SourceRow becomes a button with a `square-arrow-top-right` leading icon and routes clicks through `platform.openLink`. Spec says click opens in the system browser; previously the row was a passive `div` without the icon. Adds `status.summary.sources.open` en/zh keys for the source-row aria label.
status-summary-todos.snap.ts only seeds todos so the Workspace, Changed files, and Sources sections went unsnapped. status-summary-panel seeds all four sections in one session (todos via __e2e/update-todos, two apply_patch turns via mock LLM for real turn-change aggregate, two text turns whose text parts are swapped to completed webfetch parts via sdk.part.update for the source URLs) and captures two shots: - rest: full panel showing aggregate diff in Workspace, per-file diff stats in Changed files, leading-arrow URL rows in Sources. - artifact hover: first Changed files row with hover bg active and open + reveal icons revealed in place of the diff stats, locking down the rest→hover trailing transition introduced when ArtifactRow adopted the turn-change trailing pattern. Notification region (mock-LLM health-check toasts) is hidden via a scoped style tag before screenshotting so the snap captures the panel itself. ArtifactRow / SourceRow gain `data-slot` attributes so the snap can target the rows without coupling to CSS class names.
Codex review flagged a silent Windows regression: SessionStatusPanel keyed its per-file diff map by `aggregateFiles().file` (server-side `openPath ?? path`) while ArtifactSection looked up `FilesTabEntry.path` (locally joined by deriveArtifactFiles using `/`). On Windows the two sides can mix `C:\repo\src\a.ts` and `C:\repo/src/a.ts`, so exact string equality fails — the artifact row still renders but loses its `+N -N` diff stat. The aggregate Workspace total stays correct because it sums the map values directly, hiding the regression. Add a single `normalizeArtifactPathKey` helper in files-tab-state and route both sides through it so the lookup matches regardless of slash direction. The helper is scoped to keyed comparisons; native shell callers (openPath / showItemInFolder) still receive the original path. Includes a unit test that locks the mixed-slash case.
…apability Decompose session-status-summary into shell + git + artifact files. Per-row open / reveal capability now follows the old Files-tab pattern: panel stats artifact paths via platform.statPaths, disables actions when the file no longer exists or the host can't open paths, and surfaces openPath / showItemInFolder / openLink failures through a toast instead of swallowing them. Worktree row applies the same canOpen / disabled treatment. snap target now asserts exact seeded counts (4 todos, 2 artifacts, 2 sources) and waits for per-path diff stats to render before screenshotting, so partial-seed regressions and silent normalizeArtifactPathKey breakage cannot pass.
Summary
changesicon (Imagen → Potrace pipeline) for the Git diff stats rowChanges
Status panel redesign
sync.data.vcsfor branch,sessionInfo().executionContext.activeWorktreefor worktree,aggregateFiles(turn_change_aggregate)for diff statsFiles tab removal
"files"fromRightPanelStaticTab,RIGHT_PANEL_TAB_META, command palette, and keybind"files"values map to"status"viacoerceLegacySidePanelTabandmigrateLegacyRightPanelTabTitlebar cleanup
PawworkWorktreeBadgefromsession-header.tsx(worktree info now lives in the Status panel Git section)Test plan
"files"tab persistence maps correctly to"status"bun run dev:desktop— walk Status panel with active session in git repoSummary by CodeRabbit
New Features
Refactor
Chores
Style