@agentvalet/register 1.4.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 +109 -21
- 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";
|
|
@@ -661,8 +661,15 @@ function generatePermissionsFile(agentId, ownerId, permissions) {
|
|
|
661
661
|
const gated = new Set(p.approvalScopes ?? []);
|
|
662
662
|
const scopeList = p.scopes.map((s) => ` - \`${s}\`${gated.has(s) ? " \u2014 requires human approval" : ""}`).join("\n");
|
|
663
663
|
const approvalNote = p.requireApproval ? "\n > Requires human approval before executing.\n" : "";
|
|
664
|
+
const vendorBits = [
|
|
665
|
+
p.serverName ? `reports itself as \`${p.serverName}\`` : null,
|
|
666
|
+
p.serverHost ? `served from \`${p.serverHost}\`` : null
|
|
667
|
+
].filter(Boolean);
|
|
668
|
+
const vendorNote = vendorBits.length ? `
|
|
669
|
+
_MCP server \u2014 ${vendorBits.join(", ")}._
|
|
670
|
+
` : "";
|
|
664
671
|
return `### ${p.platformName} (\`${p.platformId}\`)
|
|
665
|
-
|
|
672
|
+
${vendorNote}
|
|
666
673
|
Approved scopes:
|
|
667
674
|
${scopeList}
|
|
668
675
|
${approvalNote}`;
|
|
@@ -758,6 +765,14 @@ function parseEnvFile(content) {
|
|
|
758
765
|
}
|
|
759
766
|
return result;
|
|
760
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
|
+
}
|
|
761
776
|
function tryResolveAgent(envFile = ".env.agentvalet") {
|
|
762
777
|
let agentId;
|
|
763
778
|
let ownerId;
|
|
@@ -2772,13 +2787,84 @@ Or run 'agentvalet-register inject' to write this into ~/.claude.json automatica
|
|
|
2772
2787
|
});
|
|
2773
2788
|
}
|
|
2774
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
|
+
|
|
2775
2861
|
// src/index.ts
|
|
2776
2862
|
var require2 = createRequire2(import.meta.url);
|
|
2777
2863
|
var { version } = require2("../package.json");
|
|
2778
2864
|
function collectScope(value, previous) {
|
|
2779
2865
|
return [...previous, value];
|
|
2780
2866
|
}
|
|
2781
|
-
var program = new
|
|
2867
|
+
var program = new Command8();
|
|
2782
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) => {
|
|
2783
2869
|
const isJson = !!opts.json;
|
|
2784
2870
|
let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
|
|
@@ -2812,7 +2898,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
2812
2898
|
console.error(JSON.stringify({ error: "--owner or AGENTVALET_OWNER is required" }));
|
|
2813
2899
|
process.exit(3);
|
|
2814
2900
|
}
|
|
2815
|
-
console.error(
|
|
2901
|
+
console.error(chalk15.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
|
|
2816
2902
|
process.exit(3);
|
|
2817
2903
|
}
|
|
2818
2904
|
const scopeMap = /* @__PURE__ */ new Map();
|
|
@@ -2820,7 +2906,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
2820
2906
|
const colon = s.indexOf(":");
|
|
2821
2907
|
if (colon === -1) {
|
|
2822
2908
|
console.error(
|
|
2823
|
-
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)`)
|
|
2824
2910
|
);
|
|
2825
2911
|
process.exit(3);
|
|
2826
2912
|
}
|
|
@@ -2843,11 +2929,11 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
2843
2929
|
});
|
|
2844
2930
|
} catch (err) {
|
|
2845
2931
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2846
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
2932
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Registration failed: ${msg}`));
|
|
2847
2933
|
process.exit(3);
|
|
2848
2934
|
}
|
|
2849
2935
|
if (!isJson) {
|
|
2850
|
-
console.log(
|
|
2936
|
+
console.log(chalk15.cyan(`
|
|
2851
2937
|
Approve at: https://app.agentvalet.ai/agents
|
|
2852
2938
|
`));
|
|
2853
2939
|
}
|
|
@@ -2855,7 +2941,7 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2855
2941
|
if (isJson) {
|
|
2856
2942
|
console.log(JSON.stringify({ status: "pending", token }));
|
|
2857
2943
|
} else {
|
|
2858
|
-
console.log(
|
|
2944
|
+
console.log(chalk15.yellow("Registration submitted (--no-wait). Token:"), token);
|
|
2859
2945
|
}
|
|
2860
2946
|
process.exit(0);
|
|
2861
2947
|
}
|
|
@@ -2866,14 +2952,14 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2866
2952
|
});
|
|
2867
2953
|
} catch (err) {
|
|
2868
2954
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2869
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
2955
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Wait failed: ${msg}`));
|
|
2870
2956
|
process.exit(3);
|
|
2871
2957
|
}
|
|
2872
2958
|
if (result.status === "rejected") {
|
|
2873
2959
|
if (isJson) {
|
|
2874
2960
|
console.log(JSON.stringify({ status: "rejected" }));
|
|
2875
2961
|
} else {
|
|
2876
|
-
console.log(
|
|
2962
|
+
console.log(chalk15.red("\nRegistration denied by owner."));
|
|
2877
2963
|
}
|
|
2878
2964
|
process.exit(1);
|
|
2879
2965
|
}
|
|
@@ -2881,7 +2967,7 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2881
2967
|
if (isJson) {
|
|
2882
2968
|
console.log(JSON.stringify({ status: "timeout" }));
|
|
2883
2969
|
} else {
|
|
2884
|
-
console.log(
|
|
2970
|
+
console.log(chalk15.yellow("\nTimed out waiting for approval."));
|
|
2885
2971
|
}
|
|
2886
2972
|
process.exit(2);
|
|
2887
2973
|
}
|
|
@@ -2901,10 +2987,10 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2901
2987
|
} catch (err) {
|
|
2902
2988
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2903
2989
|
if (err instanceof KeyClobberError) {
|
|
2904
|
-
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));
|
|
2905
2991
|
process.exit(3);
|
|
2906
2992
|
}
|
|
2907
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
2993
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Failed to save output: ${msg}`));
|
|
2908
2994
|
process.exit(3);
|
|
2909
2995
|
}
|
|
2910
2996
|
} else {
|
|
@@ -2914,25 +3000,25 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2914
3000
|
if (isJson) {
|
|
2915
3001
|
console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null }));
|
|
2916
3002
|
} else {
|
|
2917
|
-
console.log(
|
|
3003
|
+
console.log(chalk15.green(`
|
|
2918
3004
|
Approved! Agent ID: ${agentId}`));
|
|
2919
3005
|
if (keyWritten) {
|
|
2920
|
-
console.log(
|
|
3006
|
+
console.log(chalk15.gray(`Key: ${keyPath}`));
|
|
2921
3007
|
} else {
|
|
2922
|
-
console.log(
|
|
3008
|
+
console.log(chalk15.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
|
|
2923
3009
|
}
|
|
2924
3010
|
}
|
|
2925
3011
|
if (keyWritten) {
|
|
2926
3012
|
try {
|
|
2927
3013
|
if (grantedPlatforms && grantedPlatforms.length > 0) {
|
|
2928
3014
|
writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
|
|
2929
|
-
if (!isJson) console.log(
|
|
3015
|
+
if (!isJson) console.log(chalk15.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
2930
3016
|
} else {
|
|
2931
3017
|
await runRefresh({ envFile: ".env.agentvalet", outputPath: ".claude/agentvalet-permissions.md", ifStale: false, quiet: isJson });
|
|
2932
|
-
if (!isJson) console.log(
|
|
3018
|
+
if (!isJson) console.log(chalk15.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
2933
3019
|
}
|
|
2934
3020
|
} catch {
|
|
2935
|
-
if (!isJson) console.log(
|
|
3021
|
+
if (!isJson) console.log(chalk15.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
|
|
2936
3022
|
}
|
|
2937
3023
|
}
|
|
2938
3024
|
process.exit(0);
|
|
@@ -2947,7 +3033,7 @@ program.command("refresh").description("Refresh approved permissions and update
|
|
|
2947
3033
|
});
|
|
2948
3034
|
} catch (err) {
|
|
2949
3035
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2950
|
-
console.error(
|
|
3036
|
+
console.error(chalk15.red(`Refresh failed: ${msg}`));
|
|
2951
3037
|
process.exit(3);
|
|
2952
3038
|
}
|
|
2953
3039
|
});
|
|
@@ -2957,6 +3043,8 @@ program.command("mcp-server").description("Start the AgentValet MCP server (stdi
|
|
|
2957
3043
|
});
|
|
2958
3044
|
program.addCommand(listCommand());
|
|
2959
3045
|
program.addCommand(revokeCommand());
|
|
3046
|
+
program.addCommand(gitCredentialCommand());
|
|
3047
|
+
program.addCommand(gitSetupCommand());
|
|
2960
3048
|
program.addCommand(injectCommand());
|
|
2961
3049
|
program.addCommand(uninstallCommand());
|
|
2962
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
|
+
}
|