mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-28 16:55:44 +00:00
283 lines
7.5 KiB
TypeScript
283 lines
7.5 KiB
TypeScript
import type {
|
|
Event,
|
|
createOpencodeClient,
|
|
Project,
|
|
Model,
|
|
Provider,
|
|
Permission,
|
|
UserMessage,
|
|
Message,
|
|
Part,
|
|
Auth,
|
|
Config as SDKConfig,
|
|
} from "@opencode-ai/sdk"
|
|
import type { createOpencodeClient as createOpencodeClientV2, Event as TuiEvent } from "@opencode-ai/sdk/v2"
|
|
import type { CliRenderer } from "@opentui/core"
|
|
|
|
import type { BunShell } from "./shell"
|
|
import { type ToolDefinition } from "./tool"
|
|
|
|
export * from "./tool"
|
|
export type { CliRenderer } from "@opentui/core"
|
|
|
|
export type ProviderContext = {
|
|
source: "env" | "config" | "custom" | "api"
|
|
info: Provider
|
|
options: Record<string, any>
|
|
}
|
|
|
|
export type PluginInput = {
|
|
client: ReturnType<typeof createOpencodeClient>
|
|
project: Project
|
|
directory: string
|
|
worktree: string
|
|
serverUrl: URL
|
|
$: BunShell
|
|
}
|
|
|
|
export type PluginOptions = Record<string, unknown>
|
|
|
|
export type Config = Omit<SDKConfig, "plugin"> & {
|
|
plugin?: Array<string | [string, PluginOptions]>
|
|
}
|
|
|
|
type HexColor = `#${string}`
|
|
type RefName = string
|
|
type Variant = {
|
|
dark: HexColor | RefName | number
|
|
light: HexColor | RefName | number
|
|
}
|
|
type ThemeColorValue = HexColor | RefName | number | Variant
|
|
|
|
export type ThemeJson = {
|
|
$schema?: string
|
|
defs?: Record<string, HexColor | RefName>
|
|
theme: Record<string, ThemeColorValue> & {
|
|
selectedListItemText?: ThemeColorValue
|
|
backgroundMenu?: ThemeColorValue
|
|
thinkingOpacity?: number
|
|
}
|
|
}
|
|
|
|
export type Plugin = (input: PluginInput, options?: PluginOptions) => Promise<Hooks>
|
|
|
|
export type TuiEventBus = {
|
|
on: <Type extends TuiEvent["type"]>(
|
|
type: Type,
|
|
handler: (event: Extract<TuiEvent, { type: Type }>) => void,
|
|
) => () => void
|
|
}
|
|
|
|
export type TuiPluginInput<Renderer = CliRenderer> = {
|
|
client: ReturnType<typeof createOpencodeClientV2>
|
|
event: TuiEventBus
|
|
url: string
|
|
directory?: string
|
|
renderer: Renderer
|
|
}
|
|
|
|
export type TuiPlugin<Renderer = CliRenderer> = (
|
|
input: TuiPluginInput<Renderer>,
|
|
options?: PluginOptions,
|
|
) => Promise<void>
|
|
|
|
export type PluginModule<Renderer = CliRenderer> =
|
|
| Plugin
|
|
| { server?: Plugin; tui?: TuiPlugin<Renderer>; themes?: Record<string, ThemeJson> }
|
|
|
|
export type AuthHook = {
|
|
provider: string
|
|
loader?: (auth: () => Promise<Auth>, provider: Provider) => Promise<Record<string, any>>
|
|
methods: (
|
|
| {
|
|
type: "oauth"
|
|
label: string
|
|
prompts?: Array<
|
|
| {
|
|
type: "text"
|
|
key: string
|
|
message: string
|
|
placeholder?: string
|
|
validate?: (value: string) => string | undefined
|
|
condition?: (inputs: Record<string, string>) => boolean
|
|
}
|
|
| {
|
|
type: "select"
|
|
key: string
|
|
message: string
|
|
options: Array<{
|
|
label: string
|
|
value: string
|
|
hint?: string
|
|
}>
|
|
condition?: (inputs: Record<string, string>) => boolean
|
|
}
|
|
>
|
|
authorize(inputs?: Record<string, string>): Promise<AuthOuathResult>
|
|
}
|
|
| {
|
|
type: "api"
|
|
label: string
|
|
prompts?: Array<
|
|
| {
|
|
type: "text"
|
|
key: string
|
|
message: string
|
|
placeholder?: string
|
|
validate?: (value: string) => string | undefined
|
|
condition?: (inputs: Record<string, string>) => boolean
|
|
}
|
|
| {
|
|
type: "select"
|
|
key: string
|
|
message: string
|
|
options: Array<{
|
|
label: string
|
|
value: string
|
|
hint?: string
|
|
}>
|
|
condition?: (inputs: Record<string, string>) => boolean
|
|
}
|
|
>
|
|
authorize?(inputs?: Record<string, string>): Promise<
|
|
| {
|
|
type: "success"
|
|
key: string
|
|
provider?: string
|
|
}
|
|
| {
|
|
type: "failed"
|
|
}
|
|
>
|
|
}
|
|
)[]
|
|
}
|
|
|
|
export type AuthOuathResult = { url: string; instructions: string } & (
|
|
| {
|
|
method: "auto"
|
|
callback(): Promise<
|
|
| ({
|
|
type: "success"
|
|
provider?: string
|
|
} & (
|
|
| {
|
|
refresh: string
|
|
access: string
|
|
expires: number
|
|
accountId?: string
|
|
}
|
|
| { key: string }
|
|
))
|
|
| {
|
|
type: "failed"
|
|
}
|
|
>
|
|
}
|
|
| {
|
|
method: "code"
|
|
callback(code: string): Promise<
|
|
| ({
|
|
type: "success"
|
|
provider?: string
|
|
} & (
|
|
| {
|
|
refresh: string
|
|
access: string
|
|
expires: number
|
|
accountId?: string
|
|
}
|
|
| { key: string }
|
|
))
|
|
| {
|
|
type: "failed"
|
|
}
|
|
>
|
|
}
|
|
)
|
|
|
|
export interface Hooks {
|
|
event?: (input: { event: Event }) => Promise<void>
|
|
config?: (input: Config) => Promise<void>
|
|
tool?: {
|
|
[key: string]: ToolDefinition
|
|
}
|
|
auth?: AuthHook
|
|
/**
|
|
* Called when a new message is received
|
|
*/
|
|
"chat.message"?: (
|
|
input: {
|
|
sessionID: string
|
|
agent?: string
|
|
model?: { providerID: string; modelID: string }
|
|
messageID?: string
|
|
variant?: string
|
|
},
|
|
output: { message: UserMessage; parts: Part[] },
|
|
) => Promise<void>
|
|
/**
|
|
* Modify parameters sent to LLM
|
|
*/
|
|
"chat.params"?: (
|
|
input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
|
|
output: { temperature: number; topP: number; topK: number; options: Record<string, any> },
|
|
) => Promise<void>
|
|
"chat.headers"?: (
|
|
input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
|
|
output: { headers: Record<string, string> },
|
|
) => Promise<void>
|
|
"permission.ask"?: (input: Permission, output: { status: "ask" | "deny" | "allow" }) => Promise<void>
|
|
"command.execute.before"?: (
|
|
input: { command: string; sessionID: string; arguments: string },
|
|
output: { parts: Part[] },
|
|
) => Promise<void>
|
|
"tool.execute.before"?: (
|
|
input: { tool: string; sessionID: string; callID: string },
|
|
output: { args: any },
|
|
) => Promise<void>
|
|
"shell.env"?: (input: { cwd: string }, output: { env: Record<string, string> }) => Promise<void>
|
|
"tool.execute.after"?: (
|
|
input: { tool: string; sessionID: string; callID: string; args: any },
|
|
output: {
|
|
title: string
|
|
output: string
|
|
metadata: any
|
|
},
|
|
) => Promise<void>
|
|
"experimental.chat.messages.transform"?: (
|
|
input: {},
|
|
output: {
|
|
messages: {
|
|
info: Message
|
|
parts: Part[]
|
|
}[]
|
|
},
|
|
) => Promise<void>
|
|
"experimental.chat.system.transform"?: (
|
|
input: { sessionID?: string; model: Model },
|
|
output: {
|
|
system: string[]
|
|
},
|
|
) => Promise<void>
|
|
/**
|
|
* Called before session compaction starts. Allows plugins to customize
|
|
* the compaction prompt.
|
|
*
|
|
* - `context`: Additional context strings appended to the default prompt
|
|
* - `prompt`: If set, replaces the default compaction prompt entirely
|
|
*/
|
|
"experimental.session.compacting"?: (
|
|
input: { sessionID: string },
|
|
output: { context: string[]; prompt?: string },
|
|
) => Promise<void>
|
|
"experimental.text.complete"?: (
|
|
input: { sessionID: string; messageID: string; partID: string },
|
|
output: { text: string },
|
|
) => Promise<void>
|
|
/**
|
|
* Modify tool definitions (description and parameters) sent to LLM
|
|
*/
|
|
"tool.definition"?: (input: { toolID: string }, output: { description: string; parameters: any }) => Promise<void>
|
|
}
|