
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
@galaxy-stack/blackhole-cli
Advanced tools
Galaxy Code CLI and terminal UI for the Galaxy agent runtime
CLI and terminal UI for the shared Galaxy agent runtime. Published identity remains @galaxy-stack/blackhole-cli, executable blackhole.
The agent loop, context, tool execution and completion evidence run in @galaxy-stack/ai-coder-core. React 19 + Ink 7.1.1 render the fullscreen terminal. @assistant-ui/react-ink supplies conversation/composer state; a fixed viewport and grapheme-aware input render that state. The CLI owns configuration, session lifecycle and permissions.
Node.js >=22.13 is required for the optional SQLite adapter. Node may print an experimental SQLite warning. Use a current Node 22 or 24 release.
cd ../galaxy-ai-coder-core
npm ci
npm run build
cd ../galaxy-code
npm ci
npm run check
npm run dev -- chat --workspace /path/to/project
The source checkout intentionally uses file:../galaxy-ai-coder-core. Before a standalone npm release, publish a compatible core version and pin that version in the CLI manifest/lockfile. Do not publish a CLI whose dependency refers to a local filesystem path.
Releases run through publish.yml (GitHub Actions with npm OIDC trusted publishing). It checks out the core repo, builds it, verifies the core version is on the registry, rewrites the file: dependency to that registry version, and publishes with the alpha tag for prereleases. npm publish is the only npm operation OIDC authorises: dist-tag moves are not, so promote a version by hand once a stable release exists:
npm dist-tag add @galaxy-stack/blackhole-cli@<version> latest
The package's first publish set latest to 2.0.0-alpha.9, so latest and alpha diverge until a stable version ships. Publishing from a private repository is allowed but never produces a provenance attestation; npm only generates provenance for public repositories.
npm run dev -- run "Review the parser" --workspace /path/to/project --json
npm run dev -- chat --profile assistant --model glm-5.3-flash:cloud
npm run dev -- chat --session my-project
npm run dev -- skills
npm run dev -- skills show workspace/my-skill
npm run dev -- memory remember architecture "Core owns the agent loop"
npm run dev -- memory search "agent loop"
npm run dev -- memory list
npm run dev -- memory confirm architecture
npm run dev -- memory history architecture
npm run dev -- memory forget architecture
npm run dev -- sessions
npm run dev -- mcp
npm run dev -- web
npm run dev -- web doctor
blackhole web boots the Galaxy Blackhole web GUI with the overlay in web/:
patches under web/patches add the Galaxy route/UI, and the client
package in web/brand supplies the Galaxy Blackhole brand, Vietnamese locale,
key dialog, and reasoning-effort control. The Galaxy key comes from
GBH_GALAXY_API_KEY or the DSH credential store ~/.galaxy/gbh/.credentials.yaml
(written by the in-app dialog). blackhole web --help lists its flags.
Reasoning effort belongs to the system and the model, not to the CLI: Ollama
takes its think field as a boolean or the levels low/medium/high/max,
while other systems expose a different set. blackhole chat therefore resolves
the list per model and shows it as Galaxy Blackhole · Auto · Mức suy luận: …:
Mặc định sends no think field at all, so the model keeps its own default.kimi-k2.7-code) drops Tắt; a model whose capability
is still unverified keeps the levels and reports a warning.--thinking accepts auto|default|off|on|minimal|low|medium|high|xhigh|max
and is validated against the resolved list; an unsupported choice fails with
the levels that model does offer.Declare your own levels per model in ~/.galaxy/config.json when the built-in
list does not fit (same shape as the web overlay):
{
"agent": [{
"type": "manual",
"model": "my-model:cloud",
"thinking": "low",
"reasoningEfforts": { "off": null, "low": "low", "max": "max" }
}]
}
Inside the TUI: Ctrl+T cycles the effort, Ctrl+M picks a model, Ctrl+H
shows or hides the thinking transcript, Ctrl+O toggles tool details.
run --json writes a single final JSON result to stdout. Successful completion exits 0, failure/paused exits 1, cancellation exits 130. Chat needs a TTY; scripts should use run.
The TUI uses the terminal's alternate screen, with a pinned header and bottom input, and a scrollable center. Thinking, messages and tool calls share one ordered transcript. Tool badges distinguish running, success, error and cancellation; commands and paths are shown in their labels. Thinking is displayed only when the provider emits it. Ollama NDJSON is decoded and forwarded as each line arrives; text/thinking does not wait for the response to close. Scrolling up pauses auto-follow; Ctrl+G or scrolling back to the bottom resumes it. The status line shows the visible range while browsing history. Mouse reports are consumed by the viewport and never entered into the draft. Mouse reporting is disabled again on exit.
| Key | Action |
|---|---|
| Enter | Send the request |
| Esc | Cancel the active request |
| Ctrl+C | Exit and restore the terminal |
| Mouse wheel / trackpad over messages | Scroll the transcript using terminal mouse reporting |
| ↑ / ↓, PageUp / PageDown | Scroll by a line / page (Fn+↑ / Fn+↓ on compact Mac keyboards) |
| Ctrl+G | Return to the latest output and resume following it |
| Ctrl+T | Show/hide provider thinking |
| Ctrl+O | Expand/collapse tool details; pending calls include their arguments |
| ← / →, Home / End, Ctrl+A / Ctrl+E | Edit the input without moving the transcript |
| Delete / Backspace, Fn+Delete | Delete the previous / next grapheme (including Vietnamese accents and emoji) |
| Ctrl+U / Ctrl+W | Delete input before the cursor / previous word |
Approval stays above the input and accepts y/n. It expires after at most five minutes (or earlier if the run ends); expiration dismisses the prompt and denies the request. Long input scrolls horizontally so the caret stays visible. The compact layout is tested down to 40×8; 80×24 or larger is more comfortable. In noninteractive mode, tools requiring approval are denied unless their canonical ID is explicitly passed with --allow-tool (repeatable). Read-only tools and the core's balanced workspace policy remain available.
Scratch directories do not need git init. The host detects Git availability; outside a repository, review_changes compares text files against the start of the task and provides completion evidence. Validation is still required after changes. The scratch reviewer is deliberately bounded: an 8 MiB baseline text cache, 128 KiB per-file reads, and a 24 KiB change report. Oversized, binary/special-entry or unstable changes return an error instead of claiming review success; use a Git repository for those projects.
--profile coding retains workspace inspection/completion guarantees. assistant and research allow tasks that do not require code edits; research is currently a prompt profile, not a preconfigured web search service. Use configured MCP research tools when needed.
The working provider adapter is Ollama, including remote/cloud models. Existing ~/.galaxy/config.json manual-provider configuration and OLLAMA_API_KEY continue to work. --model, --base-url and --config override selection. No credentials are placed in the TUI header or source examples.
--thinking auto|on|off|low|medium|high is handled by the Ollama adapter. Turning thinking on/off controls the provider; Ctrl+T only changes what the TUI displays. Named effort levels are provider/model-specific; unsupported values are surfaced as provider errors rather than translated to a universal thinking scale. Full provider capability pickers and direct Gemini/Anthropic/OpenAI-compatible adapters remain planned.
Explicit host configuration is read from ~/.galaxy/agent.json or --agent-config:
{
"mcpServers": [
{ "name": "project", "transport": "stdio", "command": "my-mcp-server", "args": [], "timeoutMs": 30000 },
{ "name": "remote", "transport": "http", "url": "http://127.0.0.1:8080/mcp" }
]
}
Stdio commands execute only when a configured server is connected. Tool names are namespaced; canonical permissions are mcp.<server>.<tool>. All MCP calls require explicit host permission even if a server advertises readOnlyHint. Tool results cannot attest validation or filesystem effects. SDK resources/prompts APIs are available to adapters.
Remote HTTP servers can use browser OAuth: set "auth": "oauth" on the connection, then run blackhole mcp login <server> (opens the system browser, captures the localhost callback, stores tokens in <state-dir>/mcp-auth.json with 0600 permissions and refreshes them automatically). blackhole mcp logout <server> forgets the stored credentials. Browsing resources/prompts from the TUI is not implemented yet; the adapter APIs are.
The CLI also ships first-party servers and skills: orbit and nebula MCP servers are used by default (skip with --no-galaxy-mcp), and orbit-framework plus galaxy-ui ship as bundled/ skills. Memory data from the Galaxy desktop (Quasar Memory Tree) can be migrated with blackhole memory import-quasar <path-to-memory.db>: it backs up the source database into <state-dir>/import-backups/, imports active notes as confirmed entries with preserved provenance, and is safe to re-run.
Skills are discovered in ~/.agents/skills/<name>/SKILL.md and <workspace>/.agents/skills/<name>/SKILL.md. IDs include user/ or workspace/; catalog discovery is bounded to 256 entries. Content/resources load on demand with path/hash/size checks. Loading a skill grants no new execution permissions.
Host state defaults to ~/.galaxy/agent/ and must be outside the selected workspace; override with --state-dir. Memory and conversation rows use a hash of the workspace's canonical path as scope. Another worktree is a separate scope. This version does not automatically merge memory across clones.
Memory uses SQLite WAL + FTS5 with revision checks, provenance and supersession. Explicit CLI notes are confirmed. Model-generated notes are candidates, require permission to write, and are excluded from automatic recall until memory confirm. Confirmed notes are still historical data, not policy or proof that current tests passed. forget removes all revisions and search entries for the key; external backups are outside that operation.
Every command writes JSON lines to <state-dir>/logs/cli-<date>.ndjson (0600, rotated at 5 MB, three segments kept): command lifecycle, run state transitions, tool failures with stacks, MCP connect errors, model retries, OAuth session events and crashes (uncaughtException/unhandledRejection). Secrets in messages are redacted before hitting disk. blackhole logs [n] prints the newest entries so a failure can be traced after the terminal is gone.
Session history resumes with --session; simultaneous writers to the same session are rejected. This restores user/final-answer text; the detailed thinking/tool timeline currently lasts for the open TUI session. It does not resume a paused runtime checkpoint. Runtime checkpoints remain in the host store; crash-resume for production CLI is a future extension. Lab checkpoint/crash-resume testing remains available in core/testing.
npm run check
cd ../galaxy-ai-coder-core/testing
npm ci
npm run test:local
npm run dev -- health --live --scenario live/scenarios/01-write-and-validate.json --json
doctor, eval, campaign, health, run --fixture and their scenarios now belong to galaxy-ai-coder-core/testing. See MIGRATION.md and the core adapter guide. Build cleans generated output before compilation so old lab code cannot remain in the CLI npm artifact.
The composer positions the native terminal caret so the terminal's IME preedit appears inside the input. Delete on macOS removes the preceding character; Fn+Delete removes the following character. Repeated deletes in one stdin packet and combining marks are handled without losing draft changes.
While a run is active, a spinner and animated label report Connecting, Thinking, Responding, Running tools, Validating or Review. Successful completion removes this activity label; failure/cancellation feedback remains visible. The context token count sits at the right edge of the keyboard-help footer. Narrow terminals truncate the help before the count.
A single blank terminal row below the footer is reserved for Ink's render newline. This avoids the native-cursor drift in Ink 7.1.1's full-height, no-newline rendering path. At eight terminal rows the composer drops its border to retain the input and approval controls. Keep the native-cursor PTY check when changing Ink versions.
For a terminal protocol regression on macOS/Linux, run python3 scripts/verify-tui-input.py with pyte installed in that Python environment. It starts an isolated CLI without sending provider requests and checks cursor coordinates, Unicode editing, resize and terminal cleanup. It does not automate the operating system's IME UI.
FAQs
Galaxy Code CLI and terminal UI for the Galaxy agent runtime
We found that @galaxy-stack/blackhole-cli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.