@agentvalet/register 0.2.2 → 0.3.1

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
@@ -1,91 +1,56 @@
1
1
  # @agentvalet/register
2
2
 
3
- Self-register AI agents with [AgentValet](https://agentvalet.ai) — the governance and proxy layer that sits between AI agents and SaaS platforms.
3
+ Register your AI agent with AgentValet in 30 seconds.
4
4
 
5
- ## Install
5
+ ## Usage
6
6
 
7
7
  ```bash
8
- # One-off use (no install):
9
- npx @agentvalet/register --name "My Agent" --scope slack:chat:write
10
-
11
- # Or install globally:
12
- npm install -g @agentvalet/register
13
- agentvalet-register --name "My Agent" --scope slack:chat:write
8
+ npx @agentvalet/register
14
9
  ```
15
10
 
16
- ## Interactive mode
11
+ No installation required. Authenticate with GitHub, and your agent is registered automatically.
17
12
 
18
- Run with no flags for a guided wizard:
13
+ ## What it does
19
14
 
20
- ```bash
21
- npx @agentvalet/register
22
- ```
15
+ 1. Opens your browser to authenticate with GitHub
16
+ 2. Creates your AgentValet account (or finds your existing one)
17
+ 3. Registers this machine as an agent
18
+ 4. Writes config to `.agentvalet/` in the current directory
19
+ 5. Outputs the environment variables you need
23
20
 
24
- ## Flags
25
-
26
- | Flag | Default | Description |
27
- |------|---------|-------------|
28
- | `--owner <uuid>` | `AGENTVALET_OWNER` env | Owner ID from https://agentvalet.ai/settings |
29
- | `--name <name>` | prompted | Agent name |
30
- | `--description <desc>` | — | Agent description |
31
- | `--scope <platform:scope>` | — | Repeatable, e.g. `--scope slack:chat:write --scope gmail:send` |
32
- | `--api-url <url>` | `https://api.agentvalet.ai` | AgentValet API base URL |
33
- | `--output <path>` | `./.env.agentvalet` | Path to write env vars |
34
- | `--key-path <path>` | `./agentvalet.key` | Path to write private key |
35
- | `--json` | — | Machine-readable JSON output |
36
- | `--no-wait` | — | Register only, don't wait for approval |
37
- | `--timeout <seconds>` | `300` | Approval wait timeout |
38
-
39
- ## Exit codes
40
-
41
- | Code | Meaning |
42
- |------|---------|
43
- | `0` | Approved |
44
- | `1` | Denied |
45
- | `2` | Timeout |
46
- | `3` | Network or other error |
47
-
48
- ## Integration examples
49
-
50
- **Claude Code (`CLAUDE.md`):**
51
- ```markdown
52
- On startup, register with AgentValet:
53
- npx @agentvalet/register --owner {uuid} --name "Claude Code Agent" --scope slack:chat:write
54
-
55
- Then source ./.env.agentvalet before calling any tool.
56
- ```
21
+ ## Requirements
57
22
 
58
- **Python agent:**
59
- ```python
60
- import subprocess
61
- subprocess.run([
62
- "npx", "@agentvalet/register",
63
- "--name", "MyAgent",
64
- "--owner", owner_id,
65
- "--scope", "slack:chat:write",
66
- ])
67
- ```
23
+ - Node.js 18+
24
+ - A GitHub account
25
+ - An internet connection
68
26
 
69
- **LangChain / CrewAI / bash script:**
27
+ ## After registration
70
28
 
71
- Shell out to `npx @agentvalet/register` and parse the output env file:
29
+ Approve your agent in the AgentValet dashboard to activate it:
30
+ https://app.agentvalet.ai/agents
31
+
32
+ ## Commands
72
33
 
73
34
  ```bash
74
- npx @agentvalet/register --owner $OWNER_ID --name "BashAgent" --scope slack:chat:write
75
- source ./.env.agentvalet
35
+ npx @agentvalet/register # Register a new agent (GitHub onboarding)
36
+ npx @agentvalet/register refresh # Refresh approved permissions
76
37
  ```
77
38
 
78
- ## How it works
39
+ ## What gets written
40
+
41
+ - `.agentvalet/config.json` — agent ID, proxy URL, registration timestamp
42
+ - `.agentvalet/agent.key` — private key (mode 0600, never shared)
43
+
44
+ `.agentvalet/` is automatically added to your `.gitignore`.
79
45
 
80
- 1. POSTs to `/v1/register` with your owner ID, agent name, and requested scopes
81
- 2. Prints the approval URL — the owner approves in the dashboard
82
- 3. Waits for approval via SSE (with polling fallback)
83
- 4. On approval, writes the private key to `--key-path` and env vars to `--output`
46
+ ## Advanced: existing owner ID
84
47
 
85
- The agent **never holds SaaS credentials** — AgentValet injects them at proxy time.
48
+ If you already have an AgentValet owner ID, pass it directly:
49
+
50
+ ```bash
51
+ AGENTVALET_OWNER=<your-owner-id> npx @agentvalet/register
52
+ ```
86
53
 
87
- ## Links
54
+ ## GitHub OAuth App
88
55
 
89
- - Dashboard: https://agentvalet.ai
90
- - Docs: https://agentvalet.ai/docs
91
- - GitHub: https://github.com/MCSEdwin/agentvalet
56
+ The GitHub Device Flow uses AgentValet's OAuth App (client ID is public — the Device Flow does not use or expose the client secret). No secrets are stored on your machine.
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import chalk2 from "chalk";
5
+ import chalk5 from "chalk";
6
6
 
7
7
  // src/wizard.ts
8
8
  import prompts from "prompts";
@@ -422,7 +422,7 @@ function ensureMcpJson() {
422
422
  if (!agentId || !ownerId || !keyPath) return;
423
423
  servers["agent-authority"] = {
424
424
  command: "npx",
425
- args: ["-y", "@agentvalet/register", "mcp-server"],
425
+ args: ["-y", "@agentvalet/register@0.2.2", "mcp-server"],
426
426
  env: {
427
427
  AGENT_ID: agentId,
428
428
  OWNER_ID: ownerId,
@@ -434,6 +434,416 @@ function ensureMcpJson() {
434
434
  writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2) + "\n", "utf-8");
435
435
  }
436
436
 
437
+ // src/commands/onboard.ts
438
+ import chalk4 from "chalk";
439
+ import ora from "ora";
440
+ import prompts2 from "prompts";
441
+
442
+ // src/auth/github-device-flow.ts
443
+ import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device";
444
+ import open from "open";
445
+ import chalk2 from "chalk";
446
+ var GITHUB_CLIENT_ID = process.env.AGENTVALET_GITHUB_CLIENT_ID ?? "Ov23liXXXXXXXXXXXXXX";
447
+ async function authenticateWithGitHub() {
448
+ const auth = createOAuthDeviceAuth({
449
+ clientType: "oauth-app",
450
+ clientId: GITHUB_CLIENT_ID,
451
+ scopes: ["user:email", "read:user"],
452
+ onVerification(verification) {
453
+ console.log("");
454
+ console.log(chalk2.bold(" Authenticate with GitHub"));
455
+ console.log("");
456
+ console.log(` 1. Open: ${chalk2.cyan.underline(verification.verification_uri)}`);
457
+ console.log(` 2. Enter code: ${chalk2.bold.yellow(verification.user_code)}`);
458
+ console.log("");
459
+ open(verification.verification_uri).catch(() => {
460
+ console.log(chalk2.dim(" (Could not open browser \u2014 navigate to the URL above manually)"));
461
+ });
462
+ console.log(chalk2.dim(" Waiting for authorisation..."));
463
+ }
464
+ });
465
+ const tokenAuth = await auth({ type: "oauth" });
466
+ return {
467
+ token: tokenAuth.token,
468
+ scopes: tokenAuth.scopes ?? []
469
+ };
470
+ }
471
+ async function getGitHubUser(token) {
472
+ const response = await fetch("https://api.github.com/user", {
473
+ headers: {
474
+ Authorization: `Bearer ${token}`,
475
+ Accept: "application/vnd.github.v3+json"
476
+ }
477
+ });
478
+ if (!response.ok) {
479
+ throw new Error(`GitHub API error: ${response.status}`);
480
+ }
481
+ const user = await response.json();
482
+ if (!user.email) {
483
+ const emailsResponse = await fetch("https://api.github.com/user/emails", {
484
+ headers: {
485
+ Authorization: `Bearer ${token}`,
486
+ Accept: "application/vnd.github.v3+json"
487
+ }
488
+ });
489
+ if (emailsResponse.ok) {
490
+ const emails = await emailsResponse.json();
491
+ user.email = emails.find((e) => e.primary && e.verified)?.email ?? emails[0]?.email ?? null;
492
+ }
493
+ }
494
+ return user;
495
+ }
496
+
497
+ // src/api/agentvalet.ts
498
+ var API_BASE = process.env.AGENTVALET_API_URL ?? "https://api.agentvalet.ai";
499
+ async function createOrFindAccount(params) {
500
+ const controller = new AbortController();
501
+ const timeout = setTimeout(() => controller.abort(), 1e4);
502
+ try {
503
+ const response = await fetch(`${API_BASE}/v1/cli/account`, {
504
+ method: "POST",
505
+ headers: { "Content-Type": "application/json" },
506
+ body: JSON.stringify(params),
507
+ signal: controller.signal
508
+ });
509
+ if (!response.ok) {
510
+ const error = await response.json().catch(() => ({}));
511
+ throw new Error(`Account creation failed: ${response.status} ${error.message ?? ""}`);
512
+ }
513
+ return response.json();
514
+ } catch (err) {
515
+ clearTimeout(timeout);
516
+ if (err?.name === "AbortError") throw new Error("Request timed out \u2014 is the AgentValet API reachable?");
517
+ throw err;
518
+ } finally {
519
+ clearTimeout(timeout);
520
+ }
521
+ }
522
+ async function registerAgent2(params, apiKey) {
523
+ const controller = new AbortController();
524
+ const timeout = setTimeout(() => controller.abort(), 1e4);
525
+ try {
526
+ const response = await fetch(`${API_BASE}/v1/cli/register-agent`, {
527
+ method: "POST",
528
+ headers: {
529
+ "Content-Type": "application/json",
530
+ "Authorization": `Bearer ${apiKey}`
531
+ },
532
+ body: JSON.stringify(params),
533
+ signal: controller.signal
534
+ });
535
+ if (!response.ok) {
536
+ const error = await response.json().catch(() => ({}));
537
+ throw new Error(`Agent registration failed: ${response.status} ${error.message ?? ""}`);
538
+ }
539
+ return response.json();
540
+ } catch (err) {
541
+ clearTimeout(timeout);
542
+ if (err?.name === "AbortError") throw new Error("Request timed out \u2014 is the AgentValet API reachable?");
543
+ throw err;
544
+ } finally {
545
+ clearTimeout(timeout);
546
+ }
547
+ }
548
+
549
+ // src/config/store.ts
550
+ import Conf from "conf";
551
+ var store = new Conf({
552
+ projectName: "agentvalet"
553
+ });
554
+ function getStoredConfig() {
555
+ return store.store;
556
+ }
557
+ function saveConfig(config) {
558
+ store.set(config);
559
+ }
560
+ function clearConfig() {
561
+ store.clear();
562
+ }
563
+ function isAuthenticated() {
564
+ return !!store.get("apiKey");
565
+ }
566
+
567
+ // src/config/local.ts
568
+ import { mkdir as mkdir2, writeFile as writeFile2, appendFile, readFile } from "fs/promises";
569
+ import path from "path";
570
+ async function writeLocalConfig(config) {
571
+ const dir = path.join(process.cwd(), ".agentvalet");
572
+ await mkdir2(dir, { recursive: true });
573
+ await writeFile2(
574
+ path.join(dir, "config.json"),
575
+ JSON.stringify({
576
+ agent_id: config.agentId,
577
+ agent_name: config.agentName,
578
+ proxy_url: config.proxyUrl,
579
+ registered_at: (/* @__PURE__ */ new Date()).toISOString()
580
+ }, null, 2),
581
+ { encoding: "utf8", mode: 384 }
582
+ );
583
+ await writeFile2(
584
+ path.join(dir, "agent.key"),
585
+ config.privateKeyPem,
586
+ { encoding: "utf8", mode: 384 }
587
+ );
588
+ if (process.platform === "win32") {
589
+ console.warn(" Note: file permissions (0o600) are not enforced on Windows. Keep .agentvalet/ in a secure location.");
590
+ }
591
+ const gitignorePath = path.join(process.cwd(), ".gitignore");
592
+ const gitignoreContent = await readFile(gitignorePath, "utf8").catch(() => null);
593
+ if (gitignoreContent !== null) {
594
+ const lines = gitignoreContent.split("\n").map((l) => l.trim());
595
+ if (!lines.includes(".agentvalet/")) {
596
+ await appendFile(gitignorePath, "\n# AgentValet\n.agentvalet/\n");
597
+ }
598
+ }
599
+ }
600
+
601
+ // src/output/env.ts
602
+ import chalk3 from "chalk";
603
+ import { appendFile as appendFile2, writeFile as writeFile3 } from "fs/promises";
604
+ import { existsSync as existsSync2 } from "fs";
605
+ import path2 from "path";
606
+ function formatEnvBlock(vars) {
607
+ return Object.entries(vars).map(([key, value]) => {
608
+ const truncated = value.length > 60 ? value.substring(0, 40) + "..." + value.substring(value.length - 10) : value;
609
+ return ` ${chalk3.dim(key + "=")}${chalk3.white(truncated)}`;
610
+ }).join("\n");
611
+ }
612
+
613
+ // src/config/ide.ts
614
+ import { mkdir as mkdir3, writeFile as writeFile4, readFile as readFile2 } from "fs/promises";
615
+ import { existsSync as existsSync3 } from "fs";
616
+ import path3 from "path";
617
+ function buildMcpEntry(params) {
618
+ return {
619
+ command: "npx",
620
+ args: ["-y", "@agentvalet/register", "mcp-server"],
621
+ env: {
622
+ AGENT_ID: params.agentId,
623
+ OWNER_ID: params.ownerId,
624
+ PROXY_URL: params.proxyUrl,
625
+ AGENT_PRIVATE_KEY_PATH: params.keyPath
626
+ }
627
+ };
628
+ }
629
+ async function mergeJsonFile(filePath, key, value) {
630
+ let existing = {};
631
+ if (existsSync3(filePath)) {
632
+ try {
633
+ const text = await readFile2(filePath, "utf8");
634
+ existing = JSON.parse(text);
635
+ } catch {
636
+ }
637
+ }
638
+ const mcpServers = existing.mcpServers ?? {};
639
+ mcpServers[key] = value;
640
+ existing.mcpServers = mcpServers;
641
+ await writeFile4(filePath, JSON.stringify(existing, null, 2) + "\n", "utf8");
642
+ }
643
+ async function writeIdeConfigs(params) {
644
+ const cwd = process.cwd();
645
+ const written = [];
646
+ const entry = buildMcpEntry(params);
647
+ const claudeMcpPath = path3.join(cwd, ".mcp.json");
648
+ if (existsSync3(claudeMcpPath) || existsSync3(path3.join(cwd, "CLAUDE.md"))) {
649
+ try {
650
+ await mergeJsonFile(claudeMcpPath, "agentvalet", entry);
651
+ written.push(".mcp.json");
652
+ } catch (err) {
653
+ console.warn(` Warning: could not write .mcp.json: ${err.message}`);
654
+ }
655
+ }
656
+ const cursorDir = path3.join(cwd, ".cursor");
657
+ const cursorMcpPath = path3.join(cursorDir, "mcp.json");
658
+ if (existsSync3(cursorDir)) {
659
+ try {
660
+ await mkdir3(cursorDir, { recursive: true });
661
+ await mergeJsonFile(cursorMcpPath, "agentvalet", entry);
662
+ written.push(".cursor/mcp.json");
663
+ } catch (err) {
664
+ console.warn(` Warning: could not write .cursor/mcp.json: ${err.message}`);
665
+ }
666
+ }
667
+ return written;
668
+ }
669
+
670
+ // src/commands/onboard.ts
671
+ import os from "os";
672
+ import path4 from "path";
673
+ async function runOnboard() {
674
+ console.log("");
675
+ console.log(chalk4.bold(" AgentValet \u2014 Agent Registration"));
676
+ console.log(chalk4.dim(" agentvalet.ai"));
677
+ console.log("");
678
+ if (isAuthenticated()) {
679
+ const stored = getStoredConfig();
680
+ console.log(
681
+ chalk4.green(" \u2713 Already authenticated as") + chalk4.bold(` ${stored.email}`)
682
+ );
683
+ const { action } = await prompts2({
684
+ type: "select",
685
+ name: "action",
686
+ message: "What would you like to do?",
687
+ choices: [
688
+ { title: "Register a new agent for this directory", value: "register" },
689
+ { title: "Show my credentials", value: "show" },
690
+ { title: "Sign out and use a different account", value: "signout" }
691
+ ]
692
+ });
693
+ if (action === void 0) {
694
+ process.exit(0);
695
+ }
696
+ if (action === "show") {
697
+ showCredentials(stored);
698
+ return;
699
+ }
700
+ if (action === "signout") {
701
+ clearConfig();
702
+ console.log(chalk4.dim(" Signed out. Run again to re-authenticate."));
703
+ return;
704
+ }
705
+ await registerAgentFlow(stored.apiKey, stored.ownerId);
706
+ return;
707
+ }
708
+ let spinner = ora();
709
+ let githubToken;
710
+ try {
711
+ const result = await authenticateWithGitHub();
712
+ githubToken = result.token;
713
+ } catch (err) {
714
+ console.error(chalk4.red(` \u2717 Authentication failed: ${err.message}`));
715
+ process.exit(1);
716
+ }
717
+ spinner = ora(" Fetching your GitHub profile...").start();
718
+ let githubUser;
719
+ try {
720
+ githubUser = await getGitHubUser(githubToken);
721
+ spinner.succeed(` GitHub: ${chalk4.bold("@" + githubUser.login)}`);
722
+ } catch (err) {
723
+ spinner.fail(` Failed to fetch GitHub profile: ${err.message}`);
724
+ process.exit(1);
725
+ }
726
+ if (!githubUser.email) {
727
+ const { email } = await prompts2({
728
+ type: "text",
729
+ name: "email",
730
+ message: "Your email address (not visible on GitHub):",
731
+ validate: (v) => v.includes("@") || "Please enter a valid email"
732
+ });
733
+ if (email === void 0) {
734
+ process.exit(0);
735
+ }
736
+ githubUser.email = email;
737
+ }
738
+ spinner = ora(" Setting up your AgentValet account...").start();
739
+ let account;
740
+ try {
741
+ account = await createOrFindAccount({
742
+ github_token: githubToken,
743
+ github_username: githubUser.login,
744
+ email: githubUser.email,
745
+ display_name: githubUser.name ?? githubUser.login,
746
+ avatar_url: githubUser.avatar_url
747
+ });
748
+ if (account.is_new_account) {
749
+ spinner.succeed(" AgentValet account created");
750
+ } else {
751
+ spinner.succeed(" Existing AgentValet account found");
752
+ }
753
+ } catch (err) {
754
+ spinner.fail(` Account setup failed: ${err.message}`);
755
+ process.exit(1);
756
+ }
757
+ saveConfig({
758
+ apiKey: account.owner_id,
759
+ ownerId: account.owner_id,
760
+ orgId: account.org_id,
761
+ proxyUrl: account.proxy_url,
762
+ githubUsername: githubUser.login,
763
+ email: githubUser.email
764
+ });
765
+ await registerAgentFlow(account.owner_id, account.owner_id);
766
+ }
767
+ async function registerAgentFlow(apiKey, ownerId) {
768
+ const hostname = os.hostname().split(".")[0];
769
+ const dirName = process.cwd().split("/").pop() ?? process.cwd().split("\\").pop() ?? "agent";
770
+ const { agentName } = await prompts2({
771
+ type: "text",
772
+ name: "agentName",
773
+ message: "Name for this agent:",
774
+ initial: `${hostname} \u2014 ${dirName}`,
775
+ validate: (v) => v.trim().length > 0 || "Agent name is required"
776
+ });
777
+ if (agentName === void 0) {
778
+ process.exit(0);
779
+ }
780
+ const spinner = ora(" Registering agent...").start();
781
+ let agent;
782
+ try {
783
+ agent = await registerAgent2({
784
+ owner_id: ownerId,
785
+ name: agentName.trim(),
786
+ source: "cli"
787
+ }, apiKey);
788
+ spinner.succeed(` Agent registered: ${chalk4.bold(agent.agent_id)}`);
789
+ } catch (err) {
790
+ spinner.fail(` Registration failed: ${err.message}`);
791
+ process.exit(1);
792
+ }
793
+ try {
794
+ await writeLocalConfig({
795
+ agentId: agent.agent_id,
796
+ agentName: agent.agent_name,
797
+ proxyUrl: getStoredConfig().proxyUrl,
798
+ privateKeyPem: agent.private_key_pem
799
+ });
800
+ } catch (err) {
801
+ console.error(chalk4.red(` \u2717 Failed to write local config: ${err.message}`));
802
+ console.log(chalk4.dim(" Agent was registered \u2014 run again to save config locally."));
803
+ process.exit(1);
804
+ }
805
+ const ideResults = await writeIdeConfigs({
806
+ agentId: agent.agent_id,
807
+ ownerId,
808
+ proxyUrl: getStoredConfig().proxyUrl,
809
+ keyPath: path4.join(process.cwd(), ".agentvalet", "agent.key")
810
+ });
811
+ if (ideResults.length > 0) {
812
+ for (const r of ideResults) {
813
+ console.log(chalk4.dim(` MCP config written: ${r}`));
814
+ }
815
+ }
816
+ console.log("");
817
+ console.log(chalk4.bold.green(" \u2713 All done!"));
818
+ console.log("");
819
+ console.log(" Set these in your environment:");
820
+ console.log("");
821
+ console.log(formatEnvBlock({
822
+ AGENT_ID: agent.agent_id,
823
+ OWNER_ID: ownerId,
824
+ PROXY_URL: getStoredConfig().proxyUrl,
825
+ AGENT_PRIVATE_KEY_PATH: path4.join(process.cwd(), ".agentvalet", "agent.key")
826
+ }));
827
+ console.log("");
828
+ console.log(chalk4.dim(" Private key also saved to: .agentvalet/agent.key"));
829
+ console.log(chalk4.dim(" Add .agentvalet/ to your .gitignore"));
830
+ console.log("");
831
+ console.log(
832
+ ` Dashboard: ${chalk4.cyan.underline("https://app.agentvalet.ai")}`
833
+ );
834
+ console.log(chalk4.dim(" Approve this agent in your dashboard to activate it."));
835
+ console.log("");
836
+ }
837
+ function showCredentials(config) {
838
+ console.log("");
839
+ console.log(" Your AgentValet credentials:");
840
+ console.log("");
841
+ console.log(` Owner ID: ${chalk4.bold(config.ownerId)}`);
842
+ console.log(` Proxy URL: ${chalk4.bold(config.proxyUrl)}`);
843
+ console.log(` Email: ${chalk4.bold(config.email)}`);
844
+ console.log("");
845
+ }
846
+
437
847
  // src/index.ts
438
848
  function collectScope(value, previous) {
439
849
  return [...previous, value];
@@ -445,6 +855,10 @@ program.name("agentvalet-register").description("Self-register an AI agent with
445
855
  let agentName = opts.name ?? "";
446
856
  let description = opts.description ?? "";
447
857
  let scopes = opts.scope;
858
+ if (!ownerId && !isAuthenticated()) {
859
+ await runOnboard();
860
+ return;
861
+ }
448
862
  if (!agentName) {
449
863
  if (isJson) {
450
864
  console.error(JSON.stringify({ error: "--name is required in non-interactive mode" }));
@@ -461,7 +875,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
461
875
  console.error(JSON.stringify({ error: "--owner or AGENTVALET_OWNER is required" }));
462
876
  process.exit(3);
463
877
  }
464
- console.error(chalk2.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
878
+ console.error(chalk5.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
465
879
  process.exit(3);
466
880
  }
467
881
  const scopeMap = /* @__PURE__ */ new Map();
@@ -469,7 +883,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
469
883
  const colon = s.indexOf(":");
470
884
  if (colon === -1) {
471
885
  console.error(
472
- isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk2.red(`Invalid scope format: ${s} (expected platform:scope)`)
886
+ isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk5.red(`Invalid scope format: ${s} (expected platform:scope)`)
473
887
  );
474
888
  process.exit(3);
475
889
  }
@@ -492,11 +906,11 @@ program.name("agentvalet-register").description("Self-register an AI agent with
492
906
  });
493
907
  } catch (err) {
494
908
  const msg = err instanceof Error ? err.message : String(err);
495
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk2.red(`Registration failed: ${msg}`));
909
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk5.red(`Registration failed: ${msg}`));
496
910
  process.exit(3);
497
911
  }
498
912
  if (!isJson) {
499
- console.log(chalk2.cyan(`
913
+ console.log(chalk5.cyan(`
500
914
  Approve at: https://agentvalet.ai/registrations
501
915
  `));
502
916
  }
@@ -504,7 +918,7 @@ Approve at: https://agentvalet.ai/registrations
504
918
  if (isJson) {
505
919
  console.log(JSON.stringify({ status: "pending", token }));
506
920
  } else {
507
- console.log(chalk2.yellow("Registration submitted (--no-wait). Token:"), token);
921
+ console.log(chalk5.yellow("Registration submitted (--no-wait). Token:"), token);
508
922
  }
509
923
  process.exit(0);
510
924
  }
@@ -515,14 +929,14 @@ Approve at: https://agentvalet.ai/registrations
515
929
  });
516
930
  } catch (err) {
517
931
  const msg = err instanceof Error ? err.message : String(err);
518
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk2.red(`Wait failed: ${msg}`));
932
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk5.red(`Wait failed: ${msg}`));
519
933
  process.exit(3);
520
934
  }
521
935
  if (result.status === "rejected") {
522
936
  if (isJson) {
523
937
  console.log(JSON.stringify({ status: "rejected" }));
524
938
  } else {
525
- console.log(chalk2.red("\nRegistration denied by owner."));
939
+ console.log(chalk5.red("\nRegistration denied by owner."));
526
940
  }
527
941
  process.exit(1);
528
942
  }
@@ -530,7 +944,7 @@ Approve at: https://agentvalet.ai/registrations
530
944
  if (isJson) {
531
945
  console.log(JSON.stringify({ status: "timeout" }));
532
946
  } else {
533
- console.log(chalk2.yellow("\nTimed out waiting for approval."));
947
+ console.log(chalk5.yellow("\nTimed out waiting for approval."));
534
948
  }
535
949
  process.exit(2);
536
950
  }
@@ -549,30 +963,30 @@ Approve at: https://agentvalet.ai/registrations
549
963
  }));
550
964
  } catch (err) {
551
965
  const msg = err instanceof Error ? err.message : String(err);
552
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk2.red(`Failed to save output: ${msg}`));
966
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk5.red(`Failed to save output: ${msg}`));
553
967
  process.exit(3);
554
968
  }
555
969
  const keyWritten = !!privateKey;
556
970
  if (isJson) {
557
971
  console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null, envPath }));
558
972
  } else {
559
- console.log(chalk2.green(`
973
+ console.log(chalk5.green(`
560
974
  Approved! Agent ID: ${agentId}`));
561
975
  if (keyWritten) {
562
- console.log(chalk2.gray(`Key: ${keyPath}`));
976
+ console.log(chalk5.gray(`Key: ${keyPath}`));
563
977
  } else {
564
- console.log(chalk2.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
978
+ console.log(chalk5.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
565
979
  }
566
- console.log(chalk2.gray(`Env file: ${envPath}`));
980
+ console.log(chalk5.gray(`Env file: ${envPath}`));
567
981
  console.log(`
568
982
  Source the env file before calling any tool:`);
569
- console.log(chalk2.cyan(` source ${envPath}`));
983
+ console.log(chalk5.cyan(` source ${envPath}`));
570
984
  }
571
985
  if (keyWritten) {
572
986
  try {
573
987
  if (grantedPlatforms && grantedPlatforms.length > 0) {
574
988
  writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
575
- if (!isJson) console.log(chalk2.gray(`Permissions: .claude/agentvalet-permissions.md`));
989
+ if (!isJson) console.log(chalk5.gray(`Permissions: .claude/agentvalet-permissions.md`));
576
990
  } else {
577
991
  await runRefresh({
578
992
  envFile: opts.output,
@@ -580,10 +994,10 @@ Source the env file before calling any tool:`);
580
994
  ifStale: false,
581
995
  quiet: isJson
582
996
  });
583
- if (!isJson) console.log(chalk2.gray(`Permissions: .claude/agentvalet-permissions.md`));
997
+ if (!isJson) console.log(chalk5.gray(`Permissions: .claude/agentvalet-permissions.md`));
584
998
  }
585
999
  } catch {
586
- if (!isJson) console.log(chalk2.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
1000
+ if (!isJson) console.log(chalk5.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
587
1001
  }
588
1002
  }
589
1003
  process.exit(0);
@@ -598,12 +1012,12 @@ program.command("refresh").description("Refresh approved permissions and update
598
1012
  });
599
1013
  } catch (err) {
600
1014
  const msg = err instanceof Error ? err.message : String(err);
601
- console.error(chalk2.red(`Refresh failed: ${msg}`));
1015
+ console.error(chalk5.red(`Refresh failed: ${msg}`));
602
1016
  process.exit(3);
603
1017
  }
604
1018
  });
605
1019
  program.command("mcp-server").description("Start the AgentValet MCP server (stdio transport)").action(async () => {
606
- await import("./mcp-server-DMQWPHYT.js");
1020
+ await import("./mcp-server-LUNOQPUO.js");
607
1021
  });
608
1022
  program.parseAsync().catch((err) => {
609
1023
  console.error(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentvalet/register",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "Self-register AI agents with AgentValet",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,7 +11,7 @@
11
11
  "README.md"
12
12
  ],
13
13
  "scripts": {
14
- "build": "tsup src/index.ts --format esm --dts --clean",
14
+ "build": "tsup src/index.ts --format esm --dts --clean --shims",
15
15
  "dev": "tsx src/index.ts",
16
16
  "test": "vitest run",
17
17
  "typecheck": "tsc --noEmit",
@@ -19,9 +19,12 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@modelcontextprotocol/sdk": "^1.29.0",
22
+ "@octokit/auth-oauth-device": "^7.0.0",
22
23
  "chalk": "^5.3.0",
23
24
  "commander": "^12.0.0",
25
+ "conf": "^13.0.0",
24
26
  "jose": "^6.2.2",
27
+ "open": "^10.0.0",
25
28
  "ora": "^8.0.1",
26
29
  "prompts": "^2.4.2",
27
30
  "undici": "^6.0.0"