index.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import type {
  2. Event,
  3. createOpencodeClient,
  4. Project,
  5. Model,
  6. Provider,
  7. Permission,
  8. UserMessage,
  9. Part,
  10. Auth,
  11. Config,
  12. } from "@opencode-ai/sdk"
  13. import type { BunShell } from "./shell"
  14. import { type ToolDefinition } from "./tool"
  15. export * from "./tool"
  16. export type PluginInput = {
  17. client: ReturnType<typeof createOpencodeClient>
  18. project: Project
  19. directory: string
  20. worktree: string
  21. $: BunShell
  22. }
  23. export type Plugin = (input: PluginInput) => Promise<Hooks>
  24. export interface Hooks {
  25. event?: (input: { event: Event }) => Promise<void>
  26. config?: (input: Config) => Promise<void>
  27. tool?: {
  28. [key: string]: ToolDefinition
  29. }
  30. auth?: {
  31. provider: string
  32. loader?: (auth: () => Promise<Auth>, provider: Provider) => Promise<Record<string, any>>
  33. methods: (
  34. | {
  35. type: "oauth"
  36. label: string
  37. prompts?: Array<
  38. | {
  39. type: "text"
  40. key: string
  41. message: string
  42. placeholder?: string
  43. validate?: (value: string) => string | undefined
  44. condition?: (inputs: Record<string, string>) => boolean
  45. }
  46. | {
  47. type: "select"
  48. key: string
  49. message: string
  50. options: Array<{
  51. label: string
  52. value: string
  53. hint?: string
  54. }>
  55. condition?: (inputs: Record<string, string>) => boolean
  56. }
  57. >
  58. authorize(inputs?: Record<string, string>): Promise<
  59. { url: string; instructions: string } & (
  60. | {
  61. method: "auto"
  62. callback(): Promise<
  63. | ({
  64. type: "success"
  65. provider?: string
  66. } & (
  67. | {
  68. refresh: string
  69. access: string
  70. expires: number
  71. }
  72. | { key: string }
  73. ))
  74. | {
  75. type: "failed"
  76. }
  77. >
  78. }
  79. | {
  80. method: "code"
  81. callback(code: string): Promise<
  82. | ({
  83. type: "success"
  84. provider?: string
  85. } & (
  86. | {
  87. refresh: string
  88. access: string
  89. expires: number
  90. }
  91. | { key: string }
  92. ))
  93. | {
  94. type: "failed"
  95. }
  96. >
  97. }
  98. )
  99. >
  100. }
  101. | {
  102. type: "api"
  103. label: string
  104. prompts?: Array<
  105. | {
  106. type: "text"
  107. key: string
  108. message: string
  109. placeholder?: string
  110. validate?: (value: string) => string | undefined
  111. condition?: (inputs: Record<string, string>) => boolean
  112. }
  113. | {
  114. type: "select"
  115. key: string
  116. message: string
  117. options: Array<{
  118. label: string
  119. value: string
  120. hint?: string
  121. }>
  122. condition?: (inputs: Record<string, string>) => boolean
  123. }
  124. >
  125. authorize?(inputs?: Record<string, string>): Promise<
  126. | {
  127. type: "success"
  128. key: string
  129. provider?: string
  130. }
  131. | {
  132. type: "failed"
  133. }
  134. >
  135. }
  136. )[]
  137. }
  138. /**
  139. * Called when a new message is received
  140. */
  141. "chat.message"?: (input: {}, output: { message: UserMessage; parts: Part[] }) => Promise<void>
  142. /**
  143. * Modify parameters sent to LLM
  144. */
  145. "chat.params"?: (
  146. input: { model: Model; provider: Provider; message: UserMessage },
  147. output: { temperature: number; topP: number; options: Record<string, any> },
  148. ) => Promise<void>
  149. "permission.ask"?: (
  150. input: Permission,
  151. output: { status: "ask" | "deny" | "allow" },
  152. ) => Promise<void>
  153. "tool.execute.before"?: (
  154. input: { tool: string; sessionID: string; callID: string },
  155. output: { args: any },
  156. ) => Promise<void>
  157. "tool.execute.after"?: (
  158. input: { tool: string; sessionID: string; callID: string },
  159. output: {
  160. title: string
  161. output: string
  162. metadata: any
  163. },
  164. ) => Promise<void>
  165. }