@opencode-ai/plugin 0.0.0-dev-202608272023 → 0.0.0-dev-18430

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.
Files changed (159) hide show
  1. package/dist/app.d.ts +5 -0
  2. package/dist/app.js +0 -0
  3. package/dist/effect/agent.d.ts +15 -0
  4. package/dist/effect/agent.js +0 -0
  5. package/dist/{v2/promise → effect}/aisdk.d.ts +9 -6
  6. package/dist/effect/aisdk.js +0 -0
  7. package/dist/effect/catalog.d.ts +33 -0
  8. package/dist/effect/catalog.js +2 -0
  9. package/dist/effect/command.d.ts +23 -0
  10. package/dist/effect/command.js +0 -0
  11. package/dist/effect/event.d.ts +3 -0
  12. package/dist/effect/event.js +0 -0
  13. package/dist/effect/index.d.ts +15 -0
  14. package/dist/effect/index.js +14 -0
  15. package/dist/effect/integration.d.ts +80 -0
  16. package/dist/effect/integration.js +2 -0
  17. package/dist/effect/mcp.d.ts +15 -0
  18. package/dist/effect/mcp.js +0 -0
  19. package/dist/effect/permission.d.ts +21 -0
  20. package/dist/effect/permission.js +0 -0
  21. package/dist/effect/plugin.d.ts +52 -0
  22. package/dist/effect/reference.d.ts +13 -0
  23. package/dist/effect/reference.js +0 -0
  24. package/dist/effect/registration.d.ts +13 -0
  25. package/dist/effect/registration.js +0 -0
  26. package/dist/effect/session.d.ts +61 -0
  27. package/dist/effect/session.js +0 -0
  28. package/dist/effect/shell.d.ts +14 -0
  29. package/dist/effect/shell.js +0 -0
  30. package/dist/effect/skill.d.ts +14 -0
  31. package/dist/effect/skill.js +1 -0
  32. package/dist/effect/storage.d.ts +8 -0
  33. package/dist/effect/storage.js +0 -0
  34. package/dist/effect/tool.d.ts +51 -0
  35. package/dist/effect/tool.js +1 -0
  36. package/dist/effect/vcs.d.ts +39 -0
  37. package/dist/effect/vcs.js +0 -0
  38. package/dist/effect/websearch.d.ts +20 -0
  39. package/dist/effect/websearch.js +0 -0
  40. package/dist/options.js +0 -0
  41. package/dist/promise/adapter.d.ts +12 -0
  42. package/dist/promise/adapter.js +313 -0
  43. package/dist/promise/agent.d.ts +15 -0
  44. package/dist/promise/agent.js +0 -0
  45. package/dist/{v2/effect → promise}/aisdk.d.ts +9 -6
  46. package/dist/promise/aisdk.js +0 -0
  47. package/dist/promise/catalog.d.ts +33 -0
  48. package/dist/promise/catalog.js +0 -0
  49. package/dist/promise/command.d.ts +22 -0
  50. package/dist/promise/command.js +0 -0
  51. package/dist/promise/event.d.ts +3 -0
  52. package/dist/promise/event.js +0 -0
  53. package/dist/promise/index.d.ts +16 -0
  54. package/dist/promise/index.js +14 -0
  55. package/dist/promise/integration.d.ts +79 -0
  56. package/dist/promise/integration.js +2 -0
  57. package/dist/promise/mcp.d.ts +15 -0
  58. package/dist/promise/mcp.js +0 -0
  59. package/dist/promise/permission.d.ts +21 -0
  60. package/dist/promise/permission.js +0 -0
  61. package/dist/promise/plugin.d.ts +52 -0
  62. package/dist/{v2/effect → promise}/reference.d.ts +7 -5
  63. package/dist/promise/reference.js +0 -0
  64. package/dist/promise/registration.d.ts +12 -0
  65. package/dist/promise/registration.js +0 -0
  66. package/dist/promise/session.d.ts +61 -0
  67. package/dist/promise/session.js +0 -0
  68. package/dist/promise/shell.d.ts +14 -0
  69. package/dist/promise/shell.js +0 -0
  70. package/dist/promise/skill.d.ts +14 -0
  71. package/dist/promise/skill.js +0 -0
  72. package/dist/promise/storage.d.ts +8 -0
  73. package/dist/promise/storage.js +0 -0
  74. package/dist/promise/tool.d.ts +55 -0
  75. package/dist/promise/tool.js +2 -0
  76. package/dist/promise/types.d.ts +3 -0
  77. package/dist/promise/types.js +0 -0
  78. package/dist/promise/vcs.d.ts +46 -0
  79. package/dist/promise/vcs.js +0 -0
  80. package/dist/promise/websearch.d.ts +21 -0
  81. package/dist/promise/websearch.js +0 -0
  82. package/dist/storage.d.ts +14 -0
  83. package/dist/storage.js +0 -0
  84. package/dist/tui/context.d.ts +424 -0
  85. package/dist/tui/context.js +0 -0
  86. package/dist/tui/index.d.ts +2 -0
  87. package/dist/tui/index.js +2 -0
  88. package/dist/tui/plugin.d.ts +8 -0
  89. package/dist/tui/plugin.js +3 -0
  90. package/dist/tui/solid.d.ts +7 -0
  91. package/dist/tui/solid.js +16 -0
  92. package/dist/vcs.d.ts +4 -0
  93. package/dist/vcs.js +0 -0
  94. package/package.json +33 -34
  95. package/dist/example-workspace.d.ts +0 -3
  96. package/dist/example-workspace.js +0 -30
  97. package/dist/example.d.ts +0 -2
  98. package/dist/example.js +0 -16
  99. package/dist/index.d.ts +0 -322
  100. package/dist/index.js +0 -1
  101. package/dist/shell.d.ts +0 -109
  102. package/dist/shell.js +0 -1
  103. package/dist/tool.d.ts +0 -60
  104. package/dist/tool.js +0 -5
  105. package/dist/tui.d.ts +0 -510
  106. package/dist/tui.js +0 -7
  107. package/dist/v2/effect/agent.d.ts +0 -12
  108. package/dist/v2/effect/agent.js +0 -1
  109. package/dist/v2/effect/aisdk.js +0 -1
  110. package/dist/v2/effect/catalog.d.ts +0 -29
  111. package/dist/v2/effect/catalog.js +0 -1
  112. package/dist/v2/effect/command.d.ts +0 -11
  113. package/dist/v2/effect/command.js +0 -1
  114. package/dist/v2/effect/context.d.ts +0 -21
  115. package/dist/v2/effect/context.js +0 -1
  116. package/dist/v2/effect/event.d.ts +0 -8
  117. package/dist/v2/effect/event.js +0 -1
  118. package/dist/v2/effect/filesystem.d.ts +0 -23
  119. package/dist/v2/effect/filesystem.js +0 -1
  120. package/dist/v2/effect/index.d.ts +0 -3
  121. package/dist/v2/effect/index.js +0 -1
  122. package/dist/v2/effect/integration.d.ts +0 -46
  123. package/dist/v2/effect/integration.js +0 -1
  124. package/dist/v2/effect/location.d.ts +0 -6
  125. package/dist/v2/effect/location.js +0 -1
  126. package/dist/v2/effect/npm.d.ts +0 -7
  127. package/dist/v2/effect/npm.js +0 -1
  128. package/dist/v2/effect/path.d.ts +0 -8
  129. package/dist/v2/effect/path.js +0 -1
  130. package/dist/v2/effect/plugin.d.ts +0 -11
  131. package/dist/v2/effect/reference.js +0 -1
  132. package/dist/v2/effect/registration.d.ts +0 -10
  133. package/dist/v2/effect/registration.js +0 -1
  134. package/dist/v2/effect/skill.d.ts +0 -9
  135. package/dist/v2/effect/skill.js +0 -1
  136. package/dist/v2/options.js +0 -1
  137. package/dist/v2/promise/agent.d.ts +0 -6
  138. package/dist/v2/promise/agent.js +0 -1
  139. package/dist/v2/promise/aisdk.js +0 -1
  140. package/dist/v2/promise/catalog.d.ts +0 -6
  141. package/dist/v2/promise/catalog.js +0 -1
  142. package/dist/v2/promise/command.d.ts +0 -6
  143. package/dist/v2/promise/command.js +0 -1
  144. package/dist/v2/promise/context.d.ts +0 -21
  145. package/dist/v2/promise/context.js +0 -1
  146. package/dist/v2/promise/index.d.ts +0 -12
  147. package/dist/v2/promise/index.js +0 -1
  148. package/dist/v2/promise/integration.d.ts +0 -12
  149. package/dist/v2/promise/integration.js +0 -1
  150. package/dist/v2/promise/plugin.d.ts +0 -10
  151. package/dist/v2/promise/reference.d.ts +0 -6
  152. package/dist/v2/promise/reference.js +0 -1
  153. package/dist/v2/promise/registration.d.ts +0 -9
  154. package/dist/v2/promise/registration.js +0 -1
  155. package/dist/v2/promise/skill.d.ts +0 -6
  156. package/dist/v2/promise/skill.js +0 -1
  157. /package/dist/{v2/effect → effect}/plugin.js +0 -0
  158. /package/dist/{v2/options.d.ts → options.d.ts} +0 -0
  159. /package/dist/{v2/promise → promise}/plugin.js +0 -0
