vendor: import codex-plugins as packages/omo-codex/{plugin,scripts,marketplace.json,MARKETPLACE.md}
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env node
|
||||
import { homedir } from "node:os";
|
||||
import { join, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { installCachedPlugin, linkCachedPluginBins, pruneMarketplaceCache } from "./install/cache.mjs";
|
||||
import { updateCodexConfig } from "./install/config.mjs";
|
||||
import { trustedHookStatesForPlugin } from "./install/hook-trust.mjs";
|
||||
import { defaultRunCommand } from "./install/process.mjs";
|
||||
import {
|
||||
readMarketplace,
|
||||
readPluginManifest,
|
||||
resolvePluginSource,
|
||||
validatePathSegment,
|
||||
} from "./install/marketplace.mjs";
|
||||
|
||||
export async function installMarketplaceLocally(options = {}) {
|
||||
const repoRoot = resolve(options.repoRoot ?? process.cwd());
|
||||
const codexHome = resolve(options.codexHome ?? process.env.CODEX_HOME ?? join(homedir(), ".codex"));
|
||||
const binDir = resolve(options.binDir ?? process.env.CODEX_LOCAL_BIN_DIR ?? join(homedir(), ".local", "bin"));
|
||||
const runCommand = options.runCommand ?? defaultRunCommand;
|
||||
const log = options.log ?? console.log;
|
||||
const marketplace = await readMarketplace(repoRoot);
|
||||
const installed = [];
|
||||
|
||||
for (const entry of marketplace.plugins) {
|
||||
const sourcePath = resolvePluginSource(repoRoot, entry);
|
||||
const manifest = await readPluginManifest(sourcePath);
|
||||
if (manifest.name !== entry.name) {
|
||||
throw new Error(
|
||||
`plugin manifest name ${JSON.stringify(manifest.name)} does not match marketplace name ${JSON.stringify(entry.name)}`,
|
||||
);
|
||||
}
|
||||
const version = manifest.version ?? "local";
|
||||
validatePathSegment(version, "plugin version");
|
||||
|
||||
log(`Building ${entry.name}@${version}`);
|
||||
const plugin = await installCachedPlugin({
|
||||
codexHome,
|
||||
marketplaceName: marketplace.name,
|
||||
name: entry.name,
|
||||
runCommand,
|
||||
sourcePath,
|
||||
version,
|
||||
});
|
||||
const binLinks = await linkCachedPluginBins({ binDir, pluginRoot: plugin.path });
|
||||
for (const link of binLinks) {
|
||||
log(`Linked ${link.name} -> ${link.target}`);
|
||||
}
|
||||
installed.push(plugin);
|
||||
}
|
||||
|
||||
const pluginNames = marketplace.plugins.map((plugin) => plugin.name);
|
||||
const trustedHookStates = (
|
||||
await Promise.all(
|
||||
installed.map((plugin) =>
|
||||
trustedHookStatesForPlugin({
|
||||
marketplaceName: marketplace.name,
|
||||
pluginName: plugin.name,
|
||||
pluginRoot: plugin.path,
|
||||
}),
|
||||
),
|
||||
)
|
||||
).flat();
|
||||
await pruneMarketplaceCache({ codexHome, marketplaceName: marketplace.name, keepPluginNames: pluginNames });
|
||||
await updateCodexConfig({
|
||||
configPath: join(codexHome, "config.toml"),
|
||||
repoRoot,
|
||||
marketplaceName: marketplace.name,
|
||||
pluginNames,
|
||||
trustedHookStates,
|
||||
});
|
||||
|
||||
for (const plugin of installed) {
|
||||
log(`Installed ${plugin.name}@${marketplace.name} -> ${plugin.path}`);
|
||||
}
|
||||
|
||||
return { marketplaceName: marketplace.name, installed };
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const repoRoot = process.argv[2] ? resolve(process.argv[2]) : process.cwd();
|
||||
const result = await installMarketplaceLocally({ repoRoot });
|
||||
console.log(`Installed ${result.installed.length} plugin(s) from ${result.marketplaceName}.`);
|
||||
}
|
||||
|
||||
const invokedPath = process.argv[1] ? resolve(process.argv[1]) : "";
|
||||
if (invokedPath === fileURLToPath(import.meta.url)) {
|
||||
main().catch((error) => {
|
||||
console.error(error instanceof Error ? error.message : error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user