From 660aae91a3a5c0000b027bb2fe7349e6514fbb73 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 06:54:28 +0000 Subject: [PATCH] =?UTF-8?q?feat(engines):=20omp=20=E2=80=94=20install=20om?= =?UTF-8?q?p=20from=20omp.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds omp (Stencil Labs' coding agent, oh-my-pi upstream) as an engine: `moshcode install omp` runs `curl -fsSL https://omp.sh/install | sh`. The installer `bun install -g`s when a native-arch bun is present (~/.bun/bin) and otherwise downloads a prebuilt binary to ~/.local/bin; it edits no shell rc, so both are bridged via binDirs. Aliases: oh-my-pi, ohmypi, omp.sh. Agent mode is `--auto-approve` (skips tool approvals; the agent can still ask). No agentsView: `omp agents` manages bundled agent files and exits. Headless ai() is `omp -p `, resume is `--continue`, and upgrade is omp's own `omp update`. Verified with omp 18.3.1: a moshcode install into a throwaway HOME with neither dir on PATH lands the binary in ~/.local/bin and resolves it via binDirs; `omp --auto-approve` under a pty in a fresh directory opens straight to the composer — no trust or bypass dialog, so no `boot` answers. Uncosted: its session logs are not read by `cost` yet. --- README.md | 6 ++++-- src/cli-schema.mjs | 2 +- src/cost.mjs | 2 +- src/engines.mjs | 28 +++++++++++++++++++++++++++- test/engines.test.mjs | 2 ++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e5acca62..5a1bf154 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ moshcode install kimi # curl -fsSL https://code.kimi.com/kimi-code/install moshcode install qwen # npm i -g @qwen-code/qwen-code moshcode install deepseek # npm i -g @serjm/deepseek-code moshcode install mimocode # curl -fsSL https://mimo.xiaomi.com/install | bash (binary: mimo) +moshcode install omp # curl -fsSL https://omp.sh/install | sh moshcode install openagents # curl -fsSL https://openagents.org/install.sh | bash ``` @@ -118,6 +119,7 @@ moshcode agents kimi # kimi --yolo moshcode agents qwen # qwen --approval-mode=yolo (autonomous) moshcode agents deepseek # deepseek-code --turbo (autonomous) moshcode agents mimocode # mimo --dangerously-skip-permissions --trust (autonomous) +moshcode agents omp # omp --auto-approve (autonomous) moshcode agents aider # aider --yes-always (autonomous) moshcode agents openagents # openagents (dashboard) ``` @@ -461,8 +463,8 @@ of the traffic and a tenth of the price; folding them into `in` makes a $3 session look like a $60 one. Attribution is engine + directory + "started before this run did", so a session that shares a directory with another agent can pick up its neighbour's work — `--json` carries the run list when you need to check. -gemini, kimi, qwen, deepseek, mimocode and openagents keep no readable usage -log, so they report no cost rather than zero cost. +gemini, kimi, qwen, deepseek, mimocode, omp and openagents keep no readable +usage log, so they report no cost rather than zero cost. ### Driving it from a script or another agent diff --git a/src/cli-schema.mjs b/src/cli-schema.mjs index b0e3b7bd..7001b73c 100644 --- a/src/cli-schema.mjs +++ b/src/cli-schema.mjs @@ -215,7 +215,7 @@ export const CORE_CLI_COMMANDS = [ + "codex's rollout token counts, opencode's per-message cost, aider's chat history. a figure marked " + "`~` was worked out from published rates and is what the tokens WOULD cost on the api; unmarked " + "figures are the engine's own arithmetic. models with no rate show tokens and no cost — add yours " - + "to ~/.moshcode/pricing.json. gemini, kimi, deepseek, mimocode and openagents log nothing readable, " + + "to ~/.moshcode/pricing.json. gemini, kimi, deepseek, mimocode, omp and openagents log nothing readable, " + "so they report no cost rather than zero. under the table, `burn` is the same windows for every " + "engine — last 1 min, 15 min, 1 hour, 4 hours, 8 hours and the report window — with what the " + "requests inside each cost, that cost per hour, and the runs behind it; --json carries them as `burn`.", diff --git a/src/cost.mjs b/src/cost.mjs index d443c103..e20f8365 100644 --- a/src/cost.mjs +++ b/src/cost.mjs @@ -740,7 +740,7 @@ export const COST_READERS = { }; /** Engines moshcode can launch but cannot cost — named so the report can say so. */ -export const UNCOSTED_ENGINES = ["gemini", "kimi", "deepseek", "mimocode", "openagents"]; +export const UNCOSTED_ENGINES = ["gemini", "kimi", "deepseek", "mimocode", "omp", "openagents"]; /** * Finish a run: price it, and record where the price came from. diff --git a/src/engines.mjs b/src/engines.mjs index 9a483c4f..088518e7 100644 --- a/src/engines.mjs +++ b/src/engines.mjs @@ -314,6 +314,29 @@ export const ENGINES = { ], }, }, + omp: { + desc: "omp — Stencil Labs' coding agent with LSP, DAP and subagents (omp.sh)", + bin: "omp", + // `--auto-approve` skips every tool approval prompt; the agent can still + // ask a question, the same shape as kimi's --yolo. `--approval-mode=yolo` + // reaches the same place through a settings override, so this stays on the + // flag that says what it does. + agentArgs: ["--auto-approve"], + // No agentsView: `omp agents` manages the bundled task-agent definitions + // (`omp agents unpack`) — it prints and exits, not a live view to land on. + install: { cmd: "sh", args: ["-c", "curl -fsSL https://omp.sh/install | sh"] }, + // Its own updater, which handles both install shapes below and the + // stable/canary channel. + upgrade: { cmd: "omp", args: ["update"] }, + // The installer runs `bun install -g` when a native-arch bun is present, + // landing in ~/.bun/bin, and otherwise downloads a prebuilt binary to + // ~/.local/bin (PI_INSTALL_DIR). It edits no shell rc and neither directory + // is guaranteed to be on PATH, so search both. + binDirs: [path.join(homedir(), ".bun", "bin"), path.join(homedir(), ".local", "bin")], + resume: ["--continue"], + // No `state`: the TUI's approval and question wording is not verified + // here, and a guessed pattern is worse than the shared ones. + }, openagents: { desc: "OpenAgents — multi-agent launcher + dashboard (openagents.org)", // The package installs three identical bins — `agn`, `openagents`, and @@ -416,6 +439,8 @@ export const ENGINE_ALIASES = { // Same idea for openagents: `agn` and `agent-connector` are the other two // binary names its package installs, and the domain is how it's advertised. oa: "openagents", agn: "openagents", "agent-connector": "openagents", "openagents.org": "openagents", + // omp is oh-my-pi upstream (can1357/oh-my-pi); the domain is how it's advertised. + "oh-my-pi": "omp", ohmypi: "omp", "omp.sh": "omp", }; /** Resolve a name/alias to `[key, engine]`, or null. */ @@ -533,6 +558,7 @@ const AI_EXEC = { qwen: (p) => ["-p", p], // qwen prompt mode (gemini-derived) deepseek: (p) => ["--headless", "-p", p], // deepseek: -p runs one prompt and exits; --headless drops the TUI so stdout is pipe-clean mimocode: (p) => ["run", p], // mimocode one-shot (opencode-derived: `mimo run `) + omp: (p) => ["-p", p], // omp print mode: process the prompt and exit // openagents is absent on purpose: it answers no prompts itself, it starts // the engines that do. ai() throws a named error rather than picking it. }; @@ -556,7 +582,7 @@ export function aiExecArgs(engine, prompt) { */ export function pickAiEngine(preferred) { const wanted = preferred ? resolveEngine(preferred)?.[0] : null; - const order = preferred ? (wanted ? [wanted] : []) : ["claude", "codex", "opencode", "privacycode", "gemini", "kimi", "qwen", "deepseek", "mimocode", "aider"]; + const order = preferred ? (wanted ? [wanted] : []) : ["claude", "codex", "opencode", "privacycode", "gemini", "kimi", "qwen", "deepseek", "mimocode", "omp", "aider"]; for (const key of order) { if (Object.hasOwn(ENGINES, key) && Object.hasOwn(AI_EXEC, key) && isInstalled(ENGINES[key].bin, ENGINES[key].binDirs)) return key; } diff --git a/test/engines.test.mjs b/test/engines.test.mjs index 231c5ab6..b177e000 100644 --- a/test/engines.test.mjs +++ b/test/engines.test.mjs @@ -35,6 +35,7 @@ const EXPECTED_AGENT_ARGS = { qwen: ["--approval-mode=yolo"], deepseek: ["--turbo"], mimocode: ["--dangerously-skip-permissions", "--trust"], + omp: ["--auto-approve"], openagents: [], // a launcher, not an agent: nothing of its own to auto-approve aider: ["--yes-always"], }; @@ -53,6 +54,7 @@ const EXPECTED_LAUNCH_ARGS = { qwen: ["--approval-mode=yolo"], deepseek: ["--turbo"], mimocode: ["--dangerously-skip-permissions", "--trust"], // no agents view — `mimo agent` prints and exits + omp: ["--auto-approve"], // no agents view — `omp agents` manages bundled agent files and exits openagents: [], // bare launch opens the dashboard, which is its agent list aider: ["--yes-always"], };