@choiceopen/automation-plugin-cli 0.1.2 → 0.2.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 CHANGED
@@ -20,7 +20,7 @@ $ npm install -g @choiceopen/automation-plugin-cli
20
20
  $ automation COMMAND
21
21
  running command...
22
22
  $ automation (--version)
23
- @choiceopen/automation-plugin-cli/0.1.2 darwin-arm64 node-v24.12.0
23
+ @choiceopen/automation-plugin-cli/0.2.0 darwin-arm64 node-v24.13.0
24
24
  $ automation --help [COMMAND]
25
25
  USAGE
26
26
  $ automation COMMAND
@@ -30,9 +30,15 @@ USAGE
30
30
  # Commands
31
31
  <!-- commands -->
32
32
  * [`automation auth login`](#automation-auth-login)
33
+ * [`automation auth status`](#automation-auth-status)
33
34
  * [`automation autocomplete [SHELL]`](#automation-autocomplete-shell)
34
35
  * [`automation help [COMMAND]`](#automation-help-command)
36
+ * [`automation plugin checksum [FILE]`](#automation-plugin-checksum-file)
37
+ * [`automation plugin init`](#automation-plugin-init)
38
+ * [`automation plugin pack [FILE]`](#automation-plugin-pack-file)
39
+ * [`automation plugin permission [FILE]`](#automation-plugin-permission-file)
35
40
  * [`automation plugin refresh-key`](#automation-plugin-refresh-key)
41
+ * [`automation plugin run [FILE]`](#automation-plugin-run-file)
36
42
  * [`automation version`](#automation-version)
37
43
 
38
44
  ## `automation auth login`
@@ -57,7 +63,29 @@ EXAMPLES
57
63
  $ automation auth login
58
64
  ```
59
65
 
60
- _See code: [src/commands/auth/login.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.1.2/src/commands/auth/login.ts)_
66
+ _See code: [src/commands/auth/login.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/auth/login.ts)_
67
+
68
+ ## `automation auth status`
69
+
70
+ Display the current authentication status.
71
+
72
+ ```
73
+ USAGE
74
+ $ automation auth status
75
+
76
+ DESCRIPTION
77
+ Display the current authentication status.
78
+
79
+ Shows user information and session details if authenticated,
80
+ or prompts to login if not yet authenticated.
81
+
82
+ EXAMPLES
83
+ Check current authentication status
84
+
85
+ $ automation auth status
86
+ ```
87
+
88
+ _See code: [src/commands/auth/status.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/auth/status.ts)_
61
89
 
62
90
  ## `automation autocomplete [SHELL]`
63
91
 
@@ -110,6 +138,115 @@ DESCRIPTION
110
138
 
111
139
  _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.36/src/commands/help.ts)_
112
140
 
141
+ ## `automation plugin checksum [FILE]`
142
+
143
+ describe the command here
144
+
145
+ ```
146
+ USAGE
147
+ $ automation plugin checksum [FILE] [-f] [-n <value>]
148
+
149
+ ARGUMENTS
150
+ [FILE] file to read
151
+
152
+ FLAGS
153
+ -f, --force
154
+ -n, --name=<value> name to print
155
+
156
+ DESCRIPTION
157
+ describe the command here
158
+
159
+ EXAMPLES
160
+ $ automation plugin checksum
161
+ ```
162
+
163
+ _See code: [src/commands/plugin/checksum.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/plugin/checksum.ts)_
164
+
165
+ ## `automation plugin init`
166
+
167
+ Initialize a new plugin with step-by-step interactive instructions.
168
+
169
+ ```
170
+ USAGE
171
+ $ automation plugin init [-i] [-n my-awesome-plugin] [-d Descriptive
172
+ text...] [-a John Doe] [-e john.doe@example.com] [-u <value>] [--locales en_US|zh_Hans|ja_JP...] [-l
173
+ elixir|python|typescript] [-t extension|llm|tool|trigger]
174
+
175
+ FLAGS
176
+ -a, --author=John Doe Author name
177
+ -d, --description=Descriptive text... Short description
178
+ -e, --email=john.doe@example.com Author email address
179
+ -i, --[no-]interactive Use interactive mode (by default)
180
+ -l, --language=<option> Programming language to use for plugin development
181
+ <options: elixir|python|typescript>
182
+ -n, --name=my-awesome-plugin Plugin name
183
+ -t, --type=<option> Plugin type
184
+ <options: extension|llm|tool|trigger>
185
+ -u, --url=<value> Repository URL
186
+ --locales=<option>... Provide READMEs in which languages
187
+ <options: en_US|zh_Hans|ja_JP>
188
+
189
+ DESCRIPTION
190
+ Initialize a new plugin with step-by-step interactive instructions.
191
+
192
+ Providing required flags skips interactive flow and completes initialization in one go.
193
+
194
+ EXAMPLES
195
+ Start with interactive initialization:
196
+
197
+ $ automation plugin init
198
+ ```
199
+
200
+ _See code: [src/commands/plugin/init.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/plugin/init.ts)_
201
+
202
+ ## `automation plugin pack [FILE]`
203
+
204
+ describe the command here
205
+
206
+ ```
207
+ USAGE
208
+ $ automation plugin pack [FILE] [-f] [-n <value>]
209
+
210
+ ARGUMENTS
211
+ [FILE] file to read
212
+
213
+ FLAGS
214
+ -f, --force
215
+ -n, --name=<value> name to print
216
+
217
+ DESCRIPTION
218
+ describe the command here
219
+
220
+ EXAMPLES
221
+ $ automation plugin pack
222
+ ```
223
+
224
+ _See code: [src/commands/plugin/pack.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/plugin/pack.ts)_
225
+
226
+ ## `automation plugin permission [FILE]`
227
+
228
+ describe the command here
229
+
230
+ ```
231
+ USAGE
232
+ $ automation plugin permission [FILE] [-f] [-n <value>]
233
+
234
+ ARGUMENTS
235
+ [FILE] file to read
236
+
237
+ FLAGS
238
+ -f, --force
239
+ -n, --name=<value> name to print
240
+
241
+ DESCRIPTION
242
+ describe the command here
243
+
244
+ EXAMPLES
245
+ $ automation plugin permission
246
+ ```
247
+
248
+ _See code: [src/commands/plugin/permission.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/plugin/permission.ts)_
249
+
113
250
  ## `automation plugin refresh-key`
114
251
 
115
252
  Refresh or create API Key for plugin debugging in development stage.
@@ -125,7 +262,31 @@ EXAMPLES
125
262
  $ automation plugin refresh-key
126
263
  ```
127
264
 
128
- _See code: [src/commands/plugin/refresh-key.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.1.2/src/commands/plugin/refresh-key.ts)_
265
+ _See code: [src/commands/plugin/refresh-key.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/plugin/refresh-key.ts)_
266
+
267
+ ## `automation plugin run [FILE]`
268
+
269
+ describe the command here
270
+
271
+ ```
272
+ USAGE
273
+ $ automation plugin run [FILE] [-f] [-n <value>]
274
+
275
+ ARGUMENTS
276
+ [FILE] file to read
277
+
278
+ FLAGS
279
+ -f, --force
280
+ -n, --name=<value> name to print
281
+
282
+ DESCRIPTION
283
+ describe the command here
284
+
285
+ EXAMPLES
286
+ $ automation plugin run
287
+ ```
288
+
289
+ _See code: [src/commands/plugin/run.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.0/src/commands/plugin/run.ts)_
129
290
 
130
291
  ## `automation version`
131
292
 
@@ -0,0 +1,11 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Auth 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
+ }
@@ -0,0 +1,15 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Auth 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", ["auth"]);
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class AuthLogin extends Command {
3
+ static description: string;
4
+ static examples: {
5
+ command: string;
6
+ description: string;
7
+ }[];
8
+ static flags: {};
9
+ private pollingInterval;
10
+ private client_id;
11
+ private grant_type;
12
+ private endpoint;
13
+ run(): Promise<void>;
14
+ private requestDeviceCode;
15
+ private pollForToken;
16
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class AuthStatus extends Command {
3
+ static description: string;
4
+ static examples: {
5
+ command: string;
6
+ description: string;
7
+ }[];
8
+ run(): Promise<void>;
9
+ private fetchSession;
10
+ private formatDate;
11
+ }
@@ -0,0 +1,61 @@
1
+ import { Command } from "@oclif/core";
2
+ import { colorize } from "@oclif/core/ux";
3
+ import { assert } from "es-toolkit";
4
+ import { dedent } from "ts-dedent";
5
+ import * as configStore from "../../utils/config.js";
6
+ export default class AuthStatus extends Command {
7
+ static description = dedent `
8
+ Display the current authentication status.
9
+
10
+ Shows user information and session details if authenticated,
11
+ or prompts to login if not yet authenticated.
12
+ `;
13
+ static examples = [
14
+ {
15
+ command: "<%= config.bin %> <%= command.id %>",
16
+ description: "Check current authentication status",
17
+ },
18
+ ];
19
+ async run() {
20
+ await this.parse(AuthStatus);
21
+ const config = await configStore.load();
22
+ if (!config.auth?.access_token) {
23
+ this.log(colorize("yellow", "Your device has not been authenticated yet. Please execute `automation auth login`."));
24
+ return;
25
+ }
26
+ assert(config.auth?.endpoint, "Auth endpoint is required");
27
+ try {
28
+ const session = await this.fetchSession(config.auth.endpoint, config.auth.access_token);
29
+ this.log(colorize("greenBright", "✓ Authenticated\n"));
30
+ this.log(colorize("bold", colorize("gray", "Name : ")), session.user.name);
31
+ this.log(colorize("bold", colorize("gray", "Email : ")), session.user.email);
32
+ this.log(colorize("bold", colorize("gray", "Updated : ")), this.formatDate(session.session.updatedAt));
33
+ this.log(colorize("bold", colorize("gray", "Expires : ")), this.formatDate(session.session.expiresAt));
34
+ }
35
+ catch (error) {
36
+ const message = error instanceof Error ? error.message : "Unknown error";
37
+ this.log(colorize("red", `✗ Failed to fetch session: ${message}`));
38
+ process.exit(1);
39
+ }
40
+ }
41
+ async fetchSession(endpoint, accessToken) {
42
+ const response = await fetch(`${endpoint}/v1/auth/get-session`, {
43
+ headers: {
44
+ "Content-Type": "application/json",
45
+ "User-Agent": "Choiceform (Automation Plugin CLI)",
46
+ Authorization: `Bearer ${accessToken}`,
47
+ },
48
+ });
49
+ if (!response.ok) {
50
+ if (response.status === 401) {
51
+ throw new Error("Access token is invalid or expired, please login again");
52
+ }
53
+ throw new Error(`API request failed: ${response.status} ${response.statusText}`);
54
+ }
55
+ return (await response.json());
56
+ }
57
+ formatDate(isoDate) {
58
+ const date = new Date(isoDate);
59
+ return date.toLocaleString();
60
+ }
61
+ }
@@ -0,0 +1,13 @@
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
+ }
@@ -0,0 +1,22 @@
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
+ }
@@ -0,0 +1,11 @@
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
+ }
@@ -0,0 +1,31 @@
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
+ };
19
+ run(): Promise<void>;
20
+ private nameIsValid;
21
+ private reconcileInteractiveFlag;
22
+ private runInteractiveMode;
23
+ private collectName;
24
+ private collectDescription;
25
+ private collectAuthor;
26
+ private collectEmail;
27
+ private collectURL;
28
+ private collectLocales;
29
+ private collectLanguage;
30
+ private collectType;
31
+ }
@@ -0,0 +1,284 @@
1
+ import path from "node:path";
2
+ import checkbox 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
+ export default class PluginInit extends Command {
15
+ static description = dedent `
16
+ Initialize a new plugin with step-by-step interactive instructions.
17
+
18
+ Providing required flags skips interactive flow and completes initialization in one go.
19
+ `;
20
+ static examples = [
21
+ {
22
+ command: "<%= config.bin %> <%= command.id %>",
23
+ description: "Start with interactive initialization:",
24
+ },
25
+ ];
26
+ static flags = {
27
+ interactive: Flags.boolean({
28
+ allowNo: true,
29
+ char: "i",
30
+ default: true,
31
+ summary: "Use interactive mode (by default)",
32
+ }),
33
+ name: Flags.string({
34
+ char: "n",
35
+ helpValue: "my-awesome-plugin",
36
+ summary: "Plugin name",
37
+ }),
38
+ description: Flags.string({
39
+ char: "d",
40
+ default: "",
41
+ helpValue: "Descriptive text...",
42
+ summary: "Short description",
43
+ }),
44
+ author: Flags.string({
45
+ char: "a",
46
+ default: "",
47
+ helpValue: "John Doe",
48
+ summary: "Author name",
49
+ }),
50
+ email: Flags.string({
51
+ char: "e",
52
+ default: "",
53
+ helpValue: "john.doe@example.com",
54
+ summary: "Author email address",
55
+ }),
56
+ url: Flags.string({
57
+ char: "u",
58
+ default: "",
59
+ summary: "Repository URL",
60
+ }),
61
+ locales: Flags.option({
62
+ multiple: true,
63
+ options: LOCALES,
64
+ })({
65
+ delimiter: ",",
66
+ summary: "Provide READMEs in which languages",
67
+ }),
68
+ language: Flags.option({
69
+ multiple: false,
70
+ options: LANGUAGES,
71
+ })({
72
+ char: "l",
73
+ summary: "Programming language to use for plugin development",
74
+ }),
75
+ type: Flags.option({
76
+ multiple: false,
77
+ options: ["extension", "llm", "tool", "trigger"],
78
+ })({
79
+ char: "t",
80
+ summary: "Plugin type",
81
+ }),
82
+ };
83
+ async run() {
84
+ const { flags } = await this.parse(PluginInit);
85
+ this.reconcileInteractiveFlag(flags);
86
+ if (flags.interactive) {
87
+ await this.runInteractiveMode(flags);
88
+ }
89
+ assert(flags.name, "flags.name should be valid here...");
90
+ assert(flags.language, "flags.language should be valid here...");
91
+ const generator = createPluginGenerator(flags.language, {
92
+ props: { ...flags, createdAt: new Date().toISOString() },
93
+ target: path.join(process.cwd(), flags.name),
94
+ });
95
+ await generator.generate();
96
+ }
97
+ nameIsValid(name) {
98
+ return isString(name) && /^[a-z][a-z0-9_-]{2,62}[a-z0-9]$/.test(name);
99
+ }
100
+ reconcileInteractiveFlag(flags) {
101
+ if (flags.interactive && this.nameIsValid(flags.name)) {
102
+ flags.interactive = false;
103
+ }
104
+ if (!flags.interactive && !this.nameIsValid(flags.name)) {
105
+ this.log(colorize("redBright", dedent `
106
+ Without interactive mode, you should provide initial information manually.
107
+ Use ${colorize("blue", "automation help plugin init")} to see all available options.
108
+ `));
109
+ this.exit(0);
110
+ }
111
+ }
112
+ async runInteractiveMode(flags) {
113
+ this.log(dedent `
114
+ Guiding you through creating a new plugin in interactive mode
115
+ Please follow the instructions below to complete the process:\n
116
+ `);
117
+ try {
118
+ flags.name = await this.collectName();
119
+ flags.description = await this.collectDescription();
120
+ flags.author = await this.collectAuthor();
121
+ flags.email = await this.collectEmail();
122
+ flags.url = await this.collectURL();
123
+ flags.locales = await this.collectLocales(flags);
124
+ flags.language = await this.collectLanguage();
125
+ flags.type = await this.collectType();
126
+ }
127
+ catch (error) {
128
+ if (error instanceof Error && error.name === "ExitPromptError") {
129
+ process.exit(0);
130
+ }
131
+ throw error;
132
+ }
133
+ }
134
+ async collectName() {
135
+ return await input({
136
+ message: "What's the name of this new plugin:",
137
+ pattern: /^[a-z][a-z0-9_-]{2,62}[a-z0-9]$/,
138
+ patternError: dedent `
139
+ You must provide a name for the new plugin:
140
+ - Only lowercase letters, digits, underscores, and hyphens are allowed
141
+ - Minimum length of 4 and maximum length of 64
142
+ - Starts with a lowercase letter (not a digit)
143
+ - Ends with a lowercase letter or digit (not underscore or hyphen)
144
+ `,
145
+ });
146
+ }
147
+ async collectDescription() {
148
+ return await input({
149
+ message: "How do you describe this new plugin:",
150
+ default: "A brief description of the plugin's functionality",
151
+ prefill: "tab",
152
+ pattern: /^.{16,256}$/,
153
+ patternError: dedent `
154
+ You must provide a description for the new plugin:
155
+ - Allows any characters, minimum 16 characters, maximum 256 characters
156
+ `,
157
+ });
158
+ }
159
+ async collectAuthor() {
160
+ return await input({
161
+ message: "Who is the author of the new plugin:",
162
+ default: "John Doe",
163
+ prefill: "tab",
164
+ pattern: /^.{2,64}$/,
165
+ patternError: dedent `
166
+ You must provide the author name:
167
+ - Allows any characters, minimum 2 characters, maximum 64 characters
168
+ `,
169
+ });
170
+ }
171
+ async collectEmail() {
172
+ return await input({
173
+ message: "What is the email address of the author:",
174
+ default: "john.doe@example.com",
175
+ prefill: "tab",
176
+ pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2,})*$/,
177
+ patternError: dedent `You must provide the author email`,
178
+ });
179
+ }
180
+ async collectURL() {
181
+ return await input({
182
+ message: "What is the repository URL address (Optional):",
183
+ default: "https://github.com/[user]/[repo]",
184
+ prefill: "tab",
185
+ validate: (value) => {
186
+ const { success } = z
187
+ .url({ normalize: true, protocol: /https?|git/ })
188
+ .optional()
189
+ .safeParse(value);
190
+ return success || "You must provide a valid URL";
191
+ },
192
+ });
193
+ }
194
+ async collectLocales(flags) {
195
+ const values = await checkbox({
196
+ choices: [
197
+ {
198
+ checked: flags.locales?.includes("en_US"),
199
+ disabled: "(required)",
200
+ name: "English",
201
+ description: "English (United States)",
202
+ value: "en_US",
203
+ },
204
+ {
205
+ checked: flags.locales?.includes("zh_Hans"),
206
+ disabled: false,
207
+ name: "简体中文",
208
+ description: "Simplified Chinese (China)",
209
+ value: "zh_Hans",
210
+ },
211
+ {
212
+ checked: flags.locales?.includes("ja_JP"),
213
+ disabled: false,
214
+ name: "日本語",
215
+ description: "Japanese (Japan)",
216
+ value: "ja_JP",
217
+ },
218
+ ],
219
+ message: "Provide READMEs in which language(s)?",
220
+ theme: checkboxTheme,
221
+ });
222
+ return ["en_US", ...values];
223
+ }
224
+ async collectLanguage() {
225
+ return await select({
226
+ choices: [
227
+ {
228
+ name: "Elixir",
229
+ value: "elixir",
230
+ },
231
+ {
232
+ name: "Python",
233
+ value: "python",
234
+ },
235
+ {
236
+ name: "TypeScript",
237
+ value: "typescript",
238
+ },
239
+ ],
240
+ message: "What programming language do you prefer for developing this plugin?",
241
+ theme: selectTheme,
242
+ });
243
+ }
244
+ async collectType() {
245
+ return await select({
246
+ choices: [
247
+ {
248
+ name: "Extension",
249
+ value: "extension",
250
+ description: "Extend capabilities by integrating with external APIs.",
251
+ },
252
+ {
253
+ name: "Model",
254
+ value: "llm",
255
+ description: "Introduce more LLMs to enhance AI capabilities.",
256
+ },
257
+ {
258
+ name: "Tool",
259
+ value: "tool",
260
+ description: "Complete specific tasks, typically invoked by LLMs.",
261
+ },
262
+ {
263
+ name: "Trigger",
264
+ value: "trigger",
265
+ description: "Run workflows by receiving events through webhooks.",
266
+ },
267
+ ],
268
+ message: dedent `
269
+ ${colorize("blue", "Choose the type of the new plugin")}
270
+
271
+ Plugins can extend the platform's capabilities in multiple ways, making workflows more flexible and powerful.
272
+ Based on your specific requirement, plugins can be categorized into the following types:
273
+
274
+ - ${colorize("yellowBright", "Extension")}: Provide more functionality to workflows by integrating external service APIs
275
+ - ${colorize("yellowBright", "Model")}: Access more large language models to enrich the AI capabilities of workflows
276
+ - ${colorize("yellowBright", "Tool")}: Customized logic to perform specific tasks, typically invoked by LLMs and/or Agents
277
+ - ${colorize("yellowBright", "Trigger")}: Receive external events through webhooks to start workflows with initial input data
278
+
279
+ Please select the matching type from the following options:
280
+ `,
281
+ theme: selectTheme,
282
+ });
283
+ }
284
+ }