@agentvalet/register 0.4.7 → 0.4.9
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 +249 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
5
|
-
import
|
|
4
|
+
import { Command as Command5 } from "commander";
|
|
5
|
+
import chalk12 from "chalk";
|
|
6
6
|
|
|
7
7
|
// src/wizard.ts
|
|
8
8
|
import prompts from "prompts";
|
|
@@ -166,7 +166,7 @@ function parseEvent(data) {
|
|
|
166
166
|
return null;
|
|
167
167
|
}
|
|
168
168
|
function sleep(ms) {
|
|
169
|
-
return new Promise((
|
|
169
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
// src/save.ts
|
|
@@ -1454,12 +1454,12 @@ function revokeCommand() {
|
|
|
1454
1454
|
process.exit(1);
|
|
1455
1455
|
}
|
|
1456
1456
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1457
|
-
const confirmed = await new Promise((
|
|
1457
|
+
const confirmed = await new Promise((resolve5) => {
|
|
1458
1458
|
rl.question(
|
|
1459
1459
|
chalk9.yellow(`Revoke ${opts.agentId}? This cascades to all child agents and cannot be undone. (y/N) `),
|
|
1460
1460
|
(ans) => {
|
|
1461
1461
|
rl.close();
|
|
1462
|
-
|
|
1462
|
+
resolve5(ans.trim().toLowerCase() === "y");
|
|
1463
1463
|
}
|
|
1464
1464
|
);
|
|
1465
1465
|
});
|
|
@@ -1567,12 +1567,235 @@ function injectCommand() {
|
|
|
1567
1567
|
});
|
|
1568
1568
|
}
|
|
1569
1569
|
|
|
1570
|
+
// src/commands/uninstall.ts
|
|
1571
|
+
import { Command as Command4 } from "commander";
|
|
1572
|
+
import chalk11 from "chalk";
|
|
1573
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync } from "fs";
|
|
1574
|
+
import { resolve as resolve4, join as join3 } from "path";
|
|
1575
|
+
import { homedir as homedir2 } from "os";
|
|
1576
|
+
import { createSign as createSign2, createPrivateKey as createPrivateKey2 } from "crypto";
|
|
1577
|
+
var CLAUDE_START2 = "<!-- agentvalet:start -->";
|
|
1578
|
+
var CLAUDE_END2 = "<!-- agentvalet:end -->";
|
|
1579
|
+
var HOOK_MARKER2 = "agentvalet/register refresh";
|
|
1580
|
+
function signJwt2(agentId, ownerId, privateKeyPem) {
|
|
1581
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1582
|
+
const b64 = (s) => Buffer.from(s).toString("base64url");
|
|
1583
|
+
const header = b64(JSON.stringify({ alg: "RS256", typ: "JWT" }));
|
|
1584
|
+
const payload = b64(JSON.stringify({ agent_id: agentId, owner_id: ownerId, iat: now, exp: now + 300 }));
|
|
1585
|
+
const signingInput = `${header}.${payload}`;
|
|
1586
|
+
const sign = createSign2("RSA-SHA256");
|
|
1587
|
+
sign.update(signingInput);
|
|
1588
|
+
return `${signingInput}.${sign.sign(createPrivateKey2(privateKeyPem), "base64url")}`;
|
|
1589
|
+
}
|
|
1590
|
+
function stripClaudeMd() {
|
|
1591
|
+
const path7 = resolve4("CLAUDE.md");
|
|
1592
|
+
if (!existsSync7(path7)) return;
|
|
1593
|
+
let content = readFileSync4(path7, "utf-8");
|
|
1594
|
+
content = content.replace(new RegExp(`${CLAUDE_START2}[\\s\\S]*?${CLAUDE_END2}`, "m"), "");
|
|
1595
|
+
content = content.replace(/^@\.claude\/agentvalet-permissions\.md\s*$/m, "");
|
|
1596
|
+
content = content.replace(/(\r?\n){3,}/g, "\n\n").trim();
|
|
1597
|
+
writeFileSync3(path7, content ? content + "\n" : "", "utf-8");
|
|
1598
|
+
}
|
|
1599
|
+
function stripSettingsJson() {
|
|
1600
|
+
const path7 = resolve4(".claude/settings.local.json");
|
|
1601
|
+
if (!existsSync7(path7)) return;
|
|
1602
|
+
try {
|
|
1603
|
+
const settings = JSON.parse(readFileSync4(path7, "utf-8"));
|
|
1604
|
+
const hooks = settings.hooks ?? {};
|
|
1605
|
+
const ups = hooks.UserPromptSubmit ?? [];
|
|
1606
|
+
hooks.UserPromptSubmit = ups.filter(
|
|
1607
|
+
(e) => !e.hooks?.some((h) => h.command?.includes(HOOK_MARKER2))
|
|
1608
|
+
);
|
|
1609
|
+
settings.hooks = hooks;
|
|
1610
|
+
const perms = settings.permissions ?? {};
|
|
1611
|
+
const allow = perms.allow ?? [];
|
|
1612
|
+
perms.allow = allow.filter((e) => !e.startsWith("mcp__agentvalet__"));
|
|
1613
|
+
settings.permissions = perms;
|
|
1614
|
+
writeFileSync3(path7, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
1615
|
+
} catch {
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
function stripMcpJson() {
|
|
1619
|
+
const path7 = resolve4(".mcp.json");
|
|
1620
|
+
if (!existsSync7(path7)) return;
|
|
1621
|
+
try {
|
|
1622
|
+
const config = JSON.parse(readFileSync4(path7, "utf-8"));
|
|
1623
|
+
const servers = config.mcpServers ?? {};
|
|
1624
|
+
delete servers["agentvalet"];
|
|
1625
|
+
config.mcpServers = servers;
|
|
1626
|
+
writeFileSync3(path7, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
1627
|
+
} catch {
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
function deleteIfExists(p) {
|
|
1631
|
+
const abs = resolve4(p);
|
|
1632
|
+
if (existsSync7(abs)) {
|
|
1633
|
+
rmSync(abs, { recursive: true, force: true });
|
|
1634
|
+
return abs;
|
|
1635
|
+
}
|
|
1636
|
+
return null;
|
|
1637
|
+
}
|
|
1638
|
+
function cleanLocally() {
|
|
1639
|
+
const removed = [];
|
|
1640
|
+
const r = (p) => {
|
|
1641
|
+
const f = deleteIfExists(p);
|
|
1642
|
+
if (f) removed.push(f);
|
|
1643
|
+
};
|
|
1644
|
+
r(".env.agentvalet");
|
|
1645
|
+
r(".agentvalet");
|
|
1646
|
+
r("agentvalet.key");
|
|
1647
|
+
r(".claude/agentvalet-permissions.md");
|
|
1648
|
+
stripClaudeMd();
|
|
1649
|
+
stripSettingsJson();
|
|
1650
|
+
stripMcpJson();
|
|
1651
|
+
try {
|
|
1652
|
+
saveConfig({ lastAgentId: "", lastKeyPath: "" });
|
|
1653
|
+
} catch {
|
|
1654
|
+
}
|
|
1655
|
+
const oldConfig = join3(homedir2(), ".agentvalet", "config.json");
|
|
1656
|
+
if (existsSync7(oldConfig)) {
|
|
1657
|
+
rmSync(oldConfig, { force: true });
|
|
1658
|
+
removed.push(oldConfig);
|
|
1659
|
+
}
|
|
1660
|
+
if (removed.length > 0) {
|
|
1661
|
+
console.log(chalk11.green(" \u2713 Removed local files:"));
|
|
1662
|
+
for (const f of removed) console.log(chalk11.dim(` ${f}`));
|
|
1663
|
+
}
|
|
1664
|
+
console.log(chalk11.green(" \u2713 Cleaned CLAUDE.md, .mcp.json, .claude/settings.local.json"));
|
|
1665
|
+
}
|
|
1666
|
+
async function pollForApproval(apiUrl, revocationToken, timeoutMs) {
|
|
1667
|
+
const streamUrl = `${apiUrl}/v1/revoke-request/stream/${revocationToken}`;
|
|
1668
|
+
const deadline = Date.now() + timeoutMs;
|
|
1669
|
+
return new Promise((resolve5) => {
|
|
1670
|
+
let settled = false;
|
|
1671
|
+
function done(result) {
|
|
1672
|
+
if (!settled) {
|
|
1673
|
+
settled = true;
|
|
1674
|
+
resolve5(result);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
function connect() {
|
|
1678
|
+
if (Date.now() > deadline) {
|
|
1679
|
+
done("timeout");
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
fetch(streamUrl, { headers: { Accept: "text/event-stream" } }).then(async (res) => {
|
|
1683
|
+
if (!res.ok || !res.body) {
|
|
1684
|
+
done("timeout");
|
|
1685
|
+
return;
|
|
1686
|
+
}
|
|
1687
|
+
const reader = res.body.getReader();
|
|
1688
|
+
const decoder = new TextDecoder();
|
|
1689
|
+
let buf = "";
|
|
1690
|
+
while (true) {
|
|
1691
|
+
const { done: streamDone, value } = await reader.read();
|
|
1692
|
+
if (streamDone) break;
|
|
1693
|
+
buf += decoder.decode(value, { stream: true });
|
|
1694
|
+
const lines = buf.split("\n");
|
|
1695
|
+
buf = lines.pop() ?? "";
|
|
1696
|
+
for (const line of lines) {
|
|
1697
|
+
if (!line.startsWith("data: ")) continue;
|
|
1698
|
+
try {
|
|
1699
|
+
const evt = JSON.parse(line.slice(6));
|
|
1700
|
+
if (evt.status === "approved") {
|
|
1701
|
+
done("approved");
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
if (evt.status === "rejected") {
|
|
1705
|
+
done("rejected");
|
|
1706
|
+
return;
|
|
1707
|
+
}
|
|
1708
|
+
if (evt.status === "timeout") {
|
|
1709
|
+
done("timeout");
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
} catch {
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
if (!settled) setTimeout(connect, 1e3);
|
|
1717
|
+
}).catch(() => {
|
|
1718
|
+
if (!settled) setTimeout(connect, 2e3);
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
connect();
|
|
1722
|
+
setTimeout(() => done("timeout"), timeoutMs);
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1725
|
+
function uninstallCommand() {
|
|
1726
|
+
return new Command4("uninstall").description("Request agent revocation (requires owner approval) and remove all local files").option("--local-only", "Skip the server-side revoke request \u2014 just clean local files").option("--timeout <seconds>", "Seconds to wait for owner approval", "300").action(async (opts) => {
|
|
1727
|
+
const timeoutMs = parseInt(opts.timeout, 10) * 1e3;
|
|
1728
|
+
const creds = tryResolveAgent();
|
|
1729
|
+
if (opts.localOnly || !creds) {
|
|
1730
|
+
if (!creds) console.log(chalk11.dim(" No agent credentials found \u2014 cleaning local files only."));
|
|
1731
|
+
cleanLocally();
|
|
1732
|
+
console.log(chalk11.dim("\n To register a new agent: npx @agentvalet/register"));
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
let privateKeyPem;
|
|
1736
|
+
try {
|
|
1737
|
+
privateKeyPem = readFileSync4(creds.keyPath, "utf-8").trim();
|
|
1738
|
+
} catch {
|
|
1739
|
+
}
|
|
1740
|
+
if (!privateKeyPem) {
|
|
1741
|
+
console.log(chalk11.yellow(" \u26A0 Private key not found \u2014 cannot submit revocation request."));
|
|
1742
|
+
console.log(chalk11.dim(" Use --local-only to clean local files without revoking."));
|
|
1743
|
+
process.exit(1);
|
|
1744
|
+
}
|
|
1745
|
+
console.log(chalk11.dim(`
|
|
1746
|
+
Submitting revocation request for ${creds.agentId}...`));
|
|
1747
|
+
const jwt = signJwt2(creds.agentId, creds.ownerId, privateKeyPem);
|
|
1748
|
+
let revocationToken;
|
|
1749
|
+
try {
|
|
1750
|
+
const res = await fetch(`${creds.apiUrl}/v1/revoke-request`, {
|
|
1751
|
+
method: "POST",
|
|
1752
|
+
headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
|
|
1753
|
+
body: JSON.stringify({ reason: "CLI uninstall" })
|
|
1754
|
+
});
|
|
1755
|
+
const body = await res.json();
|
|
1756
|
+
if (res.status === 404 || res.status === 409) {
|
|
1757
|
+
console.log(chalk11.yellow(` \u26A0 Agent not found on server (already revoked?) \u2014 cleaning local files.`));
|
|
1758
|
+
cleanLocally();
|
|
1759
|
+
console.log(chalk11.dim("\n To register a new agent: npx @agentvalet/register"));
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
if (!res.ok || !body.revocation_token) {
|
|
1763
|
+
throw new Error(body.error ?? `HTTP ${res.status}`);
|
|
1764
|
+
}
|
|
1765
|
+
revocationToken = body.revocation_token;
|
|
1766
|
+
} catch (err) {
|
|
1767
|
+
console.error(chalk11.red(` \u2717 Failed to submit revocation request: ${err instanceof Error ? err.message : err}`));
|
|
1768
|
+
process.exit(1);
|
|
1769
|
+
}
|
|
1770
|
+
console.log(chalk11.green(" \u2713 Revocation request submitted"));
|
|
1771
|
+
console.log("");
|
|
1772
|
+
console.log(chalk11.yellow(" ACTION REQUIRED:"));
|
|
1773
|
+
console.log(chalk11.yellow(` Open ${creds.apiUrl.replace("api.", "app.")}/agents and approve the uninstall request.`));
|
|
1774
|
+
console.log(chalk11.dim(` Waiting up to ${opts.timeout}s for approval...
|
|
1775
|
+
`));
|
|
1776
|
+
const result = await pollForApproval(creds.apiUrl, revocationToken, timeoutMs);
|
|
1777
|
+
if (result === "rejected") {
|
|
1778
|
+
console.log(chalk11.red("\n \u2717 Owner rejected the uninstall request. Agent remains active."));
|
|
1779
|
+
process.exit(1);
|
|
1780
|
+
}
|
|
1781
|
+
if (result === "timeout") {
|
|
1782
|
+
console.log(chalk11.yellow("\n \u26A0 Timed out waiting for owner approval."));
|
|
1783
|
+
console.log(chalk11.dim(" The request remains pending in your dashboard. Run again to resume."));
|
|
1784
|
+
process.exit(1);
|
|
1785
|
+
}
|
|
1786
|
+
console.log(chalk11.green("\n \u2713 Approved \u2014 cleaning local files...\n"));
|
|
1787
|
+
cleanLocally();
|
|
1788
|
+
console.log("");
|
|
1789
|
+
console.log(chalk11.dim(" Agent revoked. To register a new agent: npx @agentvalet/register"));
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1570
1793
|
// src/index.ts
|
|
1571
1794
|
function collectScope(value, previous) {
|
|
1572
1795
|
return [...previous, value];
|
|
1573
1796
|
}
|
|
1574
|
-
var program = new
|
|
1575
|
-
program.name("agentvalet-register").description("Self-register an AI agent with AgentValet").version("0.4.
|
|
1797
|
+
var program = new Command5();
|
|
1798
|
+
program.name("agentvalet-register").description("Self-register an AI agent with AgentValet").version("0.4.8").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) => {
|
|
1576
1799
|
const isJson = !!opts.json;
|
|
1577
1800
|
let ownerId = opts.owner ?? process.env.AGENTVALET_OWNER ?? "";
|
|
1578
1801
|
let agentName = opts.name ?? "";
|
|
@@ -1598,7 +1821,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
1598
1821
|
console.error(JSON.stringify({ error: "--owner or AGENTVALET_OWNER is required" }));
|
|
1599
1822
|
process.exit(3);
|
|
1600
1823
|
}
|
|
1601
|
-
console.error(
|
|
1824
|
+
console.error(chalk12.red("Error: --owner or AGENTVALET_OWNER environment variable is required"));
|
|
1602
1825
|
process.exit(3);
|
|
1603
1826
|
}
|
|
1604
1827
|
const scopeMap = /* @__PURE__ */ new Map();
|
|
@@ -1606,7 +1829,7 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
1606
1829
|
const colon = s.indexOf(":");
|
|
1607
1830
|
if (colon === -1) {
|
|
1608
1831
|
console.error(
|
|
1609
|
-
isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) :
|
|
1832
|
+
isJson ? JSON.stringify({ error: `Invalid scope format: ${s} (expected platform:scope)` }) : chalk12.red(`Invalid scope format: ${s} (expected platform:scope)`)
|
|
1610
1833
|
);
|
|
1611
1834
|
process.exit(3);
|
|
1612
1835
|
}
|
|
@@ -1629,11 +1852,11 @@ program.name("agentvalet-register").description("Self-register an AI agent with
|
|
|
1629
1852
|
});
|
|
1630
1853
|
} catch (err) {
|
|
1631
1854
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1632
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
1855
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk12.red(`Registration failed: ${msg}`));
|
|
1633
1856
|
process.exit(3);
|
|
1634
1857
|
}
|
|
1635
1858
|
if (!isJson) {
|
|
1636
|
-
console.log(
|
|
1859
|
+
console.log(chalk12.cyan(`
|
|
1637
1860
|
Approve at: https://app.agentvalet.ai/agents
|
|
1638
1861
|
`));
|
|
1639
1862
|
}
|
|
@@ -1641,7 +1864,7 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
1641
1864
|
if (isJson) {
|
|
1642
1865
|
console.log(JSON.stringify({ status: "pending", token }));
|
|
1643
1866
|
} else {
|
|
1644
|
-
console.log(
|
|
1867
|
+
console.log(chalk12.yellow("Registration submitted (--no-wait). Token:"), token);
|
|
1645
1868
|
}
|
|
1646
1869
|
process.exit(0);
|
|
1647
1870
|
}
|
|
@@ -1652,14 +1875,14 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
1652
1875
|
});
|
|
1653
1876
|
} catch (err) {
|
|
1654
1877
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1655
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
1878
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk12.red(`Wait failed: ${msg}`));
|
|
1656
1879
|
process.exit(3);
|
|
1657
1880
|
}
|
|
1658
1881
|
if (result.status === "rejected") {
|
|
1659
1882
|
if (isJson) {
|
|
1660
1883
|
console.log(JSON.stringify({ status: "rejected" }));
|
|
1661
1884
|
} else {
|
|
1662
|
-
console.log(
|
|
1885
|
+
console.log(chalk12.red("\nRegistration denied by owner."));
|
|
1663
1886
|
}
|
|
1664
1887
|
process.exit(1);
|
|
1665
1888
|
}
|
|
@@ -1667,7 +1890,7 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
1667
1890
|
if (isJson) {
|
|
1668
1891
|
console.log(JSON.stringify({ status: "timeout" }));
|
|
1669
1892
|
} else {
|
|
1670
|
-
console.log(
|
|
1893
|
+
console.log(chalk12.yellow("\nTimed out waiting for approval."));
|
|
1671
1894
|
}
|
|
1672
1895
|
process.exit(2);
|
|
1673
1896
|
}
|
|
@@ -1686,7 +1909,7 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
1686
1909
|
}));
|
|
1687
1910
|
} catch (err) {
|
|
1688
1911
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1689
|
-
console.error(isJson ? JSON.stringify({ error: msg }) :
|
|
1912
|
+
console.error(isJson ? JSON.stringify({ error: msg }) : chalk12.red(`Failed to save output: ${msg}`));
|
|
1690
1913
|
process.exit(3);
|
|
1691
1914
|
}
|
|
1692
1915
|
const keyWritten = !!privateKey;
|
|
@@ -1696,23 +1919,23 @@ Approve at: https://app.agentvalet.ai/agents
|
|
|
1696
1919
|
if (isJson) {
|
|
1697
1920
|
console.log(JSON.stringify({ status: "approved", agentId, keyPath: keyWritten ? keyPath : null, envPath }));
|
|
1698
1921
|
} else {
|
|
1699
|
-
console.log(
|
|
1922
|
+
console.log(chalk12.green(`
|
|
1700
1923
|
Approved! Agent ID: ${agentId}`));
|
|
1701
1924
|
if (keyWritten) {
|
|
1702
|
-
console.log(
|
|
1925
|
+
console.log(chalk12.gray(`Key: ${keyPath}`));
|
|
1703
1926
|
} else {
|
|
1704
|
-
console.log(
|
|
1927
|
+
console.log(chalk12.yellow(`Key: not written \u2014 copy it from the dashboard and paste into ${keyPath}`));
|
|
1705
1928
|
}
|
|
1706
|
-
console.log(
|
|
1929
|
+
console.log(chalk12.gray(`Env file: ${envPath}`));
|
|
1707
1930
|
console.log(`
|
|
1708
1931
|
Source the env file before calling any tool:`);
|
|
1709
|
-
console.log(
|
|
1932
|
+
console.log(chalk12.cyan(` source ${envPath}`));
|
|
1710
1933
|
}
|
|
1711
1934
|
if (keyWritten) {
|
|
1712
1935
|
try {
|
|
1713
1936
|
if (grantedPlatforms && grantedPlatforms.length > 0) {
|
|
1714
1937
|
writePermissionsFromEvent(agentId, resolvedOwnerId, grantedPlatforms);
|
|
1715
|
-
if (!isJson) console.log(
|
|
1938
|
+
if (!isJson) console.log(chalk12.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
1716
1939
|
} else {
|
|
1717
1940
|
await runRefresh({
|
|
1718
1941
|
envFile: opts.output,
|
|
@@ -1720,10 +1943,10 @@ Source the env file before calling any tool:`);
|
|
|
1720
1943
|
ifStale: false,
|
|
1721
1944
|
quiet: isJson
|
|
1722
1945
|
});
|
|
1723
|
-
if (!isJson) console.log(
|
|
1946
|
+
if (!isJson) console.log(chalk12.gray(`Permissions: .claude/agentvalet-permissions.md`));
|
|
1724
1947
|
}
|
|
1725
1948
|
} catch {
|
|
1726
|
-
if (!isJson) console.log(
|
|
1949
|
+
if (!isJson) console.log(chalk12.yellow(`Permissions: run 'agentvalet-register refresh' to generate`));
|
|
1727
1950
|
}
|
|
1728
1951
|
}
|
|
1729
1952
|
process.exit(0);
|
|
@@ -1738,7 +1961,7 @@ program.command("refresh").description("Refresh approved permissions and update
|
|
|
1738
1961
|
});
|
|
1739
1962
|
} catch (err) {
|
|
1740
1963
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1741
|
-
console.error(
|
|
1964
|
+
console.error(chalk12.red(`Refresh failed: ${msg}`));
|
|
1742
1965
|
process.exit(3);
|
|
1743
1966
|
}
|
|
1744
1967
|
});
|
|
@@ -1748,6 +1971,7 @@ program.command("mcp-server").description("Start the AgentValet MCP server (stdi
|
|
|
1748
1971
|
program.addCommand(listCommand());
|
|
1749
1972
|
program.addCommand(revokeCommand());
|
|
1750
1973
|
program.addCommand(injectCommand());
|
|
1974
|
+
program.addCommand(uninstallCommand());
|
|
1751
1975
|
program.parseAsync().catch((err) => {
|
|
1752
1976
|
console.error(err);
|
|
1753
1977
|
process.exit(3);
|