create-donobu-plugin 1.0.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.
Files changed (2) hide show
  1. package/index.js +307 -0
  2. package/package.json +24 -0
package/index.js ADDED
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { mkdir, writeFile, readFile } from "fs/promises";
4
+ import { join, dirname } from "path";
5
+ import { createRequire } from "module";
6
+
7
+ async function getDonobuVersions() {
8
+ try {
9
+ // Find the donobu package.json by resolving the module path
10
+ const require = createRequire(import.meta.url);
11
+ const donobuPath = require.resolve("donobu");
12
+ // Navigate up to find package.json (donobu path might point to dist/main.js)
13
+ const donobuDir = dirname(donobuPath);
14
+ let packageJsonPath = join(donobuDir, "package.json");
15
+
16
+ try {
17
+ await readFile(packageJsonPath, "utf8");
18
+ } catch {
19
+ // If not found, try going up one more directory
20
+ packageJsonPath = join(dirname(donobuDir), "package.json");
21
+ }
22
+
23
+ const packageJsonContent = await readFile(packageJsonPath, "utf8");
24
+ const donobuPackageJson = JSON.parse(packageJsonContent);
25
+
26
+ return {
27
+ donobuVersion: donobuPackageJson.version,
28
+ playwrightVersion:
29
+ donobuPackageJson.devDependencies?.playwright ||
30
+ donobuPackageJson.dependencies?.playwright ||
31
+ donobuPackageJson.peerDependencies?.playwright?.replace(/^>=/, "") ||
32
+ "1.53.2",
33
+ playwrightTestVersion:
34
+ donobuPackageJson.devDependencies?.["@playwright/test"] ||
35
+ donobuPackageJson.dependencies?.["@playwright/test"] ||
36
+ donobuPackageJson.peerDependencies?.["@playwright/test"]?.replace(
37
+ /^>=/,
38
+ ""
39
+ ) ||
40
+ "1.53.2",
41
+ };
42
+ } catch (error) {
43
+ console.error("Could not read the Donobu package.json file!");
44
+ throw error;
45
+ }
46
+ }
47
+
48
+ async function createPluginStructure(pluginName) {
49
+ const pluginDir = join(process.cwd(), pluginName);
50
+ console.log(`Creating plugin directory: ${pluginDir}`);
51
+ // Get current donobu and playwright versions
52
+ const versions = await getDonobuVersions();
53
+ console.log(`Using Donobu version: ${versions.donobuVersion}`);
54
+ console.log(`Using Playwright version: ${versions.playwrightVersion}`);
55
+ // Create directory structure
56
+ await mkdir(pluginDir, { recursive: true });
57
+ await mkdir(join(pluginDir, "src"), { recursive: true });
58
+ console.log("Creating files...");
59
+ await createTemplateFiles(pluginDir, pluginName, versions);
60
+ console.log(`\nPlugin "${pluginName}" created successfully!`);
61
+ console.log(`\nNext steps:`);
62
+ console.log(` cd ${pluginName}`);
63
+ console.log(` npm install`);
64
+ console.log(` # Edit src/index.ts to add your custom tools`);
65
+ console.log(` npx install-donobu-plugin`);
66
+ }
67
+
68
+ async function createTemplateFiles(pluginDir, pluginName, versions) {
69
+ // Create package.json
70
+ const packageJson = {
71
+ name: pluginName,
72
+ version: "1.0.0",
73
+ private: true,
74
+ type: "module",
75
+ description: "Custom tools for use by Donobu.",
76
+ main: "./dist/index.mjs",
77
+ types: "./dist/index.d.ts",
78
+ exports: {
79
+ ".": "./dist/index.mjs",
80
+ },
81
+ files: ["dist"],
82
+ scripts: {
83
+ clean: "rm -rf dist",
84
+ build:
85
+ "npm run clean && npm install && tsc -p tsconfig.json && node esbuild.config.mjs",
86
+ },
87
+ license: "UNLICENSED",
88
+ devDependencies: {
89
+ donobu: `^${versions.donobuVersion}`,
90
+ playwright: versions.playwrightVersion,
91
+ "@playwright/test": versions.playwrightTestVersion,
92
+ typescript: "^5.8.3",
93
+ esbuild: "^0.25.6",
94
+ },
95
+ peerDependencies: {
96
+ donobu: `>=${versions.donobuVersion}`,
97
+ playwright: `>=${versions.playwrightVersion}`,
98
+ "@playwright/test": `>=${versions.playwrightTestVersion}`,
99
+ },
100
+ peerDependenciesMeta: {
101
+ playwright: {
102
+ optional: false,
103
+ },
104
+ "@playwright/test": {
105
+ optional: false,
106
+ },
107
+ },
108
+ dependencies: {
109
+ zod: "^3.24.1",
110
+ },
111
+ };
112
+
113
+ await writeFile(
114
+ join(pluginDir, "package.json"),
115
+ JSON.stringify(packageJson, null, 2)
116
+ );
117
+
118
+ // Create tsconfig.json
119
+ const tsConfig = {
120
+ compilerOptions: {
121
+ target: "ES2020",
122
+ module: "NodeNext",
123
+ moduleResolution: "NodeNext",
124
+ rootDir: "./src",
125
+ outDir: "./dist",
126
+ declaration: true,
127
+ strict: true,
128
+ esModuleInterop: true,
129
+ skipLibCheck: true,
130
+ forceConsistentCasingInFileNames: true,
131
+ },
132
+ include: ["src/**/*"],
133
+ };
134
+
135
+ await writeFile(
136
+ join(pluginDir, "tsconfig.json"),
137
+ JSON.stringify(tsConfig, null, 2)
138
+ );
139
+
140
+ // Create esbuild.config.mjs
141
+ const esbuildConfig = `import { build } from 'esbuild';
142
+
143
+ await build({
144
+ entryPoints: ['dist/index.js'],
145
+ outfile: 'dist/index.mjs',
146
+ bundle: true,
147
+ format: 'esm',
148
+ platform: 'node',
149
+ external: ['donobu', 'playwright'],
150
+ minify: true,
151
+ });
152
+ `;
153
+
154
+ await writeFile(join(pluginDir, "esbuild.config.mjs"), esbuildConfig);
155
+
156
+ // Create src/index.ts
157
+ const indexTs = `import type { Tool } from "donobu";
158
+ import { PluginDependencies } from "./PluginDependencies.js";
159
+
160
+ export async function loadCustomTools(
161
+ dependencies: PluginDependencies
162
+ ): Promise<Tool<any, any>[]> {
163
+ // Register your custom tools here.
164
+ return [];
165
+ }
166
+ `;
167
+
168
+ await writeFile(join(pluginDir, "src", "index.ts"), indexTs);
169
+
170
+ // Create src/createTool.ts
171
+ const createToolTs = `import { z } from "zod";
172
+ import type { ToolCallContext, ToolCallResult, Tool } from "donobu";
173
+ import { PluginDependencies } from "./PluginDependencies.js";
174
+
175
+ /**
176
+ * Factory function to create a Donobu Tool instance.
177
+ */
178
+ export function createTool<
179
+ CallSchema extends z.ZodObject<any>,
180
+ CallFromGptSchema extends z.ZodObject<any> = CallSchema,
181
+ >(
182
+ dependencies: PluginDependencies,
183
+ options: CreateToolOptions<CallSchema, CallFromGptSchema>
184
+ ): Tool<CallSchema, CallFromGptSchema> {
185
+ class AnonymousTool extends dependencies.donobu.Tool<
186
+ CallSchema,
187
+ CallFromGptSchema
188
+ > {
189
+ public constructor() {
190
+ super(
191
+ options.name,
192
+ options.description,
193
+ options.schema,
194
+ (options.gptSchema ?? options.schema) as CallFromGptSchema,
195
+ options.requiresGpt
196
+ );
197
+ }
198
+ public override async call(
199
+ ctx: ToolCallContext,
200
+ params: z.infer<CallSchema>
201
+ ): Promise<ToolCallResult> {
202
+ return options.call(ctx, params);
203
+ }
204
+ public override async callFromGpt(
205
+ ctx: ToolCallContext,
206
+ params: z.infer<CallFromGptSchema>
207
+ ): Promise<ToolCallResult> {
208
+ return options.callFromGpt
209
+ ? options.callFromGpt(ctx, params)
210
+ : this.call(ctx, params);
211
+ }
212
+ }
213
+
214
+ return new AnonymousTool();
215
+ }
216
+
217
+ export interface CreateToolOptions<
218
+ CallSchema extends z.ZodObject<any>,
219
+ CallFromGptSchema extends z.ZodObject<any> = CallSchema,
220
+ > {
221
+ /**
222
+ * @param name This is the name for the tool that will be shared with the LLM when making requests.
223
+ * @param description This is the description that will be shared with the LLM when making requests.
224
+ * @param inputSchema This is the JSON-schema for the tool when it is invoked by a non-LLM.
225
+ * @param inputSchemaForGpt This is the JSON-schema that will be shared with the LLM when making
226
+ * requests during autonomous flows.
227
+ * @param requiresGpt Set to true if this tool requires the usage of a GPT.
228
+ * @param call This is the function that will be invoked when the tool is called by a non-LLM.
229
+ * @param callFromGpt This is the function that will be invoked when the tool is called by an LLM.
230
+ */
231
+ name: string;
232
+ description: string;
233
+ requiresGpt: boolean;
234
+ schema: CallSchema;
235
+ gptSchema?: CallFromGptSchema;
236
+ call(
237
+ ctx: ToolCallContext,
238
+ params: z.infer<CallSchema>
239
+ ): Promise<ToolCallResult> | ToolCallResult;
240
+ callFromGpt?(
241
+ ctx: ToolCallContext,
242
+ params: z.infer<CallFromGptSchema>
243
+ ): Promise<ToolCallResult> | ToolCallResult;
244
+ }
245
+ `;
246
+
247
+ await writeFile(join(pluginDir, "src", "createTool.ts"), createToolTs);
248
+
249
+ // Create src/PluginDependencies.ts
250
+ const pluginDepsTs = `export interface PluginDependencies {
251
+ donobu: typeof import("donobu");
252
+ playwright: typeof import("playwright");
253
+ }
254
+ `;
255
+
256
+ await writeFile(
257
+ join(pluginDir, "src", "PluginDependencies.ts"),
258
+ pluginDepsTs
259
+ );
260
+
261
+ // Create a basic README
262
+ const readme = `# ${pluginName}
263
+
264
+ A custom Donobu plugin with tools for browser automation.
265
+
266
+ ## Development
267
+
268
+ 1. Edit \`src/index.ts\` to add your custom tools
269
+ 2. Build and install the plugin:
270
+ \`\`\`bash
271
+ npm run build
272
+ npm exec install-donobu-plugin
273
+ \`\`\`
274
+ 3. Restart Donobu to see your tools
275
+ `;
276
+
277
+ await writeFile(join(pluginDir, "README.md"), readme);
278
+ }
279
+
280
+ async function main() {
281
+ const pluginName = process.argv[2];
282
+
283
+ if (!pluginName) {
284
+ console.error("Usage: create-donobu-plugin <plugin-name>");
285
+ console.error("");
286
+ console.error("Example:");
287
+ console.error(" npm create donobu-plugin my-awesome-plugin");
288
+ process.exit(1);
289
+ }
290
+
291
+ // Validate plugin name
292
+ if (!/^[a-z0-9-_]+$/.test(pluginName)) {
293
+ console.error(
294
+ "Plugin name must contain only lowercase letters, numbers, hyphens, and underscores"
295
+ );
296
+ process.exit(1);
297
+ }
298
+
299
+ try {
300
+ await createPluginStructure(pluginName);
301
+ } catch (error) {
302
+ console.error("Failed to create plugin:", error.message);
303
+ process.exit(1);
304
+ }
305
+ }
306
+
307
+ main();
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "create-donobu-plugin",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Create a new Donobu plugin",
6
+ "author": "Donobu",
7
+ "homepage": "https://donobu.com",
8
+ "main": "index.js",
9
+ "bin": {
10
+ "create-donobu-plugin": "./index.js"
11
+ },
12
+ "files": [
13
+ "index.js"
14
+ ],
15
+ "dependencies": {
16
+ "donobu": "^2.30.1"
17
+ },
18
+ "keywords": [
19
+ "donobu",
20
+ "plugin",
21
+ "create"
22
+ ],
23
+ "license": "UNLICENSED"
24
+ }