oh-my-codex explore vs omx sparkshell command routing: Key Differences
omx explore serves as the primary read-only entry point for repository queries, while omx sparkshell acts as a specialized routing target for shell-native commands detected by the resolveExploreSparkShellRoute function in src/cli/explore.ts.
The oh-my-codex CLI provides two distinct pathways for interacting with your codebase safely. Understanding how omx explore automatically routes certain prompts to the omx sparkshell binary helps you leverage the right tool for semantic LLM-driven exploration versus high-output shell operations.
Core Architectural Differences
omx explore as the Primary Entry Point
omx explore functions as the default interface for all read-only repository interactions. It accepts natural-language prompts or prompt files and primarily runs the explore-harness binary for shell-only operations. According to the source code in src/cli/explore.ts, this command handles semantic queries like "list all authentication modules" by invoking the richer LLM-driven explorer defined in prompts/explore.md.
When you submit a prompt, the system first attempts to classify whether your input requires the full LLM context or qualifies for faster shell-native execution.
omx sparkshell as the Specialized Routing Target
omx sparkshell operates as a native side-car binary designed specifically for qualified shell commands. Unlike the explore command's general-purpose harness, sparkshell executes only read-only Git sub-commands or utilities that produce large but safe output streams. The binary is located via resolveSparkShellBinaryPathWithHydration in src/cli/sparkshell.ts (lines 1-78) and supports an optional --tmux-pane mode for bounded pane summarization.
How Command Routing Works in oh-my-codex
The Routing Detection Logic
The critical decision point occurs in resolveExploreSparkShellRoute within src/cli/explore.ts (lines 99-134). This function inspects your prompt for specific patterns:
- Git commands:
git log,git diff, and other read-only Git sub-commands - File system utilities:
find,ls,rg(ripgrep),grep - Explicit shell prefix: Commands prefixed with
run …
When detected, the function returns an ExploreSparkShellRoute object containing the parsed argv array and a reason field set to either "shell-native" or "long-output" based on the command's expected output volume.
// From src/cli/explore.ts
export function resolveExploreSparkShellRoute(prompt: string): ExploreSparkShellRoute | undefined {
const explicitShellPrefix = EXPLICIT_SHELL_PREFIX_PATTERN.test(prompt.trim());
const normalized = prompt.trim().replace(EXPLICIT_SHELL_PREFIX_PATTERN, '');
const argv = tokenizeExploreShellCommand(normalized);
if (command === 'git' && isReadOnlyGitArgs(argv)) {
return { argv, reason: classifyLongOutputShellCommand(argv) ? 'long-output' : 'shell-native' };
}
if (explicitShellPrefix && shellNativeShape && ['find','ls','rg','grep'].includes(command)) {
return { argv, reason: classifyLongOutputShellCommand(argv) ? 'long-output' : 'shell-native' };
}
return undefined;
}
Execution Flow from explore to sparkshell
When routing triggers, the runExploreViaSparkShell function (lines 137-156 in src/cli/explore.ts) takes over:
- Resolves the sparkshell binary path using
resolveSparkShellBinaryPathWithHydration - Executes the native
omx-sparkshellbinary with the routed arguments - Streams stdout and stderr directly to your terminal
If no route matches, the system falls back to the standard explore-harness via resolvePackagedExploreHarnessCommand.
Practical Usage Examples
Automatic Routing Through omx explore
For standard Git operations, the routing happens transparently:
# Automatically routed to sparkshell due to git log pattern
omx explore --prompt "git log --oneline -10"
The resolveExploreSparkShellRoute function recognizes the read-only Git pattern and returns a route with reason: "long-output", allowing sparkshell to stream the concise log efficiently.
Semantic Queries Bypassing Routing
For natural language questions requiring LLM analysis:
# Forces use of the explore-harness and LLM contract
omx explore --prompt "Which files import the axios library?"
Since this prompt contains no shell-native tokens, resolveExploreSparkShellRoute returns undefined, and the system invokes the full explorer defined in prompts/explore.md.
Direct sparkshell Invocation
Bypass the routing logic entirely when you know you need shell execution:
# Direct execution via omx sparkshell
omx sparkshell git diff --stat
omx sparkshell --tmux-pane %12 --tail-lines 400
Direct calls require the OMX_SPARKSHELL_BIN environment variable for binary resolution and enforce the same strict read-only guarantees as the routed path.
Safety Guarantees and Configuration
Both execution paths maintain strict read-only contracts preventing file modifications or arbitrary pipeline execution. The explore-harness cannot invoke non-allowed binaries, while sparkshell restricts execution to qualified commands with safe output profiles.
Configure the binaries via environment variables:
OMX_EXPLORE_BIN: Controls the explore-harness binary location (seesrc/cli/explore.ts)OMX_SPARKSHELL_BIN: Controls the sparkshell binary location (seesrc/cli/sparkshell.ts)
Summary
omx exploreprovides the default entry point for safe, read-only repository queries with automatic routing logic.resolveExploreSparkShellRouteinsrc/cli/explore.tsdetects shell-native patterns (git, find, ls, rg, grep) and "run" prefixes to trigger sparkshell routing.omx sparkshellexecutes as a specialized binary for high-output or shell-native commands, offering efficient streaming and tmux integration.- Both commands respect the read-only safety contract defined in
AGENTS.md(lines 6-13) and use distinct environment variables for binary resolution.
Frequently Asked Questions
What triggers oh-my-codex to route my explore command to sparkshell?
The resolveExploreSparkShellRoute function checks for read-only Git commands (git log, git diff), file system utilities (find, ls, rg, grep), or an explicit run prefix. When your prompt matches these patterns in src/cli/explore.ts, the system returns an ExploreSparkShellRoute and delegates execution to the sparkshell binary instead of the LLM-driven explorer.
Can I force omx explore to use the LLM instead of routing to sparkshell?
Yes. Avoid shell-native command patterns in your prompt. Instead of omx explore --prompt "git log", use natural language like omx explore --prompt "show me recent commits". When resolveExploreSparkShellRoute finds no matching tokens, it returns undefined and the system invokes the explore-harness with the full LLM contract from prompts/explore.md.
Is omx sparkshell safe to run directly on production codebases?
Yes. According to the source code in src/cli/sparkshell.ts and the safety policies in AGENTS.md, the sparkshell binary inherits the same read-only guarantees as omx explore. It explicitly validates arguments through isReadOnlyGitArgs and similar guards, exiting with an error if you attempt to execute modifying commands like git push or rm.
How do I configure custom binary paths for oh-my-codex commands?
Set the OMX_EXPLORE_BIN environment variable to override the default explore-harness location, or use OMX_SPARKSHELL_BIN to specify a custom path for the omx-sparkshell binary. Both variables are resolved through the hydration functions in src/cli/explore.ts and src/cli/sparkshell.ts respectively.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →