Skip to content

feat(data): add camera selector to annotation workspace and fix AV1 frame extraction#591

Merged
akzaidi merged 15 commits into
mainfrom
feat/dataviewer-multi-camera
Apr 30, 2026
Merged

feat(data): add camera selector to annotation workspace and fix AV1 frame extraction#591
akzaidi merged 15 commits into
mainfrom
feat/dataviewer-multi-camera

Conversation

@akzaidi
Copy link
Copy Markdown
Contributor

@akzaidi akzaidi commented Apr 29, 2026

Pull Request

PR Soundtrack: Jaimie Branch - Fly or Die

Description

Multi-camera viewing, AV1 thumbnails, LeRobot v2.x compatibility, language-instruction annotations, a compact trajectory tab, and a cleaner dataviewer environment.

Multi-camera selector + AV1 thumbnails

The annotation workspace previously hard-pinned the displayed camera to cameras[0], leaving no way to view secondary views (e.g., wrist vs front) on the Trajectory Viewer / Object Detection tabs. Selection now lives in useAnnotationWorkspaceMediaSources, derives synchronously via useMemo against a cameraOverride state (so first render produces a stable videoSrc and autoplay no longer double-fires), and falls back to cameras[0] when the override no longer matches the available list.

The backend frame-extraction fallback called the system ffmpeg via shutil.which, but the host's ffmpeg is broken (libGL symbol error) and cv2's bundled ffmpeg does not include libdav1d. Newer LeRobot datasets ship AV1-encoded MP4s, so frame thumbnails returned 404. The handler now resolves to the imageio-ffmpeg static binary first (ships libdav1d and libx264).

LeRobot v2.x layout support

The dataset loader now handles the v2.x meta/episodes.jsonl + meta/tasks.jsonl layout in addition to the legacy parquet metadata, and reads per-episode lengths from JSONL when available. Estimates joint velocities from positions when a dataset omits them, so the Trajectory Plot no longer renders empty for v2.x captures.

Language instruction annotations

Adds a LanguageInstructionWidget to the annotation panel for capturing natural-language task descriptions, paraphrases for data augmentation, and subtask decompositions for hierarchical policy conditioning. Backend exposes a new LanguageInstructionAnnotation model, store actions, and an API endpoint; tasks are loaded from meta/tasks.jsonl / tasks.parquet and dataset feature keys are preserved when transforming snake_case API responses.

Compact trajectory tab layout

Moves the trajectory plot and subtask timeline above the subtasks pane inside a single scrollable playback group, shrinks the trajectory plot to a fixed 180px height, and collapses the labels panel to a single full-height column.

Dataviewer environment cleanup

  • Rename redundant HMI_DATA_PATHDATA_DIR and HMI_STORAGE_BACKENDSTORAGE_BACKEND across backend config, routers, services, tests, .env examples, Dockerfile, docker-compose, README, and the dataviewer Terraform Container Apps module.
  • data-management/viewer/start.sh now accepts --data-dir <path> (and --data-dir=<path>), defaults DATA_DIR to <repo>/datasets, exports it to the backend, and warns when the path is missing.
  • dev:backend npm script defaults DATA_DIR to the repo-root datasets/ so launching from the VS Code task picks up datasets out of the box.

Closes #436

Type of Change

  • 🐛 Bug fix (non-breaking change fixing an issue)
  • ✨ New feature (non-breaking change adding functionality)
  • 💥 Breaking change (env var rename: HMI_DATA_PATHDATA_DIR, HMI_STORAGE_BACKENDSTORAGE_BACKEND)
  • 📚 Documentation update
  • 🏗️ Infrastructure change (Terraform/IaC) — dataviewer Container Apps env var rename
  • ♻️ Refactoring (compact trajectory tab layout)

Component(s) Affected

  • viewer — frontend annotation workspace + backend dataset service, loader, language-instruction annotation API
  • infrastructure — infrastructure/terraform/modules/dataviewer/container-apps.tf env var rename

