@agentvalet/register 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +101 -20
  2. package/package.json +11 -12
package/dist/index.js CHANGED
@@ -10,8 +10,8 @@ import {
10
10
 
11
11
  // src/index.ts
12
12
  import { createRequire as createRequire2 } from "module";
13
- import { Command as Command7 } from "commander";
14
- import chalk14 from "chalk";
13
+ import { Command as Command8 } from "commander";
14
+ import chalk15 from "chalk";
15
15
 
16
16
  // src/wizard.ts
17
17
  import prompts from "prompts";
@@ -765,6 +765,14 @@ function parseEnvFile(content) {
765
765
  }
766
766
  return result;
767
767
  }
768
+ function resolveAgent(envFile = ".env.agentvalet") {
769
+ const creds = tryResolveAgent(envFile);
770
+ if (!creds) {
771
+ process.stderr.write(NO_AGENT_MSG + "\n");
772
+ process.exit(1);
773
+ }
774
+ return creds;
775
+ }
768
776
  function tryResolveAgent(envFile = ".env.agentvalet") {
769
777
  let agentId;
770
778
  let ownerId;
@@ -2779,13 +2787,84 @@ Or run 'agentvalet-register inject' to write this into ~/.claude.json automatica
2779
2787
  });
2780
2788
  }
2781
2789
 
2790
+ // src/commands/git-credential.ts
2791
+ import { Command as Command7 } from "commander";
2792
+ import { readFileSync as readFileSync6 } from "fs";
2793
+ import { execFileSync } from "child_process";
2794
+ import chalk14 from "chalk";
2795
+ var GIT_USERNAME = "agentvalet";
2796
+ function parseCredentialInput(input) {
2797
+ const out = {};
2798
+ for (const raw of input.split("\n")) {
2799
+ const line = raw.replace(/\r$/, "");
2800
+ if (line === "") break;
2801
+ const eq = line.indexOf("=");
2802
+ if (eq <= 0) continue;
2803
+ out[line.slice(0, eq)] = line.slice(eq + 1);
2804
+ }
2805
+ return out;
2806
+ }
2807
+ function respondToCredentialRequest(action, request2, creds, privateKeyPem) {
2808
+ if (action !== "get") return "";
2809
+ let proxyHost;
2810
+ try {
2811
+ proxyHost = new URL(creds.apiUrl).host.toLowerCase();
2812
+ } catch {
2813
+ return "";
2814
+ }
2815
+ if ((request2.host ?? "").toLowerCase() !== proxyHost) return "";
2816
+ const jwt = signJwt(creds.agentId, creds.ownerId, privateKeyPem);
2817
+ return `username=${GIT_USERNAME}
2818
+ password=${jwt}
2819
+ `;
2820
+ }
2821
+ function gitConfigLine(apiUrl) {
2822
+ const origin = new URL(apiUrl).origin;
2823
+ return [`credential.${origin}.helper`, "!agentvalet git-credential"];
2824
+ }
2825
+ async function readStdin() {
2826
+ const chunks = [];
2827
+ for await (const c of process.stdin) chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(c));
2828
+ return Buffer.concat(chunks).toString("utf8");
2829
+ }
2830
+ function gitCredentialCommand() {
2831
+ return new Command7("git-credential").description("git credential helper: answers the AgentValet proxy with this agent's JWT (used via `agentvalet git-setup`)").argument("<action>", "get | store | erase (supplied by git)").action(async (action) => {
2832
+ const creds = resolveAgent();
2833
+ const request2 = parseCredentialInput(await readStdin());
2834
+ if (action !== "get") return;
2835
+ const pem = readFileSync6(creds.keyPath, "utf8");
2836
+ const reply = respondToCredentialRequest(action, request2, creds, pem);
2837
+ if (reply) process.stdout.write(reply);
2838
+ });
2839
+ }
2840
+ function gitSetupCommand() {
2841
+ return new Command7("git-setup").description("Configure git to authenticate to the AgentValet proxy with this agent's key").option("--local", "Write to the current repository's .git/config instead of the global config").option("--print", "Print the git config command instead of running it").action((opts) => {
2842
+ const creds = resolveAgent();
2843
+ const [key, value] = gitConfigLine(creds.apiUrl);
2844
+ const args = ["config", opts.local ? "--local" : "--global", key, value];
2845
+ if (opts.print) {
2846
+ process.stdout.write(`git ${args.map((a) => /\s|!/.test(a) ? JSON.stringify(a) : a).join(" ")}
2847
+ `);
2848
+ return;
2849
+ }
2850
+ execFileSync("git", args, { stdio: "inherit" });
2851
+ const origin = new URL(creds.apiUrl).origin;
2852
+ process.stderr.write(
2853
+ chalk14.green("\n \u2713 git will authenticate to ") + origin + chalk14.green(" as agent ") + creds.agentId + "\n" + chalk14.dim(`
2854
+ Use remotes of the form ${origin}/git/<owner>/<repo>.git
2855
+
2856
+ `)
2857
+ );
2858
+ });
2859
+ }
2860
+
2782
2861
  // src/index.ts
2783
2862
  var require2 = createRequire2(import.meta.url);
2784
2863
  var { version } = require2("../package.json");
2785
2864
  function collectScope(value, previous) {
2786
2865
  return [...previous, value];
2787
2866
  }
2788
- var program = new Command7();
2867
+ var program = new Command8();
2789
2868
  program.name("agentvalet-register").description("Self-register an AI agent with AgentValet").version(version).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("--json", "Machine-readable JSON output").option("--no-wait", "Register only, do not wait for approval").option("--timeout <seconds>", "Approval wait timeout in seconds", "300").option("--project", "Write project-scoped MCP configs (.mcp.json, .cursor/mcp.json) instead of user-scoped (~/.claude.json, ~/.cursor/mcp.json)").option("--force", "Replace an existing agent's key (a timestamped backup is written first)").action(async (opts) => {
2790
2869
  const isJson = !!opts.json;
2791
2870
  let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
@@ -2819,7 +2898,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
2819
2898
  console.error(JSON.stringify({ error: "--owner or AGENTVALET_OWNER is required" }));
2820
2899
  process.exit(3);
2821
2900
  }
2822
- console.error(chalk14.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
2901
+ console.error(chalk15.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
2823
2902
  process.exit(3);
2824
2903
  }
2825
2904
  const scopeMap = /* @__PURE__ */ new Map();
@@ -2827,7 +2906,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
2827
2906
  const colon = s.indexOf(":");
2828
2907
  if (colon === -1) {
2829
2908
  console.error(
2830
- isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk14.red(`Invalid scope format: ${s} (expected platform:scope)`)
2909
+ isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk15.red(`Invalid scope format: ${s} (expected platform:scope)`)
2831
2910
  );
2832
2911
  process.exit(3);
2833
2912
  }
@@ -2850,11 +2929,11 @@ program.name("agentvalet-register").description("Self-register an AI agent with
2850
2929
  });
2851
2930
  } catch (err) {
2852
2931
  const msg = err instanceof Error ? err.message : String(err);
2853
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk14.red(`Registration failed: ${msg}`));
2932
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Registration failed: ${msg}`));
2854
2933
  process.exit(3);
2855
2934
  }
2856
2935
  if (!isJson) {
2857
- console.log(chalk14.cyan(`
2936
+ console.log(chalk15.cyan(`
2858
2937
  Approve at: https://app.agentvalet.ai/agents
2859
2938
  `));
2860
2939
  }
@@ -2862,7 +2941,7 @@ Approve at: https://app.agentvalet.ai/agents
2862
2941
  if (isJson) {
2863
2942
  console.log(JSON.stringify({ status: "pending", token }));
2864
2943
  } else {
2865
- console.log(chalk14.yellow("Registration submitted (--no-wait). Token:"), token);
2944
+ console.log(chalk15.yellow("Registration submitted (--no-wait). Token:"), token);
2866
2945
  }
2867
2946
  process.exit(0);
2868
2947
  }
@@ -2873,14 +2952,14 @@ Approve at: https://app.agentvalet.ai/agents
2873
2952
  });
2874
2953
  } catch (err) {
2875
2954
  const msg = err instanceof Error ? err.message : String(err);
2876
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk14.red(`Wait failed: ${msg}`));
2955
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Wait failed: ${msg}`));
2877
2956
  process.exit(3);
2878
2957
  }
2879
2958
  if (result.status === "rejected") {
2880
2959
  if (isJson) {
2881
2960
  console.log(JSON.stringify({ status: "rejected" }));
2882
2961
  } else {
2883
- console.log(chalk14.red("\nRegistration denied by owner."));
2962
+ console.log(chalk15.red("\nRegistration denied by owner."));
2884
2963
  }
2885
2964
  process.exit(1);
2886
2965
  }
@@ -2888,7 +2967,7 @@ Approve at: https://app.agentvalet.ai/agents
2888
2967
  if (isJson) {
2889
2968
  console.log(JSON.stringify({ status: "timeout" }));
2890
2969
  } else {
2891
- console.log(chalk14.yellow("\nTimed out waiting for approval."));
2970
+ console.log(chalk15.yellow("\nTimed out waiting for approval."));
2892
2971
  }
2893
2972
  process.exit(2);
2894
2973
  }
@@ -2908,10 +2987,10 @@ Approve at: https://app.agentvalet.ai/agents
2908
2987
  } catch (err) {
2909
2988
  const msg = err instanceof Error ? err.message : String(err);
2910
2989
  if (err instanceof KeyClobberError) {
2911
- console.error(isJson ? JSON.stringify({ error: msg, existing_agent_id: err.existingAgentId }) : chalk14.red(msg));
2990
+ console.error(isJson ? JSON.stringify({ error: msg, existing_agent_id: err.existingAgentId }) : chalk15.red(msg));
2912
2991
  process.exit(3);
2913
2992
  }
2914
- console.error(isJson ? JSON.stringify({ error: msg }) : chalk14.red(`Failed to save output: ${msg}`));
2993
+ console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Failed to save output: ${msg}`));
2915
2994
  process.exit(3);
