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"], };