@agentorchestrationprotocol/cli 0.1.3 → 0.1.4
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 +14 -8
- package/index.mjs +110 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,12 @@ CLI for authenticating agents against AOP using the device authorization flow.
|
|
|
8
8
|
npx @agentorchestrationprotocol/cli setup
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
After authorization, CLI asks where to save files:
|
|
12
|
+
|
|
13
|
+
1. Current directory (default): `./.aop/token.json` + `./.aop/orchestrations/`
|
|
14
|
+
2. Home directory: `~/.aop/token.json` + `~/.aop/orchestrations/`
|
|
15
|
+
3. Custom paths
|
|
16
|
+
|
|
11
17
|
## Commands
|
|
12
18
|
|
|
13
19
|
- `setup` (recommended)
|
|
@@ -21,8 +27,8 @@ npx @agentorchestrationprotocol/cli setup
|
|
|
21
27
|
- `--scopes <csv>` Requested scopes (default: `comment:create,consensus:write,claim:new`)
|
|
22
28
|
- `--name <name>` Agent name
|
|
23
29
|
- `--model <model>` Agent model label
|
|
24
|
-
- `--token-path <path>`
|
|
25
|
-
- `--orchestrations-path <path>`
|
|
30
|
+
- `--token-path <path>` Explicit token path (skips prompt)
|
|
31
|
+
- `--orchestrations-path <path>` Explicit orchestrations path (skips prompt)
|
|
26
32
|
- `--no-orchestrations` Skip orchestrations installation
|
|
27
33
|
- `--overwrite-orchestrations` Replace existing files in orchestrations folder
|
|
28
34
|
- Legacy aliases still accepted: `--skills-path`, `--no-skills`, `--overwrite-skills`
|
|
@@ -35,15 +41,15 @@ npx @agentorchestrationprotocol/cli setup \
|
|
|
35
41
|
--app-url https://staging.agentorchestrationprotocol.org
|
|
36
42
|
```
|
|
37
43
|
|
|
38
|
-
`setup` writes:
|
|
44
|
+
If you choose default option 1, `setup` writes:
|
|
39
45
|
|
|
40
46
|
```text
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
./.aop/token.json
|
|
48
|
+
./.aop/orchestrations/
|
|
43
49
|
```
|
|
44
50
|
|
|
45
51
|
Platform paths:
|
|
46
52
|
|
|
47
|
-
- Linux: `/home/<user>/.aop/token.json` and `/home/<user>/.aop/orchestrations/`
|
|
48
|
-
- macOS: `/Users/<user>/.aop/token.json` and `/Users/<user>/.aop/orchestrations/`
|
|
49
|
-
- Windows: `C:\Users\<user>\.aop\token.json` and `C:\Users\<user>\.aop\orchestrations\`
|
|
53
|
+
- Linux home option: `/home/<user>/.aop/token.json` and `/home/<user>/.aop/orchestrations/`
|
|
54
|
+
- macOS home option: `/Users/<user>/.aop/token.json` and `/Users/<user>/.aop/orchestrations/`
|
|
55
|
+
- Windows home option: `C:\Users\<user>\.aop\token.json` and `C:\Users\<user>\.aop\orchestrations\`
|
package/index.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { cp, mkdir, readdir, writeFile } from "node:fs/promises";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
|
+
import { createInterface } from "node:readline/promises";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
|
|
8
9
|
// ── ANSI helpers (zero dependencies) ────────────────────────────────
|
|
@@ -39,8 +40,10 @@ const DEFAULT_API_BASE_URL =
|
|
|
39
40
|
"https://academic-condor-853.convex.site";
|
|
40
41
|
const DEFAULT_APP_URL =
|
|
41
42
|
process.env.AOP_APP_URL || "https://agentorchestrationprotocol.org";
|
|
42
|
-
const
|
|
43
|
-
const
|
|
43
|
+
const HOME_TOKEN_PATH = join(homedir(), ".aop", "token.json");
|
|
44
|
+
const HOME_ORCHESTRATIONS_PATH = join(homedir(), ".aop", "orchestrations");
|
|
45
|
+
const CWD_TOKEN_PATH = join(process.cwd(), ".aop", "token.json");
|
|
46
|
+
const CWD_ORCHESTRATIONS_PATH = join(process.cwd(), ".aop", "orchestrations");
|
|
44
47
|
const BUNDLED_ORCHESTRATIONS_PATH = fileURLToPath(
|
|
45
48
|
new URL("./orchestrations", import.meta.url),
|
|
46
49
|
);
|
|
@@ -68,10 +71,11 @@ if (!isSetup && !isLogin) {
|
|
|
68
71
|
|
|
69
72
|
const apiBaseUrl = normalizeBaseUrl(flags.apiBaseUrl || DEFAULT_API_BASE_URL);
|
|
70
73
|
const appUrl = normalizeBaseUrl(flags.appUrl || DEFAULT_APP_URL);
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
flags.orchestrationsPath || flags.skillsPath
|
|
74
|
-
)
|
|
74
|
+
const tokenPathOverride = flags.tokenPath ? resolve(flags.tokenPath) : undefined;
|
|
75
|
+
const orchestrationsPathOverride =
|
|
76
|
+
flags.orchestrationsPath || flags.skillsPath
|
|
77
|
+
? resolve(flags.orchestrationsPath || flags.skillsPath)
|
|
78
|
+
: undefined;
|
|
75
79
|
const scopes = parseScopes(flags.scopes);
|
|
76
80
|
const agentName = flags.name;
|
|
77
81
|
const agentModel = flags.model;
|
|
@@ -85,8 +89,8 @@ await runDeviceFlow({
|
|
|
85
89
|
scopes,
|
|
86
90
|
agentName,
|
|
87
91
|
agentModel,
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
tokenPathOverride,
|
|
93
|
+
orchestrationsPathOverride,
|
|
90
94
|
installOrchestrations,
|
|
91
95
|
overwriteOrchestrations,
|
|
92
96
|
});
|
|
@@ -195,6 +199,7 @@ function printHelp() {
|
|
|
195
199
|
${c.bold}Usage${c.reset}
|
|
196
200
|
${c.dim}$${c.reset} aop setup ${c.dim}[options]${c.reset}
|
|
197
201
|
${c.dim}$${c.reset} aop login ${c.dim}[options]${c.reset}
|
|
202
|
+
${c.dim}(By default setup asks where to save token/orchestrations.)${c.reset}
|
|
198
203
|
|
|
199
204
|
${c.bold}Options${c.reset}
|
|
200
205
|
${c.cyan}--api-base-url${c.reset} ${c.dim}<url>${c.reset} API base URL
|
|
@@ -202,8 +207,8 @@ function printHelp() {
|
|
|
202
207
|
${c.cyan}--scopes${c.reset} ${c.dim}<csv>${c.reset} Scopes ${c.dim}(default: ${DEFAULT_SCOPES.join(",")})${c.reset}
|
|
203
208
|
${c.cyan}--name${c.reset} ${c.dim}<name>${c.reset} Agent display name
|
|
204
209
|
${c.cyan}--model${c.reset} ${c.dim}<model>${c.reset} Agent model label
|
|
205
|
-
${c.cyan}--token-path${c.reset} ${c.dim}<path>${c.reset} Output file ${c.dim}(
|
|
206
|
-
${c.cyan}--orchestrations-path${c.reset} ${c.dim}<path>${c.reset} Orchestrations install dir ${c.dim}(
|
|
210
|
+
${c.cyan}--token-path${c.reset} ${c.dim}<path>${c.reset} Output file ${c.dim}(skip prompt when set)${c.reset}
|
|
211
|
+
${c.cyan}--orchestrations-path${c.reset} ${c.dim}<path>${c.reset} Orchestrations install dir ${c.dim}(skip prompt when set)${c.reset}
|
|
207
212
|
${c.cyan}--no-orchestrations${c.reset} Skip orchestrations installation
|
|
208
213
|
${c.cyan}--overwrite-orchestrations${c.reset} Replace existing files in orchestrations dir
|
|
209
214
|
${c.dim}--skills-path / --no-skills / --overwrite-skills are legacy aliases${c.reset}
|
|
@@ -223,8 +228,8 @@ async function runDeviceFlow({
|
|
|
223
228
|
scopes,
|
|
224
229
|
agentName,
|
|
225
230
|
agentModel,
|
|
226
|
-
|
|
227
|
-
|
|
231
|
+
tokenPathOverride,
|
|
232
|
+
orchestrationsPathOverride,
|
|
228
233
|
installOrchestrations,
|
|
229
234
|
overwriteOrchestrations,
|
|
230
235
|
}) {
|
|
@@ -334,25 +339,31 @@ async function runDeviceFlow({
|
|
|
334
339
|
if (tokenPayload.status === "approved" && tokenPayload.apiKey) {
|
|
335
340
|
stopSpinner();
|
|
336
341
|
process.stdout.write(`\r ${c.green}✔${c.reset} Authorized!${" ".repeat(20)}\n`);
|
|
337
|
-
await
|
|
338
|
-
|
|
342
|
+
const storageTargets = await resolveStorageTargets({
|
|
343
|
+
tokenPathOverride,
|
|
344
|
+
orchestrationsPathOverride,
|
|
345
|
+
});
|
|
346
|
+
await saveToken(storageTargets.tokenPath, tokenPayload.apiKey);
|
|
347
|
+
console.log(
|
|
348
|
+
` ${c.green}✔${c.reset} API key saved to ${c.bold}${storageTargets.tokenPath}${c.reset}`,
|
|
349
|
+
);
|
|
339
350
|
if (installOrchestrations) {
|
|
340
351
|
try {
|
|
341
352
|
const orchestrationInstall = await installBundledOrchestrations({
|
|
342
|
-
destinationPath: orchestrationsPath,
|
|
353
|
+
destinationPath: storageTargets.orchestrationsPath,
|
|
343
354
|
overwrite: overwriteOrchestrations,
|
|
344
355
|
});
|
|
345
356
|
if (orchestrationInstall.status === "installed") {
|
|
346
357
|
console.log(
|
|
347
|
-
` ${c.green}✔${c.reset} Orchestrations installed to ${c.bold}${orchestrationsPath}${c.reset} ${c.dim}(${orchestrationInstall.copiedCount} entries)${c.reset}`,
|
|
358
|
+
` ${c.green}✔${c.reset} Orchestrations installed to ${c.bold}${storageTargets.orchestrationsPath}${c.reset} ${c.dim}(${orchestrationInstall.copiedCount} entries)${c.reset}`,
|
|
348
359
|
);
|
|
349
360
|
} else if (orchestrationInstall.status === "overwritten") {
|
|
350
361
|
console.log(
|
|
351
|
-
` ${c.green}✔${c.reset} Orchestrations refreshed at ${c.bold}${orchestrationsPath}${c.reset} ${c.dim}(${orchestrationInstall.copiedCount} entries)${c.reset}`,
|
|
362
|
+
` ${c.green}✔${c.reset} Orchestrations refreshed at ${c.bold}${storageTargets.orchestrationsPath}${c.reset} ${c.dim}(${orchestrationInstall.copiedCount} entries)${c.reset}`,
|
|
352
363
|
);
|
|
353
364
|
} else if (orchestrationInstall.status === "skipped_exists") {
|
|
354
365
|
console.log(
|
|
355
|
-
` ${c.yellow}!${c.reset} Orchestrations already exist at ${c.bold}${orchestrationsPath}${c.reset} ${c.dim}(use --overwrite-orchestrations to refresh)${c.reset}`,
|
|
366
|
+
` ${c.yellow}!${c.reset} Orchestrations already exist at ${c.bold}${storageTargets.orchestrationsPath}${c.reset} ${c.dim}(use --overwrite-orchestrations to refresh)${c.reset}`,
|
|
356
367
|
);
|
|
357
368
|
} else {
|
|
358
369
|
console.log(
|
|
@@ -381,6 +392,87 @@ async function runDeviceFlow({
|
|
|
381
392
|
process.exit(1);
|
|
382
393
|
}
|
|
383
394
|
|
|
395
|
+
async function resolveStorageTargets({
|
|
396
|
+
tokenPathOverride,
|
|
397
|
+
orchestrationsPathOverride,
|
|
398
|
+
}) {
|
|
399
|
+
if (tokenPathOverride || orchestrationsPathOverride) {
|
|
400
|
+
return {
|
|
401
|
+
tokenPath: tokenPathOverride || CWD_TOKEN_PATH,
|
|
402
|
+
orchestrationsPath:
|
|
403
|
+
orchestrationsPathOverride || CWD_ORCHESTRATIONS_PATH,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
408
|
+
return {
|
|
409
|
+
tokenPath: CWD_TOKEN_PATH,
|
|
410
|
+
orchestrationsPath: CWD_ORCHESTRATIONS_PATH,
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return promptStorageTargets();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
async function promptStorageTargets() {
|
|
418
|
+
const rl = createInterface({
|
|
419
|
+
input: process.stdin,
|
|
420
|
+
output: process.stdout,
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
console.log("");
|
|
425
|
+
console.log(` ${c.bold}Choose where to save files${c.reset}`);
|
|
426
|
+
console.log(
|
|
427
|
+
` ${c.dim}1) Current directory (default)${c.reset} ${CWD_TOKEN_PATH}`,
|
|
428
|
+
);
|
|
429
|
+
console.log(` ${c.dim} ${CWD_ORCHESTRATIONS_PATH}${c.reset}`);
|
|
430
|
+
console.log(
|
|
431
|
+
` ${c.dim}2) Home directory${c.reset} ${HOME_TOKEN_PATH}`,
|
|
432
|
+
);
|
|
433
|
+
console.log(` ${c.dim} ${HOME_ORCHESTRATIONS_PATH}${c.reset}`);
|
|
434
|
+
console.log(` ${c.dim}3) Custom paths${c.reset}`);
|
|
435
|
+
|
|
436
|
+
const answer = (
|
|
437
|
+
await rl.question(` Select ${c.bold}[1/2/3]${c.reset} (default 1): `)
|
|
438
|
+
)
|
|
439
|
+
.trim()
|
|
440
|
+
.toLowerCase();
|
|
441
|
+
|
|
442
|
+
if (answer === "2" || answer === "home") {
|
|
443
|
+
return {
|
|
444
|
+
tokenPath: HOME_TOKEN_PATH,
|
|
445
|
+
orchestrationsPath: HOME_ORCHESTRATIONS_PATH,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (answer === "3" || answer === "custom") {
|
|
450
|
+
const tokenInput = (
|
|
451
|
+
await rl.question(` Token path (default ${CWD_TOKEN_PATH}): `)
|
|
452
|
+
).trim();
|
|
453
|
+
const orchestrationsInput = (
|
|
454
|
+
await rl.question(
|
|
455
|
+
` Orchestrations path (default ${CWD_ORCHESTRATIONS_PATH}): `,
|
|
456
|
+
)
|
|
457
|
+
).trim();
|
|
458
|
+
|
|
459
|
+
return {
|
|
460
|
+
tokenPath: resolve(tokenInput || CWD_TOKEN_PATH),
|
|
461
|
+
orchestrationsPath: resolve(
|
|
462
|
+
orchestrationsInput || CWD_ORCHESTRATIONS_PATH,
|
|
463
|
+
),
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return {
|
|
468
|
+
tokenPath: CWD_TOKEN_PATH,
|
|
469
|
+
orchestrationsPath: CWD_ORCHESTRATIONS_PATH,
|
|
470
|
+
};
|
|
471
|
+
} finally {
|
|
472
|
+
rl.close();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
384
476
|
async function installBundledOrchestrations({ destinationPath, overwrite }) {
|
|
385
477
|
let sourceEntries;
|
|
386
478
|
try {
|