MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / scanCodexPlugins

Function scanCodexPlugins

packages/plugins/mcp/src/sdk/codex-plugins.ts:389–455  ·  view source on GitHub ↗
(options?: {
  readonly codexHome?: string;
  /** Explicit `codex` CLI path (tests); default resolves PATH + fallbacks. */
  readonly codexCli?: string;
})

Source from the content-addressed store, hash-verified

387 * as scanned and spawned directly.
388 */
389export const scanCodexPlugins = (options?: {
390 readonly codexHome?: string;
391 /** Explicit `codex` CLI path (tests); default resolves PATH + fallbacks. */
392 readonly codexCli?: string;
393}): readonly CodexPluginEntry[] => {
394 const codexHome =
395 options?.codexHome ?? process.env["CODEX_HOME"] ?? path.join(os.homedir(), ".codex");
396
397 const codexCli = resolveCodexCli(options?.codexCli);
398 const computerUseApp = isExecutableFile(clientBinaryPath(codexHome));
399 const browserClient = browserClientPath(codexHome);
400 const chromePlugin = isReadableFile(browserClient);
401
402 /** Each curated card states what it needs; the `codex` CLI is required by
403 * all of them because every one is reached through `codex app-server`. */
404 const requirementMet: Record<CuratedCodexPlugin["requires"], boolean> = {
405 "computer-use-app": computerUseApp,
406 "chrome-plugin": chromePlugin,
407 codex: true,
408 };
409
410 const curated: readonly CodexPluginEntry[] = CURATED_CODEX_PLUGINS.map((entry) => {
411 const display = curatedDisplayMetadata(codexHome, entry.pluginName);
412 const available = codexCli !== undefined && requirementMet[entry.requires];
413 return {
414 id: entry.id,
415 name: entry.name,
416 summary: entry.summary,
417 available,
418 slug: entry.slug,
419 source: "curated" as const,
420 command: codexCli ?? "codex",
421 args: ["app-server"],
422 env: { CODEX_HOME: codexHome },
423 appServer: {
424 presetId: entry.id,
425 server: entry.server,
426 ...(entry.surface === undefined ? {} : { surface: entry.surface }),
427 ...(entry.surface === "browser" ? { modulePath: browserClient } : {}),
428 },
429 ...(available
430 ? {}
431 : { setupHint: setupHint(entry.requires, entry.name), setupUrl: setupUrl(entry.requires) }),
432 fallbackIcon: entry.publicIcon ?? "https://integrations.sh/logo/openai.com",
433 ...display,
434 };
435 });
436
437 const cacheDir = path.join(codexHome, "plugins", "cache");
438 const scanned = listDirs(cacheDir).flatMap((sourceName) => {
439 const sourceDir = path.join(cacheDir, sourceName);
440 return listDirs(sourceDir)
441 .filter((pluginName) => !CURATED_PLUGIN_NAMES.has(pluginName))
442 .flatMap((pluginName) =>
443 scanCachedPlugin(codexHome, path.join(sourceDir, pluginName), pluginName),
444 );
445 });
446

Callers 1

Calls 12

setupHintFunction · 0.90
setupUrlFunction · 0.90
resolveCodexCliFunction · 0.85
isExecutableFileFunction · 0.85
clientBinaryPathFunction · 0.85
browserClientPathFunction · 0.85
isReadableFileFunction · 0.85
curatedDisplayMetadataFunction · 0.85
listDirsFunction · 0.85
scanCachedPluginFunction · 0.85
valuesMethod · 0.80
setMethod · 0.65

Tested by

no test coverage detected