@agentvalet/register 0.4.13 → 0.4.15
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/chunk-2EFPJNYK.js +32 -0
- package/dist/index.js +201 -275
- package/dist/store-JYJXDBYX.js +16 -0
- package/package.json +1 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/config/store.ts
|
|
2
|
+
import Conf from "conf";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
var AGENT_DIR = join(homedir(), ".agentvalet");
|
|
6
|
+
var AGENT_KEY_PATH = join(AGENT_DIR, "agent.key");
|
|
7
|
+
var store = new Conf({
|
|
8
|
+
projectName: "agentvalet",
|
|
9
|
+
cwd: AGENT_DIR,
|
|
10
|
+
configName: "config"
|
|
11
|
+
});
|
|
12
|
+
function getStoredConfig() {
|
|
13
|
+
return store.store;
|
|
14
|
+
}
|
|
15
|
+
function saveConfig(config) {
|
|
16
|
+
store.set(config);
|
|
17
|
+
}
|
|
18
|
+
function clearConfig() {
|
|
19
|
+
store.clear();
|
|
20
|
+
}
|
|
21
|
+
function isAuthenticated() {
|
|
22
|
+
return !!store.get("apiKey");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
AGENT_DIR,
|
|
27
|
+
AGENT_KEY_PATH,
|
|
28
|
+
getStoredConfig,
|
|
29
|
+
saveConfig,
|
|
30
|
+
clearConfig,
|
|
31
|
+
isAuthenticated
|
|
32
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
AGENT_DIR,
|
|
4
|
+
AGENT_KEY_PATH,
|
|
5
|
+
clearConfig,
|
|
6
|
+
getStoredConfig,
|
|
7
|
+
isAuthenticated,
|
|
8
|
+
saveConfig
|
|
9
|
+
} from "./chunk-2EFPJNYK.js";
|
|
2
10
|
|
|
3
11
|
// src/index.ts
|
|
4
|
-
import { createRequire } from "module";
|
|
12
|
+
import { createRequire as createRequire2 } from "module";
|
|
5
13
|
import { Command as Command5 } from "commander";
|
|
6
14
|
import chalk12 from "chalk";
|
|
7
15
|
|
|
@@ -167,33 +175,29 @@ function parseEvent(data) {
|
|
|
167
175
|
return null;
|
|
168
176
|
}
|
|
169
177
|
function sleep(ms) {
|
|
170
|
-
return new Promise((
|
|
178
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
171
179
|
}
|
|
172
180
|
|
|
173
181
|
// src/save.ts
|
|
174
182
|
import { writeFile, mkdir } from "fs/promises";
|
|
175
|
-
import { dirname, resolve } from "path";
|
|
176
183
|
async function saveOutput(opts) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
].join("\n");
|
|
190
|
-
await writeFile(envPath, envContent, "utf-8");
|
|
191
|
-
return { keyPath, envPath };
|
|
184
|
+
await mkdir(AGENT_DIR, { recursive: true });
|
|
185
|
+
await writeFile(AGENT_KEY_PATH, opts.privateKey, { mode: 384 });
|
|
186
|
+
saveConfig({
|
|
187
|
+
agentId: opts.agentId,
|
|
188
|
+
ownerId: opts.ownerId,
|
|
189
|
+
apiUrl: opts.apiUrl,
|
|
190
|
+
keyPath: AGENT_KEY_PATH,
|
|
191
|
+
// keep legacy fields in sync
|
|
192
|
+
lastAgentId: opts.agentId,
|
|
193
|
+
lastKeyPath: AGENT_KEY_PATH
|
|
194
|
+
});
|
|
195
|
+
return { keyPath: AGENT_KEY_PATH };
|
|
192
196
|
}
|
|
193
197
|
|
|
194
198
|
// src/commands/refresh.ts
|
|
195
199
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, statSync } from "fs";
|
|
196
|
-
import { dirname
|
|
200
|
+
import { dirname, resolve as resolve2 } from "path";
|
|
197
201
|
|
|
198
202
|
// src/lib/jwt.ts
|
|
199
203
|
import { createSign, createPrivateKey } from "crypto";
|
|
@@ -629,27 +633,7 @@ To refresh this file: \`npx @agentvalet/register refresh\`
|
|
|
629
633
|
|
|
630
634
|
// src/lib/require-agent.ts
|
|
631
635
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
632
|
-
import { resolve
|
|
633
|
-
|
|
634
|
-
// src/config/store.ts
|
|
635
|
-
import Conf from "conf";
|
|
636
|
-
var store = new Conf({
|
|
637
|
-
projectName: "agentvalet"
|
|
638
|
-
});
|
|
639
|
-
function getStoredConfig() {
|
|
640
|
-
return store.store;
|
|
641
|
-
}
|
|
642
|
-
function saveConfig(config) {
|
|
643
|
-
store.set(config);
|
|
644
|
-
}
|
|
645
|
-
function clearConfig() {
|
|
646
|
-
store.clear();
|
|
647
|
-
}
|
|
648
|
-
function isAuthenticated() {
|
|
649
|
-
return !!store.get("apiKey");
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
// src/lib/require-agent.ts
|
|
636
|
+
import { resolve } from "path";
|
|
653
637
|
import chalk3 from "chalk";
|
|
654
638
|
var NO_AGENT_MSG = chalk3.red("\n \u2717 No agent registered.\n") + chalk3.dim(
|
|
655
639
|
" Run the following command first to register an agent in this directory:\n\n npx @agentvalet/register\n"
|
|
@@ -670,45 +654,34 @@ function tryResolveAgent(envFile = ".env.agentvalet") {
|
|
|
670
654
|
let ownerId;
|
|
671
655
|
let apiUrl = "https://api.agentvalet.ai";
|
|
672
656
|
let keyPath;
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
keyPath = vars["AGENTVALET_PRIVATE_KEY_PATH"];
|
|
681
|
-
} catch {
|
|
682
|
-
}
|
|
657
|
+
try {
|
|
658
|
+
const stored = getStoredConfig();
|
|
659
|
+
agentId = stored.agentId ?? stored.lastAgentId ?? void 0;
|
|
660
|
+
ownerId = stored.ownerId ?? void 0;
|
|
661
|
+
apiUrl = stored.apiUrl ?? stored.proxyUrl ?? apiUrl;
|
|
662
|
+
keyPath = stored.keyPath ?? stored.lastKeyPath ?? void 0;
|
|
663
|
+
} catch {
|
|
683
664
|
}
|
|
684
|
-
if (!
|
|
685
|
-
|
|
686
|
-
|
|
665
|
+
if (!keyPath) keyPath = AGENT_KEY_PATH;
|
|
666
|
+
if (!agentId || !ownerId) {
|
|
667
|
+
const envPath = resolve(envFile);
|
|
668
|
+
if (existsSync2(envPath)) {
|
|
687
669
|
try {
|
|
688
|
-
const
|
|
689
|
-
agentId = agentId ??
|
|
690
|
-
|
|
691
|
-
|
|
670
|
+
const vars = parseEnvFile(readFileSync2(envPath, "utf-8"));
|
|
671
|
+
agentId = agentId ?? vars["AGENTVALET_AGENT_ID"];
|
|
672
|
+
ownerId = ownerId ?? vars["AGENTVALET_OWNER_ID"];
|
|
673
|
+
apiUrl = vars["AGENTVALET_API_URL"] ?? apiUrl;
|
|
674
|
+
keyPath = vars["AGENTVALET_PRIVATE_KEY_PATH"] ?? keyPath;
|
|
692
675
|
} catch {
|
|
693
676
|
}
|
|
694
677
|
}
|
|
695
|
-
try {
|
|
696
|
-
const global = getStoredConfig();
|
|
697
|
-
if (!ownerId) ownerId = global.ownerId ?? void 0;
|
|
698
|
-
} catch {
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
if (!agentId || !ownerId || !keyPath) {
|
|
702
|
-
try {
|
|
703
|
-
const global = getStoredConfig();
|
|
704
|
-
agentId = agentId ?? global.lastAgentId ?? void 0;
|
|
705
|
-
ownerId = ownerId ?? global.ownerId ?? void 0;
|
|
706
|
-
keyPath = keyPath ?? global.lastKeyPath ?? void 0;
|
|
707
|
-
apiUrl = global.proxyUrl ?? apiUrl;
|
|
708
|
-
} catch {
|
|
709
|
-
}
|
|
710
678
|
}
|
|
679
|
+
agentId = agentId ?? process.env["AGENTVALET_AGENT_ID"];
|
|
680
|
+
ownerId = ownerId ?? process.env["AGENTVALET_OWNER_ID"];
|
|
681
|
+
if (process.env["AGENTVALET_API_URL"]) apiUrl = process.env["AGENTVALET_API_URL"];
|
|
682
|
+
if (process.env["AGENTVALET_PRIVATE_KEY_PATH"]) keyPath = process.env["AGENTVALET_PRIVATE_KEY_PATH"];
|
|
711
683
|
if (!agentId || !ownerId || !keyPath) return null;
|
|
684
|
+
if (!existsSync2(resolve(keyPath))) return null;
|
|
712
685
|
return { agentId, ownerId, keyPath, apiUrl };
|
|
713
686
|
}
|
|
714
687
|
|
|
@@ -719,19 +692,19 @@ var HOOK_COMMAND = "npx @agentvalet/register refresh --if-stale --quiet 2>/dev/n
|
|
|
719
692
|
var HOOK_MARKER = "agentvalet/register refresh";
|
|
720
693
|
function writePermissionsFromEvent(agentId, ownerId, platforms, outputPath = "./.claude/agentvalet-permissions.md") {
|
|
721
694
|
const content = generatePermissionsFile(agentId, ownerId, platforms);
|
|
722
|
-
const resolvedPath =
|
|
723
|
-
mkdirSync2(
|
|
695
|
+
const resolvedPath = resolve2(outputPath);
|
|
696
|
+
mkdirSync2(dirname(resolvedPath), { recursive: true });
|
|
724
697
|
writeFileSync2(resolvedPath, content, "utf-8");
|
|
725
698
|
embedInClaudeMd(content);
|
|
726
699
|
ensureHook();
|
|
727
700
|
}
|
|
728
701
|
async function runRefresh(options) {
|
|
729
|
-
const outputPath =
|
|
702
|
+
const outputPath = resolve2(options.outputPath);
|
|
730
703
|
if (options.ifStale) {
|
|
731
704
|
try {
|
|
732
705
|
const stat = statSync(outputPath);
|
|
733
706
|
const fileIsFresh = Date.now() - stat.mtimeMs < 36e5;
|
|
734
|
-
const claudeMdPath =
|
|
707
|
+
const claudeMdPath = resolve2("CLAUDE.md");
|
|
735
708
|
const claudeMd = existsSync3(claudeMdPath) ? readFileSync3(claudeMdPath, "utf-8") : "";
|
|
736
709
|
const blockStart = claudeMd.indexOf(CLAUDE_START);
|
|
737
710
|
const blockEnd = claudeMd.indexOf(CLAUDE_END);
|
|
@@ -742,7 +715,7 @@ async function runRefresh(options) {
|
|
|
742
715
|
}
|
|
743
716
|
}
|
|
744
717
|
const creds = tryResolveAgent(options.envFile);
|
|
745
|
-
if (!creds || !existsSync3(
|
|
718
|
+
if (!creds || !existsSync3(resolve2(creds.keyPath))) {
|
|
746
719
|
console.error(" \u2717 No agent registered.\n Run the following command first to register an agent in this directory:\n\n npx @agentvalet/register\n");
|
|
747
720
|
process.exit(1);
|
|
748
721
|
}
|
|
@@ -767,7 +740,7 @@ async function runRefresh(options) {
|
|
|
767
740
|
const json = await res.json();
|
|
768
741
|
const platforms = json.data?.platforms ?? [];
|
|
769
742
|
const content = generatePermissionsFile(agentId, ownerId, platforms);
|
|
770
|
-
mkdirSync2(
|
|
743
|
+
mkdirSync2(dirname(outputPath), { recursive: true });
|
|
771
744
|
writeFileSync2(outputPath, content, "utf-8");
|
|
772
745
|
embedInClaudeMd(content);
|
|
773
746
|
ensureHook();
|
|
@@ -776,7 +749,7 @@ async function runRefresh(options) {
|
|
|
776
749
|
}
|
|
777
750
|
}
|
|
778
751
|
function embedInClaudeMd(permissionsContent) {
|
|
779
|
-
const claudeMdPath =
|
|
752
|
+
const claudeMdPath = resolve2("CLAUDE.md");
|
|
780
753
|
const block = `${CLAUDE_START}
|
|
781
754
|
${permissionsContent.trimEnd()}
|
|
782
755
|
${CLAUDE_END}`;
|
|
@@ -803,7 +776,7 @@ ${block}
|
|
|
803
776
|
}
|
|
804
777
|
}
|
|
805
778
|
function ensureHook() {
|
|
806
|
-
const settingsPath =
|
|
779
|
+
const settingsPath = resolve2(".claude/settings.local.json");
|
|
807
780
|
let settings = {};
|
|
808
781
|
if (existsSync3(settingsPath)) {
|
|
809
782
|
try {
|
|
@@ -829,12 +802,12 @@ function ensureHook() {
|
|
|
829
802
|
perms.allow = [...allow, ...missing];
|
|
830
803
|
settings.permissions = perms;
|
|
831
804
|
}
|
|
832
|
-
mkdirSync2(
|
|
805
|
+
mkdirSync2(dirname(settingsPath), { recursive: true });
|
|
833
806
|
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
834
807
|
ensureMcpJson();
|
|
835
808
|
}
|
|
836
809
|
function ensureMcpJson() {
|
|
837
|
-
const mcpJsonPath =
|
|
810
|
+
const mcpJsonPath = resolve2(".mcp.json");
|
|
838
811
|
let mcpConfig = {};
|
|
839
812
|
if (existsSync3(mcpJsonPath)) {
|
|
840
813
|
try {
|
|
@@ -867,97 +840,108 @@ import chalk7 from "chalk";
|
|
|
867
840
|
import ora from "ora";
|
|
868
841
|
import prompts3 from "prompts";
|
|
869
842
|
|
|
870
|
-
// src/auth/
|
|
871
|
-
import {
|
|
843
|
+
// src/auth/browser-flow.ts
|
|
844
|
+
import { createServer } from "http";
|
|
845
|
+
import { createRequire } from "module";
|
|
872
846
|
import open from "open";
|
|
873
847
|
import chalk4 from "chalk";
|
|
874
|
-
var
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
848
|
+
var _require = createRequire(import.meta.url);
|
|
849
|
+
var FUNCTIONS_URL = "https://jmodblrolfoavrxqgbps.supabase.co/functions/v1";
|
|
850
|
+
var SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imptb2RibHJvbGZvYXZyeHFnYnBzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzQwODIzNzYsImV4cCI6MjA4OTY1ODM3Nn0.xQQiYHXbDsHyiTd5TsAfXtNWBUGkT4eO7Ew9UH8n6UE";
|
|
851
|
+
var APP_URL = "https://app.agentvalet.ai";
|
|
852
|
+
var CALLBACK_TIMEOUT_MS = 12e4;
|
|
853
|
+
async function findFreePort() {
|
|
854
|
+
return new Promise((resolve4, reject) => {
|
|
855
|
+
const server = createServer();
|
|
856
|
+
server.listen(0, "127.0.0.1", () => {
|
|
857
|
+
const addr = server.address();
|
|
858
|
+
if (!addr || typeof addr === "string") {
|
|
859
|
+
reject(new Error("Could not bind port"));
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
const port = addr.port;
|
|
863
|
+
server.close(() => resolve4(port));
|
|
864
|
+
});
|
|
865
|
+
server.on("error", reject);
|
|
892
866
|
});
|
|
893
|
-
const tokenAuth = await auth({ type: "oauth" });
|
|
894
|
-
return {
|
|
895
|
-
token: tokenAuth.token,
|
|
896
|
-
scopes: tokenAuth.scopes ?? []
|
|
897
|
-
};
|
|
898
867
|
}
|
|
899
|
-
async function
|
|
900
|
-
const
|
|
868
|
+
async function callCliAuth(body) {
|
|
869
|
+
const res = await fetch(`${FUNCTIONS_URL}/cli-auth`, {
|
|
870
|
+
method: "POST",
|
|
901
871
|
headers: {
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
}
|
|
872
|
+
"Content-Type": "application/json",
|
|
873
|
+
"apikey": SUPABASE_ANON_KEY
|
|
874
|
+
},
|
|
875
|
+
body: JSON.stringify(body)
|
|
905
876
|
});
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
877
|
+
const json = await res.json();
|
|
878
|
+
if (!res.ok) throw new Error(json.error ?? `HTTP ${res.status}`);
|
|
879
|
+
return json;
|
|
880
|
+
}
|
|
881
|
+
async function browserLogin() {
|
|
882
|
+
const state = crypto.randomUUID();
|
|
883
|
+
const port = await findFreePort();
|
|
884
|
+
await callCliAuth({ action: "init", state, port });
|
|
885
|
+
const codePromise = new Promise((resolve4, reject) => {
|
|
886
|
+
const server = createServer((req, res) => {
|
|
887
|
+
const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
|
|
888
|
+
if (url.pathname !== "/callback") {
|
|
889
|
+
res.writeHead(404);
|
|
890
|
+
res.end();
|
|
891
|
+
return;
|
|
915
892
|
}
|
|
893
|
+
const code2 = url.searchParams.get("code");
|
|
894
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
895
|
+
res.end(
|
|
896
|
+
"<!doctype html><html><head><title>AgentValet CLI</title><style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#060e1a;color:rgba(255,255,255,.87)}h2{margin:0 0 8px}p{margin:0;color:rgba(255,255,255,.45);font-size:14px}</style></head><body><div style='text-align:center'><h2 style='color:#34c97b'>✓ Authorized</h2><p>You can close this tab and return to your terminal.</p></div></body></html>"
|
|
897
|
+
);
|
|
898
|
+
server.close();
|
|
899
|
+
if (code2) resolve4(code2);
|
|
900
|
+
else reject(new Error("No code in callback URL"));
|
|
916
901
|
});
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
902
|
+
server.listen(port, "127.0.0.1");
|
|
903
|
+
server.on("error", (err) => reject(err));
|
|
904
|
+
setTimeout(() => {
|
|
905
|
+
server.close();
|
|
906
|
+
reject(new Error("Timed out waiting for browser authorization (2 min)"));
|
|
907
|
+
}, CALLBACK_TIMEOUT_MS);
|
|
908
|
+
});
|
|
909
|
+
const authUrl = `${APP_URL}/cli-auth?state=${state}&port=${port}`;
|
|
910
|
+
console.log(chalk4.dim(`
|
|
911
|
+
Opening browser to authorize...`));
|
|
912
|
+
console.log(chalk4.dim(` URL: ${authUrl}
|
|
913
|
+
`));
|
|
914
|
+
await open(authUrl).catch(() => {
|
|
915
|
+
console.log(chalk4.yellow(` Could not open browser automatically.`));
|
|
916
|
+
console.log(chalk4.yellow(` Please open this URL in your browser:
|
|
917
|
+
`));
|
|
918
|
+
console.log(` ${authUrl}
|
|
919
|
+
`);
|
|
920
|
+
});
|
|
921
|
+
const code = await codePromise;
|
|
922
|
+
const result = await callCliAuth({ action: "exchange", state, code });
|
|
923
|
+
return {
|
|
924
|
+
ownerId: result.owner_id,
|
|
925
|
+
orgId: result.org_id ?? null,
|
|
926
|
+
cliToken: result.cli_token,
|
|
927
|
+
email: result.email ?? null,
|
|
928
|
+
proxyUrl: result.proxy_url ?? "https://api.agentvalet.ai"
|
|
929
|
+
};
|
|
923
930
|
}
|
|
924
931
|
|
|
925
932
|
// src/api/agentvalet.ts
|
|
926
933
|
var SUPABASE_URL = "https://jmodblrolfoavrxqgbps.supabase.co";
|
|
927
|
-
var
|
|
928
|
-
var
|
|
934
|
+
var SUPABASE_ANON_KEY2 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imptb2RibHJvbGZvYXZyeHFnYnBzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzQwODIzNzYsImV4cCI6MjA4OTY1ODM3Nn0.xQQiYHXbDsHyiTd5TsAfXtNWBUGkT4eO7Ew9UH8n6UE";
|
|
935
|
+
var FUNCTIONS_URL2 = `${SUPABASE_URL}/functions/v1`;
|
|
929
936
|
var baseHeaders = {
|
|
930
937
|
"Content-Type": "application/json",
|
|
931
|
-
"apikey":
|
|
938
|
+
"apikey": SUPABASE_ANON_KEY2
|
|
932
939
|
};
|
|
933
|
-
async function createOrFindAccount(params) {
|
|
934
|
-
const controller = new AbortController();
|
|
935
|
-
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
936
|
-
try {
|
|
937
|
-
const response = await fetch(`${FUNCTIONS_URL}/cli-account`, {
|
|
938
|
-
method: "POST",
|
|
939
|
-
headers: baseHeaders,
|
|
940
|
-
body: JSON.stringify(params),
|
|
941
|
-
signal: controller.signal
|
|
942
|
-
});
|
|
943
|
-
if (!response.ok) {
|
|
944
|
-
const error = await response.json().catch(() => ({}));
|
|
945
|
-
throw new Error(`Account setup failed: ${response.status} ${error.error ?? ""}`);
|
|
946
|
-
}
|
|
947
|
-
return response.json();
|
|
948
|
-
} catch (err) {
|
|
949
|
-
clearTimeout(timeout);
|
|
950
|
-
if (err?.name === "AbortError") throw new Error("Request timed out \u2014 is the AgentValet API reachable?");
|
|
951
|
-
throw err;
|
|
952
|
-
} finally {
|
|
953
|
-
clearTimeout(timeout);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
940
|
async function registerAgent2(params, apiKey) {
|
|
957
941
|
const controller = new AbortController();
|
|
958
942
|
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
959
943
|
try {
|
|
960
|
-
const response = await fetch(`${
|
|
944
|
+
const response = await fetch(`${FUNCTIONS_URL2}/cli-register-agent`, {
|
|
961
945
|
method: "POST",
|
|
962
946
|
headers: {
|
|
963
947
|
...baseHeaders,
|
|
@@ -983,7 +967,7 @@ async function getAccount(apiKey) {
|
|
|
983
967
|
const controller = new AbortController();
|
|
984
968
|
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
985
969
|
try {
|
|
986
|
-
const response = await fetch(`${
|
|
970
|
+
const response = await fetch(`${FUNCTIONS_URL2}/cli-account`, {
|
|
987
971
|
headers: {
|
|
988
972
|
...baseHeaders,
|
|
989
973
|
"Authorization": `Bearer ${apiKey}`
|
|
@@ -1370,10 +1354,10 @@ async function runOnboard() {
|
|
|
1370
1354
|
name: "authMethod",
|
|
1371
1355
|
message: "How would you like to sign in?",
|
|
1372
1356
|
choices: [
|
|
1373
|
-
{ title: "Sign in with
|
|
1357
|
+
{ title: "Sign in with your browser (opens app.agentvalet.ai)", value: "browser" },
|
|
1374
1358
|
{ title: "Paste Owner ID from app.agentvalet.ai/settings", value: "ownerid" }
|
|
1375
1359
|
],
|
|
1376
|
-
hint: "No
|
|
1360
|
+
hint: "No account yet? Visit app.agentvalet.ai to sign up first"
|
|
1377
1361
|
});
|
|
1378
1362
|
if (authMethod === void 0) {
|
|
1379
1363
|
process.exit(0);
|
|
@@ -1382,65 +1366,24 @@ async function runOnboard() {
|
|
|
1382
1366
|
await ownerIdFlow();
|
|
1383
1367
|
return;
|
|
1384
1368
|
}
|
|
1385
|
-
let
|
|
1386
|
-
let githubToken;
|
|
1369
|
+
let credentials;
|
|
1387
1370
|
try {
|
|
1388
|
-
|
|
1389
|
-
githubToken = result.token;
|
|
1390
|
-
} catch (err) {
|
|
1391
|
-
console.error(chalk7.red(` \u2717 Authentication failed: ${err.message}`));
|
|
1392
|
-
process.exit(1);
|
|
1393
|
-
}
|
|
1394
|
-
spinner = ora(" Fetching your GitHub profile...").start();
|
|
1395
|
-
let githubUser;
|
|
1396
|
-
try {
|
|
1397
|
-
githubUser = await getGitHubUser(githubToken);
|
|
1398
|
-
spinner.succeed(` GitHub: ${chalk7.bold("@" + githubUser.login)}`);
|
|
1399
|
-
} catch (err) {
|
|
1400
|
-
spinner.fail(` Failed to fetch GitHub profile: ${err.message}`);
|
|
1401
|
-
process.exit(1);
|
|
1402
|
-
}
|
|
1403
|
-
if (!githubUser.email) {
|
|
1404
|
-
const { email } = await prompts3({
|
|
1405
|
-
type: "text",
|
|
1406
|
-
name: "email",
|
|
1407
|
-
message: "Your email address (not visible on GitHub):",
|
|
1408
|
-
validate: (v) => v.includes("@") || "Please enter a valid email"
|
|
1409
|
-
});
|
|
1410
|
-
if (email === void 0) {
|
|
1411
|
-
process.exit(0);
|
|
1412
|
-
}
|
|
1413
|
-
githubUser.email = email;
|
|
1414
|
-
}
|
|
1415
|
-
spinner = ora(" Setting up your AgentValet account...").start();
|
|
1416
|
-
let account;
|
|
1417
|
-
try {
|
|
1418
|
-
account = await createOrFindAccount({
|
|
1419
|
-
github_token: githubToken,
|
|
1420
|
-
github_username: githubUser.login,
|
|
1421
|
-
email: githubUser.email,
|
|
1422
|
-
display_name: githubUser.name ?? githubUser.login,
|
|
1423
|
-
avatar_url: githubUser.avatar_url
|
|
1424
|
-
});
|
|
1425
|
-
if (account.is_new_account) {
|
|
1426
|
-
spinner.succeed(" AgentValet account created");
|
|
1427
|
-
} else {
|
|
1428
|
-
spinner.succeed(" Existing AgentValet account found");
|
|
1429
|
-
}
|
|
1371
|
+
credentials = await browserLogin();
|
|
1430
1372
|
} catch (err) {
|
|
1431
|
-
|
|
1373
|
+
console.error(chalk7.red(`
|
|
1374
|
+
\u2717 Authentication failed: ${err.message}`));
|
|
1432
1375
|
process.exit(1);
|
|
1433
1376
|
}
|
|
1377
|
+
console.log(chalk7.green(` \u2713 Signed in${credentials.email ? " as " + chalk7.bold(credentials.email) : ""}`));
|
|
1434
1378
|
saveConfig({
|
|
1435
|
-
apiKey:
|
|
1436
|
-
ownerId:
|
|
1437
|
-
orgId:
|
|
1438
|
-
proxyUrl:
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
cliToken: account.cli_token
|
|
1379
|
+
apiKey: credentials.ownerId,
|
|
1380
|
+
ownerId: credentials.ownerId,
|
|
1381
|
+
orgId: credentials.orgId ?? void 0,
|
|
1382
|
+
proxyUrl: credentials.proxyUrl,
|
|
1383
|
+
email: credentials.email ?? "",
|
|
1384
|
+
cliToken: credentials.cliToken
|
|
1442
1385
|
});
|
|
1443
|
-
await registerAgentFlow(
|
|
1386
|
+
await registerAgentFlow(credentials.cliToken, credentials.ownerId);
|
|
1444
1387
|
}
|
|
1445
1388
|
async function ownerIdFlow() {
|
|
1446
1389
|
console.log("");
|
|
@@ -1703,12 +1646,12 @@ function revokeCommand() {
|
|
|
1703
1646
|
process.exit(1);
|
|
1704
1647
|
}
|
|
1705
1648
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1706
|
-
const confirmed = await new Promise((
|
|
1649
|
+
const confirmed = await new Promise((resolve4) => {
|
|
1707
1650
|
rl.question(
|
|
1708
1651
|
chalk9.yellow(`Revoke ${opts.agentId}? This cascades to all child agents and cannot be undone. (y/N) `),
|
|
1709
1652
|
(ans) => {
|
|
1710
1653
|
rl.close();
|
|
1711
|
-
|
|
1654
|
+
resolve4(ans.trim().toLowerCase() === "y");
|
|
1712
1655
|
}
|
|
1713
1656
|
);
|
|
1714
1657
|
});
|
|
@@ -1736,9 +1679,9 @@ import { readFile as readFile5 } from "fs/promises";
|
|
|
1736
1679
|
|
|
1737
1680
|
// src/lib/claude-config.ts
|
|
1738
1681
|
import { homedir } from "os";
|
|
1739
|
-
import { join
|
|
1682
|
+
import { join } from "path";
|
|
1740
1683
|
import { readFile as readFile3, writeFile as writeFile6, mkdir as mkdir4, access } from "fs/promises";
|
|
1741
|
-
var CLAUDE_CONFIG_PATH =
|
|
1684
|
+
var CLAUDE_CONFIG_PATH = join(homedir(), ".claude", "config");
|
|
1742
1685
|
async function writeKeyToClaudeConfig(agentId, privateKeyPem) {
|
|
1743
1686
|
let config = {};
|
|
1744
1687
|
try {
|
|
@@ -1749,7 +1692,7 @@ async function writeKeyToClaudeConfig(agentId, privateKeyPem) {
|
|
|
1749
1692
|
}
|
|
1750
1693
|
config.agent_keys = config.agent_keys ?? {};
|
|
1751
1694
|
config.agent_keys[agentId] = Buffer.from(privateKeyPem).toString("base64");
|
|
1752
|
-
await mkdir4(
|
|
1695
|
+
await mkdir4(join(homedir(), ".claude"), { recursive: true });
|
|
1753
1696
|
await writeFile6(CLAUDE_CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
|
|
1754
1697
|
}
|
|
1755
1698
|
|
|
@@ -1820,13 +1763,12 @@ function injectCommand() {
|
|
|
1820
1763
|
import { Command as Command4 } from "commander";
|
|
1821
1764
|
import chalk11 from "chalk";
|
|
1822
1765
|
import { existsSync as existsSync7, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync } from "fs";
|
|
1823
|
-
import { resolve as
|
|
1824
|
-
import { homedir as homedir2 } from "os";
|
|
1766
|
+
import { resolve as resolve3 } from "path";
|
|
1825
1767
|
var CLAUDE_START2 = "<!-- agentvalet:start -->";
|
|
1826
1768
|
var CLAUDE_END2 = "<!-- agentvalet:end -->";
|
|
1827
1769
|
var HOOK_MARKER2 = "agentvalet/register refresh";
|
|
1828
1770
|
function stripClaudeMd() {
|
|
1829
|
-
const path7 =
|
|
1771
|
+
const path7 = resolve3("CLAUDE.md");
|
|
1830
1772
|
if (!existsSync7(path7)) return;
|
|
1831
1773
|
let content = readFileSync4(path7, "utf-8");
|
|
1832
1774
|
content = content.replace(new RegExp(`${CLAUDE_START2}[\\s\\S]*?${CLAUDE_END2}`, "m"), "");
|
|
@@ -1835,7 +1777,7 @@ function stripClaudeMd() {
|
|
|
1835
1777
|
writeFileSync3(path7, content ? content + "\n" : "", "utf-8");
|
|
1836
1778
|
}
|
|
1837
1779
|
function stripSettingsJson() {
|
|
1838
|
-
const path7 =
|
|
1780
|
+
const path7 = resolve3(".claude/settings.local.json");
|
|
1839
1781
|
if (!existsSync7(path7)) return;
|
|
1840
1782
|
try {
|
|
1841
1783
|
const settings = JSON.parse(readFileSync4(path7, "utf-8"));
|
|
@@ -1854,7 +1796,7 @@ function stripSettingsJson() {
|
|
|
1854
1796
|
}
|
|
1855
1797
|
}
|
|
1856
1798
|
function stripMcpJson() {
|
|
1857
|
-
const path7 =
|
|
1799
|
+
const path7 = resolve3(".mcp.json");
|
|
1858
1800
|
if (!existsSync7(path7)) return;
|
|
1859
1801
|
try {
|
|
1860
1802
|
const config = JSON.parse(readFileSync4(path7, "utf-8"));
|
|
@@ -1865,20 +1807,23 @@ function stripMcpJson() {
|
|
|
1865
1807
|
} catch {
|
|
1866
1808
|
}
|
|
1867
1809
|
}
|
|
1868
|
-
function deleteIfExists(p) {
|
|
1869
|
-
const abs = resolve4(p);
|
|
1870
|
-
if (existsSync7(abs)) {
|
|
1871
|
-
rmSync(abs, { recursive: true, force: true });
|
|
1872
|
-
return abs;
|
|
1873
|
-
}
|
|
1874
|
-
return null;
|
|
1875
|
-
}
|
|
1876
1810
|
function cleanLocally() {
|
|
1877
1811
|
const removed = [];
|
|
1878
1812
|
const r = (p) => {
|
|
1879
|
-
const
|
|
1880
|
-
if (
|
|
1813
|
+
const abs = resolve3(p);
|
|
1814
|
+
if (existsSync7(abs)) {
|
|
1815
|
+
rmSync(abs, { recursive: true, force: true });
|
|
1816
|
+
removed.push(abs);
|
|
1817
|
+
}
|
|
1881
1818
|
};
|
|
1819
|
+
if (existsSync7(AGENT_KEY_PATH)) {
|
|
1820
|
+
rmSync(AGENT_KEY_PATH, { force: true });
|
|
1821
|
+
removed.push(AGENT_KEY_PATH);
|
|
1822
|
+
}
|
|
1823
|
+
try {
|
|
1824
|
+
clearConfig();
|
|
1825
|
+
} catch {
|
|
1826
|
+
}
|
|
1882
1827
|
r(".env.agentvalet");
|
|
1883
1828
|
r(".agentvalet");
|
|
1884
1829
|
r("agentvalet.key");
|
|
@@ -1886,17 +1831,8 @@ function cleanLocally() {
|
|
|
1886
1831
|
stripClaudeMd();
|
|
1887
1832
|
stripSettingsJson();
|
|
1888
1833
|
stripMcpJson();
|
|
1889
|
-
try {
|
|
1890
|
-
saveConfig({ lastAgentId: "", lastKeyPath: "" });
|
|
1891
|
-
} catch {
|
|
1892
|
-
}
|
|
1893
|
-
const oldConfig = join3(homedir2(), ".agentvalet", "config.json");
|
|
1894
|
-
if (existsSync7(oldConfig)) {
|
|
1895
|
-
rmSync(oldConfig, { force: true });
|
|
1896
|
-
removed.push(oldConfig);
|
|
1897
|
-
}
|
|
1898
1834
|
if (removed.length > 0) {
|
|
1899
|
-
console.log(chalk11.green(" \u2713 Removed
|
|
1835
|
+
console.log(chalk11.green(" \u2713 Removed files:"));
|
|
1900
1836
|
for (const f of removed) console.log(chalk11.dim(` ${f}`));
|
|
1901
1837
|
}
|
|
1902
1838
|
console.log(chalk11.green(" \u2713 Cleaned CLAUDE.md, .mcp.json, .claude/settings.local.json"));
|
|
@@ -1905,12 +1841,12 @@ var SSE_READ_TIMEOUT_MS = 25e3;
|
|
|
1905
1841
|
async function pollForApproval(apiUrl, revocationToken, timeoutMs) {
|
|
1906
1842
|
const streamUrl = `${apiUrl}/v1/revoke-request/stream/${revocationToken}`;
|
|
1907
1843
|
const deadline = Date.now() + timeoutMs;
|
|
1908
|
-
return new Promise((
|
|
1844
|
+
return new Promise((resolve4) => {
|
|
1909
1845
|
let settled = false;
|
|
1910
1846
|
function done(result) {
|
|
1911
1847
|
if (!settled) {
|
|
1912
1848
|
settled = true;
|
|
1913
|
-
|
|
1849
|
+
resolve4(result);
|
|
1914
1850
|
}
|
|
1915
1851
|
}
|
|
1916
1852
|
function connect() {
|
|
@@ -2047,13 +1983,13 @@ function uninstallCommand() {
|
|
|
2047
1983
|
}
|
|
2048
1984
|
|
|
2049
1985
|
// src/index.ts
|
|
2050
|
-
var require2 =
|
|
1986
|
+
var require2 = createRequire2(import.meta.url);
|
|
2051
1987
|
var { version } = require2("../package.json");
|
|
2052
1988
|
function collectScope(value, previous) {
|
|
2053
1989
|
return [...previous, value];
|
|
2054
1990
|
}
|
|
2055
1991
|
var program = new Command5();
|
|
2056
|
-
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("--
|
|
1992
|
+
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").action(async (opts) => {
|
|
2057
1993
|
const isJson = !!opts.json;
|
|
2058
1994
|
let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
|
|
2059
1995
|
let agentName = opts.name ?? "";
|
|
@@ -2155,39 +2091,34 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
2155
2091
|
const { agentId, privateKey, grantedPlatforms } = result;
|
|
2156
2092
|
const resolvedOwnerId = result.ownerId || ownerId;
|
|
2157
2093
|
let keyPath;
|
|
2158
|
-
let envPath;
|
|
2159
|
-
try {
|
|
2160
|
-
({ keyPath, envPath } = await saveOutput({
|
|
2161
|
-
agentId,
|
|
2162
|
-
ownerId: resolvedOwnerId,
|
|
2163
|
-
privateKey: privateKey ?? "",
|
|
2164
|
-
apiUrl: opts.apiUrl,
|
|
2165
|
-
keyFilePath: opts.keyPath,
|
|
2166
|
-
envFilePath: opts.output
|
|
2167
|
-
}));
|
|
2168
|
-
} catch (err) {
|
|
2169
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
2170
|
-
console.error(isJson ? JSON.stringify({ error: msg }) : chalk12.red(`Failed to save output: ${msg}`));
|
|
2171
|
-
process.exit(3);
|
|
2172
|
-
}
|
|
2173
2094
|
const keyWritten = !!privateKey;
|
|
2174
2095
|
if (keyWritten) {
|
|
2175
|
-
|
|
2096
|
+
try {
|
|
2097
|
+
({ keyPath } = await saveOutput({
|
|
2098
|
+
agentId,
|
|
2099
|
+
ownerId: resolvedOwnerId,
|
|
2100
|
+
privateKey,
|
|
2101
|
+
apiUrl: opts.apiUrl
|
|
2102
|
+
}));
|
|
2103
|
+
} catch (err) {
|
|
2104
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2105
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk12.red(`Failed to save output: ${msg}`));
|
|
2106
|
+
process.exit(3);
|
|
2107
|
+
}
|
|
2108
|
+
} else {
|
|
2109
|
+
const { AGENT_KEY_PATH: AGENT_KEY_PATH2 } = await import("./store-JYJXDBYX.js");
|
|
2110
|
+
keyPath = AGENT_KEY_PATH2;
|
|
2176
2111
|
}
|
|
2177
2112
|
if (isJson) {
|
|
2178
|
-
console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null
|
|
2113
|
+
console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null }));
|
|
2179
2114
|
} else {
|
|
2180
2115
|
console.log(chalk12.green(`
|
|
2181
2116
|
Approved! Agent ID: ${agentId}`));
|
|
2182
2117
|
if (keyWritten) {
|
|
2183
|
-
console.log(chalk12.gray(`Key:
|
|
2118
|
+
console.log(chalk12.gray(`Key: ${keyPath}`));
|
|
2184
2119
|
} else {
|
|
2185
|
-
console.log(chalk12.yellow(`Key:
|
|
2120
|
+
console.log(chalk12.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
|
|
2186
2121
|
}
|
|
2187
|
-
console.log(chalk12.gray(`Env file: ${envPath}`));
|
|
2188
|
-
console.log(`
|
|
2189
|
-
Source the env file before calling any tool:`);
|
|
2190
|
-
console.log(chalk12.cyan(` source ${envPath}`));
|
|
2191
2122
|
}
|
|
2192
2123
|
if (keyWritten) {
|
|
2193
2124
|
try {
|
|
@@ -2195,12 +2126,7 @@ Source the env file before calling any tool:`);
|
|
|
2195
2126
|
writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
|
|
2196
2127
|
if (!isJson) console.log(chalk12.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
2197
2128
|
} else {
|
|
2198
|
-
await runRefresh({
|
|
2199
|
-
envFile: opts.output,
|
|
2200
|
-
outputPath: ".claude/agentvalet-permissions.md",
|
|
2201
|
-
ifStale: false,
|
|
2202
|
-
quiet: isJson
|
|
2203
|
-
});
|
|
2129
|
+
await runRefresh({ envFile: ".env.agentvalet", outputPath: ".claude/agentvalet-permissions.md", ifStale: false, quiet: isJson });
|
|
2204
2130
|
if (!isJson) console.log(chalk12.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
2205
2131
|
}
|
|
2206
2132
|
} catch {
|
|
@@ -2209,10 +2135,10 @@ Source the env file before calling any tool:`);
|
|
|
2209
2135
|
}
|
|
2210
2136
|
process.exit(0);
|
|
2211
2137
|
});
|
|
2212
|
-
program.command("refresh").description("Refresh approved permissions and update .claude/agentvalet-permissions.md").option("--
|
|
2138
|
+
program.command("refresh").description("Refresh approved permissions and update .claude/agentvalet-permissions.md").option("--output <path>", "Path to write permissions file", "./.claude/agentvalet-permissions.md").option("--if-stale", "Skip if file is less than 1 hour old").option("--quiet", "Suppress output").action(async (opts) => {
|
|
2213
2139
|
try {
|
|
2214
2140
|
await runRefresh({
|
|
2215
|
-
envFile:
|
|
2141
|
+
envFile: ".env.agentvalet",
|
|
2216
2142
|
outputPath: opts.output,
|
|
2217
2143
|
ifStale: !!opts.ifStale,
|
|
2218
2144
|
quiet: !!opts.quiet
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGENT_DIR,
|
|
3
|
+
AGENT_KEY_PATH,
|
|
4
|
+
clearConfig,
|
|
5
|
+
getStoredConfig,
|
|
6
|
+
isAuthenticated,
|
|
7
|
+
saveConfig
|
|
8
|
+
} from "./chunk-2EFPJNYK.js";
|
|
9
|
+
export {
|
|
10
|
+
AGENT_DIR,
|
|
11
|
+
AGENT_KEY_PATH,
|
|
12
|
+
clearConfig,
|
|
13
|
+
getStoredConfig,
|
|
14
|
+
isAuthenticated,
|
|
15
|
+
saveConfig
|
|
16
|
+
};
|