@koda-sl/baker-cli 0.379.0-dev.fe3d33fa3 → 0.380.0-dev.59908a419

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/README.md CHANGED
@@ -3737,7 +3737,7 @@ baker shopify stock-holds --product <id> # ads Baker paused because th
3737
3737
 
3738
3738
  **`promotions`:** positional `<ref>` like `product`. Reads the product, scans this workspace's `src/pages/*` (import graph, ≤ 300 pages, files ≤ 256 KB) for its buy link, `/products/<handle>` or an option id, then `POST /api/shopify/promotions` with the linked landings. `data.ads[]` (`platform`, `level` ad|asset_group, `name`, `campaign`, `status` active|paused, `via` product_page|buy_link|landing), `data.landings[]` (`published`, `via` links_to_product|visitors_went_on), `data.shopping[]`, `data.catalog_ads`, `data.checked` (`not_checked` names a platform it could not read), `data.remembered` (the read carried a Session and named an ad — only then can “Restart ads when a product is back” later stage turning a pause from it back on, for review). `--full` adds ids, accounts, campaign / ad group / ad set ids, the Google `resource` and the URL.
3739
3739
 
3740
- **`stock-holds`:** `--product <ref>`, `--all` (resolved holds too). `data.holds[]` — one per paused entity and product, with `verdict` (`resumable` · `still_out_of_stock` · `changed_since` · `already_active` · `still_promotes_out_of_stock` · `cannot_confirm`) read live from the ad platform; `data.pending_sessions[]` — out-of-stock work still waiting for review that would pause this product's ads; `data.recently_closed[]` — with `--product`, its pauses turned back on or let go in the last 30 days.
3740
+ **`stock-holds`:** `--product <ref>`, `--all` (resolved holds too). `data.holds[]` — one per paused entity and product, with `verdict` (`resumable` · `still_out_of_stock` · `changed_since` · `already_active` · `still_promotes_out_of_stock` · `cannot_confirm`) read live from the ad platform; `data.pending_sessions[]` — out-of-stock work still waiting for review that would pause this product's ads; `data.recently_closed[]` — with `--product`, each ad whose pause for it was turned back on or let go in the last 30 days, once, with how its latest pause closed (`resolved_reason`) and when (`closed_at`).
3741
3741
 
3742
3742
  **Refusals:** `NO_SHOPIFY_CONNECTION` — no store is connected; `error.fix.action` is `request_connection` (`{ platform: "shopify" }`). `SHOPIFY_NOT_AVAILABLE` — Shopify can't be connected on this Baker yet; `error.fix.action` is `continue_without`. Both exit 1.
3743
3743
 
package/dist/cli.js CHANGED
@@ -66576,27 +66576,45 @@ function resumeCommand2(hold) {
66576
66576
  }
66577
66577
  var CLOSED_HOW = {
66578
66578
  resumed_by_back_in_stock_run: "turned back on by an earlier back-in-stock run",
66579
- changed_by_baker: "turned back on or changed in Baker",
66580
- already_active: "turned back on by someone",
66579
+ changed_by_baker: "turned back on by other work published in Baker",
66580
+ already_active: "found running again, turned back on by someone",
66581
66581
  removed: "removed",
66582
66582
  product_removed: "let go when the product left the store"
66583
66583
  };
