internal.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. export * as PluginInternal from "./internal"
  2. import { makeLocationNode } from "../effect/app-node"
  3. import { httpClient } from "../effect/app-node-platform"
  4. import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
  5. import { Effect, Layer, Scope } from "effect"
  6. import { AgentV2 } from "../agent"
  7. import { Catalog } from "../catalog"
  8. import { CommandV2 } from "../command"
  9. import { Config } from "../config"
  10. import { ConfigAgentPlugin } from "../config/plugin/agent"
  11. import { ConfigCommandPlugin } from "../config/plugin/command"
  12. import { ConfigExternalPlugin } from "../config/plugin/external"
  13. import { ConfigProviderPlugin } from "../config/plugin/provider"
  14. import { ConfigReferencePlugin } from "../config/plugin/reference"
  15. import { ConfigSkillPlugin } from "../config/plugin/skill"
  16. import { EventV2 } from "../event"
  17. import { FileSystem } from "../filesystem"
  18. import { FSUtil } from "../fs-util"
  19. import { Global } from "../global"
  20. import { Integration } from "../integration"
  21. import { Location } from "../location"
  22. import { ModelsDev } from "../models-dev"
  23. import { Npm } from "../npm"
  24. import { PluginV2 } from "../plugin"
  25. import { Reference } from "../reference"
  26. import { SkillV2 } from "../skill"
  27. import { State } from "../state"
  28. import { FetchHttpClient, HttpClient } from "effect/unstable/http"
  29. import { AgentPlugin } from "./agent"
  30. import { CommandPlugin } from "./command"
  31. import { ModelsDevPlugin } from "./models-dev"
  32. import { ProviderPlugins } from "./provider"
  33. import { SkillPlugin } from "./skill"
  34. import { VariantPlugin } from "./variant"
  35. export type Requirements =
  36. | AgentV2.Service
  37. | Catalog.Service
  38. | CommandV2.Service
  39. | Config.Service
  40. | EventV2.Service
  41. | FileSystem.Service
  42. | FSUtil.Service
  43. | Global.Service
  44. | HttpClient.HttpClient
  45. | Integration.Service
  46. | Location.Service
  47. | ModelsDev.Service
  48. | Npm.Service
  49. | Reference.Service
  50. | SkillV2.Service
  51. export interface Plugin<R = never> {
  52. readonly id: string
  53. readonly effect: (context: PluginContext) => Effect.Effect<void, never, R | Scope.Scope>
  54. }
  55. export function define<R>(plugin: Plugin<R>) {
  56. return plugin
  57. }
  58. const layer = Layer.effectDiscard(
  59. Effect.gen(function* () {
  60. const catalog = yield* Catalog.Service
  61. const commands = yield* CommandV2.Service
  62. const plugin = yield* PluginV2.Service
  63. const integration = yield* Integration.Service
  64. const agents = yield* AgentV2.Service
  65. const config = yield* Config.Service
  66. const location = yield* Location.Service
  67. const modelsDev = yield* ModelsDev.Service
  68. const npm = yield* Npm.Service
  69. const events = yield* EventV2.Service
  70. const fs = yield* FSUtil.Service
  71. const filesystem = yield* FileSystem.Service
  72. const global = yield* Global.Service
  73. const http = yield* HttpClient.HttpClient
  74. const skill = yield* SkillV2.Service
  75. const reference = yield* Reference.Service
  76. const add = <R>(input: Plugin<R>) => {
  77. const loaded = {
  78. id: input.id,
  79. effect: (context: PluginContext) =>
  80. input
  81. .effect(context)
  82. .pipe(
  83. Effect.provideService(Catalog.Service, catalog),
  84. Effect.provideService(CommandV2.Service, commands),
  85. Effect.provideService(Integration.Service, integration),
  86. Effect.provideService(AgentV2.Service, agents),
  87. Effect.provideService(Config.Service, config),
  88. Effect.provideService(Location.Service, location),
  89. Effect.provideService(ModelsDev.Service, modelsDev),
  90. Effect.provideService(Npm.Service, npm),
  91. Effect.provideService(EventV2.Service, events),
  92. Effect.provideService(FSUtil.Service, fs),
  93. Effect.provideService(FileSystem.Service, filesystem),
  94. Effect.provideService(Global.Service, global),
  95. Effect.provideService(HttpClient.HttpClient, http),
  96. Effect.provideService(SkillV2.Service, skill),
  97. Effect.provideService(Reference.Service, reference),
  98. ),
  99. }
  100. return plugin.add(PluginV2.ID.make(loaded.id), loaded.effect)
  101. }
  102. yield* State.batch(
  103. Effect.gen(function* () {
  104. yield* add(ConfigReferencePlugin.Plugin)
  105. yield* add(AgentPlugin.Plugin)
  106. yield* add(CommandPlugin.Plugin)
  107. yield* add(SkillPlugin.Plugin)
  108. yield* add(ModelsDevPlugin)
  109. yield* add(ConfigAgentPlugin.Plugin)
  110. yield* add(ConfigCommandPlugin.Plugin)
  111. yield* add(ConfigSkillPlugin.Plugin)
  112. for (const item of ProviderPlugins) yield* add(item)
  113. yield* add(ConfigExternalPlugin.Plugin)
  114. yield* add(ConfigProviderPlugin.Plugin)
  115. yield* add(VariantPlugin.Plugin)
  116. }),
  117. ).pipe(Effect.withSpan("PluginInternal.boot"), Effect.forkScoped({ startImmediately: true }))
  118. }),
  119. )
  120. export const locationLayer = layer.pipe(
  121. Layer.provideMerge(PluginV2.locationLayer),
  122. Layer.provideMerge(Config.locationLayer),
  123. Layer.provideMerge(FileSystem.locationLayer),
  124. Layer.provideMerge(FetchHttpClient.layer),
  125. )
  126. export const node = makeLocationNode({
  127. name: "plugin-internal",
  128. layer,
  129. deps: [
  130. Catalog.node,
  131. CommandV2.node,
  132. PluginV2.node,
  133. Integration.node,
  134. AgentV2.node,
  135. Config.node,
  136. Location.node,
  137. ModelsDev.node,
  138. Npm.node,
  139. EventV2.node,
  140. FSUtil.node,
  141. FileSystem.node,
  142. Global.node,
  143. httpClient,
  144. SkillV2.node,
  145. Reference.node,
  146. ],
  147. })