@agentvalet/register 1.5.0 → 1.7.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 +126 -28
- package/package.json +1 -1
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;
|
|
@@ -1255,6 +1263,7 @@ async function browserLogin() {
|
|
|
1255
1263
|
}
|
|
1256
1264
|
|
|
1257
1265
|
// src/api/agentvalet.ts
|
|
1266
|
+
import { generateKeyPairSync } from "crypto";
|
|
1258
1267
|
var API_URL2 = process.env.AGENTVALET_API_URL ?? "https://api.agentvalet.ai";
|
|
1259
1268
|
var FUNCTIONS_URL2 = `${API_URL2}/functions/v1`;
|
|
1260
1269
|
var baseHeaders = {
|
|
@@ -1287,6 +1296,20 @@ async function registerAgent2(params, apiKey) {
|
|
|
1287
1296
|
clearTimeout(timeout);
|
|
1288
1297
|
}
|
|
1289
1298
|
}
|
|
1299
|
+
async function registerAgentWithLocalKey(params, apiKey) {
|
|
1300
|
+
const { publicKey, privateKey } = generateKeyPairSync("rsa", {
|
|
1301
|
+
modulusLength: 2048,
|
|
1302
|
+
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
1303
|
+
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
1304
|
+
});
|
|
1305
|
+
const agent = await registerAgent2({ ...params, public_key_pem: publicKey }, apiKey);
|
|
1306
|
+
if (agent.private_key_pem || agent.public_key_pem?.trim() !== publicKey.trim()) {
|
|
1307
|
+
throw new Error(
|
|
1308
|
+
`The server did not accept this machine's public key, so agent ${agent.agent_id} cannot use it. Delete that agent in the dashboard and try again later, or report this to AgentValet support.`
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
return { agent, privateKeyPem: privateKey };
|
|
1312
|
+
}
|
|
1290
1313
|
|
|
1291
1314
|
// src/config/local.ts
|
|
1292
1315
|
import { mkdir as mkdir2, writeFile as writeFile2, appendFile, readFile } from "fs/promises";
|
|
@@ -1688,13 +1711,14 @@ async function registerAgentFlow(apiKey, ownerId, scope = "user", presetName) {
|
|
|
1688
1711
|
const agentType = resolveAgentType(detectedAtRegister);
|
|
1689
1712
|
const spinner = ora(" Registering agent...").start();
|
|
1690
1713
|
let agent;
|
|
1714
|
+
let privateKeyPem;
|
|
1691
1715
|
try {
|
|
1692
|
-
agent = await
|
|
1716
|
+
({ agent, privateKeyPem } = await registerAgentWithLocalKey({
|
|
1693
1717
|
owner_id: ownerId,
|
|
1694
1718
|
name: agentName.trim(),
|
|
1695
1719
|
source: "cli",
|
|
1696
1720
|
agent_type: agentType
|
|
1697
|
-
}, apiKey);
|
|
1721
|
+
}, apiKey));
|
|
1698
1722
|
spinner.succeed(` Agent registered: ${chalk7.bold(agent.agent_id)}`);
|
|
1699
1723
|
} catch (err) {
|
|
1700
1724
|
spinner.fail(` Registration failed: ${err.message}`);
|
|
@@ -1707,7 +1731,7 @@ async function registerAgentFlow(apiKey, ownerId, scope = "user", presetName) {
|
|
|
1707
1731
|
agentId: agent.agent_id,
|
|
1708
1732
|
agentName: agent.agent_name,
|
|
1709
1733
|
proxyUrl,
|
|
1710
|
-
privateKeyPem
|
|
1734
|
+
privateKeyPem
|
|
1711
1735
|
});
|
|
1712
1736
|
saveConfig({ lastAgentId: agent.agent_id, lastKeyPath: keyPath });
|
|
1713
1737
|
} catch (err) {
|
|
@@ -1803,7 +1827,7 @@ async function registerAgentFlow(apiKey, ownerId, scope = "user", presetName) {
|
|
|
1803
1827
|
console.log(
|
|
1804
1828
|
` Dashboard: ${chalk7.cyan.underline("https://app.agentvalet.ai")}`
|
|
1805
1829
|
);
|
|
1806
|
-
console.log(chalk7.dim("
|
|
1830
|
+
console.log(chalk7.dim(" The agent is active but has no access yet. Grant it platforms on its page in the dashboard."));
|
|
1807
1831
|
console.log("");
|
|
1808
1832
|
if (shouldSetup) {
|
|
1809
1833
|
if (scope === "user") {
|
|
@@ -2439,13 +2463,13 @@ function injectCommand() {
|
|
|
2439
2463
|
// src/commands/install.ts
|
|
2440
2464
|
import { writeFile as writeFile9, mkdir as mkdir6 } from "fs/promises";
|
|
2441
2465
|
import path7 from "path";
|
|
2442
|
-
import { generateKeyPairSync } from "crypto";
|
|
2466
|
+
import { generateKeyPairSync as generateKeyPairSync2 } from "crypto";
|
|
2443
2467
|
import { Command as Command5 } from "commander";
|
|
2444
2468
|
import chalk12 from "chalk";
|
|
2445
2469
|
import prompts4 from "prompts";
|
|
2446
2470
|
var API_URL3 = process.env.AGENTVALET_API_URL ?? "https://api.agentvalet.ai";
|
|
2447
2471
|
async function bindInstallToken(proxyUrl, bootstrapToken) {
|
|
2448
|
-
const { publicKey, privateKey } =
|
|
2472
|
+
const { publicKey, privateKey } = generateKeyPairSync2("rsa", {
|
|
2449
2473
|
modulusLength: 2048,
|
|
2450
2474
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
2451
2475
|
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
@@ -2640,7 +2664,7 @@ function installCommand() {
|
|
|
2640
2664
|
|
|
2641
2665
|
// src/commands/claim.ts
|
|
2642
2666
|
import { Command as Command6 } from "commander";
|
|
2643
|
-
import { generateKeyPairSync as
|
|
2667
|
+
import { generateKeyPairSync as generateKeyPairSync3 } from "crypto";
|
|
2644
2668
|
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, existsSync as existsSync9 } from "fs";
|
|
2645
2669
|
import { homedir as homedir3 } from "os";
|
|
2646
2670
|
import { join as join5 } from "path";
|
|
@@ -2700,7 +2724,7 @@ function claimCommand() {
|
|
|
2700
2724
|
process.exit(3);
|
|
2701
2725
|
}
|
|
2702
2726
|
const proxyUrl = opts.apiUrl.replace(/\/$/, "");
|
|
2703
|
-
const { publicKey, privateKey } =
|
|
2727
|
+
const { publicKey, privateKey } = generateKeyPairSync3("rsa", {
|
|
2704
2728
|
modulusLength: 2048,
|
|
2705
2729
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
2706
2730
|
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
@@ -2779,13 +2803,85 @@ Or run 'agentvalet-register inject' to write this into ~/.claude.json automatica
|
|
|
2779
2803
|
});
|
|
2780
2804
|
}
|
|
2781
2805
|
|
|
2806
|
+
// src/commands/git-credential.ts
|
|
2807
|
+
import { Command as Command7 } from "commander";
|
|
2808
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
2809
|
+
import { execFileSync } from "child_process";
|
|
2810
|
+
import chalk14 from "chalk";
|
|
2811
|
+
var GIT_USERNAME = "agentvalet";
|
|
2812
|
+
function parseCredentialInput(input) {
|
|
2813
|
+
const out = {};
|
|
2814
|
+
for (const raw of input.split("\n")) {
|
|
2815
|
+
const line = raw.replace(/\r$/, "");
|
|
2816
|
+
if (line === "") break;
|
|
2817
|
+
const eq = line.indexOf("=");
|
|
2818
|
+
if (eq <= 0) continue;
|
|
2819
|
+
out[line.slice(0, eq)] = line.slice(eq + 1);
|
|
2820
|
+
}
|
|
2821
|
+
return out;
|
|
2822
|
+
}
|
|
2823
|
+
function respondToCredentialRequest(action, request2, creds, privateKeyPem) {
|
|
2824
|
+
if (action !== "get") return "";
|
|
2825
|
+
let proxyHost;
|
|
2826
|
+
try {
|
|
2827
|
+
proxyHost = new URL(creds.apiUrl).host.toLowerCase();
|
|
2828
|
+
} catch {
|
|
2829
|
+
return "";
|
|
2830
|
+
}
|
|
2831
|
+
if ((request2.host ?? "").toLowerCase() !== proxyHost) return "";
|
|
2832
|
+
const jwt = signJwt(creds.agentId, creds.ownerId, privateKeyPem);
|
|
2833
|
+
return `username=${GIT_USERNAME}
|
|
2834
|
+
password=${jwt}
|
|
2835
|
+
`;
|
|
2836
|
+
}
|
|
2837
|
+
var GIT_HELPER_COMMAND = "npx --yes @agentvalet/register git-credential";
|
|
2838
|
+
function gitConfigLine(apiUrl) {
|
|
2839
|
+
const origin = new URL(apiUrl).origin;
|
|
2840
|
+
return [`credential.${origin}.helper`, `!${GIT_HELPER_COMMAND}`];
|
|
2841
|
+
}
|
|
2842
|
+
async function readStdin() {
|
|
2843
|
+
const chunks = [];
|
|
2844
|
+
for await (const c of process.stdin) chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(c));
|
|
2845
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
2846
|
+
}
|
|
2847
|
+
function gitCredentialCommand() {
|
|
2848
|
+
return new Command7("git-credential").description("git credential helper: answers the AgentValet proxy with this agent's JWT (used via `npx @agentvalet/register git-setup`)").argument("<action>", "get | store | erase (supplied by git)").action(async (action) => {
|
|
2849
|
+
const creds = resolveAgent();
|
|
2850
|
+
const request2 = parseCredentialInput(await readStdin());
|
|
2851
|
+
if (action !== "get") return;
|
|
2852
|
+
const pem = readFileSync6(creds.keyPath, "utf8");
|
|
2853
|
+
const reply = respondToCredentialRequest(action, request2, creds, pem);
|
|
2854
|
+
if (reply) process.stdout.write(reply);
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2857
|
+
function gitSetupCommand() {
|
|
2858
|
+
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) => {
|
|
2859
|
+
const creds = resolveAgent();
|
|
2860
|
+
const [key, value] = gitConfigLine(creds.apiUrl);
|
|
2861
|
+
const args = ["config", opts.local ? "--local" : "--global", key, value];
|
|
2862
|
+
if (opts.print) {
|
|
2863
|
+
process.stdout.write(`git ${args.map((a) => /\s|!/.test(a) ? JSON.stringify(a) : a).join(" ")}
|
|
2864
|
+
`);
|
|
2865
|
+
return;
|
|
2866
|
+
}
|
|
2867
|
+
execFileSync("git", args, { stdio: "inherit" });
|
|
2868
|
+
const origin = new URL(creds.apiUrl).origin;
|
|
2869
|
+
process.stderr.write(
|
|
2870
|
+
chalk14.green("\n \u2713 git will authenticate to ") + origin + chalk14.green(" as agent ") + creds.agentId + "\n" + chalk14.dim(`
|
|
2871
|
+
Use remotes of the form ${origin}/git/<owner>/<repo>.git
|
|
2872
|
+
|
|
2873
|
+
`)
|
|
2874
|
+
);
|
|
2875
|
+
});
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2782
2878
|
// src/index.ts
|
|
2783
2879
|
var require2 = createRequire2(import.meta.url);
|
|
2784
2880
|
var { version } = require2("../package.json");
|
|
2785
2881
|
function collectScope(value, previous) {
|
|
2786
2882
|
return [...previous, value];
|
|
2787
2883
|
}
|
|
2788
|
-
var program = new
|
|
2884
|
+
var program = new Command8();
|
|
2789
2885
|
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
2886
|
const isJson = !!opts.json;
|
|
2791
2887
|
let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
|
|
@@ -2819,7 +2915,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
2819
2915
|
console.error(JSON.stringify({ error: "--owner or AGENTVALET_OWNER is required" }));
|
|
2820
2916
|
process.exit(3);
|
|
2821
2917
|
}
|
|
2822
|
-
console.error(
|
|
2918
|
+
console.error(chalk15.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
|
|
2823
2919
|
process.exit(3);
|
|
2824
2920
|
}
|
|
2825
2921
|
const scopeMap = /* @__PURE__ */ new Map();
|
|
@@ -2827,7 +2923,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
2827
2923
|
const colon = s.indexOf(":");
|
|
2828
2924
|
if (colon === -1) {
|
|
2829
2925
|
console.error(
|
|
2830
|
-
isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) :
|
|
2926
|
+
isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk15.red(`Invalid scope format: ${s} (expected platform:scope)`)
|
|
2831
2927
|
);
|
|
2832
2928
|
process.exit(3);
|
|
2833
2929
|
}
|
|
@@ -2850,11 +2946,11 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
2850
2946
|
});
|
|
2851
2947
|
} catch (err) {
|
|
2852
2948
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2853
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
2949
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Registration failed: ${msg}`));
|
|
2854
2950
|
process.exit(3);
|
|
2855
2951
|
}
|
|
2856
2952
|
if (!isJson) {
|
|
2857
|
-
console.log(
|
|
2953
|
+
console.log(chalk15.cyan(`
|
|
2858
2954
|
Approve at: https://app.agentvalet.ai/agents
|
|
2859
2955
|
`));
|
|
2860
2956
|
}
|
|
@@ -2862,7 +2958,7 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2862
2958
|
if (isJson) {
|
|
2863
2959
|
console.log(JSON.stringify({ status: "pending", token }));
|
|
2864
2960
|
} else {
|
|
2865
|
-
console.log(
|
|
2961
|
+
console.log(chalk15.yellow("Registration submitted (--no-wait). Token:"), token);
|
|
2866
2962
|
}
|
|
2867
2963
|
process.exit(0);
|
|
2868
2964
|
}
|
|
@@ -2873,14 +2969,14 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2873
2969
|
});
|
|
2874
2970
|
} catch (err) {
|
|
2875
2971
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2876
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
2972
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Wait failed: ${msg}`));
|
|
2877
2973
|
process.exit(3);
|
|
2878
2974
|
}
|
|
2879
2975
|
if (result.status === "rejected") {
|
|
2880
2976
|
if (isJson) {
|
|
2881
2977
|
console.log(JSON.stringify({ status: "rejected" }));
|
|
2882
2978
|
} else {
|
|
2883
|
-
console.log(
|
|
2979
|
+
console.log(chalk15.red("\nRegistration denied by owner."));
|
|
2884
2980
|
}
|
|
2885
2981
|
process.exit(1);
|
|
2886
2982
|
}
|
|
@@ -2888,7 +2984,7 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2888
2984
|
if (isJson) {
|
|
2889
2985
|
console.log(JSON.stringify({ status: "timeout" }));
|
|
2890
2986
|
} else {
|
|
2891
|
-
console.log(
|
|
2987
|
+
console.log(chalk15.yellow("\nTimed out waiting for approval."));
|
|
2892
2988
|
}
|
|
2893
2989
|
process.exit(2);
|
|
2894
2990
|
}
|
|
@@ -2908,10 +3004,10 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2908
3004
|
} catch (err) {
|
|
2909
3005
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2910
3006
|
if (err instanceof KeyClobberError) {
|
|
2911
|
-
console.error(isJson ? JSON.stringify({ error: msg, existing_agent_id: err.existingAgentId }) :
|
|
3007
|
+
console.error(isJson ? JSON.stringify({ error: msg, existing_agent_id: err.existingAgentId }) : chalk15.red(msg));
|
|
2912
3008
|
process.exit(3);
|
|
2913
3009
|
}
|
|
2914
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
3010
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk15.red(`Failed to save output: ${msg}`));
|
|
2915
3011
|
process.exit(3);
|
|
2916
3012
|
}
|
|
2917
3013
|
} else {
|
|
@@ -2921,25 +3017,25 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2921
3017
|
if (isJson) {
|
|
2922
3018
|
console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null }));
|
|
2923
3019
|
} else {
|
|
2924
|
-
console.log(
|
|
3020
|
+
console.log(chalk15.green(`
|
|
2925
3021
|
Approved! Agent ID: ${agentId}`));
|
|
2926
3022
|
if (keyWritten) {
|
|
2927
|
-
console.log(
|
|
3023
|
+
console.log(chalk15.gray(`Key: ${keyPath}`));
|
|
2928
3024
|
} else {
|
|
2929
|
-
console.log(
|
|
3025
|
+
console.log(chalk15.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
|
|
2930
3026
|
}
|
|
2931
3027
|
}
|
|
2932
3028
|
if (keyWritten) {
|
|
2933
3029
|
try {
|
|
2934
3030
|
if (grantedPlatforms && grantedPlatforms.length > 0) {
|
|
2935
3031
|
writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
|
|
2936
|
-
if (!isJson) console.log(
|
|
3032
|
+
if (!isJson) console.log(chalk15.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
2937
3033
|
} else {
|
|
2938
3034
|
await runRefresh({ envFile: ".env.agentvalet", outputPath: ".claude/agentvalet-permissions.md", ifStale: false, quiet: isJson });
|
|
2939
|
-
if (!isJson) console.log(
|
|
3035
|
+
if (!isJson) console.log(chalk15.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
2940
3036
|
}
|
|
2941
3037
|
} catch {
|
|
2942
|
-
if (!isJson) console.log(
|
|
3038
|
+
if (!isJson) console.log(chalk15.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
|
|
2943
3039
|
}
|
|
2944
3040
|
}
|
|
2945
3041
|
process.exit(0);
|
|
@@ -2954,7 +3050,7 @@ program.command("refresh").description("Refresh approved permissions and update
|
|
|
2954
3050
|
});
|
|
2955
3051
|
} catch (err) {
|
|
2956
3052
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2957
|
-
console.error(
|
|
3053
|
+
console.error(chalk15.red(`Refresh failed: ${msg}`));
|
|
2958
3054
|
process.exit(3);
|
|
2959
3055
|
}
|
|
2960
3056
|
});
|
|
@@ -2964,6 +3060,8 @@ program.command("mcp-server").description("Start the AgentValet MCP server (stdi
|
|
|
2964
3060
|
});
|
|
2965
3061
|
program.addCommand(listCommand());
|
|
2966
3062
|
program.addCommand(revokeCommand());
|
|
3063
|
+
program.addCommand(gitCredentialCommand());
|
|
3064
|
+
program.addCommand(gitSetupCommand());
|
|
2967
3065
|
program.addCommand(injectCommand());
|
|
2968
3066
|
program.addCommand(uninstallCommand());
|
|
2969
3067
|
program.addCommand(installCommand());
|