@neurocode-ai/plugin 1.18.14 → 1.18.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ import type { PluginOptions } from "../options.js"
2
+ import type { AgentHooks } from "./agent.js"
3
+ import type { AISDKHooks } from "./aisdk.js"
4
+ import type { CatalogHooks } from "./catalog.js"
5
+ import type { CommandHooks } from "./command.js"
6
+ import type { IntegrationHooks } from "./integration.js"
7
+ import type { PluginDomain } from "./plugin.js"
8
+ import type { ReferenceHooks } from "./reference.js"
9
+ import type { SkillHooks } from "./skill.js"
10
+ import type { Reload } from "./registration.js"
11
+
12
+ export interface PluginContext {
13
+ readonly options: PluginOptions
14
+ readonly agent: AgentHooks & Reload
15
+ readonly aisdk: AISDKHooks
16
+ readonly catalog: CatalogHooks & Reload
17
+ readonly command: CommandHooks & Reload
18
+ readonly integration: IntegrationHooks & Reload
19
+ readonly plugin: PluginDomain
20
+ readonly reference: ReferenceHooks & Reload
21
+ readonly skill: SkillHooks & Reload
22
+ }
@@ -0,0 +1,10 @@
1
+ import type { Event as SDKEvent } from "@neurocode-ai/sdk/v2/types"
2
+ import type { Stream } from "effect"
3
+
4
+ export type EventMap = {
5
+ [Item in SDKEvent as Item["type"]]: Item
6
+ }
7
+
8
+ export interface Event {
9
+ subscribe<Type extends keyof EventMap>(type: Type): Stream.Stream<EventMap[Type]>
10
+ }
@@ -0,0 +1,17 @@
1
+ import type { FileSystemEntry } from "@neurocode-ai/sdk/v2/types"
2
+ import type { Effect } from "effect"
3
+
4
+ export interface FileSystem {
5
+ read(input: { readonly path: string }): Effect.Effect<{ readonly content: Uint8Array; readonly mime: string }>
6
+ list(input?: { readonly path?: string }): Effect.Effect<FileSystemEntry[]>
7
+ find(input: {
8
+ readonly query: string
9
+ readonly type?: "file" | "directory"
10
+ readonly limit?: number
11
+ }): Effect.Effect<FileSystemEntry[]>
12
+ glob(input: {
13
+ readonly pattern: string
14
+ readonly path?: string
15
+ readonly limit?: number
16
+ }): Effect.Effect<readonly FileSystemEntry[]>
17
+ }
@@ -0,0 +1,3 @@
1
+ export type { PluginContext } from "./context.js"
2
+ export { define } from "./plugin.js"
3
+ export type { Plugin } from "./plugin.js"
@@ -0,0 +1,63 @@
1
+ import type {
2
+ ConnectionInfo,
3
+ CredentialOAuth,
4
+ CredentialValue,
5
+ IntegrationEnvMethod,
6
+ IntegrationInputs,
7
+ IntegrationKeyMethod,
8
+ IntegrationMethod,
9
+ IntegrationOAuthMethod,
10
+ IntegrationRef,
11
+ } from "@neurocode-ai/sdk/v2/types"
12
+ import type { Effect, Scope } from "effect"
13
+ import type { Hooks } from "./registration.js"
14
+
15
+ export type IntegrationOAuthAuthorization = {
16
+ readonly url: string
17
+ readonly instructions: string
18
+ } & (
19
+ | {
20
+ readonly mode: "auto"
21
+ readonly callback: Effect.Effect<CredentialOAuth, unknown>
22
+ }
23
+ | {
24
+ readonly mode: "code"
25
+ readonly callback: (code: string) => Effect.Effect<CredentialOAuth, unknown>
26
+ }
27
+ )
28
+ export type IntegrationOAuthMethodRegistration = {
29
+ readonly integrationID: string
30
+ readonly method: IntegrationOAuthMethod
31
+ readonly authorize: (inputs: IntegrationInputs) => Effect.Effect<IntegrationOAuthAuthorization, unknown, Scope.Scope>
32
+ readonly refresh?: (credential: CredentialOAuth) => Effect.Effect<CredentialOAuth, unknown>
33
+ readonly label?: (credential: CredentialOAuth) => string | undefined
34
+ }
35
+ export type IntegrationMethodRegistration =
36
+ | IntegrationOAuthMethodRegistration
37
+ | {
38
+ readonly integrationID: string
39
+ readonly method: IntegrationKeyMethod
40
+ }
41
+ | {
42
+ readonly integrationID: string
43
+ readonly method: IntegrationEnvMethod
44
+ }
45
+
46
+ export interface IntegrationDraft {
47
+ list(): readonly IntegrationRef[]
48
+ get(id: string): IntegrationRef | undefined
49
+ update(id: string, update: (integration: IntegrationRef) => void): void
50
+ remove(id: string): void
51
+ readonly method: {
52
+ list(integrationID: string): readonly IntegrationMethod[]
53
+ update(input: IntegrationMethodRegistration): void
54
+ remove(integrationID: string, method: IntegrationMethod): void
55
+ }
56
+ }
57
+
58
+ export interface IntegrationHooks extends Hooks<{ transform: IntegrationDraft }> {
59
+ readonly connection: {
60
+ readonly active: (integrationID: string) => Effect.Effect<ConnectionInfo | undefined>
61
+ readonly resolve: (connection: ConnectionInfo) => Effect.Effect<CredentialValue | undefined, unknown>
62
+ }
63
+ }
@@ -0,0 +1,6 @@
1
+ export interface Location {
2
+ readonly directory: string
3
+ readonly project: {
4
+ readonly directory: string
5
+ }
6
+ }
@@ -0,0 +1,11 @@
1
+ import type { Effect } from "effect"
2
+
3
+ export interface Npm {
4
+ add(pkg: string): Effect.Effect<
5
+ {
6
+ readonly directory: string
7
+ readonly entrypoint?: string
8
+ },
9
+ unknown
10
+ >
11
+ }
@@ -0,0 +1,8 @@
1
+ export interface Path {
2
+ readonly home: string
3
+ readonly data: string
4
+ readonly cache: string
5
+ readonly config: string
6
+ readonly state: string
7
+ readonly temp: string
8
+ }
@@ -0,0 +1,16 @@
1
+ import type { Effect, Scope } from "effect"
2
+ import type { PluginContext } from "./context.js"
3
+
4
+ export interface Plugin<R = Scope.Scope> {
5
+ readonly id: string
6
+ readonly effect: (context: PluginContext) => Effect.Effect<void, never, R>
7
+ }
8
+
9
+ export function define<R = Scope.Scope>(plugin: Plugin<R>) {
10
+ return plugin
11
+ }
12
+
13
+ export interface PluginDomain {
14
+ readonly add: (plugin: Plugin) => Effect.Effect<void>
15
+ readonly remove: (id: string) => Effect.Effect<void>
16
+ }
@@ -0,0 +1,12 @@
1
+ import type { ReferenceGitSource, ReferenceLocalSource } from "@neurocode-ai/sdk/v2/types"
2
+ import type { Hooks } from "./registration.js"
3
+
4
+ export interface ReferenceDraft {
5
+ add(name: string, source: ReferenceLocalSource | ReferenceGitSource): void
6
+ remove(name: string): void
7
+ list(): readonly (readonly [string, ReferenceLocalSource | ReferenceGitSource])[]
8
+ }
9
+
10
+ export type ReferenceHooks = Hooks<{
11
+ transform: ReferenceDraft
12
+ }>
@@ -0,0 +1,15 @@
1
+ import type { Effect, Scope } from "effect"
2
+
3
+ export interface Registration {
4
+ readonly dispose: Effect.Effect<void>
5
+ }
6
+
7
+ export interface Reload {
8
+ readonly reload: () => Effect.Effect<void>
9
+ }
10
+
11
+ export type Hooks<Spec> = {
12
+ readonly [Name in keyof Spec]: (
13
+ callback: (input: Spec[Name]) => Effect.Effect<void> | void,
14
+ ) => Effect.Effect<Registration, never, Scope.Scope>
15
+ }
@@ -0,0 +1,11 @@
1
+ import type { SkillV2Source } from "@neurocode-ai/sdk/v2/types"
2
+ import type { Hooks } from "./registration.js"
3
+
4
+ export interface SkillDraft {
5
+ source(source: SkillV2Source): void
6
+ list(): readonly SkillV2Source[]
7
+ }
8
+
9
+ export type SkillHooks = Hooks<{
10
+ transform: SkillDraft
11
+ }>
@@ -0,0 +1 @@
1
+ export type PluginOptions = Readonly<Record<string, any>>
@@ -0,0 +1,103 @@
1
+ # OpenCode V2 Promise Plugin API
2
+
3
+ The Promise plugin API is the async/await equivalent of `@opencode-ai/plugin/v2/effect`. It grants plugins the same two in-process capabilities:
4
+
5
+ - `hook` installs behavior at an OpenCode extension point.
6
+ - `reload` reruns every transform hook for a stateful domain.
7
+
8
+ The only difference from the Effect API is the async boundary: hook callbacks, hook registration, `reload`, and `Registration.dispose` use Promises instead of Effects.
9
+
10
+ ## Defining A Plugin
11
+
12
+ ```ts
13
+ import { define } from "@opencode-ai/plugin/v2/promise"
14
+
15
+ export const Plugin = define({
16
+ id: "example",
17
+ setup: async (ctx) => {
18
+ await ctx.catalog.transform((catalog) => {
19
+ catalog.provider.update("example", (provider) => {
20
+ provider.name = "Example"
21
+ })
22
+ })
23
+ },
24
+ })
25
+ ```
26
+
27
+ Plugin setup registers hooks imperatively. It does not return a hook object.
28
+
29
+ Configuration supplied for the plugin is available as `ctx.options`.
30
+
31
+ A registration may be removed early through `dispose`:
32
+
33
+ ```ts
34
+ const registration = await ctx.catalog.transform(applyCatalog)
35
+ await registration.dispose()
36
+ ```
37
+
38
+ ## Transform Hooks
39
+
40
+ Transform hooks contribute to stateful domains. The draft editor is synchronous; the callback may be `async` when it needs to await other work:
41
+
42
+ ```ts
43
+ await ctx.agent.transform((agent) => {
44
+ agent.update("reviewer", (item) => {
45
+ item.description = "Reviews code for regressions"
46
+ item.mode = "subagent"
47
+ })
48
+ })
49
+ ```
50
+
51
+ Available transform hooks are namespaced by domain:
52
+
53
+ ```ts
54
+ ctx.agent.transform
55
+ ctx.catalog.transform
56
+ ctx.command.transform
57
+ ctx.integration.transform
58
+ ctx.reference.transform
59
+ ctx.skill.transform
60
+ ```
61
+
62
+ ## Runtime Hooks
63
+
64
+ Runtime hooks intercept live operations:
65
+
66
+ ```ts
67
+ await ctx.aisdk.sdk(async (event) => {
68
+ if (event.package !== "@ai-sdk/xai") return
69
+ const mod = await import("@ai-sdk/xai")
70
+ event.sdk = mod.createXai(event.options)
71
+ })
72
+
73
+ await ctx.aisdk.language((event) => {
74
+ if (event.model.providerID !== "xai") return
75
+ event.language = event.sdk.responses(event.model.api.id)
76
+ })
77
+ ```
78
+
79
+ ## Reloading A Domain
80
+
81
+ When data captured by a transform changes, reload the affected domain:
82
+
83
+ ```ts
84
+ let data = await loadCatalog()
85
+
86
+ await ctx.catalog.transform((catalog) => {
87
+ applyCatalog(data, catalog)
88
+ })
89
+
90
+ data = await loadCatalog()
91
+ await ctx.catalog.reload()
92
+ ```
93
+
94
+ Available reload operations are:
95
+
96
+ ```ts
97
+ ctx.agent.reload()
98
+ ctx.catalog.reload()
99
+ ctx.command.reload()
100
+ ctx.integration.reload()
101
+ ctx.reference.reload()
102
+ ctx.skill.reload()
103
+ ```
@@ -0,0 +1,8 @@
1
+ import type { AgentDraft } from "../effect/agent.js"
2
+ import type { Hooks } from "./registration.js"
3
+
4
+ export type { AgentDraft }
5
+
6
+ export type AgentHooks = Hooks<{
7
+ transform: AgentDraft
8
+ }>
@@ -0,0 +1,18 @@
1
+ import type { LanguageModelV3 } from "@ai-sdk/provider"
2
+ import type { ModelV2Info } from "@neurocode-ai/sdk/v2/types"
3
+ import type { Hooks } from "./registration.js"
4
+
5
+ export type AISDKHooks = Hooks<{
6
+ sdk: {
7
+ readonly model: ModelV2Info
8
+ readonly package: string
9
+ readonly options: Record<string, any>
10
+ sdk?: any
11
+ }
12
+ language: {
13
+ readonly model: ModelV2Info
14
+ readonly sdk: any
15
+ readonly options: Record<string, any>
16
+ language?: LanguageModelV3
17
+ }
18
+ }>
@@ -0,0 +1,8 @@
1
+ import type { CatalogDraft, CatalogProviderRecord } from "../effect/catalog.js"
2
+ import type { Hooks } from "./registration.js"
3
+
4
+ export type { CatalogDraft, CatalogProviderRecord }
5
+
6
+ export type CatalogHooks = Hooks<{
7
+ transform: CatalogDraft
8
+ }>
@@ -0,0 +1,8 @@
1
+ import type { CommandDraft } from "../effect/command.js"
2
+ import type { Hooks } from "./registration.js"
3
+
4
+ export type { CommandDraft }
5
+
6
+ export type CommandHooks = Hooks<{
7
+ transform: CommandDraft
8
+ }>
@@ -0,0 +1,22 @@
1
+ import type { PluginOptions } from "../options.js"
2
+ import type { AgentHooks } from "./agent.js"
3
+ import type { AISDKHooks } from "./aisdk.js"
4
+ import type { CatalogHooks } from "./catalog.js"
5
+ import type { CommandHooks } from "./command.js"
6
+ import type { IntegrationHooks } from "./integration.js"
7
+ import type { PluginDomain } from "./plugin.js"
8
+ import type { ReferenceHooks } from "./reference.js"
9
+ import type { SkillHooks } from "./skill.js"
10
+ import type { Reload } from "./registration.js"
11
+
12
+ export interface PluginContext {
13
+ readonly options: PluginOptions
14
+ readonly agent: AgentHooks & Reload
15
+ readonly aisdk: AISDKHooks
16
+ readonly catalog: CatalogHooks & Reload
17
+ readonly command: CommandHooks & Reload
18
+ readonly integration: IntegrationHooks & Reload
19
+ readonly plugin: PluginDomain
20
+ readonly reference: ReferenceHooks & Reload
21
+ readonly skill: SkillHooks & Reload
22
+ }
@@ -0,0 +1,12 @@
1
+ export type { PluginContext } from "./context.js"
2
+ export type { PluginOptions } from "../options.js"
3
+ export { define } from "./plugin.js"
4
+ export type { Plugin, PluginDomain } from "./plugin.js"
5
+ export type { Registration, Reload } from "./registration.js"
6
+ export type { AgentDraft, AgentHooks } from "./agent.js"
7
+ export type { AISDKHooks } from "./aisdk.js"
8
+ export type { CatalogDraft, CatalogHooks, CatalogProviderRecord } from "./catalog.js"
9
+ export type { CommandDraft, CommandHooks } from "./command.js"
10
+ export type { IntegrationDraft, IntegrationHooks, IntegrationMethodRegistration } from "./integration.js"
11
+ export type { ReferenceDraft, ReferenceHooks } from "./reference.js"
12
+ export type { SkillDraft, SkillHooks } from "./skill.js"
@@ -0,0 +1,14 @@
1
+ import type { IntegrationDraft, IntegrationMethodRegistration } from "../effect/integration.js"
2
+ import type { CredentialValue } from "@neurocode-ai/sdk/v2/types"
3
+ import type { Hooks } from "./registration.js"
4
+
5
+ export type { IntegrationDraft, IntegrationMethodRegistration }
6
+
7
+ export interface IntegrationHooks extends Hooks<{ transform: IntegrationDraft }> {
8
+ readonly connection: {
9
+ readonly active: (integrationID: string) => Promise<import("@neurocode-ai/sdk/v2/types").ConnectionInfo | undefined>
10
+ readonly resolve: (
11
+ connection: import("@neurocode-ai/sdk/v2/types").ConnectionInfo,
12
+ ) => Promise<CredentialValue | undefined>
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ import type { PluginContext } from "./context.js"
2
+
3
+ export interface Plugin {
4
+ readonly id: string
5
+ readonly setup: (context: PluginContext) => Promise<void> | void
6
+ }
7
+
8
+ export function define(plugin: Plugin) {
9
+ return plugin
10
+ }
11
+
12
+ export interface PluginDomain {
13
+ readonly add: (plugin: Plugin) => Promise<void>
14
+ readonly remove: (id: string) => Promise<void>
15
+ }
@@ -0,0 +1,8 @@
1
+ import type { ReferenceDraft } from "../effect/reference.js"
2
+ import type { Hooks } from "./registration.js"
3
+
4
+ export type { ReferenceDraft }
5
+
6
+ export type ReferenceHooks = Hooks<{
7
+ transform: ReferenceDraft
8
+ }>
@@ -0,0 +1,11 @@
1
+ export interface Registration {
2
+ readonly dispose: () => Promise<void>
3
+ }
4
+
5
+ export interface Reload {
6
+ readonly reload: () => Promise<void>
7
+ }
8
+
9
+ export type Hooks<Spec> = {
10
+ readonly [Name in keyof Spec]: (callback: (input: Spec[Name]) => Promise<void> | void) => Promise<Registration>
11
+ }
@@ -0,0 +1,8 @@
1
+ import type { SkillDraft } from "../effect/skill.js"
2
+ import type { Hooks } from "./registration.js"
3
+
4
+ export type { SkillDraft }
5
+
6
+ export type SkillHooks = Hooks<{
7
+ transform: SkillDraft
8
+ }>