@koda-sl/baker-cli 0.342.0-dev.ee2d2f03a → 0.343.0-dev.4845130c3
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 +11 -4
- package/canvas/end-card-composition/meta.json +1 -5
- package/canvas/feature-reveal-composition/meta.json +2 -12
- package/canvas/lower-third-composition/meta.json +1 -7
- package/canvas/video-call-composition/meta.json +5 -27
- package/dist/cli.js +201 -33
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,12 +118,14 @@ Use `--output` to change format:
|
|
|
118
118
|
|
|
119
119
|
| Format | Description | Best for | Available on |
|
|
120
120
|
|---------|------------------------------------|--------------------|--------------|
|
|
121
|
-
| `json` | Structured JSON envelope (default) | AI agents | every command |
|
|
122
|
-
| `files` | Tab-separated, one row per result | Piping / shell |
|
|
123
|
-
| `md` | Markdown table | Human reading |
|
|
121
|
+
| `json` | Structured JSON envelope (default) | AI agents | every command that prints the envelope |
|
|
122
|
+
| `files` | Tab-separated, one row per result | Piping / shell | commands whose `baker schema` lists `output` |
|
|
123
|
+
| `md` | Markdown table | Human reading | commands whose `baker schema` lists `output` |
|
|
124
124
|
| `csv` | RFC 4180 comma-separated values | Analysis tools | `baker research …` only |
|
|
125
125
|
| `jsonl` | One JSON object per line | Streaming/appending | `baker research …` only |
|
|
126
126
|
|
|
127
|
+
`--output json` is accepted even by a command that declares no `--output`: the envelope is already what it prints, and on a command whose default is a readable view (`baker tags list`, the `draft` commands) it becomes that command's `--json`. The few commands that print only text — `baker analytics sending-events`, `baker canvas run` and `rerun` — refuse it, as a command without its own `--output` refuses `md` and `files`.
|
|
128
|
+
|
|
127
129
|
`csv` and `jsonl` are implemented by the research family alone. Asking any other command for them — or for a format that does not exist — falls back to the JSON envelope and says so on stderr, rather than printing nothing and exiting 0.
|
|
128
130
|
|
|
129
131
|
`files` and `md` print rows and nothing else, so any `hints` or data-quality note the envelope carries is written to **stderr** instead. Reading stdout alone still gives you clean, parseable rows.
|
|
@@ -609,11 +611,16 @@ baker ads google keywords update <criterion-id> --customer-id 1234567890 --clear
|
|
|
609
611
|
baker ads google ads create --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> \
|
|
610
612
|
--headlines "Fast Widgets,Buy Online,Free Shipping" --descriptions "Best widgets around.,Ships tomorrow." \
|
|
611
613
|
--final-url https://example.com
|
|
614
|
+
# Copy with commas in it — repeat the flag once per item (or quote the item: '"Fast, free quotes",Book today')
|
|
615
|
+
baker ads google ads create --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> \
|
|
616
|
+
--headlines "Fast Widgets,Buy Online,Free Shipping" \
|
|
617
|
+
--descriptions "Calls, messages and bookings in one place." --descriptions "Ships tomorrow, free." \
|
|
618
|
+
--final-url https://example.com
|
|
612
619
|
# Responsive display ad — images are fields on the ad; register each image as an asset first (returns a g_temp_* ref)
|
|
613
620
|
baker ads google assets create --customer-id 1234567890 --file '{"type":"image","imageId":"<baker_image_id>","name":"Hero"}'
|
|
614
621
|
baker ads google ads create --customer-id 1234567890 --ad-group-ref g_temp_<adgroup> --format responsiveDisplay \
|
|
615
622
|
--headlines "Come back and save" --long-headline "Finish signing up and get 20% off" \
|
|
616
|
-
--descriptions "Fast setup, no card required" --business-name "Acme" --final-url https://example.com \
|
|
623
|
+
--descriptions '"Fast setup, no card required"' --business-name "Acme" --final-url https://example.com \
|
|
617
624
|
--marketing-images g_temp_<img_landscape> --square-marketing-images g_temp_<img_square> --logo-images g_temp_<img_logo>
|
|
618
625
|
# Video ad — the YouTube video is its own asset first, then referenced by --video-assets
|
|
619
626
|
baker ads google assets create --customer-id 1234567890 --file '{"type":"youtubeVideo","youtubeVideoId":"dQw4w9WgXcQ"}'
|
|
@@ -8,11 +8,7 @@
|
|
|
8
8
|
"default_duration": 3,
|
|
9
9
|
"inputs": {},
|
|
10
10
|
"params": {
|
|
11
|
-
"logo_svg": {
|
|
12
|
-
"kind": "string",
|
|
13
|
-
"default": "",
|
|
14
|
-
"description": "Raw inline <svg>…</svg> wordmark with fill set to text_color (optional)."
|
|
15
|
-
},
|
|
11
|
+
"logo_svg": { "kind": "string", "default": "", "description": "Raw inline <svg>…</svg> wordmark with fill set to text_color (optional)." },
|
|
16
12
|
"headline": { "kind": "string", "required": true, "description": "Closing line." },
|
|
17
13
|
"cta_text": { "kind": "string", "default": "", "description": "Call-to-action pill label (optional)." },
|
|
18
14
|
"bg_color": { "kind": "color", "default": "#0b1020" },
|
|
@@ -9,20 +9,10 @@
|
|
|
9
9
|
"inputs": {},
|
|
10
10
|
"params": {
|
|
11
11
|
"title": { "kind": "string", "default": "", "description": "Optional heading above the list." },
|
|
12
|
-
"features": {
|
|
13
|
-
"kind": "json",
|
|
14
|
-
"required": true,
|
|
15
|
-
"description": "Array of 1–6 short labels, e.g. [\"No setup fees\", \"Cancel anytime\"]."
|
|
16
|
-
},
|
|
12
|
+
"features": { "kind": "json", "required": true, "description": "Array of 1–6 short labels, e.g. [\"No setup fees\", \"Cancel anytime\"]." },
|
|
17
13
|
"text_color": { "kind": "color", "default": "#0b1020" },
|
|
18
14
|
"accent_color": { "kind": "color", "default": "#1f9d57", "description": "Check-circle fill." },
|
|
19
15
|
"check_color": { "kind": "color", "default": "#ffffff", "description": "The check mark inside the circle." },
|
|
20
|
-
"stagger_s": {
|
|
21
|
-
"kind": "number",
|
|
22
|
-
"default": 0.18,
|
|
23
|
-
"min": 0.02,
|
|
24
|
-
"max": 1,
|
|
25
|
-
"description": "Seconds between each item."
|
|
26
|
-
}
|
|
16
|
+
"stagger_s": { "kind": "number", "default": 0.18, "min": 0.02, "max": 1, "description": "Seconds between each item." }
|
|
27
17
|
}
|
|
28
18
|
}
|
|
@@ -13,12 +13,6 @@
|
|
|
13
13
|
"bar_color": { "kind": "color", "default": "#0b1020" },
|
|
14
14
|
"text_color": { "kind": "color", "default": "#ffffff" },
|
|
15
15
|
"accent_color": { "kind": "color", "default": "#5b8cff", "description": "The leading accent block." },
|
|
16
|
-
"from_bottom_px": {
|
|
17
|
-
"kind": "integer",
|
|
18
|
-
"default": 220,
|
|
19
|
-
"min": 0,
|
|
20
|
-
"max": 1600,
|
|
21
|
-
"description": "Distance of the bar from the bottom edge."
|
|
22
|
-
}
|
|
16
|
+
"from_bottom_px": { "kind": "integer", "default": 220, "min": 0, "max": 1600, "description": "Distance of the bar from the bottom edge." }
|
|
23
17
|
}
|
|
24
18
|
}
|
|
@@ -15,34 +15,12 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"params": {
|
|
18
|
-
"headline": {
|
|
19
|
-
|
|
20
|
-
"default": "",
|
|
21
|
-
"description": "Big line on the content stage (what the presenter is showing)."
|
|
22
|
-
},
|
|
23
|
-
"claim": {
|
|
24
|
-
"kind": "string",
|
|
25
|
-
"default": "",
|
|
26
|
-
"description": "Short proof/claim on the floating glass card (optional)."
|
|
27
|
-
},
|
|
18
|
+
"headline": { "kind": "string", "default": "", "description": "Big line on the content stage (what the presenter is showing)." },
|
|
19
|
+
"claim": { "kind": "string", "default": "", "description": "Short proof/claim on the floating glass card (optional)." },
|
|
28
20
|
"caption": { "kind": "string", "default": "", "description": "A caption line in the lower band (optional)." },
|
|
29
|
-
"pip_at_s": {
|
|
30
|
-
|
|
31
|
-
"default": 2,
|
|
32
|
-
"min": 0,
|
|
33
|
-
"max": 30,
|
|
34
|
-
"description": "When the presenter shrinks to the corner pill."
|
|
35
|
-
},
|
|
36
|
-
"bg_color": {
|
|
37
|
-
"kind": "color",
|
|
38
|
-
"default": "#0b1020",
|
|
39
|
-
"description": "Content-stage background (behind the presenter)."
|
|
40
|
-
},
|
|
21
|
+
"pip_at_s": { "kind": "number", "default": 2, "min": 0, "max": 30, "description": "When the presenter shrinks to the corner pill." },
|
|
22
|
+
"bg_color": { "kind": "color", "default": "#0b1020", "description": "Content-stage background (behind the presenter)." },
|
|
41
23
|
"text_color": { "kind": "color", "default": "#ffffff" },
|
|
42
|
-
"accent_color": {
|
|
43
|
-
"kind": "color",
|
|
44
|
-
"default": "#5b8cff",
|
|
45
|
-
"description": "Headline accent + caption underline + pill ring tint."
|
|
46
|
-
}
|
|
24
|
+
"accent_color": { "kind": "color", "default": "#5b8cff", "description": "Headline accent + caption underline + pill ring tint." }
|
|
47
25
|
}
|
|
48
26
|
}
|
package/dist/cli.js
CHANGED
|
@@ -17043,6 +17043,113 @@ Examples:
|
|
|
17043
17043
|
// src/commands/ads/google/write-commands.ts
|
|
17044
17044
|
import { defineCommand as defineCommand31 } from "citty";
|
|
17045
17045
|
|
|
17046
|
+
// src/commands/ads/google/ad-copy-flags.ts
|
|
17047
|
+
var AD_COPY_LIST_FLAGS = ["headlines", "descriptions", "long-headlines"];
|
|
17048
|
+
var AD_COPY_LIST_USAGE = `repeat the flag once per item, or pass one comma-separated list and wrap an item that contains a comma in double quotes: '"Fast, free quotes",Book today'. A flag given once is read as a list, so a lone item with a comma needs its double quotes too: '"Fast, free quotes"'`;
|
|
17049
|
+
function skipBlanks(value, at) {
|
|
17050
|
+
let i = at;
|
|
17051
|
+
while (value[i] === " " || value[i] === " ") i++;
|
|
17052
|
+
return i;
|
|
17053
|
+
}
|
|
17054
|
+
function readQuotedField(value, open, flag) {
|
|
17055
|
+
let text2 = "";
|
|
17056
|
+
let j = open + 1;
|
|
17057
|
+
while (!(value[j] === '"' && value[j + 1] !== '"')) {
|
|
17058
|
+
if (j >= value.length) {
|
|
17059
|
+
failWriteValidation(`--${flag} has a quote with no closing quote: ${value} \u2014 ${AD_COPY_LIST_USAGE}`);
|
|
17060
|
+
}
|
|
17061
|
+
text2 += value[j];
|
|
17062
|
+
j += value[j] === '"' ? 2 : 1;
|
|
17063
|
+
}
|
|
17064
|
+
const after = skipBlanks(value, j + 1);
|
|
17065
|
+
if (after < value.length && value[after] !== ",") {
|
|
17066
|
+
failWriteValidation(
|
|
17067
|
+
`--${flag}: text follows the closing quote of "${text2}" \u2014 a quoted item must end at a comma. To put a quote inside an item, double it ("") or ${AD_COPY_LIST_USAGE}`
|
|
17068
|
+
);
|
|
17069
|
+
}
|
|
17070
|
+
return { text: text2, next: after + 1 };
|
|
17071
|
+
}
|
|
17072
|
+
function splitQuotedList(value, flag) {
|
|
17073
|
+
const fields = [];
|
|
17074
|
+
let i = 0;
|
|
17075
|
+
while (i <= value.length) {
|
|
17076
|
+
const start = skipBlanks(value, i);
|
|
17077
|
+
if (value[start] === '"') {
|
|
17078
|
+
const { text: text2, next } = readQuotedField(value, start, flag);
|
|
17079
|
+
fields.push({ text: text2, quoted: true });
|
|
17080
|
+
i = next;
|
|
17081
|
+
} else {
|
|
17082
|
+
const comma = value.indexOf(",", start);
|
|
17083
|
+
const end = comma === -1 ? value.length : comma;
|
|
17084
|
+
fields.push({ text: value.slice(start, end), quoted: false });
|
|
17085
|
+
i = end + 1;
|
|
17086
|
+
}
|
|
17087
|
+
}
|
|
17088
|
+
const several = fields.length > 1;
|
|
17089
|
+
return fields.map((field) => ({ text: field.text.trim(), splitAtComma: several && !field.quoted }));
|
|
17090
|
+
}
|
|
17091
|
+
function jsonStringArray(value) {
|
|
17092
|
+
if (!value.startsWith("[")) return void 0;
|
|
17093
|
+
try {
|
|
17094
|
+
const parsed = JSON.parse(value);
|
|
17095
|
+
return Array.isArray(parsed) && parsed.every((v) => typeof v === "string") ? parsed : void 0;
|
|
17096
|
+
} catch {
|
|
17097
|
+
return void 0;
|
|
17098
|
+
}
|
|
17099
|
+
}
|
|
17100
|
+
function parseCopyList(value, flag) {
|
|
17101
|
+
let items;
|
|
17102
|
+
if (Array.isArray(value)) {
|
|
17103
|
+
items = value.filter((v) => typeof v === "string").map((v) => ({ text: v.trim(), splitAtComma: false }));
|
|
17104
|
+
} else if (typeof value === "string") {
|
|
17105
|
+
const trimmed = value.trim();
|
|
17106
|
+
const json = jsonStringArray(trimmed);
|
|
17107
|
+
items = json ? json.map((v) => ({ text: v.trim(), splitAtComma: false })) : splitQuotedList(trimmed, flag);
|
|
17108
|
+
} else {
|
|
17109
|
+
return void 0;
|
|
17110
|
+
}
|
|
17111
|
+
const kept = items.filter((item) => item.text.length > 0);
|
|
17112
|
+
return kept.length > 0 ? kept : void 0;
|
|
17113
|
+
}
|
|
17114
|
+
function copyListFlag(value, flag) {
|
|
17115
|
+
return parseCopyList(value, flag)?.map((item) => item.text);
|
|
17116
|
+
}
|
|
17117
|
+
function refuseDashLedValue(rawArgs, flag) {
|
|
17118
|
+
for (let i = 0; i < rawArgs.length - 1; i++) {
|
|
17119
|
+
if (rawArgs[i] === "--") return;
|
|
17120
|
+
const value = rawArgs[i + 1];
|
|
17121
|
+
if (rawArgs[i] === `--${flag}` && value?.startsWith("-")) {
|
|
17122
|
+
failWriteValidation(
|
|
17123
|
+
`--${flag} is followed by "${value}", which starts with a dash and is read as another flag, not as copy. Join copy that starts with a dash to its flag with =: --${flag}="${value}"`
|
|
17124
|
+
);
|
|
17125
|
+
}
|
|
17126
|
+
}
|
|
17127
|
+
}
|
|
17128
|
+
function withRepeatedCopyFlags(args5, rawArgs) {
|
|
17129
|
+
const out = { ...args5 };
|
|
17130
|
+
for (const flag of AD_COPY_LIST_FLAGS) {
|
|
17131
|
+
refuseDashLedValue(rawArgs ?? [], flag);
|
|
17132
|
+
const values = repeatedFlagValues(rawArgs ?? [], flag);
|
|
17133
|
+
if (values.length > 1) {
|
|
17134
|
+
out[flag] = values;
|
|
17135
|
+
}
|
|
17136
|
+
}
|
|
17137
|
+
return out;
|
|
17138
|
+
}
|
|
17139
|
+
function copyListSplitHints(args5) {
|
|
17140
|
+
const hints2 = [];
|
|
17141
|
+
for (const flag of AD_COPY_LIST_FLAGS) {
|
|
17142
|
+
const items = parseCopyList(args5[flag], flag) ?? [];
|
|
17143
|
+
const fragments = items.filter((item, index) => index > 0 && item.splitAtComma && new RegExp("^\\p{Ll}", "u").test(item.text));
|
|
17144
|
+
if (fragments.length > 0) {
|
|
17145
|
+
hints2.push(
|
|
17146
|
+
`--${flag}: ${fragments.map((f) => `"${f.text}"`).join(", ")} starts in lowercase \u2014 it looks like the end of one item cut at a comma. Check the staged copy; if it was one item, fix this op in place with \`draft amend <ref>\` (the ref this response returned) rather than staging it again, which would leave the cut copy staged too \u2014 ${AD_COPY_LIST_USAGE}.`
|
|
17147
|
+
);
|
|
17148
|
+
}
|
|
17149
|
+
}
|
|
17150
|
+
return hints2;
|
|
17151
|
+
}
|
|
17152
|
+
|
|
17046
17153
|
// src/commands/ads/google/conversion-upload-command.ts
|
|
17047
17154
|
import { readFileSync as readFileSync4 } from "fs";
|
|
17048
17155
|
import { defineCommand as defineCommand30 } from "citty";
|
|
@@ -18098,10 +18205,10 @@ var keywordListsCommand = defineCommand31({
|
|
|
18098
18205
|
}
|
|
18099
18206
|
});
|
|
18100
18207
|
function rsaContentFromFlags(args5) {
|
|
18101
|
-
const headlines =
|
|
18102
|
-
const descriptions =
|
|
18208
|
+
const headlines = copyListFlag(args5.headlines, "headlines");
|
|
18209
|
+
const descriptions = copyListFlag(args5.descriptions, "descriptions");
|
|
18103
18210
|
if (!headlines || !descriptions) {
|
|
18104
|
-
failWriteValidation("responsive search ads need --headlines and --descriptions
|
|
18211
|
+
failWriteValidation("responsive search ads need --headlines and --descriptions, or use --file");
|
|
18105
18212
|
}
|
|
18106
18213
|
const finalUrls = listFlag(args5["final-url"]);
|
|
18107
18214
|
if (!finalUrls) {
|
|
@@ -18121,11 +18228,11 @@ function rdaContentFromFlags(args5, base) {
|
|
|
18121
18228
|
format: "responsiveDisplay",
|
|
18122
18229
|
...base !== null && typeof base === "object" && !Array.isArray(base) ? base : {}
|
|
18123
18230
|
};
|
|
18124
|
-
const headlines =
|
|
18231
|
+
const headlines = copyListFlag(args5.headlines, "headlines");
|
|
18125
18232
|
if (headlines) {
|
|
18126
18233
|
content.headlines = headlines.map((text2) => ({ text: text2 }));
|
|
18127
18234
|
}
|
|
18128
|
-
const descriptions =
|
|
18235
|
+
const descriptions = copyListFlag(args5.descriptions, "descriptions");
|
|
18129
18236
|
if (descriptions) {
|
|
18130
18237
|
content.descriptions = descriptions.map((text2) => ({ text: text2 }));
|
|
18131
18238
|
}
|
|
@@ -18176,11 +18283,11 @@ function demandGenContentFromFlags(args5, base) {
|
|
|
18176
18283
|
if (typeof args5["ad-name"] === "string") {
|
|
18177
18284
|
content.name = args5["ad-name"];
|
|
18178
18285
|
}
|
|
18179
|
-
const headlines =
|
|
18286
|
+
const headlines = copyListFlag(args5.headlines, "headlines");
|
|
18180
18287
|
if (headlines) {
|
|
18181
18288
|
content.headlines = headlines.map((text2) => ({ text: text2 }));
|
|
18182
18289
|
}
|
|
18183
|
-
const descriptions =
|
|
18290
|
+
const descriptions = copyListFlag(args5.descriptions, "descriptions");
|
|
18184
18291
|
if (descriptions) {
|
|
18185
18292
|
content.descriptions = descriptions.map((text2) => ({ text: text2 }));
|
|
18186
18293
|
}
|
|
@@ -18213,15 +18320,15 @@ function demandGenVideoContentFromFlags(args5, base) {
|
|
|
18213
18320
|
if (typeof args5["ad-name"] === "string") {
|
|
18214
18321
|
content.name = args5["ad-name"];
|
|
18215
18322
|
}
|
|
18216
|
-
const headlines =
|
|
18323
|
+
const headlines = copyListFlag(args5.headlines, "headlines");
|
|
18217
18324
|
if (headlines) {
|
|
18218
18325
|
content.headlines = headlines.map((text2) => ({ text: text2 }));
|
|
18219
18326
|
}
|
|
18220
|
-
const longHeadlines =
|
|
18327
|
+
const longHeadlines = copyListFlag(args5["long-headlines"], "long-headlines");
|
|
18221
18328
|
if (longHeadlines) {
|
|
18222
18329
|
content.longHeadlines = longHeadlines.map((text2) => ({ text: text2 }));
|
|
18223
18330
|
}
|
|
18224
|
-
const descriptions =
|
|
18331
|
+
const descriptions = copyListFlag(args5.descriptions, "descriptions");
|
|
18225
18332
|
if (descriptions) {
|
|
18226
18333
|
content.descriptions = descriptions.map((text2) => ({ text: text2 }));
|
|
18227
18334
|
}
|
|
@@ -18251,11 +18358,11 @@ function appContentFromFlags(args5, base) {
|
|
|
18251
18358
|
format: "app",
|
|
18252
18359
|
...base !== null && typeof base === "object" && !Array.isArray(base) ? base : {}
|
|
18253
18360
|
};
|
|
18254
|
-
const headlines =
|
|
18361
|
+
const headlines = copyListFlag(args5.headlines, "headlines");
|
|
18255
18362
|
if (headlines) {
|
|
18256
18363
|
content.headlines = headlines.map((text2) => ({ text: text2 }));
|
|
18257
18364
|
}
|
|
18258
|
-
const descriptions =
|
|
18365
|
+
const descriptions = copyListFlag(args5.descriptions, "descriptions");
|
|
18259
18366
|
if (descriptions) {
|
|
18260
18367
|
content.descriptions = descriptions.map((text2) => ({ text: text2 }));
|
|
18261
18368
|
}
|
|
@@ -18357,10 +18464,13 @@ var adContentArgs = {
|
|
|
18357
18464
|
type: "string",
|
|
18358
18465
|
description: "responsiveSearch (default) | responsiveDisplay | call | app | video | demandGen | demandGenVideo"
|
|
18359
18466
|
},
|
|
18360
|
-
headlines: {
|
|
18467
|
+
headlines: {
|
|
18468
|
+
type: "string",
|
|
18469
|
+
description: `Headlines (RSA/RDA/demandGen/demandGenVideo/app) \u2014 ${AD_COPY_LIST_USAGE}`
|
|
18470
|
+
},
|
|
18361
18471
|
descriptions: {
|
|
18362
18472
|
type: "string",
|
|
18363
|
-
description:
|
|
18473
|
+
description: `Descriptions (RSA/RDA/demandGen/demandGenVideo/app) \u2014 ${AD_COPY_LIST_USAGE}`
|
|
18364
18474
|
},
|
|
18365
18475
|
path1: { type: "string" },
|
|
18366
18476
|
path2: { type: "string" },
|
|
@@ -18371,7 +18481,7 @@ var adContentArgs = {
|
|
|
18371
18481
|
},
|
|
18372
18482
|
"long-headlines": {
|
|
18373
18483
|
type: "string",
|
|
18374
|
-
description:
|
|
18484
|
+
description: `Long headlines, up to 5 of 90 chars (demandGenVideo \u2014 no other format has them) \u2014 ${AD_COPY_LIST_USAGE}`
|
|
18375
18485
|
},
|
|
18376
18486
|
"business-name": { type: "string", description: "Business name (responsiveDisplay/demandGen/demandGenVideo)" },
|
|
18377
18487
|
"marketing-images": {
|
|
@@ -18422,16 +18532,22 @@ var adsCommand = defineCommand31({
|
|
|
18422
18532
|
...adContentArgs,
|
|
18423
18533
|
status: { type: "string" }
|
|
18424
18534
|
},
|
|
18425
|
-
run: async ({ args:
|
|
18535
|
+
run: async ({ args: parsedArgs, rawArgs }) => {
|
|
18536
|
+
const args5 = withRepeatedCopyFlags(parsedArgs, rawArgs);
|
|
18426
18537
|
const customerId = requireCustomerId(args5);
|
|
18427
18538
|
const file = loadJsonFileArg(args5.file);
|
|
18428
18539
|
const format = args5.format ?? "responsiveSearch";
|
|
18429
18540
|
const content = adContentFromFlags(args5, format, file.content);
|
|
18430
|
-
await stageCreate(
|
|
18431
|
-
|
|
18432
|
-
|
|
18433
|
-
|
|
18434
|
-
|
|
18541
|
+
await stageCreate(
|
|
18542
|
+
"google.ad.create",
|
|
18543
|
+
customerId,
|
|
18544
|
+
{
|
|
18545
|
+
adGroup: requireStringFlag(args5["ad-group-ref"] ?? file.adGroup, "--ad-group-ref"),
|
|
18546
|
+
status: args5.status ?? file.status,
|
|
18547
|
+
content
|
|
18548
|
+
},
|
|
18549
|
+
copyListSplitHints(args5)
|
|
18550
|
+
);
|
|
18435
18551
|
}
|
|
18436
18552
|
}),
|
|
18437
18553
|
update: defineCommand31({
|
|
@@ -18440,7 +18556,8 @@ var adsCommand = defineCommand31({
|
|
|
18440
18556
|
description: "Stage an ad update. Any content change needs --format plus EVERY required field of that format (or --file with the complete content) \u2014 a field you send replaces its current value wholesale, so a list you pass must already include the entries you want to keep. Optional asset lists you omit entirely are left untouched on the ad. Status-only changes need neither --format nor content flags."
|
|
18441
18557
|
},
|
|
18442
18558
|
args: { ...customerIdArg, ...fileArg, ...adContentArgs, status: { type: "string" } },
|
|
18443
|
-
run: async ({ args:
|
|
18559
|
+
run: async ({ args: parsedArgs, rawArgs }) => {
|
|
18560
|
+
const args5 = withRepeatedCopyFlags(parsedArgs, rawArgs);
|
|
18444
18561
|
const customerId = requireCustomerId(args5);
|
|
18445
18562
|
const file = loadJsonFileArg(args5.file);
|
|
18446
18563
|
const format = args5.format;
|
|
@@ -18454,7 +18571,8 @@ var adsCommand = defineCommand31({
|
|
|
18454
18571
|
await stageUpdate("google.ad.update", customerId, requireTarget(args5, "ad"), payload, [
|
|
18455
18572
|
...payload.content !== void 0 ? [
|
|
18456
18573
|
"Each content field you sent replaces its current value wholesale at publish \u2014 re-check that every headline, description, final URL and asset you want to KEEP is in this payload, not just the ones you changed."
|
|
18457
|
-
] : []
|
|
18574
|
+
] : [],
|
|
18575
|
+
...format ? copyListSplitHints(args5) : []
|
|
18458
18576
|
]);
|
|
18459
18577
|
}
|
|
18460
18578
|
}),
|
|
@@ -18483,9 +18601,9 @@ var assetGroupsCommand = defineCommand31({
|
|
|
18483
18601
|
},
|
|
18484
18602
|
name: { type: "string", description: "Asset group name" },
|
|
18485
18603
|
"final-urls": { type: "string", description: "Comma-separated final URLs" },
|
|
18486
|
-
headlines: { type: "string", description:
|
|
18487
|
-
"long-headlines": { type: "string", description:
|
|
18488
|
-
descriptions: { type: "string", description:
|
|
18604
|
+
headlines: { type: "string", description: `Headlines (3\u201315, \u226430 chars) \u2014 ${AD_COPY_LIST_USAGE}` },
|
|
18605
|
+
"long-headlines": { type: "string", description: `Long headlines (1\u20135, \u226490 chars) \u2014 ${AD_COPY_LIST_USAGE}` },
|
|
18606
|
+
descriptions: { type: "string", description: `Descriptions (2\u20135, \u226490 chars) \u2014 ${AD_COPY_LIST_USAGE}` },
|
|
18489
18607
|
"business-name": { type: "string" },
|
|
18490
18608
|
"image-assets": { type: "string", description: "Comma-separated marketing image asset refs (1.91:1)" },
|
|
18491
18609
|
"square-image-assets": {
|
|
@@ -18499,11 +18617,12 @@ var assetGroupsCommand = defineCommand31({
|
|
|
18499
18617
|
"logo-assets": { type: "string", description: "Comma-separated logo image asset refs" },
|
|
18500
18618
|
status: { type: "string", description: "ENABLED | PAUSED (default PAUSED)" }
|
|
18501
18619
|
},
|
|
18502
|
-
run: async ({ args:
|
|
18620
|
+
run: async ({ args: parsedArgs, rawArgs }) => {
|
|
18621
|
+
const args5 = withRepeatedCopyFlags(parsedArgs, rawArgs);
|
|
18503
18622
|
const customerId = requireCustomerId(args5);
|
|
18504
|
-
const headlines =
|
|
18505
|
-
const longHeadlines =
|
|
18506
|
-
const descriptions =
|
|
18623
|
+
const headlines = copyListFlag(args5.headlines, "headlines");
|
|
18624
|
+
const longHeadlines = copyListFlag(args5["long-headlines"], "long-headlines");
|
|
18625
|
+
const descriptions = copyListFlag(args5.descriptions, "descriptions");
|
|
18507
18626
|
const payload = mergePayload(loadJsonFileArg(args5.file), {
|
|
18508
18627
|
campaign: args5["campaign-ref"],
|
|
18509
18628
|
name: args5.name,
|
|
@@ -18518,7 +18637,7 @@ var assetGroupsCommand = defineCommand31({
|
|
|
18518
18637
|
logoAssets: listFlag(args5["logo-assets"]),
|
|
18519
18638
|
status: args5.status
|
|
18520
18639
|
});
|
|
18521
|
-
await stageCreate("google.assetGroup.create", customerId, payload);
|
|
18640
|
+
await stageCreate("google.assetGroup.create", customerId, payload, copyListSplitHints(args5));
|
|
18522
18641
|
}
|
|
18523
18642
|
}),
|
|
18524
18643
|
update: defineCommand31({
|
|
@@ -67574,6 +67693,7 @@ function commandFor(root, argv) {
|
|
|
67574
67693
|
const { command, resolved } = resolveCommand2(root, argv);
|
|
67575
67694
|
return resolved ? command : null;
|
|
67576
67695
|
}
|
|
67696
|
+
var OUTPUT_EXPLANATION = "This command has no --output option: `--output json` is accepted by every command that prints the JSON envelope, and md or files only where `baker schema` lists `output`. Drop the option and read the default output. ";
|
|
67577
67697
|
function unknownFlagEnvelope(unknown, commandPath, suggestion, hasSchema) {
|
|
67578
67698
|
const list = unknown.join(", ");
|
|
67579
67699
|
return {
|
|
@@ -67583,7 +67703,7 @@ function unknownFlagEnvelope(unknown, commandPath, suggestion, hasSchema) {
|
|
|
67583
67703
|
message: `${list} ${unknown.length > 1 ? "are not options" : "is not an option"} of \`baker ${commandPath}\`.`,
|
|
67584
67704
|
fix: {
|
|
67585
67705
|
action: hasSchema ? "check_schema" : "check_help",
|
|
67586
|
-
explanation: (suggestion ? `Did you mean ${suggestion}? ` : "") + `Run \`${hasSchema ? `baker schema ${commandPath}` : `baker ${commandPath} --help`}\` to see every option this command takes. Do not re-run the same call: until this version an unrecognised option was accepted and ignored, so a command that looked like it had filtered or narrowed the result was in fact answering the unfiltered question.`
|
|
67706
|
+
explanation: (unknown.some((flag) => flag === "--output" || flag.startsWith("--output=")) ? OUTPUT_EXPLANATION : "") + (suggestion ? `Did you mean ${suggestion}? ` : "") + `Run \`${hasSchema ? `baker schema ${commandPath}` : `baker ${commandPath} --help`}\` to see every option this command takes. Do not re-run the same call: until this version an unrecognised option was accepted and ignored, so a command that looked like it had filtered or narrowed the result was in fact answering the unfiltered question.`
|
|
67587
67707
|
},
|
|
67588
67708
|
retryable: false
|
|
67589
67709
|
}
|
|
@@ -67622,6 +67742,53 @@ function refuseUnknownFlags(root, argv) {
|
|
|
67622
67742
|
process.exit(1);
|
|
67623
67743
|
}
|
|
67624
67744
|
|
|
67745
|
+
// src/output-flag.ts
|
|
67746
|
+
var FLAG = "--output";
|
|
67747
|
+
var ENVELOPE = "json";
|
|
67748
|
+
var PRINTS_NO_ENVELOPE = /* @__PURE__ */ new Set(["analytics sending-events", "canvas run", "canvas rerun"]);
|
|
67749
|
+
function declaredArg(command, name) {
|
|
67750
|
+
const args5 = command.args;
|
|
67751
|
+
if (!args5 || typeof args5 !== "object" || !(name in args5)) {
|
|
67752
|
+
return null;
|
|
67753
|
+
}
|
|
67754
|
+
const def = args5[name];
|
|
67755
|
+
return def && typeof def === "object" ? def : {};
|
|
67756
|
+
}
|
|
67757
|
+
function envelopeRequests(argv) {
|
|
67758
|
+
const end = argv.indexOf("--");
|
|
67759
|
+
const limit = end === -1 ? argv.length : end;
|
|
67760
|
+
const found = [];
|
|
67761
|
+
for (let index = 0; index < limit; index++) {
|
|
67762
|
+
const token = argv[index];
|
|
67763
|
+
if (token === `${FLAG}=${ENVELOPE}`) {
|
|
67764
|
+
found.push({ index, length: 1 });
|
|
67765
|
+
} else if (token === FLAG && argv[index + 1] === ENVELOPE && index + 1 < limit) {
|
|
67766
|
+
found.push({ index, length: 2 });
|
|
67767
|
+
index++;
|
|
67768
|
+
}
|
|
67769
|
+
}
|
|
67770
|
+
return found;
|
|
67771
|
+
}
|
|
67772
|
+
function outputFlagForCommand(root, argv) {
|
|
67773
|
+
const requests = envelopeRequests(argv);
|
|
67774
|
+
if (requests.length === 0) {
|
|
67775
|
+
return argv;
|
|
67776
|
+
}
|
|
67777
|
+
const command = commandFor(root, argv);
|
|
67778
|
+
if (!command || declaredArg(command, "output") || PRINTS_NO_ENVELOPE.has(commandPathOf(root, argv))) {
|
|
67779
|
+
return argv;
|
|
67780
|
+
}
|
|
67781
|
+
const jsonSwitch = declaredArg(command, "json")?.type === "boolean";
|
|
67782
|
+
const dropped = new Set(requests.flatMap(({ index, length }) => length === 2 ? [index, index + 1] : [index]));
|
|
67783
|
+
const first = requests[0]?.index;
|
|
67784
|
+
return argv.flatMap((token, index) => {
|
|
67785
|
+
if (!dropped.has(index)) {
|
|
67786
|
+
return [token];
|
|
67787
|
+
}
|
|
67788
|
+
return jsonSwitch && index === first ? ["--json"] : [];
|
|
67789
|
+
});
|
|
67790
|
+
}
|
|
67791
|
+
|
|
67625
67792
|
// src/version.ts
|
|
67626
67793
|
import { readFileSync as readFileSync21 } from "fs";
|
|
67627
67794
|
function packageJsonUrl() {
|
|
@@ -67648,7 +67815,7 @@ var main = defineCommand245({
|
|
|
67648
67815
|
Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
|
|
67649
67816
|
Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
|
|
67650
67817
|
Output: All commands return JSON envelopes: { ok: true, data: ... } or { ok: false, error: { code, message } }.
|
|
67651
|
-
Formats:
|
|
67818
|
+
Formats: --output json works on every command that prints the envelope. --output md|files only where 'baker schema <command>' lists output. (The research commands additionally accept csv and jsonl.)
|
|
67652
67819
|
Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
67653
67820
|
},
|
|
67654
67821
|
subCommands: {
|
|
@@ -67686,6 +67853,7 @@ process.argv = [...process.argv.slice(0, 2), ...normalizeCacheFlag(process.argv.
|
|
|
67686
67853
|
installStreamTaps();
|
|
67687
67854
|
logInvocation(process.argv.slice(2));
|
|
67688
67855
|
installExitRecord();
|
|
67856
|
+
process.argv = [...process.argv.slice(0, 2), ...outputFlagForCommand(main, process.argv.slice(2))];
|
|
67689
67857
|
refuseUnknownFlags(main, process.argv.slice(2));
|
|
67690
67858
|
process.argv = [...process.argv.slice(0, 2), ...cacheFlagForParser(process.argv.slice(2))];
|
|
67691
67859
|
runMain(main);
|