From 260259a07abb69cfd052cd3641ff6d8e57e7a745 Mon Sep 17 00:00:00 2001
From: FUG
Date: Thu, 25 Jun 2026 14:53:33 +0900
Subject: [PATCH] Install all supported agent platforms by default
---
README.md | 55 ++++++++++--------
bin/lazycodex-ai.js | 100 ++++++++++++++++++++++++++-------
package.json | 4 +-
test/lazycodex-ai-bin.test.mjs | 63 ++++++++++++++++++++-
4 files changed, 176 insertions(+), 46 deletions(-)
diff --git a/README.md b/README.md
index 2747f7a..05e054d 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
LazyCodex
The one and only agent harness for complex codebases.
- Project memory, planning, execution, and verified completion inside Codex.
+ Project memory, planning, execution, and verified completion across Codex, Claude Code, and Gemini from one installer.
@@ -28,7 +28,7 @@
> [!NOTE]
> **[OmO] 60K Stars: the terrifying token burner has arrived in LazyCodex.**
>
-> Sisyphus Labs' OmO is the quality-obsessed agent harness whose public lore says it loved Anthropic models hard enough to get third-party clients blocked. Now that same OmO quality bar is available for Codex through LazyCodex.
+> Sisyphus Labs' OmO is the quality-obsessed agent harness whose public lore says it loved Anthropic models hard enough to get third-party clients blocked. Now that same OmO quality bar is available through LazyCodex across Codex, Claude Code, and Gemini in one pass.
>
> If you wanted OmO but did not want the setup ceremony, start here:
>
@@ -46,8 +46,16 @@ One line. No global install, no `npm i -g`. Always use `npx`:
npx lazycodex-ai install
```
-This is shorthand for `npx --yes --package oh-my-openagent omo install --platform=codex`. For a fully autonomous, no-TUI setup:
+By default this runs OmO install for all supported targets: Codex, Claude Code,
+and Gemini. To install only one surface, pass an explicit platform:
+```bash
+npx lazycodex-ai install --platform=codex
+npx lazycodex-ai install --platform=claude-code
+npx lazycodex-ai install --platform=gemini
+```
+
+For a fully autonomous, no-TUI setup:
```bash
npx lazycodex-ai install --no-tui --codex-autonomous
```
@@ -87,7 +95,7 @@ npx lazycodex-ai doctor
```
`doctor` prints the installation health report: plugin cache, hooks, MCP
-servers, agents, and config state. Inside Codex, type `$` in the composer to
+servers, agents, and config state. Inside the target agent, check the command menu or CLI shortcuts to
browse every installed skill — `init-deep`, `ulw-loop`, `ulw-plan`,
`start-work`, and the rest — and hooks announce themselves with
`LazyCodex(): ...` status messages during a session.
@@ -98,13 +106,13 @@ browse every installed skill — `init-deep`, `ulw-loop`, `ulw-plan`,
npx lazycodex-ai uninstall
```
-Removes the installed plugin cache, bin links, agent roles, and the managed
-sections of `~/.codex/config.toml`.
+Removes the installed plugin cache, bin links, agent roles, and managed
+sections of the target agent config.
## ⚡ Commands
-LazyCodex installs these as OmO commands for Codex. Invoke them with the
-`$command` syntax shown by the installer.
+LazyCodex installs these as OmO commands for the target agent. Invoke them with
+the `$command` syntax shown by the installer.
| Command | Type this | What it does |
| --- | --- | --- |
@@ -117,15 +125,15 @@ Full documentation lives at [lazycodex.ai/docs](https://lazycodex.ai/docs).
## Use the built-in workflows
LazyCodex should be judged by the features it actually installs. It is the
-Codex distribution for OmO's agent harness: project memory, planning,
+light distribution for OmO's agent harness: project memory, planning,
execution, verified completion, skills, hooks, model routing, and diagnostics.
### 1. `$init-deep` creates project memory
`$init-deep` generates hierarchical `AGENTS.md` context. It scores complex
directories, writes local guidance near the code that needs it, and gives future
-agents landmarks before they edit. Type `$init-deep` in the Codex composer —
-the `$` prefix is how every installed skill is invoked.
+agents landmarks before they edit. Type `$init-deep` in the target agent —
+the `$` prefix is how every installed skill is invoked when the surface exposes command syntax.
Use it when the repository is too large to explain from memory. Run it again
when the shape of the codebase changes.
@@ -161,20 +169,19 @@ actual work:
| `rules` | Project instructions from AGENTS, rules, and instruction files |
| `comment-checker` | Feedback after edit-like operations |
-### 4. Sub-agent roles ride Codex's native multi-agent tools
+### 4. Sub-agent roles ride the target agent's multi-agent tools
-LazyCodex installs selectable agent roles into `~/.codex/agents/`: `explorer`,
-`librarian`, `plan`, `momus`, `metis`, and `codex-ultrawork-reviewer`. Pick one
-by passing `agent_type` to Codex's `spawn_agent` tool — the child agent runs
-with that role's model and instructions:
+LazyCodex installs selectable agent roles for surfaces that expose sub-agent role
+selection: `explorer`, `librarian`, `plan`, `momus`, `metis`, and
+`lazycodex-gate-reviewer`. Pick one through the target agent's sub-agent tool
+when that field is available:
```jsonc
spawn_agent({"message": "TASK: map the auth flow end to end.", "agent_type": "explorer"})
```
-The installer exposes `agent_type` on `multi_agent_v2` sessions (Codex hides it
-by default). If your Codex build's spawn tool has no `agent_type` parameter,
-describe the role inside `message` instead — the skills are written to fall
+If your target agent's spawn tool has no typed role parameter,
+describe the role inside the task message instead — the skills are written to fall
back to that form automatically.
Start at [https://lazycodex.ai](https://lazycodex.ai).
@@ -183,15 +190,15 @@ Start at [https://lazycodex.ai](https://lazycodex.ai).
## 💤 What is this?
-**LazyCodex** packages [OmO (oh-my-openagent)](https://github.com/code-yeongyu/oh-my-openagent) as the Codex agent harness for complex codebases.
+**LazyCodex** packages [OmO (oh-my-openagent)](https://github.com/code-yeongyu/oh-my-openagent) as a light agent harness for complex codebases across Codex, Claude Code, and Gemini.
-Think [LazyVim](https://github.com/LazyVim/LazyVim) for [lazy.nvim](https://github.com/folke/lazy.nvim), but for Codex.
+Think [LazyVim](https://github.com/LazyVim/LazyVim) for [lazy.nvim](https://github.com/folke/lazy.nvim), but for coding-agent harness setup.
-OmO is the agent harness: discipline agents, parallel orchestration, multi-model routing, skills, hooks, and verified completion. LazyCodex packages that harness for Codex.
+OmO is the agent harness: discipline agents, parallel orchestration, multi-model routing, skills, hooks, and verified completion. LazyCodex packages the Hephaestus slice so the same setup can be installed into Codex, Claude Code, and Gemini without hand-wiring each surface.
-> _"LazyVim made Neovim usable for the rest of us. LazyCodex does the same for Codex."_
+> _"LazyVim made Neovim usable for the rest of us. LazyCodex does the same for agent harness setup."_
-Credit: The LazyCodex name idea is inspired by [LazyVim](https://github.com/LazyVim/LazyVim). The Ultragoal and UltraQA ideas are inspired by [oh-my-codex](https://github.com/Yeachan-Heo/oh-my-codex), reimplemented from concept for this Codex setup.
+Credit: The LazyCodex name idea is inspired by [LazyVim](https://github.com/LazyVim/LazyVim). The Ultragoal and UltraQA ideas are inspired by [oh-my-codex](https://github.com/Yeachan-Heo/oh-my-codex), reimplemented from concept for this setup.
## 🧩 What you get
diff --git a/bin/lazycodex-ai.js b/bin/lazycodex-ai.js
index 186178d..65afcfc 100755
--- a/bin/lazycodex-ai.js
+++ b/bin/lazycodex-ai.js
@@ -5,31 +5,93 @@ import { spawnSync } from "node:child_process"
const args = process.argv.slice(2)
const dryRun = args[0] === "--dry-run"
const forwardedArgs = dryRun ? args.slice(1) : args
-const commandArgs =
+const DEFAULT_PLATFORMS = ["codex", "claude-code", "gemini"]
+const ALL_PLATFORM_ALIASES = new Set(["all", "multi", "all-platforms", "*"])
+const CODEX_ONLY_ARGS = new Set(["--codex-autonomous"])
+
+function parseInstallArgs(values) {
+ const platforms = []
+ const passthrough = []
+ let allPlatforms = false
+
+ for (let i = 0; i < values.length; i += 1) {
+ const arg = values[i]
+ if (arg === "--all-platforms") {
+ allPlatforms = true
+ continue
+ }
+ if (arg === "--platform") {
+ const value = values[i + 1]
+ if (!value) {
+ passthrough.push(arg)
+ continue
+ }
+ i += 1
+ if (ALL_PLATFORM_ALIASES.has(value)) {
+ allPlatforms = true
+ } else {
+ platforms.push(value)
+ }
+ continue
+ }
+ if (arg.startsWith("--platform=")) {
+ const value = arg.slice("--platform=".length)
+ if (ALL_PLATFORM_ALIASES.has(value)) {
+ allPlatforms = true
+ } else {
+ platforms.push(value)
+ }
+ continue
+ }
+ passthrough.push(arg)
+ }
+
+ const targets = allPlatforms || platforms.length === 0 ? DEFAULT_PLATFORMS : [...new Set(platforms)]
+ return { targets, passthrough }
+}
+
+function argsForPlatform(platform, passthrough) {
+ const safeArgs = platform === "codex" ? passthrough : passthrough.filter((arg) => !CODEX_ONLY_ARGS.has(arg))
+ return [
+ "--yes",
+ "--package",
+ "oh-my-openagent",
+ "omo",
+ "install",
+ `--platform=${platform}`,
+ ...safeArgs,
+ ]
+}
+
+function buildInstallCommands(values) {
+ const { targets, passthrough } = parseInstallArgs(values)
+ return targets.map((platform) => argsForPlatform(platform, passthrough))
+}
+
+const installArgs = forwardedArgs.slice(1)
+const commands =
forwardedArgs[0] === "install"
- ? [
- "--yes",
- "--package",
- "oh-my-openagent",
- "omo",
- "install",
- "--platform=codex",
- ...forwardedArgs.slice(1),
- ]
- : ["--yes", "--package", "oh-my-openagent", "omo", ...forwardedArgs]
+ ? buildInstallCommands(installArgs)
+ : [["--yes", "--package", "oh-my-openagent", "omo", ...forwardedArgs]]
if (dryRun) {
- console.log(["npx", ...commandArgs].join(" "))
+ console.log(commands.map((commandArgs) => ["npx", ...commandArgs].join(" ")).join("\n"))
process.exit(0)
}
-const result = spawnSync("npx", commandArgs, {
- stdio: "inherit",
-})
+for (const commandArgs of commands) {
+ const result = spawnSync("npx", commandArgs, {
+ stdio: "inherit",
+ })
+
+ if (result.error) {
+ console.error(result.error.message)
+ process.exit(1)
+ }
-if (result.error) {
- console.error(result.error.message)
- process.exit(1)
+ if ((result.status ?? 1) !== 0) {
+ process.exit(result.status ?? 1)
+ }
}
-process.exit(result.status ?? 1)
+process.exit(0)
diff --git a/package.json b/package.json
index 7e22828..d53c6cb 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "lazycodex-ai",
"version": "0.2.2",
- "description": "Codex install alias for oh-my-openagent. Run `npx lazycodex-ai install` to set up the Codex platform.",
+ "description": "OmO installer for Codex, Claude Code, and Gemini agent harness targets.",
"type": "module",
"bin": {
"lazycodex-ai": "bin/lazycodex-ai.js"
@@ -17,6 +17,8 @@
},
"keywords": [
"codex",
+ "claude-code",
+ "gemini",
"oh-my-openagent",
"ai-agents",
"orchestration"
diff --git a/test/lazycodex-ai-bin.test.mjs b/test/lazycodex-ai-bin.test.mjs
index babc96e..22caf87 100644
--- a/test/lazycodex-ai-bin.test.mjs
+++ b/test/lazycodex-ai-bin.test.mjs
@@ -44,7 +44,7 @@ describe("lazycodex-ai npm package", () => {
assert.match(publishWorkflow, new RegExp(`default: "${releaseVersion}"`))
})
- it("dry-runs install through oh-my-openagent with the Codex platform default", () => {
+ it("dry-runs install through oh-my-openagent for Codex, Claude Code, and Gemini by default", () => {
// given
assert.equal(existsSync(binPath), true, "lazycodex-ai bin must exist")
@@ -55,12 +55,71 @@ describe("lazycodex-ai npm package", () => {
{ cwd: root, encoding: "utf8" },
)
+ // then
+ assert.equal(result.status, 0, result.stderr)
+ assert.deepEqual(result.stdout.trim().split("\n"), [
+ "npx --yes --package oh-my-openagent omo install --platform=codex --no-tui --codex-autonomous",
+ "npx --yes --package oh-my-openagent omo install --platform=claude-code --no-tui",
+ "npx --yes --package oh-my-openagent omo install --platform=gemini --no-tui",
+ ])
+ })
+
+ it("preserves explicit install platform targets", () => {
+ // given
+ assert.equal(existsSync(binPath), true, "lazycodex-ai bin must exist")
+
+ // when
+ const result = spawnSync(
+ process.execPath,
+ [binPath, "--dry-run", "install", "--platform=claude-code", "--no-tui"],
+ { cwd: root, encoding: "utf8" },
+ )
+
// then
assert.equal(result.status, 0, result.stderr)
assert.equal(
result.stdout.trim(),
- "npx --yes --package oh-my-openagent omo install --platform=codex --no-tui --codex-autonomous",
+ "npx --yes --package oh-my-openagent omo install --platform=claude-code --no-tui",
+ )
+ })
+
+ it("preserves explicit install platform targets passed as a separate value", () => {
+ // given
+ assert.equal(existsSync(binPath), true, "lazycodex-ai bin must exist")
+
+ // when
+ const result = spawnSync(
+ process.execPath,
+ [binPath, "--dry-run", "install", "--platform", "gemini", "--no-tui"],
+ { cwd: root, encoding: "utf8" },
+ )
+
+ // then
+ assert.equal(result.status, 0, result.stderr)
+ assert.equal(
+ result.stdout.trim(),
+ "npx --yes --package oh-my-openagent omo install --platform=gemini --no-tui",
+ )
+ })
+
+ it("expands --platform=all into every supported platform target", () => {
+ // given
+ assert.equal(existsSync(binPath), true, "lazycodex-ai bin must exist")
+
+ // when
+ const result = spawnSync(
+ process.execPath,
+ [binPath, "--dry-run", "install", "--platform=all", "--no-tui"],
+ { cwd: root, encoding: "utf8" },
)
+
+ // then
+ assert.equal(result.status, 0, result.stderr)
+ assert.deepEqual(result.stdout.trim().split("\n"), [
+ "npx --yes --package oh-my-openagent omo install --platform=codex --no-tui",
+ "npx --yes --package oh-my-openagent omo install --platform=claude-code --no-tui",
+ "npx --yes --package oh-my-openagent omo install --platform=gemini --no-tui",
+ ])
})
it("dry-runs non-install commands through oh-my-openagent", () => {