@retasc/cli 1.1.2 → 1.2.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/dist/api.js +8 -0
- package/dist/index.js +79 -1
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -14,6 +14,10 @@ const fns = {
|
|
|
14
14
|
mintKey: makeFunctionReference("manage:mintKey"),
|
|
15
15
|
rotateKey: makeFunctionReference("manage:rotateKey"),
|
|
16
16
|
revokeKey: makeFunctionReference("manage:revokeKey"),
|
|
17
|
+
createInvite: makeFunctionReference("manage:createInvite"),
|
|
18
|
+
acceptInvite: makeFunctionReference("manage:acceptInvite"),
|
|
19
|
+
listInvites: makeFunctionReference("manage:listInvites"),
|
|
20
|
+
revokeInvite: makeFunctionReference("manage:revokeInvite"),
|
|
17
21
|
};
|
|
18
22
|
function client() {
|
|
19
23
|
const cfg = loadConfig();
|
|
@@ -32,4 +36,8 @@ export const api = {
|
|
|
32
36
|
mintKey: (args) => client().action(fns.mintKey, args),
|
|
33
37
|
rotateKey: (args) => client().action(fns.rotateKey, args),
|
|
34
38
|
revokeKey: (args) => client().mutation(fns.revokeKey, args),
|
|
39
|
+
createInvite: (args) => client().action(fns.createInvite, args),
|
|
40
|
+
acceptInvite: (args) => client().mutation(fns.acceptInvite, args),
|
|
41
|
+
listInvites: (args) => client().query(fns.listInvites, args),
|
|
42
|
+
revokeInvite: (args) => client().mutation(fns.revokeInvite, args),
|
|
35
43
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
3
6
|
import { loadConfig, patchConfig, saveConfig, configPath, isLoggedIn } from "./config.js";
|
|
4
7
|
import { installMcp, normalizeScope } from "./commands/mcp.js";
|
|
5
8
|
import { installGate } from "./commands/gate.js";
|
|
@@ -11,11 +14,16 @@ import { tidyAction, doneAction } from "./commands/tidy.js";
|
|
|
11
14
|
import { runProxy } from "./proxy.js";
|
|
12
15
|
import { deviceLogin } from "./auth.js";
|
|
13
16
|
import { api } from "./api.js";
|
|
17
|
+
// Single source of truth for the version: read package.json at runtime from the
|
|
18
|
+
// compiled file's location (dist/index.js -> ../package.json). A JSON import won't
|
|
19
|
+
// work here — tsconfig has rootDir "src", so importing ../package.json is outside
|
|
20
|
+
// rootDir and fails tsc.
|
|
21
|
+
const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8"));
|
|
14
22
|
const program = new Command();
|
|
15
23
|
program
|
|
16
24
|
.name("retasc")
|
|
17
25
|
.description("Retasc — sign in, create projects, mint agent API keys, and wire your agent to the MCP server.")
|
|
18
|
-
.version(
|
|
26
|
+
.version(pkg.version);
|
|
19
27
|
function requireLogin() {
|
|
20
28
|
if (!isLoggedIn()) {
|
|
21
29
|
console.error("Not signed in. Run `retasc login` first.");
|
|
@@ -280,6 +288,76 @@ key
|
|
|
280
288
|
fail(e);
|
|
281
289
|
}
|
|
282
290
|
});
|
|
291
|
+
// --- members / invites -----------------------------------------------------
|
|
292
|
+
// An owner invites a human to their org with a single-use, expiring code; the
|
|
293
|
+
// invitee redeems it with `retasc join <code>` (authed as themselves via GitHub —
|
|
294
|
+
// no email needed). RTSC-137.
|
|
295
|
+
const members = program.command("members").description("Invite people to an org and manage invites.");
|
|
296
|
+
members
|
|
297
|
+
.command("invite")
|
|
298
|
+
.description("Mint a single-use invite code for an org (owner only). Shown once.")
|
|
299
|
+
.requiredOption("--org-id <id>")
|
|
300
|
+
.option("--expires-days <n>", "Days until the code expires (1–30, default 7)", (v) => parseInt(v, 10))
|
|
301
|
+
.action(async (opts) => {
|
|
302
|
+
requireLogin();
|
|
303
|
+
try {
|
|
304
|
+
const res = (await api.createInvite({ orgId: opts.orgId, expiresInDays: opts.expiresDays }));
|
|
305
|
+
console.log(`✓ Invite code: ${res.code}`);
|
|
306
|
+
console.log(` Expires ${new Date(res.expiresAt).toISOString().slice(0, 10)}. Single-use — shown once.`);
|
|
307
|
+
console.log(` Share it; they run: retasc login && retasc join ${res.code}`);
|
|
308
|
+
}
|
|
309
|
+
catch (e) {
|
|
310
|
+
fail(e);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
members
|
|
314
|
+
.command("list")
|
|
315
|
+
.description("List an org's invites and their status (owner only).")
|
|
316
|
+
.requiredOption("--org-id <id>")
|
|
317
|
+
.action(async (opts) => {
|
|
318
|
+
requireLogin();
|
|
319
|
+
try {
|
|
320
|
+
const res = await api.listInvites({ orgId: opts.orgId });
|
|
321
|
+
console.log(JSON.stringify(res, null, 2));
|
|
322
|
+
}
|
|
323
|
+
catch (e) {
|
|
324
|
+
fail(e);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
members
|
|
328
|
+
.command("revoke")
|
|
329
|
+
.description("Revoke an unused invite (owner only).")
|
|
330
|
+
.requiredOption("--invite-id <id>")
|
|
331
|
+
.action(async (opts) => {
|
|
332
|
+
requireLogin();
|
|
333
|
+
try {
|
|
334
|
+
await api.revokeInvite({ inviteId: opts.inviteId });
|
|
335
|
+
console.log("✓ Revoked.");
|
|
336
|
+
}
|
|
337
|
+
catch (e) {
|
|
338
|
+
fail(e);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
program
|
|
342
|
+
.command("join")
|
|
343
|
+
.description("Redeem an invite code to join an org (as the signed-in GitHub user).")
|
|
344
|
+
.argument("<code>", "The invite code you were given")
|
|
345
|
+
.action(async (code) => {
|
|
346
|
+
requireLogin();
|
|
347
|
+
try {
|
|
348
|
+
const res = (await api.acceptInvite({ code }));
|
|
349
|
+
const where = res.slug ? ` "${res.slug}"` : "";
|
|
350
|
+
if (res.alreadyMember) {
|
|
351
|
+
console.log(`• You're already a member of org${where} (${res.role}). Nothing to do.`);
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
console.log(`✓ Joined org${where} as ${res.role}. It'll show up in \`retasc whoami\`.`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch (e) {
|
|
358
|
+
fail(e);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
283
361
|
// --- mcp wiring ------------------------------------------------------------
|
|
284
362
|
const mcp = program.command("mcp").description("Wire the Retasc MCP server into your agent.");
|
|
285
363
|
mcp
|
package/package.json
CHANGED