2916
2995
  }
2917
2996
  } else {
@@ -2921,25 +3000,25 @@ Approve at: https://app.agentvalet.ai/agents
2921
3000
  if (isJson) {
2922
3001
  console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null }));
2923
3002
  } else {
2924
- console.log(chalk14.green(`
3003
+ console.log(chalk15.green(`
2925
3004
  Approved! Agent ID: ${agentId}`));
2926
3005
  if (keyWritten) {
2927
- console.log(chalk14.gray(`Key: ${keyPath}`));
3006
+ console.log(chalk15.gray(`Key: ${keyPath}`));
2928
3007
  } else {
2929
- console.log(chalk14.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
3008
+ console.log(chalk15.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
2930
3009
  }
2931
3010
  }
2932
3011
  if (keyWritten) {
2933
3012
  try {
2934
3013
  if (grantedPlatforms && grantedPlatforms.length > 0) {
2935
3014
  writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
2936
- if (!isJson) console.log(chalk14.gray(`Permissions: .claude/agentvalet-permissions.md`));
3015
+ if (!isJson) console.log(chalk15.gray(`Permissions: .claude/agentvalet-permissions.md`));
2937
3016
  } else {
2938
3017
  await runRefresh({ envFile: ".env.agentvalet", outputPath: ".claude/agentvalet-permissions.md", ifStale: false, quiet: isJson });
2939
- if (!isJson) console.log(chalk14.gray(`Permissions: .claude/agentvalet-permissions.md`));
3018
+ if (!isJson) console.log(chalk15.gray(`Permissions: .claude/agentvalet-permissions.md`));
2940
3019
  }
2941
3020
  } catch {
2942
- if (!isJson) console.log(chalk14.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
3021
+ if (!isJson) console.log(chalk15.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
2943
3022
  }
2944
3023
  }
2945
3024
  process.exit(0);
@@ -2954,7 +3033,7 @@ program.command("refresh").description("Refresh approved permissions and update
2954
3033
  });
2955
3034
  } catch (err) {
2956
3035
  const msg = err instanceof Error ? err.message : String(err);
2957
- console.error(chalk14.red(`Refresh failed: ${msg}`));
3036
+ console.error(chalk15.red(`Refresh failed: ${msg}`));
2958
3037
  process.exit(3);
2959
3038
  }
2960
3039
  });
@@ -2964,6 +3043,8 @@ program.command("mcp-server").description("Start the AgentValet MCP server (stdi
2964
3043
  });
2965
3044
  program.addCommand(listCommand());
2966
3045
  program.addCommand(revokeCommand());
3046
+ program.addCommand(gitCredentialCommand());
3047
+ program.addCommand(gitSetupCommand());
2967
3048
  program.addCommand(injectCommand());
2968
3049
  program.addCommand(uninstallCommand());
2969
3050
  program.addCommand(installCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentvalet/register",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Self-register AI agents with AgentValet",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,13 +10,6 @@
10
10
  "dist",
11
11
  "README.md"
12
12
  ],
13
- "scripts": {
14
- "build": "tsup src/index.ts --format esm --dts --clean --shims",
15
- "dev": "tsx src/index.ts",
16
- "test": "vitest run",
17
- "typecheck": "tsc --noEmit",
18
- "prepublishOnly": "node ../../scripts/no-secrets.mjs && pnpm build && node ../../scripts/no-workspace-protocol.mjs"
19
- },
20
13
  "dependencies": {
21
14
  "@modelcontextprotocol/sdk": "^1.29.0",
22
15
  "@octokit/auth-oauth-device": "^7.0.0",
@@ -29,13 +22,13 @@
29
22
  "undici": "^6.0.0"
30
23
  },
31
24
  "devDependencies": {
32
- "@agentvalet/mcp-server": "workspace:^",
33
25
  "@types/node": "^20.0.0",
34
26
  "@types/prompts": "^2.4.0",
35
27
  "tsup": "^8.0.0",
36
28
  "tsx": "^4.0.0",
37
29
  "typescript": "^5.0.0",
38
- "vitest": "^1.5.0"
30
+ "vitest": "^1.5.0",
31
+ "@agentvalet/mcp-server": "^1.14.0"
39
32
  },
40
33
  "engines": {
41
34
  "node": ">=18"
@@ -61,5 +54,11 @@
61
54
  "valet",
62
55
  "agentvalet"
63
56
  ],
64
- "license": "MIT"
65
- }
57
+ "license": "MIT",
58
+ "scripts": {
59
+ "build": "tsup src/index.ts --format esm --dts --clean --shims",
60
+ "dev": "tsx src/index.ts",
61
+ "test": "vitest run",
62
+ "typecheck": "tsc --noEmit"
63
+ }
64
+ }