@erdoai/cli 0.34.0 → 0.36.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 +101 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -241,6 +241,25 @@ var ErdoClient = class {
241
241
  setAutonomyMode(mode) {
242
242
  return this.request("PUT", "/v1/autonomy-mode", { mode });
243
243
  }
244
+ // --- Manager accounts: operate many client (managed) orgs with ONE manager key ---
245
+ // The manager is your active org; you must be an admin/owner of it. A managed org
246
+ // is a client tenant you provision and operate. The manager key (createManagerKey)
247
+ // is a single credential that acts inside any managed org via X-Organization-ID.
248
+ listManagedOrganizations() {
249
+ return this.request("GET", "/v1/managed-organizations");
250
+ }
251
+ createManagedOrganization(input) {
252
+ return this.request("POST", "/v1/managed-organizations", input);
253
+ }
254
+ revokeManagedOrganization(slug) {
255
+ return this.request(
256
+ "DELETE",
257
+ `/v1/managed-organizations/${encodeURIComponent(slug)}`
258
+ );
259
+ }
260
+ createManagerKey() {
261
+ return this.request("POST", "/v1/manager-key");
262
+ }
244
263
  // Run a read-only HogQL query against the org's page-analytics events. Rows are
245
264
  // positional per columns; enabled:false means page analytics is off for the org
246
265
  // (not zero traffic). A rejected query surfaces PostHog's message as the error.
@@ -771,12 +790,24 @@ var ErdoClient = class {
771
790
  // review id immediately (poll getPageReview for the typed findings). goal is
772
791
  // the operator's optional declared campaign goal — it steers which conversion
773
792
  // principles apply, and a page whose evident form contradicts it is a finding.
774
- reviewPages(urls, goal) {
775
- return this.request("POST", "/v1/page-reviews", goal ? { urls, goal } : { urls });
793
+ reviewPages(urls, goal, audience) {
794
+ const body = { urls };
795
+ if (goal) body.goal = goal;
796
+ if (audience) body.audience = audience;
797
+ return this.request("POST", "/v1/page-reviews", body);
776
798
  }
777
799
  getPageReview(id) {
778
800
  return this.request("GET", `/v1/page-reviews/${encodeURIComponent(id)}`);
779
801
  }
802
+ // List past reviews newest first as lean summaries (id, status, URLs, scores —
803
+ // no findings). Pass a url to track one page's score over time.
804
+ listPageReviews(url, limit) {
805
+ const params = new URLSearchParams();
806
+ if (url) params.set("url", url);
807
+ if (limit) params.set("limit", String(limit));
808
+ const qs = params.toString();
809
+ return this.request("GET", `/v1/page-reviews${qs ? "?" + qs : ""}`);
810
+ }
780
811
  updatePage(pageID, input) {
781
812
  return this.request("PUT", `/v1/pages/${encodeURIComponent(pageID)}`, input);
782
813
  }
@@ -1239,6 +1270,61 @@ org.command("autonomy [mode]").description("Show or set the org's engine-autonom
1239
1270
  fail(e);
1240
1271
  }
1241
1272
  });
1273
+ var managed = org.command("managed").description("Operate client orgs via a manager account");
1274
+ managed.command("list").description("List the client orgs your org manages").action(async () => {
1275
+ try {
1276
+ const { organizations } = await new ErdoClient().listManagedOrganizations();
1277
+ if (organizations.length === 0) {
1278
+ console.log("No managed orgs. Create one with: erdo org managed create --name <name>");
1279
+ return;
1280
+ }
1281
+ for (const o of organizations) {
1282
+ console.log(`${o.slug || "-"} ${o.name} ${o.role} ${o.id}`);
1283
+ }
1284
+ } catch (e) {
1285
+ fail(e);
1286
+ }
1287
+ });
1288
+ managed.command("create").description("Provision a new client org managed by your org").requiredOption("--name <name>", "display name for the new managed org").option("--slug <slug>", "desired slug (a unique suffix is appended if it collides)").action(async (opts) => {
1289
+ try {
1290
+ const o = await new ErdoClient().createManagedOrganization({ name: opts.name, slug: opts.slug });
1291
+ console.log(`Created managed org: ${o.name}`);
1292
+ console.log(`slug: ${o.slug}
1293
+ id: ${o.id}`);
1294
+ process.stderr.write(
1295
+ `Operate it with the manager key by passing --org ${o.slug} on any command (e.g. erdo --org ${o.slug} datasets list).
1296
+ `
1297
+ );
1298
+ } catch (e) {
1299
+ fail(e);
1300
+ }
1301
+ });
1302
+ managed.command("revoke <slug>").description("Stop managing a client org (removes access; keeps an audit record)").action(async (slug) => {
1303
+ try {
1304
+ await new ErdoClient().revokeManagedOrganization(slug);
1305
+ console.log(`revoked: ${slug}`);
1306
+ } catch (e) {
1307
+ fail(e);
1308
+ }
1309
+ });
1310
+ managed.command("key").description("Mint (or rotate) your manager key \u2014 one credential for every managed org; shown ONCE").action(async () => {
1311
+ try {
1312
+ const res = await new ErdoClient().createManagerKey();
1313
+ process.stderr.write(
1314
+ "Store this manager key now \u2014 it is shown only once and cannot be retrieved again.\n"
1315
+ );
1316
+ console.log(res.token);
1317
+ process.stderr.write(
1318
+ `
1319
+ token id: ${res.token_id}
1320
+ expires: ${res.expires_at}
1321
+ This key operates every org you manage; target one with X-Organization-ID (or \`erdo --org <slug> \u2026\`). Running this again rotates the key.
1322
+ `
1323
+ );
1324
+ } catch (e) {
1325
+ fail(e);
1326
+ }
1327
+ });
1242
1328
  var tokenCmd = program.command("token").description("Manage your API tokens (account-level credentials)");
1243
1329
  tokenCmd.command("create").description("Mint a new API token; the secret is printed ONCE").requiredOption("--name <name>", "a label for the token").option("--expires-days <n>", "days until expiry (default: 30)", (v) => parseInt(v, 10)).option("--org <idOrSlug>", "the token's default org (defaults to your active org; must be one you belong to)").action(async (opts) => {
1244
1330
  try {
@@ -2488,10 +2574,13 @@ pagesCmd.command("review <url...>").description(
2488
2574
  ).option("--wait", "poll until the review is ready, then print the findings").option(
2489
2575
  "--goal <goal>",
2490
2576
  "what the page's campaign is trying to achieve ('book demos', 'brand awareness for a launch') \u2014 steers which conversion principles apply; a page whose evident form contradicts the goal is itself a finding"
2577
+ ).option(
2578
+ "--audience <audience>",
2579
+ "who the page targets \u2014 the ICP ('out-of-state condo investors') \u2014 the critic judges clarity, proof, and tone through that reader's eyes; a page that evidently speaks to someone else is itself a finding"
2491
2580
  ).action(async (urls, opts) => {
2492
2581
  try {
2493
2582
  const client = new ErdoClient();
2494
- const started = await client.reviewPages(urls, opts.goal);
2583
+ const started = await client.reviewPages(urls, opts.goal, opts.audience);
2495
2584
  if (!opts.wait) {
2496
2585
  print(started);
2497
2586
  return;
@@ -2514,6 +2603,15 @@ pagesCmd.command("review <url...>").description(
2514
2603
  fail(e);
2515
2604
  }
2516
2605
  });
2606
+ pagesCmd.command("reviews").description(
2607
+ "List past page reviews (newest first) as lean summaries \u2014 id, status, reviewed URLs, and conversion scores, without the findings. --url filters to reviews that included that exact page: the way to see one page's score over time."
2608
+ ).option("--url <url>", "only reviews whose submitted URLs include this exact page URL").option("--limit <n>", "max reviews to return (default 20, max 100)").action(async (opts) => {
2609
+ try {
2610
+ print(await new ErdoClient().listPageReviews(opts.url, opts.limit ? Number(opts.limit) : void 0));
2611
+ } catch (e) {
2612
+ fail(e);
2613
+ }
2614
+ });
2517
2615
  pagesCmd.command("review-result <id>").description("Read a page review by id \u2014 its status and, once ready, the typed per-page findings").action(async (id) => {
2518
2616
  try {
2519
2617
  print(await new ErdoClient().getPageReview(id));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erdoai/cli",
3
- "version": "0.34.0",
3
+ "version": "0.36.0",
4
4
  "description": "Erdo CLI — drive datasets, pages, and evals from the terminal or CI",
5
5
  "type": "module",
6
6
  "bin": {