@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.
- package/dist/index.js +101 -20
- 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
|
|
14
|
-
import
|
|
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
|
|
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(
|
|
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)` }) :
|
|
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 }) :
|
|
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(
|
|
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(
|
|
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 }) :
|
|
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(
|
|
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(
|
|
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 }) :
|
|
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 }) :
|
|
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(
|
|
3003
|
+
console.log(chalk15.green(`
|
|
2925
3004
|
Approved! Agent ID: ${agentId}`));
|
|
2926
3005
|
if (keyWritten) {
|
|
2927
|
-
console.log(
|
|
3006
|
+
console.log(chalk15.gray(`Key: ${keyPath}`));
|
|
2928
3007
|
} else {
|
|
2929
|
-
console.log(
|
|
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(
|
|
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(
|
|
3018
|
+
if (!isJson) console.log(chalk15.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
2940
3019
|
}
|
|
2941
3020
|
} catch {
|
|
2942
|
-
if (!isJson) console.log(
|
|
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(
|
|
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.
|
|
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
|
+
}
|