/** * Local structural types for the OpenCode v2 plugin API. * * OpenCode v2 (anomalyco/opencode branch `v2`, unreleased) loads plugins via * `packages/core/src/plugin/supervisor.ts`, which schema-decodes the module's * default export as `{ id: string, tui?: boolean, effect | setup: function }` * and adapts `setup` promise plugins with `PluginPromise.fromPromise`. The * full typed surface lives in the unpublished `@opencode-ai/plugin` v2 * package; these structural declarations mirror the pieces this plugin uses * (derived from the v2 branch at c85b09de6) so the adapter compiles against * our v1-pinned dependencies with zero new runtime deps. Field shapes are * validated by v2's own schemas at runtime; treat drift there as a signal to * refresh these types, not to loosen the adapter. */ /** Credential.OAuth — stored OAuth credential for an integration method. */ export interface V2OAuthCredential { type: "oauth"; /** Plain string at the Promise boundary; v2's adapter applies its Effect brand. */ methodID: any; refresh: string; access: string; expires: number; metadata?: Record; } export type V2CredentialValue = V2OAuthCredential | { type: "key"; key: string; metadata?: Record; }; /** Result of an OAuth authorize() call; mode picks the completion flow. */ interface V2OAuthAuthorizationBase { url: string; instructions: string; expiresAt?: number; } export type V2OAuthAuthorization = V2OAuthAuthorizationBase & ({ mode: "auto"; callback: Promise; } | { mode: "code"; callback: (code: string) => Promise; }); export type V2IntegrationMethodRegistration = { integrationID: string; method: { id: string; type: "oauth"; label: string; }; authorize: (answer: unknown) => Promise; refresh?: (credential: V2OAuthCredential) => Promise; label?: (credential: V2OAuthCredential) => string | undefined; } | { integrationID: string; method: { id: string; type: "command"; label: string; command: ReadonlyArray; }; } | { integrationID: string; method: { type: "key"; label?: string; }; } | { integrationID: string; method: { type: "env"; names: ReadonlyArray; }; }; export interface V2ConnectionInfo { id?: string; type?: string; label?: string; methodID?: string; name?: string; [key: string]: unknown; } export interface V2IntegrationDraft { list(): ReadonlyArray<{ id: string; name: string; }>; get(id: string): { id: string; name: string; } | undefined; update(id: string, update: (integration: { id: string; name: string; }) => void): void; remove(id: string): void; method: { list(integrationID: string): ReadonlyArray; update(input: V2IntegrationMethodRegistration): void; remove(integrationID: string, method: unknown): void; }; } export interface V2IntegrationDomain { transform(callback: (draft: V2IntegrationDraft) => void): Promise<{ dispose: () => Promise; }>; reload(): Promise; connection: { active(integrationID: string): Promise; resolve(connection: V2ConnectionInfo): Promise; }; } /** Catalog model draft — mutable subset of Model.Info we stamp. */ export interface V2CatalogModelDraft { id?: any; modelID?: any; providerID?: any; name: string; family?: any; package?: string; status: string; enabled: boolean; capabilities: { tools: boolean; input: string[]; output: string[]; }; variants: Array<{ id: any; [key: string]: unknown; }>; time: { released: any; }; cost: Array<{ input: any; output: any; cache: { read: any; write: any; }; }>; limit: { context: any; input?: any; output: any; }; [key: string]: unknown; } export interface V2CatalogProviderDraft { id?: any; name: string; activation?: string; package?: string; integrationID?: any; [key: string]: unknown; } export interface V2CatalogDraft { provider: { list(): ReadonlyArray<{ provider: V2CatalogProviderDraft; models: ReadonlyMap; }>; get(providerID: string): { provider: V2CatalogProviderDraft; models: ReadonlyMap; } | undefined; update(providerID: string, update: (provider: V2CatalogProviderDraft) => void): void; remove(providerID: string): void; }; model: { get(providerID: string, modelID: string): V2CatalogModelDraft | undefined; update(providerID: string, modelID: string, update: (model: V2CatalogModelDraft) => void): void; remove(providerID: string, modelID: string): void; default: { get(): { providerID: string; modelID: string; } | undefined; set(providerID: string, modelID: string): void; }; }; } export interface V2CatalogDomain { transform(callback: (draft: V2CatalogDraft) => void): Promise<{ dispose: () => Promise; }>; reload(): Promise; } /** session.hook("model.request") event; baseURL/headers are mutable. */ export interface V2SessionModelRequestEvent { sessionID: string; agent: string; model: { providerID: string; id: string; variant?: string; }; baseURL?: string; headers: Record; } export interface V2SessionDomain { hook(name: "model.request" | "http.request" | "http.response" | "context", callback: (event: any) => Promise | void, options?: { providerID?: string; }): Promise<{ dispose: () => Promise; }>; } export interface V2ToolExecuteBeforeEvent { tool: string; sessionID: string; agent?: string; messageID?: string; id: string; input: unknown; } export interface V2ToolExecuteAfterEvent { tool: string; sessionID: string; agent?: string; messageID?: string; id: string; input: unknown; status: "completed" | "error"; result?: { output?: unknown; content?: unknown; metadata?: unknown; }; error?: { message?: string; }; } export interface V2ToolDomain { transform(callback: (draft: { add(tool: { name: string; description: string; input: Record; execute: (input: unknown, context: { sessionID: string; agent?: string; messageID?: string; id?: string; progress?: (update: Readonly>) => Promise; }) => Promise<{ output?: any; content?: string | ReadonlyArray<{ type: "text"; text: string; } | { type: "file"; uri: string; mime: string; name?: string; }>; metadata?: Readonly>; }>; }): void; }) => void): Promise<{ dispose: () => Promise; }>; hook(name: "execute.before" | "execute.after", callback: (event: V2ToolExecuteBeforeEvent | V2ToolExecuteAfterEvent) => Promise | void): Promise<{ dispose: () => Promise; }>; } export interface V2EventDomain { subscribe(): AsyncIterable<{ type: string; [key: string]: unknown; }>; } /** Subset of the v2 plugin Context domains this adapter uses. */ export interface V2Context { app: { name: string; version: string; channel: string; }; options: Record; integration: V2IntegrationDomain; catalog: V2CatalogDomain; session: V2SessionDomain; tool: V2ToolDomain; event: V2EventDomain; } /** v2 promise-plugin module shape: default-exported { id, setup }. */ export interface V2Plugin { id: string; tui?: boolean; setup(context: V2Context): Promise void | Promise)>; } /** Package `./server` entry accepted by both the v1 and v2 loaders. */ export interface V2DualPlugin extends V2Plugin { server(input: unknown): Promise; } export {};