feat: events and sync-status panes in tree view - #262
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThis change adds application and resource event panes with sync-operation details, responsive layouts, keyboard and command access, refresh scheduling, stale-request protection, normalized API data, tree sync summaries, and unit, golden, and end-to-end tests. ChangesEvents and sync-status feature
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant Operator
participant TreeView
participant Model
participant ApplicationService
participant ArgoCDServer
Operator->>TreeView: Press e or run events
TreeView->>Model: Open pane for selected application or resource
Model->>ApplicationService: Request events and operation state
ApplicationService->>ArgoCDServer: Fetch Kubernetes events and application state
ArgoCDServer-->>ApplicationService: Return event and operation responses
ApplicationService-->>Model: Return normalized, tagged results
Model-->>TreeView: Render events, sync details, and refresh state
Operator->>TreeView: Navigate or press Escape
TreeView->>Model: Retarget or close pane
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✨ 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.
Actionable comments posted: 10
🤖 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 `@cmd/app/events_pane.go`:
- Around line 26-30: Update Model.panePageSize to derive the scroll amount from
the rendered pane body height using the same paneLayout geometry as
renderSidePane, rather than subtracting a fixed overhead from Terminal.Rows;
preserve the minimum page size of one. Add a focused regression test for
narrow-layout pgdown behavior to verify it does not skip rows or jump directly
to the clamped end.
- Around line 76-110: Add a distinct per-pane load generation to the state and
load-result message contracts so repeated opens of the same target cannot apply
stale responses. In cmd/app/events_pane.go lines 76-110, allocate and store a
new generation whenever handleShowSyncStatus or handleShowEvents opens or
switches panes, then pass it to the loader. In cmd/app/api_integration.go lines
1651-1711, capture that generation and include it in every success and error
message; apply results only when the generation matches the current pane, and
add out-of-order completion tests.
- Around line 99-105: Update handleShowEvents and loadEvents to support
cluster-scoped targets with an empty detail.Namespace while preserving
detail.UID and detail.Name in EventsResource. Adjust the
ApplicationService.ListEvents contract and selector validation/fallback so an
empty ResourceNamespace is accepted when the unique resource UID or name is
present. Add regression coverage for both the Argo CD event API contract and
cluster-scoped event targets.
In `@cmd/app/input_components.go`:
- Around line 520-523: The handleKeyMsg function intercepts Ctrl+C globally and
returns QuitMsg before mode-specific routing occurs, making Ctrl+C unreachable
in ModeCommand. Either exempt ModeCommand from the global Ctrl+C handling in
handleKeyMsg by checking the current mode before returning QuitMsg, or
restructure the key-handling flow to dispatch Ctrl+C to the appropriate mode
handler after routing so ModeCommand can process the cancellation before the
quit path executes.
In `@cmd/app/input_handlers.go`:
- Line 1740: Update the "left", "h", "right", "l" navigation branch in input
handling to detect a child Application and invoke handleNavigateToChildApp for
"l" and "right" before the generic TreeView.Update expansion path. Preserve
existing behavior for non-Application rows and left/collapse navigation, and add
regression tests covering child drill-in with both keys.
In `@cmd/app/model.go`:
- Around line 575-577: Preserve namespace identity throughout sync-summary
rendering: extend the tree messages and watch targets to carry each
application’s namespace, update the ResourceTreeLoadedMsg and
ResourceTreeStreamMsg handling to call findAppByNameAndNamespace with that
namespace, and key TreeView.syncSummaries by the full name-and-namespace
identity. Update the duplicate-name test to cover ResourceTreeLoadedMsg and
verify summaries remain isolated between namespaces.
In `@cmd/app/view_pane.go`:
- Around line 159-168: The row-building logic must reserve space for both r.Kind
and r.Status, not only name. Update the sizing and clipping around the visible
row composition so an oversized kind is truncated before adding the ellipsis,
while preserving the status suffix and existing name behavior; add a test
covering a long kind that verifies the rendered row ends with SyncFailed.
- Around line 265-270: Use lipgloss.Width for the “more above” marker in the
title-width calculation within the view pane title rendering logic, preserving
display-cell sizing. Update
cmd/app/testdata/snapshots/pane_events_scrolled.golden at line 2 to retain the
full Events · Pod web-6f7d9b-x4k2m title, and add a 50-cell MoreAbove case in
cmd/app/view_pane_test.go lines 235-253 asserting the title is not truncated.
- Around line 39-63: The paneLayout and renderMainLayout flow must safely handle
tiny availableRows values without negative body heights or reserving more rows
than exist. Clamp paneBodyRows and related row calculations to nonnegative,
enforce a minimum total height before opening either pane, and ensure
renderSidePane never receives a negative slice bound; add tests covering budgets
0 through 4.
In `@pkg/api/applications.go`:
- Around line 622-626: Update the status selection near the HookType check so
hook resources use r.HookPhase only when it is non-empty; otherwise retain the
existing r.Status value. Preserve the current phase-based behavior whenever a
hook phase is available.
🪄 Autofix
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: CHILL
Plan: Pro Plus
Run ID: 38277003-6708-4877-8fa8-ae12fadd807c
📒 Files selected for processing (39)
cmd/app/api_integration.gocmd/app/events_pane.gocmd/app/events_pane_test.gocmd/app/input_components.gocmd/app/input_handlers.gocmd/app/input_handlers_delete_test.gocmd/app/model.gocmd/app/model_init.gocmd/app/nav_router.gocmd/app/testdata/snapshots/pane_events_bottom_80x24.goldencmd/app/testdata/snapshots/pane_events_loading_empty_error.goldencmd/app/testdata/snapshots/pane_events_scrolled.goldencmd/app/testdata/snapshots/pane_events_side_100x24.goldencmd/app/testdata/snapshots/pane_syncstatus_failed_100x24.goldencmd/app/testdata/snapshots/pane_syncstatus_never_synced.goldencmd/app/testdata/snapshots/tree_view_selection.goldencmd/app/testdata/snapshots/tree_view_sync_summary_variants.goldencmd/app/view.gocmd/app/view_layout.gocmd/app/view_pane.gocmd/app/view_pane_golden_test.gocmd/app/view_pane_test.gocmd/app/view_status.gocmd/app/view_status_test.gocmd/app/view_tree_golden_test.goe2e/events_pane_test.gopkg/api/applications.gopkg/api/applications_test.gopkg/api/events.gopkg/api/events_test.gopkg/autocomplete/autocomplete.gopkg/humantime/humantime.gopkg/humantime/humantime_test.gopkg/model/events.gopkg/model/messages.gopkg/model/state.gopkg/model/types.gopkg/tui/treeview/treeview.gopkg/tui/treeview/treeview_test.go
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cmd/app/events_pane_test.go (1)
647-653: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the complete loader message contract.
Set
m.switchEpochto a nonzero sentinel in both HTTP-loader tests. If the fixture epoch is zero, an omittedSwitchEpochalso passes the existing event assertion. The sync-status test does not checkTarget,SwitchEpoch,LoadSeq, orDetails.Revision. A loader can then emit a completion that the freshness gate discards, or omit the displayed revision, without failing this test.Proposed test coverage
func TestLoadEvents_ProducesGatedMessageWithData(t *testing.T) { m := buildEventsPaneTestModel() + m.switchEpoch = 42 m.state.Server = &model.Server{BaseURL: server.URL, Token: "test-token"} target := model.EventsTarget{AppName: "test-app", AppNamespace: "test-namespace"} func TestLoadSyncStatus_FetchesFullOperationState(t *testing.T) { m := buildEventsPaneTestModel() + m.switchEpoch = 42 m.state.Server = &model.Server{BaseURL: server.URL, Token: "test-token"} target := model.SyncStatusTarget{AppName: "test-app", AppNamespace: "test-namespace"} loaded, ok := msg.(model.SyncStatusLoadedMsg) if !ok { t.Fatalf("expected SyncStatusLoadedMsg, got %T: %+v", msg, msg) } - if loaded.Details == nil || loaded.Details.Phase != "Failed" || len(loaded.Details.Resources) != 1 { + if loaded.Target != target || loaded.SwitchEpoch != m.switchEpoch || loaded.LoadSeq != 1 { + t.Errorf("expected gating fields carried through, got %+v", loaded) + } + if loaded.Details == nil || loaded.Details.Phase != "Failed" || + loaded.Details.Revision != "a1b2c3d" || len(loaded.Details.Resources) != 1 { t.Errorf("expected full operation state with resource results, got %+v", loaded.Details) }Also applies to: 683-683
🤖 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 `@cmd/app/events_pane_test.go` around lines 647 - 653, Strengthen the loader tests around m.loadEvents and the sync-status assertion: initialize m.switchEpoch to a nonzero sentinel in both HTTP-loader tests, then assert the complete EventsLoadedMsg contract—Target, SwitchEpoch, LoadSeq, and Details.Revision—so stale completions or missing displayed revisions fail the tests.
🤖 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.
Nitpick comments:
In `@cmd/app/events_pane_test.go`:
- Around line 647-653: Strengthen the loader tests around m.loadEvents and the
sync-status assertion: initialize m.switchEpoch to a nonzero sentinel in both
HTTP-loader tests, then assert the complete EventsLoadedMsg contract—Target,
SwitchEpoch, LoadSeq, and Details.Revision—so stale completions or missing
displayed revisions fail the tests.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: cb1d7921-143d-40b9-92d6-66038994f385
📒 Files selected for processing (12)
cmd/app/api_integration.gocmd/app/events_pane.gocmd/app/events_pane_test.gocmd/app/input_handlers.gocmd/app/model.gocmd/app/testdata/snapshots/pane_events_scrolled.goldencmd/app/view_pane.gocmd/app/view_pane_test.gopkg/api/applications.gopkg/api/applications_test.gopkg/model/events.gopkg/model/messages.go
🚧 Files skipped from review as they are similar to previous changes (9)
- cmd/app/input_handlers.go
- cmd/app/api_integration.go
- cmd/app/testdata/snapshots/pane_events_scrolled.golden
- pkg/api/applications.go
- pkg/model/events.go
- cmd/app/view_pane.go
- cmd/app/model.go
- cmd/app/events_pane.go
- pkg/model/messages.go
…-scoped resource events
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
cmd/app/input_handlers.go (1)
1699-1711: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the redundant block and the now-unreachable tree branch.
handleKeyMsgreturnsm.handleTreeViewKeys(msg)forViewTree, sohandleNormalModeGlobalKeysnever runs in tree view. Thectrl+dbranch at Line 1866 that checksm.state.Navigation.View == model.ViewTreeis now dead code. The extra{ ... }block insidehandleTreeViewKeysis also a leftover of the extraction and adds a nesting level without effect.♻️ Proposed cleanup
func (m *Model) handleTreeViewKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) { - { - switch msg.String() { + switch msg.String() { ... - } }case "ctrl+d": - // Open delete confirmation for selected app (apps view) or resource (tree view) + // Open delete confirmation for selected app (apps view) if m.state.Navigation.View == model.ViewApps { return m.handleAppDelete() } - if m.state.Navigation.View == model.ViewTree { - return m.handleResourceDelete() - } return m, nil🤖 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 `@cmd/app/input_handlers.go` around lines 1699 - 1711, Remove the redundant inner block from handleTreeViewKeys, and delete the unreachable ctrl+d branch in handleNormalModeGlobalKeys that checks for model.ViewTree. Preserve the remaining non-tree global key handling and tree-specific behavior unchanged.e2e/events_pane_test.go (1)
94-114: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueExtract the shared e2e setup.
Both tests repeat the same 15 lines: framework creation,
MockArgoServerWithEvents, workspace setup,WriteArgoConfig,StartAppArgs, andopenDemoTree. Extract a helper that returns the framework so future pane tests do not copy it again.Also applies to: 156-177
🤖 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 `@e2e/events_pane_test.go` around lines 94 - 114, Extract the repeated setup sequence into a shared helper for the events pane tests, covering NewTUITest, MockArgoServerWithEvents, workspace/config setup, StartAppArgs, and openDemoTree. Have the helper return the initialized test framework and update both affected tests to call it while preserving cleanup and existing failure handling.
🤖 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 `@cmd/app/view_pane.go`:
- Around line 400-421: Update the bottom-border construction in the
frame-rendering method to suppress decorations when their combined width exceeds
the available `f.Width - 2`: drop the status segment first, then the “more
below” marker if the remaining fill is still negative, while preserving the
existing decorations when they fit. Ensure the resulting border uses only the
decorations that fit and add a narrow-width frame test asserting every rendered
line has width `f.Width`.
In `@cmd/app/view_status_test.go`:
- Around line 35-37: Update the assertion in the tree-hint test around the
current strings.Contains check to detect the emitted "enter: details" hint
instead of the obsolete "e: events" string, while preserving the existing
failure message and pane-open behavior being verified.
In `@e2e/events_pane_test.go`:
- Around line 144-150: Update both escape assertions in the event pane tests to
check the negative “esc: close” condition against the plain snapshot variable s,
rather than tf.Screen(). Keep the existing positive application check and wait
behavior unchanged.
In `@pkg/autocomplete/autocomplete.go`:
- Around line 102-108: Update the command registry near the existing events
entry to add the syncstatus command, including its required aliases and
description, while preserving events for the event pane. Ensure registration
restores completion and help support for :syncstatus and routes it to the latest
sync operation.
---
Nitpick comments:
In `@cmd/app/input_handlers.go`:
- Around line 1699-1711: Remove the redundant inner block from
handleTreeViewKeys, and delete the unreachable ctrl+d branch in
handleNormalModeGlobalKeys that checks for model.ViewTree. Preserve the
remaining non-tree global key handling and tree-specific behavior unchanged.
In `@e2e/events_pane_test.go`:
- Around line 94-114: Extract the repeated setup sequence into a shared helper
for the events pane tests, covering NewTUITest, MockArgoServerWithEvents,
workspace/config setup, StartAppArgs, and openDemoTree. Have the helper return
the initialized test framework and update both affected tests to call it while
preserving cleanup and existing failure handling.
🪄 Autofix
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: CHILL
Plan: Pro Plus
Run ID: dbb619ab-8479-4d7b-b28c-79e379dd1abb
📒 Files selected for processing (33)
cmd/app/events_pane.gocmd/app/events_pane_test.gocmd/app/input_components.gocmd/app/input_handlers.gocmd/app/model.gocmd/app/nav_router.gocmd/app/testdata/snapshots/pane_approw_never_synced.goldencmd/app/testdata/snapshots/pane_approw_status_and_events_100x30.goldencmd/app/testdata/snapshots/pane_events_bottom_80x24.goldencmd/app/testdata/snapshots/pane_events_loading_empty_error.goldencmd/app/testdata/snapshots/pane_events_scrolled.goldencmd/app/testdata/snapshots/pane_events_side_100x24.goldencmd/app/testdata/snapshots/tree_view_sync_summary_variants.goldencmd/app/view_pane.gocmd/app/view_pane_golden_test.gocmd/app/view_pane_test.gocmd/app/view_status.gocmd/app/view_status_test.goe2e/events_pane_test.gopkg/api/applications.gopkg/api/events.gopkg/api/events_test.gopkg/autocomplete/autocomplete.gopkg/config/argonaut_config.gopkg/config/argonaut_config_test.gopkg/humantime/humantime.gopkg/humantime/humantime_test.gopkg/model/events.gopkg/model/messages.gopkg/model/state.gopkg/model/types.gopkg/tui/treeview/treeview.gopkg/tui/treeview/treeview_test.go
💤 Files with no reviewable changes (1)
- pkg/model/types.go
🚧 Files skipped from review as they are similar to previous changes (14)
- pkg/model/state.go
- pkg/api/events.go
- cmd/app/nav_router.go
- pkg/tui/treeview/treeview_test.go
- cmd/app/model.go
- cmd/app/input_components.go
- cmd/app/testdata/snapshots/pane_events_loading_empty_error.golden
- pkg/model/messages.go
- cmd/app/testdata/snapshots/pane_events_side_100x24.golden
- cmd/app/testdata/snapshots/pane_events_bottom_80x24.golden
- pkg/api/applications.go
- pkg/tui/treeview/treeview.go
- cmd/app/view_pane_golden_test.go
- cmd/app/testdata/snapshots/tree_view_sync_summary_variants.golden
…n-validated style tests
…l+e/y and shift+arrows
… summary; full repaint on selection start
…r; :events on|off [always]
|
@coderabbitai please review |
|
|
…shared auto-open guard, glyph+color in one map, drop dead config write
|
@coderabbitai review |
✅ Action performedReview finished.
|
Sole finding (restore :syncstatus) was withdrawn by CodeRabbit after the design change was explained — sync status merged into the auto-opening events pane.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
cmd/app/input_mouse.go (1)
20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReturn
ClearScreendirectly.
tea.ClearScreenis atea.Cmd, so return it directly instead of wrappingtea.ClearScreen()in a command.🤖 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 `@cmd/app/input_mouse.go` at line 20, Update the command return in the mouse input handler to return the tea.ClearScreen command directly, removing the unnecessary wrapper function while preserving the existing model return.
🤖 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 `@cmd/app/input_handlers.go`:
- Around line 1709-1719: Update the ctrl+e/shift+down handler in the Events
offset logic to clamp st.Offset to the side pane’s available capacity before
incrementing it, matching renderSidePane’s bounds. Ensure m.state.Events.Offset
cannot grow beyond the maximum valid scroll position while preserving the
existing decrement behavior for ctrl+y/shift+up.
In `@cmd/app/view_status.go`:
- Around line 138-148: Update the status hint logic in cmd/app/view_status.go
lines 138-148 to identify the active pane or use a pane-neutral scroll label,
and include the sync-status shortcut when space permits. Update the help content
in cmd/app/view_modals.go lines 60-69 to document S and :syncstatus and describe
e and Enter consistently with event behavior. Regenerate
cmd/app/testdata/snapshots/modal_help.golden lines 18-23 to match the revised
help text.
---
Nitpick comments:
In `@cmd/app/input_mouse.go`:
- Line 20: Update the command return in the mouse input handler to return the
tea.ClearScreen command directly, removing the unnecessary wrapper function
while preserving the existing model return.
🪄 Autofix
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: CHILL
Plan: Pro Plus
Run ID: 9c1ca1d1-1dc6-4e8b-b569-1972f6901a85
📒 Files selected for processing (45)
README.mdcmd/app/events_pane.gocmd/app/events_pane_test.gocmd/app/input_components.gocmd/app/input_handlers.gocmd/app/input_mouse.gocmd/app/input_mouse_test.gocmd/app/model.gocmd/app/model_init.gocmd/app/model_watchers.gocmd/app/nav_router.gocmd/app/testdata/snapshots/modal_help.goldencmd/app/testdata/snapshots/pane_approw_never_synced.goldencmd/app/testdata/snapshots/pane_approw_status_and_events_100x30.goldencmd/app/testdata/snapshots/pane_events_bottom_80x24.goldencmd/app/testdata/snapshots/pane_events_loading_empty_error.goldencmd/app/testdata/snapshots/pane_events_scrolled.goldencmd/app/testdata/snapshots/pane_events_side_100x24.goldencmd/app/testdata/snapshots/tree_view_sync_summary_variants.goldencmd/app/view_modals.gocmd/app/view_pane.gocmd/app/view_pane_golden_test.gocmd/app/view_pane_test.gocmd/app/view_selection_test.gocmd/app/view_status.gocmd/app/view_status_test.goe2e/driver_unix_test.goe2e/events_pane_test.gopkg/api/applications.gopkg/api/applications_test.gopkg/api/events.gopkg/api/events_test.gopkg/autocomplete/autocomplete.gopkg/config/argonaut_config.gopkg/config/argonaut_config_test.gopkg/humantime/humantime.gopkg/humantime/humantime_test.gopkg/model/events.gopkg/model/messages.gopkg/model/state.gopkg/model/types.gopkg/theme/sha_color.gopkg/theme/sha_color_test.gopkg/tui/treeview/treeview.gopkg/tui/treeview/treeview_test.go
💤 Files with no reviewable changes (1)
- pkg/model/types.go
🚧 Files skipped from review as they are similar to previous changes (19)
- pkg/model/state.go
- cmd/app/testdata/snapshots/pane_events_bottom_80x24.golden
- cmd/app/testdata/snapshots/pane_approw_status_and_events_100x30.golden
- cmd/app/testdata/snapshots/tree_view_sync_summary_variants.golden
- cmd/app/testdata/snapshots/pane_events_loading_empty_error.golden
- pkg/humantime/humantime_test.go
- pkg/humantime/humantime.go
- pkg/model/messages.go
- pkg/api/events_test.go
- cmd/app/testdata/snapshots/pane_events_scrolled.golden
- cmd/app/view_pane.go
- cmd/app/view_pane_golden_test.go
- cmd/app/input_components.go
- cmd/app/testdata/snapshots/pane_approw_never_synced.golden
- pkg/api/events.go
- pkg/tui/treeview/treeview.go
- pkg/model/events.go
- cmd/app/testdata/snapshots/pane_events_side_100x24.golden
- pkg/api/applications.go
…gif re-recorded to match
Closes #258 — implements the plan from the issue comments.
e/enteropens events for the selected row (app-level on the root),S/:syncstatusthe last sync operation with per-resource results. Side pane at ≥100 cols, bottom pane below; read-only overlay — esc lands back on the untouched tree. The app root grows a livelast sync: ✖ Failed · 2m ago · …line fed by the watch.Major decisions:
model.Appkeeps only aSyncOpSummary; the fullsyncResult(per-resource rows) is fetched on pane open viaGetApplication.▲/▼scroll markers anchor in the border; geometry lives in one place (view_pane.go).enterloses its expand alias (l/→remain); child-Application drill-in preserved.Needs a real-server check:
items.status.operationState.syncResult.revisionfield selection on the initial list (fallback: request the wholeoperationStatesubtree).Summary by CodeRabbit
New Features
Bug Fixes
Documentation