@agentvalet/register 0.4.12 → 0.4.14
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 +396 -149
- package/dist/store-JYJXDBYX.js +16 -0
- package/package.json +10 -9
|
@@ -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,4 +1,12 @@
|
|
|
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
12
|
import { createRequire } from "module";
|
|
@@ -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
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync, statSync } from "fs";
|
|
196
|
-
import { dirname
|
|
199
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, statSync } from "fs";
|
|
200
|
+
import { dirname, resolve as resolve2 } from "path";
|
|
197
201
|
|
|
198
202
|
// src/lib/jwt.ts
|
|
199
203
|
import { createSign, createPrivateKey } from "crypto";
|
|
@@ -211,7 +215,7 @@ function signJwt(agentId, ownerId, privateKeyPem) {
|
|
|
211
215
|
}
|
|
212
216
|
|
|
213
217
|
// src/lib/skill-writer.ts
|
|
214
|
-
import { existsSync, writeFileSync } from "fs";
|
|
218
|
+
import { existsSync, writeFileSync, mkdirSync } from "fs";
|
|
215
219
|
import { execSync } from "child_process";
|
|
216
220
|
import path from "path";
|
|
217
221
|
import chalk2 from "chalk";
|
|
@@ -316,6 +320,11 @@ The \`.mcp.json\` in this directory has been configured. Run \`/mcp\` in Claude
|
|
|
316
320
|
if (detected.openclaw) {
|
|
317
321
|
lines.push(`### OpenClaw
|
|
318
322
|
See \`SKILL.md\` for platform call instructions.`);
|
|
323
|
+
}
|
|
324
|
+
if (detected.factoryDroid) {
|
|
325
|
+
lines.push(`### Factory Droid
|
|
326
|
+
\`~/.factory/mcp.json\` has been updated with the AgentValet MCP server block.
|
|
327
|
+
Type \`@AgentValet\` in Factory Droid to activate governance. Use \`/av-status\` to verify connections.`);
|
|
319
328
|
}
|
|
320
329
|
if (lines.length === 0) {
|
|
321
330
|
lines.push(`Add the MCP server to your IDE manually. See: https://docs.agentvalet.ai/setup`);
|
|
@@ -370,6 +379,203 @@ AGENT_PRIVATE_KEY_PATH=${keyPath}
|
|
|
370
379
|
console.log(chalk2.green(" \u2713 AGENTVALET.md created \u2014 quick reference for this agent"));
|
|
371
380
|
console.log(chalk2.dim(" Add to .gitignore if it contains sensitive paths"));
|
|
372
381
|
}
|
|
382
|
+
function writeFactoryDroidDroid() {
|
|
383
|
+
const droidsDir = path.join(process.cwd(), ".factory", "droids");
|
|
384
|
+
if (!existsSync(droidsDir)) mkdirSync(droidsDir, { recursive: true });
|
|
385
|
+
const dest = path.join(droidsDir, "agentvalet.yaml");
|
|
386
|
+
if (existsSync(dest)) {
|
|
387
|
+
console.log(chalk2.dim(" Factory Droid: .factory/droids/agentvalet.yaml already exists"));
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const content = `# AgentValet Governance Droid
|
|
391
|
+
# Automatically created by @agentvalet/register
|
|
392
|
+
# Commit this file to your repo
|
|
393
|
+
|
|
394
|
+
name: AgentValet
|
|
395
|
+
description: >
|
|
396
|
+
Routes all platform API calls through AgentValet's credential
|
|
397
|
+
proxy. Enforces per-agent permissions, rate limits, and human
|
|
398
|
+
approval for high-risk operations. Every call is logged.
|
|
399
|
+
|
|
400
|
+
model: inherit
|
|
401
|
+
|
|
402
|
+
mcp_servers:
|
|
403
|
+
- agentvalet
|
|
404
|
+
|
|
405
|
+
autonomy: Low
|
|
406
|
+
|
|
407
|
+
instructions: |
|
|
408
|
+
You are operating under AgentValet credential governance.
|
|
409
|
+
|
|
410
|
+
## Rules \u2014 read before every platform call
|
|
411
|
+
|
|
412
|
+
1. NEVER call platform APIs (Slack, Stripe, Gmail, GitHub, etc.) directly.
|
|
413
|
+
Always use the \`use_platform\` MCP tool.
|
|
414
|
+
|
|
415
|
+
2. Call \`list_platforms\` at the start of any session that involves
|
|
416
|
+
platform calls. Do not assume platforms are available.
|
|
417
|
+
|
|
418
|
+
3. Call \`authzen_evaluate\` before any destructive operation
|
|
419
|
+
(delete, send, charge, publish). Do not proceed if decision=false.
|
|
420
|
+
|
|
421
|
+
4. If \`use_platform\` returns \`{ status: "pending_approval" }\`,
|
|
422
|
+
wait for human approval. Do not retry the call.
|
|
423
|
+
|
|
424
|
+
5. If AgentValet MCP tools are unavailable, stop and tell the user:
|
|
425
|
+
"AgentValet MCP is not connected. Run: npx @agentvalet/register"
|
|
426
|
+
Do not attempt platform calls without governance.
|
|
427
|
+
|
|
428
|
+
## Making a platform call
|
|
429
|
+
|
|
430
|
+
\`\`\`
|
|
431
|
+
use_platform({
|
|
432
|
+
platform: "slack",
|
|
433
|
+
endpoint: "/api/chat.postMessage",
|
|
434
|
+
method: "POST",
|
|
435
|
+
scope: "slack:write",
|
|
436
|
+
data: { channel: "#general", text: "Hello" }
|
|
437
|
+
})
|
|
438
|
+
\`\`\`
|
|
439
|
+
|
|
440
|
+
## Scope categories
|
|
441
|
+
|
|
442
|
+
- Read scopes (*.read, *.list) \u2014 lower risk, may auto-approve
|
|
443
|
+
- Write scopes (*.write, *.create) \u2014 check authzen_evaluate first
|
|
444
|
+
- Destructive scopes (*.delete, stripe:charge, mail:send) \u2014 always
|
|
445
|
+
call authzen_evaluate, always inform user before proceeding
|
|
446
|
+
|
|
447
|
+
Dashboard: https://app.agentvalet.ai
|
|
448
|
+
Docs: https://docs.agentvalet.ai
|
|
449
|
+
`;
|
|
450
|
+
writeFileSync(dest, content, "utf8");
|
|
451
|
+
console.log(chalk2.green(" \u2713 Factory Droid: created .factory/droids/agentvalet.yaml"));
|
|
452
|
+
console.log(chalk2.dim(" Commit this file to your repo"));
|
|
453
|
+
}
|
|
454
|
+
function writeFactoryDroidCommand() {
|
|
455
|
+
const commandsDir = path.join(process.cwd(), ".factory", "commands");
|
|
456
|
+
if (!existsSync(commandsDir)) mkdirSync(commandsDir, { recursive: true });
|
|
457
|
+
const statusDest = path.join(commandsDir, "av-status.md");
|
|
458
|
+
if (!existsSync(statusDest)) {
|
|
459
|
+
const statusContent = `# /av-status
|
|
460
|
+
|
|
461
|
+
Check your AgentValet agent status and approved platform connections.
|
|
462
|
+
|
|
463
|
+
## Instructions for the droid
|
|
464
|
+
|
|
465
|
+
1. Call \`list_platforms\` using the AgentValet MCP server
|
|
466
|
+
2. Display the results in a clean table:
|
|
467
|
+
- Platform name
|
|
468
|
+
- Approved scopes
|
|
469
|
+
- Whether any scope requires human approval
|
|
470
|
+
3. If no platforms are approved yet, tell the user to visit
|
|
471
|
+
https://app.agentvalet.ai/agents to configure permissions
|
|
472
|
+
4. If AgentValet MCP is not connected, explain how to set it up:
|
|
473
|
+
Run: npx @agentvalet/register
|
|
474
|
+
`;
|
|
475
|
+
writeFileSync(statusDest, statusContent, "utf8");
|
|
476
|
+
console.log(chalk2.green(" \u2713 Factory Droid: created .factory/commands/av-status.md"));
|
|
477
|
+
} else {
|
|
478
|
+
console.log(chalk2.dim(" Factory Droid: .factory/commands/av-status.md already exists"));
|
|
479
|
+
}
|
|
480
|
+
const registerDest = path.join(commandsDir, "av-register.md");
|
|
481
|
+
if (!existsSync(registerDest)) {
|
|
482
|
+
const registerContent = `# /av-register
|
|
483
|
+
|
|
484
|
+
Register or re-register this project with AgentValet.
|
|
485
|
+
|
|
486
|
+
## Instructions for the droid
|
|
487
|
+
|
|
488
|
+
Tell the user to run the following command in their terminal:
|
|
489
|
+
|
|
490
|
+
\`\`\`bash
|
|
491
|
+
npx @agentvalet/register
|
|
492
|
+
\`\`\`
|
|
493
|
+
|
|
494
|
+
This will:
|
|
495
|
+
1. Authenticate with GitHub (opens browser)
|
|
496
|
+
2. Create or find their AgentValet account
|
|
497
|
+
3. Register this machine as an agent
|
|
498
|
+
4. Configure Factory Droid MCP integration automatically
|
|
499
|
+
|
|
500
|
+
After running, approve the agent at: https://app.agentvalet.ai/agents
|
|
501
|
+
`;
|
|
502
|
+
writeFileSync(registerDest, registerContent, "utf8");
|
|
503
|
+
console.log(chalk2.green(" \u2713 Factory Droid: created .factory/commands/av-register.md"));
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function writeFactoryDroidReliabilityDroid() {
|
|
507
|
+
const droidsDir = path.join(process.cwd(), ".factory", "droids");
|
|
508
|
+
if (!existsSync(droidsDir)) mkdirSync(droidsDir, { recursive: true });
|
|
509
|
+
const dest = path.join(droidsDir, "agentvalet-reliability.yaml");
|
|
510
|
+
if (existsSync(dest)) return;
|
|
511
|
+
const content = `# AgentValet Reliability Droid
|
|
512
|
+
# Monitors agent call patterns and surfaces governance issues
|
|
513
|
+
# Commit this file to your repo
|
|
514
|
+
|
|
515
|
+
name: AgentValet Reliability
|
|
516
|
+
description: >
|
|
517
|
+
Monitors AI agent behaviour against AgentValet governance rules.
|
|
518
|
+
Surfaces approval-required actions, scope violations, rate limit
|
|
519
|
+
warnings, and audit anomalies directly in Factory Droid.
|
|
520
|
+
|
|
521
|
+
type: reliability
|
|
522
|
+
model: inherit
|
|
523
|
+
mcp_servers:
|
|
524
|
+
- agentvalet
|
|
525
|
+
autonomy: Low
|
|
526
|
+
|
|
527
|
+
triggers:
|
|
528
|
+
- on_agent_action: true
|
|
529
|
+
- on_approval_required: true
|
|
530
|
+
- on_scope_violation: true
|
|
531
|
+
|
|
532
|
+
instructions: |
|
|
533
|
+
You are a governance monitor. You observe what the other droids
|
|
534
|
+
are doing and flag any actions that require human oversight.
|
|
535
|
+
|
|
536
|
+
## Your responsibilities
|
|
537
|
+
|
|
538
|
+
1. BEFORE any droid makes a platform API call, check if the scope
|
|
539
|
+
requires approval using \`authzen_evaluate\`:
|
|
540
|
+
- If decision=false: block the call, explain why, suggest alternatives
|
|
541
|
+
- If decision=true: allow, but log it
|
|
542
|
+
|
|
543
|
+
2. WHEN a droid calls \`use_platform\`, verify:
|
|
544
|
+
- The platform is in the approved list from \`list_platforms\`
|
|
545
|
+
- The scope matches what was approved
|
|
546
|
+
- The call hasn't exceeded rate limits
|
|
547
|
+
|
|
548
|
+
3. SURFACE approval-required actions clearly:
|
|
549
|
+
"\u26A0 This action requires human approval: [action description]
|
|
550
|
+
Waiting for approval at app.agentvalet.ai/approvals"
|
|
551
|
+
|
|
552
|
+
4. MONITOR for unusual patterns:
|
|
553
|
+
- Multiple calls to the same destructive scope in quick succession
|
|
554
|
+
- Calls to platforms not in the approved list
|
|
555
|
+
- Call volume spikes beyond normal operation
|
|
556
|
+
|
|
557
|
+
5. REPORT governance status when asked:
|
|
558
|
+
- Current approved platforms and scopes
|
|
559
|
+
- Pending approvals
|
|
560
|
+
- Recent audit log entries (call list_platforms + agent_status)
|
|
561
|
+
|
|
562
|
+
## What you do NOT do
|
|
563
|
+
|
|
564
|
+
- You do not make platform API calls yourself
|
|
565
|
+
- You do not approve actions on behalf of the human
|
|
566
|
+
- You do not bypass governance even if another droid requests it
|
|
567
|
+
|
|
568
|
+
## Escalation
|
|
569
|
+
|
|
570
|
+
If you detect a potential security concern (unexpected scope,
|
|
571
|
+
unusual call pattern), immediately tell the human:
|
|
572
|
+
"\u{1F534} Governance alert: [description]. Recommend reviewing at
|
|
573
|
+
app.agentvalet.ai/audit"
|
|
574
|
+
`;
|
|
575
|
+
writeFileSync(dest, content, "utf8");
|
|
576
|
+
console.log(chalk2.green(" \u2713 Factory Droid: created .factory/droids/agentvalet-reliability.yaml"));
|
|
577
|
+
console.log(chalk2.dim(" Commit this file to your repo"));
|
|
578
|
+
}
|
|
373
579
|
function ensureMcpServer() {
|
|
374
580
|
try {
|
|
375
581
|
execSync("npx --yes @agentvalet/mcp-server --version", {
|
|
@@ -427,27 +633,7 @@ To refresh this file: \`npx @agentvalet/register refresh\`
|
|
|
427
633
|
|
|
428
634
|
// src/lib/require-agent.ts
|
|
429
635
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
430
|
-
import { resolve
|
|
431
|
-
|
|
432
|
-
// src/config/store.ts
|
|
433
|
-
import Conf from "conf";
|
|
434
|
-
var store = new Conf({
|
|
435
|
-
projectName: "agentvalet"
|
|
436
|
-
});
|
|
437
|
-
function getStoredConfig() {
|
|
438
|
-
return store.store;
|
|
439
|
-
}
|
|
440
|
-
function saveConfig(config) {
|
|
441
|
-
store.set(config);
|
|
442
|
-
}
|
|
443
|
-
function clearConfig() {
|
|
444
|
-
store.clear();
|
|
445
|
-
}
|
|
446
|
-
function isAuthenticated() {
|
|
447
|
-
return !!store.get("apiKey");
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// src/lib/require-agent.ts
|
|
636
|
+
import { resolve } from "path";
|
|
451
637
|
import chalk3 from "chalk";
|
|
452
638
|
var NO_AGENT_MSG = chalk3.red("\n \u2717 No agent registered.\n") + chalk3.dim(
|
|
453
639
|
" Run the following command first to register an agent in this directory:\n\n npx @agentvalet/register\n"
|
|
@@ -468,45 +654,34 @@ function tryResolveAgent(envFile = ".env.agentvalet") {
|
|
|
468
654
|
let ownerId;
|
|
469
655
|
let apiUrl = "https://api.agentvalet.ai";
|
|
470
656
|
let keyPath;
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
keyPath = vars["AGENTVALET_PRIVATE_KEY_PATH"];
|
|
479
|
-
} catch {
|
|
480
|
-
}
|
|
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 {
|
|
481
664
|
}
|
|
482
|
-
if (!
|
|
483
|
-
|
|
484
|
-
|
|
665
|
+
if (!keyPath) keyPath = AGENT_KEY_PATH;
|
|
666
|
+
if (!agentId || !ownerId) {
|
|
667
|
+
const envPath = resolve(envFile);
|
|
668
|
+
if (existsSync2(envPath)) {
|
|
485
669
|
try {
|
|
486
|
-
const
|
|
487
|
-
agentId = agentId ??
|
|
488
|
-
|
|
489
|
-
|
|
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;
|
|
490
675
|
} catch {
|
|
491
676
|
}
|
|
492
677
|
}
|
|
493
|
-
try {
|
|
494
|
-
const global = getStoredConfig();
|
|
495
|
-
if (!ownerId) ownerId = global.ownerId ?? void 0;
|
|
496
|
-
} catch {
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
if (!agentId || !ownerId || !keyPath) {
|
|
500
|
-
try {
|
|
501
|
-
const global = getStoredConfig();
|
|
502
|
-
agentId = agentId ?? global.lastAgentId ?? void 0;
|
|
503
|
-
ownerId = ownerId ?? global.ownerId ?? void 0;
|
|
504
|
-
keyPath = keyPath ?? global.lastKeyPath ?? void 0;
|
|
505
|
-
apiUrl = global.proxyUrl ?? apiUrl;
|
|
506
|
-
} catch {
|
|
507
|
-
}
|
|
508
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"];
|
|
509
683
|
if (!agentId || !ownerId || !keyPath) return null;
|
|
684
|
+
if (!existsSync2(resolve(keyPath))) return null;
|
|
510
685
|
return { agentId, ownerId, keyPath, apiUrl };
|
|
511
686
|
}
|
|
512
687
|
|
|
@@ -517,19 +692,19 @@ var HOOK_COMMAND = "npx @agentvalet/register refresh --if-stale --quiet 2>/dev/n
|
|
|
517
692
|
var HOOK_MARKER = "agentvalet/register refresh";
|
|
518
693
|
function writePermissionsFromEvent(agentId, ownerId, platforms, outputPath = "./.claude/agentvalet-permissions.md") {
|
|
519
694
|
const content = generatePermissionsFile(agentId, ownerId, platforms);
|
|
520
|
-
const resolvedPath =
|
|
521
|
-
|
|
695
|
+
const resolvedPath = resolve2(outputPath);
|
|
696
|
+
mkdirSync2(dirname(resolvedPath), { recursive: true });
|
|
522
697
|
writeFileSync2(resolvedPath, content, "utf-8");
|
|
523
698
|
embedInClaudeMd(content);
|
|
524
699
|
ensureHook();
|
|
525
700
|
}
|
|
526
701
|
async function runRefresh(options) {
|
|
527
|
-
const outputPath =
|
|
702
|
+
const outputPath = resolve2(options.outputPath);
|
|
528
703
|
if (options.ifStale) {
|
|
529
704
|
try {
|
|
530
705
|
const stat = statSync(outputPath);
|
|
531
706
|
const fileIsFresh = Date.now() - stat.mtimeMs < 36e5;
|
|
532
|
-
const claudeMdPath =
|
|
707
|
+
const claudeMdPath = resolve2("CLAUDE.md");
|
|
533
708
|
const claudeMd = existsSync3(claudeMdPath) ? readFileSync3(claudeMdPath, "utf-8") : "";
|
|
534
709
|
const blockStart = claudeMd.indexOf(CLAUDE_START);
|
|
535
710
|
const blockEnd = claudeMd.indexOf(CLAUDE_END);
|
|
@@ -540,7 +715,7 @@ async function runRefresh(options) {
|
|
|
540
715
|
}
|
|
541
716
|
}
|
|
542
717
|
const creds = tryResolveAgent(options.envFile);
|
|
543
|
-
if (!creds || !existsSync3(
|
|
718
|
+
if (!creds || !existsSync3(resolve2(creds.keyPath))) {
|
|
544
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");
|
|
545
720
|
process.exit(1);
|
|
546
721
|
}
|
|
@@ -565,7 +740,7 @@ async function runRefresh(options) {
|
|
|
565
740
|
const json = await res.json();
|
|
566
741
|
const platforms = json.data?.platforms ?? [];
|
|
567
742
|
const content = generatePermissionsFile(agentId, ownerId, platforms);
|
|
568
|
-
|
|
743
|
+
mkdirSync2(dirname(outputPath), { recursive: true });
|
|
569
744
|
writeFileSync2(outputPath, content, "utf-8");
|
|
570
745
|
embedInClaudeMd(content);
|
|
571
746
|
ensureHook();
|
|
@@ -574,7 +749,7 @@ async function runRefresh(options) {
|
|
|
574
749
|
}
|
|
575
750
|
}
|
|
576
751
|
function embedInClaudeMd(permissionsContent) {
|
|
577
|
-
const claudeMdPath =
|
|
752
|
+
const claudeMdPath = resolve2("CLAUDE.md");
|
|
578
753
|
const block = `${CLAUDE_START}
|
|
579
754
|
${permissionsContent.trimEnd()}
|
|
580
755
|
${CLAUDE_END}`;
|
|
@@ -601,7 +776,7 @@ ${block}
|
|
|
601
776
|
}
|
|
602
777
|
}
|
|
603
778
|
function ensureHook() {
|
|
604
|
-
const settingsPath =
|
|
779
|
+
const settingsPath = resolve2(".claude/settings.local.json");
|
|
605
780
|
let settings = {};
|
|
606
781
|
if (existsSync3(settingsPath)) {
|
|
607
782
|
try {
|
|
@@ -627,12 +802,12 @@ function ensureHook() {
|
|
|
627
802
|
perms.allow = [...allow, ...missing];
|
|
628
803
|
settings.permissions = perms;
|
|
629
804
|
}
|
|
630
|
-
|
|
805
|
+
mkdirSync2(dirname(settingsPath), { recursive: true });
|
|
631
806
|
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
632
807
|
ensureMcpJson();
|
|
633
808
|
}
|
|
634
809
|
function ensureMcpJson() {
|
|
635
|
-
const mcpJsonPath =
|
|
810
|
+
const mcpJsonPath = resolve2(".mcp.json");
|
|
636
811
|
let mcpConfig = {};
|
|
637
812
|
if (existsSync3(mcpJsonPath)) {
|
|
638
813
|
try {
|
|
@@ -849,7 +1024,7 @@ function formatEnvBlock(vars) {
|
|
|
849
1024
|
}
|
|
850
1025
|
|
|
851
1026
|
// src/config/ide.ts
|
|
852
|
-
import { mkdir as mkdir3, writeFile as writeFile4, readFile as readFile2, appendFile as appendFile3 } from "fs/promises";
|
|
1027
|
+
import { mkdir as mkdir3, writeFile as writeFile4, readFile as readFile2, appendFile as appendFile3, copyFile } from "fs/promises";
|
|
853
1028
|
import { existsSync as existsSync5 } from "fs";
|
|
854
1029
|
import path4 from "path";
|
|
855
1030
|
import os from "os";
|
|
@@ -980,6 +1155,72 @@ async function writeIdeConfigs(params) {
|
|
|
980
1155
|
console.warn(` Warning: could not write .cursor/mcp.json: ${err.message}`);
|
|
981
1156
|
}
|
|
982
1157
|
}
|
|
1158
|
+
if (detected.factoryDroid) {
|
|
1159
|
+
const fdResults = await writeFactoryDroidConfig(mcpParams);
|
|
1160
|
+
written.push(...fdResults);
|
|
1161
|
+
}
|
|
1162
|
+
return written;
|
|
1163
|
+
}
|
|
1164
|
+
async function mergeFactoryDroidMcpJson(filePath, key, value) {
|
|
1165
|
+
let existing = {};
|
|
1166
|
+
if (existsSync5(filePath)) {
|
|
1167
|
+
try {
|
|
1168
|
+
const text = await readFile2(filePath, "utf8");
|
|
1169
|
+
existing = JSON.parse(text);
|
|
1170
|
+
} catch {
|
|
1171
|
+
await copyFile(filePath, filePath + ".backup");
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
if (existing[key]) return;
|
|
1175
|
+
existing[key] = value;
|
|
1176
|
+
await writeFile4(filePath, JSON.stringify(existing, null, 2) + "\n", "utf8");
|
|
1177
|
+
}
|
|
1178
|
+
async function updateGitignoreForFactoryDroid() {
|
|
1179
|
+
const gitignorePath = path4.join(process.cwd(), ".gitignore");
|
|
1180
|
+
if (!existsSync5(gitignorePath)) return;
|
|
1181
|
+
const existing = await readFile2(gitignorePath, "utf8");
|
|
1182
|
+
if (existing.includes(".factory/mcp.json")) return;
|
|
1183
|
+
const additions = [
|
|
1184
|
+
"",
|
|
1185
|
+
"# Factory Droid \u2014 private key in MCP config",
|
|
1186
|
+
".factory/mcp.json",
|
|
1187
|
+
"",
|
|
1188
|
+
"# Factory Droid \u2014 commit these:",
|
|
1189
|
+
"# .factory/droids/",
|
|
1190
|
+
"# .factory/commands/"
|
|
1191
|
+
].join("\n");
|
|
1192
|
+
await appendFile3(gitignorePath, additions + "\n", "utf8");
|
|
1193
|
+
}
|
|
1194
|
+
async function writeFactoryDroidConfig(params) {
|
|
1195
|
+
const home = os.homedir();
|
|
1196
|
+
const written = [];
|
|
1197
|
+
const entry = buildMcpEntry(params);
|
|
1198
|
+
const globalDir = path4.join(home, ".factory");
|
|
1199
|
+
const projectDir = path4.join(process.cwd(), ".factory");
|
|
1200
|
+
const globalDirExists = existsSync5(globalDir);
|
|
1201
|
+
const projectDirExists = existsSync5(projectDir);
|
|
1202
|
+
if (globalDirExists) {
|
|
1203
|
+
try {
|
|
1204
|
+
await mergeFactoryDroidMcpJson(path4.join(globalDir, "mcp.json"), "agentvalet", entry);
|
|
1205
|
+
written.push("~/.factory/mcp.json");
|
|
1206
|
+
} catch (err) {
|
|
1207
|
+
console.warn(` Warning: could not write ~/.factory/mcp.json: ${err.message}`);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
if (projectDirExists && !globalDirExists) {
|
|
1211
|
+
try {
|
|
1212
|
+
await mergeFactoryDroidMcpJson(path4.join(projectDir, "mcp.json"), "agentvalet", entry);
|
|
1213
|
+
written.push(".factory/mcp.json");
|
|
1214
|
+
} catch (err) {
|
|
1215
|
+
console.warn(` Warning: could not write .factory/mcp.json: ${err.message}`);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
if (written.length > 0) {
|
|
1219
|
+
try {
|
|
1220
|
+
await updateGitignoreForFactoryDroid();
|
|
1221
|
+
} catch {
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
983
1224
|
return written;
|
|
984
1225
|
}
|
|
985
1226
|
|
|
@@ -1017,7 +1258,8 @@ function detectFrameworks() {
|
|
|
1017
1258
|
codex: existsSync6(path5.join(home, ".codex")) || tryBinary("codex"),
|
|
1018
1259
|
claudeCode: existsSync6(path5.join(home, ".claude")) || tryBinary("claude"),
|
|
1019
1260
|
cursor: existsSync6(path5.join(process.cwd(), ".cursor")) || cursorInstalled(),
|
|
1020
|
-
openclaw: existsSync6(path5.join(home, ".openclaw"))
|
|
1261
|
+
openclaw: existsSync6(path5.join(home, ".openclaw")),
|
|
1262
|
+
factoryDroid: existsSync6(path5.join(home, ".factory")) || existsSync6(path5.join(process.cwd(), ".factory"))
|
|
1021
1263
|
};
|
|
1022
1264
|
}
|
|
1023
1265
|
async function frameworkSetupConsent(detected) {
|
|
@@ -1036,6 +1278,11 @@ async function frameworkSetupConsent(detected) {
|
|
|
1036
1278
|
if (detected.openclaw) {
|
|
1037
1279
|
items.push("OpenClaw \u2192 SKILL.md (usage rules)");
|
|
1038
1280
|
}
|
|
1281
|
+
if (detected.factoryDroid) {
|
|
1282
|
+
items.push("Factory Droid \u2192 add MCP server to ~/.factory/mcp.json");
|
|
1283
|
+
items.push(" \u2192 create .factory/droids/agentvalet.yaml");
|
|
1284
|
+
items.push(" \u2192 create .factory/commands/av-status.md");
|
|
1285
|
+
}
|
|
1039
1286
|
if (items.length === 0) return false;
|
|
1040
1287
|
console.log("");
|
|
1041
1288
|
console.log(chalk6.bold(" Detected agent frameworks"));
|
|
@@ -1255,6 +1502,16 @@ async function registerAgentFlow(apiKey, ownerId) {
|
|
|
1255
1502
|
}
|
|
1256
1503
|
const detected = detectFrameworks();
|
|
1257
1504
|
const shouldSetup = await frameworkSetupConsent(detected);
|
|
1505
|
+
let installReliabilityDroid = false;
|
|
1506
|
+
if (detected.factoryDroid && shouldSetup) {
|
|
1507
|
+
const { reliability } = await prompts3({
|
|
1508
|
+
type: "confirm",
|
|
1509
|
+
name: "reliability",
|
|
1510
|
+
message: "Also install AgentValet Reliability Droid for Factory Droid? (monitors agent governance)",
|
|
1511
|
+
initial: false
|
|
1512
|
+
});
|
|
1513
|
+
installReliabilityDroid = reliability ?? false;
|
|
1514
|
+
}
|
|
1258
1515
|
if (shouldSetup) {
|
|
1259
1516
|
console.log("");
|
|
1260
1517
|
console.log(chalk7.bold(" Configuring agent frameworks..."));
|
|
@@ -1284,6 +1541,13 @@ async function registerAgentFlow(apiKey, ownerId) {
|
|
|
1284
1541
|
if (detected.openclaw) {
|
|
1285
1542
|
writeSkillMd();
|
|
1286
1543
|
}
|
|
1544
|
+
if (detected.factoryDroid) {
|
|
1545
|
+
writeFactoryDroidDroid();
|
|
1546
|
+
writeFactoryDroidCommand();
|
|
1547
|
+
if (installReliabilityDroid) {
|
|
1548
|
+
writeFactoryDroidReliabilityDroid();
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1287
1551
|
writeQuickstartDoc({
|
|
1288
1552
|
agentId: agent.agent_id,
|
|
1289
1553
|
ownerId,
|
|
@@ -1412,12 +1676,12 @@ function revokeCommand() {
|
|
|
1412
1676
|
process.exit(1);
|
|
1413
1677
|
}
|
|
1414
1678
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1415
|
-
const confirmed = await new Promise((
|
|
1679
|
+
const confirmed = await new Promise((resolve4) => {
|
|
1416
1680
|
rl.question(
|
|
1417
1681
|
chalk9.yellow(`Revoke ${opts.agentId}? This cascades to all child agents and cannot be undone. (y/N) `),
|
|
1418
1682
|
(ans) => {
|
|
1419
1683
|
rl.close();
|
|
1420
|
-
|
|
1684
|
+
resolve4(ans.trim().toLowerCase() === "y");
|
|
1421
1685
|
}
|
|
1422
1686
|
);
|
|
1423
1687
|
});
|
|
@@ -1445,9 +1709,9 @@ import { readFile as readFile5 } from "fs/promises";
|
|
|
1445
1709
|
|
|
1446
1710
|
// src/lib/claude-config.ts
|
|
1447
1711
|
import { homedir } from "os";
|
|
1448
|
-
import { join
|
|
1712
|
+
import { join } from "path";
|
|
1449
1713
|
import { readFile as readFile3, writeFile as writeFile6, mkdir as mkdir4, access } from "fs/promises";
|
|
1450
|
-
var CLAUDE_CONFIG_PATH =
|
|
1714
|
+
var CLAUDE_CONFIG_PATH = join(homedir(), ".claude", "config");
|
|
1451
1715
|
async function writeKeyToClaudeConfig(agentId, privateKeyPem) {
|
|
1452
1716
|
let config = {};
|
|
1453
1717
|
try {
|
|
@@ -1458,7 +1722,7 @@ async function writeKeyToClaudeConfig(agentId, privateKeyPem) {
|
|
|
1458
1722
|
}
|
|
1459
1723
|
config.agent_keys = config.agent_keys ?? {};
|
|
1460
1724
|
config.agent_keys[agentId] = Buffer.from(privateKeyPem).toString("base64");
|
|
1461
|
-
await mkdir4(
|
|
1725
|
+
await mkdir4(join(homedir(), ".claude"), { recursive: true });
|
|
1462
1726
|
await writeFile6(CLAUDE_CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
|
|
1463
1727
|
}
|
|
1464
1728
|
|
|
@@ -1529,13 +1793,12 @@ function injectCommand() {
|
|
|
1529
1793
|
import { Command as Command4 } from "commander";
|
|
1530
1794
|
import chalk11 from "chalk";
|
|
1531
1795
|
import { existsSync as existsSync7, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync } from "fs";
|
|
1532
|
-
import { resolve as
|
|
1533
|
-
import { homedir as homedir2 } from "os";
|
|
1796
|
+
import { resolve as resolve3 } from "path";
|
|
1534
1797
|
var CLAUDE_START2 = "<!-- agentvalet:start -->";
|
|
1535
1798
|
var CLAUDE_END2 = "<!-- agentvalet:end -->";
|
|
1536
1799
|
var HOOK_MARKER2 = "agentvalet/register refresh";
|
|
1537
1800
|
function stripClaudeMd() {
|
|
1538
|
-
const path7 =
|
|
1801
|
+
const path7 = resolve3("CLAUDE.md");
|
|
1539
1802
|
if (!existsSync7(path7)) return;
|
|
1540
1803
|
let content = readFileSync4(path7, "utf-8");
|
|
1541
1804
|
content = content.replace(new RegExp(`${CLAUDE_START2}[\\s\\S]*?${CLAUDE_END2}`, "m"), "");
|
|
@@ -1544,7 +1807,7 @@ function stripClaudeMd() {
|
|
|
1544
1807
|
writeFileSync3(path7, content ? content + "\n" : "", "utf-8");
|
|
1545
1808
|
}
|
|
1546
1809
|
function stripSettingsJson() {
|
|
1547
|
-
const path7 =
|
|
1810
|
+
const path7 = resolve3(".claude/settings.local.json");
|
|
1548
1811
|
if (!existsSync7(path7)) return;
|
|
1549
1812
|
try {
|
|
1550
1813
|
const settings = JSON.parse(readFileSync4(path7, "utf-8"));
|
|
@@ -1563,7 +1826,7 @@ function stripSettingsJson() {
|
|
|
1563
1826
|
}
|
|
1564
1827
|
}
|
|
1565
1828
|
function stripMcpJson() {
|
|
1566
|
-
const path7 =
|
|
1829
|
+
const path7 = resolve3(".mcp.json");
|
|
1567
1830
|
if (!existsSync7(path7)) return;
|
|
1568
1831
|
try {
|
|
1569
1832
|
const config = JSON.parse(readFileSync4(path7, "utf-8"));
|
|
@@ -1574,20 +1837,23 @@ function stripMcpJson() {
|
|
|
1574
1837
|
} catch {
|
|
1575
1838
|
}
|
|
1576
1839
|
}
|
|
1577
|
-
function deleteIfExists(p) {
|
|
1578
|
-
const abs = resolve4(p);
|
|
1579
|
-
if (existsSync7(abs)) {
|
|
1580
|
-
rmSync(abs, { recursive: true, force: true });
|
|
1581
|
-
return abs;
|
|
1582
|
-
}
|
|
1583
|
-
return null;
|
|
1584
|
-
}
|
|
1585
1840
|
function cleanLocally() {
|
|
1586
1841
|
const removed = [];
|
|
1587
1842
|
const r = (p) => {
|
|
1588
|
-
const
|
|
1589
|
-
if (
|
|
1843
|
+
const abs = resolve3(p);
|
|
1844
|
+
if (existsSync7(abs)) {
|
|
1845
|
+
rmSync(abs, { recursive: true, force: true });
|
|
1846
|
+
removed.push(abs);
|
|
1847
|
+
}
|
|
1590
1848
|
};
|
|
1849
|
+
if (existsSync7(AGENT_KEY_PATH)) {
|
|
1850
|
+
rmSync(AGENT_KEY_PATH, { force: true });
|
|
1851
|
+
removed.push(AGENT_KEY_PATH);
|
|
1852
|
+
}
|
|
1853
|
+
try {
|
|
1854
|
+
clearConfig();
|
|
1855
|
+
} catch {
|
|
1856
|
+
}
|
|
1591
1857
|
r(".env.agentvalet");
|
|
1592
1858
|
r(".agentvalet");
|
|
1593
1859
|
r("agentvalet.key");
|
|
@@ -1595,17 +1861,8 @@ function cleanLocally() {
|
|
|
1595
1861
|
stripClaudeMd();
|
|
1596
1862
|
stripSettingsJson();
|
|
1597
1863
|
stripMcpJson();
|
|
1598
|
-
try {
|
|
1599
|
-
saveConfig({ lastAgentId: "", lastKeyPath: "" });
|
|
1600
|
-
} catch {
|
|
1601
|
-
}
|
|
1602
|
-
const oldConfig = join3(homedir2(), ".agentvalet", "config.json");
|
|
1603
|
-
if (existsSync7(oldConfig)) {
|
|
1604
|
-
rmSync(oldConfig, { force: true });
|
|
1605
|
-
removed.push(oldConfig);
|
|
1606
|
-
}
|
|
1607
1864
|
if (removed.length > 0) {
|
|
1608
|
-
console.log(chalk11.green(" \u2713 Removed
|
|
1865
|
+
console.log(chalk11.green(" \u2713 Removed files:"));
|
|
1609
1866
|
for (const f of removed) console.log(chalk11.dim(` ${f}`));
|
|
1610
1867
|
}
|
|
1611
1868
|
console.log(chalk11.green(" \u2713 Cleaned CLAUDE.md, .mcp.json, .claude/settings.local.json"));
|
|
@@ -1614,12 +1871,12 @@ var SSE_READ_TIMEOUT_MS = 25e3;
|
|
|
1614
1871
|
async function pollForApproval(apiUrl, revocationToken, timeoutMs) {
|
|
1615
1872
|
const streamUrl = `${apiUrl}/v1/revoke-request/stream/${revocationToken}`;
|
|
1616
1873
|
const deadline = Date.now() + timeoutMs;
|
|
1617
|
-
return new Promise((
|
|
1874
|
+
return new Promise((resolve4) => {
|
|
1618
1875
|
let settled = false;
|
|
1619
1876
|
function done(result) {
|
|
1620
1877
|
if (!settled) {
|
|
1621
1878
|
settled = true;
|
|
1622
|
-
|
|
1879
|
+
resolve4(result);
|
|
1623
1880
|
}
|
|
1624
1881
|
}
|
|
1625
1882
|
function connect() {
|
|
@@ -1762,7 +2019,7 @@ function collectScope(value, previous) {
|
|
|
1762
2019
|
return [...previous, value];
|
|
1763
2020
|
}
|
|
1764
2021
|
var program = new Command5();
|
|
1765
|
-
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("--
|
|
2022
|
+
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) => {
|
|
1766
2023
|
const isJson = !!opts.json;
|
|
1767
2024
|
let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
|
|
1768
2025
|
let agentName = opts.name ?? "";
|
|
@@ -1864,39 +2121,34 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
1864
2121
|
const { agentId, privateKey, grantedPlatforms } = result;
|
|
1865
2122
|
const resolvedOwnerId = result.ownerId || ownerId;
|
|
1866
2123
|
let keyPath;
|
|
1867
|
-
let envPath;
|
|
1868
|
-
try {
|
|
1869
|
-
({ keyPath, envPath } = await saveOutput({
|
|
1870
|
-
agentId,
|
|
1871
|
-
ownerId: resolvedOwnerId,
|
|
1872
|
-
privateKey: privateKey ?? "",
|
|
1873
|
-
apiUrl: opts.apiUrl,
|
|
1874
|
-
keyFilePath: opts.keyPath,
|
|
1875
|
-
envFilePath: opts.output
|
|
1876
|
-
}));
|
|
1877
|
-
} catch (err) {
|
|
1878
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1879
|
-
console.error(isJson ? JSON.stringify({ error: msg }) : chalk12.red(`Failed to save output: ${msg}`));
|
|
1880
|
-
process.exit(3);
|
|
1881
|
-
}
|
|
1882
2124
|
const keyWritten = !!privateKey;
|
|
1883
2125
|
if (keyWritten) {
|
|
1884
|
-
|
|
2126
|
+
try {
|
|
2127
|
+
({ keyPath } = await saveOutput({
|
|
2128
|
+
agentId,
|
|
2129
|
+
ownerId: resolvedOwnerId,
|
|
2130
|
+
privateKey,
|
|
2131
|
+
apiUrl: opts.apiUrl
|
|
2132
|
+
}));
|
|
2133
|
+
} catch (err) {
|
|
2134
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2135
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk12.red(`Failed to save output: ${msg}`));
|
|
2136
|
+
process.exit(3);
|
|
2137
|
+
}
|
|
2138
|
+
} else {
|
|
2139
|
+
const { AGENT_KEY_PATH: AGENT_KEY_PATH2 } = await import("./store-JYJXDBYX.js");
|
|
2140
|
+
keyPath = AGENT_KEY_PATH2;
|
|
1885
2141
|
}
|
|
1886
2142
|
if (isJson) {
|
|
1887
|
-
console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null
|
|
2143
|
+
console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null }));
|
|
1888
2144
|
} else {
|
|
1889
2145
|
console.log(chalk12.green(`
|
|
1890
2146
|
Approved! Agent ID: ${agentId}`));
|
|
1891
2147
|
if (keyWritten) {
|
|
1892
|
-
console.log(chalk12.gray(`Key:
|
|
2148
|
+
console.log(chalk12.gray(`Key: ${keyPath}`));
|
|
1893
2149
|
} else {
|
|
1894
|
-
console.log(chalk12.yellow(`Key:
|
|
2150
|
+
console.log(chalk12.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
|
|
1895
2151
|
}
|
|
1896
|
-
console.log(chalk12.gray(`Env file: ${envPath}`));
|
|
1897
|
-
console.log(`
|
|
1898
|
-
Source the env file before calling any tool:`);
|
|
1899
|
-
console.log(chalk12.cyan(` source ${envPath}`));
|
|
1900
2152
|
}
|
|
1901
2153
|
if (keyWritten) {
|
|
1902
2154
|
try {
|
|
@@ -1904,12 +2156,7 @@ Source the env file before calling any tool:`);
|
|
|
1904
2156
|
writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
|
|
1905
2157
|
if (!isJson) console.log(chalk12.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
1906
2158
|
} else {
|
|
1907
|
-
await runRefresh({
|
|
1908
|
-
envFile: opts.output,
|
|
1909
|
-
outputPath: ".claude/agentvalet-permissions.md",
|
|
1910
|
-
ifStale: false,
|
|
1911
|
-
quiet: isJson
|
|
1912
|
-
});
|
|
2159
|
+
await runRefresh({ envFile: ".env.agentvalet", outputPath: ".claude/agentvalet-permissions.md", ifStale: false, quiet: isJson });
|
|
1913
2160
|
if (!isJson) console.log(chalk12.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
1914
2161
|
}
|
|
1915
2162
|
} catch {
|
|
@@ -1918,10 +2165,10 @@ Source the env file before calling any tool:`);
|
|
|
1918
2165
|
}
|
|
1919
2166
|
process.exit(0);
|
|
1920
2167
|
});
|
|
1921
|
-
program.command("refresh").description("Refresh approved permissions and update .claude/agentvalet-permissions.md").option("--
|
|
2168
|
+
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) => {
|
|
1922
2169
|
try {
|
|
1923
2170
|
await runRefresh({
|
|
1924
|
-
envFile:
|
|
2171
|
+
envFile: ".env.agentvalet",
|
|
1925
2172
|
outputPath: opts.output,
|
|
1926
2173
|
ifStale: !!opts.ifStale,
|
|
1927
2174
|
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
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvalet/register",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "Self-register AI agents with AgentValet",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,13 @@
|
|
|
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": "pnpm build"
|
|
19
|
+
},
|
|
13
20
|
"dependencies": {
|
|
14
21
|
"@agentvalet/mcp-server": "*",
|
|
15
22
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -48,11 +55,5 @@
|
|
|
48
55
|
"valet",
|
|
49
56
|
"agentvalet"
|
|
50
57
|
],
|
|
51
|
-
"license": "MIT"
|
|
52
|
-
|
|
53
|
-
"build": "tsup src/index.ts --format esm --dts --clean --shims",
|
|
54
|
-
"dev": "tsx src/index.ts",
|
|
55
|
-
"test": "vitest run",
|
|
56
|
-
"typecheck": "tsc --noEmit"
|
|
57
|
-
}
|
|
58
|
-
}
|
|
58
|
+
"license": "MIT"
|
|
59
|
+
}
|