@agentplugins/adapter-opencode 0.1.0

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.
package/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # @agentplugins/adapter-opencode
2
+
3
+ > AgentPlugins platform adapter for [OpenCode](https://opencode.ai/docs/plugins/).
4
+
5
+ Generates OpenCode-compatible plugins from a universal `PluginManifest`: a TypeScript module with the plugin's hooks, tools, and MCP server config, plus a JSON descriptor.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @agentplugins/adapter-opencode
11
+ ```
12
+
13
+ Typically installed transitively via [`@agentplugins/cli`](https://www.npmjs.com/package/@agentplugins/cli).
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { createOpenCodeAdapter } from '@agentplugins/adapter-opencode';
19
+
20
+ const adapter = createOpenCodeAdapter();
21
+ const output = await adapter.compile(manifest);
22
+ ```
23
+
24
+ Or via the CLI:
25
+
26
+ ```bash
27
+ npx agentplugins build --target opencode
28
+ ```
29
+
30
+ ## Output shape
31
+
32
+ A successful build writes to `dist/opencode/`:
33
+
34
+ ```
35
+ dist/opencode/
36
+ ├── <plugin-name>.ts
37
+ └── opencode.json
38
+ ```
39
+
40
+ Install with: `cp dist/opencode/*.ts dist/opencode/opencode.json .opencode/plugins/`
41
+
42
+ ## Native support
43
+
44
+ OpenCode natively executes TypeScript plugin modules, so inline handlers are emitted as real TypeScript functions (not wrapped scripts). This gives you first-class type checking and IDE support in the generated code.
45
+
46
+ ## License
47
+
48
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,445 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ EVENT_HOOKS: () => EVENT_HOOKS,
24
+ EVENT_TYPE_CONDITIONS: () => EVENT_TYPE_CONDITIONS,
25
+ HOOK_MAPPING: () => HOOK_MAPPING,
26
+ buildHandlerInvocation: () => buildHandlerInvocation2,
27
+ createOpenCodeAdapter: () => createOpenCodeAdapter,
28
+ createValidate: () => createValidate,
29
+ default: () => factory_default,
30
+ generateManifest: () => generateManifest,
31
+ generatePluginFile: () => generatePluginFile
32
+ });
33
+ module.exports = __toCommonJS(index_exports);
34
+
35
+ // src/validate.ts
36
+ var import_core = require("@agentplugins/core");
37
+ var SUPPORTED_HOOKS = [
38
+ "sessionStart",
39
+ "sessionEnd",
40
+ "preToolUse",
41
+ "postToolUse",
42
+ "permissionRequest",
43
+ "notification",
44
+ "preCompact",
45
+ "stop"
46
+ ];
47
+ function createValidate() {
48
+ return function validate(plugin) {
49
+ const issues = [];
50
+ const seenHooks = /* @__PURE__ */ new Set();
51
+ const hooks = plugin.hooks ?? {};
52
+ for (const [hookName, hookDef] of Object.entries(hooks)) {
53
+ const universalHook = hookName;
54
+ if (!SUPPORTED_HOOKS.includes(universalHook)) {
55
+ issues.push({
56
+ severity: import_core.Severity.ERROR,
57
+ field: "hooks",
58
+ message: `Hook "${hookName}" is not supported by OpenCode. Supported hooks: ${SUPPORTED_HOOKS.join(", ")}.`
59
+ });
60
+ }
61
+ if (seenHooks.has(universalHook)) {
62
+ issues.push({
63
+ severity: import_core.Severity.ERROR,
64
+ field: "hooks",
65
+ message: `Duplicate registration for hook "${hookName}". OpenCode does not allow multiple handlers per hook.`
66
+ });
67
+ }
68
+ seenHooks.add(universalHook);
69
+ const handler = hookDef?.handler;
70
+ if (handler?.type === "command") {
71
+ issues.push({
72
+ severity: import_core.Severity.INFO,
73
+ field: `hooks.${hookName}`,
74
+ message: `Command handler will be wrapped using Bun.$() for OpenCode compatibility.`
75
+ });
76
+ } else if (handler?.type === "http") {
77
+ issues.push({
78
+ severity: import_core.Severity.INFO,
79
+ field: `hooks.${hookName}`,
80
+ message: `HTTP handler will be wrapped using Bun.$() (curl) for OpenCode compatibility.`
81
+ });
82
+ }
83
+ }
84
+ if (!plugin.name || plugin.name.trim().length === 0) {
85
+ issues.push({
86
+ severity: import_core.Severity.ERROR,
87
+ field: "name",
88
+ message: "Plugin name is required and must be a non-empty string."
89
+ });
90
+ } else if (!/^[a-z0-9._-]+$/i.test(plugin.name)) {
91
+ issues.push({
92
+ severity: import_core.Severity.WARNING,
93
+ field: "name",
94
+ message: `Plugin name "${plugin.name}" contains characters that may not be safe for filesystem paths.`
95
+ });
96
+ }
97
+ return issues;
98
+ };
99
+ }
100
+
101
+ // src/hook-mapping.ts
102
+ var HOOK_MAPPING = {
103
+ sessionStart: "event",
104
+ sessionEnd: "event",
105
+ preToolUse: "tool.execute.before",
106
+ postToolUse: "tool.execute.after",
107
+ permissionRequest: "permission.ask",
108
+ notification: "event",
109
+ preCompact: "experimental.session.compacting",
110
+ stop: "event"
111
+ };
112
+ var EVENT_TYPE_CONDITIONS = {
113
+ sessionStart: 'event.type === "session.created"',
114
+ sessionEnd: 'event.type === "session.deleted"',
115
+ stop: 'event.type === "session.idle"'
116
+ };
117
+ var EVENT_HOOKS = [
118
+ "sessionStart",
119
+ "sessionEnd",
120
+ "notification",
121
+ "stop"
122
+ ];
123
+ function buildEventHookBlock(registrations) {
124
+ const branches = [];
125
+ for (const reg of registrations) {
126
+ const condition = EVENT_TYPE_CONDITIONS[reg.hook];
127
+ if (!condition) {
128
+ branches.push(buildHandlerInvocation(reg.def.handler, reg.hook));
129
+ continue;
130
+ }
131
+ const handlerBody = buildHandlerInvocation(reg.def.handler, reg.hook);
132
+ branches.push(` if (${condition}) {
133
+ ${handlerBody}
134
+ }`);
135
+ }
136
+ return [
137
+ ` event: async (ctx) => {`,
138
+ ` const { event } = ctx;`,
139
+ branches.join("\n"),
140
+ ` }`
141
+ ].join("\n");
142
+ }
143
+ function buildHookArgs(ocHook, _universalHook) {
144
+ switch (ocHook) {
145
+ case "tool.execute.before":
146
+ case "tool.execute.after":
147
+ return "input, output";
148
+ case "permission.ask":
149
+ return "request";
150
+ case "experimental.session.compacting":
151
+ return "session";
152
+ default:
153
+ return "ctx";
154
+ }
155
+ }
156
+ function buildHandlerInvocation(handler, hookName, ocHook) {
157
+ const indent = " ";
158
+ switch (handler.type) {
159
+ case "inline": {
160
+ const ih = handler;
161
+ const contextArg = getContextArg(ocHook);
162
+ return [
163
+ `${indent}// [${hookName}] inline handler`,
164
+ `${indent}const result = await (${ih.handler.toString()})(${contextArg});`,
165
+ `${indent}return result;`
166
+ ].join("\n");
167
+ }
168
+ case "command": {
169
+ const ch = handler;
170
+ return [
171
+ `${indent}// [${hookName}] command handler (wrapped via Bun.$)`,
172
+ `${indent}const proc = Bun.$\`${ch.command}\`;`,
173
+ `${indent}const stdout = await proc.text();`,
174
+ `${indent}return stdout;`
175
+ ].join("\n");
176
+ }
177
+ case "http": {
178
+ const hh = handler;
179
+ return [
180
+ `${indent}// [${hookName}] HTTP handler (wrapped via fetch)`,
181
+ `${indent}const response = await fetch("${hh.url}", {`,
182
+ `${indent} method: "POST",`,
183
+ `${indent} headers: ${JSON.stringify(hh.headers ?? {})},`,
184
+ `${indent} body: JSON.stringify(ctx),`,
185
+ `${indent}});`,
186
+ `${indent}return response.json();`
187
+ ].join("\n");
188
+ }
189
+ default: {
190
+ return `${indent}throw new Error("Unsupported handler type: ${handler.type}");`;
191
+ }
192
+ }
193
+ }
194
+ function getContextArg(ocHook) {
195
+ if (!ocHook) return "ctx";
196
+ if (ocHook === "event") {
197
+ return "{ event }";
198
+ }
199
+ if (ocHook === "tool.execute.before" || ocHook === "tool.execute.after") {
200
+ return "{ input, output }";
201
+ }
202
+ if (ocHook === "permission.ask") {
203
+ return "{ request }";
204
+ }
205
+ if (ocHook === "experimental.session.compacting") {
206
+ return "{ session }";
207
+ }
208
+ return "ctx";
209
+ }
210
+
211
+ // src/handler-invocation.ts
212
+ var INDENT = " ";
213
+ function buildHandlerInvocation2(handler, hookName, contextVar) {
214
+ switch (handler.type) {
215
+ case "inline": {
216
+ const ih = handler;
217
+ return [
218
+ `${INDENT}// [${hookName}] inline handler`,
219
+ `${INDENT}try {`,
220
+ `${INDENT} const result = await (${ih.handler.toString()})(${contextVar});`,
221
+ `${INDENT} return result;`,
222
+ `${INDENT}} catch (error) {`,
223
+ `${INDENT} console.error(\`[${hookName}] inline handler error:\`, error);`,
224
+ `${INDENT} throw error;`,
225
+ `${INDENT}}`
226
+ ].join("\n");
227
+ }
228
+ case "command": {
229
+ const ch = handler;
230
+ return [
231
+ `${INDENT}// [${hookName}] command handler (wrapped via Bun.$)`,
232
+ `${INDENT}try {`,
233
+ `${INDENT} const proc = Bun.$\`${ch.command}\`;`,
234
+ `${INDENT} const stdout = await proc.text();`,
235
+ `${INDENT} return stdout;`,
236
+ `${INDENT}} catch (error) {`,
237
+ `${INDENT} console.error(\`[${hookName}] command handler error:\`, error);`,
238
+ `${INDENT} throw error;`,
239
+ `${INDENT}}`
240
+ ].join("\n");
241
+ }
242
+ case "http": {
243
+ const hh = handler;
244
+ return [
245
+ `${INDENT}// [${hookName}] HTTP handler (wrapped via fetch)`,
246
+ `${INDENT}try {`,
247
+ `${INDENT} const response = await fetch("${hh.url}", {`,
248
+ `${INDENT} method: "POST",`,
249
+ `${INDENT} headers: ${JSON.stringify(hh.headers ?? {})},`,
250
+ `${INDENT} body: JSON.stringify(${contextVar}),`,
251
+ `${INDENT} });`,
252
+ `${INDENT} return response.json();`,
253
+ `${INDENT}} catch (error) {`,
254
+ `${INDENT} console.error(\`[${hookName}] HTTP handler error:\`, error);`,
255
+ `${INDENT} throw error;`,
256
+ `${INDENT}}`
257
+ ].join("\n");
258
+ }
259
+ default: {
260
+ return `${INDENT}throw new Error("Unsupported handler type: ${handler.type}");`;
261
+ }
262
+ }
263
+ }
264
+
265
+ // src/output-generators.ts
266
+ function generatePluginFile(manifest, hookCodeMap) {
267
+ const pluginFileName = `${manifest.name}.ts`;
268
+ const hookEntries = [];
269
+ for (const [hookName, handlerCode] of hookCodeMap) {
270
+ hookEntries.push(
271
+ ` "${hookName}": async (${getHookParams(hookName)}) => {
272
+ ${indentHandler(handlerCode)}
273
+ }`
274
+ );
275
+ }
276
+ const pluginFileContent = [
277
+ `// Auto-generated by AgentPlugins for OpenCode`,
278
+ `// Plugin: ${manifest.name}`,
279
+ `// Description: ${manifest.description ?? "No description provided"}`,
280
+ ``,
281
+ `/**`,
282
+ ` * ${manifest.name} \u2014 OpenCode Plugin`,
283
+ ` *`,
284
+ ` * This module was generated by @agentplugins/adapter-opencode.`,
285
+ ` * Drop this file into \`.opencode/plugins/\` or`,
286
+ ` * \`~/.config/opencode/plugins/\` to activate.`,
287
+ ` */`,
288
+ ``,
289
+ `export default async function(ctx) {`,
290
+ ` return {`,
291
+ hookEntries.join(",\n"),
292
+ ` };`,
293
+ `}`,
294
+ ``
295
+ ].join("\n");
296
+ return {
297
+ path: pluginFileName,
298
+ content: pluginFileContent
299
+ };
300
+ }
301
+ function getHookParams(hookName) {
302
+ switch (hookName) {
303
+ case "event":
304
+ return "{ event }";
305
+ case "tool.execute.before":
306
+ return "input, output";
307
+ case "tool.execute.after":
308
+ return "input, output";
309
+ case "permission.ask":
310
+ return "{ permission }";
311
+ case "experimental.session.compacting":
312
+ return "{ event }";
313
+ default:
314
+ return "{}";
315
+ }
316
+ }
317
+ function indentHandler(handlerCode) {
318
+ return handlerCode.split("\n").map((line) => ` ${line}`).join("\n");
319
+ }
320
+ function generateManifest(manifest, hooks) {
321
+ const configFileName = "opencode.json";
322
+ const opencodeConfig = {
323
+ name: manifest.name,
324
+ description: manifest.description ?? "",
325
+ version: manifest.version ?? "0.1.0",
326
+ author: manifest.author ?? "",
327
+ license: manifest.license ?? "MIT",
328
+ hooks: Object.fromEntries(
329
+ Array.from(hooks.keys()).map((k) => [k, true])
330
+ ),
331
+ tools: manifest.tools?.map((tool) => ({
332
+ name: tool.name,
333
+ description: tool.description,
334
+ parameters: tool.parameters
335
+ })) ?? [],
336
+ discovery: {
337
+ paths: [".opencode/plugins/", "~/.config/opencode/plugins/"]
338
+ }
339
+ };
340
+ const configFileContent = JSON.stringify(opencodeConfig, null, 2);
341
+ return {
342
+ path: configFileName,
343
+ content: configFileContent
344
+ };
345
+ }
346
+
347
+ // src/factory.ts
348
+ var SUPPORTED_HOOKS2 = [
349
+ "sessionStart",
350
+ "sessionEnd",
351
+ "preToolUse",
352
+ "postToolUse",
353
+ "permissionRequest",
354
+ "notification",
355
+ "preCompact",
356
+ "stop"
357
+ ];
358
+ var OpenCodeAdapter = class {
359
+ /** Platform identifier used by AgentPlugins core. */
360
+ name = "opencode";
361
+ /** Human-readable platform name. */
362
+ displayName = "OpenCode";
363
+ /**
364
+ * Universal hooks supported by this adapter.
365
+ *
366
+ * These map to OpenCode's native hook system (event, tool.execute.before,
367
+ * tool.execute.after, permission.ask, experimental.session.compacting, …).
368
+ */
369
+ supportedHooks = SUPPORTED_HOOKS2;
370
+ /**
371
+ * Handler types natively supported by OpenCode.
372
+ *
373
+ * OpenCode plugins are TypeScript functions, so "inline" is the native
374
+ * handler type. "command" and "http" handlers are automatically wrapped
375
+ * using Bun's shell API (`$`) so that they appear as inline functions to
376
+ * the OpenCode runtime.
377
+ */
378
+ supportedHandlers = ["inline"];
379
+ /** Path to manifest file (relative to plugin root). */
380
+ manifestPath = "opencode.json";
381
+ /** OpenCode uses JSON configuration (opencode.json). */
382
+ manifestFormat = "json";
383
+ /**
384
+ * Validates a plugin for this platform, returning any issues.
385
+ */
386
+ validate(plugin) {
387
+ const validateFn = createValidate();
388
+ return validateFn(plugin);
389
+ }
390
+ /**
391
+ * Compiles the universal plugin into platform-specific output.
392
+ */
393
+ compile(plugin) {
394
+ const validateFn = createValidate();
395
+ const issues = validateFn(plugin);
396
+ const hookCodeMap = /* @__PURE__ */ new Map();
397
+ const eventRegistrations = [];
398
+ const hooks = plugin.hooks ?? {};
399
+ for (const [hookName, hookDef] of Object.entries(hooks)) {
400
+ const universalHook = hookName;
401
+ const ocHook = HOOK_MAPPING[universalHook];
402
+ if (!ocHook || !hookDef) continue;
403
+ if (EVENT_HOOKS.includes(universalHook)) {
404
+ eventRegistrations.push({ hook: universalHook, def: hookDef });
405
+ } else {
406
+ const contextVar = buildHookArgs(ocHook, universalHook);
407
+ const handlerCode = buildHandlerInvocation2(hookDef.handler, universalHook, contextVar);
408
+ hookCodeMap.set(ocHook, handlerCode);
409
+ }
410
+ }
411
+ if (eventRegistrations.length > 0) {
412
+ const eventBlock = buildEventHookBlock(eventRegistrations);
413
+ hookCodeMap.set("event", eventBlock);
414
+ }
415
+ const files = [
416
+ generatePluginFile(plugin, hookCodeMap),
417
+ generateManifest(plugin, hookCodeMap)
418
+ ];
419
+ return {
420
+ files,
421
+ manifest: { name: plugin.name, version: plugin.version },
422
+ warnings: [],
423
+ issues,
424
+ postInstall: [
425
+ `cp ${plugin.name}.ts .opencode/plugins/`,
426
+ `cp opencode.json .opencode/plugins/`
427
+ ]
428
+ };
429
+ }
430
+ };
431
+ function createOpenCodeAdapter() {
432
+ return new OpenCodeAdapter();
433
+ }
434
+ var factory_default = createOpenCodeAdapter();
435
+ // Annotate the CommonJS export names for ESM import in node:
436
+ 0 && (module.exports = {
437
+ EVENT_HOOKS,
438
+ EVENT_TYPE_CONDITIONS,
439
+ HOOK_MAPPING,
440
+ buildHandlerInvocation,
441
+ createOpenCodeAdapter,
442
+ createValidate,
443
+ generateManifest,
444
+ generatePluginFile
445
+ });
@@ -0,0 +1,121 @@
1
+ import { PlatformAdapter, UniversalHookName, HookHandler, PluginManifest, FileOutput, ValidationIssue } from '@agentplugins/core';
2
+
3
+ /**
4
+ * AgentPlugins — OpenCode Adapter Factory
5
+ *
6
+ * Factory function for creating OpenCode adapter instances.
7
+ * This module provides the createOpenCodeAdapter() factory and the
8
+ * default adapter instance.
9
+ *
10
+ * @module @agentplugins/adapter-opencode
11
+ */
12
+
13
+ /**
14
+ * Creates a new instance of the OpenCode adapter.
15
+ */
16
+ declare function createOpenCodeAdapter(): PlatformAdapter;
17
+ /** Default adapter instance for convenience. */
18
+ declare const _default: PlatformAdapter;
19
+
20
+ /**
21
+ * Hook Mapping — OpenCode Adapter
22
+ *
23
+ * Maps universal AgentPlugins hooks to OpenCode hook names and generates
24
+ * the TypeScript code for hook handlers.
25
+ *
26
+ * Bug fixes in this module:
27
+ * 1. Event hooks: Handler now receives `{ event }` instead of undefined `ctx`
28
+ * 2. Tool hooks: Handler receives `{ input, output }` instead of ignoring args
29
+ */
30
+
31
+ /**
32
+ * Maps universal hook names to their OpenCode equivalents.
33
+ * OpenCode uses a single "event" hook for session/turn events with type discrimination.
34
+ * This is Partial because OpenCode only supports 8 of the 19 universal hooks.
35
+ */
36
+ declare const HOOK_MAPPING: Partial<Record<UniversalHookName, string>>;
37
+ /**
38
+ * Conditions for event-type hooks that need conditional branching on event.type.
39
+ * Only event hooks (sessionStart, sessionEnd, stop) have type conditions.
40
+ * Notification is unconditional.
41
+ */
42
+ declare const EVENT_TYPE_CONDITIONS: Record<string, string>;
43
+ /**
44
+ * Hooks that are implemented via the generic "event" handler with type branching.
45
+ */
46
+ declare const EVENT_HOOKS: readonly UniversalHookName[];
47
+
48
+ /**
49
+ * AgentPlugins — OpenCode Adapter buildHandlerInvocation()
50
+ *
51
+ * Generates the TypeScript code that invokes a handler inside an OpenCode
52
+ * hook function.
53
+ *
54
+ * This module extracts handler invocation generation from the main adapter
55
+ * to enable TDD and better separation of concerns.
56
+ *
57
+ * Key bug fixed: inline handlers previously used `ctx` directly, which is
58
+ * undefined in event hook scope. The context variable must be passed as a
59
+ * parameter to buildHandlerInvocation.
60
+ */
61
+
62
+ /**
63
+ * Builds the TypeScript code that invokes a handler within an OpenCode hook.
64
+ *
65
+ * @param handler - The handler to invoke (inline, command, or http)
66
+ * @param hookName - The universal hook name (for comments)
67
+ * @param contextVar - The context variable name to pass (e.g., "args", "event")
68
+ * @returns TypeScript code string that invokes the handler
69
+ */
70
+ declare function buildHandlerInvocation(handler: HookHandler, hookName: UniversalHookName, contextVar: string): string;
71
+
72
+ /**
73
+ * output-generators.ts — OpenCode output file generators
74
+ *
75
+ * These functions generate the two output files for the OpenCode adapter:
76
+ * 1. `{pluginName}.ts` - The TypeScript plugin file with hook handlers
77
+ * 2. `opencode.json` - The plugin manifest configuration
78
+ */
79
+
80
+ /**
81
+ * Generates the TypeScript plugin file content.
82
+ *
83
+ * @param manifest - The plugin manifest
84
+ * @param hookCodeMap - Map of OpenCode hook names to their handler code strings
85
+ * @returns FileOutput with path `{pluginName}.ts` and TypeScript content
86
+ */
87
+ declare function generatePluginFile(manifest: PluginManifest, hookCodeMap: Map<string, string>): FileOutput;
88
+ /**
89
+ * Generates the opencode.json manifest file content.
90
+ *
91
+ * @param manifest - The plugin manifest
92
+ * @param hooks - Map of OpenCode hook names to their handler code strings
93
+ * @returns FileOutput with path `opencode.json` and JSON content
94
+ */
95
+ declare function generateManifest(manifest: PluginManifest, hooks: Map<string, string>): FileOutput;
96
+
97
+ /**
98
+ * AgentPlugins — OpenCode Adapter validate()
99
+ *
100
+ * Validates a universal plugin manifest for the OpenCode platform.
101
+ *
102
+ * Checks performed:
103
+ * 1. Every declared hook is supported by OpenCode.
104
+ * 2. Every handler can be adapted (inline is native; command/http get INFO notes).
105
+ * 3. The plugin name is present and valid for a directory name.
106
+ * 4. No duplicate hook registrations.
107
+ */
108
+
109
+ /**
110
+ * Creates a validate function for the OpenCode adapter.
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * import { createValidate } from "@agentplugins/adapter-opencode";
115
+ * const validate = createValidate();
116
+ * const issues = validate(manifest);
117
+ * ```
118
+ */
119
+ declare function createValidate(): (plugin: PluginManifest) => ValidationIssue[];
120
+
121
+ export { EVENT_HOOKS, EVENT_TYPE_CONDITIONS, HOOK_MAPPING, buildHandlerInvocation, createOpenCodeAdapter, createValidate, _default as default, generateManifest, generatePluginFile };
@@ -0,0 +1,121 @@
1
+ import { PlatformAdapter, UniversalHookName, HookHandler, PluginManifest, FileOutput, ValidationIssue } from '@agentplugins/core';
2
+
3
+ /**
4
+ * AgentPlugins — OpenCode Adapter Factory
5
+ *
6
+ * Factory function for creating OpenCode adapter instances.
7
+ * This module provides the createOpenCodeAdapter() factory and the
8
+ * default adapter instance.
9
+ *
10
+ * @module @agentplugins/adapter-opencode
11
+ */
12
+
13
+ /**
14
+ * Creates a new instance of the OpenCode adapter.
15
+ */
16
+ declare function createOpenCodeAdapter(): PlatformAdapter;
17
+ /** Default adapter instance for convenience. */
18
+ declare const _default: PlatformAdapter;
19
+
20
+ /**
21
+ * Hook Mapping — OpenCode Adapter
22
+ *
23
+ * Maps universal AgentPlugins hooks to OpenCode hook names and generates
24
+ * the TypeScript code for hook handlers.
25
+ *
26
+ * Bug fixes in this module:
27
+ * 1. Event hooks: Handler now receives `{ event }` instead of undefined `ctx`
28
+ * 2. Tool hooks: Handler receives `{ input, output }` instead of ignoring args
29
+ */
30
+
31
+ /**
32
+ * Maps universal hook names to their OpenCode equivalents.
33
+ * OpenCode uses a single "event" hook for session/turn events with type discrimination.
34
+ * This is Partial because OpenCode only supports 8 of the 19 universal hooks.
35
+ */
36
+ declare const HOOK_MAPPING: Partial<Record<UniversalHookName, string>>;
37
+ /**
38
+ * Conditions for event-type hooks that need conditional branching on event.type.
39
+ * Only event hooks (sessionStart, sessionEnd, stop) have type conditions.
40
+ * Notification is unconditional.
41
+ */
42
+ declare const EVENT_TYPE_CONDITIONS: Record<string, string>;
43
+ /**
44
+ * Hooks that are implemented via the generic "event" handler with type branching.
45
+ */
46
+ declare const EVENT_HOOKS: readonly UniversalHookName[];
47
+
48
+ /**
49
+ * AgentPlugins — OpenCode Adapter buildHandlerInvocation()
50
+ *
51
+ * Generates the TypeScript code that invokes a handler inside an OpenCode
52
+ * hook function.
53
+ *
54
+ * This module extracts handler invocation generation from the main adapter
55
+ * to enable TDD and better separation of concerns.
56
+ *
57
+ * Key bug fixed: inline handlers previously used `ctx` directly, which is
58
+ * undefined in event hook scope. The context variable must be passed as a
59
+ * parameter to buildHandlerInvocation.
60
+ */
61
+
62
+ /**
63
+ * Builds the TypeScript code that invokes a handler within an OpenCode hook.
64
+ *
65
+ * @param handler - The handler to invoke (inline, command, or http)
66
+ * @param hookName - The universal hook name (for comments)
67
+ * @param contextVar - The context variable name to pass (e.g., "args", "event")
68
+ * @returns TypeScript code string that invokes the handler
69
+ */
70
+ declare function buildHandlerInvocation(handler: HookHandler, hookName: UniversalHookName, contextVar: string): string;
71
+
72
+ /**
73
+ * output-generators.ts — OpenCode output file generators
74
+ *
75
+ * These functions generate the two output files for the OpenCode adapter:
76
+ * 1. `{pluginName}.ts` - The TypeScript plugin file with hook handlers
77
+ * 2. `opencode.json` - The plugin manifest configuration
78
+ */
79
+
80
+ /**
81
+ * Generates the TypeScript plugin file content.
82
+ *
83
+ * @param manifest - The plugin manifest
84
+ * @param hookCodeMap - Map of OpenCode hook names to their handler code strings
85
+ * @returns FileOutput with path `{pluginName}.ts` and TypeScript content
86
+ */
87
+ declare function generatePluginFile(manifest: PluginManifest, hookCodeMap: Map<string, string>): FileOutput;
88
+ /**
89
+ * Generates the opencode.json manifest file content.
90
+ *
91
+ * @param manifest - The plugin manifest
92
+ * @param hooks - Map of OpenCode hook names to their handler code strings
93
+ * @returns FileOutput with path `opencode.json` and JSON content
94
+ */
95
+ declare function generateManifest(manifest: PluginManifest, hooks: Map<string, string>): FileOutput;
96
+
97
+ /**
98
+ * AgentPlugins — OpenCode Adapter validate()
99
+ *
100
+ * Validates a universal plugin manifest for the OpenCode platform.
101
+ *
102
+ * Checks performed:
103
+ * 1. Every declared hook is supported by OpenCode.
104
+ * 2. Every handler can be adapted (inline is native; command/http get INFO notes).
105
+ * 3. The plugin name is present and valid for a directory name.
106
+ * 4. No duplicate hook registrations.
107
+ */
108
+
109
+ /**
110
+ * Creates a validate function for the OpenCode adapter.
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * import { createValidate } from "@agentplugins/adapter-opencode";
115
+ * const validate = createValidate();
116
+ * const issues = validate(manifest);
117
+ * ```
118
+ */
119
+ declare function createValidate(): (plugin: PluginManifest) => ValidationIssue[];
120
+
121
+ export { EVENT_HOOKS, EVENT_TYPE_CONDITIONS, HOOK_MAPPING, buildHandlerInvocation, createOpenCodeAdapter, createValidate, _default as default, generateManifest, generatePluginFile };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,cAAc,EAOpB,MAAM,mBAAmB,CAAC;AAiC3B;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACrD,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAc;IAE3C,oCAAoC;IACpC,QAAQ,CAAC,WAAW,cAAc;IAElC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,iBAAiB,EAAE,CASnD;IAEF;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,EAAE,SAAS,WAAW,EAAE,CAAc;IAEhE,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,wBAAwB;IAE7C,wDAAwD;IACxD,QAAQ,CAAC,cAAc,EAAG,MAAM,CAAU;IAI1C;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,EAAE;IAgEnD;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa;IA2G9C;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAcrB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;CAyC/B;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD;AAED,gDAAgD;;AAChD,wBAAqC"}
package/dist/index.js ADDED
@@ -0,0 +1,413 @@
1
+ // src/validate.ts
2
+ import {
3
+ Severity
4
+ } from "@agentplugins/core";
5
+ var SUPPORTED_HOOKS = [
6
+ "sessionStart",
7
+ "sessionEnd",
8
+ "preToolUse",
9
+ "postToolUse",
10
+ "permissionRequest",
11
+ "notification",
12
+ "preCompact",
13
+ "stop"
14
+ ];
15
+ function createValidate() {
16
+ return function validate(plugin) {
17
+ const issues = [];
18
+ const seenHooks = /* @__PURE__ */ new Set();
19
+ const hooks = plugin.hooks ?? {};
20
+ for (const [hookName, hookDef] of Object.entries(hooks)) {
21
+ const universalHook = hookName;
22
+ if (!SUPPORTED_HOOKS.includes(universalHook)) {
23
+ issues.push({
24
+ severity: Severity.ERROR,
25
+ field: "hooks",
26
+ message: `Hook "${hookName}" is not supported by OpenCode. Supported hooks: ${SUPPORTED_HOOKS.join(", ")}.`
27
+ });
28
+ }
29
+ if (seenHooks.has(universalHook)) {
30
+ issues.push({
31
+ severity: Severity.ERROR,
32
+ field: "hooks",
33
+ message: `Duplicate registration for hook "${hookName}". OpenCode does not allow multiple handlers per hook.`
34
+ });
35
+ }
36
+ seenHooks.add(universalHook);
37
+ const handler = hookDef?.handler;
38
+ if (handler?.type === "command") {
39
+ issues.push({
40
+ severity: Severity.INFO,
41
+ field: `hooks.${hookName}`,
42
+ message: `Command handler will be wrapped using Bun.$() for OpenCode compatibility.`
43
+ });
44
+ } else if (handler?.type === "http") {
45
+ issues.push({
46
+ severity: Severity.INFO,
47
+ field: `hooks.${hookName}`,
48
+ message: `HTTP handler will be wrapped using Bun.$() (curl) for OpenCode compatibility.`
49
+ });
50
+ }
51
+ }
52
+ if (!plugin.name || plugin.name.trim().length === 0) {
53
+ issues.push({
54
+ severity: Severity.ERROR,
55
+ field: "name",
56
+ message: "Plugin name is required and must be a non-empty string."
57
+ });
58
+ } else if (!/^[a-z0-9._-]+$/i.test(plugin.name)) {
59
+ issues.push({
60
+ severity: Severity.WARNING,
61
+ field: "name",
62
+ message: `Plugin name "${plugin.name}" contains characters that may not be safe for filesystem paths.`
63
+ });
64
+ }
65
+ return issues;
66
+ };
67
+ }
68
+
69
+ // src/hook-mapping.ts
70
+ var HOOK_MAPPING = {
71
+ sessionStart: "event",
72
+ sessionEnd: "event",
73
+ preToolUse: "tool.execute.before",
74
+ postToolUse: "tool.execute.after",
75
+ permissionRequest: "permission.ask",
76
+ notification: "event",
77
+ preCompact: "experimental.session.compacting",
78
+ stop: "event"
79
+ };
80
+ var EVENT_TYPE_CONDITIONS = {
81
+ sessionStart: 'event.type === "session.created"',
82
+ sessionEnd: 'event.type === "session.deleted"',
83
+ stop: 'event.type === "session.idle"'
84
+ };
85
+ var EVENT_HOOKS = [
86
+ "sessionStart",
87
+ "sessionEnd",
88
+ "notification",
89
+ "stop"
90
+ ];
91
+ function buildEventHookBlock(registrations) {
92
+ const branches = [];
93
+ for (const reg of registrations) {
94
+ const condition = EVENT_TYPE_CONDITIONS[reg.hook];
95
+ if (!condition) {
96
+ branches.push(buildHandlerInvocation(reg.def.handler, reg.hook));
97
+ continue;
98
+ }
99
+ const handlerBody = buildHandlerInvocation(reg.def.handler, reg.hook);
100
+ branches.push(` if (${condition}) {
101
+ ${handlerBody}
102
+ }`);
103
+ }
104
+ return [
105
+ ` event: async (ctx) => {`,
106
+ ` const { event } = ctx;`,
107
+ branches.join("\n"),
108
+ ` }`
109
+ ].join("\n");
110
+ }
111
+ function buildHookArgs(ocHook, _universalHook) {
112
+ switch (ocHook) {
113
+ case "tool.execute.before":
114
+ case "tool.execute.after":
115
+ return "input, output";
116
+ case "permission.ask":
117
+ return "request";
118
+ case "experimental.session.compacting":
119
+ return "session";
120
+ default:
121
+ return "ctx";
122
+ }
123
+ }
124
+ function buildHandlerInvocation(handler, hookName, ocHook) {
125
+ const indent = " ";
126
+ switch (handler.type) {
127
+ case "inline": {
128
+ const ih = handler;
129
+ const contextArg = getContextArg(ocHook);
130
+ return [
131
+ `${indent}// [${hookName}] inline handler`,
132
+ `${indent}const result = await (${ih.handler.toString()})(${contextArg});`,
133
+ `${indent}return result;`
134
+ ].join("\n");
135
+ }
136
+ case "command": {
137
+ const ch = handler;
138
+ return [
139
+ `${indent}// [${hookName}] command handler (wrapped via Bun.$)`,
140
+ `${indent}const proc = Bun.$\`${ch.command}\`;`,
141
+ `${indent}const stdout = await proc.text();`,
142
+ `${indent}return stdout;`
143
+ ].join("\n");
144
+ }
145
+ case "http": {
146
+ const hh = handler;
147
+ return [
148
+ `${indent}// [${hookName}] HTTP handler (wrapped via fetch)`,
149
+ `${indent}const response = await fetch("${hh.url}", {`,
150
+ `${indent} method: "POST",`,
151
+ `${indent} headers: ${JSON.stringify(hh.headers ?? {})},`,
152
+ `${indent} body: JSON.stringify(ctx),`,
153
+ `${indent}});`,
154
+ `${indent}return response.json();`
155
+ ].join("\n");
156
+ }
157
+ default: {
158
+ return `${indent}throw new Error("Unsupported handler type: ${handler.type}");`;
159
+ }
160
+ }
161
+ }
162
+ function getContextArg(ocHook) {
163
+ if (!ocHook) return "ctx";
164
+ if (ocHook === "event") {
165
+ return "{ event }";
166
+ }
167
+ if (ocHook === "tool.execute.before" || ocHook === "tool.execute.after") {
168
+ return "{ input, output }";
169
+ }
170
+ if (ocHook === "permission.ask") {
171
+ return "{ request }";
172
+ }
173
+ if (ocHook === "experimental.session.compacting") {
174
+ return "{ session }";
175
+ }
176
+ return "ctx";
177
+ }
178
+
179
+ // src/handler-invocation.ts
180
+ var INDENT = " ";
181
+ function buildHandlerInvocation2(handler, hookName, contextVar) {
182
+ switch (handler.type) {
183
+ case "inline": {
184
+ const ih = handler;
185
+ return [
186
+ `${INDENT}// [${hookName}] inline handler`,
187
+ `${INDENT}try {`,
188
+ `${INDENT} const result = await (${ih.handler.toString()})(${contextVar});`,
189
+ `${INDENT} return result;`,
190
+ `${INDENT}} catch (error) {`,
191
+ `${INDENT} console.error(\`[${hookName}] inline handler error:\`, error);`,
192
+ `${INDENT} throw error;`,
193
+ `${INDENT}}`
194
+ ].join("\n");
195
+ }
196
+ case "command": {
197
+ const ch = handler;
198
+ return [
199
+ `${INDENT}// [${hookName}] command handler (wrapped via Bun.$)`,
200
+ `${INDENT}try {`,
201
+ `${INDENT} const proc = Bun.$\`${ch.command}\`;`,
202
+ `${INDENT} const stdout = await proc.text();`,
203
+ `${INDENT} return stdout;`,
204
+ `${INDENT}} catch (error) {`,
205
+ `${INDENT} console.error(\`[${hookName}] command handler error:\`, error);`,
206
+ `${INDENT} throw error;`,
207
+ `${INDENT}}`
208
+ ].join("\n");
209
+ }
210
+ case "http": {
211
+ const hh = handler;
212
+ return [
213
+ `${INDENT}// [${hookName}] HTTP handler (wrapped via fetch)`,
214
+ `${INDENT}try {`,
215
+ `${INDENT} const response = await fetch("${hh.url}", {`,
216
+ `${INDENT} method: "POST",`,
217
+ `${INDENT} headers: ${JSON.stringify(hh.headers ?? {})},`,
218
+ `${INDENT} body: JSON.stringify(${contextVar}),`,
219
+ `${INDENT} });`,
220
+ `${INDENT} return response.json();`,
221
+ `${INDENT}} catch (error) {`,
222
+ `${INDENT} console.error(\`[${hookName}] HTTP handler error:\`, error);`,
223
+ `${INDENT} throw error;`,
224
+ `${INDENT}}`
225
+ ].join("\n");
226
+ }
227
+ default: {
228
+ return `${INDENT}throw new Error("Unsupported handler type: ${handler.type}");`;
229
+ }
230
+ }
231
+ }
232
+
233
+ // src/output-generators.ts
234
+ function generatePluginFile(manifest, hookCodeMap) {
235
+ const pluginFileName = `${manifest.name}.ts`;
236
+ const hookEntries = [];
237
+ for (const [hookName, handlerCode] of hookCodeMap) {
238
+ hookEntries.push(
239
+ ` "${hookName}": async (${getHookParams(hookName)}) => {
240
+ ${indentHandler(handlerCode)}
241
+ }`
242
+ );
243
+ }
244
+ const pluginFileContent = [
245
+ `// Auto-generated by AgentPlugins for OpenCode`,
246
+ `// Plugin: ${manifest.name}`,
247
+ `// Description: ${manifest.description ?? "No description provided"}`,
248
+ ``,
249
+ `/**`,
250
+ ` * ${manifest.name} \u2014 OpenCode Plugin`,
251
+ ` *`,
252
+ ` * This module was generated by @agentplugins/adapter-opencode.`,
253
+ ` * Drop this file into \`.opencode/plugins/\` or`,
254
+ ` * \`~/.config/opencode/plugins/\` to activate.`,
255
+ ` */`,
256
+ ``,
257
+ `export default async function(ctx) {`,
258
+ ` return {`,
259
+ hookEntries.join(",\n"),
260
+ ` };`,
261
+ `}`,
262
+ ``
263
+ ].join("\n");
264
+ return {
265
+ path: pluginFileName,
266
+ content: pluginFileContent
267
+ };
268
+ }
269
+ function getHookParams(hookName) {
270
+ switch (hookName) {
271
+ case "event":
272
+ return "{ event }";
273
+ case "tool.execute.before":
274
+ return "input, output";
275
+ case "tool.execute.after":
276
+ return "input, output";
277
+ case "permission.ask":
278
+ return "{ permission }";
279
+ case "experimental.session.compacting":
280
+ return "{ event }";
281
+ default:
282
+ return "{}";
283
+ }
284
+ }
285
+ function indentHandler(handlerCode) {
286
+ return handlerCode.split("\n").map((line) => ` ${line}`).join("\n");
287
+ }
288
+ function generateManifest(manifest, hooks) {
289
+ const configFileName = "opencode.json";
290
+ const opencodeConfig = {
291
+ name: manifest.name,
292
+ description: manifest.description ?? "",
293
+ version: manifest.version ?? "0.1.0",
294
+ author: manifest.author ?? "",
295
+ license: manifest.license ?? "MIT",
296
+ hooks: Object.fromEntries(
297
+ Array.from(hooks.keys()).map((k) => [k, true])
298
+ ),
299
+ tools: manifest.tools?.map((tool) => ({
300
+ name: tool.name,
301
+ description: tool.description,
302
+ parameters: tool.parameters
303
+ })) ?? [],
304
+ discovery: {
305
+ paths: [".opencode/plugins/", "~/.config/opencode/plugins/"]
306
+ }
307
+ };
308
+ const configFileContent = JSON.stringify(opencodeConfig, null, 2);
309
+ return {
310
+ path: configFileName,
311
+ content: configFileContent
312
+ };
313
+ }
314
+
315
+ // src/factory.ts
316
+ var SUPPORTED_HOOKS2 = [
317
+ "sessionStart",
318
+ "sessionEnd",
319
+ "preToolUse",
320
+ "postToolUse",
321
+ "permissionRequest",
322
+ "notification",
323
+ "preCompact",
324
+ "stop"
325
+ ];
326
+ var OpenCodeAdapter = class {
327
+ /** Platform identifier used by AgentPlugins core. */
328
+ name = "opencode";
329
+ /** Human-readable platform name. */
330
+ displayName = "OpenCode";
331
+ /**
332
+ * Universal hooks supported by this adapter.
333
+ *
334
+ * These map to OpenCode's native hook system (event, tool.execute.before,
335
+ * tool.execute.after, permission.ask, experimental.session.compacting, …).
336
+ */
337
+ supportedHooks = SUPPORTED_HOOKS2;
338
+ /**
339
+ * Handler types natively supported by OpenCode.
340
+ *
341
+ * OpenCode plugins are TypeScript functions, so "inline" is the native
342
+ * handler type. "command" and "http" handlers are automatically wrapped
343
+ * using Bun's shell API (`$`) so that they appear as inline functions to
344
+ * the OpenCode runtime.
345
+ */
346
+ supportedHandlers = ["inline"];
347
+ /** Path to manifest file (relative to plugin root). */
348
+ manifestPath = "opencode.json";
349
+ /** OpenCode uses JSON configuration (opencode.json). */
350
+ manifestFormat = "json";
351
+ /**
352
+ * Validates a plugin for this platform, returning any issues.
353
+ */
354
+ validate(plugin) {
355
+ const validateFn = createValidate();
356
+ return validateFn(plugin);
357
+ }
358
+ /**
359
+ * Compiles the universal plugin into platform-specific output.
360
+ */
361
+ compile(plugin) {
362
+ const validateFn = createValidate();
363
+ const issues = validateFn(plugin);
364
+ const hookCodeMap = /* @__PURE__ */ new Map();
365
+ const eventRegistrations = [];
366
+ const hooks = plugin.hooks ?? {};
367
+ for (const [hookName, hookDef] of Object.entries(hooks)) {
368
+ const universalHook = hookName;
369
+ const ocHook = HOOK_MAPPING[universalHook];
370
+ if (!ocHook || !hookDef) continue;
371
+ if (EVENT_HOOKS.includes(universalHook)) {
372
+ eventRegistrations.push({ hook: universalHook, def: hookDef });
373
+ } else {
374
+ const contextVar = buildHookArgs(ocHook, universalHook);
375
+ const handlerCode = buildHandlerInvocation2(hookDef.handler, universalHook, contextVar);
376
+ hookCodeMap.set(ocHook, handlerCode);
377
+ }
378
+ }
379
+ if (eventRegistrations.length > 0) {
380
+ const eventBlock = buildEventHookBlock(eventRegistrations);
381
+ hookCodeMap.set("event", eventBlock);
382
+ }
383
+ const files = [
384
+ generatePluginFile(plugin, hookCodeMap),
385
+ generateManifest(plugin, hookCodeMap)
386
+ ];
387
+ return {
388
+ files,
389
+ manifest: { name: plugin.name, version: plugin.version },
390
+ warnings: [],
391
+ issues,
392
+ postInstall: [
393
+ `cp ${plugin.name}.ts .opencode/plugins/`,
394
+ `cp opencode.json .opencode/plugins/`
395
+ ]
396
+ };
397
+ }
398
+ };
399
+ function createOpenCodeAdapter() {
400
+ return new OpenCodeAdapter();
401
+ }
402
+ var factory_default = createOpenCodeAdapter();
403
+ export {
404
+ EVENT_HOOKS,
405
+ EVENT_TYPE_CONDITIONS,
406
+ HOOK_MAPPING,
407
+ buildHandlerInvocation2 as buildHandlerInvocation,
408
+ createOpenCodeAdapter,
409
+ createValidate,
410
+ factory_default as default,
411
+ generateManifest,
412
+ generatePluginFile
413
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@agentplugins/adapter-opencode",
3
+ "version": "0.1.0",
4
+ "description": "OpenCode platform adapter for AgentPlugins - generates OpenCode-compatible plugins from universal manifests",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsup src/index.ts --format cjs,esm --dts",
17
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
18
+ "clean": "rm -rf dist",
19
+ "test": "vitest",
20
+ "test:run": "vitest run"
21
+ },
22
+ "dependencies": {
23
+ "@agentplugins/core": "workspace:*",
24
+ "zod": "^3.22.0"
25
+ },
26
+ "devDependencies": {
27
+ "tsup": "^8.0.0",
28
+ "typescript": "^5.3.0",
29
+ "vitest": "^1.0.0"
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "README.md"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "license": "MIT",
39
+ "keywords": [
40
+ "agentplugins",
41
+ "opencode",
42
+ "adapter",
43
+ "ai",
44
+ "plugins"
45
+ ]
46
+ }