@@ -0,0 +1,424 @@
1
+ import type { AgentInfo, CommandInfo, FormCancelInput, FormInfo, FormReplyInput, IntegrationInfo, LocationRef, McpResource, McpServer, ModelInfo, OpenCodeClient, OpenCodeEvent, PermissionSavedInfo, PermissionRequest, Project, ProviderInfo, ReferenceInfo, SessionInfo, SessionMessageInfo, SessionInboxInfo, ShellInfo, SkillInfo, VcsInfo } from "@opencode-ai/client";
2
+ import type { ResolvedTheme } from "@opencode-ai/theme/tui";
3
+ import type { CliRenderer, KeyEvent, MarkdownCodeBlockRenderer, Renderable } from "@opentui/core";
4
+ import type { JSX } from "@opentui/solid";
5
+ import type { Store } from "solid-js/store";
6
+ export interface Storage {
7
+ /**
8
+ * Durable JSON state: persisted to disk, survives hot reloads and TUI
9
+ * restarts, and stays live-synced across running TUI instances.
10
+ */
11
+ store<Value extends object>(key: string, options: {
12
+ readonly initial: Value;
13
+ }): readonly [Store<Value>, (mutation: (draft: Value) => void) => Promise<void>];
14
+ /**
15
+ * Ephemeral in-memory state: survives plugin hot reloads (old and new
16
+ * generations share the same live store) and is gone when the TUI exits.
17
+ * Updates are synchronous and values need not be JSON-serializable.
18
+ */
19
+ memory<Value extends object>(key: string, options: {
20
+ readonly initial: Value;
21
+ }): readonly [Store<Value>, (mutation: (draft: Value) => void) => void];
22
+ }
23
+ interface LocationCollection<Value> {
24
+ list(location?: LocationRef): Value[] | undefined;
25
+ sync(location?: LocationRef): Promise<void>;
26
+ invalidate(location?: LocationRef): void;
27
+ }
28
+ export interface Data {
29
+ readonly on: <Type extends OpenCodeEvent["type"]>(type: Type, handler: (event: Extract<OpenCodeEvent, {
30
+ type: Type;
31
+ }>) => void) => () => void;
32
+ readonly listen: (handler: (event: {
33
+ details: OpenCodeEvent;
34
+ }) => void) => () => void;
35
+ readonly session: {
36
+ list(): SessionInfo[];
37
+ get(sessionID: string): SessionInfo | undefined;
38
+ root(sessionID: string): string;
39
+ family(sessionID: string): string[];
40
+ cost(sessionID: string): number;
41
+ status(sessionID: string): "idle" | "running";
42
+ readonly pending: {
43
+ list(sessionID: string): SessionInboxInfo[];
44
+ sync(sessionID: string): Promise<void>;
45
+ invalidate(sessionID: string): void;
46
+ };
47
+ sync(sessionID: string): Promise<void>;
48
+ invalidate(sessionID: string): void;
49
+ readonly message: {
50
+ list(sessionID: string): SessionMessageInfo[];
51
+ get(sessionID: string, messageID: string): SessionMessageInfo | undefined;
52
+ sync(sessionID: string): Promise<void>;
53
+ invalidate(sessionID: string): void;
54
+ };
55
+ readonly permission: {
56
+ list(sessionID: string): PermissionRequest[] | undefined;
57
+ sync(sessionID: string): Promise<void>;
58
+ invalidate(sessionID: string): void;
59
+ };
60
+ readonly form: {
61
+ list(sessionID: string, location?: LocationRef): Array<FormInfo & {
62
+ readonly location?: LocationRef;
63
+ }> | undefined;
64
+ sync(sessionID: string, location?: LocationRef): Promise<void>;
65
+ invalidate(sessionID: string, location?: LocationRef): void;
66
+ reply(input: FormReplyInput, location?: LocationRef): Promise<void>;
67
+ cancel(input: FormCancelInput, location?: LocationRef): Promise<void>;
68
+ };
69
+ };
70
+ readonly project: {
71
+ list(): Project[];
72
+ get(projectID: string): Project | undefined;
73
+ sync(): Promise<void>;
74
+ invalidate(): void;
75
+ readonly permission: {
76
+ list(projectID: string): PermissionSavedInfo[] | undefined;
77
+ sync(projectID: string): Promise<void>;
78
+ invalidate(projectID: string): void;
79
+ };
80
+ };
81
+ readonly shell: {
82
+ list(location?: LocationRef): ShellInfo[];
83
+ get(id: string): ShellInfo | undefined;
84
+ sync(location?: LocationRef): Promise<void>;
85
+ invalidate(location?: LocationRef): void;
86
+ };
87
+ readonly location: {
88
+ default(): LocationRef;
89
+ sync(location?: LocationRef): Promise<void>;
90
+ invalidate(location?: LocationRef): void;
91
+ readonly vcs: {
92
+ info(location?: LocationRef): VcsInfo | undefined;
93
+ sync(location?: LocationRef): Promise<void>;
94
+ invalidate(location?: LocationRef): void;
95
+ };
96
+ readonly agent: LocationCollection<AgentInfo>;
97
+ readonly command: LocationCollection<CommandInfo>;
98
+ readonly integration: LocationCollection<IntegrationInfo>;
99
+ readonly mcp: {
100
+ readonly server: LocationCollection<McpServer>;
101
+ readonly resource: LocationCollection<McpResource>;
102
+ };
103
+ readonly model: LocationCollection<ModelInfo>;
104
+ readonly provider: LocationCollection<ProviderInfo>;
105
+ readonly reference: LocationCollection<ReferenceInfo>;
106
+ readonly skill: LocationCollection<SkillInfo>;
107
+ };
108
+ }
109
+ export type Route = {
110
+ readonly type: "home";
111
+ } | {
112
+ readonly type: "session";
113
+ readonly sessionID: string;
114
+ } | {
115
+ readonly type: "plugin";
116
+ readonly id: string;
117
+ readonly name: string;
118
+ readonly data?: Record<string, any>;
119
+ };
120
+ export type Destination = Route | Omit<Extract<Route, {
121
+ readonly type: "plugin";
122
+ }>, "id">;
123
+ export interface Page {
124
+ readonly name: string;
125
+ readonly render: (input: {
126
+ readonly data?: Record<string, any>;
127
+ }) => JSX.Element;
128
+ }
129
+ type PromptFooterInput = {
130
+ readonly sessionID?: string;
131
+ readonly mode: "normal" | "shell";
132
+ };
133
+ /**
134
+ * The host UI's slot tree. Every path is one slot: a named boundary a plugin
135
+ * may render around, inside, or take over. Paths are absolute and
136
+ * dot-separated, and a path contains every path it prefixes — replacing
137
+ * `prompt.footer` owns everything under `prompt.footer.*`.
138
+ *
139
+ * Each slot publishes an input: reactive props passed to every claim render
140
+ * targeting it. Inputs carry only what the SDK cannot answer — instance
141
+ * identity and client-local state. Paths and their inputs are documented
142
+ * API: coarse, few, and kept stable across host refactors.
143
+ */
144
+ export interface SlotMap {
145
+ readonly app: Readonly<Record<string, never>>;
146
+ readonly "home.footer": Readonly<Record<string, never>>;
147
+ readonly "prompt.footer": PromptFooterInput;
148
+ readonly "prompt.footer.status": PromptFooterInput;
149
+ readonly "prompt.footer.file": PromptFooterInput;
150
+ readonly "session.composer.top": {
151
+ readonly sessionID: string;
152
+ };
153
+ readonly "sidebar.content": {
154
+ readonly sessionID: string;
155
+ };
156
+ readonly "sidebar.footer": {
157
+ readonly sessionID: string;
158
+ };
159
+ }
160
+ export type SlotPath = keyof SlotMap;
161
+ /**
162
+ * One contribution to the slot tree. Exactly one placement key names an
163
+ * absolute target path:
164
+ * - `prepend` / `append`: first/last inside the target's boundary
165
+ * - `before` / `after`: siblings adjacent to the target, outside its boundary
166
+ * - `replace`: take over the target. The boundary itself survives — siblings
167
+ * anchored `before`/`after` it still compose — but the original content and
168
+ * every claim inside the boundary are suppressed and recorded, never
169
+ * silently dropped. At the same target the last-enabled claim wins; an
170
+ * ancestor replacement beats a descendant one regardless of enable order.
171
+ *
172
+ * A claim aimed at a path the host no longer publishes degrades: additive
173
+ * claims append to the nearest surviving ancestor, replacements are
174
+ * suppressed. Several claims at one anchor coexist in plugin enable order.
175
+ *
176
+ * `render` receives the target slot's input, reactively. The `?: never`
177
+ * fields make the variants mutually exclusive: a claim with two placement
178
+ * keys is a type error, not a silent priority pick.
179
+ */
180
+ export type SlotClaim<Path extends SlotPath = SlotPath> = Path extends SlotPath ? {
181
+ readonly render: (input: SlotMap[Path]) => JSX.Element;
182
+ } & ({
183
+ readonly prepend: Path;
184
+ readonly append?: never;
185
+ readonly before?: never;
186
+ readonly after?: never;
187
+ readonly replace?: never;
188
+ } | {
189
+ readonly append: Path;
190
+ readonly prepend?: never;
191
+ readonly before?: never;
192
+ readonly after?: never;
193
+ readonly replace?: never;
194
+ } | {
195
+ readonly before: Path;
196
+ readonly prepend?: never;
197
+ readonly append?: never;
198
+ readonly after?: never;
199
+ readonly replace?: never;
200
+ } | {
201
+ readonly after: Path;
202
+ readonly prepend?: never;
203
+ readonly append?: never;
204
+ readonly before?: never;
205
+ readonly replace?: never;
206
+ } | {
207
+ readonly replace: Path;
208
+ readonly prepend?: never;
209
+ readonly append?: never;
210
+ readonly before?: never;
211
+ readonly after?: never;
212
+ }) : never;
213
+ export interface App {
214
+ readonly version: string;
215
+ readonly channel: string;
216
+ }
217
+ export type ToastVariant = "info" | "success" | "warning" | "error";
218
+ export interface ToastOptions {
219
+ readonly title?: string;
220
+ readonly message: string;
221
+ readonly variant?: ToastVariant;
222
+ readonly duration?: number;
223
+ }
224
+ export interface Toast {
225
+ show(options: ToastOptions): void;
226
+ }
227
+ export type AttentionWhen = "always" | "focused" | "blurred";
228
+ export type AttentionSoundName = "default" | "question" | "permission" | "error" | "done" | "subagent_done";
229
+ export type AttentionNotification = boolean | {
230
+ readonly when?: AttentionWhen;
231
+ };
232
+ export type AttentionSound = boolean | {
233
+ readonly name?: AttentionSoundName;
234
+ readonly volume?: number;
235
+ readonly when?: AttentionWhen;
236
+ };
237
+ export interface AttentionNotifyOptions {
238
+ readonly title?: string;
239
+ readonly message: string;
240
+ readonly notification?: AttentionNotification;
241
+ readonly sound?: AttentionSound;
242
+ }
243
+ export type AttentionNotifySkipReason = "attention_disabled" | "empty_message" | "blurred" | "focused" | "focus_unknown" | "renderer_destroyed";
244
+ export interface AttentionNotifyResult {
245
+ readonly ok: boolean;
246
+ readonly notification: boolean;
247
+ readonly sound: boolean;
248
+ readonly skipped?: AttentionNotifySkipReason;
249
+ }
250
+ export interface Attention {
251
+ notify(options: AttentionNotifyOptions): Promise<AttentionNotifyResult>;
252
+ }
253
+ export type DialogSize = "medium" | "large" | "xlarge";
254
+ export interface DialogOptions {
255
+ readonly size?: DialogSize;
256
+ readonly centered?: boolean;
257
+ }
258
+ export interface DialogAlertOptions {
259
+ readonly title: string;
260
+ readonly message: string;
261
+ }
262
+ export interface DialogConfirmOptions {
263
+ readonly title: string;
264
+ readonly message: string;
265
+ readonly label?: {
266
+ readonly confirm?: string;
267
+ readonly cancel?: string;
268
+ };
269
+ }
270
+ export interface DialogPromptOptions {
271
+ readonly title: string;
272
+ readonly description?: string;
273
+ readonly placeholder?: string;
274
+ readonly value?: string;
275
+ }
276
+ export interface DialogSelectOption<Value> {
277
+ readonly title: string;
278
+ readonly value: Value;
279
+ readonly description?: string;
280
+ readonly category?: string;
281
+ readonly disabled?: boolean;
282
+ }
283
+ export interface DialogSelectOptions<Value> {
284
+ readonly title: string;
285
+ readonly placeholder?: string;
286
+ readonly options: readonly DialogSelectOption<Value>[];
287
+ readonly current?: Value;
288
+ }
289
+ export interface Dialog {
290
+ /** Shows a dialog. */
291
+ show(render: () => JSX.Element, onClose?: () => void): void;
292
+ /** Sets the active dialog's presentation options. */
293
+ set(options: DialogOptions): void;
294
+ /** Closes the active dialog. */
295
+ clear(): void;
296
+ alert(options: DialogAlertOptions): Promise<void>;
297
+ confirm(options: DialogConfirmOptions): Promise<boolean | undefined>;
298
+ prompt(options: DialogPromptOptions): Promise<string | undefined>;
299
+ select<Value>(options: DialogSelectOptions<Value>): Promise<Value | undefined>;
300
+ }
301
+ export interface KeymapCommand {
302
+ /** Stable command and config keybind identifier. Omit for an inline command. */
303
+ readonly id?: string;
304
+ /** Optional label used by command discovery and keyboard-help UI. */
305
+ readonly title?: string;
306
+ /** Optional longer description. */
307
+ readonly description?: string;
308
+ /** Groups the command in discovery and keyboard-help UI. */
309
+ readonly group?: string;
310
+ /** Enables or disables the command. */
311
+ readonly enabled?: boolean | (() => boolean);
312
+ /** Configures automatic binding, or disables it for a named command. */
313
+ readonly bind?: false | string;
314
+ /** Adds a named command to the command palette. */
315
+ readonly palette?: true;
316
+ /** Adds a named command to prompt slash completion. */
317
+ readonly slash?: {
318
+ readonly name: string;
319
+ readonly aliases?: string[];
320
+ /** Keeps the slash command in the prompt and passes its raw input to run. */
321
+ readonly arguments?: true;
322
+ };
323
+ /** Promotes the command in discovery UI. */
324
+ readonly suggested?: boolean | (() => boolean);
325
+ /** Executes the command. Keyboard dispatch includes its event; programmatic dispatch does not. Return false to continue. */
326
+ readonly run: (input?: string, event?: KeyEvent) => void | false | Promise<void>;
327
+ }
328
+ export interface KeymapLayer {
329
+ /** Limits the layer to one OpenCode input mode. Use global to opt out; defaults to base. */
330
+ readonly mode?: string;
331
+ /** Enables or disables the complete layer. */
332
+ readonly enabled?: boolean | (() => boolean);
333
+ /** Limits the layer to a focused renderable. */
334
+ readonly target?: () => Renderable | null | undefined;
335
+ /** Resolves conflicts with other active layers. */
336
+ readonly priority?: number;
337
+ /** Commands owned by this layer. */
338
+ readonly commands?: readonly KeymapCommand[];
339
+ /** IDs of commands whose configured bindings should be active in this layer. */
340
+ readonly bindings?: readonly string[];
341
+ }
342
+ export interface KeymapPending {
343
+ readonly key: string;
344
+ readonly token?: string;
345
+ }
346
+ export interface KeymapActive {
347
+ readonly key: string;
348
+ readonly title?: string;
349
+ readonly description?: string;
350
+ readonly group?: string;
351
+ readonly continues: boolean;
352
+ }
353
+ export interface Keymap {
354
+ /** Creates a reactive keymap layer owned by the calling component. */
355
+ layer(input: () => KeymapLayer): void;
356
+ /** Dispatches a reachable command by ID. */
357
+ dispatch(id: string, input?: string): void;
358
+ /** Returns every formatted shortcut for a registered command. */
359
+ shortcuts(id: string): readonly string[];
360
+ /** Returns the currently reachable commands. Reactive when read in a Solid computation. */
361
+ commands(): readonly KeymapCommand[];
362
+ /** Returns the pending key sequence. Reactive when read in a Solid computation. */
363
+ pending(): readonly KeymapPending[];
364
+ /** Returns bindings reachable from the pending key sequence. Reactive when read in a Solid computation. */
365
+ active(): readonly KeymapActive[];
366
+ /** Controls mutually exclusive OpenCode input modes. */
367
+ readonly mode: {
368
+ /** Returns the active mode. */
369
+ current(): string;
370
+ /** Pushes a mode until the returned cleanup is called. */
371
+ push(mode: string): () => void;
372
+ };
373
+ }
374
+ export interface UI {
375
+ readonly dialog: Dialog;
376
+ readonly toast: Toast;
377
+ readonly format: {
378
+ path(value: string): string;
379
+ };
380
+ readonly router: {
381
+ register(page: Page): () => void;
382
+ navigate(destination: Destination): void;
383
+ current(): Route;
384
+ };
385
+ readonly tabs: {
386
+ /** Returns whether session tabs are enabled for this TUI. */
387
+ enabled(): boolean;
388
+ /** Returns the currently open root-session tabs. Reactive when read in a Solid computation. */
389
+ list(): readonly {
390
+ readonly sessionID: string;
391
+ readonly title?: string;
392
+ readonly active: boolean;
393
+ readonly busy: boolean;
394
+ readonly attention: boolean;
395
+ readonly unread?: "activity" | "error";
396
+ }[];
397
+ /** Opens (or focuses) a tab for a session, adding it when not already open. Returns false when tabs are disabled. */
398
+ open(sessionID: string): boolean;
399
+ /** Focuses an already-open tab and returns false when it is not open. */
400
+ focus(sessionID: string): boolean;
401
+ /** Closes an open tab, or the active tab when omitted, and returns false when no tab matched. */
402
+ close(sessionID?: string): boolean;
403
+ };
404
+ /** Claims a place in the slot tree; see SlotClaim. */
405
+ readonly slot: (claim: SlotClaim) => () => void;
406
+ }
407
+ export interface Context {
408
+ readonly options: Readonly<Record<string, any>>;
409
+ readonly location: LocationRef | undefined;
410
+ readonly app: App;
411
+ readonly renderer: CliRenderer;
412
+ readonly client: OpenCodeClient;
413
+ readonly data: Data;
414
+ readonly attention: Attention;
415
+ readonly theme: ResolvedTheme;
416
+ readonly themeMode: "dark" | "light";
417
+ readonly markdown: {
418
+ registerCodeBlockRenderer(language: string, render: MarkdownCodeBlockRenderer): () => void;
419
+ };
420
+ readonly keymap: Keymap;
421
+ readonly storage: Storage;
422
+ readonly ui: UI;
423
+ }
424
+ export {};
File without changes
@@ -0,0 +1,2 @@
1
+ export * as Plugin from "./plugin.js";
2
+ export { PluginContextProvider, usePlugin } from "./solid.js";
@@ -0,0 +1,2 @@
1
+ export * as Plugin from "./plugin.js";
2
+ export { PluginContextProvider, usePlugin } from "./solid.js";
@@ -0,0 +1,8 @@
1
+ import type { Context } from "./context.js";
2
+ export type { Context };
3
+ export type Cleanup = () => Promise<void> | void;
4
+ export interface Definition {
5
+ readonly id: string;
6
+ readonly setup: (context: Context) => Promise<Cleanup | void> | Cleanup | void;
7
+ }
8
+ export declare function define(plugin: Definition): Definition;
@@ -0,0 +1,3 @@
1
+ export function define(plugin) {
2
+ return plugin;
3
+ }
@@ -0,0 +1,7 @@
1
+ import { type JSX } from "solid-js";
2
+ import type { Context } from "./context.js";
3
+ export declare function PluginContextProvider(props: {
4
+ readonly value: Context;
5
+ readonly children: JSX.Element;
6
+ }): JSX.Element;
7
+ export declare function usePlugin(): Context;
@@ -0,0 +1,16 @@
1
+ import { createComponent, createContext, useContext } from "solid-js";
2
+ const PluginContext = createContext();
3
+ export function PluginContextProvider(props) {
4
+ return createComponent(PluginContext.Provider, {
5
+ value: props.value,
6
+ get children() {
7
+ return props.children;
8
+ },
9
+ });
10
+ }
11
+ export function usePlugin() {
12
+ const context = useContext(PluginContext);
13
+ if (!context)
14
+ throw new Error("PluginContextProvider is missing");
15
+ return context;
16
+ }
package/dist/vcs.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export interface VcsDiscovery {
2
+ readonly id?: string;
3
+ readonly markers: readonly string[];
4
+ }
package/dist/vcs.js ADDED
File without changes
package/package.json CHANGED
@@ -1,41 +1,30 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode-ai/plugin",
4
- "version": "0.0.0-dev-202608272023",
4
+ "version": "0.0.0-dev-18430",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "scripts": {
8
+ "test": "bun test --timeout 5000",
8
9
  "typecheck": "tsgo --noEmit",
9
- "build": "tsc"
10
+ "build": "tsc -p tsconfig.build.json"
10
11
  },
