@agentvalet/register 0.4.3 → 0.4.5

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/dist/index.js +220 -178
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import chalk7 from "chalk";
5
+ import chalk8 from "chalk";
6
6
 
7
7
  // src/wizard.ts
8
8
  import prompts from "prompts";
@@ -166,7 +166,7 @@ function parseEvent(data) {
166
166
  return null;
167
167
  }
168
168
  function sleep(ms) {
169
- return new Promise((resolve3) => setTimeout(resolve3, ms));
169
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
170
170
  }
171
171
 
172
172
  // src/save.ts
@@ -191,9 +191,9 @@ async function saveOutput(opts) {
191
191
  }
192
192
 
193
193
  // src/commands/refresh.ts
194
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync, statSync } from "fs";
194
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync, statSync } from "fs";
195
195
  import { createSign, createPrivateKey } from "crypto";
196
- import { dirname as dirname2, resolve as resolve2, join } from "path";
196
+ import { dirname as dirname2, resolve as resolve3 } from "path";
197
197
 
198
198
  // src/lib/skill-writer.ts
199
199
  import { existsSync, writeFileSync } from "fs";
@@ -410,6 +410,10 @@ To refresh this file: \`npx @agentvalet/register refresh\`
410
410
  `;
411
411
  }
412
412
 
413
+ // src/lib/require-agent.ts
414
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
415
+ import { resolve as resolve2, join } from "path";
416
+
413
417
  // src/config/store.ts
414
418
  import Conf from "conf";