Testing Performed

  • Started dataviewer locally with multi-camera datasets (leisaac-pick-orange, so101-multi-pick-merged, so101-dual-camera-demos_*`)
  • Verified the camera dropdown lists all observation.images.* keys and switching updates both <video> source and frame thumbnails
  • Verified selection persists across episode transitions when the camera key is still present
  • Confirmed AV1 frame extraction returns valid 200 JPEGs via /api/datasets/<id>/episodes/<ep>/frames/<idx>?camera=... (previously 404 with Failed to read frame)
  • Loaded a LeRobot v2.x dataset and confirmed episodes, task descriptions, and trajectory plots render
  • Captured a language-instruction annotation, reloaded the episode, and verified persistence
  • Backend pytest: 414/415 passing locally (1 unrelated pre-existing HDF5 video test failure)
  • Frontend vitest: 658/658 passing; ESLint, tsc, and Prettier all clean

Local re-validation on feat/dataviewer-multi-camera: npm run test 701/701, npm run lint 0 errors, ruff check src/ clean, pytest 432 pass (1 unrelated HDF5 video test skipped in environments without ffmpeg/cv2).

Documentation Impact

  • Updated data-management/viewer/README.md and backend .env.example / .env.azure.example for the env var rename.

Bug Fix Checklist

  • Linked to issue being fixed
  • Regression test included for new loader paths (tests/test_lerobot_loader.py covers v2.x layout and JSONL metadata)
  • Justification for skipped tests: AV1 fallback path requires a real AV1 MP4 fixture and a working static ffmpeg, which isn't currently mocked in the cv2/ffmpeg test surface; camera-override behavior is exercised indirectly by use-annotation-workspace-media-controller.test.tsx and the workspace integration tests.

Migration Notes

If you maintain local .env files or external deployment configs for the dataviewer, rename:

Old New
HMI_DATA_PATH DATA_DIR
HMI_STORAGE_BACKEND STORAGE_BACKEND

data-management/viewer/start.sh and npm run dev:backend now default DATA_DIR to the repo-root datasets/ folder, so most local setups need no override.

Checklist

  • My code follows the project conventions
  • Commit messages follow conventional commit format
  • I have performed a self-review
  • Documentation impact assessed above
  • No new linting warnings introduced

…rame extraction

- expose cameras list and setCameraName from media-sources hook with selection preserved across episodes
- render CameraSelector alongside ViewerDisplayControls in playback card
- prefer imageio-ffmpeg static binary so frame thumbnails work for AV1 videos

🎥 - Generated by Copilot
@akzaidi akzaidi requested a review from a team as a code owner April 29, 2026 02:15
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ✅ 0 package(s) with unknown licenses.
  • ⚠️ 1 packages with OpenSSF Scorecard issues.
See the Details below.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA dcd2d57.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
npm/@babel/parser 7.29.2 🟢 7
Details
CheckScoreReason
Code-Review🟢 8Found 24/30 approved changesets -- score normalized to 8
Packaging⚠️ -1packaging workflow not detected
Maintained🟢 1030 commit(s) and 16 issue activity found in the last 90 days -- score normalized to 10
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 2badge detected: InProgress
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
npm/@babel/runtime 7.29.2 🟢 7
Details
CheckScoreReason
Code-Review🟢 8Found 24/30 approved changesets -- score normalized to 8
Packaging⚠️ -1packaging workflow not detected
Maintained🟢 1030 commit(s) and 16 issue activity found in the last 90 days -- score normalized to 10
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 2badge detected: InProgress
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
npm/@floating-ui/core 1.7.5 UnknownUnknown
npm/@floating-ui/dom 1.7.6 UnknownUnknown
npm/@floating-ui/react-dom 2.1.8 UnknownUnknown
npm/@floating-ui/utils 0.2.11 UnknownUnknown
npm/@humanfs/core 0.19.2 UnknownUnknown
npm/@humanfs/node 0.16.8 UnknownUnknown
npm/@humanfs/types 0.15.0 UnknownUnknown
npm/@mux/mux-data-google-ima 0.3.17 UnknownUnknown
npm/@mux/mux-player 3.12.0 🟢 5.5
Details
CheckScoreReason
Maintained🟢 1026 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 6Found 12/18 approved changesets -- score normalized to 6
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@mux/mux-player-react 3.12.0 🟢 5.5
Details
CheckScoreReason
Maintained🟢 1026 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 6Found 12/18 approved changesets -- score normalized to 6
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@mux/mux-video 0.30.7 🟢 5.5
Details
CheckScoreReason
Maintained🟢 1026 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 6Found 12/18 approved changesets -- score normalized to 6
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@mux/playback-core 0.34.1 🟢 5.5
Details
CheckScoreReason
Maintained🟢 1026 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 6Found 12/18 approved changesets -- score normalized to 6
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@types/node 25.6.0 🟢 6.5
Details
CheckScoreReason
Code-Review🟢 8Found 25/29 approved changesets -- score normalized to 8
Packaging⚠️ -1packaging workflow not detected
Maintained🟢 1030 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
License🟢 9license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Pinned-Dependencies🟢 8dependency not pinned by hash detected -- score normalized to 8
Binary-Artifacts🟢 10no binaries found in the repo
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
npm/@typescript-eslint/project-service 8.59.1 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 16/22 approved changesets -- score normalized to 7
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@typescript-eslint/scope-manager 8.59.1 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 16/22 approved changesets -- score normalized to 7
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@typescript-eslint/tsconfig-utils 8.59.1 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 16/22 approved changesets -- score normalized to 7
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@typescript-eslint/types 8.59.1 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 16/22 approved changesets -- score normalized to 7
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@typescript-eslint/typescript-estree 8.59.1 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 16/22 approved changesets -- score normalized to 7
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@typescript-eslint/utils 8.59.1 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 16/22 approved changesets -- score normalized to 7
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@typescript-eslint/visitor-keys 8.59.1 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 16/22 approved changesets -- score normalized to 7
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/ajv 6.15.0 🟢 5
Details
CheckScoreReason
Code-Review⚠️ 1Found 3/30 approved changesets -- score normalized to 1
Security-Policy🟢 10security policy file detected
Maintained🟢 88 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 8
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 2badge detected: InProgress
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/axe-core 4.11.3 🟢 6.5
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 1030 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 4branch protection is not maximal on development and all release branches
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/baseline-browser-mapping 2.10.24 UnknownUnknown
npm/brace-expansion 1.1.14 🟢 6.3
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy🟢 10security policy file detected
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Packaging⚠️ -1packaging workflow not detected
Code-Review⚠️ 2Found 7/24 approved changesets -- score normalized to 2
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Maintained🟢 1014 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 9license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/call-bind 1.0.9 🟢 4.2
Details
CheckScoreReason
Code-Review⚠️ 0Found 0/30 approved changesets -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Maintained🟢 34 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
SAST⚠️ 0no SAST tool detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 10security policy file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
npm/caniuse-lite 1.0.30001791 🟢 4.5
Details
CheckScoreReason
Code-Review⚠️ 0Found 0/30 approved changesets -- score normalized to 0
Maintained🟢 1026 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
SAST⚠️ 0no SAST tool detected
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy⚠️ 0security policy file not detected
Pinned-Dependencies🟢 10all dependencies are pinned
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
npm/castable-video 1.1.13 UnknownUnknown
npm/cli-truncate 5.2.0 🟢 4
Details
CheckScoreReason
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Code-Review⚠️ 2Found 7/30 approved changesets -- score normalized to 2
Maintained🟢 34 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/custom-media-element 1.4.6 UnknownUnknown
npm/dash-video-element 0.3.2 UnknownUnknown
npm/electron-to-chromium 1.5.344 UnknownUnknown
npm/es-abstract 1.24.2 🟢 5.2
Details
CheckScoreReason
Code-Review⚠️ 0Found 0/24 approved changesets -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 76 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 7
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Security-Policy🟢 10security policy file detected
Fuzzing⚠️ 0project is not fuzzed
SAST🟢 7SAST tool detected but not run on all commits
npm/es-iterator-helpers 1.3.2 🟢 5
Details
CheckScoreReason
Code-Review⚠️ 0Found 0/30 approved changesets -- score normalized to 0
Maintained🟢 1030 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
SAST⚠️ 0no SAST tool detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 10security policy file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
npm/es-module-lexer 2.1.0 ⚠️ 2.9
Details
CheckScoreReason
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Code-Review⚠️ 0Found 2/30 approved changesets -- score normalized to 0
Maintained⚠️ 23 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 9binaries present in source code
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/es-toolkit 1.46.0 UnknownUnknown
npm/hasown 2.0.3 UnknownUnknown
npm/hls-video-element 1.5.11 UnknownUnknown
npm/hls.js 1.6.16 🟢 6.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 24 issue activity found in the last 90 days -- score normalized to 10
Code-Review⚠️ 2Found 4/15 approved changesets -- score normalized to 2
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
License🟢 9license file detected
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection🟢 8branch protection is not maximal on development and all release branches
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
SAST🟢 10SAST tool is run on all commits
npm/media-chrome 4.19.0 🟢 5.1
Details
CheckScoreReason
Code-Review🟢 5Found 15/30 approved changesets -- score normalized to 5
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1026 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy⚠️ 0security policy file not detected
Pinned-Dependencies🟢 4dependency not pinned by hash detected -- score normalized to 4
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/media-tracks 0.3.5 UnknownUnknown
npm/mux-embed 5.18.1 UnknownUnknown
npm/node-releases 2.0.38 🟢 3.8
Details
CheckScoreReason
Code-Review⚠️ 0Found 0/30 approved changesets -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 911 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 9
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies⚠️ 2dependency not pinned by hash detected -- score normalized to 2
SAST⚠️ 0no SAST tool detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
npm/player.style 0.3.4 UnknownUnknown
npm/safe-array-concat 1.1.4 🟢 4.5
Details
CheckScoreReason
Maintained🟢 68 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
SAST⚠️ 0no SAST tool detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review⚠️ 0Found 0/30 approved changesets -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Security-Policy🟢 10security policy file detected
npm/side-channel-list 1.0.1 UnknownUnknown
npm/slice-ansi 8.0.0 🟢 4.1
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Code-Review⚠️ 0Found 1/30 approved changesets -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Maintained🟢 67 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 6
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/std-env 4.1.0 UnknownUnknown
npm/string-width 8.2.1 🟢 4.4
Details
CheckScoreReason
Code-Review🟢 3Found 9/30 approved changesets -- score normalized to 3
Packaging⚠️ -1packaging workflow not detected
Maintained🟢 66 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 6
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/undici-types 7.19.2 🟢 8.4
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 20 issue activity found in the last 90 days -- score normalized to 10
Dependency-Update-Tool🟢 10update tool detected
Code-Review🟢 10all changesets reviewed
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 8binaries present in source code
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies🟢 4dependency not pinned by hash detected -- score normalized to 4
Vulnerabilities🟢 100 existing vulnerabilities detected
Packaging🟢 10packaging workflow detected
SAST🟢 10SAST tool is run on all commits
Signed-Releases⚠️ -1no releases found
Fuzzing🟢 10project is fuzzed
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
CI-Tests🟢 1030 out of 30 merged PRs checked by a CI test -- score normalized to 10
Contributors🟢 10project has 78 contributing companies or organizations
npm/vimeo-video-element 1.7.1 UnknownUnknown
npm/ws 8.20.0 🟢 5.4
Details
CheckScoreReason
Code-Review⚠️ 1Found 3/29 approved changesets -- score normalized to 1
Security-Policy🟢 10security policy file detected
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Packaging⚠️ -1packaging workflow not detected
Maintained🟢 85 commit(s) and 5 issue activity found in the last 90 days -- score normalized to 8
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • data-management/viewer/frontend/package-lock.json

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 29, 2026

Codecov Report

❌ Patch coverage is 87.03704% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.70%. Comparing base (3f1edd1) to head (dcd2d57).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../viewer/backend/src/api/services/lerobot_loader.py 85.48% 9 Missing ⚠️
...nts/annotation-panel/LanguageInstructionWidget.tsx 92.42% 2 Missing and 3 partials ⚠️
...a-management/viewer/frontend/src/lib/api-client.ts 72.72% 2 Missing and 1 partial ⚠️
...tests__/support/annotationWorkspaceTestSupport.tsx 75.00% 1 Missing and 1 partial ⚠️
...on-workspace/useAnnotationWorkspaceMediaSources.ts 85.71% 0 Missing and 2 partials ⚠️
...ent/viewer/frontend/src/stores/annotation-store.ts 80.00% 0 Missing and 2 partials ⚠️
data-management/viewer/backend/src/api/config.py 75.00% 1 Missing ⚠️
...ent/viewer/backend/src/api/routers/joint_config.py 0.00% 1 Missing ⚠️
...anagement/viewer/backend/src/api/routers/labels.py 50.00% 1 Missing ⚠️
...ackend/src/api/services/dataset_service/service.py 0.00% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #591      +/-   ##
==========================================
+ Coverage   63.91%   67.70%   +3.79%     
==========================================
  Files         250      263      +13     
  Lines       15409    16827    +1418     
  Branches     2163     2331     +168     
==========================================
+ Hits         9848    11392    +1544     
+ Misses       5274     5142     -132     
- Partials      287      293       +6     
Flag Coverage Δ *Carryforward flag
pester 83.13% <ø> (ø) Carriedforward from 60cc414
pytest-data-pipeline 100.00% <ø> (ø) Carriedforward from 60cc414
pytest-dataviewer 66.92% <87.12%> (+1.80%) ⬆️
pytest-dm-tools 100.00% <ø> (ø) Carriedforward from 60cc414
pytest-evaluation 99.83% <ø> (?)
pytest-fuzz 4.90% <0.00%> (-0.08%) ⬇️
pytest-inference 0.00% <ø> (ø) Carriedforward from 60cc414
pytest-training 82.14% <ø> (ø) Carriedforward from 60cc414
vitest 53.02% <86.95%> (+1.93%) ⬆️

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...ement/viewer/backend/src/api/models/annotations.py 100.00% <100.00%> (ø)
...r/backend/src/api/services/dataset_service/base.py 78.26% <100.00%> (+3.90%) ⬆️
...rc/api/services/dataset_service/lerobot_handler.py 33.70% <100.00%> (+3.11%) ⬆️
...nnotation-workspace/AnnotationWorkspaceContent.tsx 100.00% <100.00%> (+13.33%) ⬆️
...ion-workspace/AnnotationWorkspaceTrajectoryTab.tsx 100.00% <100.00%> (+25.00%) ⬆️
...nnotation-workspace/useAnnotationWorkspaceShell.ts 77.00% <ø> (ø)
...anagement/viewer/frontend/src/types/annotations.ts 100.00% <100.00%> (ø)
data-management/viewer/backend/src/api/config.py 74.68% <75.00%> (ø)
...ent/viewer/backend/src/api/routers/joint_config.py 46.15% <0.00%> (ø)
...anagement/viewer/backend/src/api/routers/labels.py 78.65% <50.00%> (ø)
... and 8 more

... and 13 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

akzaidi added 10 commits April 29, 2026 04:07
- Add libdav to cspell dictionary (libdav1d reference in lerobot_handler docstring)
- Sort imports in AnnotationWorkspacePlaybackCard for simple-import-sort
- Update ffmpeg extraction tests to mock _resolve_ffmpeg directly

🤖 - Generated by Copilot
- Format ffmpeg test monkeypatch calls onto single lines for ruff
- Add cameras/selectedCamera/onSelectCamera to test fixtures for new
  AnnotationWorkspacePlaybackCard required props

🤖 - Generated by Copilot
- Apply prettier to AnnotationWorkspacePlaybackCard and useAnnotationWorkspaceShell
- Add CameraSelector to episode-viewer mock so AnnotationWorkspace tests render
- Derive cameraName synchronously via useMemo with separate override state
  so initial render no longer produces a transient null videoSrc that
  triggers the frame-only autoplay path twice

🤖 - Generated by Copilot
- format paths with both v2.x (episode_chunk/episode_index) and v3 placeholders
- derive chunk index from episode_index // chunks_size for v2.x layouts
- read episode lengths from meta/episodes.jsonl when present
- add tests covering v2.x path resolution and episode metadata

🛠️ - Generated by Copilot
…dataviewer

- add LanguageInstructionAnnotation model, store actions, and panel widget
- load task descriptions from meta/tasks.jsonl and tasks.parquet
- preserve dataset feature keys when transforming snake_case API responses
- support v2.x LeRobot layout in loader and read episodes.jsonl lengths
- cover v2.x layout and jsonl metadata with new loader tests

🏷️ - Generated by Copilot
- move trajectory plot and subtask timeline above the subtasks pane
- shrink trajectory plot to a fixed 180px height
- collapse the labels panel back to a single full-height column

🎨 - Generated by Copilot
- compute finite-difference velocities in build_trajectory when not provided
- guards against zero or non-monotonic timestamps with a small dt floor

📈 - Generated by Copilot
…y layout tests

- Track the LanguageInstructionWidget component that was referenced from
  the annotation-panel barrel but never committed
- Mock LanguageInstructionWidget in the workspace test support module
- Update trajectory tab layout tests to match the compact single-column
  labels panel and graph-inside-playback-group structure

🤖 - Generated by Copilot
- rename HMI_STORAGE_BACKEND to STORAGE_BACKEND across backend, tests, docker-compose, Dockerfile, README, and dataviewer Terraform module
- rename HMI_DATA_PATH to DATA_DIR across config, routers, services, tests, .env examples, and Dockerfile
- add --data-dir/--data-dir=<path> argument to data-management/viewer/start.sh with sensible default of <repo>/datasets and missing-path warning
- default dev:backend DATA_DIR to ../../../datasets in viewer package.json so launching from the VS Code task picks up the repo-root datasets folder

🤖 - Generated by Copilot
Copy link
Copy Markdown
Collaborator

@katriendg katriendg left a comment

Choose a reason for hiding this comment

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

Thanks so much @akzaidi, this is great work and adding a big new update for dataviewer!

Reviewed with Copilot and there are a number of things we can enhance before merging - also happy to pick up any of these in your branch directly before we merge. Let's discuss!

Multi-camera selection, AV1 thumbnails, LeRobot v2.x compatibility, and the language-instruction widget are all valuable additions, and I confirmed locally that the test suite (414 backend, 658 frontend) is green on the branch. A few items to resolve before merge:

📚 Missing user-facing documentation for the new features

This PR ships two net-new user-visible capabilities, and neither is documented anywhere a user (or an agent driving the dataviewer) would discover them:

  • Camera selector — no mention in data-management/viewer/README.md, .github/skills/dataviewer/SKILL.md, or the docs site. A user with a multi-camera dataset has no way to know switching is now possible, where the control lives, or how the fallback (cameras[0] when override is stale) behaves.
  • Language instruction / VLA annotation — same gap. The 317-line LanguageInstructionWidget introduces new annotation semantics (source: human / template / llm-generated / retroactive, paraphrases for augmentation, subtask decomposition for hierarchical conditioning) that downstream training consumers will need to understand. Today this is only documented in TS/Py docstrings.

Please add a short "Annotation features" or "What you can annotate" subsection to the viewer README covering both, and update the dataviewer SKILL.md so the agent knows these surfaces exist.

📝 Documentation drift from the env var rename

The HMI_DATA_PATH → DATA_DIR / HMI_STORAGE_BACKEND → STORAGE_BACKEND rename was not propagated to:

Also rename HMI_LOCAL_DATA_PATH at the source. It's still used as the docker-compose host-mount selector in data-management/viewer/docker-compose.yml and in the README example at data-management/viewer/README.md. Keeping the HMI_ prefix only here will read as an incomplete rename and confuse future readers. Suggest renaming to something like DATAVIEWER_HOST_DATA_DIR (or LOCAL_DATA_PATH) in the compose file, README, and any CI workflow that references it (e.g., .github/workflows/dast-zap-scan.yml).

🧪 Test coverage gaps for the new code paths

Surface Why it matters
LanguageInstructionWidget.tsx (new, 317 LOC) Currently mocked as <div>Language Instructions</div> in test support; zero direct tests for empty state, "Use as Instruction" template seeding, paraphrase/subtask add+remove, Enter-key submit, or clear.
LanguageInstructionAnnotation round-trip No backend test posts/reads an EpisodeAnnotation containing a language instruction.
LeRobotLoader.get_tasks() New method, neither the jsonl nor the parquet branch is exercised. The new TestV2EpisodeLayout fixture already writes task rows — extending it is one assertion.
build_trajectory velocity estimation Brand-new finite-difference path with no unit test, including the length<=1 and zero-dt edge cases.
_resolve_ffmpeg The test refactor monkeypatches the resolver itself, which removes coverage of the actual imageio_ffmpegshutil.which fallback chain that this PR introduces. Add a focused test for the resolver.
Camera override in useAnnotationWorkspaceMediaSources Author calls this "indirect" — please add direct assertions for stale-override fallback and stable first-render cameraName.

🔒 Security / robustness

  • LanguageInstructionAnnotation.paraphrases and subtask_instructions are unbounded lists of unbounded strings. instruction itself is max_length=1000, but the lists are not, so a client can post multi-MB payloads that get persisted to the on-disk JSON store. Please add a max_length on each list and a per-item max_length to mirror instruction.

🧠 Code soundness (medium)

  • LeRobotLoader._is_v2_layout: substring check "{episode_index" in data_path works today, but the comment promises codebase_version-independent detection. A future v3 template that uses {episode_index} for naming would silently flip to v2 mode. Tighten by also requiring {episode_chunk or matching the episode_*.parquet filename pattern.
  • build_trajectory: the velocity-estimation guard checks the length parameter, not joint_positions.shape[0]. If a caller ever passes length>1 against a single-row positions array, np.diff returns empty and the assignment raises. Add joint_positions.shape[0] > 1 to the guard.
  • LeRobotLoader.get_tasks() parquet branch uses bare except Exception while the jsonl branch narrows to (json.JSONDecodeError, OSError). Make them consistent.

✅ What's solid

  • Camera-override design (override state + useMemo) avoids the autoplay double-fire cleanly.
  • AV1 fix via imageio_ffmpeg is the right call.
  • v2.x layout regression test (TestV2EpisodeLayout) is well-built.
  • start.sh --data-dir parsing handles both spellings with empty-value guarding.
  • Terraform STORAGE_BACKEND rename is consistent.

akzaidi added 2 commits April 29, 2026 21:07
…rename

- bound paraphrases/subtask_instructions, tighten v2 layout detection, fix velocity guard
- rename HMI_DATA_PATH to DATA_DIR and HMI_LOCAL_DATA_PATH to DATAVIEWER_HOST_DATA_DIR
- add backend + frontend tests for new annotation surfaces
- document camera selector and language instruction widget

🛠️ - Generated by Copilot
- reflow build_trajectory velocity guard onto a single line per ruff
- reformat new LanguageInstructionWidget and media-sources tests with prettier

🎨 - Generated by Copilot
@akzaidi
Copy link
Copy Markdown
Contributor Author

akzaidi commented Apr 30, 2026

Thank you @katriendg for the review! Tried to tackle most of those misses and gaps. I am doing a refactor of the agentic harness in a separate branch, but gave the dataviewer a pass with a couple datasets to make sure it works with the new features now. But much more to come in a future PR!

…aviewer-multi-camera

- Cover playback card controls, range slider, and media-source branches
- Add trajectory tab and content guard tests
- Extend LanguageInstructionWidget, api-client, and annotation type tests
- PR-scoped frontend coverage: 96.5% lines, 97.0% functions, 79.0% branches
- Track remaining branch gaps under #210 sub-issues (#214, #215, #217)

🤖 - Generated by Copilot
…me interpolation

🔧 - Generated by Copilot
Copy link
Copy Markdown
Collaborator

@katriendg katriendg left a comment

Choose a reason for hiding this comment

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

Thanks @akzaidi! I added a few front-end tests, though we need to cover more tests which is already tracked by front-end test issue backlog. Just focused on some of the changes.

I believe this is good to merge, and then @WilliamBerryiii we can pick-up and work on #590

@akzaidi akzaidi merged commit c809d2f into main Apr 30, 2026
46 checks passed
@akzaidi akzaidi deleted the feat/dataviewer-multi-camera branch April 30, 2026 15:23
WilliamBerryiii pushed a commit that referenced this pull request May 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.8.0](v0.7.4...v0.8.0)
(2026-05-08)


### ⚠ BREAKING CHANGES

* **dataviewer:** bump frontend stack to React 19, Vite 8, Tailwind v4,
MSAL 5, ESLint 10
([#524](#524))

### ✨ Features

* **agents:** add automated validation for high-risk Dependabot bumps
([#574](#574))
([8c3686a](8c3686a)),
closes
[#573](#573)
* **data:** add camera selector to annotation workspace and fix AV1
frame extraction
([#591](#591))
([c809d2f](c809d2f))
* **data:** seed dataviewer frontend test foundation and per-section
codecov flags
([#594](#594))
([c06c4e3](c06c4e3))
* **dataviewer:** add OWASP security middleware stack
([#439](#439))
([239edb9](239edb9))
* **infrastructure:** add conversion pipeline Terraform module
([#542](#542))
([244531e](244531e))
* **infrastructure:** upgrade OSMO to chart 1.2.1 / image 6.2 with
secure auth and skrl 2.0.0 compatibility
([#492](#492))
([edfd7a5](edfd7a5))
* **pipeline:** add ACSA setup for ROS2 bag sync to Blob
([#451](#451))
([c271a54](c271a54))
* **workflows:** add advisory Dependabot PR reviewer agentic workflow
([#498](#498))
([d4bb140](d4bb140))
* **workflows:** trigger AW Dependabot PR reviewer after PR Validation
([#580](#580))
([7ab3d16](7ab3d16))


### 🐛 Bug Fixes

* **ci:** correct stale version comment for
actions/create-github-app-token
([#506](#506))
([b2e9a54](b2e9a54))
* **ci:** restore data-pipeline and training broken tests by domain
folder restructure
([#547](#547))
([06d8472](06d8472))
* **docs:** update remaining stale 'Coming soon' labels in
docs/README.md
([#507](#507))
([02439d6](02439d6))
* **docs:** update stale coming soon label for Training section
([#472](#472))
([46db49b](46db49b))
* **evaluation:** scope SIL AzureML validation code path and script
reference
([#387](#387))
([9f138a9](9f138a9))
* **infrastructure:** OSMO workflow execution, PostgreSQL public access,
and quickstart corrections
([#477](#477))
([9ed2da6](9ed2da6))
* **scripts:** exclude CHANGELOG.md from changed-files msdate check
([#644](#644))
([8133bdc](8133bdc))
* **workflows:** allow dependabot[bot] to activate AW Dependabot PR
Review
([#586](#586))
([39dc022](39dc022))
* **workflows:** correct branches filter on AW Dependabot PR Review
workflow_run trigger
([#584](#584))
([fe06b52](fe06b52))
* **workflows:** normalize validate.yaml placeholder env/compute values
([#510](#510))
([340ff44](340ff44))
* **workflows:** recompile aw-dependabot-pr-review lock file
([#576](#576))
([d77c167](d77c167))
* **workflows:** switch AW Dependabot PR Review to pull_request_target
([#589](#589))
([3f1edd1](3f1edd1))


### 📚 Documentation

* **docs:** Fix deployment guide links
([#614](#614))
([0070b04](0070b04))
* document dependency-pinning-artifacts directory purpose
([#508](#508))
([50e0010](50e0010))


### 📦 Build System

* **training:** standardize on Python 3.12 across manifests, containers,
and runtime scripts
([#541](#541))
([7ad014a](7ad014a))


### 🔧 Operations

* **build:** add Copilot cloud agent setup-steps workflow
([#593](#593))
([c912668](c912668))


### 🔧 Miscellaneous

* **build:** exclude auto-generated CHANGELOG.md from cspell and seed
dictionary
([#582](#582))
([de1dd57](de1dd57))
* **build:** redesign codecov flags and split pytest CI per component
([#520](#520))
([357e745](357e745))
* **dataviewer:** bump frontend stack to React 19, Vite 8, Tailwind v4,
MSAL 5, ESLint 10
([#524](#524))
([50f8ad4](50f8ad4))
* **dataviewer:** repoint stale src/dataviewer references to
data-management/viewer
([#504](#504))
([88fa1b4](88fa1b4)),
closes
[#503](#503)
* **deps-dev:** bump basic-ftp from 5.3.0 to 5.3.1
([#618](#618))
([ca10f2a](ca10f2a))
* **deps-dev:** bump globals from 15.15.0 to 17.5.0 in
/data-management/viewer/frontend
([#527](#527))
([0e0b2ae](0e0b2ae))
* **deps-dev:** bump ip-address from 10.1.0 to 10.2.0
([#616](#616))
([816c9cf](816c9cf))
* **deps-dev:** bump lint-staged from 16.4.0 to 17.0.2 in the
root-npm-dependencies group across 1 directory
([#626](#626))
([0e2f293](0e2f293))
* **deps-dev:** bump pydantic from 2.13.3 to 2.13.4 in the
python-dependencies group across 1 directory
([#629](#629))
([c24f1c1](c24f1c1))
* **deps-dev:** bump the python-dependencies group across 1 directory
with 2 updates
([#514](#514))
([8410f4b](8410f4b))
* **deps:** bump azure-core from 1.39.0 to 1.40.0 in /evaluation in the
inference-dependencies group across 1 directory
([#597](#597))
([6141db4](6141db4))
* **deps:** bump cryptography from 46.0.6 to 46.0.7 in
/data-management/viewer
([#424](#424))
([5fb6d58](5fb6d58))
* **deps:** bump cryptography from 46.0.6 to 46.0.7 in
/data-management/viewer/backend
([#423](#423))
([b516ad5](b516ad5))
* **deps:** bump lucide-react from 0.469.0 to 1.8.0 in
/data-management/viewer/frontend
([#528](#528))
([1bdfc1e](1bdfc1e))
* **deps:** bump nginx from `8aa63af` to `5616878` in
/data-management/viewer/frontend
([#511](#511))
([9e7e20e](9e7e20e))
* **deps:** bump nginx from 1.27-alpine to 1.29-alpine in
/data-management/viewer/frontend
([#484](#484))
([0e5c3dd](0e5c3dd))
* **deps:** bump node from `435f353` to `e49fd70` in
/data-management/viewer/frontend
([#560](#560))
([2884649](2884649))
* **deps:** bump react-is from 18.3.1 to 19.2.5 in
/data-management/viewer/frontend
([#530](#530))
([d51318c](d51318c))
* **deps:** bump tensordict from 0.11.0 to 0.12.1 in /evaluation in the
inference-dependencies group across 1 directory
([#456](#456))
([b24e733](b24e733))
* **deps:** bump the dataviewer-backend-dependencies group across 1
directory with 2 updates
([#531](#531))
([171a1da](171a1da))
* **deps:** bump the dataviewer-backend-dependencies group across 1
directory with 5 updates
([#516](#516))
([4f9a577](4f9a577))
* **deps:** bump the dataviewer-backend-dependencies group across 1
directory with 5 updates
([#602](#602))
([6c27ab5](6c27ab5))
* **deps:** bump the dataviewer-dependencies group across 1 directory
with 2 updates
([#529](#529))
([8646971](8646971))
* **deps:** bump the dataviewer-dependencies group across 1 directory
with 3 updates
([#601](#601))
([d28fb50](d28fb50))
* **deps:** bump the dataviewer-dependencies group across 1 directory
with 3 updates
([#632](#632))
([4ca5f3e](4ca5f3e))
* **deps:** bump the dataviewer-dependencies group across 1 directory
with 5 updates
([#515](#515))
([109ee81](109ee81))
* **deps:** bump the dataviewer-frontend-patch-minor group across 1
directory with 6 updates
([#630](#630))
([04d5dfd](04d5dfd))
* **deps:** bump the dataviewer-frontend-patch-minor group across 1
directory with 9 updates
([#563](#563))
([c08f450](c08f450))
* **deps:** bump the docusaurus-dependencies group across 1 directory
with 4 updates
([#627](#627))
([f5825fc](f5825fc))
* **deps:** bump the docusaurus-dependencies group across 1 directory
with 6 updates
([#599](#599))
([b859344](b859344))
* **deps:** bump the github-actions group across 1 directory with 4
updates
([#459](#459))
([2609c52](2609c52))
* **deps:** bump the github-actions group across 1 directory with 4
updates
([#517](#517))
([f54bf5d](f54bf5d))
* **deps:** bump the inference-dependencies group across 1 directory
with 11 updates
([#562](#562))
([087f53a](087f53a))
* **deps:** bump the inference-dependencies group across 1 directory
with 2 updates
([#628](#628))
([4a3be47](4a3be47))
* **deps:** bump the pip group across 2 directories with 1 update
([#494](#494))
([a14b6b0](a14b6b0))
* **docs:** update stale Python 3.11 references to 3.12
([#575](#575))
([6f85c95](6f85c95))
* **scripts:** remove redundant SC1091 disables in OSMO deploy scripts
([#509](#509))
([ae1cb82](ae1cb82))


### 🔒 Security

* **build:** pin dependencies and hash-verify downloads
([#465](#465))
([0289f49](0289f49))
* **build:** remediate dependency security advisories
([#479](#479))
([7196d6d](7196d6d))
* **deps-dev:** bump basic-ftp from 5.2.1 to 5.2.2
([#454](#454))
([cb158f1](cb158f1))
* **deps-dev:** bump basic-ftp from 5.2.2 to 5.3.0
([#495](#495))
([e983b8b](e983b8b))
* **deps-dev:** bump hypothesis from 6.152.3 to 6.152.4 in the
python-dependencies group
([#598](#598))
([83384d2](83384d2))
* **deps-dev:** bump markdownlint-cli2 from 0.22.0 to 0.22.1 in the
root-npm-dependencies group
([#559](#559))
([32bde35](32bde35))
* **deps-dev:** bump picomatch from 2.3.1 to 2.3.2 in /docs/docusaurus
([#455](#455))
([66f86ca](66f86ca))
* **deps-dev:** bump postcss from 8.5.10 to 8.5.12 in
/data-management/viewer/frontend
([#569](#569))
([a652dba](a652dba))
* **deps-dev:** bump the python-dependencies group with 2 updates
([#457](#457))
([749d231](749d231))
* **deps-dev:** bump the python-dependencies group with 2 updates
([#485](#485))
([71b44fd](71b44fd))
* **deps-dev:** bump the python-dependencies group with 3 updates
([#564](#564))
([9fc52fd](9fc52fd))
* **deps-dev:** bump typescript from 6.0.2 to 6.0.3 in /docs/docusaurus
in the docusaurus-dependencies group
([#513](#513))
([5694dbc](5694dbc))
* **deps:** bump azureml/openmpi4.1.0-ubuntu22.04 from 20260303.v5 to
20260409.v4 in /evaluation/sil/docker
([#480](#480))
([25d4df8](25d4df8))
* **deps:** bump cryptography from 46.0.6 to 46.0.7 in /evaluation in
the uv group across 1 directory
([#538](#538))
([92c5b2e](92c5b2e))
* **deps:** bump diffusers from 0.35.2 to 0.38.0 in /training/il/lerobot
([#638](#638))
([6261d19](6261d19))
* **deps:** bump follow-redirects from 1.15.11 to 1.16.0 in
/docs/docusaurus
([#469](#469))
([0458908](0458908))
* **deps:** bump gitpython and mako for lerobot IL training
([#623](#623))
([9f8022b](9f8022b))
* **deps:** bump node from 24.14.1-slim to 25.9.0-slim in
/data-management/viewer/frontend
([#482](#482))
([1532d09](1532d09))
* **deps:** bump packaging from 26.0 to 26.1 in /evaluation in the
inference-dependencies group
([#483](#483))
([f4afb6c](f4afb6c))
* **deps:** bump pillow from 12.1.1 to 12.2.0
([#467](#467))
([39fb663](39fb663))
* **deps:** bump python from 3.11-slim to 3.14-slim in
/data-management/viewer/backend
([#481](#481))
([7af9dfc](7af9dfc))
* **deps:** bump the dataviewer-backend-dependencies group across 1
directory with 15 updates
([#428](#428))
([e4446a2](e4446a2))
* **deps:** bump the dataviewer-backend-dependencies group in
/data-management/viewer/backend with 4 updates
([#487](#487))
([0f57c5b](0f57c5b))
* **deps:** bump the dataviewer-backend-dependencies group in
/data-management/viewer/backend with 8 updates
([#566](#566))
([d6e7869](d6e7869))
* **deps:** bump the dataviewer-dependencies group across 1 directory
with 5 updates
([#464](#464))
([24c208d](24c208d))
* **deps:** bump the dataviewer-dependencies group in
/data-management/viewer with 2 updates
([#486](#486))
([90149f3](90149f3))
* **deps:** bump the dataviewer-dependencies group in
/data-management/viewer with 6 updates
([#565](#565))
([f0bb36b](f0bb36b))
* **deps:** bump the dataviewer-frontend-patch-minor group across 1
directory with 10 updates
([#613](#613))
([e481f83](e481f83))
* **deps:** bump the github-actions group across 1 directory with 4
updates
([#534](#534))
([5478ab6](5478ab6))
* **deps:** bump the github-actions group with 2 updates
([#488](#488))
([4e6ce98](4e6ce98))
* **deps:** bump the github-actions group with 3 updates
([#567](#567))
([48c38dc](48c38dc))
* **deps:** bump the github-actions group with 3 updates
([#634](#634))
([00cfb49](00cfb49))
* **deps:** bump the github-actions group with 6 updates
([#603](#603))
([73eb79a](73eb79a))
* **deps:** bump the training-dependencies group across 1 directory with
23 updates
([#463](#463))
([d5a8656](d5a8656))
* **deps:** bump yaml from 2.8.2 to 2.8.3 in
/data-management/viewer/frontend
([#453](#453))
([10449df](10449df))
* pytest harness, dependabot advisories, and OSSF Scorecard remediations
([#501](#501))
([e8756e8](e8756e8))
* **scripts:** pin and hash-verify all shell script downloads
([#468](#468))
([0c2bb9c](0c2bb9c))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: physical-ai-toolchain-release[bot] <267194360+physical-ai-toolchain-release[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(dataviewer): support multiple camera angles in episode viewer

3 participants