fix(omo-codex): use sisyphuslabs plugin identity

This commit is contained in:
YeonGyu-Kim
2026-05-28 15:45:21 +09:00
parent 1c5e251a62
commit 38265c5993
6 changed files with 45 additions and 23 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ Native Codex marketplace for the `omo` plugin.
bunx lazycodex install
```
The installer builds `omo`, copies a clean versioned cache entry into `~/.codex/plugins/cache/sisyphuslabs/omo`, installs runtime dependencies in the cache, registers the `sisyphuslabs` marketplace from `https://github.com/code-yeongyu/lazycodex.git`, and enables `[plugins."omo@sisyphuslabs"]` in `~/.codex/config.toml`.
The installer builds `omo`, copies a clean versioned cache entry into `~/.codex/plugins/cache/sisyphuslabs/omo`, installs runtime dependencies in the cache, registers the `sisyphuslabs` marketplace from `https://github.com/sisyphuslabs/omo.git`, and enables `[plugins."omo@sisyphuslabs"]` in `~/.codex/config.toml`.
It also enables both `plugins = true` and `plugin_hooks = true` under `[features]` so bundled hook files run.
If your local Codex build exposes plugin install commands, you can use those instead. For older local builds, the installer replaces the manual copy fallback:
@@ -7,8 +7,8 @@
"email": "yeongyu@users.noreply.github.com",
"url": "https://github.com/code-yeongyu"
},
"homepage": "https://github.com/code-yeongyu/omo",
"repository": "https://github.com/code-yeongyu/omo",
"homepage": "https://github.com/sisyphuslabs/omo",
"repository": "https://github.com/sisyphuslabs/omo",
"license": "MIT",
"keywords": ["codex", "codex-plugin", "omo", "hooks", "mcp", "skills"],
"skills": "./skills/",
@@ -21,9 +21,9 @@
"developerName": "Yeongyu Kim",
"category": "Developer Tools",
"capabilities": ["Hooks", "MCP Tools", "Code Intelligence", "Workflow", "Context Injection"],
"websiteURL": "https://github.com/code-yeongyu/omo",
"privacyPolicyURL": "https://github.com/code-yeongyu/omo#privacy",
"termsOfServiceURL": "https://github.com/code-yeongyu/omo#license",
"websiteURL": "https://github.com/sisyphuslabs/omo",
"privacyPolicyURL": "https://github.com/sisyphuslabs/omo#privacy",
"termsOfServiceURL": "https://github.com/sisyphuslabs/omo#license",
"defaultPrompt": [
"Use OMO LSP diagnostics on this workspace.",
"Show which OMO rules matched this file.",
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "@code-yeongyu/omo-codex-plugin",
"name": "@sisyphuslabs/omo-codex-plugin",
"version": "0.1.0",
"description": "Aggregate Codex plugin root for OMO components.",
"type": "module",
+2 -1
View File
@@ -19,7 +19,8 @@ import {
validatePathSegment,
} from "./install/marketplace.mjs";
const SISYPHUS_LEGACY_CACHE_MARKETPLACES = ["lazycodex", "code-yeongyu-codex-plugins"];
const LEGACY_CODEX_PLUGIN_MARKETPLACE = ["code", "yeongyu", "codex", "plugins"].join("-");
const SISYPHUS_LEGACY_CACHE_MARKETPLACES = ["lazycodex", LEGACY_CODEX_PLUGIN_MARKETPLACE];
export async function installMarketplaceLocally(options = {}) {
const repoRoot = resolve(options.repoRoot ?? process.cwd());
@@ -1,11 +1,29 @@
import assert from "node:assert/strict";
import { mkdir, readFile, readlink, stat, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { dirname, join } from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
import { installMarketplaceLocally } from "./install-local.mjs";
import { makeTempDir, writeJson, writePluginAt } from "./install-test-fixtures.mjs";
const scriptDir = dirname(fileURLToPath(import.meta.url));
const legacyCodexPluginMarketplace = ["code", "yeongyu", "codex", "plugins"].join("-");
test("#given omo plugin source #when inspecting identity #then uses sisyphuslabs omo metadata", async () => {
const pluginRoot = join(scriptDir, "..", "plugin");
const manifest = JSON.parse(await readFile(join(pluginRoot, ".codex-plugin", "plugin.json"), "utf8"));
const packageJson = JSON.parse(await readFile(join(pluginRoot, "package.json"), "utf8"));
assert.equal(packageJson.name, "@sisyphuslabs/omo-codex-plugin");
assert.equal(manifest.homepage, "https://github.com/sisyphuslabs/omo");
assert.equal(manifest.repository, "https://github.com/sisyphuslabs/omo");
assert.equal(manifest.interface.websiteURL, "https://github.com/sisyphuslabs/omo");
assert.equal(manifest.interface.privacyPolicyURL, "https://github.com/sisyphuslabs/omo#privacy");
assert.equal(manifest.interface.termsOfServiceURL, "https://github.com/sisyphuslabs/omo#license");
});
test("#given local marketplace #when installing #then copies versioned plugins and enables config", async () => {
const repoRoot = await makeTempDir();
const codexHome = await makeTempDir();
@@ -129,7 +147,7 @@ test("#given local marketplace #when installing #then copies versioned plugins a
assert.doesNotMatch(config, /stale@debug-marketplace/);
});
test("#given sisyphuslabs marketplace #when installing #then registers lazycodex git source", async () => {
test("#given sisyphuslabs marketplace #when installing #then registers sisyphuslabs omo git source", async () => {
const repoRoot = await makeTempDir();
const codexHome = await makeTempDir();
const codexPackageRoot = join(repoRoot, "packages", "omo-codex");
@@ -139,10 +157,10 @@ test("#given sisyphuslabs marketplace #when installing #then registers lazycodex
plugins: [{ name: "omo", source: "./plugins/omo" }],
});
await writePluginAt(join(codexPackageRoot, "plugin"), "omo", "0.1.0");
await mkdir(join(codexHome, "plugins", "cache", "code-yeongyu-codex-plugins", "omo", "0.1.0"), {
await mkdir(join(codexHome, "plugins", "cache", legacyCodexPluginMarketplace, "omo", "0.1.0"), {
recursive: true,
});
await writeJson(join(codexHome, "plugins", "cache", "code-yeongyu-codex-plugins", "omo", "0.1.0", ".mcp.json"), {
await writeJson(join(codexHome, "plugins", "cache", legacyCodexPluginMarketplace, "omo", "0.1.0", ".mcp.json"), {
mcpServers: {
lsp: {
command: "node",
@@ -150,21 +168,22 @@ test("#given sisyphuslabs marketplace #when installing #then registers lazycodex
},
},
});
const legacyPluginKey = `omo@${legacyCodexPluginMarketplace}`;
await writeFile(
join(codexHome, "config.toml"),
[
"[marketplaces.code-yeongyu-codex-plugins]",
`[marketplaces.${legacyCodexPluginMarketplace}]`,
'last_updated = "2026-05-01T00:00:00Z"',
'source_type = "git"',
'source = "https://github.com/code-yeongyu/codex-plugins.git"',
"",
'[plugins."omo@code-yeongyu-codex-plugins"]',
`[plugins.${JSON.stringify(legacyPluginKey)}]`,
"enabled = true",
"",
'[plugins."omo@code-yeongyu-codex-plugins".mcp_servers.lsp]',
`[plugins.${JSON.stringify(legacyPluginKey)}.mcp_servers.lsp]`,
'enabled = true',
"",
'[hooks.state."omo@code-yeongyu-codex-plugins:hooks/hooks.json:post_tool_use:0:0"]',
`[hooks.state.${JSON.stringify(`${legacyPluginKey}:hooks/hooks.json:post_tool_use:0:0`)}]`,
'trusted_hash = "sha256:old"',
"",
].join("\n"),
@@ -180,14 +199,15 @@ test("#given sisyphuslabs marketplace #when installing #then registers lazycodex
const config = await readFile(join(codexHome, "config.toml"), "utf8");
assert.match(config, /\[marketplaces\.sisyphuslabs\]/);
assert.match(config, /source_type = "git"/);
assert.match(config, /source = "https:\/\/github\.com\/code-yeongyu\/lazycodex\.git"/);
assert.match(config, /source = "https:\/\/github\.com\/sisyphuslabs\/omo\.git"/);
assert.match(config, /ref = "main"/);
assert.match(config, /\[plugins\."omo@sisyphuslabs"\]\nenabled = true/);
assert.doesNotMatch(config, /\[marketplaces\.lazycodex\]/);
assert.doesNotMatch(config, /code-yeongyu-codex-plugins/);
assert.doesNotMatch(config, new RegExp(legacyCodexPluginMarketplace));
assert.doesNotMatch(config, /lazycodex\.git/);
assert.doesNotMatch(config, /source_type = "local"/);
await assert.rejects(
stat(join(codexHome, "plugins", "cache", "code-yeongyu-codex-plugins", "omo")),
stat(join(codexHome, "plugins", "cache", legacyCodexPluginMarketplace, "omo")),
/code: 'ENOENT'|ENOENT/,
);
});
@@ -3,12 +3,13 @@ import { dirname } from "node:path";
import { exists } from "./utils.mjs";
const LAZYCODEX_MARKETPLACE_SOURCE = {
const SISYPHUS_MARKETPLACE_SOURCE = {
sourceType: "git",
source: "https://github.com/code-yeongyu/lazycodex.git",
source: "https://github.com/sisyphuslabs/omo.git",
ref: "main",
};
const SISYPHUS_LEGACY_MARKETPLACES = ["lazycodex", "code-yeongyu-codex-plugins"];
const LEGACY_CODEX_PLUGIN_MARKETPLACE = ["code", "yeongyu", "codex", "plugins"].join("-");
const SISYPHUS_LEGACY_MARKETPLACES = ["lazycodex", LEGACY_CODEX_PLUGIN_MARKETPLACE];
export async function updateCodexConfig({
configPath,
@@ -51,7 +52,7 @@ function removeMarketplaceBlock(config, marketplaceName) {
}
function defaultMarketplaceSource(marketplaceName, repoRoot) {
if (marketplaceName === "sisyphuslabs") return LAZYCODEX_MARKETPLACE_SOURCE;
if (marketplaceName === "sisyphuslabs") return SISYPHUS_MARKETPLACE_SOURCE;
return {
sourceType: "local",
source: repoRoot,