/** * pi-chimera — Codex-compatibility extension (post-split). * * After the Workstream 2 split, pi-chimera keeps its name but contains ONLY * the Codex compatibility patch: it discovers the optional * `@howaboua/pi-codex-conversion` package when it is loaded and reports the * inherited tool names and extension paths it would project into child * sessions. The multi-agent machinery itself lives in pi-subagents, which * computes the same metadata from its own copy of the tiny contract module * (`extension-inheritance.ts`); neither extension imports the other. * * Standalone: pi-chimera never depends on pi-subagents or on the conversion * package. Without the conversion package this extension is inert — it * reports "no conversion package loaded" and changes nothing. */ import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { Type } from "typebox"; import { collectInheritedExtensionMetadata } from "./extension-inheritance.ts"; const STATUS_KEY = "pi-chimera-compat"; const OWN_EXTENSION_PATH = resolve(fileURLToPath(import.meta.url)); export default function piChimera(pi: ExtensionAPI): void { const metadata = (): { conversionPackagePresent: boolean; extensionPaths: string[]; inheritedToolNames: string[]; } => { const collected = collectInheritedExtensionMetadata( typeof pi.getAllTools === "function" ? pi.getAllTools() : [], typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [], OWN_EXTENSION_PATH, ); return { conversionPackagePresent: collected.inheritedToolNames.length > 0, extensionPaths: collected.extensionPaths, inheritedToolNames: collected.inheritedToolNames, }; }; // The documented capability: a public tool that reports the conversion // metadata (inherited tool names + extension paths). pi-subagents computes // the same metadata from its own copy of the contract module; this tool is // the compat extension's own surface for verification and operator use. pi.registerTool({ description: "Report the Codex-conversion metadata: whether the @howaboua/pi-codex-conversion package is loaded, the extension paths it contributes, and its inherited tool names. Compat extensions never depend on the conversion package.", execute() { return Promise.resolve({ content: [{ text: JSON.stringify(metadata()), type: "text" as const }], details: metadata(), }); }, label: "Codex Conversion Metadata", name: "codex_conversion_metadata", parameters: Type.Object({}, { additionalProperties: false }), promptSnippet: "Show the Codex-conversion package metadata", }); pi.registerCommand("codex-compat", { description: "Show the Codex-conversion package metadata (inherited tool names and extension paths)", handler: async (_args, ctx) => { const result = metadata(); const summary = result.conversionPackagePresent ? `codex conversion: ${result.inheritedToolNames.length} tool(s) from ${result.extensionPaths.length} path(s)` : "codex conversion: no conversion package loaded"; ctx.ui.setStatus(STATUS_KEY, summary); if (ctx.hasUI) { ctx.ui.notify( result.conversionPackagePresent ? `Codex conversion package found: ${result.inheritedToolNames.join(", ")}` : "No Codex conversion package loaded; pi-chimera is inert.", result.conversionPackagePresent ? "info" : "warning", ); } }, }); pi.on("session_start", async (_event, ctx) => { const result = metadata(); ctx.ui.setStatus( STATUS_KEY, result.conversionPackagePresent ? `codex conversion: ${result.inheritedToolNames.length} tool(s)` : "codex conversion: not loaded", ); }); }