Skip to content

Add /orbit: hand the Loom CLI session off to the Orbit desktop app#141

Open
dannon wants to merge 12 commits into
galaxyproject:mainfrom
dannon:feat/orbit-handoff
Open

Add /orbit: hand the Loom CLI session off to the Orbit desktop app#141
dannon wants to merge 12 commits into
galaxyproject:mainfrom
dannon:feat/orbit-handoff

Conversation

@dannon
Copy link
Copy Markdown
Member

@dannon dannon commented May 29, 2026

/orbit lets someone who started in npx @galaxyproject/loom pop the same analysis open in Orbit with one keystroke -- same cwd, same notebook, richer view. The CLI shuts down gracefully (its session-shutdown lifecycle writes the notebook summary first) and Orbit resumes that cwd, so there are never two brains writing one session.

How it works:

  • findOrbit() locates an installed Orbit (ORBIT_BIN override, then platform-conventional paths); launchOrbit() spawns it detached with --cwd <cwd> and unrefs so the CLI can exit.
  • The /orbit command glues those together: launch + graceful shutdown, or a "not installed -- grab a release" message with the URL.
  • Orbit's main process learns --cwd <path> (above LOOM_CWD) plus a single-instance lock, so a second Orbit --cwd X hands its argv to the running instance, which switches the analysis dir behind a confirm dialog instead of opening a second window.

v1 launches an already-installed Orbit; auto-installing from the release feed when it's missing is a deferred follow-up. Discovery is unit-tested per platform; the launch/handoff itself is observation-only (manual macOS smoke still to do).

Note: the macOS binary inside Orbit.app is lowercase orbit (forge's executableName), verified against the built app -- the discovery paths reflect that.

dannon added 12 commits May 29, 2026 07:14
The extension API exposes ctx.cwd as the session's working directory, which is the right contract -- process.cwd() reads the shell's current dir and could drift if the user cd's mid-session.
The bundle is Orbit.app, but forge.config sets executableName: "orbit", so
the inner binary (and CFBundleExecutable) is lowercase. The darwin candidates
pointed at .../MacOS/Orbit, which never exists on a real install, so /orbit
always reported "not installed" on macOS. Verified against the built Orbit.app.
…rbit

The brain (extensions/loom/) was carrying Orbit-specific knowledge -- install
paths, the .app bundle layout, the --cwd launch protocol, ORBIT_BIN, the release
URL -- which breaks the shell-neutral rule. Pulled all of it into a sibling pi
extension, extensions/orbit-handoff/, that owns the launcher and the /orbit
command; bin/loom.js loads it via -e the same way it loads the brain. A sibling
extension (not bin/ or shared/) keeps it inside the typecheck scope while
staying out of the brain.

Also fixes the session-kill bug: bin/loom.js is also Orbit's embedded brain, so
/orbit could fire there and shut the embedded session down. The handler now
no-ops with a notice when LOOM_SHELL_KIND is "orbit". Test covers that guard.
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.

1 participant