Support launching DIVE Desktop on a dataset from the command line#1754
Open
mattdawkins wants to merge 3 commits into
Open
Support launching DIVE Desktop on a dataset from the command line#1754mattdawkins wants to merge 3 commits into
mattdawkins wants to merge 3 commits into
Conversation
Add --import / --annotations / --name so the app can be started directly on media plus an annotation file, skipping the import wizard: dive-desktop --import input_list.txt --annotations detections.csv --import accepts anything the wizard does (image directory, image-list text file, or video) and --annotations accepts a VIAME CSV or DIVE JSON. The import runs through the same backend calls as the wizard (beginMediaImport -> finalizeMediaImport -> dataFileImport), so the result is an ordinary dataset: it lands in the recents list and can be reopened later. Media needing transcoding is converted first and opens when the job completes. Two things worth calling out: - The renderer pulls the pending dataset (desktop:cli-open-pending) once it is mounted, rather than the main process pushing it. Settings are owned by the renderer and handed to the background process at startup, and the import needs them, so the request waits on that handoff. It also avoids racing an import that finishes before the window is ready. - A second launch carrying --import forwards to the running instance instead of being dropped by the single-instance lock. The args are parsed from the raw process.argv and passed via requestSingleInstanceLock(additionalData), because the argv Chromium forwards to second-instance hoists switches ahead of positionals and so detaches --import from its value. Window creation is now guarded on holding the lock; a losing instance previously raced its own app.quit() and could report a spurious startup failure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The launch flags only handled single-camera datasets, since they went
straight to beginMediaImport. Name each camera instead to import a
multi-camera or stereo dataset:
dive-desktop --camera left=/data/left --camera right=/data/right \
--annotations left=/data/left.csv --annotations right=/data/right.csv \
--calibration /data/calibration_matrices.npz
--camera is repeatable and takes <name>=<media>, splitting on the first =
so Windows paths survive; flag order is the display order. --annotations
becomes <camera>=<file> in this mode, since each camera carries its own
track file. --calibration takes a stereo calibration (.npz or .json), and
--default-display picks the camera shown on open (default: left when
present, else the first camera).
Stereo is not a separate flag: as elsewhere in DIVE, cameras named exactly
left and right are typed stereo by the importer, anything else multicam.
Multi-camera launches route through beginMultiCamImport rather than
beginMediaImport, which takes the per-camera track files in its sourceList
and hands the calibration to finalizeMediaImport to copy and normalize, so
annotations must not also be imported via dataFileImport.
Also fixed along the way:
- second-instance forwarding gated on cliArgs.importPath, which a
multi-camera launch does not set, so forwarding a multi-camera dataset to
a running instance was silently dropped.
- parseCliArgs can now reject bad usage (mixing --import with --camera, a
lone camera, annotations naming an unknown camera, mismatched media
kinds). It is called at module scope, so a throw there would have taken
the process down with no message; the error is now held and reported once
the app is ready.
- a failed CLI import only raised a modal dialog, which is invisible to
anyone driving the app from a script; it is logged as well now, and the
message no longer says "Failed to open undefined" for multi-camera.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Opening a dataset while the viewer already shows another one keeps ViewerLoader mounted and only changes the :id route param. Vue Router calls beforeRouteUpdate for that, not beforeRouteLeave, so the unsaved-changes guard never ran -- and the id watcher in Viewer reloads by way of discardChanges(), silently throwing away unsaved edits. Guard beforeRouteUpdate with the same navigateAwayGuard. Previously unreachable, since navigation into the viewer always came from another route. The CLI launch flags made it reachable: forwarding a dataset to a running instance navigates viewer -> viewer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mattdawkins
added a commit
to VIAME/VIAME
that referenced
this pull request
Jul 13, 2026
Points the dive submodule at viame/master f1fe0b2a, which adds --import / --annotations / --name to dive-desktop so it can be started directly on media plus an annotation file (VIAME CSV or DIVE JSON), skipping the import wizard: dive-desktop --import input_list.txt --annotations detections.csv Upstream PR against dive main: Kitware/dive#1754 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mattdawkins
added a commit
to VIAME/VIAME
that referenced
this pull request
Jul 13, 2026
Points the dive submodule at viame/master d622e3a2, which extends the
dive-desktop launch flags to multi-camera and stereo datasets:
dive-desktop --camera left=<media> --camera right=<media> \
--annotations left=<file> --annotations right=<file> \
--calibration <file>
Cameras named exactly left/right import as stereo, anything else as
multicam, matching how DIVE types these datasets elsewhere.
Upstream PR against dive main: Kitware/dive#1754
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mattdawkins
added a commit
to VIAME/VIAME
that referenced
this pull request
Jul 13, 2026
Opening a dataset from the command line while the viewer already shows another one navigates viewer -> viewer, which fires beforeRouteUpdate rather than beforeRouteLeave, so DIVE's unsaved-changes guard was skipped and the reload silently discarded unsaved edits. Upstream PR against dive main: Kitware/dive#1754 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
--import/--annotations/--nameso DIVE Desktop can be started directly on media plus an annotation file, skipping the import wizard:dive-desktop --import input_list.txt --annotations detections.csv --name "Sea Lions"--importaccepts anything the wizard does (an image-sequence directory, an image-list text file, or a video);--annotationsaccepts a VIAME CSV or DIVE JSON.This came out of wanting to review detector output over an image list without clicking through the import wizard each time.
Behavior
The import runs through the same backend calls as the wizard (
beginMediaImport→finalizeMediaImport→dataFileImport), so the result is an ordinary dataset — it lands in the recents list and can be reopened later, exactly as if it had been imported by hand. Media that needs transcoding is converted first, and the viewer opens when the conversion job completes.Two things worth a look in review
Renderer pulls, main process does not push. The renderer asks for the pending dataset (
desktop:cli-open-pending) once it is mounted. Settings are owned by the renderer and handed to the background process at startup, and the import needs them (fordataPath), so the request waits on that handoff — otherwise the backend throwssettings has not been initialized. Pulling also avoids racing the listener registration against an import that finishes before the window is ready.Second-instance forwarding. A second launch carrying
--importnow opens that dataset in the running window instead of being dropped by the single-instance lock. The args are parsed from the rawprocess.argvand handed over viarequestSingleInstanceLock(additionalData), because the argv Chromium forwards tosecond-instancehoists switches ahead of positionals and thereby detaches--importfrom its value:Window creation is now guarded on actually holding the lock. Previously a losing instance raced its own
app.quit(), and with the "already running" dialog no longer blocking that race it would build a window mid-teardown and report a spurious "application failed to start".Testing
=syntax, short flags, relative-path resolution, and not swallowing a following flag as a value).build:electron:dirand exercised end to end on a 3-image list with a VIAME CSV of 570 polygon detections: dataset imports, viewer opens, annotations and polygons render, dataset appears in recents. Second-instance forwarding verified with a separate CSV opening into the already-running window.platform/suite passes apart from twoweb-girder/multicamFileRegistry.spec.tsfailures that reproduce on a cleanmainand are unrelated to this change.🤖 Generated with Claude Code