415
419
  var store = new Conf({
@@ -428,24 +432,11 @@ function isAuthenticated() {
428
432
  return !!store.get("apiKey");
429
433
  }
430
434
 
431
- // src/commands/refresh.ts
432
- var CLAUDE_START = "<!-- agentvalet:start -->";
433
- var CLAUDE_END = "<!-- agentvalet:end -->";
434
- var HOOK_COMMAND = "npx @agentvalet/register refresh --if-stale --quiet 2>/dev/null || true";
435
- var HOOK_MARKER = "agentvalet/register refresh";
436
- function base64url(input) {
437
- return Buffer.from(input).toString("base64url");
438
- }
439
- function signJwt(agentId, ownerId, privateKeyPem) {
440
- const now = Math.floor(Date.now() / 1e3);
441
- const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
442
- const payload = base64url(JSON.stringify({ agent_id: agentId, owner_id: ownerId, iat: now, exp: now + 300 }));
443
- const signingInput = `${header}.${payload}`;
444
- const sign = createSign("RSA-SHA256");
445
- sign.update(signingInput);
446
- const signature = sign.sign(createPrivateKey(privateKeyPem), "base64url");
447
- return `${signingInput}.${signature}`;
448
- }
435
+ // src/lib/require-agent.ts
436
+ import chalk3 from "chalk";
437
+ var NO_AGENT_MSG = chalk3.red("\n \u2717 No agent registered.\n") + chalk3.dim(
438
+ " Run the following command first to register an agent in this directory:\n\n npx @agentvalet/register\n"
439
+ );
449
440
  function parseEnvFile(content) {
450
441
  const result = {};
451
442
  for (const line of content.split("\n")) {
@@ -457,42 +448,68 @@ function parseEnvFile(content) {
457
448
  }
458
449
  return result;
459
450
  }
460
- function writePermissionsFromEvent(agentId, ownerId, platforms, outputPath = "./.claude/agentvalet-permissions.md") {
461
- const content = generatePermissionsFile(agentId, ownerId, platforms);
462
- const resolvedPath = resolve2(outputPath);
463
- mkdirSync(dirname2(resolvedPath), { recursive: true });
464
- writeFileSync2(resolvedPath, content, "utf-8");
465
- embedInClaudeMd(content);
466
- ensureHook();
467
- }
468
- async function runRefresh(options) {
469
- const outputPath = resolve2(options.outputPath);
470
- if (options.ifStale) {
451
+ function resolveAgent(envFile = ".env.agentvalet") {
452
+ let agentId;
453
+ let ownerId;
454
+ let apiUrl = "https://api.agentvalet.ai";
455
+ let keyPath;
456
+ const envPath = resolve2(envFile);
457
+ if (existsSync2(envPath)) {
471
458
  try {
472
- const stat = statSync(outputPath);
473
- const fileIsFresh = Date.now() - stat.mtimeMs < 36e5;
474
- const claudeMdPath = resolve2("CLAUDE.md");
475
- const claudeMd = existsSync2(claudeMdPath) ? readFileSync2(claudeMdPath, "utf-8") : "";
476
- const blockStart = claudeMd.indexOf(CLAUDE_START);
477
- const blockEnd = claudeMd.indexOf(CLAUDE_END);
478
- const blockContent = blockStart !== -1 && blockEnd !== -1 ? claudeMd.slice(blockStart, blockEnd) : "";
479
- const blockHasPlatforms = blockContent.includes("### ");
480
- if (fileIsFresh && blockHasPlatforms) return;
459
+ const vars = parseEnvFile(readFileSync2(envPath, "utf-8"));
460
+ agentId = vars["AGENTVALET_AGENT_ID"];
461
+ ownerId = vars["AGENTVALET_OWNER_ID"];
462
+ apiUrl = vars["AGENTVALET_API_URL"] ?? apiUrl;
463
+ keyPath = vars["AGENTVALET_PRIVATE_KEY_PATH"];
464
+ } catch {
465
+ }
466
+ }
467
+ if (!agentId || !ownerId || !keyPath) {
468
+ const localConfigPath = join(process.cwd(), ".agentvalet", "config.json");
469
+ if (existsSync2(localConfigPath)) {
470
+ try {
471
+ const local = JSON.parse(readFileSync2(localConfigPath, "utf-8"));
472
+ agentId = agentId ?? local["agent_id"];
473
+ apiUrl = local["proxy_url"] ?? apiUrl;
474
+ keyPath = keyPath ?? join(process.cwd(), ".agentvalet", "agent.key");
475
+ } catch {
476
+ }
477
+ }
478
+ try {
479
+ const global = getStoredConfig();
480
+ if (!ownerId) ownerId = global.ownerId ?? void 0;
481
+ } catch {
482
+ }
483
+ }
484
+ if (!agentId || !ownerId || !keyPath) {
485
+ try {
486
+ const global = getStoredConfig();
487
+ agentId = agentId ?? global.lastAgentId ?? void 0;
488
+ ownerId = ownerId ?? global.ownerId ?? void 0;
489
+ keyPath = keyPath ?? global.lastKeyPath ?? void 0;
490
+ apiUrl = global.proxyUrl ?? apiUrl;
481
491
  } catch {
482
492
  }
483
493
  }
494
+ if (!agentId || !ownerId || !keyPath) {
495
+ process.stderr.write(NO_AGENT_MSG + "\n");
496
+ process.exit(1);
497
+ }
498
+ return { agentId, ownerId, keyPath, apiUrl };
499
+ }
500
+ function tryResolveAgent(envFile = ".env.agentvalet") {
484
501
  let agentId;
485
502
  let ownerId;
486
503
  let apiUrl = "https://api.agentvalet.ai";
487
504
  let keyPath;
488
- const envPath = resolve2(options.envFile);
505
+ const envPath = resolve2(envFile);
489
506
  if (existsSync2(envPath)) {
490
507
  try {
491
- const envVars = parseEnvFile(readFileSync2(envPath, "utf-8"));
492
- agentId = envVars["AGENTVALET_AGENT_ID"];
493
- ownerId = envVars["AGENTVALET_OWNER_ID"];
494
- apiUrl = envVars["AGENTVALET_API_URL"] ?? apiUrl;
495
- keyPath = envVars["AGENTVALET_PRIVATE_KEY_PATH"];
508
+ const vars = parseEnvFile(readFileSync2(envPath, "utf-8"));
509
+ agentId = vars["AGENTVALET_AGENT_ID"];
510
+ ownerId = vars["AGENTVALET_OWNER_ID"];
511
+ apiUrl = vars["AGENTVALET_API_URL"] ?? apiUrl;
512
+ keyPath = vars["AGENTVALET_PRIVATE_KEY_PATH"];
496
513
  } catch {
497
514
  }
498
515
  }
@@ -507,22 +524,72 @@ async function runRefresh(options) {
507
524
  } catch {
508
525
  }
509
526
  }
510
- if (!ownerId) {
511
- try {
512
- ownerId = getStoredConfig().ownerId ?? void 0;
513
- } catch {
514
- }
527
+ try {
528
+ const global = getStoredConfig();
529
+ if (!ownerId) ownerId = global.ownerId ?? void 0;
530
+ } catch {
515
531
  }
516
532
  }
517
533
  if (!agentId || !ownerId || !keyPath) {
518
- throw new Error(
519
- `Cannot find agent credentials.
520
- Run 'npx @agentvalet/register' in this directory first.`
521
- );
534
+ try {
535
+ const global = getStoredConfig();
536
+ agentId = agentId ?? global.lastAgentId ?? void 0;
537
+ ownerId = ownerId ?? global.ownerId ?? void 0;
538
+ keyPath = keyPath ?? global.lastKeyPath ?? void 0;
539
+ apiUrl = global.proxyUrl ?? apiUrl;
540
+ } catch {
541
+ }
522
542
  }
543
+ if (!agentId || !ownerId || !keyPath) return null;
544
+ return { agentId, ownerId, keyPath, apiUrl };
545
+ }
546
+
547
+ // src/commands/refresh.ts
548
+ var CLAUDE_START = "<!-- agentvalet:start -->";
549
+ var CLAUDE_END = "<!-- agentvalet:end -->";
550
+ var HOOK_COMMAND = "npx @agentvalet/register refresh --if-stale --quiet 2>/dev/null || true";
551
+ var HOOK_MARKER = "agentvalet/register refresh";
552
+ function base64url(input) {
553
+ return Buffer.from(input).toString("base64url");
554
+ }
555
+ function signJwt(agentId, ownerId, privateKeyPem) {
556
+ const now = Math.floor(Date.now() / 1e3);
557
+ const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
558
+ const payload = base64url(JSON.stringify({ agent_id: agentId, owner_id: ownerId, iat: now, exp: now + 300 }));
559
+ const signingInput = `${header}.${payload}`;
560
+ const sign = createSign("RSA-SHA256");
561
+ sign.update(signingInput);
562
+ const signature = sign.sign(createPrivateKey(privateKeyPem), "base64url");
563
+ return `${signingInput}.${signature}`;
564
+ }
565
+ function writePermissionsFromEvent(agentId, ownerId, platforms, outputPath = "./.claude/agentvalet-permissions.md") {
566
+ const content = generatePermissionsFile(agentId, ownerId, platforms);
567
+ const resolvedPath = resolve3(outputPath);
568
+ mkdirSync(dirname2(resolvedPath), { recursive: true });
569
+ writeFileSync2(resolvedPath, content, "utf-8");
570
+ embedInClaudeMd(content);
571
+ ensureHook();
572
+ }
573
+ async function runRefresh(options) {
574
+ const outputPath = resolve3(options.outputPath);
575
+ if (options.ifStale) {
576
+ try {
577
+ const stat = statSync(outputPath);
578
+ const fileIsFresh = Date.now() - stat.mtimeMs < 36e5;
579
+ const claudeMdPath = resolve3("CLAUDE.md");
580
+ const claudeMd = existsSync3(claudeMdPath) ? readFileSync3(claudeMdPath, "utf-8") : "";
581
+ const blockStart = claudeMd.indexOf(CLAUDE_START);
582
+ const blockEnd = claudeMd.indexOf(CLAUDE_END);
583
+ const blockContent = blockStart !== -1 && blockEnd !== -1 ? claudeMd.slice(blockStart, blockEnd) : "";
584
+ const blockHasPlatforms = blockContent.includes("### ");
585
+ if (fileIsFresh && blockHasPlatforms) return;
586
+ } catch {
587
+ }
588
+ }
589
+ const { agentId, ownerId, keyPath, apiUrl } = resolveAgent(options.envFile);
523
590
  let privateKeyPem;
524
591
  try {
525
- privateKeyPem = readFileSync2(keyPath, "utf-8");
592
+ privateKeyPem = readFileSync3(keyPath, "utf-8");
526
593
  } catch {
527
594
  throw new Error(`Cannot read private key: ${keyPath}`);
528
595
  }
@@ -549,18 +616,18 @@ Run 'npx @agentvalet/register' in this directory first.`
549
616
  }
550
617
  }
551
618
  function embedInClaudeMd(permissionsContent) {
552
- const claudeMdPath = resolve2("CLAUDE.md");
619
+ const claudeMdPath = resolve3("CLAUDE.md");
553
620
  const block = `${CLAUDE_START}
554
621
  ${permissionsContent.trimEnd()}
555
622
  ${CLAUDE_END}`;
556
- if (!existsSync2(claudeMdPath)) {
623
+ if (!existsSync3(claudeMdPath)) {
557
624
  writeFileSync2(claudeMdPath, `# Agent Instructions
558
625
 
559
626
  ${block}
560
627
  `, "utf-8");
561
628
  return;
562
629
  }
563
- const existing = readFileSync2(claudeMdPath, "utf-8");
630
+ const existing = readFileSync3(claudeMdPath, "utf-8");
564
631
  if (existing.includes(CLAUDE_START)) {
565
632
  const replaced = existing.replace(
566
633
  new RegExp(`${CLAUDE_START}[\\s\\S]*?${CLAUDE_END}`, "m"),
@@ -576,11 +643,11 @@ ${block}
576
643
  }
577
644
  }
578
645
  function ensureHook() {
579
- const settingsPath = resolve2(".claude/settings.local.json");
646
+ const settingsPath = resolve3(".claude/settings.local.json");
580
647
  let settings = {};
581
- if (existsSync2(settingsPath)) {
648
+ if (existsSync3(settingsPath)) {
582
649
  try {
583
- settings = JSON.parse(readFileSync2(settingsPath, "utf-8"));
650
+ settings = JSON.parse(readFileSync3(settingsPath, "utf-8"));
584
651
  } catch {
585
652
  return;
586
653
  }
@@ -607,51 +674,20 @@ function ensureHook() {
607
674
  ensureMcpJson();
608
675
  }
609
676
  function ensureMcpJson() {
610
- const mcpJsonPath = resolve2(".mcp.json");
677
+ const mcpJsonPath = resolve3(".mcp.json");
611
678
  let mcpConfig = {};
612
- if (existsSync2(mcpJsonPath)) {
679
+ if (existsSync3(mcpJsonPath)) {
613
680
  try {
614
- mcpConfig = JSON.parse(readFileSync2(mcpJsonPath, "utf-8"));
681
+ mcpConfig = JSON.parse(readFileSync3(mcpJsonPath, "utf-8"));
615
682
  } catch {
616
683
  return;
617
684
  }
618
685
  }
619
686
  const servers = mcpConfig.mcpServers ?? {};
620
687
  if (servers["agentvalet"]) return;
621
- let agentId;
622
- let ownerId;
623
- let apiUrl = "https://api.agentvalet.ai";
624
- let keyPath;
625
- const envPath = resolve2(".env.agentvalet");
626
- if (existsSync2(envPath)) {
627
- try {
628
- const envVars = parseEnvFile(readFileSync2(envPath, "utf-8"));
629
- agentId = envVars["AGENTVALET_AGENT_ID"];
630
- ownerId = envVars["AGENTVALET_OWNER_ID"];
631
- apiUrl = envVars["AGENTVALET_API_URL"] ?? apiUrl;
632
- keyPath = envVars["AGENTVALET_PRIVATE_KEY_PATH"];
633
- } catch {
634
- }
635
- }
636
- if (!agentId || !keyPath) {
637
- const localConfigPath = join(process.cwd(), ".agentvalet", "config.json");
638
- if (existsSync2(localConfigPath)) {
639
- try {
640
- const local = JSON.parse(readFileSync2(localConfigPath, "utf-8"));
641
- agentId = agentId ?? local["agent_id"];
642
- apiUrl = local["proxy_url"] ?? apiUrl;
643
- keyPath = keyPath ?? join(process.cwd(), ".agentvalet", "agent.key");
644
- } catch {
645
- }
646
- }
647
- if (!ownerId) {
648
- try {
649
- ownerId = getStoredConfig().ownerId ?? void 0;
650
- } catch {
651
- }
652
- }
653
- }
654
- if (!agentId || !ownerId || !keyPath) return;
688
+ const creds = tryResolveAgent();
689
+ if (!creds) return;
690
+ const { agentId, ownerId, apiUrl, keyPath } = creds;
655
691
  servers["agentvalet"] = {
656
692
  command: "npx",
657
693
  args: ["-y", "@agentvalet/register", "mcp-server"],
@@ -667,14 +703,14 @@ function ensureMcpJson() {
667
703
  }
668
704
 
669
705
  // src/commands/onboard.ts
670
- import chalk6 from "chalk";
706
+ import chalk7 from "chalk";
671
707
  import ora from "ora";
672
708
  import prompts3 from "prompts";
673
709
 
674
710
  // src/auth/github-device-flow.ts
675
711
  import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device";
676
712
  import open from "open";
677
- import chalk3 from "chalk";
713
+ import chalk4 from "chalk";
678
714
  var GITHUB_CLIENT_ID = process.env.AGENTVALET_GITHUB_CLIENT_ID ?? "Ov23liQcaW0HcqJxmLfF";
679
715
  async function authenticateWithGitHub() {
680
716
  const auth = createOAuthDeviceAuth({
@@ -683,15 +719,15 @@ async function authenticateWithGitHub() {
683
719
  scopes: ["user:email", "read:user"],
684
720
  onVerification(verification) {
685
721
  console.log("");
686
- console.log(chalk3.bold(" Authenticate with GitHub"));
722
+ console.log(chalk4.bold(" Authenticate with GitHub"));
687
723
  console.log("");
688
- console.log(` 1. Open: ${chalk3.cyan.underline(verification.verification_uri)}`);
689
- console.log(` 2. Enter code: ${chalk3.bold.yellow(verification.user_code)}`);
724
+ console.log(` 1. Open: ${chalk4.cyan.underline(verification.verification_uri)}`);
725
+ console.log(` 2. Enter code: ${chalk4.bold.yellow(verification.user_code)}`);
690
726
  console.log("");
691
727
  open(verification.verification_uri).catch(() => {
692
- console.log(chalk3.dim(" (Could not open browser \u2014 navigate to the URL above manually)"));
728
+ console.log(chalk4.dim(" (Could not open browser \u2014 navigate to the URL above manually)"));
693
729
  });
694
- console.log(chalk3.dim(" Waiting for authorisation..."));
730
+ console.log(chalk4.dim(" Waiting for authorisation..."));
695
731
  }
696
732
  });
697
733
  const tokenAuth = await auth({ type: "oauth" });
@@ -843,20 +879,20 @@ async function writeLocalConfig(config) {
843
879
  }
844
880
 
845
881
  // src/output/env.ts
846
- import chalk4 from "chalk";
882
+ import chalk5 from "chalk";
847
883
  import { appendFile as appendFile2, writeFile as writeFile3 } from "fs/promises";
848
- import { existsSync as existsSync3 } from "fs";
884
+ import { existsSync as existsSync4 } from "fs";
849
885
  import path3 from "path";
850
886
  function formatEnvBlock(vars) {
851
887
  return Object.entries(vars).map(([key, value]) => {
852
888
  const truncated = value.length > 60 ? value.substring(0, 40) + "..." + value.substring(value.length - 10) : value;
853
- return ` ${chalk4.dim(key + "=")}${chalk4.white(truncated)}`;
889
+ return ` ${chalk5.dim(key + "=")}${chalk5.white(truncated)}`;
854
890
  }).join("\n");
855
891
  }
856
892
 
857
893
  // src/config/ide.ts
858
894
  import { mkdir as mkdir3, writeFile as writeFile4, readFile as readFile2, appendFile as appendFile3 } from "fs/promises";
859
- import { existsSync as existsSync4 } from "fs";
895
+ import { existsSync as existsSync5 } from "fs";
860
896
  import path4 from "path";
861
897
  import os from "os";
862
898
  function buildMcpEntry(params) {
@@ -873,7 +909,7 @@ function buildMcpEntry(params) {
873
909
  }
874
910
  async function mergeJsonFile(filePath, key, value) {
875
911
  let existing = {};
876
- if (existsSync4(filePath)) {
912
+ if (existsSync5(filePath)) {
877
913
  try {
878
914
  const text = await readFile2(filePath, "utf8");
879
915
  existing = JSON.parse(text);
@@ -931,9 +967,9 @@ async function writeGlobalFrameworkConfigs(params) {
931
967
  const written = [];
932
968
  const codexDir = path4.join(os.homedir(), ".codex");
933
969
  const codexConfigPath = path4.join(codexDir, "config.toml");
934
- if (existsSync4(codexDir)) {
970
+ if (existsSync5(codexDir)) {
935
971
  try {
936
- const existing = existsSync4(codexConfigPath) ? await readFile2(codexConfigPath, "utf8") : "";
972
+ const existing = existsSync5(codexConfigPath) ? await readFile2(codexConfigPath, "utf8") : "";
937
973
  if (!existing.includes("[mcp_servers.agentvalet]")) {
938
974
  const addition = `
939
975
  [mcp_servers.agentvalet]
@@ -964,7 +1000,7 @@ async function writeIdeConfigs(params) {
964
1000
  console.warn(` Warning: could not write .mcp.json: ${err.message}`);
965
1001
  }
966
1002
  const claudeMdPath = path4.join(cwd, "CLAUDE.md");
967
- if (!existsSync4(claudeMdPath)) {
1003
+ if (!existsSync5(claudeMdPath)) {
968
1004
  try {
969
1005
  await writeFile4(claudeMdPath, buildClaudeMd(params.agentId, params.ownerId, params.proxyUrl), "utf8");
970
1006
  written.push("CLAUDE.md");
@@ -990,12 +1026,12 @@ async function writeIdeConfigs(params) {
990
1026
  }
991
1027
 
992
1028
  // src/config/frameworks.ts
993
- import { existsSync as existsSync5 } from "fs";
1029
+ import { existsSync as existsSync6 } from "fs";
994
1030
  import { execSync as execSync2 } from "child_process";
995
1031
  import os2 from "os";
996
1032
  import path5 from "path";
997
1033
  import prompts2 from "prompts";
998
- import chalk5 from "chalk";
1034
+ import chalk6 from "chalk";
999
1035
  function tryBinary(cmd) {
1000
1036
  try {
1001
1037
  execSync2(`${cmd} --version`, { stdio: "ignore", timeout: 3e3 });
@@ -1010,20 +1046,20 @@ function cursorInstalled() {
1010
1046
  if (platform === "win32") {
1011
1047
  const appData = process.env.APPDATA ?? path5.join(home, "AppData", "Roaming");
1012
1048
  const localAppData = process.env.LOCALAPPDATA ?? path5.join(home, "AppData", "Local");
1013
- return existsSync5(path5.join(appData, "Cursor")) || existsSync5(path5.join(localAppData, "Programs", "cursor"));
1049
+ return existsSync6(path5.join(appData, "Cursor")) || existsSync6(path5.join(localAppData, "Programs", "cursor"));
1014
1050
  }
1015
1051
  if (platform === "darwin") {
1016
- return existsSync5(path5.join(home, "Library", "Application Support", "Cursor")) || existsSync5("/Applications/Cursor.app");
1052
+ return existsSync6(path5.join(home, "Library", "Application Support", "Cursor")) || existsSync6("/Applications/Cursor.app");
1017
1053
  }
1018
- return existsSync5(path5.join(home, ".config", "Cursor")) || existsSync5("/usr/share/applications/cursor.desktop");
1054
+ return existsSync6(path5.join(home, ".config", "Cursor")) || existsSync6("/usr/share/applications/cursor.desktop");
1019
1055
  }
1020
1056
  function detectFrameworks() {
1021
1057
  const home = os2.homedir();
1022
1058
  return {
1023
- codex: existsSync5(path5.join(home, ".codex")) || tryBinary("codex"),
1024
- claudeCode: existsSync5(path5.join(home, ".claude")) || tryBinary("claude"),
1025
- cursor: existsSync5(path5.join(process.cwd(), ".cursor")) || cursorInstalled(),
1026
- openclaw: existsSync5(path5.join(home, ".openclaw"))
1059
+ codex: existsSync6(path5.join(home, ".codex")) || tryBinary("codex"),
1060
+ claudeCode: existsSync6(path5.join(home, ".claude")) || tryBinary("claude"),
1061
+ cursor: existsSync6(path5.join(process.cwd(), ".cursor")) || cursorInstalled(),
1062
+ openclaw: existsSync6(path5.join(home, ".openclaw"))
1027
1063
  };
1028
1064
  }
1029
1065
  async function frameworkSetupConsent(detected) {
@@ -1044,9 +1080,9 @@ async function frameworkSetupConsent(detected) {
1044
1080
  }
1045
1081
  if (items.length === 0) return false;
1046
1082
  console.log("");
1047
- console.log(chalk5.bold(" Detected agent frameworks"));
1083
+ console.log(chalk6.bold(" Detected agent frameworks"));
1048
1084
  for (const item of items) {
1049
- console.log(chalk5.dim(` ${item}`));
1085
+ console.log(chalk6.dim(` ${item}`));
1050
1086
  }
1051
1087
  console.log("");
1052
1088
  const { confirm } = await prompts2({
@@ -1064,13 +1100,13 @@ import path6 from "path";
1064
1100
  import { writeFile as writeFile5 } from "fs/promises";
1065
1101
  async function runOnboard() {
1066
1102
  console.log("");
1067
- console.log(chalk6.bold(" AgentValet \u2014 Agent Registration"));
1068
- console.log(chalk6.dim(" app.agentvalet.ai"));
1103
+ console.log(chalk7.bold(" AgentValet \u2014 Agent Registration"));
1104
+ console.log(chalk7.dim(" app.agentvalet.ai"));
1069
1105
  console.log("");
1070
1106
  if (isAuthenticated()) {
1071
1107
  const stored = getStoredConfig();
1072
1108
  console.log(
1073
- chalk6.green(" \u2713 Already authenticated as") + chalk6.bold(` ${stored.email}`)
1109
+ chalk7.green(" \u2713 Already authenticated as") + chalk7.bold(` ${stored.email}`)
1074
1110
  );
1075
1111
  const { action } = await prompts3({
1076
1112
  type: "select",
@@ -1091,10 +1127,10 @@ async function runOnboard() {
1091
1127
  }
1092
1128
  if (action === "signout") {
1093
1129
  clearConfig();
1094
- console.log(chalk6.dim(" Signed out. Run again to re-authenticate."));
1130
+ console.log(chalk7.dim(" Signed out. Run again to re-authenticate."));
1095
1131
  return;
1096
1132
  }
1097
- await registerAgentFlow(stored.apiKey, stored.ownerId);
1133
+ await registerAgentFlow(stored.cliToken, stored.ownerId);
1098
1134
  return;
1099
1135
  }
1100
1136
  const { authMethod } = await prompts3({
@@ -1120,14 +1156,14 @@ async function runOnboard() {
1120
1156
  const result = await authenticateWithGitHub();
1121
1157
  githubToken = result.token;
1122
1158
  } catch (err) {
1123
- console.error(chalk6.red(` \u2717 Authentication failed: ${err.message}`));
1159
+ console.error(chalk7.red(` \u2717 Authentication failed: ${err.message}`));
1124
1160
  process.exit(1);
1125
1161
  }
1126
1162
  spinner = ora(" Fetching your GitHub profile...").start();
1127
1163
  let githubUser;
1128
1164
  try {
1129
1165
  githubUser = await getGitHubUser(githubToken);
1130
- spinner.succeed(` GitHub: ${chalk6.bold("@" + githubUser.login)}`);
1166
+ spinner.succeed(` GitHub: ${chalk7.bold("@" + githubUser.login)}`);
1131
1167
  } catch (err) {
1132
1168
  spinner.fail(` Failed to fetch GitHub profile: ${err.message}`);
1133
1169
  process.exit(1);
@@ -1169,13 +1205,14 @@ async function runOnboard() {
1169
1205
  orgId: account.org_id,
1170
1206
  proxyUrl: account.proxy_url,
1171
1207
  githubUsername: githubUser.login,
1172
- email: githubUser.email
1208
+ email: githubUser.email,
1209
+ cliToken: account.cli_token
1173
1210
  });
1174
- await registerAgentFlow(account.owner_id, account.owner_id);
1211
+ await registerAgentFlow(account.cli_token, account.owner_id);
1175
1212
  }
1176
1213
  async function ownerIdFlow() {
1177
1214
  console.log("");
1178
- console.log(chalk6.dim(" Find your Owner ID at: ") + chalk6.cyan.underline("https://app.agentvalet.ai/settings"));
1215
+ console.log(chalk7.dim(" Find your Owner ID at: ") + chalk7.cyan.underline("https://app.agentvalet.ai/settings"));
1179
1216
  console.log("");
1180
1217
  const { ownerId } = await prompts3({
1181
1218
  type: "text",
@@ -1190,10 +1227,10 @@ async function ownerIdFlow() {
1190
1227
  let account;
1191
1228
  try {
1192
1229
  account = await getAccount(ownerId.trim());
1193
- spinner.succeed(` Account verified \u2014 plan: ${chalk6.bold(account.plan)}`);
1230
+ spinner.succeed(` Account verified \u2014 plan: ${chalk7.bold(account.plan)}`);
1194
1231
  } catch (err) {
1195
1232
  spinner.fail(` Could not verify Owner ID: ${err.message}`);
1196
- console.log(chalk6.dim(" Make sure you copied the full Owner ID from app.agentvalet.ai/settings"));
1233
+ console.log(chalk7.dim(" Make sure you copied the full Owner ID from app.agentvalet.ai/settings"));
1197
1234
  process.exit(1);
1198
1235
  }
1199
1236
  saveConfig({
@@ -1201,9 +1238,10 @@ async function ownerIdFlow() {
1201
1238
  ownerId: account.owner_id,
1202
1239
  orgId: account.org_id,
1203
1240
  proxyUrl: "https://api.agentvalet.ai",
1204
- email: account.email ?? ""
1241
+ email: account.email ?? "",
1242
+ cliToken: account.cli_token
1205
1243
  });
1206
- await registerAgentFlow(account.owner_id, account.owner_id);
1244
+ await registerAgentFlow(account.cli_token, account.owner_id);
1207
1245
  }
1208
1246
  async function registerAgentFlow(apiKey, ownerId) {
1209
1247
  const hostname = os3.hostname().split(".")[0];
@@ -1226,7 +1264,7 @@ async function registerAgentFlow(apiKey, ownerId) {
1226
1264
  name: agentName.trim(),
1227
1265
  source: "cli"
1228
1266
  }, apiKey);
1229
- spinner.succeed(` Agent registered: ${chalk6.bold(agent.agent_id)}`);
1267
+ spinner.succeed(` Agent registered: ${chalk7.bold(agent.agent_id)}`);
1230
1268
  } catch (err) {
1231
1269
  spinner.fail(` Registration failed: ${err.message}`);
1232
1270
  process.exit(1);
@@ -1240,9 +1278,10 @@ async function registerAgentFlow(apiKey, ownerId) {
1240
1278
  proxyUrl,
1241
1279
  privateKeyPem: agent.private_key_pem
1242
1280
  });
1281
+ saveConfig({ lastAgentId: agent.agent_id, lastKeyPath: keyPath });
1243
1282
  } catch (err) {
1244
- console.error(chalk6.red(` \u2717 Failed to write local config: ${err.message}`));
1245
- console.log(chalk6.dim(" Agent was registered \u2014 run again to save config locally."));
1283
+ console.error(chalk7.red(` \u2717 Failed to write local config: ${err.message}`));
1284
+ console.log(chalk7.dim(" Agent was registered \u2014 run again to save config locally."));
1246
1285
  process.exit(1);
1247
1286
  }
1248
1287
  try {
@@ -1260,7 +1299,7 @@ async function registerAgentFlow(apiKey, ownerId) {
1260
1299
  const shouldSetup = await frameworkSetupConsent(detected);
1261
1300
  if (shouldSetup) {
1262
1301
  console.log("");
1263
- console.log(chalk6.bold(" Configuring agent frameworks..."));
1302
+ console.log(chalk7.bold(" Configuring agent frameworks..."));
1264
1303
  console.log("");
1265
1304
  const ideResults = await writeIdeConfigs({
1266
1305
  agentId: agent.agent_id,
@@ -1270,7 +1309,7 @@ async function registerAgentFlow(apiKey, ownerId) {
1270
1309
  detected
1271
1310
  });
1272
1311
  for (const r of ideResults) {
1273
- console.log(chalk6.green(` \u2713 ${r}`));
1312
+ console.log(chalk7.green(` \u2713 ${r}`));
1274
1313
  }
1275
1314
  const globalResults = await writeGlobalFrameworkConfigs({
1276
1315
  agentId: agent.agent_id,
@@ -1279,7 +1318,7 @@ async function registerAgentFlow(apiKey, ownerId) {
1279
1318
  keyPath
1280
1319
  });
1281
1320
  for (const r of globalResults) {
1282
- console.log(chalk6.green(` \u2713 ${r}`));
1321
+ console.log(chalk7.green(` \u2713 ${r}`));
1283
1322
  }
1284
1323
  if (detected.codex) {
1285
1324
  writeAgentsMd();
@@ -1297,11 +1336,11 @@ async function registerAgentFlow(apiKey, ownerId) {
1297
1336
  ensureMcpServer();
1298
1337
  } else if (shouldSetup === false) {
1299
1338
  console.log("");
1300
- console.log(chalk6.dim(" To configure agent frameworks manually:"));
1301
- console.log(chalk6.dim(" https://docs.agentvalet.ai/setup"));
1339
+ console.log(chalk7.dim(" To configure agent frameworks manually:"));
1340
+ console.log(chalk7.dim(" https://docs.agentvalet.ai/setup"));
1302
1341
  }
1303
1342
  console.log("");
1304
- console.log(chalk6.bold.green(" \u2713 All done!"));
1343
+ console.log(chalk7.bold.green(" \u2713 All done!"));
1305
1344
  console.log("");
1306
1345
  console.log(" Set these in your environment:");
1307
1346
  console.log("");
@@ -1312,26 +1351,26 @@ async function registerAgentFlow(apiKey, ownerId) {
1312
1351
  AGENT_PRIVATE_KEY_PATH: path6.join(process.cwd(), ".agentvalet", "agent.key")
1313
1352
  }));
1314
1353
  console.log("");
1315
- console.log(chalk6.dim(" Private key also saved to: .agentvalet/agent.key"));
1316
- console.log(chalk6.dim(" Add .agentvalet/ to your .gitignore"));
1354
+ console.log(chalk7.dim(" Private key also saved to: .agentvalet/agent.key"));
1355
+ console.log(chalk7.dim(" Add .agentvalet/ to your .gitignore"));
1317
1356
  console.log("");
1318
1357
  console.log(
1319
- ` Dashboard: ${chalk6.cyan.underline("https://app.agentvalet.ai")}`
1358
+ ` Dashboard: ${chalk7.cyan.underline("https://app.agentvalet.ai")}`
1320
1359
  );
1321
- console.log(chalk6.dim(" Approve this agent in your dashboard to activate it."));
1360
+ console.log(chalk7.dim(" Approve this agent in your dashboard to activate it."));
1322
1361
  console.log("");
1323
1362
  console.log(" Useful commands:");
1324
- console.log(chalk6.dim(" npx @agentvalet/register \u2014 register another agent"));
1325
- console.log(chalk6.dim(" npx @agentvalet/register refresh \u2014 refresh approved permissions"));
1363
+ console.log(chalk7.dim(" npx @agentvalet/register \u2014 register another agent"));
1364
+ console.log(chalk7.dim(" npx @agentvalet/register refresh \u2014 refresh approved permissions"));
1326
1365
  console.log("");
1327
1366
  }
1328
1367
  function showCredentials(config) {
1329
1368
  console.log("");
1330
1369
  console.log(" Your AgentValet credentials:");
1331
1370
  console.log("");
1332
- console.log(` Owner ID: ${chalk6.bold(config.ownerId)}`);
1333
- console.log(` Proxy URL: ${chalk6.bold(config.proxyUrl)}`);
1334
- console.log(` Email: ${chalk6.bold(config.email)}`);
1371
+ console.log(` Owner ID: ${chalk7.bold(config.ownerId)}`);
1372
+ console.log(` Proxy URL: ${chalk7.bold(config.proxyUrl)}`);
1373
+ console.log(` Email: ${chalk7.bold(config.email)}`);
1335
1374
  console.log("");
1336
1375
  }
1337
1376
 
@@ -1340,7 +1379,7 @@ function collectScope(value, previous) {
1340
1379
  return [...previous, value];
1341
1380
  }
1342
1381
  var program = new Command();
1343
- program.name("agentvalet-register").description("Self-register an AI agent with AgentValet").version("0.4.1").option("--owner <uuid>", "Owner ID (or set AGENTVALET_OWNER env var)").option("--name <name>", "Agent name").option("--description <desc>", "Agent description").option("--scope <platform:scope>", "Requested scope, repeatable", collectScope, []).option("--api-url <url>", "AgentValet API base URL", "https://api.agentvalet.ai").option("--output <path>", "Path to write .env file", "./.env.agentvalet").option("--key-path <path>", "Path to write private key", "./agentvalet.key").option("--json", "Machine-readable JSON output").option("--no-wait", "Register only, do not wait for approval").option("--timeout <seconds>", "Approval wait timeout in seconds", "300").action(async (opts) => {
1382
+ program.name("agentvalet-register").description("Self-register an AI agent with AgentValet").version("0.4.5").option("--owner <uuid>", "Owner ID (or set AGENTVALET_OWNER env var)").option("--name <name>", "Agent name").option("--description <desc>", "Agent description").option("--scope <platform:scope>", "Requested scope, repeatable", collectScope, []).option("--api-url <url>", "AgentValet API base URL", "https://api.agentvalet.ai").option("--output <path>", "Path to write .env file", "./.env.agentvalet").option("--key-path <path>", "Path to write private key", "./agentvalet.key").option("--json", "Machine-readable JSON output").option("--no-wait", "Register only, do not wait for approval").option("--timeout <seconds>", "Approval wait timeout in seconds", "300").action(async (opts) => {
1344
1383
  const isJson = !!opts.json;
1345
1384
  let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
1346
1385
  let agentName = opts.name ?? "";
@@ -1366,7 +1405,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
1366
1405
  console.error(JSON.stringify({ error: "--owner or AGENTVALET_OWNER is required" }));
1367
1406
  process.exit(3);
1368
1407
  }
1369
- console.error(chalk7.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
1408
+ console.error(chalk8.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
1370
1409
  process.exit(3);
1371
1410
  }
1372
1411
  const scopeMap = /* @__PURE__ */ new Map();
@@ -1374,7 +1413,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
1374
1413
  const colon = s.indexOf(":");
1375
1414
  if (colon === -1) {
1376
1415
  console.error(
1377
- isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk7.red(`Invalid scope format: ${s} (expected platform:scope)`)
1416
+ isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk8.red(`Invalid scope format: ${s} (expected platform:scope)`)
1378
1417
  );
1379
1418
  process.exit(3);
1380
1419
  }
@@ -1397,11 +1436,11 @@ program.name("agentvalet-register").description("Self-register an AI agent with
1397
1436
  });
1398
1437
  } catch (err) {
1399
1438
  const msg = err instanceof Error ? err.message : String(err);
1400
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk7.red(`Registration failed: ${msg}`));
1439
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk8.red(`Registration failed: ${msg}`));
1401
1440
  process.exit(3);
1402
1441
  }
1403
1442
  if (!isJson) {
1404
- console.log(chalk7.cyan(`
1443
+ console.log(chalk8.cyan(`
1405
1444
  Approve at: https://app.agentvalet.ai/agents
1406
1445
  `));
1407
1446
  }
@@ -1409,7 +1448,7 @@ Approve at: https://app.agentvalet.ai/agents
1409
1448
  if (isJson) {
1410
1449
  console.log(JSON.stringify({ status: "pending", token }));
1411
1450
  } else {
1412
- console.log(chalk7.yellow("Registration submitted (--no-wait). Token:"), token);
1451
+ console.log(chalk8.yellow("Registration submitted (--no-wait). Token:"), token);
1413
1452
  }
1414
1453
  process.exit(0);
1415
1454
  }
@@ -1420,14 +1459,14 @@ Approve at: https://app.agentvalet.ai/agents
1420
1459
  });
1421
1460
  } catch (err) {
1422
1461
  const msg = err instanceof Error ? err.message : String(err);
1423
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk7.red(`Wait failed: ${msg}`));
1462
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk8.red(`Wait failed: ${msg}`));
1424
1463
  process.exit(3);
1425
1464
  }
1426
1465
  if (result.status === "rejected") {
1427
1466
  if (isJson) {
1428
1467
  console.log(JSON.stringify({ status: "rejected" }));
1429
1468
  } else {
1430
- console.log(chalk7.red("\nRegistration denied by owner."));
1469
+ console.log(chalk8.red("\nRegistration denied by owner."));
1431
1470
  }
1432
1471
  process.exit(1);
1433
1472
  }
@@ -1435,7 +1474,7 @@ Approve at: https://app.agentvalet.ai/agents
1435
1474
  if (isJson) {
1436
1475
  console.log(JSON.stringify({ status: "timeout" }));
1437
1476
  } else {
1438
- console.log(chalk7.yellow("\nTimed out waiting for approval."));
1477
+ console.log(chalk8.yellow("\nTimed out waiting for approval."));
1439
1478
  }
1440
1479
  process.exit(2);
1441
1480
  }
@@ -1454,30 +1493,33 @@ Approve at: https://app.agentvalet.ai/agents
1454
1493
  }));
1455
1494
  } catch (err) {
1456
1495
  const msg = err instanceof Error ? err.message : String(err);
1457
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk7.red(`Failed to save output: ${msg}`));
1496
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk8.red(`Failed to save output: ${msg}`));
1458
1497
  process.exit(3);
1459
1498
  }
1460
1499
  const keyWritten = !!privateKey;
1500
+ if (keyWritten) {
1501
+ saveConfig({ lastAgentId: agentId, lastKeyPath: keyPath, ownerId: resolvedOwnerId });
1502
+ }
1461
1503
  if (isJson) {
1462
1504
  console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null, envPath }));
1463
1505
  } else {
1464
- console.log(chalk7.green(`
1506
+ console.log(chalk8.green(`
1465
1507
  Approved! Agent ID: ${agentId}`));
1466
1508
  if (keyWritten) {
1467
- console.log(chalk7.gray(`Key: ${keyPath}`));
1509
+ console.log(chalk8.gray(`Key: ${keyPath}`));
1468
1510
  } else {
1469
- console.log(chalk7.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
1511
+ console.log(chalk8.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
1470
1512
  }
1471
- console.log(chalk7.gray(`Env file: ${envPath}`));
1513
+ console.log(chalk8.gray(`Env file: ${envPath}`));
1472
1514
  console.log(`
1473
1515
  Source the env file before calling any tool:`);
1474
- console.log(chalk7.cyan(` source ${envPath}`));
1516
+ console.log(chalk8.cyan(` source ${envPath}`));
1475
1517
  }
1476
1518
  if (keyWritten) {
1477
1519
  try {
1478
1520
  if (grantedPlatforms && grantedPlatforms.length > 0) {
1479
1521
  writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
1480
- if (!isJson) console.log(chalk7.gray(`Permissions: .claude/agentvalet-permissions.md`));
1522
+ if (!isJson) console.log(chalk8.gray(`Permissions: .claude/agentvalet-permissions.md`));
1481
1523
  } else {
1482
1524
  await runRefresh({
1483
1525
  envFile: opts.output,
@@ -1485,10 +1527,10 @@ Source the env file before calling any tool:`);
1485
1527
  ifStale: false,
1486
1528
  quiet: isJson
1487
1529
  });
1488
- if (!isJson) console.log(chalk7.gray(`Permissions: .claude/agentvalet-permissions.md`));
1530
+ if (!isJson) console.log(chalk8.gray(`Permissions: .claude/agentvalet-permissions.md`));
1489
1531
  }
1490
1532
  } catch {
1491
- if (!isJson) console.log(chalk7.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
1533
+ if (!isJson) console.log(chalk8.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
1492
1534
  }
1493
1535
  }
1494
1536
  process.exit(0);
@@ -1503,7 +1545,7 @@ program.command("refresh").description("Refresh approved permissions and update
1503
1545
  });
1504
1546
  } catch (err) {
1505
1547
  const msg = err instanceof Error ? err.message : String(err);
1506
- console.error(chalk7.red(`Refresh failed: ${msg}`));
1548
+ console.error(chalk8.red(`Refresh failed: ${msg}`));
1507
1549
  process.exit(3);
1508
1550
  }
1509
1551
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentvalet/register",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Self-register AI agents with AgentValet",
5
5
  "type": "module",
6
6
  "bin": {