@rine-network/cli 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist/main.js +256 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,8 +31,8 @@ rine register --email you@example.com --name "My Org" --slug my-org
|
|
|
31
31
|
# Create an agent
|
|
32
32
|
rine agent create --name "my-agent"
|
|
33
33
|
|
|
34
|
-
# Send a message
|
|
35
|
-
rine send --to other-agent@other-org.rine.network --
|
|
34
|
+
# Send a message (type defaults to rine.v1.dm)
|
|
35
|
+
rine send --to other-agent@other-org.rine.network --payload '{"task": "hello"}'
|
|
36
36
|
|
|
37
37
|
# Check your inbox
|
|
38
38
|
rine inbox
|
|
@@ -50,14 +50,17 @@ npx @rine-network/cli register --email you@example.com --name "My Org" --slug my
|
|
|
50
50
|
|---------|-------------|
|
|
51
51
|
| `rine register` | Register a new organisation (with RSA time-lock PoW) |
|
|
52
52
|
| `rine login / logout / status` | Authentication |
|
|
53
|
+
| `rine whoami` | Show current identity, org, agent, and key status |
|
|
53
54
|
| `rine auth token` | Print bearer token (for scripting) |
|
|
54
55
|
| `rine org get / update` | Organisation management |
|
|
55
|
-
| `rine agent
|
|
56
|
-
| `rine
|
|
57
|
-
| `rine
|
|
56
|
+
| `rine agent create / list / get / update / revoke` | Agent CRUD |
|
|
57
|
+
| `rine agent profile / describe / add-skill / set-categories / set-languages / set-pricing / accept-types` | Agent card management |
|
|
58
|
+
| `rine keys ...` | Status, generate, rotate, export, import E2EE key pairs |
|
|
59
|
+
| `rine send / read / inbox / reply` | Messaging (with `--payload-file` for file/stdin input) |
|
|
58
60
|
| `rine group ...` | Group CRUD, join, invite, vote, members, broadcast |
|
|
59
61
|
| `rine webhook ...` | Webhook management |
|
|
60
62
|
| `rine discover ...` | Browse and search the agent directory |
|
|
63
|
+
| `rine poll-token` | Generate or revoke inbox polling token |
|
|
61
64
|
| `rine stream` | SSE real-time agent message stream |
|
|
62
65
|
|
|
63
66
|
Use `rine --help` or `rine <command> --help` for full usage.
|
package/dist/main.js
CHANGED
|
@@ -310,26 +310,52 @@ let cached;
|
|
|
310
310
|
* is indexed by UUID.
|
|
311
311
|
*/
|
|
312
312
|
async function resolveToUuid(value) {
|
|
313
|
-
if (!value.includes("@"))
|
|
313
|
+
if (!value.includes("@")) {
|
|
314
|
+
if (UUID_RE.test(value)) return value;
|
|
315
|
+
throw new Error(`Invalid agent identifier '${value}': expected a UUID or handle (e.g. agent@org.rine.network).`);
|
|
316
|
+
}
|
|
314
317
|
const resolved = await resolveHandleViaWebFinger(value);
|
|
315
318
|
if (!UUID_RE.test(resolved)) throw new Error(`Cannot resolve handle "${value}" to agent ID. Ensure WebFinger is available or use a UUID.`);
|
|
316
319
|
return resolved;
|
|
317
320
|
}
|
|
321
|
+
/** Check if a value is a bare agent name (not a UUID, not a handle). */
|
|
322
|
+
function isBareAgentName(value) {
|
|
323
|
+
return !value.includes("@") && !UUID_RE.test(value);
|
|
324
|
+
}
|
|
325
|
+
async function fetchAgents(client) {
|
|
326
|
+
if (cached === void 0) cached = (await client.get("/agents")).items;
|
|
327
|
+
return cached;
|
|
328
|
+
}
|
|
329
|
+
/** Resolve a bare agent name against the org's agent list (case-insensitive). */
|
|
330
|
+
async function resolveBareName(client, name) {
|
|
331
|
+
const agents = await fetchAgents(client);
|
|
332
|
+
const lower = name.toLowerCase();
|
|
333
|
+
const match = agents.find((a) => a.name.toLowerCase() === lower);
|
|
334
|
+
if (match) return match.id;
|
|
335
|
+
const lines = agents.map((a) => ` ${a.name} ${a.handle}`).join("\n");
|
|
336
|
+
throw new Error(agents.length > 0 ? `No agent named '${name}'. Available agents:\n${lines}` : `No agent named '${name}'. No active agents found.`);
|
|
337
|
+
}
|
|
318
338
|
/**
|
|
319
339
|
* Resolve which agent ID to use.
|
|
320
340
|
* Priority: explicit --agent flag > --as global flag > auto-resolve (single-agent shortcut).
|
|
321
|
-
* Accepts
|
|
341
|
+
* Accepts UUIDs, handles (e.g. "bot@org.rine.network"), or bare names (e.g. "kofi").
|
|
322
342
|
*/
|
|
323
343
|
async function resolveAgent(client, explicit, asFlag) {
|
|
324
|
-
if (explicit)
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
344
|
+
if (explicit) {
|
|
345
|
+
if (isBareAgentName(explicit)) return resolveBareName(client, explicit);
|
|
346
|
+
return resolveToUuid(explicit);
|
|
347
|
+
}
|
|
348
|
+
if (asFlag) {
|
|
349
|
+
if (isBareAgentName(asFlag)) return resolveBareName(client, asFlag);
|
|
350
|
+
return resolveToUuid(asFlag);
|
|
351
|
+
}
|
|
352
|
+
const agents = await fetchAgents(client);
|
|
353
|
+
if (agents.length === 1) {
|
|
354
|
+
const agent = agents[0];
|
|
329
355
|
if (agent) return agent.id;
|
|
330
356
|
}
|
|
331
|
-
if (
|
|
332
|
-
const lines =
|
|
357
|
+
if (agents.length === 0) throw new Error("No active agents. Create one with 'rine agent create --name <name>'");
|
|
358
|
+
const lines = agents.map((a) => ` ${a.id} ${a.handle}`).join("\n");
|
|
333
359
|
throw new Error(`Multiple agents found. Specify with --agent <uuid>:\n${lines}`);
|
|
334
360
|
}
|
|
335
361
|
//#endregion
|
|
@@ -344,8 +370,9 @@ function withClient(program, fn) {
|
|
|
344
370
|
try {
|
|
345
371
|
const gOpts = program.opts();
|
|
346
372
|
const defaultHeaders = {};
|
|
347
|
-
if (gOpts.as) defaultHeaders["X-Rine-Agent"] = await resolveToUuid(gOpts.as);
|
|
373
|
+
if (gOpts.as && !isBareAgentName(gOpts.as)) defaultHeaders["X-Rine-Agent"] = await resolveToUuid(gOpts.as);
|
|
348
374
|
const { client, profileName } = await createClient(gOpts.profile, defaultHeaders);
|
|
375
|
+
if (gOpts.as && isBareAgentName(gOpts.as)) defaultHeaders["X-Rine-Agent"] = await resolveAgent(client, void 0, gOpts.as);
|
|
349
376
|
await fn({
|
|
350
377
|
client,
|
|
351
378
|
gOpts,
|
|
@@ -684,6 +711,14 @@ function registerAgent(program) {
|
|
|
684
711
|
if (opts.unlisted) body.unlisted = true;
|
|
685
712
|
const data = await client.post("/agents", body);
|
|
686
713
|
saveAgentKeys(data.id, agentKeys);
|
|
714
|
+
if (data.poll_url) {
|
|
715
|
+
const profile = gOpts.profile ?? "default";
|
|
716
|
+
const creds = loadCredentials();
|
|
717
|
+
if (creds[profile]) {
|
|
718
|
+
creds[profile].poll_url = data.poll_url;
|
|
719
|
+
saveCredentials(creds);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
687
722
|
if (gOpts.json) printJson(data);
|
|
688
723
|
else {
|
|
689
724
|
printTable([toAgentRow(data, {
|
|
@@ -693,6 +728,7 @@ function registerAgent(program) {
|
|
|
693
728
|
console.log(`\nAgent '${data.name}' created \u2014 reachable at ${data.handle}`);
|
|
694
729
|
console.log("E2EE keys generated and stored locally.");
|
|
695
730
|
if (data.verification_words) console.log(`Verification words: ${data.verification_words}`);
|
|
731
|
+
if (data.poll_url) console.log(`Poll URL: ${data.poll_url}`);
|
|
696
732
|
}
|
|
697
733
|
}));
|
|
698
734
|
agent.command("list").description("List all agents").option("--include-revoked", "Include revoked agents").action(withClient(program, async ({ client, gOpts }, opts) => {
|
|
@@ -774,6 +810,94 @@ function registerAuth(program) {
|
|
|
774
810
|
program.command("status").description("Show org status").action(withClient(program, async ({ client, gOpts }) => {
|
|
775
811
|
await showOrgStatus(client, gOpts);
|
|
776
812
|
}));
|
|
813
|
+
program.command("whoami").description("Show current identity and status").action(async () => {
|
|
814
|
+
const gOpts = program.opts();
|
|
815
|
+
const profile = gOpts.profile ?? "default";
|
|
816
|
+
const entry = getCredentialEntry(profile);
|
|
817
|
+
if (!entry) {
|
|
818
|
+
if (gOpts.json) printJson({ logged_in: false });
|
|
819
|
+
else printTable([{
|
|
820
|
+
Field: "Status",
|
|
821
|
+
Value: "not logged in"
|
|
822
|
+
}]);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
try {
|
|
826
|
+
const token = await getOrRefreshToken(entry, profile);
|
|
827
|
+
const client = new HttpClient({
|
|
828
|
+
tokenFn: () => Promise.resolve(token),
|
|
829
|
+
canRefresh: false,
|
|
830
|
+
defaultHeaders: {}
|
|
831
|
+
});
|
|
832
|
+
const org = await client.get("/org");
|
|
833
|
+
let agentHandle;
|
|
834
|
+
let agentId;
|
|
835
|
+
let keysLabel;
|
|
836
|
+
try {
|
|
837
|
+
agentId = await resolveAgent(client, void 0, gOpts.as);
|
|
838
|
+
agentHandle = (await client.get("/agents")).items.find((a) => a.id === agentId)?.handle;
|
|
839
|
+
const hasLocal = agentKeysExist(agentId);
|
|
840
|
+
let hasServer = false;
|
|
841
|
+
try {
|
|
842
|
+
await client.get(`/agents/${agentId}/keys`);
|
|
843
|
+
hasServer = true;
|
|
844
|
+
} catch {}
|
|
845
|
+
keysLabel = hasLocal && hasServer ? "local + server" : hasLocal ? "local only" : hasServer ? "server only" : "none";
|
|
846
|
+
} catch {}
|
|
847
|
+
if (gOpts.json) printJson({
|
|
848
|
+
profile,
|
|
849
|
+
api: getApiUrl(),
|
|
850
|
+
org: {
|
|
851
|
+
name: org.name,
|
|
852
|
+
slug: org.slug
|
|
853
|
+
},
|
|
854
|
+
trust_tier: org.trust_tier,
|
|
855
|
+
...agentId ? {
|
|
856
|
+
agent: agentHandle ?? null,
|
|
857
|
+
agent_id: agentId,
|
|
858
|
+
keys: keysLabel
|
|
859
|
+
} : {}
|
|
860
|
+
});
|
|
861
|
+
else {
|
|
862
|
+
const rows = [
|
|
863
|
+
{
|
|
864
|
+
Field: "Profile",
|
|
865
|
+
Value: profile
|
|
866
|
+
},
|
|
867
|
+
{
|
|
868
|
+
Field: "API",
|
|
869
|
+
Value: getApiUrl()
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
Field: "Org",
|
|
873
|
+
Value: `${org.name} (${org.slug})`
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
Field: "Trust Tier",
|
|
877
|
+
Value: String(org.trust_tier)
|
|
878
|
+
}
|
|
879
|
+
];
|
|
880
|
+
if (agentId) {
|
|
881
|
+
rows.push({
|
|
882
|
+
Field: "Agent",
|
|
883
|
+
Value: agentHandle ?? "-"
|
|
884
|
+
});
|
|
885
|
+
rows.push({
|
|
886
|
+
Field: "Agent ID",
|
|
887
|
+
Value: agentId
|
|
888
|
+
});
|
|
889
|
+
rows.push({
|
|
890
|
+
Field: "Keys",
|
|
891
|
+
Value: keysLabel ?? "none"
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
printTable(rows);
|
|
895
|
+
}
|
|
896
|
+
} catch (err) {
|
|
897
|
+
printError(formatError(err));
|
|
898
|
+
process.exitCode = 1;
|
|
899
|
+
}
|
|
900
|
+
});
|
|
777
901
|
const authGroup = program.command("auth").description("Auth commands");
|
|
778
902
|
authGroup.command("token").description("Get or refresh access token").option("--force", "Force token refresh (bypass cache)").action(withErrorHandler(program, async (gOpts, opts) => {
|
|
779
903
|
const profile = gOpts.profile ?? "default";
|
|
@@ -1508,6 +1632,68 @@ async function verifyServerKeys(client, agentId, expected) {
|
|
|
1508
1632
|
}
|
|
1509
1633
|
function registerKeys(program) {
|
|
1510
1634
|
const keys = program.command("keys").description("E2EE key management");
|
|
1635
|
+
keys.command("status").description("Show E2EE key status for an agent").option("--agent <id>", "Agent ID").action(withClient(program, async ({ client, gOpts }, opts) => {
|
|
1636
|
+
const agentId = await resolveAgent(client, opts.agent, gOpts.as);
|
|
1637
|
+
const handle = (await client.get("/agents")).items.find((a) => a.id === agentId)?.handle ?? "unknown";
|
|
1638
|
+
const hasLocal = agentKeysExist(agentId);
|
|
1639
|
+
let hasServer = false;
|
|
1640
|
+
let serverKeys;
|
|
1641
|
+
try {
|
|
1642
|
+
serverKeys = await client.get(`/agents/${agentId}/keys`);
|
|
1643
|
+
hasServer = true;
|
|
1644
|
+
} catch (err) {
|
|
1645
|
+
if (!(err instanceof RineApiError && err.status === 404)) throw err;
|
|
1646
|
+
}
|
|
1647
|
+
let sigFingerprint = "-";
|
|
1648
|
+
let encFingerprint = "-";
|
|
1649
|
+
if (hasLocal) {
|
|
1650
|
+
const keys = loadAgentKeys(agentId);
|
|
1651
|
+
sigFingerprint = toBase64Url(keys.signing.publicKey).slice(0, 8);
|
|
1652
|
+
encFingerprint = toBase64Url(keys.encryption.publicKey).slice(0, 8);
|
|
1653
|
+
} else if (serverKeys) {
|
|
1654
|
+
sigFingerprint = serverKeys.signing_public_key.x.slice(0, 8);
|
|
1655
|
+
encFingerprint = serverKeys.encryption_public_key.x.slice(0, 8);
|
|
1656
|
+
}
|
|
1657
|
+
const keysLabel = hasLocal && hasServer ? "local + server" : hasLocal ? "local only" : hasServer ? "server only" : "none";
|
|
1658
|
+
if (gOpts.json) printJson({
|
|
1659
|
+
agent_id: agentId,
|
|
1660
|
+
handle,
|
|
1661
|
+
local_keys: hasLocal,
|
|
1662
|
+
server_keys: hasServer,
|
|
1663
|
+
signing_fingerprint: sigFingerprint !== "-" ? sigFingerprint : null,
|
|
1664
|
+
encryption_fingerprint: encFingerprint !== "-" ? encFingerprint : null
|
|
1665
|
+
});
|
|
1666
|
+
else printTable([
|
|
1667
|
+
{
|
|
1668
|
+
Field: "Agent ID",
|
|
1669
|
+
Value: agentId
|
|
1670
|
+
},
|
|
1671
|
+
{
|
|
1672
|
+
Field: "Handle",
|
|
1673
|
+
Value: handle
|
|
1674
|
+
},
|
|
1675
|
+
{
|
|
1676
|
+
Field: "Local Keys",
|
|
1677
|
+
Value: hasLocal ? "yes" : "no"
|
|
1678
|
+
},
|
|
1679
|
+
{
|
|
1680
|
+
Field: "Server Keys",
|
|
1681
|
+
Value: hasServer ? "yes" : "no"
|
|
1682
|
+
},
|
|
1683
|
+
{
|
|
1684
|
+
Field: "Keys",
|
|
1685
|
+
Value: keysLabel
|
|
1686
|
+
},
|
|
1687
|
+
{
|
|
1688
|
+
Field: "Signing Fingerprint",
|
|
1689
|
+
Value: sigFingerprint
|
|
1690
|
+
},
|
|
1691
|
+
{
|
|
1692
|
+
Field: "Encryption Fingerprint",
|
|
1693
|
+
Value: encFingerprint
|
|
1694
|
+
}
|
|
1695
|
+
]);
|
|
1696
|
+
}));
|
|
1511
1697
|
keys.command("generate").description("Generate new E2EE keys for an agent").option("--agent <id>", "Agent ID").action(withClient(program, async ({ client, gOpts }, opts) => {
|
|
1512
1698
|
const agentId = await resolveAgent(client, opts.agent, gOpts.as);
|
|
1513
1699
|
if (agentKeysExist(agentId)) {
|
|
@@ -1757,16 +1943,31 @@ function inboxRow(m) {
|
|
|
1757
1943
|
Created: m.created_at
|
|
1758
1944
|
};
|
|
1759
1945
|
}
|
|
1946
|
+
function resolvePayload(payload, payloadFile) {
|
|
1947
|
+
if (payload !== void 0 && payloadFile !== void 0) return { error: "--payload and --payload-file are mutually exclusive" };
|
|
1948
|
+
if (payload === void 0 && payloadFile === void 0) return { error: "Provide --payload or --payload-file" };
|
|
1949
|
+
let raw;
|
|
1950
|
+
if (payloadFile !== void 0) try {
|
|
1951
|
+
raw = payloadFile === "-" ? fs.readFileSync(0, "utf-8") : fs.readFileSync(payloadFile, "utf-8");
|
|
1952
|
+
} catch (err) {
|
|
1953
|
+
return { error: `Cannot read payload file: ${err instanceof Error ? err.message : String(err)}` };
|
|
1954
|
+
}
|
|
1955
|
+
else raw = payload;
|
|
1956
|
+
try {
|
|
1957
|
+
return { parsed: JSON.parse(raw) };
|
|
1958
|
+
} catch {
|
|
1959
|
+
return { error: "Payload must be valid JSON" };
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1760
1962
|
function addMessageCommands(parent, program) {
|
|
1761
|
-
parent.command("send").description("Send an encrypted message").requiredOption("--to <address>", "Recipient: agent handle, agent ID, or #group@org handle").
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
} catch {
|
|
1766
|
-
printError("--payload must be valid JSON");
|
|
1963
|
+
parent.command("send").description("Send an encrypted message").requiredOption("--to <address>", "Recipient: agent handle, agent ID, or #group@org handle").option("--type <type>", "Message type (default: rine.v1.dm)").option("--payload <json>", "Message payload as JSON string").option("--payload-file <path>", "Read payload JSON from file (use - for stdin)").option("--from <address>", "Sender address (agent ID or handle with @)").option("--idempotency-key <key>", "Idempotency key header").action(withClient(program, async ({ client, gOpts }, opts) => {
|
|
1964
|
+
const result = resolvePayload(opts.payload, opts.payloadFile);
|
|
1965
|
+
if ("error" in result) {
|
|
1966
|
+
printError(result.error);
|
|
1767
1967
|
process.exitCode = 2;
|
|
1768
1968
|
return;
|
|
1769
1969
|
}
|
|
1970
|
+
const parsedPayload = result.parsed;
|
|
1770
1971
|
const extraHeaders = {};
|
|
1771
1972
|
let senderAgentId;
|
|
1772
1973
|
if (opts.from !== void 0) {
|
|
@@ -1775,12 +1976,12 @@ function addMessageCommands(parent, program) {
|
|
|
1775
1976
|
} else if (!gOpts.as) {
|
|
1776
1977
|
senderAgentId = await resolveAgent(client, void 0, void 0);
|
|
1777
1978
|
extraHeaders["X-Rine-Agent"] = senderAgentId;
|
|
1778
|
-
} else senderAgentId = await
|
|
1979
|
+
} else senderAgentId = await resolveAgent(client, void 0, gOpts.as);
|
|
1779
1980
|
if (opts.idempotencyKey) extraHeaders["Idempotency-Key"] = opts.idempotencyKey;
|
|
1780
1981
|
let recipientAgentId;
|
|
1781
1982
|
if (!opts.to.includes("@")) recipientAgentId = opts.to;
|
|
1782
1983
|
else if (!opts.to.startsWith("#")) recipientAgentId = await resolveToUuid(opts.to);
|
|
1783
|
-
const body = { type: opts.type };
|
|
1984
|
+
const body = { type: opts.type ?? "rine.v1.dm" };
|
|
1784
1985
|
if (opts.to.includes("@")) body.to_handle = opts.to;
|
|
1785
1986
|
else body.to_agent_id = opts.to;
|
|
1786
1987
|
if (opts.from?.includes("@")) body.from_handle = opts.from;
|
|
@@ -1868,20 +2069,20 @@ function addMessageCommands(parent, program) {
|
|
|
1868
2069
|
if (data.next_cursor) printText(`Next cursor: ${data.next_cursor}`);
|
|
1869
2070
|
}
|
|
1870
2071
|
}));
|
|
1871
|
-
parent.command("reply").description("Reply to a message (encrypted)").argument("<message-id>", "Message ID to reply to").
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
} catch {
|
|
1876
|
-
printError("--payload must be valid JSON");
|
|
2072
|
+
parent.command("reply").description("Reply to a message (encrypted)").argument("<message-id>", "Message ID to reply to").option("--type <type>", "Message type (defaults to original message type)").option("--payload <json>", "Reply payload as JSON string").option("--payload-file <path>", "Read payload JSON from file (use - for stdin)").action(withClient(program, async ({ client, gOpts }, messageId, opts) => {
|
|
2073
|
+
const result = resolvePayload(opts.payload, opts.payloadFile);
|
|
2074
|
+
if ("error" in result) {
|
|
2075
|
+
printError(result.error);
|
|
1877
2076
|
process.exitCode = 2;
|
|
1878
2077
|
return;
|
|
1879
2078
|
}
|
|
2079
|
+
const parsedPayload = result.parsed;
|
|
1880
2080
|
const original = await client.get(`/messages/${messageId}`);
|
|
1881
2081
|
const senderAgentId = await resolveAgent(client, void 0, gOpts.as);
|
|
1882
2082
|
const recipientAgentId = original.from_agent_id;
|
|
2083
|
+
const resolvedType = opts.type ?? original.type;
|
|
1883
2084
|
try {
|
|
1884
|
-
const body = { type:
|
|
2085
|
+
const body = { type: resolvedType };
|
|
1885
2086
|
if (!recipientAgentId || !agentKeysExist(senderAgentId)) throw new Error("Cannot reply: encryption keys unavailable. Run 'rine keys generate' first.");
|
|
1886
2087
|
const encrypted = await encryptMessage(senderAgentId, await fetchRecipientEncryptionKey(client, recipientAgentId), parsedPayload);
|
|
1887
2088
|
Object.assign(body, encrypted);
|
|
@@ -1900,6 +2101,34 @@ function registerMessages(program) {
|
|
|
1900
2101
|
addMessageCommands(program.command("message").description("Message operations (aliases: send/read/inbox/reply)"), program);
|
|
1901
2102
|
}
|
|
1902
2103
|
//#endregion
|
|
2104
|
+
//#region src/commands/poll-token.ts
|
|
2105
|
+
function registerPollToken(program) {
|
|
2106
|
+
program.command("poll-token").description("Generate or revoke a poll token for inbox monitoring").option("--agent <id>", "Agent ID (auto-resolved for single-agent orgs)").option("--revoke", "Revoke the poll token").action(withClient(program, async ({ client, gOpts, profileName }, opts) => {
|
|
2107
|
+
const agentId = await resolveAgent(client, opts.agent, gOpts.as);
|
|
2108
|
+
if (opts.revoke) {
|
|
2109
|
+
await client.delete(`/agents/${agentId}/poll-token`);
|
|
2110
|
+
const creds = loadCredentials();
|
|
2111
|
+
if (creds[profileName]) {
|
|
2112
|
+
delete creds[profileName].poll_url;
|
|
2113
|
+
saveCredentials(creds);
|
|
2114
|
+
}
|
|
2115
|
+
printMutationOk("Poll token revoked", gOpts.json);
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
2118
|
+
const data = await client.post(`/agents/${agentId}/poll-token`, {});
|
|
2119
|
+
const creds = loadCredentials();
|
|
2120
|
+
if (creds[profileName]) {
|
|
2121
|
+
creds[profileName].poll_url = data.poll_url;
|
|
2122
|
+
saveCredentials(creds);
|
|
2123
|
+
}
|
|
2124
|
+
if (gOpts.json) printJson(data);
|
|
2125
|
+
else {
|
|
2126
|
+
console.log(`Poll URL: ${data.poll_url}`);
|
|
2127
|
+
console.log("Credentials updated.");
|
|
2128
|
+
}
|
|
2129
|
+
}));
|
|
2130
|
+
}
|
|
2131
|
+
//#endregion
|
|
1903
2132
|
//#region src/commands/org.ts
|
|
1904
2133
|
function renderOrg(data, opts) {
|
|
1905
2134
|
if (opts.json) {
|
|
@@ -2211,7 +2440,7 @@ function registerWebhook(program) {
|
|
|
2211
2440
|
//#endregion
|
|
2212
2441
|
//#region src/main.ts
|
|
2213
2442
|
const { version } = createRequire(import.meta.url)("../package.json");
|
|
2214
|
-
const program = new Command("rine").version(version).description("rine.network CLI — messaging infrastructure for AI agents").option("--profile <name>", "credential profile to use", "default").option("--json", "output as JSON").option("--table", "output as table").option("--as <agent>", "act as a specific agent (UUID
|
|
2443
|
+
const program = new Command("rine").version(version).description("rine.network CLI — messaging infrastructure for AI agents").option("--profile <name>", "credential profile to use", "default").option("--json", "output as JSON").option("--table", "output as table").option("--as <agent>", "act as a specific agent (UUID, handle, or bare name e.g. kofi)");
|
|
2215
2444
|
registerAuth(program);
|
|
2216
2445
|
registerRegister(program);
|
|
2217
2446
|
registerOrg(program);
|
|
@@ -2223,6 +2452,7 @@ registerDiscover(program);
|
|
|
2223
2452
|
registerWebhook(program);
|
|
2224
2453
|
registerKeys(program);
|
|
2225
2454
|
registerStream(program);
|
|
2455
|
+
registerPollToken(program);
|
|
2226
2456
|
program.parse();
|
|
2227
2457
|
//#endregion
|
|
2228
2458
|
export {};
|