@wrangled/cli 0.3.51 → 0.3.52

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/dist/guide.js CHANGED
@@ -385,6 +385,7 @@ ${cli} content unpublish <deployment-id> [--force] take one deployed landing p
385
385
  ${cli} meta adset publish --plan '<json>' --idempotency-key <key> [--run <run-id>] make a paused Meta ad set to add ads to
386
386
  ${cli} meta adset show <id> | meta adset reconcile <id> read an ad set publication, or check whether one left sending landed
387
387
  ${cli} meta ad create --account act_<id> --adset <id> --file <path> --text "<words>" --headline "<h>" --link <url> [--cta <type>] [--name <n>] [--status paused|active --reason "<why>"] [--run <run-id>] make a Facebook ad from files in one step
388
+ ${cli} meta adset budget <id> | meta campaign budget <id> (--percent <n> | --daily <n>) --reason "<why>" change a daily budget within the workspace's limits
388
389
  ${cli} content publish-record <sku> --file <publication.json> record a publish before sending it
389
390
  ${cli} content publish-finish <publication-id> --status sending|published|failed|not_sent_practice [--input '<json>']
390
391
  ${cli} content track-link <sku> <url> [--channel facebook|email|sms|web] [--campaign <id>] tag a link with its SKU
@@ -392,6 +393,7 @@ ${cli} agent start | show <run-id> | runs | finish <run-id> --status <s> --file
392
393
  ${cli} agent draft --agent p3_refresh the P3 refresh hand's counted draft
393
394
  ${cli} brand get | brand set --file <path> [--sources '<json>' | @file.json]
394
395
  ${cli} proposals create --input '<json>' | proposals list [--status <s>] [--run <run-id>]
396
+ ${cli} proposals execute <proposal-id> apply an approved pause or budget proposal to Meta, in live mode only
395
397
  ${cli} content add-page <url> add a landing page and read it now
396
398
  ${cli} plans create --name <name> --goal <text> --channel meta|ghl|klaviyo|web [--target '<json>'] [--landing <sku> | --landing-url <url>] [--funnel <key> --step <key>] [--run <agent-run-id>] plan a campaign push
397
399
  ${cli} plans show <plan-id> | plans add <plan-id> <sku> [--role <role>] [--position <n>] | plans remove <plan-id> <sku>
