feat(orbit): add 'glab orbit local' command + extract binarymgr package

Summary

Adds a new glab orbit local command that downloads, installs, updates, and runs the Orbit local CLI binary — same UX as glab duo cli (--install, --update, --yes, plus pass-through args).

To support both binaries without duplication, the managed-binary lifecycle that previously lived under internal/commands/duo/cli/cliutils is extracted into a reusable internal/binarymgr package driven by a Spec. Duo migrates onto it; orbit local plugs in with a tarball extractor for its .tar.gz distribution.

This MR is bootstrap-only — no query/status/etc. subcommands under orbit local. All other args are passed through to the binary.

Commits

  1. refactor(binarymgr) — extract managed-binary lifecycle into shared internal/binarymgr package; migrate duo/cli to use it; delete duo/cli/cliutils. Behavior-preserving for duo.
  2. feat(orbit) — add glab orbit local command, executors, config keys (orbit_local_*), env-var mapping (GLAB_ORBIT_LOCAL_BINARY_PATH), regenerated config stub and docs.
  3. fix(scripts) — make changed-test-pkgs.sh skip dirs that no longer exist on disk so make test-changed works after a package deletion (surfaced by deleting cliutils).

Distribution facts

  • Project: gitlab-org/orbit/knowledge-graph (ID 77960826)
  • Generic package: orbit-local, version omits leading v (e.g. 0.53.0)
  • Asset: orbit-local-<os>-<arch>.tar.gz containing top-level orbit binary
  • Platforms: darwin/linux × x86_64/aarch64. No Windows (not published upstream).
  • Pre-1.0, so MaxCompatibleMajor is intentionally unset (uncapped). Add a cap when 1.0 ships.

Notable design choices

  • internal/binarymgr/: Spec describes the binary; Manager owns registry/download/install; Runner owns prompt + exec orchestration. TarGzExtractor plugs in for tarball-distributed binaries with zip-slip and absolute-path guards.
  • Executor is a closure: each command package builds a func(ctx, path, args) that closes over its IOStreams and adds its own distribution env var (GITLAB_DUO_DISTRIBUTION / GITLAB_ORBIT_DISTRIBUTION). Unix uses syscall.Exec; Windows uses subprocess.
  • Shared install dir: both binaries land in <config-dir>/bin/ (duo, orbit) — same package-manager-style layout, no PATH pollution.

Test plan

  • make build
  • make test (3181 tests, 0 failed, 7 skipped)
  • make lint (0 issues)
  • make gen-docs
  • go vet ./...
  • Ported all original duo cliutils tests onto binarymgr, plus new tests for TarGzExtractor (extraction, missing binary, zip-slip, absolute-path, symlink skip)
  • Integration test for detectPlatform against the running host
  • Manual smoke test on macOS: glab orbit local --install, glab orbit local --update, plain glab orbit local
  • Manual smoke test that glab duo cli --install / --update still work unchanged

Configuration / env vars added

Config key Env var
orbit_local_auto_run
orbit_local_auto_download
orbit_local_binary_path GLAB_ORBIT_LOCAL_BINARY_PATH
orbit_local_binary_version
orbit_local_binary_checksum
orbit_local_last_update_check

Out of scope

  • glab orbit local query / status / etc. — those will come in follow-up MRs.
  • Windows support — the binary isn't published for Windows yet.
  • Sharing config-loading code between duo and orbit beyond the existing config.Config interface.
Edited by Jay McCure

Merge request reports

Loading