@erdoai/cli 0.46.0 → 0.47.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 +116 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -281,6 +281,28 @@ var ErdoClient = class {
281
281
  createManagerKey() {
282
282
  return this.request("POST", "/v1/manager-key");
283
283
  }
284
+ // --- Custom page domains: the branded hostnames the org's pages serve from ---
285
+ listCustomDomains() {
286
+ return this.request("GET", "/v1/custom-domains");
287
+ }
288
+ createCustomDomain(domain) {
289
+ return this.request("POST", "/v1/custom-domains", { domain });
290
+ }
291
+ deleteCustomDomain(domain) {
292
+ return this.request(
293
+ "DELETE",
294
+ `/v1/custom-domains/${encodeURIComponent(domain)}`
295
+ );
296
+ }
297
+ // Moves a domain to another org you also administer, keeping its CDN hostname
298
+ // and certificate — the cutover is atomic, with no re-validation downtime.
299
+ transferCustomDomain(domain, targetOrg) {
300
+ return this.request(
301
+ "POST",
302
+ `/v1/custom-domains/${encodeURIComponent(domain)}/transfer`,
303
+ { target_org: targetOrg }
304
+ );
305
+ }
284
306
  // Run a read-only HogQL query against the org's page-analytics events. Rows are
285
307
  // positional per columns; enabled:false means page analytics is off for the org
286
308
  // (not zero traffic). A rejected query surfaces PostHog's message as the error.
@@ -662,6 +684,8 @@ var ErdoClient = class {
662
684
  listDatasets(params) {
663
685
  const q = new URLSearchParams();
664
686
  if (params?.class) q.set("class", params.class);
687
+ if (params?.limit !== void 0) q.set("limit", String(params.limit));
688
+ if (params?.offset !== void 0) q.set("offset", String(params.offset));
665
689
  const qs = q.toString();
666
690
  return this.request("GET", `/v1/datasets${qs ? `?${qs}` : ""}`);
667
691
  }
@@ -866,6 +890,8 @@ var ErdoClient = class {
866
890
  if (opts.status) params.set("status", opts.status);
867
891
  if (opts.limit) params.set("limit", String(opts.limit));
868
892
  if (opts.workstream_slug) params.set("workstream_slug", opts.workstream_slug);
893
+ if (opts.subject_resource_type) params.set("subject_resource_type", opts.subject_resource_type);
894
+ if (opts.subject_resource_id) params.set("subject_resource_id", opts.subject_resource_id);
869
895
  const qs = params.toString();
870
896
  return this.request(
871
897
  "GET",
@@ -2379,27 +2405,34 @@ runsCmd.command("get <id>").description("Show an agent run (status, output, trac
2379
2405
  }
2380
2406
  });
2381
2407
  var approvalsCmd = program.command("approvals").description("List and decide approval requests (actions agents paused on)");
2382
- approvalsCmd.command("list").description("List approval requests, optionally filtered by status").option("-s, --status <status>", "pending | approved | rejected | expired (default: all)").option("-l, --limit <n>", "max requests", (v) => parseInt(v, 10)).option("--workstream <slug>", "only approvals for this workstream").option("--json", "output raw JSON").action(async (opts) => {
2383
- try {
2384
- const res = await new ErdoClient().listApprovals({
2385
- status: opts.status,
2386
- limit: opts.limit,
2387
- workstream_slug: opts.workstream
2388
- });
2389
- if (opts.json) {
2390
- print(res);
2391
- return;
2392
- }
2393
- for (const r of res.requests) {
2394
- const occ = r.occurrence_count && r.occurrence_count > 1 ? ` \xD7${r.occurrence_count}` : "";
2395
- console.log(
2396
- `${r.id} ${r.status} ${r.action_key} ${r.action_display} ${r.created_at}${occ}`
2397
- );
2408
+ approvalsCmd.command("list").description("List approval requests, optionally filtered by status").option("-s, --status <status>", "pending | approved | rejected | expired (default: all)").option("-l, --limit <n>", "max requests", (v) => parseInt(v, 10)).option("--workstream <slug>", "only approvals for this workstream").option(
2409
+ "--subject-type <type>",
2410
+ "only approvals whose subject resource is of this type (e.g. paid_media_campaign)"
2411
+ ).option("--subject-id <id>", "only approvals whose subject resource has this id").option("--json", "output raw JSON").action(
2412
+ async (opts) => {
2413
+ try {
2414
+ const res = await new ErdoClient().listApprovals({
2415
+ status: opts.status,
2416
+ limit: opts.limit,
2417
+ workstream_slug: opts.workstream,
2418
+ subject_resource_type: opts.subjectType,
2419
+ subject_resource_id: opts.subjectId
2420
+ });
2421
+ if (opts.json) {
2422
+ print(res);
2423
+ return;
2424
+ }
2425
+ for (const r of res.requests) {
2426
+ const occ = r.occurrence_count && r.occurrence_count > 1 ? ` \xD7${r.occurrence_count}` : "";
2427
+ console.log(
2428
+ `${r.id} ${r.status} ${r.action_key} ${r.action_display} ${r.created_at}${occ}`
2429
+ );
2430
+ }
2431
+ } catch (e) {
2432
+ fail(e);
2398
2433
  }
2399
- } catch (e) {
2400
- fail(e);
2401
2434
  }
2402
- });
2435
+ );
2403
2436
  approvalsCmd.command("decide <id>").description("Approve or reject a pending approval request").option("--approve", "approve the request").option("--reject", "reject the request").option(
2404
2437
  "--scope <scope>",
2405
2438
  "once (default) | always_this_job | always_this_workstream | always_org | always_user",
@@ -2954,15 +2987,76 @@ pagesCmd.command("review-result <id>").description("Read a page review by id \u2
2954
2987
  fail(e);
2955
2988
  }
2956
2989
  });
2990
+ var domainsCmd = pagesCmd.command("domains").description("Custom domains the org's published pages serve from");
2991
+ domainsCmd.command("list").description("List the org's custom domains with live lifecycle status").action(async () => {
2992
+ try {
2993
+ const { domains } = await new ErdoClient().listCustomDomains();
2994
+ if (domains.length === 0) {
2995
+ console.log("No custom domains. Register one with: erdo pages domains add <domain>");
2996
+ return;
2997
+ }
2998
+ for (const d of domains) {
2999
+ const checked = d.last_checked_at ? `checked ${d.last_checked_at}` : "never checked";
3000
+ const reason = d.error_reason ? ` ${d.error_reason}` : "";
3001
+ console.log(`${d.domain} ${d.status} ${checked}${reason}`);
3002
+ }
3003
+ } catch (e) {
3004
+ fail(e);
3005
+ }
3006
+ });
3007
+ domainsCmd.command("add <domain>").description("Register a custom domain (a direct subdomain, e.g. pages.acme.com) and print the DNS records to create").action(async (domain) => {
3008
+ try {
3009
+ const d = await new ErdoClient().createCustomDomain(domain);
3010
+ console.log(`${d.domain}: ${d.status}`);
3011
+ if (d.dns_records.length > 0) {
3012
+ process.stderr.write("Create these records at the domain's DNS provider:\n");
3013
+ for (const r of d.dns_records) {
3014
+ console.log(`${r.type} ${r.name} ${r.value}`);
3015
+ }
3016
+ }
3017
+ } catch (e) {
3018
+ fail(e);
3019
+ }
3020
+ });
3021
+ domainsCmd.command("remove <domain>").description("Remove a custom domain registration (stops it serving pages)").action(async (domain) => {
3022
+ try {
3023
+ const res = await new ErdoClient().deleteCustomDomain(domain);
3024
+ console.log(`removed: ${res.domain}`);
3025
+ } catch (e) {
3026
+ fail(e);
3027
+ }
3028
+ });
3029
+ domainsCmd.command("transfer <domain> <targetOrg>").description("Move a domain to another org you administer, keeping its certificate (no serving downtime)").action(async (domain, targetOrg) => {
3030
+ try {
3031
+ const d = await new ErdoClient().transferCustomDomain(domain, targetOrg);
3032
+ console.log(`${d.domain} now belongs to ${targetOrg} (status: ${d.status})`);
3033
+ } catch (e) {
3034
+ fail(e);
3035
+ }
3036
+ });
2957
3037
  var datasetsCmd = program.command("datasets").description("Datasets");
2958
3038
  datasetsCmd.command("list").description("List datasets").option(
2959
3039
  "--class <class>",
2960
3040
  "filter by structural class: 'table' or 'scratch', or 'all' to include scratch analysis by-products (default hides scratch)"
2961
- ).action(async (opts) => {
3041
+ ).option(
3042
+ "-l, --limit <n>",
3043
+ "max datasets to return (default 20, max 100)",
3044
+ (v) => parseInt(v, 10)
3045
+ ).option("--offset <n>", "skip the first n datasets (newest first)", (v) => parseInt(v, 10)).action(async (opts) => {
2962
3046
  try {
2963
- const { datasets } = await new ErdoClient().listDatasets({ class: opts.class });
3047
+ const { datasets, total } = await new ErdoClient().listDatasets({
3048
+ class: opts.class,
3049
+ limit: opts.limit,
3050
+ offset: opts.offset
3051
+ });
2964
3052
  for (const d of datasets)
2965
3053
  console.log(`${d.slug} ${d.type} ${d.status} ${d.class ?? "-"} ${d.name}`);
3054
+ const shown = (opts.offset ?? 0) + datasets.length;
3055
+ if (total > shown) {
3056
+ console.error(`(showing ${datasets.length} of ${total} \u2014 use --limit/--offset for more)`);
3057
+ } else {
3058
+ console.error(`(${total} dataset${total === 1 ? "" : "s"})`);
3059
+ }
2966
3060
  } catch (e) {
2967
3061
  fail(e);
2968
3062
  }
@@ -3157,7 +3251,7 @@ integrationsCmd.command("apps [query]").description("Search connectable apps (na
3157
3251
  fail(e);
3158
3252
  }
3159
3253
  });
3160
- integrationsCmd.command("connect <app>").description("Connect an app \u2014 pass credentials with -c, or get a browser connect URL for OAuth apps").option("-c, --credential <key=value...>", "credential field (repeatable)", (v, acc) => acc.concat(v), []).option("-n, --name <name>", "display name for the connection").action(async (app, opts) => {
3254
+ integrationsCmd.command("connect <app>").description("Connect an app \u2014 pass its API key or other credentials with -c, or omit them to get a browser connect URL for OAuth apps").option("-c, --credential <key=value...>", "credential field, e.g. -c api_key=\u2026 (repeatable); rejected by OAuth apps, which have no credential to pass", (v, acc) => acc.concat(v), []).option("-n, --name <name>", "display name for the connection").action(async (app, opts) => {
3161
3255
  try {
3162
3256
  let credentials;
3163
3257
  if (opts.credential.length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erdoai/cli",
3
- "version": "0.46.0",
3
+ "version": "0.47.0",
4
4
  "description": "Erdo CLI — drive datasets, pages, and evals from the terminal or CI",
5
5
  "type": "module",
6
6
  "bin": {