package/dist/main.js CHANGED
@@ -1029,8 +1029,10 @@ const commands = {
1029
1029
  "meta ads resume": metaStatusCommand("ads", "resume"),
1030
1030
  "meta adset pause": metaStatusCommand("adset", "pause"),
1031
1031
  "meta adset resume": metaStatusCommand("adset", "resume"),
1032
+ "meta adset budget": metaBudgetCommand("adset"),
1033
+ "meta campaign budget": metaBudgetCommand("campaign"),
1032
1034
  "meta changes": {
1033
- usage: "meta changes [--since <YYYY-MM-DD>] the log of Meta ads and ad sets turned on or off, newest first",
1035
+ usage: "meta changes [--since <YYYY-MM-DD>] the log of Meta ads and ad sets turned on or off and budgets changed, newest first",
1034
1036
  async run(args, options) {
1035
1037
  if (args.length !== 0)
1036
1038
  throw new CliError("Usage: meta changes [--since <YYYY-MM-DD>]", exitCodes.usage);
@@ -1044,7 +1046,7 @@ const commands = {
1044
1046
  },
1045
1047
  },
1046
1048
  "meta changes undo": {
1047
- usage: 'meta changes undo <change-id> --reason "<why>" [--idempotency-key <key>] put the ad or ad set back the way it was',
1049
+ usage: 'meta changes undo <change-id> --reason "<why>" [--idempotency-key <key>] put the ad, ad set or budget back the way it was',
1048
1050
  async run(args, options) {
1049
1051
  if (args.length !== 1 || !options.reason)
1050
1052
  throw new CliError('Usage: meta changes undo <change-id> --reason "<why>" [--idempotency-key <key>]', exitCodes.usage);
@@ -1053,7 +1055,7 @@ const commands = {
1053
1055
  reason: options.reason,
1054
1056
  idempotencyKey,
1055
1057
  });
1056
- printMetaStatusResult(result, options.format);
1058
+ printMetaChangeResult(result, options.format);
1057
1059
  },
1058
1060
  },
1059
1061
  "meta changes reconcile": {
@@ -1062,7 +1064,7 @@ const commands = {
1062
1064
  if (args.length !== 1)
1063
1065
  throw new CliError("Usage: meta changes reconcile <change-id>", exitCodes.usage);
1064
1066
  const { change } = await api(await resolveConnection(options), `/api/v1/meta/changes/${encodeURIComponent(args[0])}/reconcile`, {});
1065
- printMetaStatusResult({ changes: [change], unchanged: [] }, options.format);
1067
+ printMetaChangeResult({ changes: [change], unchanged: [] }, options.format);
1066
1068
  },
1067
1069
  },
1068
1070
  "content unpublish": {
@@ -2058,6 +2060,15 @@ const commands = {
2058
2060
  console.log(renderTable(PROPOSAL_COLUMNS, proposals.map(proposalRow)));
2059
2061
  },
2060
2062
  },
2063
+ "proposals execute": {
2064
+ usage: "proposals execute <proposal-id> apply an approved pause or budget proposal to Meta (live mode only), within the control list",
2065
+ async run(args, options) {
2066
+ if (args.length !== 1)
2067
+ throw new CliError("Usage: proposals execute <proposal-id>", exitCodes.usage);
2068
+ const result = await api(await resolveConnection(options), `/api/v1/proposals/${encodeURIComponent(args[0])}/execute`, {});
2069
+ printMetaChangeResult(result, options.format);
2070
+ },
2071
+ },
2061
2072
  "skill publish": {
2062
2073
  usage: "skill publish <dir> [--notes <text>] [--harness claude,codex]",
2063
2074
  async run(args, options) {
@@ -2887,7 +2898,9 @@ Options:
2887
2898
  --tool-run <id> a succeeded tool run content create and edit link; repeat for several
2888
2899
  --run <id> the agent run making the content (content) or the Meta change (meta ads|adset), the tool run to
2889
2900
  record (creatives create), or the tool run whose outputs media list shows
2890
- --reason <why> why: what meta ads|adset pause|resume, meta changes undo and meta ad create --status active record in the change log
2901
+ --reason <why> why: what meta ads|adset pause|resume, meta adset|campaign budget, meta changes undo and meta ad create --status active record in the change log
2902
+ --percent <n> with meta adset|campaign budget, the whole-number percent change from Meta's daily budget now (--percent=-10 lowers it)
2903
+ --daily <n> with meta adset|campaign budget, the new daily budget in the currency's smallest unit (6000 is 60.00 USD)
2891
2904
  --account <act_id> meta ad create: the ad account
2892
2905
  --adset <id> meta ad create: the ad set the new ad goes into
2893
2906
  --text <text | @file> meta ad create: the ad's primary text
@@ -2992,6 +3005,8 @@ function parseOptions(argv) {
2992
3005
  limit: { type: "string" },
2993
3006
  run: { type: "string" },
2994
3007
  reason: { type: "string" },
3008
+ percent: { type: "string" },
3009
+ daily: { type: "string" },
2995
3010
  lineage: { type: "string" },
2996
3011
  tags: { type: "string" },
2997
3012
  sources: { type: "string" },
@@ -3122,6 +3137,8 @@ function parseOptions(argv) {
3122
3137
  limit: values.limit,
3123
3138
  run: values.run,
3124
3139
  reason: values.reason,
3140
+ percent: values.percent,
3141
+ daily: values.daily,
3125
3142
  lineage: values.lineage,
3126
3143
  tags: values.tags,
3127
3144
  sources: values.sources,
@@ -3692,7 +3709,35 @@ function metaStatusCommand(noun, verb) {
3692
3709
  idempotencyKey,
3693
3710
  ...(options.run === undefined ? {} : { runId: options.run }),
3694
3711
  });
3695
- printMetaStatusResult(result, options.format);
3712
+ printMetaChangeResult(result, options.format);
3713
+ },
3714
+ };
3715
+ }
3716
+ /** A daily budget change, for agents to compute from Meta's budget now (--percent) or to set outright in the currency's smallest unit (--daily). */
3717
+ function metaBudgetCommand(level) {
3718
+ const usage = `meta ${level} budget <${level}-id> (--percent <n> | --daily <smallest units>) --reason "<why>" [--run <run-id>] [--idempotency-key <key>]`;
3719
+ return {
3720
+ usage: `${usage} change ${level === "adset" ? "an ad set's" : "a campaign's"} daily budget on the control list, within the workspace's limits`,
3721
+ async run(args, options) {
3722
+ if (args.length !== 1 || !options.reason || (options.percent === undefined) === (options.daily === undefined))
3723
+ throw new CliError(`Usage: ${usage}`, exitCodes.usage);
3724
+ const whole = (text, flag) => {
3725
+ const n = Number(text);
3726
+ if (text.trim() === "" || !Number.isInteger(n))
3727
+ throw new CliError(`${flag} must be a whole number.`, exitCodes.usage);
3728
+ return n;
3729
+ };
3730
+ const amount = options.percent !== undefined ? { changePercent: whole(options.percent, "--percent") } : { dailyBudget: whole(options.daily, "--daily") };
3731
+ const idempotencyKey = options.idempotencyKey ?? announceKey(`budget-${randomUUID()}`);
3732
+ const result = await api(await resolveConnection(options), "/api/v1/meta/budgets", {
3733
+ level,
3734
+ id: args[0],
3735
+ ...amount,
3736
+ reason: options.reason,
3737
+ idempotencyKey,
3738
+ ...(options.run === undefined ? {} : { runId: options.run }),
3739
+ });
3740
+ printMetaChangeResult(result, options.format);
3696
3741
  },
3697
3742
  };
3698
3743
  }
@@ -3701,7 +3746,7 @@ function metaChangeRow(c) {
3701
3746
  id: c.id,
3702
3747
  level: c.level,
3703
3748
  object: c.objectId,
3704
- change: `${c.before.status} -> ${c.after.status}`,
3749
+ change: c.kind === "budget" ? `daily budget ${c.before.dailyBudget} -> ${c.after.dailyBudget}` : `${c.before.status} -> ${c.after.status}`,
3705
3750
  status: c.undoneBy ? `${c.status} (undone by ${c.undoneBy})` : c.error ? `${c.status}: ${c.error}` : c.status,
3706
3751
  when: c.createdAt,
3707
3752
  by: c.requestedBy,
@@ -3713,13 +3758,15 @@ function announceKey(key) {
3713
3758
  console.error(`Idempotency key: ${key} (if no answer comes, send the same command again with --idempotency-key ${key})`);
3714
3759
  return key;
3715
3760
  }
3716
- function printMetaStatusResult(result, format) {
3761
+ function printMetaChangeResult(result, format) {
3717
3762
  if (format === "json")
3718
3763
  return printJson(result);
3719
3764
  if (result.changes.length > 0)
3720
3765
  console.log(renderTable(META_CHANGE_COLUMNS, result.changes.map(metaChangeRow)));
3721
- for (const u of result.unchanged)
3722
- console.log(`${u.level === "ad" ? "Ad" : "Ad set"} ${u.objectId} was already ${u.status}; nothing was sent.`);
3766
+ for (const u of result.unchanged) {
3767
+ const what = { ad: "Ad", adset: "Ad set", campaign: "Campaign" }[u.level];
3768
+ console.log("status" in u ? `${what} ${u.objectId} was already ${u.status}; nothing was sent.` : `${what} ${u.objectId}'s daily budget is already ${u.dailyBudget}; nothing was sent.`);
3769
+ }
3723
3770
  for (const c of result.changes.filter((c) => c.status === "sending")) {
3724
3771
  console.log(`Meta's answer for change ${c.id} was lost. Run \`${brand.slug} meta changes reconcile ${c.id}\` in a minute to settle it.`);
3725
3772
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrangled/cli",
3
- "version": "0.3.51",
3
+ "version": "0.3.52",
4
4
  "description": "Command-line access to your marketing data warehouse, for people and coding agents",
5
5
  "type": "module",
6
6
  "bin": {