156 lines · 7.0 KB · TypeScript
RawDownload
// ---------------------------------------------------------------------------// Curated Codex plugin metadata — the isomorphic half of Codex plugin// discovery. The names and summaries here are BOTH the searchable catalog// presets (presets.ts, bundled client-side) and the curated entries the// node-only scanner reports (codex-plugins.ts), so the two can never drift.// Keep the summaries carrying the words people actually search for// ("iMessage", "texts", "computer use", "screen activity").// --------------------------------------------------------------------------- export interface CuratedCodexPlugin {  /** Card/preset id, e.g. `codex-messages`. */  readonly id: string;  /** The Codex plugin name in the plugin cache. */  readonly pluginName: string;  readonly name: string;  /** Suggested integration slug, e.g. `codex_messages`. */  readonly slug: string;  /** The MCP server name this plugin registers inside Codex — the `server`   *  the app-server bridge calls tools against. */  readonly server: string;  /** A public image for this plugin, used when the machine-local icon cannot   *  be read (i.e. Codex is not installed here). Only some plugins have one   *  published; the rest fall back to the provider's mark. */  readonly publicIcon?: string;  /** Present when the plugin has no MCP server of its own and its API is   *  projected onto another one. Computer Use and Chrome both ship as   *  skills/`node-repl` content: Codex never starts a server for either, and   *  their APIs are driven through `node_repl` — see `codex-sky-tools.ts` and   *  `codex-browser-tools.ts`. */  readonly surface?: "sky" | "browser";  /** What must exist on disk for this card to be usable, beyond the `codex`   *  CLI itself. `computer-use-app` is the shared Codex Computer Use app;   *  `chrome-plugin` is the Chrome plugin's bundled browser client; `codex`   *  means the CLI alone is enough (a server Codex always carries). */  readonly requires: "computer-use-app" | "chrome-plugin" | "codex";  readonly summary: string;} /** What to do when a card is not usable yet. * *  Written as numbered steps rather than one sentence: a person reading this *  has just been told they cannot proceed, and the useful answer is the *  shortest ordered path to being able to. Each step names where to go, and *  the last one says to come back — otherwise the card is a dead end. The *  plugin's own name is substituted in, so the instruction is about the thing *  the person clicked rather than about plugins in general. */export const setupSteps = (  requires: CuratedCodexPlugin["requires"],  name: string,): readonly string[] => {  const install = "Install the Codex app from openai.com/codex, then sign in.";  const finish = "Come back here and add it.";  if (requires === "codex") return [install, finish];  if (requires === "chrome-plugin") {    return [      install,      "In Codex, open Settings \u2192 Computer use and install the ChatGPT browser extension.",      "Use Chrome once inside Codex, so it can reach your browser.",      finish,    ];  }  return [    install,    `Open ${name} once inside Codex. macOS asks for its permissions the first time \u2014 Full Disk Access, Contacts, and Automation.`,    finish,  ];}; /** The steps as one string, for the wire and for plain-text surfaces. */export const setupHint = (requires: CuratedCodexPlugin["requires"], name: string): string =>  setupSteps(requires, name)    .map((step, index) => `${index + 1}. ${step}`)    .join("\n"); /** Where a person goes to get what a card needs. * *  Linked rather than only described: a card that cannot be used is a dead end *  unless it hands over the next step. Chrome's own requirement is documented *  on the Computer Use page, so it points there instead of the app download. */export const setupUrl = (requires: CuratedCodexPlugin["requires"]): string =>  requires === "chrome-plugin"    ? "https://learn.chatgpt.com/docs/computer-use"    : "https://openai.com/codex"; export const CURATED_CODEX_PLUGINS: readonly CuratedCodexPlugin[] = [  // Names are exactly the plugins' own displayNames — nothing invented, no  // provenance suffix. Codex provenance shows in the summaries and on the  // focused add screen; search keywords people type ("imessage", "apple",  // "texts") live in the summaries.  {    id: "codex-messages",    pluginName: "messages",    name: "Messages",    slug: "codex_messages",    // Served by the app itself (`packages/app/public`), because the Messages    // app icon is published nowhere hotlinkable: it is a system app, absent    // from the App Store artwork API, and `messages.apple.com` resolves to    // the plain Apple mark. Root-relative, so local and cloud both serve it.    publicIcon: "/plugin-icons/messages.webp",    requires: "computer-use-app",    server: "messages",    summary:      "Read, search, and send iMessage/SMS texts through Apple's Messages app on this Mac, via the Codex plugin. Reads and sends are approved in its native dialogs.",  },  {    id: "codex-computer-use",    pluginName: "computer-use",    name: "Computer Use",    slug: "codex_computer_use",    publicIcon: "https://learn.chatgpt.com/images/codex/icons/computer-use-plugin-icon.png",    requires: "computer-use-app",    server: "node_repl",    surface: "sky",    summary:      "Control macOS desktop apps via the Codex plugin: read the screen and accessibility tree, click, type, and scroll.",  },  {    // Chrome is skills-only: its API is the bundled `browser-client.mjs`,    // driven through `node_repl` exactly as Computer Use drives `@oai/sky`.    id: "codex-chrome",    pluginName: "chrome",    name: "Chrome",    slug: "codex_chrome",    publicIcon: "https://learn.chatgpt.com/images/codex/icons/chrome-production-large.png",    server: "node_repl",    surface: "browser",    requires: "chrome-plugin",    summary:      "Control the Chrome browser on this Mac through the Codex plugin: open tabs, navigate to a URL, read the page, click, and type. Uses your real Chrome, with its logged-in sessions.",  },  {    // A server Codex carries itself — no plugin app, no local binary beyond    // the CLI.    id: "codex-openai-docs",    pluginName: "openai-developers",    name: "OpenAI Developer Docs",    slug: "codex_openai_docs",    server: "openaiDeveloperDocs",    requires: "codex",    summary:      "Search and read OpenAI's developer documentation and API reference, including OpenAPI specs and endpoint listings, via the Codex plugin.",  },  {    id: "codex-computer-history",    pluginName: "computer-history",    name: "Computer History",    slug: "codex_computer_history",    requires: "computer-use-app",    server: "computer-history",    summary:      "Ask about recent on-screen activity from Codex's private local record (requires Computer History enabled in Codex).",  },]; export const isCodexPresetId = (id: string | undefined): boolean =>  id !== undefined && CURATED_CODEX_PLUGINS.some((plugin) => plugin.id === id);