@choiceopen/automation-plugin-cli 0.0.1 → 0.1.2
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 +9 -134
- package/dist/commands/auth/login.js +12 -10
- package/dist/commands/plugin/index.js +1 -0
- package/dist/commands/plugin/refresh-key.js +103 -0
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.js +12 -2
- package/oclif.manifest.json +6 -337
- package/package.json +1 -1
- package/dist/commands/auth/index.d.ts +0 -11
- package/dist/commands/auth/index.js +0 -15
- package/dist/commands/auth/login.d.ts +0 -15
- package/dist/commands/plugin/checksum.d.ts +0 -13
- package/dist/commands/plugin/checksum.js +0 -22
- package/dist/commands/plugin/index.d.ts +0 -11
- package/dist/commands/plugin/init.d.ts +0 -33
- package/dist/commands/plugin/init.js +0 -363
- package/dist/commands/plugin/pack.d.ts +0 -13
- package/dist/commands/plugin/pack.js +0 -22
- package/dist/commands/plugin/permission.d.ts +0 -13
- package/dist/commands/plugin/permission.js +0 -22
- package/dist/commands/plugin/run.d.ts +0 -13
- package/dist/commands/plugin/run.js +0 -22
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/utils/generator.d.ts +0 -20
- package/dist/utils/generator.js +0 -68
- package/dist/utils/theme.d.ts +0 -13
- package/dist/utils/theme.js +0 -13
- package/dist/utils/views.d.ts +0 -2
- package/dist/utils/views.js +0 -8
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.
|
|
23
|
+
@choiceopen/automation-plugin-cli/0.1.2 darwin-arm64 node-v24.12.0
|
|
24
24
|
$ automation --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ automation COMMAND
|
|
@@ -32,11 +32,7 @@ USAGE
|
|
|
32
32
|
* [`automation auth login`](#automation-auth-login)
|
|
33
33
|
* [`automation autocomplete [SHELL]`](#automation-autocomplete-shell)
|
|
34
34
|
* [`automation help [COMMAND]`](#automation-help-command)
|
|
35
|
-
* [`automation plugin
|
|
36
|
-
* [`automation plugin init`](#automation-plugin-init)
|
|
37
|
-
* [`automation plugin pack [FILE]`](#automation-plugin-pack-file)
|
|
38
|
-
* [`automation plugin permission [FILE]`](#automation-plugin-permission-file)
|
|
39
|
-
* [`automation plugin run [FILE]`](#automation-plugin-run-file)
|
|
35
|
+
* [`automation plugin refresh-key`](#automation-plugin-refresh-key)
|
|
40
36
|
* [`automation version`](#automation-version)
|
|
41
37
|
|
|
42
38
|
## `automation auth login`
|
|
@@ -61,7 +57,7 @@ EXAMPLES
|
|
|
61
57
|
$ automation auth login
|
|
62
58
|
```
|
|
63
59
|
|
|
64
|
-
_See code: [src/commands/auth/login.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.
|
|
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)_
|
|
65
61
|
|
|
66
62
|
## `automation autocomplete [SHELL]`
|
|
67
63
|
|
|
@@ -114,143 +110,22 @@ DESCRIPTION
|
|
|
114
110
|
|
|
115
111
|
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.36/src/commands/help.ts)_
|
|
116
112
|
|
|
117
|
-
## `automation plugin
|
|
113
|
+
## `automation plugin refresh-key`
|
|
118
114
|
|
|
119
|
-
|
|
115
|
+
Refresh or create API Key for plugin debugging in development stage.
|
|
120
116
|
|
|
121
117
|
```
|
|
122
118
|
USAGE
|
|
123
|
-
$ automation plugin
|
|
124
|
-
|
|
125
|
-
ARGUMENTS
|
|
126
|
-
[FILE] file to read
|
|
127
|
-
|
|
128
|
-
FLAGS
|
|
129
|
-
-f, --force
|
|
130
|
-
-n, --name=<value> name to print
|
|
131
|
-
|
|
132
|
-
DESCRIPTION
|
|
133
|
-
describe the command here
|
|
134
|
-
|
|
135
|
-
EXAMPLES
|
|
136
|
-
$ automation plugin checksum
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
_See code: [src/commands/plugin/checksum.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.0.1/src/commands/plugin/checksum.ts)_
|
|
140
|
-
|
|
141
|
-
## `automation plugin init`
|
|
142
|
-
|
|
143
|
-
Initialize a new plugin with step-by-step interactive instructions.
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
USAGE
|
|
147
|
-
$ automation plugin init [-i] [-n my-awesome-plugin] [-d Descriptive
|
|
148
|
-
text...] [-a John Doe] [-e john.doe@example.com] [-u <value>] [--locales en_US|zh_Hans|ja_JP...] [-l
|
|
149
|
-
elixir|python|typescript] [-t extension|llm|tool|trigger] [-p endpoints:register|model:call_llm|model:call_embedding
|
|
150
|
-
|model:call_moderation|model:call_rerank|model:call_stt|model:call_tts|storage:kv|tools:invoke...]
|
|
151
|
-
|
|
152
|
-
FLAGS
|
|
153
|
-
-a, --author=John Doe Author name
|
|
154
|
-
-d, --description=Descriptive text... Short description
|
|
155
|
-
-e, --email=john.doe@example.com Author email address
|
|
156
|
-
-i, --[no-]interactive Use interactive mode (by default)
|
|
157
|
-
-l, --language=<option> Programming language to use for plugin development
|
|
158
|
-
<options: elixir|python|typescript>
|
|
159
|
-
-n, --name=my-awesome-plugin Plugin name
|
|
160
|
-
-p, --permissions=<option>... Permissions required by the plugin
|
|
161
|
-
<options:
|
|
162
|
-
endpoints:register|model:call_llm|model:call_embedding|model:call_moderation|mo
|
|
163
|
-
del:call_rerank|model:call_stt|model:call_tts|storage:kv|tools:invoke>
|
|
164
|
-
-t, --type=<option> Plugin type
|
|
165
|
-
<options: extension|llm|tool|trigger>
|
|
166
|
-
-u, --url=<value> Repository URL
|
|
167
|
-
--locales=<option>... Provide READMEs in which languages
|
|
168
|
-
<options: en_US|zh_Hans|ja_JP>
|
|
169
|
-
|
|
170
|
-
DESCRIPTION
|
|
171
|
-
Initialize a new plugin with step-by-step interactive instructions.
|
|
172
|
-
|
|
173
|
-
Providing required flags skips interactive flow and completes initialization in one go.
|
|
174
|
-
|
|
175
|
-
EXAMPLES
|
|
176
|
-
Start with interactive initialization:
|
|
177
|
-
|
|
178
|
-
$ automation plugin init
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
_See code: [src/commands/plugin/init.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.0.1/src/commands/plugin/init.ts)_
|
|
182
|
-
|
|
183
|
-
## `automation plugin pack [FILE]`
|
|
184
|
-
|
|
185
|
-
describe the command here
|
|
186
|
-
|
|
187
|
-
```
|
|
188
|
-
USAGE
|
|
189
|
-
$ automation plugin pack [FILE] [-f] [-n <value>]
|
|
190
|
-
|
|
191
|
-
ARGUMENTS
|
|
192
|
-
[FILE] file to read
|
|
193
|
-
|
|
194
|
-
FLAGS
|
|
195
|
-
-f, --force
|
|
196
|
-
-n, --name=<value> name to print
|
|
197
|
-
|
|
198
|
-
DESCRIPTION
|
|
199
|
-
describe the command here
|
|
200
|
-
|
|
201
|
-
EXAMPLES
|
|
202
|
-
$ automation plugin pack
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
_See code: [src/commands/plugin/pack.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.0.1/src/commands/plugin/pack.ts)_
|
|
206
|
-
|
|
207
|
-
## `automation plugin permission [FILE]`
|
|
208
|
-
|
|
209
|
-
describe the command here
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
USAGE
|
|
213
|
-
$ automation plugin permission [FILE] [-f] [-n <value>]
|
|
214
|
-
|
|
215
|
-
ARGUMENTS
|
|
216
|
-
[FILE] file to read
|
|
217
|
-
|
|
218
|
-
FLAGS
|
|
219
|
-
-f, --force
|
|
220
|
-
-n, --name=<value> name to print
|
|
221
|
-
|
|
222
|
-
DESCRIPTION
|
|
223
|
-
describe the command here
|
|
224
|
-
|
|
225
|
-
EXAMPLES
|
|
226
|
-
$ automation plugin permission
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
_See code: [src/commands/plugin/permission.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.0.1/src/commands/plugin/permission.ts)_
|
|
230
|
-
|
|
231
|
-
## `automation plugin run [FILE]`
|
|
232
|
-
|
|
233
|
-
describe the command here
|
|
234
|
-
|
|
235
|
-
```
|
|
236
|
-
USAGE
|
|
237
|
-
$ automation plugin run [FILE] [-f] [-n <value>]
|
|
238
|
-
|
|
239
|
-
ARGUMENTS
|
|
240
|
-
[FILE] file to read
|
|
241
|
-
|
|
242
|
-
FLAGS
|
|
243
|
-
-f, --force
|
|
244
|
-
-n, --name=<value> name to print
|
|
119
|
+
$ automation plugin refresh-key
|
|
245
120
|
|
|
246
121
|
DESCRIPTION
|
|
247
|
-
|
|
122
|
+
Refresh or create API Key for plugin debugging in development stage.
|
|
248
123
|
|
|
249
124
|
EXAMPLES
|
|
250
|
-
$ automation plugin
|
|
125
|
+
$ automation plugin refresh-key
|
|
251
126
|
```
|
|
252
127
|
|
|
253
|
-
_See code: [src/commands/plugin/
|
|
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)_
|
|
254
129
|
|
|
255
130
|
## `automation version`
|
|
256
131
|
|
|
@@ -29,15 +29,16 @@ export default class AuthLogin extends Command {
|
|
|
29
29
|
await this.parse(AuthLogin);
|
|
30
30
|
const config = await configStore.load();
|
|
31
31
|
assert(config.auth?.endpoint, "Auth endpoint is required");
|
|
32
|
-
|
|
32
|
+
this.endpoint = config.auth.endpoint;
|
|
33
|
+
const payload = await this.requestDeviceCode(this.endpoint);
|
|
33
34
|
this.log(colorize("yellowBright", "Starting device authorization flow...\n"));
|
|
34
35
|
this.log(colorize("bold", colorize("gray", "Verification URL : ")), payload.verification_uri);
|
|
35
36
|
this.log(colorize("bold", colorize("gray", "Verification Code: ")), `${payload.user_code}\n`);
|
|
36
37
|
const autoOpen = await confirm({
|
|
37
38
|
message: dedent `
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
Do you want to open the verification URL in your browser automatically?
|
|
40
|
+
If not, you can manually open the URL and paste the code.
|
|
41
|
+
`,
|
|
41
42
|
});
|
|
42
43
|
if (autoOpen) {
|
|
43
44
|
await open(payload.verification_uri_complete);
|
|
@@ -45,7 +46,7 @@ export default class AuthLogin extends Command {
|
|
|
45
46
|
const spinner = yoctoSpinner({ text: "Polling for token..." }).start();
|
|
46
47
|
const result = (await this.pollForToken(payload.device_code, spinner));
|
|
47
48
|
await configStore.update({ auth: { access_token: result.access_token } });
|
|
48
|
-
const session = await fetch(`${
|
|
49
|
+
const session = await fetch(`${this.endpoint}/v1/auth/get-session`, {
|
|
49
50
|
headers: {
|
|
50
51
|
"Content-Type": "application/json",
|
|
51
52
|
"User-Agent": "Choiceform (Automation Plugin CLI)",
|
|
@@ -53,10 +54,10 @@ export default class AuthLogin extends Command {
|
|
|
53
54
|
},
|
|
54
55
|
}).then((response) => response.json());
|
|
55
56
|
this.log(colorize("greenBright", dedent `
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
Welcome back, ${session.user.name} <${session.user.email}>!
|
|
58
|
+
To create a new plugin, you can use the following command:
|
|
59
|
+
\`${colorize("bold", colorize("yellowBright", "automation plugin init"))}\`
|
|
60
|
+
`));
|
|
60
61
|
}
|
|
61
62
|
async requestDeviceCode(endpoint) {
|
|
62
63
|
const response = await fetch(`${endpoint}/v1/auth/device/code`, {
|
|
@@ -72,7 +73,7 @@ export default class AuthLogin extends Command {
|
|
|
72
73
|
async pollForToken(device_code, spinner) {
|
|
73
74
|
return new Promise((resolve) => {
|
|
74
75
|
const poll = async () => {
|
|
75
|
-
const response = await fetch(
|
|
76
|
+
const response = await fetch(`${this.endpoint}/v1/auth/device/token`, {
|
|
76
77
|
method: "POST",
|
|
77
78
|
headers: {
|
|
78
79
|
"Content-Type": "application/json",
|
|
@@ -92,6 +93,7 @@ export default class AuthLogin extends Command {
|
|
|
92
93
|
break;
|
|
93
94
|
case "slow_down":
|
|
94
95
|
this.pollingInterval += 5;
|
|
96
|
+
setTimeout(poll, this.pollingInterval * 1000);
|
|
95
97
|
break;
|
|
96
98
|
case "access_denied":
|
|
97
99
|
spinner.error("Access was denied by the user");
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { Command } from "@oclif/core";
|
|
4
|
+
import { colorize } from "@oclif/core/ux";
|
|
5
|
+
import { assert } from "es-toolkit";
|
|
6
|
+
import { dedent } from "ts-dedent";
|
|
7
|
+
import * as configStore from "../../utils/config.js";
|
|
8
|
+
export default class PluginRefreshKey extends Command {
|
|
9
|
+
static description = dedent `Refresh or create API Key for plugin debugging in development stage.`;
|
|
10
|
+
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
11
|
+
async run() {
|
|
12
|
+
await this.parse(PluginRefreshKey);
|
|
13
|
+
// Step 1: Check access token
|
|
14
|
+
const config = await configStore.load();
|
|
15
|
+
if (!config.auth?.access_token) {
|
|
16
|
+
this.log(colorize("red", "✗ You're not authenticated yet, please run 'automation auth login' first."));
|
|
17
|
+
return process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
// Step 2: Fetch debug API Key
|
|
21
|
+
const apiKey = await this.fetchDebugApiKey(config.auth.access_token);
|
|
22
|
+
// Step 3: Manage .env file
|
|
23
|
+
await this.updateEnvFile(apiKey);
|
|
24
|
+
// Display success message
|
|
25
|
+
this.log(colorize("green", "✓ Debug API Key refreshed successfully"));
|
|
26
|
+
this.log(colorize("green", "✓ DEBUG_API_KEY updated in .env file"));
|
|
27
|
+
this.log("");
|
|
28
|
+
this.log("Your debug API Key has been saved to .env file.");
|
|
29
|
+
this.log(`Key preview: ${this.maskApiKey(apiKey)}`);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
33
|
+
this.log(colorize("red", `✗ Failed to refresh debug API Key: ${message}`));
|
|
34
|
+
return process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async fetchDebugApiKey(accessToken) {
|
|
38
|
+
// Get endpoint from config, use default if not available
|
|
39
|
+
const config = await configStore.load();
|
|
40
|
+
assert(config.hub?.endpoint, "Hub endpoint is required");
|
|
41
|
+
const response = await fetch(`${config.hub.endpoint}/api/v1/debug_api_key`, {
|
|
42
|
+
method: "GET",
|
|
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
|
+
const data = (await response.json());
|
|
56
|
+
if (!data.api_key) {
|
|
57
|
+
throw new Error("API response format error: missing api_key field");
|
|
58
|
+
}
|
|
59
|
+
return data.api_key;
|
|
60
|
+
}
|
|
61
|
+
async updateEnvFile(apiKey) {
|
|
62
|
+
const envPath = join(process.cwd(), ".env");
|
|
63
|
+
try {
|
|
64
|
+
// Check if .env file exists
|
|
65
|
+
let envContent = "";
|
|
66
|
+
let existingKey = false;
|
|
67
|
+
try {
|
|
68
|
+
envContent = await fs.readFile(envPath, "utf-8");
|
|
69
|
+
existingKey = envContent.includes("DEBUG_API_KEY=");
|
|
70
|
+
}
|
|
71
|
+
catch (_error) {
|
|
72
|
+
// File doesn't exist, will create new file
|
|
73
|
+
}
|
|
74
|
+
let newContent;
|
|
75
|
+
if (existingKey) {
|
|
76
|
+
// Replace existing DEBUG_API_KEY
|
|
77
|
+
newContent = envContent.replace(/^DEBUG_API_KEY=.*$/m, `DEBUG_API_KEY=${apiKey}`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Append new DEBUG_API_KEY
|
|
81
|
+
const separator = envContent && !envContent.endsWith("\n") ? "\n" : "";
|
|
82
|
+
newContent = `${envContent + separator}DEBUG_API_KEY=${apiKey}\n`;
|
|
83
|
+
}
|
|
84
|
+
await fs.writeFile(envPath, newContent, "utf-8");
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error instanceof Error &&
|
|
88
|
+
"code" in error &&
|
|
89
|
+
error.code === "EACCES") {
|
|
90
|
+
throw new Error("Permission denied: cannot write .env file");
|
|
91
|
+
}
|
|
92
|
+
throw new Error(`Failed to update .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
maskApiKey(apiKey) {
|
|
96
|
+
if (apiKey.length <= 8) {
|
|
97
|
+
return "***";
|
|
98
|
+
}
|
|
99
|
+
const start = apiKey.substring(0, 4);
|
|
100
|
+
const end = apiKey.substring(apiKey.length - 4);
|
|
101
|
+
return `${start}...${end}`;
|
|
102
|
+
}
|
|
103
|
+
}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
4
4
|
endpoint: z.ZodOptional<z.ZodURL>;
|
|
5
5
|
access_token: z.ZodOptional<z.ZodString>;
|
|
6
6
|
}, z.core.$strip>>;
|
|
7
|
+
hub: z.ZodOptional<z.ZodObject<{
|
|
8
|
+
endpoint: z.ZodOptional<z.ZodURL>;
|
|
9
|
+
}, z.core.$strip>>;
|
|
7
10
|
}, z.core.$strip>;
|
|
8
11
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
9
12
|
export declare function save(config: Config): Promise<void>;
|
package/dist/utils/config.js
CHANGED
|
@@ -7,7 +7,7 @@ function getConfigDir() {
|
|
|
7
7
|
return process.env.CHOICEFORM_CONFIG_DIR ?? join(homedir(), ".choiceform");
|
|
8
8
|
}
|
|
9
9
|
function getConfigFile() {
|
|
10
|
-
return join(getConfigDir(), "
|
|
10
|
+
return join(getConfigDir(), "atomemo.json");
|
|
11
11
|
}
|
|
12
12
|
const ConfigSchema = z.object({
|
|
13
13
|
auth: z
|
|
@@ -16,6 +16,11 @@ const ConfigSchema = z.object({
|
|
|
16
16
|
access_token: z.string().optional(),
|
|
17
17
|
})
|
|
18
18
|
.optional(),
|
|
19
|
+
hub: z
|
|
20
|
+
.object({
|
|
21
|
+
endpoint: z.url().optional(),
|
|
22
|
+
})
|
|
23
|
+
.optional(),
|
|
19
24
|
});
|
|
20
25
|
export async function save(config) {
|
|
21
26
|
const validated = ConfigSchema.parse(config);
|
|
@@ -36,7 +41,12 @@ export async function load() {
|
|
|
36
41
|
auth: {
|
|
37
42
|
endpoint: process.env.NODE_ENV === "production"
|
|
38
43
|
? "https://oneauth.choiceform.io"
|
|
39
|
-
: "
|
|
44
|
+
: "https://oneauth.choiceform.io",
|
|
45
|
+
},
|
|
46
|
+
hub: {
|
|
47
|
+
endpoint: process.env.NODE_ENV === "production"
|
|
48
|
+
? "https://automation-plugin-api.choiceform.io"
|
|
49
|
+
: "https://automation-plugin-api.choiceform.io",
|
|
40
50
|
},
|
|
41
51
|
};
|
|
42
52
|
await save(defaultConfig);
|