11
12
  "exports": {
12
13
  ".": {
13
- "import": "./dist/index.js",
14
- "types": "./dist/index.d.ts"
14
+ "import": "./dist/promise/index.js",
15
+ "types": "./dist/promise/index.d.ts"
15
16
  },
16
- "./tool": {
17
- "import": "./dist/tool.js",
18
- "types": "./dist/tool.d.ts"
17
+ "./effect": {
18
+ "import": "./dist/effect/index.js",
19
+ "types": "./dist/effect/index.d.ts"
19
20
  },
20
21
  "./tui": {
21
- "import": "./dist/tui.js",
22
- "types": "./dist/tui.d.ts"
22
+ "import": "./dist/tui/index.js",
23
+ "types": "./dist/tui/index.d.ts"
23
24
  },
24
- "./v2/effect": {
25
- "import": "./dist/v2/effect/index.js",
26
- "types": "./dist/v2/effect/index.d.ts"
27
- },
28
- "./v2/effect/integration": {
29
- "import": "./dist/v2/effect/integration.js",
30
- "types": "./dist/v2/effect/integration.d.ts"
31
- },
32
- "./v2/effect/plugin": {
33
- "import": "./dist/v2/effect/plugin.js",
34
- "types": "./dist/v2/effect/plugin.d.ts"
35
- },
36
- "./v2/promise": {
37
- "import": "./dist/v2/promise/index.js",
38
- "types": "./dist/v2/promise/index.d.ts"
25
+ "./*": {
26
+ "import": "./dist/*.js",
27
+ "types": "./dist/*.d.ts"
39
28
  }
40
29
  },
41
30
  "files": [
@@ -43,32 +32,42 @@
43
32
  ],
44
33
  "dependencies": {
45
34
  "@ai-sdk/provider": "3.0.8",
46
- "@opencode-ai/sdk": "0.0.0-dev-202608272023",
47
- "effect": "4.0.0-beta.83",
35
+ "@opencode-ai/ai": "0.0.0-dev-18430",
36
+ "@opencode-ai/client": "0.0.0-dev-18430",
37
+ "@opencode-ai/protocol": "0.0.0-dev-18430",
38
+ "@opencode-ai/schema": "0.0.0-dev-18430",
39
+ "@standard-schema/spec": "1.1.0",
40
+ "effect": "4.0.0-rc.111",
48
41
  "zod": "4.1.8"
49
42
  },
50
43
  "peerDependencies": {
51
- "@opentui/core": ">=0.4.5",
52
- "@opentui/keymap": ">=0.4.5",
53
- "@opentui/solid": ">=0.4.5"
44
+ "@opencode-ai/theme": "0.0.0-dev-18430",
45
+ "@opentui/core": ">=0.5.8",
46
+ "@opentui/solid": ">=0.5.8",
47
+ "solid-js": ">=1.9.0"
54
48
  },
55
49
  "peerDependenciesMeta": {
56
- "@opentui/core": {
50
+ "@opencode-ai/theme": {
57
51
  "optional": true
58
52
  },
59
- "@opentui/keymap": {
53
+ "@opentui/core": {
60
54
  "optional": true
61
55
  },
62
56
  "@opentui/solid": {
63
57
  "optional": true
58
+ },
59
+ "solid-js": {
60
+ "optional": true
64
61
  }
65
62
  },
66
63
  "devDependencies": {
67
- "@opentui/core": "0.4.5",
68
- "@opentui/keymap": "0.4.5",
69
- "@opentui/solid": "0.4.5",
64
+ "@opencode-ai/theme": "0.0.0-dev-18430",
65
+ "@opentui/core": "0.5.8",
66
+ "@opentui/solid": "0.5.8",
67
+ "@tsconfig/bun": "1.0.9",
70
68
  "@tsconfig/node22": "22.0.2",
71
69
  "@types/node": "24.12.2",
70
+ "solid-js": "1.9.10",
72
71
  "typescript": "5.8.2",
73
72
  "@typescript/native-preview": "7.0.0-dev.20251207.1"
74
73
  }
@@ -1,3 +0,0 @@
1
- import type { Plugin } from "@opencode-ai/plugin";
2
- export declare const FolderWorkspacePlugin: Plugin;
3
- export default FolderWorkspacePlugin;
@@ -1,30 +0,0 @@
1
- import { mkdir, rm } from "node:fs/promises";
2
- export const FolderWorkspacePlugin = async ({ experimental_workspace }) => {
3
- experimental_workspace.register("folder", {
4
- name: "Folder",
5
- description: "Create a blank folder",
6
- configure(config) {
7
- const rand = "" + Math.random();
8
- return {
9
- ...config,
10
- directory: `/tmp/folder/folder-${rand}`,
11
- };
12
- },
13
- async create(config) {
14
- if (!config.directory)
15
- return;
16
- await mkdir(config.directory, { recursive: true });
17
- },
18
- async remove(config) {
19
- await rm(config.directory, { recursive: true, force: true });
20
- },
21
- target(config) {
22
- return {
23
- type: "local",
24
- directory: config.directory,
25
- };
26
- },
27
- });
28
- return {};
29
- };
30
- export default FolderWorkspacePlugin;
package/dist/example.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import { Plugin } from "./index.js";
2
- export declare const ExamplePlugin: Plugin;
package/dist/example.js DELETED
@@ -1,16 +0,0 @@
1
- import { tool } from "./tool.js";
2
- export const ExamplePlugin = async (_ctx) => {
3
- return {
4
- tool: {
5
- mytool: tool({
6
- description: "This is a custom tool",
7
- args: {
8
- foo: tool.schema.string().describe("foo"),
9
- },
10
- async execute(args) {
11
- return `Hello ${args.foo}!`;
12
- },
13
- }),
14
- },
15
- };
16
- };