chore: initialize qiming workspace repository
This commit is contained in:
333
qimingcode/packages/plugin/src/index.ts
Normal file
333
qimingcode/packages/plugin/src/index.ts
Normal file
@@ -0,0 +1,333 @@
|
||||
import type {
|
||||
Event,
|
||||
createOpencodeClient,
|
||||
Project,
|
||||
Model,
|
||||
Provider,
|
||||
Permission,
|
||||
UserMessage,
|
||||
Message,
|
||||
Part,
|
||||
Auth,
|
||||
Config as SDKConfig,
|
||||
} from "@opencode-ai/sdk"
|
||||
import type { Provider as ProviderV2, Model as ModelV2 } from "@opencode-ai/sdk/v2"
|
||||
|
||||
import type { BunShell } from "./shell.js"
|
||||
import { type ToolDefinition } from "./tool.js"
|
||||
|
||||
export * from "./tool.js"
|
||||
|
||||
export type ProviderContext = {
|
||||
source: "env" | "config" | "custom" | "api"
|
||||
info: Provider
|
||||
options: Record<string, any>
|
||||
}
|
||||
|
||||
export type WorkspaceInfo = {
|
||||
id: string
|
||||
type: string
|
||||
name: string
|
||||
branch: string | null
|
||||
directory: string | null
|
||||
extra: unknown | null
|
||||
projectID: string
|
||||
}
|
||||
|
||||
export type WorkspaceTarget =
|
||||
| {
|
||||
type: "local"
|
||||
directory: string
|
||||
}
|
||||
| {
|
||||
type: "remote"
|
||||
url: string | URL
|
||||
headers?: HeadersInit
|
||||
}
|
||||
|
||||
export type WorkspaceAdaptor = {
|
||||
name: string
|
||||
description: string
|
||||
configure(config: WorkspaceInfo): WorkspaceInfo | Promise<WorkspaceInfo>
|
||||
create(config: WorkspaceInfo, env: Record<string, string | undefined>, from?: WorkspaceInfo): Promise<void>
|
||||
remove(config: WorkspaceInfo): Promise<void>
|
||||
target(config: WorkspaceInfo): WorkspaceTarget | Promise<WorkspaceTarget>
|
||||
}
|
||||
|
||||
export type PluginInput = {
|
||||
client: ReturnType<typeof createOpencodeClient>
|
||||
project: Project
|
||||
directory: string
|
||||
worktree: string
|
||||
experimental_workspace: {
|
||||
register(type: string, adaptor: WorkspaceAdaptor): void
|
||||
}
|
||||
serverUrl: URL
|
||||
$: BunShell
|
||||
}
|
||||
|
||||
export type PluginOptions = Record<string, unknown>
|
||||
|
||||
export type Config = Omit<SDKConfig, "plugin"> & {
|
||||
plugin?: Array<string | [string, PluginOptions]>
|
||||
}
|
||||
|
||||
export type Plugin = (input: PluginInput, options?: PluginOptions) => Promise<Hooks>
|
||||
|
||||
export type PluginModule = {
|
||||
id?: string
|
||||
server: Plugin
|
||||
tui?: never
|
||||
}
|
||||
|
||||
type Rule = {
|
||||
key: string
|
||||
op: "eq" | "neq"
|
||||
value: string
|
||||
}
|
||||
|
||||
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
|
||||
/** @deprecated Use `when` instead */
|
||||
condition?: (inputs: Record<string, string>) => boolean
|
||||
when?: Rule
|
||||
}
|
||||
| {
|
||||
type: "select"
|
||||
key: string
|
||||
message: string
|
||||
options: Array<{
|
||||
label: string
|
||||
value: string
|
||||
hint?: string
|
||||
}>
|
||||
/** @deprecated Use `when` instead */
|
||||
condition?: (inputs: Record<string, string>) => boolean
|
||||
when?: Rule
|
||||
}
|
||||
>
|
||||
authorize(inputs?: Record<string, string>): Promise<AuthOAuthResult>
|
||||
}
|
||||
| {
|
||||
type: "api"
|
||||
label: string
|
||||
prompts?: Array<
|
||||
| {
|
||||
type: "text"
|
||||
key: string
|
||||
message: string
|
||||
placeholder?: string
|
||||
validate?: (value: string) => string | undefined
|
||||
/** @deprecated Use `when` instead */
|
||||
condition?: (inputs: Record<string, string>) => boolean
|
||||
when?: Rule
|
||||
}
|
||||
| {
|
||||
type: "select"
|
||||
key: string
|
||||
message: string
|
||||
options: Array<{
|
||||
label: string
|
||||
value: string
|
||||
hint?: string
|
||||
}>
|
||||
/** @deprecated Use `when` instead */
|
||||
condition?: (inputs: Record<string, string>) => boolean
|
||||
when?: Rule
|
||||
}
|
||||
>
|
||||
authorize?(inputs?: Record<string, string>): Promise<
|
||||
| {
|
||||
type: "success"
|
||||
key: string
|
||||
provider?: string
|
||||
}
|
||||
| {
|
||||
type: "failed"
|
||||
}
|
||||
>
|
||||
}
|
||||
)[]
|
||||
}
|
||||
|
||||
export type AuthOAuthResult = { url: string; instructions: string } & (
|
||||
| {
|
||||
method: "auto"
|
||||
callback(): Promise<
|
||||
| ({
|
||||
type: "success"
|
||||
provider?: string
|
||||
} & (
|
||||
| {
|
||||
refresh: string
|
||||
access: string
|
||||
expires: number
|
||||
accountId?: string
|
||||
enterpriseUrl?: string
|
||||
}
|
||||
| { key: string }
|
||||
))
|
||||
| {
|
||||
type: "failed"
|
||||
}
|
||||
>
|
||||
}
|
||||
| {
|
||||
method: "code"
|
||||
callback(code: string): Promise<
|
||||
| ({
|
||||
type: "success"
|
||||
provider?: string
|
||||
} & (
|
||||
| {
|
||||
refresh: string
|
||||
access: string
|
||||
expires: number
|
||||
accountId?: string
|
||||
enterpriseUrl?: string
|
||||
}
|
||||
| { key: string }
|
||||
))
|
||||
| {
|
||||
type: "failed"
|
||||
}
|
||||
>
|
||||
}
|
||||
)
|
||||
|
||||
export type ProviderHookContext = {
|
||||
auth?: Auth
|
||||
}
|
||||
|
||||
export type ProviderHook = {
|
||||
id: string
|
||||
models?: (provider: ProviderV2, ctx: ProviderHookContext) => Promise<Record<string, ModelV2>>
|
||||
}
|
||||
|
||||
/** @deprecated Use AuthOAuthResult instead. */
|
||||
export type AuthOuathResult = AuthOAuthResult
|
||||
|
||||
export interface Hooks {
|
||||
event?: (input: { event: Event }) => Promise<void>
|
||||
config?: (input: Config) => Promise<void>
|
||||
tool?: {
|
||||
[key: string]: ToolDefinition
|
||||
}
|
||||
auth?: AuthHook
|
||||
provider?: ProviderHook
|
||||
/**
|
||||
* 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
|
||||
maxOutputTokens: number | undefined
|
||||
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; sessionID?: string; callID?: 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>
|
||||
/**
|
||||
* Called after compaction succeeds and before a synthetic user
|
||||
* auto-continue message is added.
|
||||
*
|
||||
* - `enabled`: Defaults to `true`. Set to `false` to skip the synthetic
|
||||
* user "continue" turn.
|
||||
*/
|
||||
"experimental.compaction.autocontinue"?: (
|
||||
input: {
|
||||
sessionID: string
|
||||
agent: string
|
||||
model: Model
|
||||
provider: ProviderContext
|
||||
message: UserMessage
|
||||
overflow: boolean
|
||||
},
|
||||
output: { enabled: boolean },
|
||||
) => 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>
|
||||
}
|
||||
Reference in New Issue
Block a user