@erdoai/cli 0.32.0 → 0.34.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 +150 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -310,6 +310,29 @@ var ErdoClient = class {
310
310
  createProject(input) {
311
311
  return this.request("POST", "/v1/projects", input);
312
312
  }
313
+ // --- pages ---
314
+ listPages(params) {
315
+ const q = new URLSearchParams();
316
+ if (params?.query) q.set("query", params.query);
317
+ if (params?.createdAfter) q.set("created_after", params.createdAfter);
318
+ if (params?.createdBefore) q.set("created_before", params.createdBefore);
319
+ if (params?.limit) q.set("limit", String(params.limit));
320
+ if (params?.offset) q.set("offset", String(params.offset));
321
+ const qs = q.toString();
322
+ return this.request("GET", `/v1/pages${qs ? `?${qs}` : ""}`);
323
+ }
324
+ deletePage(id) {
325
+ return this.request(
326
+ "DELETE",
327
+ `/v1/pages/${encodeURIComponent(id)}`
328
+ );
329
+ }
330
+ restorePage(id) {
331
+ return this.request(
332
+ "POST",
333
+ `/v1/pages/restore/${encodeURIComponent(id)}`
334
+ );
335
+ }
313
336
  // --- workstreams ---
314
337
  listWorkstreams(status) {
315
338
  const q = new URLSearchParams();
@@ -465,6 +488,22 @@ var ErdoClient = class {
465
488
  input
466
489
  );
467
490
  }
491
+ // --- activity feed ---
492
+ // The unified, ranked, read-only feed: attention items, approvals, workstream
493
+ // events, catalog updates, and urgent cause-clusters. Respond via
494
+ // respondAttentionItem / decideApproval — this is a view only.
495
+ listActivityFeed(params) {
496
+ const q = new URLSearchParams();
497
+ if (params?.limit) q.set("limit", String(params.limit));
498
+ if (params?.offset) q.set("offset", String(params.offset));
499
+ if (params?.categories) q.set("categories", params.categories);
500
+ if (params?.scope) q.set("scope", params.scope);
501
+ const qs = q.toString();
502
+ return this.request(
503
+ "GET",
504
+ `/v1/activity/feed${qs ? `?${qs}` : ""}`
505
+ );
506
+ }
468
507
  // --- knowledge review queue ---
469
508
  listReviewItems(params) {
470
509
  const q = new URLSearchParams();
@@ -729,9 +768,11 @@ var ErdoClient = class {
729
768
  return this.request("POST", "/v1/pages", input);
730
769
  }
731
770
  // Start a review of external page URLs with the real landing critic; returns a
732
- // review id immediately (poll getPageReview for the typed findings).
733
- reviewPages(urls) {
734
- return this.request("POST", "/v1/page-reviews", { urls });
771
+ // review id immediately (poll getPageReview for the typed findings). goal is
772
+ // the operator's optional declared campaign goal — it steers which conversion
773
+ // 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 });
735
776
  }
736
777
  getPageReview(id) {
737
778
  return this.request("GET", `/v1/page-reviews/${encodeURIComponent(id)}`);
@@ -2201,6 +2242,74 @@ attnCmd.command("respond <id>").description(
2201
2242
  }
2202
2243
  }
2203
2244
  );
2245
+ function activityLine(it) {
2246
+ const handle = it.slug || it.id;
2247
+ const parts = [it.title || it.type];
2248
+ if (it.summary && it.summary !== it.title) {
2249
+ const s = it.summary.replace(/\s+/g, " ").trim();
2250
+ parts.push(`\u2014 ${s.length > 80 ? `${s.slice(0, 79)}\u2026` : s}`);
2251
+ }
2252
+ return ` ${handle} ${parts.join(" ")}`;
2253
+ }
2254
+ function activityAction(it) {
2255
+ if (it.type === "approval_request") return `erdo approvals decide ${it.id} --approve|--reject`;
2256
+ return `erdo attention respond ${it.slug || it.id}`;
2257
+ }
2258
+ function renderActivityFeed(feed) {
2259
+ const items = feed.items ?? [];
2260
+ const needs = items.filter((it) => it.needs_action);
2261
+ if (needs.length > 0) {
2262
+ console.log("NEEDS YOU");
2263
+ for (const it of needs) {
2264
+ const sev = it.severity ? `[${it.severity}] ` : "";
2265
+ console.log(` ${sev}${it.title || it.type}`);
2266
+ console.log(` ${activityAction(it)}`);
2267
+ }
2268
+ console.log("");
2269
+ }
2270
+ const clusters = feed.urgent_clusters ?? [];
2271
+ if (clusters.length > 0) {
2272
+ console.log("URGENT");
2273
+ if (feed.flood_summary) console.log(` ${feed.flood_summary}`);
2274
+ for (const c of clusters) console.log(` \u2022 ${c.summary} (${c.count})`);
2275
+ console.log("");
2276
+ }
2277
+ const rest = items.filter((it) => !it.needs_action && !it.clustered);
2278
+ if (rest.length > 0) {
2279
+ console.log("RECENT");
2280
+ for (const it of rest) console.log(activityLine(it));
2281
+ console.log("");
2282
+ }
2283
+ if (needs.length === 0 && clusters.length === 0 && rest.length === 0) {
2284
+ console.log("Nothing in the feed.");
2285
+ return;
2286
+ }
2287
+ console.log(`${items.length} shown \xB7 ${feed.total} total`);
2288
+ }
2289
+ program.command("activity").alias("feed").description(
2290
+ "The unified activity feed \u2014 needs-you items first, then urgent cause-clusters, then recent activity. Read-only: respond with `erdo attention respond` / `erdo approvals decide`."
2291
+ ).option("-n, --limit <n>", "max items (default 20, max 100)", (v) => parseInt(v, 10)).option("--offset <n>", "pagination offset", (v) => parseInt(v, 10)).option(
2292
+ "--categories <list>",
2293
+ "comma-separated: attention,approval,workstream,catalog,job,heartbeat (default excludes runs)"
2294
+ ).option("--scope <scope>", "following | all (default all)").option("--json", "raw JSON response").action(
2295
+ async (opts) => {
2296
+ try {
2297
+ const feed = await new ErdoClient().listActivityFeed({
2298
+ limit: opts.limit,
2299
+ offset: opts.offset,
2300
+ categories: opts.categories,
2301
+ scope: opts.scope
2302
+ });
2303
+ if (opts.json) {
2304
+ print(feed);
2305
+ return;
2306
+ }
2307
+ renderActivityFeed(feed);
2308
+ } catch (e) {
2309
+ fail(e);
2310
+ }
2311
+ }
2312
+ );
2204
2313
  var reviewsCmd = program.command("reviews").description(
2205
2314
  "The Knowledge Review queue \u2014 knowledge patches the critic proposes, investigations, and deduplicated failure signals awaiting a human decision"
2206
2315
  );
@@ -2329,10 +2438,40 @@ pagesCmd.command("validate").description("Validate page content without deployin
2329
2438
  fail(e);
2330
2439
  }
2331
2440
  });
