Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/omo-codex/plugin/components/ultrawork/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Codex passes the prompt payload on stdin. When the pattern `\b(?:ultrawork|ulw)\

If a prior `UserPromptSubmit` hook output in transcript JSONL already contains `<ultrawork-mode>`, the hook suppresses itself so the same directive is not injected repeatedly. Plain transcript text containing `<ultrawork-mode>` is ignored unless it comes from hook output.

Bundled agent role TOMLs in `agents/` ship to `CODEX_HOME/agents/` at install time, not via a runtime hook. The installer writes regular file copies on Linux, macOS, and Windows. For the public marketplace, the source is the installed-marketplace snapshot, not the versioned plugin cache, so agent role configs remain valid when Codex replaces `~/.codex/plugins/cache/sisyphuslabs/omo/<version>/` during auto-update or removes temporary marketplace state. Both code paths overwrite stale files and write a `.installed-agents.json` manifest next to the source root for clean uninstall tracking.
Bundled agent role TOMLs in `agents/` ship to `CODEX_HOME/agents/` at install time, not via a runtime hook. The installer writes regular file copies on Linux, macOS, and Windows. For the public marketplace, the source is the installed-marketplace snapshot, not the versioned plugin cache, so agent role configs remain valid when Codex replaces `~/.codex/plugins/cache/sisyphuslabs/omo/<version>/` during auto-update or removes temporary marketplace state. Both code paths write a `.installed-agents.json` manifest next to the source root for clean uninstall tracking and a `CODEX_HOME/.omo/native-agents.json` hash manifest so unmodified managed TOMLs can refresh while user-modified TOMLs are preserved.

## Smoke test

Expand Down
18 changes: 15 additions & 3 deletions packages/omo-codex/plugin/test/bootstrap-setup.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const MARKETPLACE_SOURCE_LINE = 'source = "https://github.com/code-yeongyu/lazyc
const PERMISSIONS_KEY_PATTERN = /approval_policy|sandbox_mode|network_access/;
const PLUGIN_VERSION = "9.9.9";

const BUNDLED_EXPLORER_TOML = 'description = "Explorer agent"\nmodel_reasoning_effort = "medium"\n';
const BUNDLED_METIS_TOML = 'description = "Metis agent"\nmodel_reasoning_effort = "high"\n';
const BUNDLED_EXPLORER_TOML = 'name = "explorer"\ndescription = "Explorer agent"\nmodel_reasoning_effort = "medium"\n';
const BUNDLED_METIS_TOML = 'name = "metis"\ndescription = "Metis agent"\nmodel_reasoning_effort = "high"\n';

async function withSetupFixture(run) {
const root = await mkdtemp(join(tmpdir(), "omo-bootstrap-setup-"));
Expand Down Expand Up @@ -175,7 +175,7 @@ test("#given user-tuned reasoning and service tier on an installed agent #when a
await mkdir(join(fixture.codexHome, "agents"), { recursive: true });
await writeFile(
join(fixture.codexHome, "agents", "explorer.toml"),
'description = "Explorer agent"\nmodel_reasoning_effort = "low"\nservice_tier = "flex"\n',
'name = "explorer"\ndescription = "Explorer agent"\nmodel_reasoning_effort = "low"\nservice_tier = "flex"\n',
);

await runWorkerSetup(setupOptions(fixture));
Expand All @@ -186,6 +186,18 @@ test("#given user-tuned reasoning and service tier on an installed agent #when a
});
});

test("#given a user-tuned model on an installed agent #when bootstrap re-links agents #then the custom model is preserved", async () => {
await withSetupFixture(async (fixture) => {
await mkdir(join(fixture.codexHome, "agents"), { recursive: true });
const customized = 'name = "explorer"\ndescription = "Explorer agent"\nmodel = "custom-provider/explorer"\nmodel_reasoning_effort = "medium"\n';
await writeFile(join(fixture.codexHome, "agents", "explorer.toml"), customized);

await runWorkerSetup(setupOptions(fixture));

assert.equal(await readFile(join(fixture.codexHome, "agents", "explorer.toml"), "utf8"), customized);
});
});

test("#given an unwritable config.toml #when the worker setup runs #then it degrades naming config.toml and leaves the file untouched", async () => {
await withSetupFixture(async (fixture) => {
const configPath = join(fixture.codexHome, "config.toml");
Expand Down
87 changes: 87 additions & 0 deletions packages/omo-codex/scripts/install-agent-links.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,52 @@ test(
},
);

test(
"#given unmodified installed ultrawork plan #when bundled default changes #then reinstall refreshes the managed TOML",
async () => {
const repoRoot = await makeTempDir();
const codexHome = await makeTempDir();
const codexPackageRoot = join(repoRoot, "packages", "omo-codex");
const pluginRoot = join(codexPackageRoot, "plugin");
const agentsRoot = join(pluginRoot, "components", "ultrawork", "agents");

await writeJson(join(codexPackageRoot, "marketplace.json"), {
name: "sisyphuslabs",
plugins: [{ name: "omo", source: "./plugins/omo" }],
});
await writePluginAt(pluginRoot, "omo", "0.1.0");
await mkdir(agentsRoot, { recursive: true });
await writeFile(
join(agentsRoot, "plan.toml"),
'name = "plan"\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "xhigh"\n',
);

await installMarketplaceLocally({
repoRoot,
codexHome,
platform: "linux",
runCommand: async () => {},
log: () => {},
});
await writeFile(
join(agentsRoot, "plan.toml"),
'name = "plan"\nmodel = "gpt-5.6"\nmodel_reasoning_effort = "high"\n',
);
await installMarketplaceLocally({
repoRoot,
codexHome,
platform: "linux",
runCommand: async () => {},
log: () => {},
});

assert.equal(
await readFile(join(codexHome, "agents", "plan.toml"), "utf8"),
'name = "plan"\nmodel = "gpt-5.6"\nmodel_reasoning_effort = "high"\n',
);
},
);

test(
"#given user edited installed ultrawork plan #when reinstalling after snapshot refresh #then high survives",
async () => {
Expand Down Expand Up @@ -252,6 +298,47 @@ test(
},
);

test(
"#given user edited installed ultrawork plan model #when reinstalling after snapshot refresh #then custom model survives",
async () => {
const repoRoot = await makeTempDir();
const codexHome = await makeTempDir();
const codexPackageRoot = join(repoRoot, "packages", "omo-codex");
const pluginRoot = join(codexPackageRoot, "plugin");
const agentsRoot = join(pluginRoot, "components", "ultrawork", "agents");

await writeJson(join(codexPackageRoot, "marketplace.json"), {
name: "sisyphuslabs",
plugins: [{ name: "omo", source: "./plugins/omo" }],
});
await writePluginAt(pluginRoot, "omo", "0.1.0");
await mkdir(agentsRoot, { recursive: true });
await writeFile(
join(agentsRoot, "plan.toml"),
'name = "plan"\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "xhigh"\n',
);

await installMarketplaceLocally({
repoRoot,
codexHome,
platform: "linux",
runCommand: async () => {},
log: () => {},
});
const customized = 'name = "plan"\nmodel = "custom-provider/plan-model"\nmodel_reasoning_effort = "xhigh"\n';
await writeFile(join(codexHome, "agents", "plan.toml"), customized);
await installMarketplaceLocally({
repoRoot,
codexHome,
platform: "linux",
runCommand: async () => {},
log: () => {},
});

assert.equal(await readFile(join(codexHome, "agents", "plan.toml"), "utf8"), customized);
},
);

test(
"#given user removed installed ultrawork service tier #when reinstalling after snapshot refresh #then removal survives",
async () => {
Expand Down
Loading