@erdoai/cli 0.64.1 → 0.65.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.
Files changed (2) hide show
  1. package/dist/index.js +81 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -297,6 +297,36 @@ var ErdoClient = class {
297
297
  createManagerKey() {
298
298
  return this.request("POST", "/v1/manager-key");
299
299
  }
300
+ // Brings an EXISTING org under your manager org by redeeming a one-time consent
301
+ // token — a manager credential on its own can never adopt an arbitrary org, it
302
+ // has to present a secret only the target org's owner (or, for an ownerless
303
+ // managed org, its current manager) could have minted. The path is a sibling of
304
+ // /v1/managed-organizations rather than a nested `adopt` because Encore rejects
305
+ // a static segment alongside the parameterized /:orgSlug routes.
306
+ adoptManagedOrganization(token) {
307
+ return this.request("POST", "/v1/managed-organization-adoptions", { token });
308
+ }
309
+ // Seats a person in a managed org. The role is capped at admin — ownership of a
310
+ // client org stays with the client — and an omitted role means the backend's
311
+ // default (member).
312
+ addManagedOrganizationMember(slug, input) {
313
+ return this.request(
314
+ "POST",
315
+ `/v1/managed-organizations/${encodeURIComponent(slug)}/members`,
316
+ input
317
+ );
318
+ }
319
+ // Offers an ownerless managed org to another manager. Such an org has no owner
320
+ // to consent, so without this it stays pinned to whoever created it; the mint is
321
+ // refused the moment the org has a real owner, since re-parenting is then the
322
+ // owner's call through an adoption token.
323
+ createManagedOrganizationHandoffToken(slug, successorManagerSlug) {
324
+ return this.request(
325
+ "POST",
326
+ `/v1/managed-organizations/${encodeURIComponent(slug)}/handoff-tokens`,
327
+ { successor_manager_slug: successorManagerSlug }
328
+ );
329
+ }
300
330
  // --- Custom page domains: the branded hostnames the org's pages serve from ---
301
331
  listCustomDomains() {
302
332
  return this.request("GET", "/v1/custom-domains");
@@ -1751,6 +1781,57 @@ id: ${o.id}`);
1751
1781
  fail(e);
1752
1782
  }
1753
1783
  });
1784
+ managed.command("adopt <token>").description("Take over an existing org by redeeming a one-time consent token").action(async (token) => {
1785
+ try {
1786
+ const o = await new ErdoClient().adoptManagedOrganization(token);
1787
+ console.log(`Adopted managed org: ${o.name}`);
1788
+ console.log(`slug: ${o.slug}
1789
+ id: ${o.id}`);
1790
+ process.stderr.write(
1791
+ `Operate it with the manager key by passing --org ${o.slug} on any command (e.g. erdo --org ${o.slug} datasets list).
1792
+ `
1793
+ );
1794
+ } catch (e) {
1795
+ fail(e);
1796
+ }
1797
+ });
1798
+ managed.command("add-member <orgSlug> <email>").description("Seat a person in a managed org (role member or admin)").option("--role <role>", "member (default) or admin").action(async (orgSlug, email, opts) => {
1799
+ try {
1800
+ if (opts.role && opts.role !== "member" && opts.role !== "admin") {
1801
+ fail(new Error("--role must be member or admin (ownership of a managed org stays with the client)"));
1802
+ }
1803
+ const m = await new ErdoClient().addManagedOrganizationMember(orgSlug, {
1804
+ email,
1805
+ role: opts.role
1806
+ });
1807
+ if (m.invited) {
1808
+ console.log(`Invited ${m.email} to ${m.org_slug} as ${m.role} \u2014 pending until they accept`);
1809
+ } else {
1810
+ console.log(`Added ${m.email} to ${m.org_slug} as ${m.role}`);
1811
+ }
1812
+ } catch (e) {
1813
+ fail(e);
1814
+ }
1815
+ });
1816
+ managed.command("handoff-token <orgSlug>").description("Mint a one-time token offering an ownerless managed org to another manager; shown ONCE").requiredOption("--successor <managerOrgSlug>", "the manager org allowed to redeem the token").action(async (orgSlug, opts) => {
1817
+ try {
1818
+ const res = await new ErdoClient().createManagedOrganizationHandoffToken(orgSlug, opts.successor);
1819
+ process.stderr.write(
1820
+ "Give this handoff token to the successor manager now \u2014 it is shown only once and cannot be retrieved again.\n"
1821
+ );
1822
+ console.log(res.token);
1823
+ process.stderr.write(
1824
+ `
1825
+ org: ${res.org_slug}
1826
+ successor: ${res.successor_manager_slug}
1827
+ expires: ${res.expires_at}
1828
+ Only ${res.successor_manager_slug} can redeem it, with: erdo org managed adopt <token>, and only until it expires at the time above.
1829
+ `
1830
+ );
1831
+ } catch (e) {
1832
+ fail(e);
1833
+ }
1834
+ });
1754
1835
  managed.command("revoke <slug>").description("Stop managing a client org (removes access; keeps an audit record)").action(async (slug) => {
1755
1836
  try {
1756
1837
  await new ErdoClient().revokeManagedOrganization(slug);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erdoai/cli",
3
- "version": "0.64.1",
3
+ "version": "0.65.0",
4
4
  "description": "Erdo CLI — drive datasets, pages, and evals from the terminal or CI",
5
5
  "type": "module",
6
6
  "bin": {