2332
- pagesCmd.command("list").description("List artifacts (pages, charts, ...)").option("-t, --type <type>", "filter by type (e.g. html_page)").option("-l, --limit <n>", "max results", (v) => parseInt(v, 10)).action(async (opts) => {
2441
+ pagesCmd.command("list").description("List pages (newest first). With --type, lists any artifact type instead.").option("-t, --type <type>", "list all artifacts of this type (e.g. html) rather than just pages").option("--query <substr>", "case-insensitive title substring filter (pages only)").option("--created-after <iso>", "only pages created at/after this RFC3339 timestamp (pages only)").option("--created-before <iso>", "only pages created at/before this RFC3339 timestamp (pages only)").option("-l, --limit <n>", "max results", (v) => parseInt(v, 10)).option("--offset <n>", "pagination offset", (v) => parseInt(v, 10)).action(
2442
+ async (opts) => {
2443
+ try {
2444
+ if (opts.type) {
2445
+ const { artifacts } = await new ErdoClient().listArtifacts(opts.type, opts.limit);
2446
+ for (const a of artifacts) console.log(`${a.id} ${a.type} ${a.title}`);
2447
+ return;
2448
+ }
2449
+ const { pages } = await new ErdoClient().listPages({
2450
+ query: opts.query,
2451
+ createdAfter: opts.createdAfter,
2452
+ createdBefore: opts.createdBefore,
2453
+ limit: opts.limit,
2454
+ offset: opts.offset
2455
+ });
2456
+ for (const p of pages) {
2457
+ const vis = p.public ? p.public_url || "public" : "private";
2458
+ console.log(`${p.id} ${p.created_at} ${vis} ${p.title}`);
2459
+ }
2460
+ } catch (e) {
2461
+ fail(e);
2462
+ }
2463
+ }
2464
+ );
2465
+ pagesCmd.command("delete <id>").description("Delete a page (soft delete \u2014 unpublishes it and hides it from listings; restorable)").action(async (id) => {
2466
+ try {
2467
+ print(await new ErdoClient().deletePage(id));
2468
+ } catch (e) {
2469
+ fail(e);
2470
+ }
2471
+ });
2472
+ pagesCmd.command("restore <id>").description("Restore a previously deleted page (comes back private)").action(async (id) => {
2333
2473
  try {
2334
- const { artifacts } = await new ErdoClient().listArtifacts(opts.type, opts.limit);
2335
- for (const a of artifacts) console.log(`${a.id} ${a.type} ${a.title}`);
2474
+ print(await new ErdoClient().restorePage(id));
2336
2475
  } catch (e) {
2337
2476
  fail(e);
2338
2477
  }
@@ -2346,10 +2485,13 @@ pagesCmd.command("get <id>").description("Show an artifact").action(async (id) =
2346
2485
  });
2347
2486
  pagesCmd.command("review <url...>").description(
2348
2487
  "Review external landing page URLs with Erdo's real conversion critic \u2014 typed defects (severity, issue, why it costs conversions, evidence, fix) plus strengths, judged from fold + full-page captures on desktop and mobile. Returns a review id; use --wait to poll and print the findings."
2349
- ).option("--wait", "poll until the review is ready, then print the findings").action(async (urls, opts) => {
2488
+ ).option("--wait", "poll until the review is ready, then print the findings").option(
2489
+ "--goal <goal>",
2490
+ "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"
2491
+ ).action(async (urls, opts) => {
2350
2492
  try {
2351
2493
  const client = new ErdoClient();
2352
- const started = await client.reviewPages(urls);
2494
+ const started = await client.reviewPages(urls, opts.goal);
2353
2495
  if (!opts.wait) {
2354
2496
  print(started);
2355
2497
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erdoai/cli",
3
- "version": "0.32.0",
3
+ "version": "0.34.0",
4
4
  "description": "Erdo CLI — drive datasets, pages, and evals from the terminal or CI",
5
5
  "type": "module",
6
6
  "bin": {