@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 +48 -0
- package/dist/index.cjs +445 -0
- package/dist/index.d.cts +121 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +413 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
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
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -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 };
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|