Skip to content

feat(egocap): cameras-first operator page with resizable side panel and 3D view upgrades - #1411

Merged
NVshawnhwang merged 4 commits into
mainfrom
shhwang/egocap-operator-layout
Nov 3, 2026
Merged

NVshawnhwang merged 4 commits into
mainfrom
shhwang/egocap-operator-layout

Conversation

@NVshawnhwang

@NVshawnhwang NVshawnhwang commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Cameras-first operator page with an operator bar, device-health summary, and a resizable side panel.
  • 3D view upgrades: floor, grid, origin axes, and finger-shaded gloves.
  • Touches only examples/egocap/ (frontend, viser_scene.py backend, tests).

Testing

Run locally from examples/egocap/:

  • Frontend npm run test: 20 files, 257 tests passed. npm run lint (tsc -b --noEmit): clean.
  • Backend uv run pytest tests/backend: 365 passed, 3 failed. The 3 failures are the "file name that is not valid UTF-8" tests (test_recordings.py, test_task_file_routes.py, test_task_files.py); they create non-UTF-8 file names, which macOS rejects. They don't touch this change, so I expect them to pass on Linux CI.
  • ruff check / ruff format --check on backend: pass. pre-commit on the diff: clean.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an operator layout with a recording and device-status bar, camera stage, and resizable side panel for 3D visualization and session details. The panel width can be adjusted, reset, and retained.
    • Added Normal, Large, and Full screen viewing options for the 3D view, with close controls for expanded modes.
    • Highlighted the primary camera and added a floor grid, origin axes, and shaded finger joints in the 3D scene.
  • Documentation
    • Added an overview of the operator layout, 3D view controls, and responsive behavior.

…nd 3D view upgrades

Port of the operator-page frontend work: cameras-first layout with an
operator bar, device-health summary, and a resizable side panel, plus a
3D view with floor, grid, origin axes and finger-shaded gloves.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Shawn Hwang <265103681+NVshawnhwang@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
Walkthrough

The frontend adds an operator layout with recording and device status, a resizable sidebar, prioritized camera tiles, and Normal, Large, and Full screen controls for the embedded 3D view. The backend adds shaded glove joints and bones, plus a floor slab, grid, and origin axes in the 3D scene.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  actor Operator
  participant RecordingPanel
  participant App
  participant OperatorBar
  Operator->>RecordingPanel: Clicks Stop
  RecordingPanel->>App: Reports STOPPING phase
  App->>OperatorBar: Passes pending recording phase
  OperatorBar->>Operator: Displays STOPPING
Loading
Merge Risk: Moderate · previous review 3211f

The operator clock can imply a take is still being tracked after the feed is lost or recording stops. Fix those indicators and the failing pre-commit checks before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the main change: a cameras-first operator page with a resizable side panel and 3D view upgrades. The raw summary confirms the App layout change to cameras in the main stage with a resi…
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.
Full details: Title check

Explanation

The title names the main change: a cameras-first operator page with a resizable side panel and 3D view upgrades. The raw summary confirms the App layout change to cameras in the main stage with a resizable sidebar, plus the glove colors, floor, grid, and origin axes in the 3D view. The title covers the primary change and does not mention the Pose Viser fullscreen and size controls, the device-health chips, or the operator bar. Those are expected omissions for a title of this length.

Full details: Docstring Coverage

Explanation

Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 30 functions across 16 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 834ecad and 3211fd7.

Files selected for processing: 18
  • examples/egocap/backend/egocap_web/viser_scene.py
  • examples/egocap/frontend/README.md
  • examples/egocap/frontend/src/App.operatorLayout.test.tsx
  • examples/egocap/frontend/src/App.tsx
  • examples/egocap/frontend/src/CameraGrid.test.tsx
  • examples/egocap/frontend/src/CameraGrid.tsx
  • examples/egocap/frontend/src/OperatorBar.test.tsx
  • examples/egocap/frontend/src/OperatorBar.tsx
  • examples/egocap/frontend/src/PoseViserPanel.test.tsx
  • examples/egocap/frontend/src/PoseViserPanel.tsx
  • examples/egocap/frontend/src/RecordingPanel.tsx
  • examples/egocap/frontend/src/SidebarResizer.tsx
  • examples/egocap/frontend/src/deviceHealth.test.ts
  • examples/egocap/frontend/src/deviceHealth.ts
  • examples/egocap/frontend/src/sidebarWidth.test.ts
  • examples/egocap/frontend/src/sidebarWidth.ts
  • examples/egocap/frontend/src/styles.css
  • examples/egocap/tests/backend/test_viser_scene.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Shawn Hwang <265103681+NVshawnhwang@users.noreply.github.com>

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

  • Fix comments: Fix CodeRabbit comments on this PR

@gareth-morgan-nv

Copy link
Copy Markdown
Contributor

🤖 Agent-generated (Claude Code · claude-sonnet-5-5)

Summary