66584
- function nothingHeldHint(answer) {
66584
+ function nothingHeldHint(answer, asked) {
66585
+ if (!asked.product) return "No ad is still paused because a product ran out: there is nothing to resume.";
66586
+ if (answer.pending_sessions.length > 0) {
66587
+ return "The latest pause for this product is still waiting for review and was never published, so nothing is paused and there is nothing to resume.";
66588
+ }
66585
66589
  const closed = answer.recently_closed;
66586
66590
  if (closed.length > 0) {
66587
- const how = [...new Set(closed.map((hold) => CLOSED_HOW[hold.resolved_reason]))].join(" or ");
66588
- return `Baker paused ${closed.map(holdName).join(", ")} when this product ran out, and ${closed.length === 1 ? "it has" : "they have"} since been ${how}: there is nothing left to resume. Tell the user that \u2014 never that nothing was paused.`;
66589
- }
66590
- if (answer.pending_sessions.length > 0) {
66591
- return "No pause for this product has been published yet, so there is nothing to resume.";
66591
+ const each = closed.map((hold) => `Baker paused ${holdName(hold)} for it, and it was later ${CLOSED_HOW[hold.resolved_reason]}`).join("; ");
66592
+ return `Nothing is still paused because this product ran out, so there is nothing to resume: ${each}. Tell the user that, naming only ${closed.length === 1 ? "this ad" : "these ads"} \u2014 never that nothing was paused, and never whether an ad is running now.`;
66592
66593
  }
66593
66594
  if (answer.holds.length > 0) return "None of these is still paused because its product ran out: nothing to resume.";
66594
66595
  return "Baker has no pause on record for this product running out: there is nothing to resume.";
66595
66596
  }
66596
- function stockHoldHints(answer) {
66597
+ function leftAloneHint(hold) {
66598
+ const name = holdName(hold);
66599
+ switch (hold.verdict) {
66600
+ case "still_out_of_stock":
66601
+ return `${name} stays paused: \u201C${hold.product.title ?? hold.product.id}\u201D still cannot be bought. Leave it.`;
66602
+ case "changed_since":
66603
+ return `${name} was changed by someone after Baker paused it: leave it, and tell the user.`;
66604
+ case "still_promotes_out_of_stock":
66605
+ return `${name} still sends people to \u201C${hold.verdict_detail ?? "another product"}\u201D, which is out: leave it until that is back.`;
66606
+ case "cannot_confirm":
66607
+ return `${name} could not be confirmed as untouched since Baker paused it: leave it, and tell the user to check it.`;
66608
+ case "already_active":
66609
+ return `${name} is already running again: nothing to do.`;
66610
+ default:
66611
+ return null;
66612
+ }
66613
+ }
66614
+ function stockHoldHints(answer, asked) {
66597
66615
  const hints2 = [];
66598
66616
  const held = answer.holds.filter((hold) => hold.state === "held");
66599
- if (held.length === 0) hints2.push(nothingHeldHint(answer));
66617
+ if (held.length === 0) hints2.push(nothingHeldHint(answer, asked));
66600
66618
  const resumable = held.filter((hold) => hold.verdict === "resumable");
66601
66619
  if (resumable.length > 0) {
66602
66620
  hints2.push(
@@ -66604,19 +66622,8 @@ function stockHoldHints(answer) {
66604
66622
  );
66605
66623
  }
66606
66624
  for (const hold of held) {
66607
- if (hold.verdict === "changed_since") {
66608
- hints2.push(`${holdName(hold)} was changed by someone after Baker paused it: leave it, and tell the user.`);
66609
- } else if (hold.verdict === "still_promotes_out_of_stock") {
66610
- hints2.push(
66611
- `${holdName(hold)} still sends people to \u201C${hold.verdict_detail ?? "another product"}\u201D, which is out: leave it until that is back.`
66612
- );
66613
- } else if (hold.verdict === "cannot_confirm") {
66614
- hints2.push(
66615
- `${holdName(hold)} could not be confirmed as untouched since Baker paused it: leave it, and tell the user to check it.`
66616
- );
66617
- } else if (hold.verdict === "already_active") {
66618
- hints2.push(`${holdName(hold)} is already running again: nothing to do.`);
66619
- }
66625
+ const why = leftAloneHint(hold);
66626
+ if (why) hints2.push(why);
66620
66627
  }
66621
66628
  for (const session of answer.pending_sessions) {
66622
66629
  hints2.push(
@@ -66640,7 +66647,7 @@ registerSchema({
66640
66647
  });
66641
66648
  registerSchema({
66642
66649
  command: "shopify.stock-holds",
66643
- description: "Start here when a product is back in stock: the ads Baker paused because it ran out, each with a `verdict` \u2014 `resumable` (resume it), `still_out_of_stock`, `changed_since` (someone changed it after Baker paused it: leave it), `already_active`, `still_promotes_out_of_stock` (it also sends people to another product that is still out: `verdict_detail` names it), `cannot_confirm`. Resume only what is resumable. `pending_sessions` lists out-of-stock work still waiting for review that would pause this product's ads: tell the user to discard it. With `--product`, `recently_closed` lists its pauses turned back on or let go in the last 30 days: an empty `holds` never means nothing was paused.",
66650
+ description: "Start here when a product is back in stock: the ads Baker paused because it ran out, each with a `verdict` \u2014 `resumable` (resume it), `still_out_of_stock`, `changed_since` (someone changed it after Baker paused it: leave it), `already_active`, `still_promotes_out_of_stock` (it also sends people to another product that is still out: `verdict_detail` names it), `cannot_confirm`. Resume only what is resumable. `pending_sessions` lists out-of-stock work still waiting for review that would pause this product's ads: tell the user to discard it. With `--product`, `recently_closed` lists each ad whose pause was turned back on or let go in the last 30 days, once, with how its latest pause closed: an empty `holds` never means nothing was paused. Tell the user in plain words, never a verdict code.",
66644
66651
  args: {
66645
66652
  product: { type: "string", description: "Only one product's holds: its id, handle or link", required: false },
66646
66653
  all: { type: "boolean", description: "Resolved holds too (resumed or released)", required: false, default: false },
@@ -66709,7 +66716,10 @@ var stockHoldsCommand = defineCommand210({
66709
66716
  params({ product: args5.product, all: args5.all, full: args5.full })
66710
66717
  );
66711
66718
  const { store, ...data } = answer;
66712
- emit2(data, { store, count: answer.holds.length }, [...storeStateHints(store), ...stockHoldHints(answer)]);
66719
+ emit2(data, { store, count: answer.holds.length }, [
66720
+ ...storeStateHints(store),
66721
+ ...stockHoldHints(answer, { product: args5.product !== void 0 })
66722
+ ]);
66713
66723
  } catch (err) {
66714
66724
  fail9(err);
66715
66725
  }