@agentvalet/register 0.3.5 → 0.3.7
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 +162 -53
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -642,6 +642,30 @@ async function registerAgent2(params, apiKey) {
|
|
|
642
642
|
clearTimeout(timeout);
|
|
643
643
|
}
|
|
644
644
|
}
|
|
645
|
+
async function getAccount(apiKey) {
|
|
646
|
+
const controller = new AbortController();
|
|
647
|
+
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
648
|
+
try {
|
|
649
|
+
const response = await fetch(`${FUNCTIONS_URL}/cli-account`, {
|
|
650
|
+
headers: {
|
|
651
|
+
...baseHeaders,
|
|
652
|
+
"Authorization": `Bearer ${apiKey}`
|
|
653
|
+
},
|
|
654
|
+
signal: controller.signal
|
|
655
|
+
});
|
|
656
|
+
if (!response.ok) {
|
|
657
|
+
const error = await response.json().catch(() => ({}));
|
|
658
|
+
throw new Error(`Failed to fetch account: ${response.status} ${error.error ?? ""}`);
|
|
659
|
+
}
|
|
660
|
+
return response.json();
|
|
661
|
+
} catch (err) {
|
|
662
|
+
clearTimeout(timeout);
|
|
663
|
+
if (err?.name === "AbortError") throw new Error("Request timed out \u2014 is the AgentValet API reachable?");
|
|
664
|
+
throw err;
|
|
665
|
+
} finally {
|
|
666
|
+
clearTimeout(timeout);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
645
669
|
|
|
646
670
|
// src/config/store.ts
|
|
647
671
|
import Conf from "conf";
|
|
@@ -738,6 +762,48 @@ async function mergeJsonFile(filePath, key, value) {
|
|
|
738
762
|
existing.mcpServers = mcpServers;
|
|
739
763
|
await writeFile4(filePath, JSON.stringify(existing, null, 2) + "\n", "utf8");
|
|
740
764
|
}
|
|
765
|
+
function buildClaudeMd(agentId, ownerId, proxyUrl) {
|
|
766
|
+
return `# AgentValet \u2014 Credential Governance
|
|
767
|
+
|
|
768
|
+
Agent ID: \`${agentId}\`
|
|
769
|
+
Owner ID: \`${ownerId}\`
|
|
770
|
+
|
|
771
|
+
All external platform API calls **must** go through the AgentValet proxy.
|
|
772
|
+
Never call platform APIs (Slack, Stripe, Gmail, GitHub, etc.) directly.
|
|
773
|
+
|
|
774
|
+
## Making a platform call
|
|
775
|
+
|
|
776
|
+
Use the \`mcp__agent-authority__use_platform\` MCP tool:
|
|
777
|
+
|
|
778
|
+
\`\`\`
|
|
779
|
+
mcp__agent-authority__use_platform({
|
|
780
|
+
platform: "slack",
|
|
781
|
+
endpoint: "/api/chat.postMessage",
|
|
782
|
+
method: "POST",
|
|
783
|
+
scope: "slack:write",
|
|
784
|
+
data: { channel: "#general", text: "Hello" }
|
|
785
|
+
})
|
|
786
|
+
\`\`\`
|
|
787
|
+
|
|
788
|
+
## Before any platform session
|
|
789
|
+
|
|
790
|
+
1. Call \`mcp__agent-authority__list_platforms\` to see approved platforms and scopes
|
|
791
|
+
2. Call \`mcp__agent-authority__authzen_evaluate\` before destructive operations
|
|
792
|
+
3. If a call returns \`pending_approval\` \u2014 wait, do not retry
|
|
793
|
+
|
|
794
|
+
## Rules
|
|
795
|
+
|
|
796
|
+
- **NEVER** write inline JWT signing code, \`node -e\` scripts, or manual HTTP calls
|
|
797
|
+
- The MCP tool handles authentication automatically
|
|
798
|
+
- \`AGENT_PRIVATE_KEY_PATH\` points to your key \u2014 do not read or log it
|
|
799
|
+
|
|
800
|
+
## If AgentValet MCP is not connected
|
|
801
|
+
|
|
802
|
+
Tell the user: "AgentValet MCP is not connected. Run: npx @agentvalet/register"
|
|
803
|
+
|
|
804
|
+
Dashboard: ${proxyUrl.replace("api.", "app.")}
|
|
805
|
+
`;
|
|
806
|
+
}
|
|
741
807
|
async function writeGlobalFrameworkConfigs(params) {
|
|
742
808
|
const written = [];
|
|
743
809
|
const privateKeyEscaped = params.privateKeyPem.replace(/\n/g, "\\n");
|
|
@@ -764,57 +830,36 @@ AGENT_PRIVATE_KEY = "${privateKeyEscaped}"
|
|
|
764
830
|
console.warn(` Warning: could not write Codex CLI config: ${err.message}`);
|
|
765
831
|
}
|
|
766
832
|
}
|
|
767
|
-
const claudeConfigPath = path4.join(os.homedir(), ".claude", "claude_desktop_config.json");
|
|
768
|
-
if (existsSync4(claudeConfigPath)) {
|
|
769
|
-
try {
|
|
770
|
-
let config = {};
|
|
771
|
-
try {
|
|
772
|
-
const text = await readFile2(claudeConfigPath, "utf8");
|
|
773
|
-
config = JSON.parse(text);
|
|
774
|
-
} catch {
|
|
775
|
-
console.warn(" Warning: ~/.claude/claude_desktop_config.json is malformed \u2014 skipping");
|
|
776
|
-
config = null;
|
|
777
|
-
}
|
|
778
|
-
if (config !== null) {
|
|
779
|
-
if (config.mcpServers?.agentvalet) {
|
|
780
|
-
} else {
|
|
781
|
-
config.mcpServers = config.mcpServers ?? {};
|
|
782
|
-
config.mcpServers.agentvalet = {
|
|
783
|
-
command: "npx",
|
|
784
|
-
args: ["-y", "@agentvalet/mcp-server"],
|
|
785
|
-
env: {
|
|
786
|
-
AGENT_ID: params.agentId,
|
|
787
|
-
OWNER_ID: params.ownerId,
|
|
788
|
-
PROXY_URL: params.proxyUrl,
|
|
789
|
-
AGENT_PRIVATE_KEY: privateKeyEscaped
|
|
790
|
-
}
|
|
791
|
-
};
|
|
792
|
-
await writeFile4(claudeConfigPath, JSON.stringify(config, null, 2) + "\n", "utf8");
|
|
793
|
-
written.push("~/.claude/claude_desktop_config.json");
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
} catch (err) {
|
|
797
|
-
console.warn(` Warning: could not write Claude Code global config: ${err.message}`);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
833
|
return written;
|
|
801
834
|
}
|
|
802
835
|
async function writeIdeConfigs(params) {
|
|
836
|
+
const { detected, ...mcpParams } = params;
|
|
803
837
|
const cwd = process.cwd();
|
|
804
838
|
const written = [];
|
|
805
|
-
const entry = buildMcpEntry(
|
|
806
|
-
|
|
807
|
-
|
|
839
|
+
const entry = buildMcpEntry(mcpParams);
|
|
840
|
+
if (detected.claudeCode) {
|
|
841
|
+
const claudeMcpPath = path4.join(cwd, ".mcp.json");
|
|
808
842
|
try {
|
|
809
843
|
await mergeJsonFile(claudeMcpPath, "agentvalet", entry);
|
|
810
844
|
written.push(".mcp.json");
|
|
811
845
|
} catch (err) {
|
|
812
846
|
console.warn(` Warning: could not write .mcp.json: ${err.message}`);
|
|
813
847
|
}
|
|
848
|
+
const claudeMdPath = path4.join(cwd, "CLAUDE.md");
|
|
849
|
+
if (!existsSync4(claudeMdPath)) {
|
|
850
|
+
try {
|
|
851
|
+
await writeFile4(claudeMdPath, buildClaudeMd(params.agentId, params.ownerId, params.proxyUrl), "utf8");
|
|
852
|
+
written.push("CLAUDE.md");
|
|
853
|
+
} catch (err) {
|
|
854
|
+
console.warn(` Warning: could not write CLAUDE.md: ${err.message}`);
|
|
855
|
+
}
|
|
856
|
+
} else {
|
|
857
|
+
written.push("CLAUDE.md (already exists \u2014 skipped)");
|
|
858
|
+
}
|
|
814
859
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
860
|
+
if (detected.cursor) {
|
|
861
|
+
const cursorDir = path4.join(cwd, ".cursor");
|
|
862
|
+
const cursorMcpPath = path4.join(cursorDir, "mcp.json");
|
|
818
863
|
try {
|
|
819
864
|
await mkdir3(cursorDir, { recursive: true });
|
|
820
865
|
await mergeJsonFile(cursorMcpPath, "agentvalet", entry);
|
|
@@ -832,35 +877,49 @@ import os2 from "os";
|
|
|
832
877
|
import path5 from "path";
|
|
833
878
|
import prompts2 from "prompts";
|
|
834
879
|
import chalk5 from "chalk";
|
|
880
|
+
function cursorInstalled() {
|
|
881
|
+
const home = os2.homedir();
|
|
882
|
+
const platform = process.platform;
|
|
883
|
+
if (platform === "win32") {
|
|
884
|
+
const appData = process.env.APPDATA ?? path5.join(home, "AppData", "Roaming");
|
|
885
|
+
const localAppData = process.env.LOCALAPPDATA ?? path5.join(home, "AppData", "Local");
|
|
886
|
+
return existsSync5(path5.join(appData, "Cursor")) || existsSync5(path5.join(localAppData, "Programs", "cursor"));
|
|
887
|
+
}
|
|
888
|
+
if (platform === "darwin") {
|
|
889
|
+
return existsSync5(path5.join(home, "Library", "Application Support", "Cursor")) || existsSync5("/Applications/Cursor.app");
|
|
890
|
+
}
|
|
891
|
+
return existsSync5(path5.join(home, ".config", "Cursor")) || existsSync5("/usr/share/applications/cursor.desktop");
|
|
892
|
+
}
|
|
835
893
|
function detectFrameworks() {
|
|
836
894
|
const home = os2.homedir();
|
|
837
895
|
return {
|
|
838
896
|
codex: existsSync5(path5.join(home, ".codex", "config.toml")),
|
|
839
897
|
claudeCode: existsSync5(path5.join(home, ".claude")),
|
|
840
|
-
cursor: existsSync5(path5.join(process.cwd(), ".cursor")),
|
|
898
|
+
cursor: existsSync5(path5.join(process.cwd(), ".cursor")) || cursorInstalled(),
|
|
841
899
|
openclaw: existsSync5(path5.join(home, ".openclaw"))
|
|
842
900
|
};
|
|
843
901
|
}
|
|
844
902
|
async function frameworkSetupConsent(detected) {
|
|
845
903
|
const items = [];
|
|
846
|
-
if (detected.codex) {
|
|
847
|
-
items.push("Codex CLI \u2192 add MCP server to ~/.codex/config.toml");
|
|
848
|
-
items.push(" \u2192 copy AGENTS.md to current directory");
|
|
849
|
-
}
|
|
850
|
-
if (detected.openclaw) {
|
|
851
|
-
items.push("OpenClaw \u2192 copy SKILL.md to current directory");
|
|
852
|
-
}
|
|
853
904
|
if (detected.claudeCode) {
|
|
854
|
-
items.push("Claude Code \u2192
|
|
905
|
+
items.push("Claude Code \u2192 .mcp.json (MCP server)");
|
|
906
|
+
items.push(" \u2192 CLAUDE.md (usage rules)");
|
|
855
907
|
}
|
|
856
908
|
if (detected.cursor) {
|
|
857
|
-
items.push("Cursor \u2192 .cursor/mcp.json");
|
|
909
|
+
items.push("Cursor \u2192 .cursor/mcp.json (MCP server)");
|
|
910
|
+
}
|
|
911
|
+
if (detected.codex) {
|
|
912
|
+
items.push("Codex CLI \u2192 ~/.codex/config.toml (MCP server)");
|
|
913
|
+
items.push(" \u2192 AGENTS.md (usage rules)");
|
|
914
|
+
}
|
|
915
|
+
if (detected.openclaw) {
|
|
916
|
+
items.push("OpenClaw \u2192 SKILL.md (usage rules)");
|
|
858
917
|
}
|
|
859
918
|
if (items.length === 0) return false;
|
|
860
919
|
console.log("");
|
|
861
|
-
console.log(chalk5.bold("
|
|
920
|
+
console.log(chalk5.bold(" Detected agent frameworks"));
|
|
862
921
|
for (const item of items) {
|
|
863
|
-
console.log(chalk5.dim(`
|
|
922
|
+
console.log(chalk5.dim(` ${item}`));
|
|
864
923
|
}
|
|
865
924
|
console.log("");
|
|
866
925
|
const { confirm } = await prompts2({
|
|
@@ -910,6 +969,23 @@ async function runOnboard() {
|
|
|
910
969
|
await registerAgentFlow(stored.apiKey, stored.ownerId);
|
|
911
970
|
return;
|
|
912
971
|
}
|
|
972
|
+
const { authMethod } = await prompts3({
|
|
973
|
+
type: "select",
|
|
974
|
+
name: "authMethod",
|
|
975
|
+
message: "How would you like to sign in?",
|
|
976
|
+
choices: [
|
|
977
|
+
{ title: "Sign in with GitHub (opens browser)", value: "github" },
|
|
978
|
+
{ title: "Paste Owner ID from app.agentvalet.ai/settings", value: "ownerid" }
|
|
979
|
+
],
|
|
980
|
+
hint: "No GitHub account? Choose the second option after signing up at app.agentvalet.ai"
|
|
981
|
+
});
|
|
982
|
+
if (authMethod === void 0) {
|
|
983
|
+
process.exit(0);
|
|
984
|
+
}
|
|
985
|
+
if (authMethod === "ownerid") {
|
|
986
|
+
await ownerIdFlow();
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
913
989
|
let spinner = ora();
|
|
914
990
|
let githubToken;
|
|
915
991
|
try {
|
|
@@ -969,6 +1045,38 @@ async function runOnboard() {
|
|
|
969
1045
|
});
|
|
970
1046
|
await registerAgentFlow(account.owner_id, account.owner_id);
|
|
971
1047
|
}
|
|
1048
|
+
async function ownerIdFlow() {
|
|
1049
|
+
console.log("");
|
|
1050
|
+
console.log(chalk6.dim(" Find your Owner ID at: ") + chalk6.cyan.underline("https://app.agentvalet.ai/settings"));
|
|
1051
|
+
console.log("");
|
|
1052
|
+
const { ownerId } = await prompts3({
|
|
1053
|
+
type: "text",
|
|
1054
|
+
name: "ownerId",
|
|
1055
|
+
message: "Paste your Owner ID:",
|
|
1056
|
+
validate: (v) => v.trim().length > 10 || "Owner ID looks too short"
|
|
1057
|
+
});
|
|
1058
|
+
if (ownerId === void 0) {
|
|
1059
|
+
process.exit(0);
|
|
1060
|
+
}
|
|
1061
|
+
const spinner = ora(" Verifying Owner ID...").start();
|
|
1062
|
+
let account;
|
|
1063
|
+
try {
|
|
1064
|
+
account = await getAccount(ownerId.trim());
|
|
1065
|
+
spinner.succeed(` Account verified \u2014 plan: ${chalk6.bold(account.plan)}`);
|
|
1066
|
+
} catch (err) {
|
|
1067
|
+
spinner.fail(` Could not verify Owner ID: ${err.message}`);
|
|
1068
|
+
console.log(chalk6.dim(" Make sure you copied the full Owner ID from app.agentvalet.ai/settings"));
|
|
1069
|
+
process.exit(1);
|
|
1070
|
+
}
|
|
1071
|
+
saveConfig({
|
|
1072
|
+
apiKey: account.owner_id,
|
|
1073
|
+
ownerId: account.owner_id,
|
|
1074
|
+
orgId: account.org_id,
|
|
1075
|
+
proxyUrl: "https://api.agentvalet.ai",
|
|
1076
|
+
email: account.email ?? ""
|
|
1077
|
+
});
|
|
1078
|
+
await registerAgentFlow(account.owner_id, account.owner_id);
|
|
1079
|
+
}
|
|
972
1080
|
async function registerAgentFlow(apiKey, ownerId) {
|
|
973
1081
|
const hostname = os3.hostname().split(".")[0];
|
|
974
1082
|
const dirName = process.cwd().split("/").pop() ?? process.cwd().split("\\").pop() ?? "agent";
|
|
@@ -1017,7 +1125,8 @@ async function registerAgentFlow(apiKey, ownerId) {
|
|
|
1017
1125
|
agentId: agent.agent_id,
|
|
1018
1126
|
ownerId,
|
|
1019
1127
|
proxyUrl: getStoredConfig().proxyUrl,
|
|
1020
|
-
keyPath: path6.join(process.cwd(), ".agentvalet", "agent.key")
|
|
1128
|
+
keyPath: path6.join(process.cwd(), ".agentvalet", "agent.key"),
|
|
1129
|
+
detected
|
|
1021
1130
|
});
|
|
1022
1131
|
for (const r of ideResults) {
|
|
1023
1132
|
console.log(chalk6.green(` \u2713 ${r}`));
|
|
@@ -1079,7 +1188,7 @@ function collectScope(value, previous) {
|
|
|
1079
1188
|
return [...previous, value];
|
|
1080
1189
|
}
|
|
1081
1190
|
var program = new Command();
|
|
1082
|
-
program.name("agentvalet-register").description("Self-register an AI agent with AgentValet").version("0.3.
|
|
1191
|
+
program.name("agentvalet-register").description("Self-register an AI agent with AgentValet").version("0.3.7").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("--output <path>", "Path to write .env file", "./.env.agentvalet").option("--key-path <path>", "Path to write private key", "./agentvalet.key").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").action(async (opts) => {
|
|
1083
1192
|
const isJson = !!opts.json;
|
|
1084
1193
|
let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
|
|
1085
1194
|
let agentName = opts.name ?? "";
|