@choiceopen/automation-plugin-cli 0.0.1 → 0.1.3

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.
@@ -1,115 +0,0 @@
1
- import confirm from "@inquirer/confirm";
2
- import { Command } from "@oclif/core";
3
- import { colorize } from "@oclif/core/ux";
4
- import { assert } from "es-toolkit";
5
- import open from "open";
6
- import { dedent } from "ts-dedent";
7
- import yoctoSpinner from "yocto-spinner";
8
- import * as configStore from "../../utils/config.js";
9
- export default class AuthLogin extends Command {
10
- static description = dedent `
11
- Uses device authorization flow to login with your Choiceform account by following these steps:
12
-
13
- 1. Request a validation code automatically
14
- 2. Show the validation code and a verification URL to the user
15
- 3. Open the verification URL in the user's browser and paste the verification code
16
- 4. Submit the validation code to complete the device authorization flow
17
- `;
18
- static examples = [
19
- {
20
- command: "<%= config.bin %> <%= command.id %>",
21
- description: "Login by using device authorization flow",
22
- },
23
- ];
24
- static flags = {};
25
- pollingInterval = 5;
26
- client_id = "automation_plugin_cli";
27
- grant_type = "urn:ietf:params:oauth:grant-type:device_code";
28
- async run() {
29
- await this.parse(AuthLogin);
30
- const config = await configStore.load();
31
- assert(config.auth?.endpoint, "Auth endpoint is required");
32
- const payload = await this.requestDeviceCode(config.auth.endpoint);
33
- this.log(colorize("yellowBright", "Starting device authorization flow...\n"));
34
- this.log(colorize("bold", colorize("gray", "Verification URL : ")), payload.verification_uri);
35
- this.log(colorize("bold", colorize("gray", "Verification Code: ")), `${payload.user_code}\n`);
36
- const autoOpen = await confirm({
37
- message: dedent `
38
- Do you want to open the verification URL in your browser automatically?
39
- If not, you can manually open the URL and paste the code.
40
- `,
41
- });
42
- if (autoOpen) {
43
- await open(payload.verification_uri_complete);
44
- }
45
- const spinner = yoctoSpinner({ text: "Polling for token..." }).start();
46
- const result = (await this.pollForToken(payload.device_code, spinner));
47
- await configStore.update({ auth: { access_token: result.access_token } });
48
- const session = await fetch(`${config.auth.endpoint}/v1/auth/get-session`, {
49
- headers: {
50
- "Content-Type": "application/json",
51
- "User-Agent": "Choiceform (Automation Plugin CLI)",
52
- Authorization: `Bearer ${result.access_token}`,
53
- },
54
- }).then((response) => response.json());
55
- this.log(colorize("greenBright", dedent `
56
- Welcome back, ${session.user.name} <${session.user.email}>!
57
- To create a new plugin, you can use the following command:
58
- \`${colorize("bold", colorize("yellowBright", "automation plugin init"))}\`
59
- `));
60
- }
61
- async requestDeviceCode(endpoint) {
62
- const response = await fetch(`${endpoint}/v1/auth/device/code`, {
63
- method: "POST",
64
- headers: {
65
- "Content-Type": "application/json",
66
- "User-Agent": "Choiceform (Automation Plugin CLI)",
67
- },
68
- body: JSON.stringify({ client_id: this.client_id }),
69
- });
70
- return (await response.json());
71
- }
72
- async pollForToken(device_code, spinner) {
73
- return new Promise((resolve) => {
74
- const poll = async () => {
75
- const response = await fetch("http://localhost:5001/v1/auth/device/token", {
76
- method: "POST",
77
- headers: {
78
- "Content-Type": "application/json",
79
- "User-Agent": "Choiceform (Automation Plugin CLI)",
80
- },
81
- body: JSON.stringify({
82
- grant_type: this.grant_type,
83
- client_id: this.client_id,
84
- device_code,
85
- }),
86
- });
87
- const payload = (await response.json());
88
- if (payload.error) {
89
- switch (payload.error) {
90
- case "authorization_pending":
91
- setTimeout(poll, this.pollingInterval * 1000);
92
- break;
93
- case "slow_down":
94
- this.pollingInterval += 5;
95
- break;
96
- case "access_denied":
97
- spinner.error("Access was denied by the user");
98
- return process.exit(0);
99
- case "expired_token":
100
- spinner.error("The device code has expired. Please try again.");
101
- return process.exit(0);
102
- default:
103
- spinner.error(`Error: ${payload.error_description}`);
104
- return process.exit(1);
105
- }
106
- }
107
- else {
108
- spinner.success("Token acquired successfully\n");
109
- resolve(payload);
110
- }
111
- };
112
- setTimeout(poll, this.pollingInterval * 1000);
113
- });
114
- }
115
- }
@@ -1,13 +0,0 @@
1
- import { Command } from "@oclif/core";
2
- export default class PluginChecksum extends Command {
3
- static args: {
4
- file: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
- };
6
- static description: string;
7
- static examples: string[];
8
- static flags: {
9
- force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- };
12
- run(): Promise<void>;
13
- }
@@ -1,22 +0,0 @@
1
- import { Args, Command, Flags } from "@oclif/core";
2
- export default class PluginChecksum extends Command {
3
- static args = {
4
- file: Args.string({ description: "file to read" }),
5
- };
6
- static description = "describe the command here";
7
- static examples = ["<%= config.bin %> <%= command.id %>"];
8
- static flags = {
9
- // flag with no value (-f, --force)
10
- force: Flags.boolean({ char: "f" }),
11
- // flag with a value (-n, --name=VALUE)
12
- name: Flags.string({ char: "n", description: "name to print" }),
13
- };
14
- async run() {
15
- const { args, flags } = await this.parse(PluginChecksum);
16
- const name = flags.name ?? "world";
17
- this.log(`hello ${name} from /Users/nightire/Code/github.com/choice-open/automation-plugin-cli/src/commands/plugin/checksum.ts`);
18
- if (args.file && flags.force) {
19
- this.log(`you input --force and --file: ${args.file}`);
20
- }
21
- }
22
- }
@@ -1,11 +0,0 @@
1
- import { Command } from "@oclif/core";
2
- export default class Plugin extends Command {
3
- static description: string;
4
- static enableJsonFlag: boolean;
5
- static examples: {
6
- command: string;
7
- description: string;
8
- }[];
9
- static hidden: boolean;
10
- run(): Promise<void>;
11
- }
@@ -1,15 +0,0 @@
1
- import { Command } from "@oclif/core";
2
- export default class Plugin extends Command {
3
- static description = "Manages your plugin via subcommands";
4
- static enableJsonFlag = true;
5
- static examples = [
6
- {
7
- command: "<%= config.bin %> help <%= command.id %> [COMMAND]",
8
- description: "Check help for each individual sub-command",
9
- },
10
- ];
11
- static hidden = true;
12
- async run() {
13
- await this.config.runCommand("help", ["plugin"]);
14
- }
15
- }
@@ -1,33 +0,0 @@
1
- import { Command } from "@oclif/core";
2
- export default class PluginInit extends Command {
3
- static description: string;
4
- static examples: {
5
- command: string;
6
- description: string;
7
- }[];
8
- static flags: {
9
- interactive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- description: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
- author: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
- email: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
- url: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
- locales: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
- language: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
- type: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
- permissions: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
- };
20
- run(): Promise<void>;
21
- private nameIsValid;
22
- private reconcileInteractiveFlag;
23
- private runInteractiveMode;
24
- private collectName;
25
- private collectDescription;
26
- private collectAuthor;
27
- private collectEmail;
28
- private collectURL;
29
- private collectLocales;
30
- private collectLanguage;
31
- private collectType;
32
- private collectPermissions;
33
- }
@@ -1,363 +0,0 @@
1
- import path from "node:path";
2
- import checkbox, { Separator } from "@inquirer/checkbox";
3
- import input from "@inquirer/input";
4
- import select from "@inquirer/select";
5
- import { Command, Flags } from "@oclif/core";
6
- import { colorize } from "@oclif/core/ux";
7
- import { assert, isString } from "es-toolkit";
8
- import { dedent } from "ts-dedent";
9
- import z from "zod";
10
- import { createPluginGenerator } from "../../utils/generator.js";
11
- import { checkboxTheme, selectTheme } from "../../utils/theme.js";
12
- const LOCALES = ["en_US", "zh_Hans", "ja_JP"];
13
- const LANGUAGES = ["elixir", "python", "typescript"];
14
- const PERMISSIONS = [
15
- "endpoints:register",
16
- "model:call_llm",
17
- "model:call_embedding",
18
- "model:call_moderation",
19
- "model:call_rerank",
20
- "model:call_stt",
21
- "model:call_tts",
22
- "storage:kv",
23
- "tools:invoke",
24
- ];
25
- export default class PluginInit extends Command {
26
- static description = dedent `
27
- Initialize a new plugin with step-by-step interactive instructions.
28
-
29
- Providing required flags skips interactive flow and completes initialization in one go.
30
- `;
31
- static examples = [
32
- {
33
- command: "<%= config.bin %> <%= command.id %>",
34
- description: "Start with interactive initialization:",
35
- },
36
- ];
37
- static flags = {
38
- interactive: Flags.boolean({
39
- allowNo: true,
40
- char: "i",
41
- default: true,
42
- summary: "Use interactive mode (by default)",
43
- }),
44
- name: Flags.string({
45
- char: "n",
46
- helpValue: "my-awesome-plugin",
47
- summary: "Plugin name",
48
- }),
49
- description: Flags.string({
50
- char: "d",
51
- default: "",
52
- helpValue: "Descriptive text...",
53
- summary: "Short description",
54
- }),
55
- author: Flags.string({
56
- char: "a",
57
- default: "",
58
- helpValue: "John Doe",
59
- summary: "Author name",
60
- }),
61
- email: Flags.string({
62
- char: "e",
63
- default: "",
64
- helpValue: "john.doe@example.com",
65
- summary: "Author email address",
66
- }),
67
- url: Flags.string({
68
- char: "u",
69
- default: "",
70
- summary: "Repository URL",
71
- }),
72
- locales: Flags.option({
73
- multiple: true,
74
- options: LOCALES,
75
- })({
76
- delimiter: ",",
77
- summary: "Provide READMEs in which languages",
78
- }),
79
- language: Flags.option({
80
- multiple: false,
81
- options: LANGUAGES,
82
- })({
83
- char: "l",
84
- summary: "Programming language to use for plugin development",
85
- }),
86
- type: Flags.option({
87
- multiple: false,
88
- options: ["extension", "llm", "tool", "trigger"],
89
- })({
90
- char: "t",
91
- summary: "Plugin type",
92
- }),
93
- permissions: Flags.option({
94
- multiple: true,
95
- options: PERMISSIONS,
96
- })({
97
- char: "p",
98
- delimiter: ",",
99
- summary: "Permissions required by the plugin",
100
- }),
101
- };
102
- async run() {
103
- const { flags } = await this.parse(PluginInit);
104
- this.reconcileInteractiveFlag(flags);
105
- if (flags.interactive) {
106
- await this.runInteractiveMode(flags);
107
- }
108
- assert(flags.name, "flags.name should be valid here...");
109
- assert(flags.language, "flags.language should be valid here...");
110
- const generator = createPluginGenerator(flags.language, {
111
- props: { ...flags, createdAt: new Date().toISOString() },
112
- target: path.join(process.cwd(), flags.name),
113
- });
114
- await generator.generate();
115
- }
116
- nameIsValid(name) {
117
- return isString(name) && /^[a-z][a-z0-9_-]{2,62}[a-z0-9]$/.test(name);
118
- }
119
- reconcileInteractiveFlag(flags) {
120
- if (flags.interactive && this.nameIsValid(flags.name)) {
121
- flags.interactive = false;
122
- }
123
- if (!flags.interactive && !this.nameIsValid(flags.name)) {
124
- this.log(colorize("redBright", dedent `
125
- Without interactive mode, you should provide initial information manually.
126
- Use ${colorize("blue", "automation help plugin init")} to see all available options.
127
- `));
128
- this.exit(0);
129
- }
130
- }
131
- async runInteractiveMode(flags) {
132
- this.log(dedent `
133
- Guiding you through creating a new plugin in interactive mode
134
- Please follow the instructions below to complete the process:\n
135
- `);
136
- try {
137
- flags.name = await this.collectName();
138
- flags.description = await this.collectDescription();
139
- flags.author = await this.collectAuthor();
140
- flags.email = await this.collectEmail();
141
- flags.url = await this.collectURL();
142
- flags.locales = await this.collectLocales(flags);
143
- flags.language = await this.collectLanguage();
144
- flags.type = await this.collectType();
145
- flags.permissions = await this.collectPermissions(flags);
146
- }
147
- catch (error) {
148
- if (error instanceof Error && error.name === "ExitPromptError") {
149
- process.exit(0);
150
- }
151
- throw error;
152
- }
153
- }
154
- async collectName() {
155
- return await input({
156
- message: "What's the name of this new plugin:",
157
- pattern: /^[a-z][a-z0-9_-]{2,62}[a-z0-9]$/,
158
- patternError: dedent `
159
- You must provide a name for the new plugin:
160
- - Only lowercase letters, digits, underscores, and hyphens are allowed
161
- - Minimum length of 4 and maximum length of 64
162
- - Starts with a lowercase letter (not a digit)
163
- - Ends with a lowercase letter or digit (not underscore or hyphen)
164
- `,
165
- });
166
- }
167
- async collectDescription() {
168
- return await input({
169
- message: "How do you describe this new plugin:",
170
- default: "A brief description of the plugin's functionality",
171
- prefill: "tab",
172
- pattern: /^.{16,256}$/,
173
- patternError: dedent `
174
- You must provide a description for the new plugin:
175
- - Allows any characters, minimum 16 characters, maximum 256 characters
176
- `,
177
- });
178
- }
179
- async collectAuthor() {
180
- return await input({
181
- message: "Who is the author of the new plugin:",
182
- default: "John Doe",
183
- prefill: "tab",
184
- pattern: /^.{2,64}$/,
185
- patternError: dedent `
186
- You must provide the author name:
187
- - Allows any characters, minimum 2 characters, maximum 64 characters
188
- `,
189
- });
190
- }
191
- async collectEmail() {
192
- return await input({
193
- message: "What is the email address of the author:",
194
- default: "john.doe@example.com",
195
- prefill: "tab",
196
- pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2,})*$/,
197
- patternError: dedent `You must provide the author email`,
198
- });
199
- }
200
- async collectURL() {
201
- return await input({
202
- message: "What is the repository URL address (Optional):",
203
- default: "https://github.com/[user]/[repo]",
204
- prefill: "tab",
205
- validate: (value) => {
206
- const { success } = z
207
- .url({ normalize: true, protocol: /https?|git/ })
208
- .optional()
209
- .safeParse(value);
210
- return success || "You must provide a valid URL";
211
- },
212
- });
213
- }
214
- async collectLocales(flags) {
215
- const values = await checkbox({
216
- choices: [
217
- {
218
- checked: flags.locales?.includes("en_US"),
219
- disabled: "(required)",
220
- name: "English",
221
- description: "English (United States)",
222
- value: "en_US",
223
- },
224
- {
225
- checked: flags.locales?.includes("zh_Hans"),
226
- disabled: false,
227
- name: "简体中文",
228
- description: "Simplified Chinese (China)",
229
- value: "zh_Hans",
230
- },
231
- {
232
- checked: flags.locales?.includes("ja_JP"),
233
- disabled: false,
234
- name: "日本語",
235
- description: "Japanese (Japan)",
236
- value: "ja_JP",
237
- },
238
- ],
239
- message: "Provide READMEs in which language(s)?",
240
- theme: checkboxTheme,
241
- });
242
- return ["en_US", ...values];
243
- }
244
- async collectLanguage() {
245
- return await select({
246
- choices: [
247
- {
248
- name: "Elixir",
249
- value: "elixir",
250
- },
251
- {
252
- name: "Python",
253
- value: "python",
254
- },
255
- {
256
- name: "TypeScript",
257
- value: "typescript",
258
- },
259
- ],
260
- message: "What programming language do you prefer for developing this plugin?",
261
- theme: selectTheme,
262
- });
263
- }
264
- async collectType() {
265
- return await select({
266
- choices: [
267
- {
268
- name: "Extension",
269
- value: "extension",
270
- description: "Extend capabilities by integrating with external APIs.",
271
- },
272
- {
273
- name: "Model",
274
- value: "llm",
275
- description: "Introduce more LLMs to enhance AI capabilities.",
276
- },
277
- {
278
- name: "Tool",
279
- value: "tool",
280
- description: "Complete specific tasks, typically invoked by LLMs.",
281
- },
282
- {
283
- name: "Trigger",
284
- value: "trigger",
285
- description: "Run workflows by receiving events through webhooks.",
286
- },
287
- ],
288
- message: dedent `
289
- ${colorize("blue", "Choose the type of the new plugin")}
290
-
291
- Plugins can extend the platform's capabilities in multiple ways, making workflows more flexible and powerful.
292
- Based on your specific requirement, plugins can be categorized into the following types:
293
-
294
- - ${colorize("yellowBright", "Extension")}: Provide more functionality to workflows by integrating external service APIs
295
- - ${colorize("yellowBright", "Model")}: Access more large language models to enrich the AI capabilities of workflows
296
- - ${colorize("yellowBright", "Tool")}: Customized logic to perform specific tasks, typically invoked by LLMs and/or Agents
297
- - ${colorize("yellowBright", "Trigger")}: Receive external events through webhooks to start workflows with initial input data
298
-
299
- Please select the matching type from the following options:
300
- `,
301
- theme: selectTheme,
302
- });
303
- }
304
- async collectPermissions(flags) {
305
- return await checkbox({
306
- choices: [
307
- new Separator(colorize("yellowBright", " ⎯⎯⎯⎯⎯ Endpoints ⎯⎯⎯⎯⎯")),
308
- {
309
- checked: flags.permissions?.includes("endpoints:register"),
310
- value: "endpoints:register",
311
- description: "Ability to register API endpoints",
312
- },
313
- new Separator(colorize("yellowBright", " ⎯⎯⎯⎯⎯ Model ⎯⎯⎯⎯⎯")),
314
- {
315
- checked: flags.permissions?.includes("model:call_llm"),
316
- value: "model:call_llm",
317
- description: "Ability to call LLMs",
318
- },
319
- {
320
- checked: flags.permissions?.includes("model:call_embedding"),
321
- value: "model:call_embedding",
322
- description: "Ability to call embeddings models",
323
- },
324
- {
325
- checked: flags.permissions?.includes("model:call_moderation"),
326
- value: "model:call_moderation",
327
- description: "Ability to call moderation models",
328
- },
329
- {
330
- checked: flags.permissions?.includes("model:call_rerank"),
331
- value: "model:call_rerank",
332
- description: "Ability to call rerank models",
333
- },
334
- {
335
- checked: flags.permissions?.includes("model:call_stt"),
336
- value: "model:call_stt",
337
- description: "Ability to call STT models",
338
- },
339
- {
340
- checked: flags.permissions?.includes("model:call_tts"),
341
- value: "model:call_tts",
342
- description: "Ability to call TTS models",
343
- },
344
- new Separator(colorize("yellowBright", " ⎯⎯⎯⎯⎯ Storage ⎯⎯⎯⎯⎯")),
345
- {
346
- checked: flags.permissions?.includes("storage:kv"),
347
- value: "storage:kv",
348
- description: "Ability to use key-value storage",
349
- },
350
- new Separator(colorize("yellowBright", " ⎯⎯⎯⎯⎯ Tools ⎯⎯⎯⎯⎯")),
351
- {
352
- checked: flags.permissions?.includes("tools:invoke"),
353
- value: "tools:invoke",
354
- description: "Ability to invoke other tools",
355
- },
356
- ],
357
- loop: false,
358
- pageSize: 15,
359
- message: "Select required permissions for the plugin:",
360
- theme: checkboxTheme,
361
- });
362
- }
363
- }
@@ -1,13 +0,0 @@
1
- import { Command } from "@oclif/core";
2
- export default class PluginPack extends Command {
3
- static args: {
4
- file: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
- };
6
- static description: string;
7
- static examples: string[];
8
- static flags: {
9
- force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- };
12
- run(): Promise<void>;
13
- }
@@ -1,22 +0,0 @@
1
- import { Args, Command, Flags } from "@oclif/core";
2
- export default class PluginPack extends Command {
3
- static args = {
4
- file: Args.string({ description: "file to read" }),
5
- };
6
- static description = "describe the command here";
7
- static examples = ["<%= config.bin %> <%= command.id %>"];
8
- static flags = {
9
- // flag with no value (-f, --force)
10
- force: Flags.boolean({ char: "f" }),
11
- // flag with a value (-n, --name=VALUE)
12
- name: Flags.string({ char: "n", description: "name to print" }),
13
- };
14
- async run() {
15
- const { args, flags } = await this.parse(PluginPack);
16
- const name = flags.name ?? "world";
17
- this.log(`hello ${name} from /Users/nightire/Code/github.com/choice-open/automation-plugin-cli/src/commands/plugin/pack.ts`);
18
- if (args.file && flags.force) {
19
- this.log(`you input --force and --file: ${args.file}`);
20
- }
21
- }
22
- }
@@ -1,13 +0,0 @@
1
- import { Command } from "@oclif/core";
2
- export default class PluginPermission extends Command {
3
- static args: {
4
- file: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
- };
6
- static description: string;
7
- static examples: string[];
8
- static flags: {
9
- force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- };
12
- run(): Promise<void>;
13
- }
@@ -1,22 +0,0 @@
1
- import { Args, Command, Flags } from "@oclif/core";
2
- export default class PluginPermission extends Command {
3
- static args = {
4
- file: Args.string({ description: "file to read" }),
5
- };
6
- static description = "describe the command here";
7
- static examples = ["<%= config.bin %> <%= command.id %>"];
8
- static flags = {
9
- // flag with no value (-f, --force)
10
- force: Flags.boolean({ char: "f" }),
11
- // flag with a value (-n, --name=VALUE)
12
- name: Flags.string({ char: "n", description: "name to print" }),
13
- };
14
- async run() {
15
- const { args, flags } = await this.parse(PluginPermission);
16
- const name = flags.name ?? "world";
17
- this.log(`hello ${name} from /Users/nightire/Code/github.com/choice-open/automation-plugin-cli/src/commands/plugin/permission.ts`);
18
- if (args.file && flags.force) {
19
- this.log(`you input --force and --file: ${args.file}`);
20
- }
21
- }
22
- }
@@ -1,13 +0,0 @@
1
- import { Command } from "@oclif/core";
2
- export default class PluginRun extends Command {
3
- static args: {
4
- file: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
- };
6
- static description: string;
7
- static examples: string[];
8
- static flags: {
9
- force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- };
12
- run(): Promise<void>;
13
- }