refactor(plugin): use direct runtime registry
This commit is contained in:
@@ -36,12 +36,6 @@ export const Plugin = define({
|
|||||||
const fs = yield* FSUtil.Service
|
const fs = yield* FSUtil.Service
|
||||||
const location = yield* Location.Service
|
const location = yield* Location.Service
|
||||||
const npm = yield* Npm.Service
|
const npm = yield* Npm.Service
|
||||||
const loaded: EffectPlugin[] = []
|
|
||||||
|
|
||||||
yield* ctx.plugin.transform((plugins) => {
|
|
||||||
for (const plugin of loaded) plugins.add(plugin)
|
|
||||||
})
|
|
||||||
|
|
||||||
yield* Effect.gen(function* () {
|
yield* Effect.gen(function* () {
|
||||||
const configured: { package: string; options?: Record<string, any> }[] = []
|
const configured: { package: string; options?: Record<string, any> }[] = []
|
||||||
|
|
||||||
@@ -86,14 +80,12 @@ export const Plugin = define({
|
|||||||
const mod = yield* Effect.promise(() => import(entrypoint))
|
const mod = yield* Effect.promise(() => import(entrypoint))
|
||||||
const value = (yield* Schema.decodeUnknownEffect(PluginModule)(mod)).default
|
const value = (yield* Schema.decodeUnknownEffect(PluginModule)(mod)).default
|
||||||
const plugin = "effect" in value ? value : PluginPromise.fromPromise(value)
|
const plugin = "effect" in value ? value : PluginPromise.fromPromise(value)
|
||||||
loaded.push({
|
yield* ctx.plugin.add({
|
||||||
id: plugin.id,
|
id: plugin.id,
|
||||||
effect: (host) => plugin.effect({ ...host, options: ref.options ?? {} }),
|
effect: (host) => plugin.effect({ ...host, options: ref.options ?? {} }),
|
||||||
})
|
})
|
||||||
}).pipe(Effect.ignoreCause)
|
}).pipe(Effect.ignoreCause)
|
||||||
}
|
}
|
||||||
|
|
||||||
yield* ctx.plugin.reload()
|
|
||||||
}).pipe(Effect.forkScoped({ startImmediately: true }))
|
}).pipe(Effect.forkScoped({ startImmediately: true }))
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
+23
-31
@@ -1,7 +1,7 @@
|
|||||||
export * as PluginV2 from "./plugin"
|
export * as PluginV2 from "./plugin"
|
||||||
|
|
||||||
import { Context, Effect, Exit, Layer, Schema, Scope } from "effect"
|
import { Context, Effect, Exit, Layer, Schema, Scope } from "effect"
|
||||||
import type { Plugin, PluginDraft } from "@opencode-ai/plugin/v2/effect"
|
import type { Plugin } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { AgentV2 } from "./agent"
|
import { AgentV2 } from "./agent"
|
||||||
import { AISDK } from "./aisdk"
|
import { AISDK } from "./aisdk"
|
||||||
import { Catalog } from "./catalog"
|
import { Catalog } from "./catalog"
|
||||||
@@ -27,8 +27,8 @@ export const Event = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Interface {
|
export interface Interface {
|
||||||
readonly transform: State.Transform<PluginDraft>
|
readonly add: (id: ID, effect: Plugin["effect"]) => Effect.Effect<void>
|
||||||
readonly reload: State.Reload
|
readonly remove: (id: ID) => Effect.Effect<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Plugin") {}
|
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Plugin") {}
|
||||||
@@ -40,17 +40,23 @@ export const layer = Layer.effect(
|
|||||||
const locks = KeyedMutex.makeUnsafe<ID>()
|
const locks = KeyedMutex.makeUnsafe<ID>()
|
||||||
const scope = yield* Scope.make()
|
const scope = yield* Scope.make()
|
||||||
const active = new Map<ID, Scope.Closeable>()
|
const active = new Map<ID, Scope.Closeable>()
|
||||||
|
const loading = new Set<ID>()
|
||||||
let host: Parameters<Plugin["effect"]>[0]
|
let host: Parameters<Plugin["effect"]>[0]
|
||||||
|
|
||||||
const attach = Effect.fn("Plugin.attach")(function* (plugin: Plugin, host: Parameters<Plugin["effect"]>[0]) {
|
const add = Effect.fn("Plugin.add")(function* (id: ID, effect: Plugin["effect"]) {
|
||||||
const id = ID.make(plugin.id)
|
if (loading.has(id)) return yield* Effect.die(`Plugin load cycle detected for ${id}`)
|
||||||
|
|
||||||
yield* locks.withLock(id)(
|
yield* locks.withLock(id)(
|
||||||
|
Effect.sync(() => loading.add(id)).pipe(
|
||||||
|
Effect.andThen(
|
||||||
|
State.batch(
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const existing = active.get(id)
|
const existing = active.get(id)
|
||||||
|
active.delete(id)
|
||||||
if (existing) yield* Scope.close(existing, Exit.void).pipe(Effect.ignore)
|
if (existing) yield* Scope.close(existing, Exit.void).pipe(Effect.ignore)
|
||||||
|
|
||||||
const child = yield* Scope.fork(scope)
|
const child = yield* Scope.fork(scope)
|
||||||
yield* plugin.effect(host).pipe(
|
yield* effect(host).pipe(
|
||||||
Scope.provide(child),
|
Scope.provide(child),
|
||||||
Effect.withSpan("Plugin.load", { attributes: { "plugin.id": id } }),
|
Effect.withSpan("Plugin.load", { attributes: { "plugin.id": id } }),
|
||||||
Effect.onExit((exit) => (Exit.isFailure(exit) ? Scope.close(child, exit) : Effect.void)),
|
Effect.onExit((exit) => (Exit.isFailure(exit) ? Scope.close(child, exit) : Effect.void)),
|
||||||
@@ -58,39 +64,25 @@ export const layer = Layer.effect(
|
|||||||
active.set(id, child)
|
active.set(id, child)
|
||||||
yield* events.publish(Event.Added, { id })
|
yield* events.publish(Event.Added, { id })
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Effect.ensuring(Effect.sync(() => loading.delete(id))),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const detach = Effect.fn("Plugin.detach")(function* (id: ID) {
|
const remove = Effect.fn("Plugin.remove")(function* (id: ID) {
|
||||||
|
if (loading.has(id)) return yield* Effect.die(`Cannot remove plugin ${id} while it is loading`)
|
||||||
|
|
||||||
yield* locks.withLock(id)(
|
yield* locks.withLock(id)(
|
||||||
|
State.batch(
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const current = active.get(id)
|
const current = active.get(id)
|
||||||
active.delete(id)
|
active.delete(id)
|
||||||
if (current) yield* Scope.close(current, Exit.void).pipe(Effect.ignore)
|
if (current) yield* Scope.close(current, Exit.void).pipe(Effect.ignore)
|
||||||
}),
|
}),
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const state = State.create<Map<ID, Plugin>, PluginDraft>({
|
|
||||||
initial: () => new Map(),
|
|
||||||
draft: (draft) => ({
|
|
||||||
list: () => Array.from(draft.values()),
|
|
||||||
add: (plugin) => draft.set(ID.make(plugin.id), plugin),
|
|
||||||
remove: (id) => draft.delete(ID.make(id)),
|
|
||||||
}),
|
|
||||||
finalize: (draft) =>
|
|
||||||
State.batch(
|
|
||||||
Effect.gen(function* () {
|
|
||||||
const desired = new Set<ID>()
|
|
||||||
for (const plugin of draft.list()) desired.add(ID.make(plugin.id))
|
|
||||||
|
|
||||||
for (const id of active.keys()) {
|
|
||||||
if (!desired.has(id)) yield* detach(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const plugin of draft.list()) yield* attach(plugin, host)
|
|
||||||
}).pipe(Effect.withSpan("Plugin.reconcile")),
|
|
||||||
),
|
),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
yield* Effect.addFinalizer((exit) =>
|
yield* Effect.addFinalizer((exit) =>
|
||||||
@@ -101,8 +93,8 @@ export const layer = Layer.effect(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const service = Service.of({
|
const service = Service.of({
|
||||||
transform: state.transform,
|
add,
|
||||||
reload: state.reload,
|
remove,
|
||||||
})
|
})
|
||||||
host = yield* PluginHost.make(service)
|
host = yield* PluginHost.make(service)
|
||||||
return service
|
return service
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Catalog } from "../catalog"
|
|||||||
import { CommandV2 } from "../command"
|
import { CommandV2 } from "../command"
|
||||||
import { Integration } from "../integration"
|
import { Integration } from "../integration"
|
||||||
import { ModelV2 } from "../model"
|
import { ModelV2 } from "../model"
|
||||||
import type { PluginV2 } from "../plugin"
|
import { PluginV2 } from "../plugin"
|
||||||
import { ProviderV2 } from "../provider"
|
import { ProviderV2 } from "../provider"
|
||||||
import { Reference } from "../reference"
|
import { Reference } from "../reference"
|
||||||
import { SkillV2 } from "../skill"
|
import { SkillV2 } from "../skill"
|
||||||
@@ -126,8 +126,8 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
plugin: {
|
plugin: {
|
||||||
reload: plugin.reload,
|
add: (input) => plugin.add(PluginV2.ID.make(input.id), input.effect),
|
||||||
transform: plugin.transform,
|
remove: (id) => plugin.remove(PluginV2.ID.make(id)),
|
||||||
},
|
},
|
||||||
reference: {
|
reference: {
|
||||||
reload: reference.reload,
|
reload: reference.reload,
|
||||||
|
|||||||
@@ -23,10 +23,8 @@ import { Npm } from "../npm"
|
|||||||
import { PluginV2 } from "../plugin"
|
import { PluginV2 } from "../plugin"
|
||||||
import { Reference } from "../reference"
|
import { Reference } from "../reference"
|
||||||
import { SkillV2 } from "../skill"
|
import { SkillV2 } from "../skill"
|
||||||
import { State } from "../state"
|
|
||||||
import { AgentPlugin } from "./agent"
|
import { AgentPlugin } from "./agent"
|
||||||
import { CommandPlugin } from "./command"
|
import { CommandPlugin } from "./command"
|
||||||
import { PluginHost } from "./host"
|
|
||||||
import { ModelsDevPlugin } from "./models-dev"
|
import { ModelsDevPlugin } from "./models-dev"
|
||||||
import { ProviderPlugins } from "./provider"
|
import { ProviderPlugins } from "./provider"
|
||||||
import { SkillPlugin } from "./skill"
|
import { SkillPlugin } from "./skill"
|
||||||
@@ -73,9 +71,8 @@ export const locationLayer = Layer.effectDiscard(
|
|||||||
const global = yield* Global.Service
|
const global = yield* Global.Service
|
||||||
const skill = yield* SkillV2.Service
|
const skill = yield* SkillV2.Service
|
||||||
const reference = yield* Reference.Service
|
const reference = yield* Reference.Service
|
||||||
const host = yield* PluginHost.make(plugin)
|
const add = <R>(input: Plugin<R>) => {
|
||||||
|
const loaded = {
|
||||||
const wrap = <R>(input: Plugin<R>) => ({
|
|
||||||
id: input.id,
|
id: input.id,
|
||||||
effect: (context: PluginContext) =>
|
effect: (context: PluginContext) =>
|
||||||
input
|
input
|
||||||
@@ -96,26 +93,23 @@ export const locationLayer = Layer.effectDiscard(
|
|||||||
Effect.provideService(SkillV2.Service, skill),
|
Effect.provideService(SkillV2.Service, skill),
|
||||||
Effect.provideService(Reference.Service, reference),
|
Effect.provideService(Reference.Service, reference),
|
||||||
),
|
),
|
||||||
})
|
}
|
||||||
|
return plugin.add(PluginV2.ID.make(loaded.id), loaded.effect)
|
||||||
|
}
|
||||||
|
|
||||||
yield* State.batch(
|
yield* Effect.gen(function* () {
|
||||||
Effect.gen(function* () {
|
yield* add(AgentPlugin.Plugin)
|
||||||
yield* plugin.transform((plugins) => {
|
yield* add(CommandPlugin.Plugin)
|
||||||
plugins.add(wrap(AgentPlugin.Plugin))
|
yield* add(SkillPlugin.Plugin)
|
||||||
plugins.add(wrap(CommandPlugin.Plugin))
|
yield* add(ModelsDevPlugin)
|
||||||
plugins.add(wrap(SkillPlugin.Plugin))
|
yield* add(ConfigProviderPlugin.Plugin)
|
||||||
plugins.add(wrap(ModelsDevPlugin))
|
yield* add(ConfigAgentPlugin.Plugin)
|
||||||
plugins.add(wrap(ConfigProviderPlugin.Plugin))
|
yield* add(ConfigCommandPlugin.Plugin)
|
||||||
plugins.add(wrap(ConfigAgentPlugin.Plugin))
|
yield* add(ConfigSkillPlugin.Plugin)
|
||||||
plugins.add(wrap(ConfigCommandPlugin.Plugin))
|
yield* add(ConfigReferencePlugin.Plugin)
|
||||||
plugins.add(wrap(ConfigSkillPlugin.Plugin))
|
for (const item of ProviderPlugins) yield* add(item)
|
||||||
plugins.add(wrap(ConfigReferencePlugin.Plugin))
|
yield* add(ConfigExternalPlugin.Plugin)
|
||||||
for (const item of ProviderPlugins) plugins.add(wrap(item))
|
}).pipe(Effect.withSpan("PluginInternal.boot"), Effect.forkScoped({ startImmediately: true }))
|
||||||
})
|
|
||||||
|
|
||||||
yield* wrap(ConfigExternalPlugin.Plugin).effect(host)
|
|
||||||
}),
|
|
||||||
).pipe(Effect.withSpan("PluginInternal.boot"), Effect.forkScoped({ startImmediately: true }))
|
|
||||||
}),
|
}),
|
||||||
).pipe(
|
).pipe(
|
||||||
Layer.provideMerge(PluginV2.locationLayer),
|
Layer.provideMerge(PluginV2.locationLayer),
|
||||||
|
|||||||
@@ -67,8 +67,11 @@ export function fromPromise(plugin: Plugin) {
|
|||||||
reload: () => run(host.integration.reload()),
|
reload: () => run(host.integration.reload()),
|
||||||
},
|
},
|
||||||
plugin: {
|
plugin: {
|
||||||
transform: transform(host.plugin),
|
add: (input) => {
|
||||||
reload: () => run(host.plugin.reload()),
|
const child = fromPromise(input)
|
||||||
|
return run(host.plugin.add(child))
|
||||||
|
},
|
||||||
|
remove: (id) => run(host.plugin.remove(id)),
|
||||||
},
|
},
|
||||||
reference: {
|
reference: {
|
||||||
transform: transform(host.reference),
|
transform: transform(host.reference),
|
||||||
|
|||||||
@@ -197,9 +197,7 @@ describe("LocationServiceMap", () => {
|
|||||||
Effect.flatMap((dir) =>
|
Effect.flatMap((dir) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugins = yield* PluginV2.Service
|
const plugins = yield* PluginV2.Service
|
||||||
yield* plugins.transform((draft) =>
|
const reviewer = define({
|
||||||
draft.add(
|
|
||||||
define({
|
|
||||||
id: "reviewer",
|
id: "reviewer",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.agent
|
ctx.agent
|
||||||
@@ -210,9 +208,8 @@ describe("LocationServiceMap", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.pipe(Effect.asVoid),
|
.pipe(Effect.asVoid),
|
||||||
}),
|
})
|
||||||
),
|
yield* plugins.add(PluginV2.ID.make(reviewer.id), reviewer.effect)
|
||||||
)
|
|
||||||
|
|
||||||
expect(yield* (yield* AgentV2.Service).get(AgentV2.ID.make("reviewer"))).toMatchObject({
|
expect(yield* (yield* AgentV2.Service).get(AgentV2.ID.make("reviewer"))).toMatchObject({
|
||||||
description: "Reviews code",
|
description: "Reviews code",
|
||||||
|
|||||||
@@ -9,14 +9,13 @@ import { PluginTestLayer } from "./plugin/fixture"
|
|||||||
const it = testEffect(PluginTestLayer)
|
const it = testEffect(PluginTestLayer)
|
||||||
|
|
||||||
describe("PluginV2", () => {
|
describe("PluginV2", () => {
|
||||||
it.effect("reconciles transformed plugins", () =>
|
it.effect("adds, replaces, and removes plugins", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugins = yield* PluginV2.Service
|
const plugins = yield* PluginV2.Service
|
||||||
const agents = yield* AgentV2.Service
|
const agents = yield* AgentV2.Service
|
||||||
let description = "first"
|
let description = "first"
|
||||||
|
|
||||||
const registration = yield* plugins.transform((draft) => {
|
const managed = () =>
|
||||||
draft.add(
|
|
||||||
define({
|
define({
|
||||||
id: "managed",
|
id: "managed",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
@@ -27,17 +26,17 @@ describe("PluginV2", () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.pipe(Effect.asVoid),
|
.pipe(Effect.asVoid),
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
yield* plugins.add(PluginV2.ID.make("managed"), managed().effect)
|
||||||
|
|
||||||
expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("first")
|
expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("first")
|
||||||
|
|
||||||
description = "second"
|
description = "second"
|
||||||
yield* plugins.reload()
|
yield* plugins.add(PluginV2.ID.make("managed"), managed().effect)
|
||||||
expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("second")
|
expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("second")
|
||||||
|
|
||||||
yield* registration.dispose
|
yield* plugins.remove(PluginV2.ID.make("managed"))
|
||||||
expect(yield* agents.get(AgentV2.ID.make("configured"))).toBeUndefined()
|
expect(yield* agents.get(AgentV2.ID.make("configured"))).toBeUndefined()
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ export function host(overrides: Overrides = {}): PluginContext {
|
|||||||
reload: () => Effect.die("unused integration.reload"),
|
reload: () => Effect.die("unused integration.reload"),
|
||||||
},
|
},
|
||||||
plugin: overrides.plugin ?? {
|
plugin: overrides.plugin ?? {
|
||||||
transform: () => Effect.die("unused plugin.transform"),
|
add: () => Effect.die("unused plugin.add"),
|
||||||
reload: () => Effect.die("unused plugin.reload"),
|
remove: () => Effect.die("unused plugin.remove"),
|
||||||
},
|
},
|
||||||
reference: overrides.reference ?? {
|
reference: overrides.reference ?? {
|
||||||
transform: () => Effect.die("unused reference.transform"),
|
transform: () => Effect.die("unused reference.transform"),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { AISDKHooks } from "./aisdk.js"
|
|||||||
import type { CatalogHooks } from "./catalog.js"
|
import type { CatalogHooks } from "./catalog.js"
|
||||||
import type { CommandHooks } from "./command.js"
|
import type { CommandHooks } from "./command.js"
|
||||||
import type { IntegrationHooks } from "./integration.js"
|
import type { IntegrationHooks } from "./integration.js"
|
||||||
import type { PluginHooks } from "./plugin.js"
|
import type { PluginDomain } from "./plugin.js"
|
||||||
import type { ReferenceHooks } from "./reference.js"
|
import type { ReferenceHooks } from "./reference.js"
|
||||||
import type { SkillHooks } from "./skill.js"
|
import type { SkillHooks } from "./skill.js"
|
||||||
import type { Reload } from "./registration.js"
|
import type { Reload } from "./registration.js"
|
||||||
@@ -16,7 +16,7 @@ export interface PluginContext {
|
|||||||
readonly catalog: CatalogHooks & Reload
|
readonly catalog: CatalogHooks & Reload
|
||||||
readonly command: CommandHooks & Reload
|
readonly command: CommandHooks & Reload
|
||||||
readonly integration: IntegrationHooks & Reload
|
readonly integration: IntegrationHooks & Reload
|
||||||
readonly plugin: PluginHooks & Reload
|
readonly plugin: PluginDomain
|
||||||
readonly reference: ReferenceHooks & Reload
|
readonly reference: ReferenceHooks & Reload
|
||||||
readonly skill: SkillHooks & Reload
|
readonly skill: SkillHooks & Reload
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export type { PluginContext } from "./context.js"
|
export type { PluginContext } from "./context.js"
|
||||||
export { define } from "./plugin.js"
|
export { define } from "./plugin.js"
|
||||||
export type { Plugin, PluginDraft } from "./plugin.js"
|
export type { Plugin } from "./plugin.js"
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { Effect, Scope } from "effect"
|
import type { Effect, Scope } from "effect"
|
||||||
import type { PluginContext } from "./context.js"
|
import type { PluginContext } from "./context.js"
|
||||||
import type { PluginOptions } from "../options.js"
|
|
||||||
import type { Hooks } from "./registration.js"
|
|
||||||
|
|
||||||
export interface Plugin {
|
export interface Plugin {
|
||||||
readonly id: string
|
readonly id: string
|
||||||
@@ -12,17 +10,7 @@ export function define(plugin: Plugin) {
|
|||||||
return plugin
|
return plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginRef {
|
export interface PluginDomain {
|
||||||
readonly package: string
|
readonly add: (plugin: Plugin) => Effect.Effect<void>
|
||||||
readonly options?: PluginOptions
|
readonly remove: (id: string) => Effect.Effect<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginDraft {
|
|
||||||
list(): readonly Plugin[]
|
|
||||||
add(plugin: Plugin): void
|
|
||||||
remove(id: string): void
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PluginHooks = Hooks<{
|
|
||||||
transform: PluginDraft
|
|
||||||
}>
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { AISDKHooks } from "./aisdk.js"
|
|||||||
import type { CatalogHooks } from "./catalog.js"
|
import type { CatalogHooks } from "./catalog.js"
|
||||||
import type { CommandHooks } from "./command.js"
|
import type { CommandHooks } from "./command.js"
|
||||||
import type { IntegrationHooks } from "./integration.js"
|
import type { IntegrationHooks } from "./integration.js"
|
||||||
import type { PluginHooks } from "./plugin.js"
|
import type { PluginDomain } from "./plugin.js"
|
||||||
import type { ReferenceHooks } from "./reference.js"
|
import type { ReferenceHooks } from "./reference.js"
|
||||||
import type { SkillHooks } from "./skill.js"
|
import type { SkillHooks } from "./skill.js"
|
||||||
import type { Reload } from "./registration.js"
|
import type { Reload } from "./registration.js"
|
||||||
@@ -16,7 +16,7 @@ export interface PluginContext {
|
|||||||
readonly catalog: CatalogHooks & Reload
|
readonly catalog: CatalogHooks & Reload
|
||||||
readonly command: CommandHooks & Reload
|
readonly command: CommandHooks & Reload
|
||||||
readonly integration: IntegrationHooks & Reload
|
readonly integration: IntegrationHooks & Reload
|
||||||
readonly plugin: PluginHooks & Reload
|
readonly plugin: PluginDomain
|
||||||
readonly reference: ReferenceHooks & Reload
|
readonly reference: ReferenceHooks & Reload
|
||||||
readonly skill: SkillHooks & Reload
|
readonly skill: SkillHooks & Reload
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export type { PluginContext } from "./context.js"
|
export type { PluginContext } from "./context.js"
|
||||||
export type { PluginOptions } from "../options.js"
|
export type { PluginOptions } from "../options.js"
|
||||||
export { define } from "./plugin.js"
|
export { define } from "./plugin.js"
|
||||||
export type { Plugin, PluginDraft, PluginHooks, PluginRef } from "./plugin.js"
|
export type { Plugin, PluginDomain } from "./plugin.js"
|
||||||
export type { Registration, Reload } from "./registration.js"
|
export type { Registration, Reload } from "./registration.js"
|
||||||
export type { AgentDraft, AgentHooks } from "./agent.js"
|
export type { AgentDraft, AgentHooks } from "./agent.js"
|
||||||
export type { AISDKHooks } from "./aisdk.js"
|
export type { AISDKHooks } from "./aisdk.js"
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import type { PluginContext } from "./context.js"
|
import type { PluginContext } from "./context.js"
|
||||||
import type { PluginDraft, PluginRef } from "../effect/plugin.js"
|
|
||||||
import type { Hooks } from "./registration.js"
|
|
||||||
|
|
||||||
export interface Plugin {
|
export interface Plugin {
|
||||||
readonly id: string
|
readonly id: string
|
||||||
@@ -11,8 +9,7 @@ export function define(plugin: Plugin) {
|
|||||||
return plugin
|
return plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { PluginDraft, PluginRef }
|
export interface PluginDomain {
|
||||||
|
readonly add: (plugin: Plugin) => Promise<void>
|
||||||
export type PluginHooks = Hooks<{
|
readonly remove: (id: string) => Promise<void>
|
||||||
transform: PluginDraft
|
}
|
||||||
}>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user