Adds a cameras-first operator page for examples/egocap/: an OperatorBar (recording state, task, saved count, device-health chips), a resizable side panel, 3D-view sizing, and a floor/grid/finger-shaded gloves in viser_scene.py. Architecture is sound: device health is derived client-side from the existing CaptureStatusResponse (itself built from the capture server's StatusSnapshot by the single CaptureStatusMonitor/CaptureClient), and the Viser sampler still reuses the monitor's latest tracking slot, so nothing bypasses the capture server and no state or contract was changed in capture_status.py/preview_protocol.py/captureStatus.ts. Two correctness issues and the repo's own test/docstring standards (examples/egocap/AGENTS.md) need attention before merge.

Legend: 🚫 Blocker · 💡 Suggestion · 🔍 Nit

Finding
🚫 PR description — frontend npm run test/npm run lint were not run ("no Node available") and one backend test failed (called flaky). examples/egocap/AGENTS.md makes running every suite, with real output reported, the contributor's responsibility; CI is not a substitute.
🚫 frontend/src/OperatorBar.tsx:185 — with live === false, healthy chips are downgraded to neutral but chipsNeedingAttention only counts warning/critical, so the kicker still reads "All devices OK" over retained data. The bar elsewhere (NO FEED) is careful never to present stale state as current. Show a "last known" label when !live; the existing test only covers live={true}.
🚫 examples/egocap/AGENTS.md docstring rule — new production functions/components lack docstrings: HealthChipView (OperatorBar.tsx:107), OperatorBar (:119), SidebarResizer (SidebarResizer.tsx:23), detailOf (deviceHealth.ts:68), saveSidebarWidth, and the new effects/handlers in App.tsx.
💡 frontend/src/App.tsx:453-459 — the resize handler clamps the width and the effect then saves it, so merely shrinking the window overwrites the stored egocap.sidebarWidth (the effect also saves on mount). The operator's remembered choice is lost. Persist only on explicit drag end, key press, or reset.
💡 frontend/src/CameraGrid.tsx:186 — primary camera chosen by /head/i on the camera name: matches e.g. "overhead", misses a head camera not named that way. Prefer an explicit field from the station config.
💡 frontend/src/OperatorBar.tsx:60 — deriveRecIndicator's switch (snapshot.episodePhase) has no default return; a new backend phase would yield undefined at runtime. Add an exhaustive/default case.
💡 frontend/src/OperatorBar.tsx (take timer) — already raised by CodeRabbit (stop the timer when the feed is not live); agree.
🔍 frontend/src/PoseViserPanel.tsx:100 — src={visualization.url ?? undefined} only works around ready losing type narrowing; narrow inline instead.
🔍 frontend/src/deviceHealth.ts deviceChipLabel — matches on id.includes("hand"/"controller"/"headset"); brittle against new device ids. Match on the known id prefixes.
🔍 frontend/src/styles.css — ~890 added lines; worth a pass for unused selectors (e.g. op-rec--stale variants) and hardcoded sizes.

Actionables (for bots — copy-paste-ready for AI)

Agent-generated suggestions, not human-vetted obligations. Skip anything wrong, already
addressed, or not worth the churn.

  • examples/egocap/frontend/src/OperatorBar.tsx:185 — when live is false, render a "last known" label instead of "All devices OK"; add a test for the stale case.
  • examples/egocap/frontend/src/App.tsx:453-459 — stop persisting the clamped width from the resize handler and mount effect; call saveSidebarWidth only from drag-end, key-press and reset paths.
  • examples/egocap/frontend/src/OperatorBar.tsx:107,119, SidebarResizer.tsx:23, deviceHealth.ts:68, sidebarWidth.ts (saveSidebarWidth) — add purpose docstrings; add short why-comments to the new logical blocks.
  • examples/egocap/frontend/src/OperatorBar.tsx:60 — add a default/exhaustiveness branch to the episodePhase switch.
  • examples/egocap/frontend/src/CameraGrid.tsx:186 — replace the /head/i name heuristic with an explicit primary-camera setting.
  • Run uv run pytest tests/backend plus the frontend npm run test and npm run lint from examples/egocap/frontend, and report the actual output in the PR description.

@gareth-morgan-nv gareth-morgan-nv 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.

LGTM. This new layout is a big improvement. Fix the items in the agent review above.

- Stale feed no longer reads "All devices OK"; it says "Last known: no faults".
- Persist the side-panel width only on drag end, key press and reset, so a
  window refit never overwrites the operator's saved choice.
- Exhaustiveness branch for the recording phase switch.
- Purpose docstrings for the new components and helpers.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Shawn Hwang <265103681+NVshawnhwang@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Shawn Hwang <265103681+NVshawnhwang@users.noreply.github.com>
@NVshawnhwang
NVshawnhwang merged commit 8f460b2 into main Nov 3, 2026
41 checks passed
@NVshawnhwang
NVshawnhwang deleted the shhwang/egocap-operator-layout branch November 3, 2026 23:51

This branch was previously deployed

1 inactive deployment
dev — b12fd7bf Deployed Nov 3, 2026 by NVshawnhwang via publish-wheel #6434
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants