Files
galaxy/specs/galaxy-control-cli/README.md
T
rkw6086 dbfa8bcd48 Complete agent monitoring and Galaxy Control integration
- expose command-monitor conversations and preserve visible agent transcripts
- add bounded polling and a dedicated shell interrupt tool
- improve direct-provider images, skills, tool history, and usage handling
- package and brand Galaxy Control across releases, installers, persistence, and docs
2026-07-29 15:04:58 -05:00

10 KiB

Galaxy Control operator README

galaxyctrl is the CLI entrypoint for controlling an already-running local Galaxy app instance. It is intended for scripts, demos, agent workflows, and developer automation that need to perform allowlisted Galaxy UI actions through the installed channel-specific Galaxy binary without launching the GUI. The implemented command surface contains exactly 77 typed, allowlisted actions. All 77 actions execute after exact-action credential validation. Close actions flow through normal Galaxy close behavior, so existing app warnings remain authoritative. The Block, Auth, Drive, and History families are absent, and input.insert plus input.replace stage text without submitting it.

Packaging model

galaxyctrl is packaged as a thin channel wrapper rather than a standalone Rust binary. The wrapper resolves the installed channel-specific Galaxy executable and invokes it with the hidden --galaxyctrl control-mode flag:

  • crates/local_control owns discovery records, local authentication material, client transport, protocol envelopes, action names, and error types.
  • crates/galaxy_cli owns command parsing conventions for local-control subcommands.
  • the channel-specific app binary owns the hidden --galaxyctrl dispatch path and exits before normal GUI startup.
  • the app-side bridge owns the per-process loopback listener and dispatches supported actions onto the live Galaxy UI context. The control-mode path should initialize only the work needed for CLI parsing, instance discovery, local authentication loading, request serialization, HTTP transport, and output formatting. It should not initialize GUI state, terminal models, rendering, workspaces, or main-app startup paths. Release artifacts and helper names may be channelized, but operator docs and examples use galaxyctrl unless an integration branch explicitly documents a channel-specific alias. This branch wires the core hidden dispatch contract through the existing Galaxy binary. Platform packaging creates wrapper scripts that call the channel binary with --galaxyctrl instead of producing or selecting a separate galaxyctrl binary.

Install and invocation guidance

macOS

For local development checks, build the local Galaxy binary and invoke it with the hidden control-mode flag:

cargo run -p galaxy --bin galaxy-oss -- --galaxyctrl instance list

For distributable checks, use the installed galaxyctrl wrapper. The wrapper execs the app bundle's channel-specific executable with --galaxyctrl. Release builds publish a channel-specific macOS galaxyctrl archive containing the wrapper, forwarded Galaxy binary, and required resources.

Linux

For local development checks, build the local Galaxy binary and invoke it with the hidden control-mode flag:

cargo run -p galaxy --bin galaxy-oss -- --galaxyctrl instance list

For distributable checks, use the packaged galaxyctrl wrapper. The wrapper execs the packaged channel-specific Galaxy executable with --galaxyctrl. The standalone script/linux/bundle --artifact galaxyctrl validation artifact includes that wrapper and compiles the forwarded channel binary with galaxy_control_cli. Release builds publish matching x86_64 and aarch64 Linux archives. Normal Linux app packages install channel-specific galaxy-ai and galaxyctrl launchers alongside the terminal launcher. Run galaxyctrl --version after installation to confirm the shell is resolving the expected build.

Windows

Until the wrapper installer lands, build the local Galaxy binary and invoke it with the hidden control-mode flag for development checks:

cargo run -p galaxy --bin galaxy-oss -- --galaxyctrl instance list

Windows release archives and installer integration remain unavailable until the authenticated broker transport is implemented.

End-to-end local test flow

Use matching app and CLI bits from the same branch or release artifact so the protocol version and action catalog agree.

  1. Start Galaxy and leave at least one window open.
  2. Open Settings > Galaxy Control, or run Enable Galaxy Control from the Command Palette. Local automation access is enabled by default on internal dogfood builds and disabled by default on public channels (Stable, Preview, OSS). Enabling it allows same-user scripts and agents to perform approved actions in Galaxy.
  3. Confirm that the local-control server registered the running same-channel process:
    galaxyctrl instance list
    
  4. Confirm app health and inspect protocol and build identity metadata:
    galaxyctrl app ping
    galaxyctrl app version
    galaxyctrl surface list
    
  5. If exactly one compatible same-channel instance is listed, create a new terminal tab:
    galaxyctrl tab create
    
  6. If multiple compatible same-channel instances are listed, copy the desired instance_id and target it explicitly:
    galaxyctrl app ping --instance <instance_id>
    galaxyctrl app version --instance <instance_id>
    galaxyctrl tab create --instance <instance_id>
    
  7. Verify the running app receives focus for the selected instance and a new terminal tab appears according to Galaxy's normal new-tab placement behavior. The success response includes the created tab's opaque ID.
  8. Inspect state before and after the mutation:
    galaxyctrl tab list --instance <instance_id>
    

Expected failures:

  • galaxyctrl instance list with no running compatible app: exits zero with an empty list;
  • a command that needs a selected app when no compatible app is running: exits non-zero with a no-instance error;
  • multiple ambiguous instances: exits non-zero and asks for --instance;
  • an explicit instance or PID from another channel: exits non-zero with a no-instance error;
  • unsupported app build or stale discovery record: exits non-zero with a protocol, stale-target, or transport error;

Security model

The local-control protocol is designed for same-user scripting, not cross-user or network access. The trust boundary is the local user account.

  • Loopback-only listener. Each Galaxy process binds its control server to 127.0.0.1 on an ephemeral port. The listener is not reachable from the network.
  • Brokered scoped credentials. Discovery records contain instance metadata, loopback control-endpoint information, and an instance-bound Unix-domain-socket broker reference when Galaxy Control is enabled. The broker authenticates the connecting OS user with kernel peer credentials before decoding the credential request or issuing an action-scoped credential. Records do not contain bearer tokens or reusable full-access credentials.
  • Short-lived grants. galaxyctrl requests an action-scoped credential over the owner-authenticated broker socket for the selected instance, then presents that credential to /v1/control. Grants are instance-bound, expired entries are pruned, and the in-memory grant set is capped. Missing, invalid, expired, revoked, or wrong-instance credentials are rejected before request decoding. After decoding identifies the requested action, insufficient-scope credentials are rejected before selector resolution or handler dispatch.
  • Protected local state. The authoritative Galaxy Control setting uses platform secure storage, never imports a value from ordinary or private preferences, and defaults to enabled only on internal dogfood channels (disabled by default on public channels). On POSIX platforms, discovery records and broker sockets use owner-only permissions. On Windows, local-control publication remains disabled until equivalent ACL and broker protections are implemented.
  • Channel-scoped discovery. Each channel-specific CLI considers only records from its own Galaxy channel. Listing, implicit selection, and explicit instance or PID selection cannot target another channel.
  • Stale-record pruning. On each instance list or implicit discovery call, same-channel records whose PID is no longer alive are deleted automatically. Candidates are also health-probed and accepted only when the live app reports the expected instance identity.
  • No CORS. The control endpoints do not set permissive CORS headers, so browser-origin JavaScript cannot read responses even if it guesses the port. The credential requirement provides a second layer since browsers cannot read the brokered credential material.
sequenceDiagram
    participant CLI as galaxyctrl
    participant FS as ~/.galaxy/local-control/
    participant Broker as Credential broker
    participant HTTP as Galaxy loopback server<br/>(127.0.0.1:ephemeral)
    participant Bridge as App bridge

    CLI->>FS: Read discovery records (user-only permissions / ACL)
    FS-->>CLI: instance_id, loopback endpoint, broker socket reference
    CLI->>CLI: Prune stale PIDs, select instance
    CLI->>Broker: Connect to Unix socket<br/>exact action + selected instance
    Broker->>Broker: Authenticate peer OS user before decode;<br/>check Galaxy Control enabled + catalog action
    alt Disabled, invalid, or insufficient scope
        Broker-->>CLI: Structured denial
    else Grant allowed
        Broker-->>CLI: Short-lived scoped credential
        CLI->>HTTP: POST /v1/control<br/>Authorization: Bearer <scoped credential>
        HTTP->>HTTP: Verify credential expiry + instance binding before decode
        HTTP->>HTTP: Decode typed request; verify action scope
        HTTP->>Bridge: Dispatch action to app context
        Bridge-->>HTTP: Structured result or error
        HTTP-->>CLI: JSON response envelope
    end

Known limitations and future hardening:

  • Windows local-control publication is disabled until discovery-record ACL creation and validation are implemented.
  • Unexpired exact-action credentials may be reused for their granted action. Close actions flow through normal Galaxy close behavior and may trigger existing app warnings.
  • Same-user malicious software can still invoke trusted wrappers or automate the desktop, so brokered credentials are least-privilege guardrails rather than a complete hostile same-user sandbox.
  • Future catalog expansion should consider per-request nonces, stricter platform secure-storage constraints, and stronger approval or policy gates.

Documentation review notes

  • Keep examples scoped to the authoritative 77-action catalog and explicitly call out that close actions use normal Galaxy close behavior.
  • Do not document excluded families or actions as usable just because internal app implementations exist.
  • Windows packaging may initially follow the existing helper-wrapper pattern. Update this README when that decision is final.