/** * Tool registry. * * `ToolContext` bundles the plugin-closure state and helpers each * `codex-*` tool needs. The plugin builds a `ToolContext` inside * `OpenAIOAuthPlugin` and passes it to `createToolRegistry` so that every * tool factory can access closure state (mutable refs, helpers) without * living inside the plugin function body. * * **Status**: all registered `codex-*` tools live in per-tool modules under * `lib/tools/`. The plugin entrypoint wires the shared context once and * exposes the returned registry on the OpenCode plugin surface. * * See `lib/tools/AGENTS.md` for the per-tool factory pattern. */ import type { AccountManager, AccountSelectionExplainability } from "../accounts.js"; import type { AccountStorageV3, FlaggedAccountMetadataV1 } from "../storage.js"; import type { UiRuntimeOptions } from "../ui/runtime.js"; import type { BeginnerAccountSnapshot, BeginnerDiagnosticSeverity, BeginnerRuntimeSnapshot } from "../ui/beginner.js"; import type { ModelFamily } from "../prompts/codex.js"; import type { RoutingVisibilitySnapshot, RuntimeMetrics } from "../runtime.js"; import type { ToolDefinition } from "@opencode-ai/plugin/tool"; export { createCodexDiagTool } from "./codex-diag.js"; export { createCodexDiffTool } from "./codex-diff.js"; export { createCodexKeychainTool } from "./codex-keychain.js"; /** * Mutable reference wrapper. * * Used for plugin-closure state that tools both read and write * (e.g. `cachedAccountManager`). The plugin hands a single `MutableRef` * to every factory so writes made inside a tool propagate to the outer * closure and all other tools without depending on module-level state. */ export type MutableRef = { current: T; }; /** * Shared tool context. * * Every `codex-*` tool factory receives this object. Fields fall into * three groups: * * - Plugin-state refs (`cachedAccountManagerRef`, …) — mutable * - Read-only runtime handles (`runtimeMetrics`, `beginnerSafeModeRef`) * - Helper functions captured from the plugin closure * * The factory `createTool(ctx)` returns a standard `tool({...})` * result. Keeping the surface in one type lets us evolve it without * threading dozens of arguments through 24 call sites. * * The type lists the closure state and helpers used across the current * registry. Each tool only destructures the subset it uses. */ export interface ToolContext { cachedAccountManagerRef: MutableRef; accountManagerPromiseRef: MutableRef | null>; reloadCachedAccountManager: () => Promise; runtimeMetrics: RuntimeMetrics; beginnerSafeModeRef: { readonly current: boolean; }; resolveUiRuntime: () => UiRuntimeOptions; getStatusMarker: (ui: UiRuntimeOptions, status: "ok" | "warning" | "error") => string; formatCommandAccountLabel: (account: { email?: string; accountId?: string; accountUserId?: string; accountLabel?: string; accountTags?: string[]; accountNote?: string; } | undefined, index: number, options?: { maskEmail?: boolean; peerAccounts?: readonly ({ accountUserId?: string; } | undefined)[]; omitSeat?: boolean; }) => string; resolveMaskEmail: () => boolean; normalizeAccountTags: (raw: string) => string[]; supportsInteractiveMenus: () => boolean; promptAccountIndexSelection: (ui: UiRuntimeOptions, storage: AccountStorageV3, title: string) => Promise; resolveActiveIndex: (storage: { activeIndex: number; activeIndexByFamily?: Partial>; accounts: unknown[]; }, family?: ModelFamily) => number; getRateLimitResetTimeForFamily: (account: { rateLimitResetTimes?: Record; }, now: number, family: ModelFamily) => number | null; formatRateLimitEntry: (account: { rateLimitResetTimes?: Record; }, now: number, family?: ModelFamily) => string | null; formatQuotaExhaustionEntry: (account: { quotaExhaustedUntil?: number; }, now: number) => string | null; buildJsonAccountIdentity: (index: number, options?: { includeSensitive?: boolean; account?: { email?: string; accountId?: string; accountUserId?: string; accountLabel?: string; accountTags?: string[]; accountNote?: string; }; label?: string; peerAccounts?: readonly ({ accountUserId?: string; } | undefined)[]; }) => Record; buildRoutingVisibilitySnapshot: (overrides?: { modelFamily?: ModelFamily | null; effectiveModel?: string | null; quotaKey?: string | null; selectedAccountIndex?: number | null; selectionExplainability?: AccountSelectionExplainability[]; }) => RoutingVisibilitySnapshot; appendRoutingVisibilityText: (lines: string[], routing: RoutingVisibilitySnapshot, options?: { includeExplainability?: boolean; }) => void; appendRoutingVisibilityUi: (ui: UiRuntimeOptions, lines: string[], routing: RoutingVisibilitySnapshot, options?: { includeExplainability?: boolean; }) => void; toBeginnerAccountSnapshots: (storage: AccountStorageV3, activeIndex: number, now: number) => BeginnerAccountSnapshot[]; getBeginnerRuntimeSnapshot: () => BeginnerRuntimeSnapshot; formatDoctorSeverity: (ui: UiRuntimeOptions, severity: BeginnerDiagnosticSeverity) => string; formatDoctorSeverityText: (severity: BeginnerDiagnosticSeverity) => string; buildSetupChecklistState: () => Promise<{ now: number; storage: AccountStorageV3 | null; activeIndex: number; snapshots: BeginnerAccountSnapshot[]; runtime: BeginnerRuntimeSnapshot; checklist: ReturnType; summary: ReturnType; nextAction: string; }>; renderSetupChecklistOutput: (ui: UiRuntimeOptions, state: Awaited>) => string; runSetupWizard: (ui: UiRuntimeOptions, state: Awaited>) => Promise; invalidateAccountManagerCache: (clearedSnapshots?: Readonly) => void; upsertFlaggedAccountRecord: (accounts: FlaggedAccountMetadataV1[], record: FlaggedAccountMetadataV1) => void; } /** * Build the codex-* tool registry from a prepared context. * * Returned shape matches the `tool: { … }` map the plugin exposes on the * `Plugin` output object. * * Every exported entry below maps directly to a per-file tool factory. */ export type CodexToolRegistry = Record; export declare function createToolRegistry(ctx: ToolContext): CodexToolRegistry; //# sourceMappingURL=index.d.ts.map