@koda-sl/baker-cli 0.154.0 → 0.156.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.
- package/README.md +8 -1
- package/dist/{chunk-UFBKUMN2.js → chunk-JOPBGFXC.js} +2 -2
- package/dist/{chunk-FBUVCOH6.js → chunk-R4PG6VCS.js} +71 -44
- package/dist/chunk-R4PG6VCS.js.map +1 -0
- package/dist/cli.js +760 -102
- package/dist/cli.js.map +1 -1
- package/dist/{output-R534QTMO.js → output-KLK2GZXR.js} +2 -2
- package/dist/{shared-MUWU7BK5.js → shared-AXAXNKGE.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-FBUVCOH6.js.map +0 -1
- /package/dist/{chunk-UFBKUMN2.js.map → chunk-JOPBGFXC.js.map} +0 -0
- /package/dist/{output-R534QTMO.js.map → output-KLK2GZXR.js.map} +0 -0
- /package/dist/{shared-MUWU7BK5.js.map → shared-AXAXNKGE.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -45,20 +45,22 @@ import {
|
|
|
45
45
|
resolveAccountIdArg,
|
|
46
46
|
resolveEffectiveStatus,
|
|
47
47
|
todayIso
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-JOPBGFXC.js";
|
|
49
49
|
import {
|
|
50
50
|
buildQueryCacheKey,
|
|
51
51
|
cacheGet,
|
|
52
52
|
cacheSet,
|
|
53
|
+
connectionFixExplanation,
|
|
53
54
|
getManagerIdForCustomer,
|
|
54
55
|
getQueryTtl,
|
|
55
56
|
handleConnectionError,
|
|
57
|
+
isNotConnectedError,
|
|
56
58
|
resolveCustomerId,
|
|
57
59
|
toCsvRow,
|
|
58
60
|
writeAdsJson,
|
|
59
61
|
writeAdsOutput,
|
|
60
62
|
writeJsonEnvelope
|
|
61
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-R4PG6VCS.js";
|
|
62
64
|
import {
|
|
63
65
|
ApiError,
|
|
64
66
|
apiGet,
|
|
@@ -75,7 +77,7 @@ import {
|
|
|
75
77
|
} from "./chunk-RK67WL4O.js";
|
|
76
78
|
|
|
77
79
|
// src/cli.ts
|
|
78
|
-
import { defineCommand as
|
|
80
|
+
import { defineCommand as defineCommand185, runMain } from "citty";
|
|
79
81
|
|
|
80
82
|
// src/commands/actions/index.ts
|
|
81
83
|
import { defineCommand as defineCommand18 } from "citty";
|
|
@@ -492,6 +494,141 @@ function looksScheduled(name, description) {
|
|
|
492
494
|
${description}`;
|
|
493
495
|
return SCHEDULE_SIGNALS.some((re) => re.test(haystack));
|
|
494
496
|
}
|
|
497
|
+
var SURFACE_RULES = [
|
|
498
|
+
{
|
|
499
|
+
surface: "analysis",
|
|
500
|
+
nameOnly: true,
|
|
501
|
+
signals: [
|
|
502
|
+
/^\s*(?:re-?)?(?:investigate|analyse|analyze|audit|review|document|assess|evaluate|research|map|inventory|examine|diagnose)\b/i
|
|
503
|
+
],
|
|
504
|
+
hint: "This names the analysis itself \u2014 investigating, auditing and documenting are work you do now, not work you file. Run it in this chat and deliver the finding; a Task is for a fix something genuinely blocks (bar: `__tooling__/docs/tools/baker/actions.md`)."
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
surface: "ask-user",
|
|
508
|
+
signals: [
|
|
509
|
+
/\bproduction\s+(?:domain|url|site|hostname)\b/i,
|
|
510
|
+
/\b(?:confirm|check|verify)\s+(?:with|w\/)\s+(?:the\s+)?(?:client|user|customer|team)\b/i,
|
|
511
|
+
/\bmissing\s+(?:the\s+)?(?:value|values|id|ids|url|budget|domain|credentials?|account\s+id|measurement\s+id)\b/i,
|
|
512
|
+
/\b(?:ask|get)\s+(?:the\s+)?(?:client|user)\s+for\b/i
|
|
513
|
+
],
|
|
514
|
+
hint: "This is a missing input, not blocked work. Ask for it with AskUserQuestion (one question), then do the work in the same turn \u2014 filing the Task AND asking the question is the same request twice."
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
surface: "tag-manager",
|
|
518
|
+
signals: [
|
|
519
|
+
/\bgtm\b/i,
|
|
520
|
+
/\btag\s*manager\b/i,
|
|
521
|
+
/\bdata\s*layer\b/i,
|
|
522
|
+
/\bfiring\s+trigger\b/i,
|
|
523
|
+
/\bbuilt-?in\s+variables?\b/i,
|
|
524
|
+
/\bconsent\s+(?:mode|settings?|state)\b/i,
|
|
525
|
+
/\bga4\s+(?:config|configuration|event)\b/i,
|
|
526
|
+
/\bcontainer\s+(?:tag|trigger|variable)s?\b/i,
|
|
527
|
+
/\b(?:conversion|form|submit|submission|click|purchase|lead|custom)\s+event\b/i,
|
|
528
|
+
/\btrack\w*\b[\s\S]*\bevent\b/i
|
|
529
|
+
],
|
|
530
|
+
except: [/\bserver-?\s?side\b/i, /\bsgtm\b/i, /\bhosting\b/i],
|
|
531
|
+
hint: "This is a change inside the GTM container \u2014 `baker tag-manager` stages it now and it applies at publish (guide: `__tooling__/docs/tools/baker/tag-manager.md`). Stage it instead of filing it, and if several container fixes really are blocked, they belong in ONE Task, not one per finding."
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
surface: "site-tags",
|
|
535
|
+
signals: [
|
|
536
|
+
/\bpixel\b/i,
|
|
537
|
+
/\binsight\s+tag\b/i,
|
|
538
|
+
/\bclarity\b/i,
|
|
539
|
+
/\bhotjar\b/i,
|
|
540
|
+
/\bgtm\s+snippet\b/i,
|
|
541
|
+
/\b(?:install|add|remove|swap)\b[\s\S]*\b(?:snippet|script|tag)\b/i
|
|
542
|
+
],
|
|
543
|
+
hint: "This is a tag or script on the site \u2014 it goes through the `request_tag_input` approval form in this chat, which also collects any secret values (guide: `__tooling__/docs/tools/baker/tags.md`). Show the form instead of filing a Task."
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
surface: "ads-write",
|
|
547
|
+
signals: [
|
|
548
|
+
/\b(?:pause|unpause|enable|disable|launch|restructure|duplicate|clone|rebuild)\b[\s\S]*\b(?:campaign|ad\s*set|ad\s*group|adgroup)\b/i,
|
|
549
|
+
/\b(?:tcpa|troas|target\s+cpa|target\s+roas)\b/i,
|
|
550
|
+
/\b(?:daily|campaign|lifetime|ad\s*set)\s+budget\b/i,
|
|
551
|
+
/\b(?:raise|lower|increase|decrease|adjust|change|set|update)\s+(?:the\s+)?budget\b/i,
|
|
552
|
+
/\bbid\s+strateg/i,
|
|
553
|
+
/\bnegative\s+keywords?\b/i,
|
|
554
|
+
/\b(?:lookalike|custom)\s+audience\b/i,
|
|
555
|
+
/\bswap\s+(?:the\s+)?creative\b/i
|
|
556
|
+
],
|
|
557
|
+
hint: "This is an ad-platform change the write surface covers \u2014 stage it now with `baker ads google|meta|linkedin` and it applies at publish (guides: `__tooling__/docs/tools/baker/ads-google.md`, `__tooling__/docs/tools/baker/ads-meta.md`, `__tooling__/docs/tools/baker/ads-linkedin.md`). Staging is not going live."
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
surface: "landing",
|
|
561
|
+
signals: [
|
|
562
|
+
/\b(?:landing\s+page|hero|headline|above\s+the\s+fold)\b/i,
|
|
563
|
+
/\b(?:rewrite|tighten|restyle)\b[\s\S]*\b(?:copy|page|section)\b/i
|
|
564
|
+
],
|
|
565
|
+
hint: "This is a page change \u2014 build it in this chat with the `/landing` skill. Only file it if something outside the page blocks the work."
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
surface: "flow",
|
|
569
|
+
signals: [/\b(?:form|flow)\s+(?:step|steps|branching|logic|redirect|behaviou?r)\b/i, /\bthank\s*you\s+redirect\b/i],
|
|
570
|
+
hint: "This is form behaviour \u2014 change it in this chat with the `/flow-builder` skill. Only file it if something outside the form blocks the work."
|
|
571
|
+
}
|
|
572
|
+
];
|
|
573
|
+
var FAN_OUT_THRESHOLD = 3;
|
|
574
|
+
var SCHEDULED_HINT = 'This reads as recurring/scheduled work. If it should run on a cadence or a future date, create a Scheduled Action instead \u2014 baker scheduled-actions create --cron "0 9 * * MON" (or --run-at; guide: `__tooling__/docs/tools/baker/scheduled-actions.md`). Do NOT capture "set up a scheduled action" as a Work Action.';
|
|
575
|
+
function looksExecutable(name, description) {
|
|
576
|
+
const full = `${name}
|
|
577
|
+
${description}`;
|
|
578
|
+
for (const rule of SURFACE_RULES) {
|
|
579
|
+
const haystack = rule.nameOnly ? name : full;
|
|
580
|
+
if (rule.except?.some((re) => re.test(full))) {
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
if (rule.signals.some((re) => re.test(haystack))) {
|
|
584
|
+
return { surface: rule.surface, hint: rule.hint };
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
function buildCreateHints({
|
|
590
|
+
name,
|
|
591
|
+
description,
|
|
592
|
+
tempId,
|
|
593
|
+
tags,
|
|
594
|
+
prioritySet,
|
|
595
|
+
draftCreateCount
|
|
596
|
+
}) {
|
|
597
|
+
const hints = [];
|
|
598
|
+
const advisory = advisoryHint(name, description);
|
|
599
|
+
if (advisory) {
|
|
600
|
+
hints.push(
|
|
601
|
+
`${advisory.hint} If nothing actually blocks it: baker actions draft remove ${tempId}, then do the work.`
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
if (draftCreateCount >= FAN_OUT_THRESHOLD) {
|
|
605
|
+
hints.push(
|
|
606
|
+
`${draftCreateCount} Tasks are staged in this chat. Re-read them with \`baker actions draft\`: can any be done now with a surface you already have, and do any two touch the same system (same container, same campaign, same page)? Those belong in ONE Task \u2014 fold them together with \`baker actions update\` and drop the extras with \`baker actions draft remove <tempId>\`.`
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
hints.push(`Link dependencies: baker actions link --blocker <id> --blocked ${tempId}`);
|
|
610
|
+
if (!description) {
|
|
611
|
+
hints.push("Add description: baker actions update <tempId> --description '...' (what/why/where/done-when)");
|
|
612
|
+
}
|
|
613
|
+
if (!tags || tags.length === 0) {
|
|
614
|
+
hints.push(
|
|
615
|
+
"MISSING --tags. This action is invisible to the backlog's tag filter. Re-run with --tags <slug,...> (`baker actions tags list` for the taxonomy, `baker actions tags create --slug <slug>` to mint) \u2014 or `baker actions update <tempId> --tags <slug,...>`."
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
if (!prioritySet) {
|
|
619
|
+
hints.push(
|
|
620
|
+
`MISSING --priority. Without it this action ranks as 'normal' (medium) in the do-first ordering, so urgent/high client work won't surface first. Re-run with --priority ${ACTION_PRIORITIES.join("|")} \u2014 or \`baker actions update <tempId> --priority <level>\`.`
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
return hints;
|
|
624
|
+
}
|
|
625
|
+
function advisoryHint(name, description) {
|
|
626
|
+
if (looksScheduled(name, description)) {
|
|
627
|
+
return { kind: "scheduled", hint: SCHEDULED_HINT };
|
|
628
|
+
}
|
|
629
|
+
const executable = looksExecutable(name, description);
|
|
630
|
+
return executable ? { kind: "executable", ...executable } : null;
|
|
631
|
+
}
|
|
495
632
|
|
|
496
633
|
// src/commands/actions/skillCatalog.ts
|
|
497
634
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
@@ -811,7 +948,9 @@ var actionsCreateRequestSchema = z.object({
|
|
|
811
948
|
tags: z.array(z.string()).optional(),
|
|
812
949
|
priority: actionPrioritySchema.optional()
|
|
813
950
|
});
|
|
814
|
-
var actionsCreateResponseSchema = okResponse(
|
|
951
|
+
var actionsCreateResponseSchema = okResponse(
|
|
952
|
+
z.object({ tempId: z.string(), draftCreateCount: z.number().optional() })
|
|
953
|
+
);
|
|
815
954
|
var actionsGetRequestSchema = z.object({ actionId: z.string().min(1) });
|
|
816
955
|
var actionsGetResponseSchema = okResponse(actionDetailSchema.nullable());
|
|
817
956
|
var actionsListRequestSchema = z.object({
|
|
@@ -2184,6 +2323,7 @@ var chatChangeTypeSchema = z5.enum([
|
|
|
2184
2323
|
"linkedin-ads",
|
|
2185
2324
|
"google-ads",
|
|
2186
2325
|
"meta-ads",
|
|
2326
|
+
"tag-manager",
|
|
2187
2327
|
// Immediate (already-applied) library effects — see lib/chatChanges.ts.
|
|
2188
2328
|
"image",
|
|
2189
2329
|
"video",
|
|
@@ -2521,7 +2661,8 @@ var historyCategorySchema = z7.enum([
|
|
|
2521
2661
|
"creative",
|
|
2522
2662
|
"report",
|
|
2523
2663
|
"domain",
|
|
2524
|
-
"integration"
|
|
2664
|
+
"integration",
|
|
2665
|
+
"tag_manager"
|
|
2525
2666
|
]);
|
|
2526
2667
|
var historyListRequestSchema = z7.object({
|
|
2527
2668
|
limit: z7.number().int().min(1).max(200).optional(),
|
|
@@ -3376,27 +3517,17 @@ var createCommand = defineCommand3({
|
|
|
3376
3517
|
...tags ? { tags } : {},
|
|
3377
3518
|
...priority !== void 0 && priority !== null ? { priority } : {}
|
|
3378
3519
|
});
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
hints
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
hints.push(
|
|
3391
|
-
"MISSING --tags. This action is invisible to the backlog's tag filter. Re-run with --tags <slug,...> (`baker actions tags list` for the taxonomy, `baker actions tags create --slug <slug>` to mint) \u2014 or `baker actions update <tempId> --tags <slug,...>`."
|
|
3392
|
-
);
|
|
3393
|
-
}
|
|
3394
|
-
if (priority === void 0) {
|
|
3395
|
-
hints.push(
|
|
3396
|
-
`MISSING --priority. Without it this action ranks as 'normal' (medium) in the do-first ordering, so urgent/high client work won't surface first. Re-run with --priority ${ACTION_PRIORITIES.join("|")} \u2014 or \`baker actions update <tempId> --priority <level>\`.`
|
|
3397
|
-
);
|
|
3398
|
-
}
|
|
3399
|
-
writeJson({ ...response, hints });
|
|
3520
|
+
writeJson({
|
|
3521
|
+
...response,
|
|
3522
|
+
hints: buildCreateHints({
|
|
3523
|
+
name,
|
|
3524
|
+
description: args.description ?? "",
|
|
3525
|
+
tempId,
|
|
3526
|
+
tags,
|
|
3527
|
+
prioritySet: priority !== void 0,
|
|
3528
|
+
draftCreateCount: response.data.draftCreateCount ?? 0
|
|
3529
|
+
})
|
|
3530
|
+
});
|
|
3400
3531
|
} catch (err) {
|
|
3401
3532
|
failApi(err);
|
|
3402
3533
|
}
|
|
@@ -5696,12 +5827,23 @@ function getRetryDelay(code) {
|
|
|
5696
5827
|
if (code === "TIMEOUT") return 5e3;
|
|
5697
5828
|
return void 0;
|
|
5698
5829
|
}
|
|
5699
|
-
function parseApiError(errorMessage, originalQuery, customerId) {
|
|
5830
|
+
function parseApiError(errorMessage, originalQuery, customerId, apiCode) {
|
|
5700
5831
|
const ctx = {
|
|
5701
5832
|
originalQuery,
|
|
5702
5833
|
customerId,
|
|
5703
5834
|
apiErrorMessage: errorMessage
|
|
5704
5835
|
};
|
|
5836
|
+
if (apiCode && isNotConnectedError(apiCode, errorMessage)) {
|
|
5837
|
+
return {
|
|
5838
|
+
ok: false,
|
|
5839
|
+
error: {
|
|
5840
|
+
code: "NO_GOOGLE_ADS_CONNECTION",
|
|
5841
|
+
message: errorMessage,
|
|
5842
|
+
fix: { action: "request_connection", explanation: connectionFixExplanation("google_ads") },
|
|
5843
|
+
retryable: false
|
|
5844
|
+
}
|
|
5845
|
+
};
|
|
5846
|
+
}
|
|
5705
5847
|
for (const rule of CORRECTION_RULES) {
|
|
5706
5848
|
if (rule.matchApiError?.test(errorMessage)) {
|
|
5707
5849
|
const fix = rule.fix(ctx);
|
|
@@ -5841,7 +5983,7 @@ Examples:
|
|
|
5841
5983
|
writeJsonEnvelope({ ok: true, data, fields: fieldDescs, hints: window.hints });
|
|
5842
5984
|
} catch (err) {
|
|
5843
5985
|
if (err instanceof ApiError) {
|
|
5844
|
-
writeAdsJson(parseApiError(err.message, "", customerId));
|
|
5986
|
+
writeAdsJson(parseApiError(err.message, "", customerId, err.code));
|
|
5845
5987
|
process.exit(1);
|
|
5846
5988
|
}
|
|
5847
5989
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
@@ -5902,7 +6044,7 @@ Examples:
|
|
|
5902
6044
|
writeAdsJson({ ok: true, data });
|
|
5903
6045
|
} catch (err) {
|
|
5904
6046
|
if (err instanceof ApiError) {
|
|
5905
|
-
writeAdsJson(parseApiError(err.message, "", customerId));
|
|
6047
|
+
writeAdsJson(parseApiError(err.message, "", customerId, err.code));
|
|
5906
6048
|
process.exit(1);
|
|
5907
6049
|
}
|
|
5908
6050
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
@@ -6156,6 +6298,9 @@ function loadPatchArg(args) {
|
|
|
6156
6298
|
}
|
|
6157
6299
|
function handleGoogleError(err) {
|
|
6158
6300
|
if (err instanceof ApiError) {
|
|
6301
|
+
if (isNotConnectedError(err.code, err.message)) {
|
|
6302
|
+
handleConnectionError("google_ads", err.message);
|
|
6303
|
+
}
|
|
6159
6304
|
writeJsonEnvelope({ ok: false, error: { code: err.code ?? "API_ERROR", message: err.message } });
|
|
6160
6305
|
process.exit(1);
|
|
6161
6306
|
}
|
|
@@ -6594,6 +6739,9 @@ function buildDiscoverBody(customerId, args) {
|
|
|
6594
6739
|
}
|
|
6595
6740
|
function handleKeywordError(err) {
|
|
6596
6741
|
if (err instanceof ApiError) {
|
|
6742
|
+
if (isNotConnectedError(err.code, err.message)) {
|
|
6743
|
+
handleConnectionError("google_ads", err.message);
|
|
6744
|
+
}
|
|
6597
6745
|
const envelope = {
|
|
6598
6746
|
ok: false,
|
|
6599
6747
|
error: {
|
|
@@ -6737,6 +6885,26 @@ registerSchema({
|
|
|
6737
6885
|
output: { type: "string", description: "Format: json|csv|jsonl|md", required: false, default: "json" }
|
|
6738
6886
|
}
|
|
6739
6887
|
});
|
|
6888
|
+
function handleMetricsError(err) {
|
|
6889
|
+
if (err instanceof ApiError) {
|
|
6890
|
+
if (isNotConnectedError(err.code, err.message)) {
|
|
6891
|
+
handleConnectionError("google_ads", err.message);
|
|
6892
|
+
}
|
|
6893
|
+
const envelope = {
|
|
6894
|
+
ok: false,
|
|
6895
|
+
error: {
|
|
6896
|
+
code: err.code,
|
|
6897
|
+
message: err.message,
|
|
6898
|
+
fix: { action: "reject", explanation: err.message },
|
|
6899
|
+
retryable: err.code === "RATE_LIMITED"
|
|
6900
|
+
}
|
|
6901
|
+
};
|
|
6902
|
+
writeAdsJson(envelope);
|
|
6903
|
+
process.exit(1);
|
|
6904
|
+
}
|
|
6905
|
+
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
6906
|
+
process.exit(1);
|
|
6907
|
+
}
|
|
6740
6908
|
var metricsCommand = defineCommand26({
|
|
6741
6909
|
meta: {
|
|
6742
6910
|
name: "metrics",
|
|
@@ -6804,21 +6972,7 @@ Examples:
|
|
|
6804
6972
|
};
|
|
6805
6973
|
writeAdsJson({ ok: true, data, fields, query_context: queryContext });
|
|
6806
6974
|
} catch (err) {
|
|
6807
|
-
|
|
6808
|
-
const envelope = {
|
|
6809
|
-
ok: false,
|
|
6810
|
-
error: {
|
|
6811
|
-
code: err.code,
|
|
6812
|
-
message: err.message,
|
|
6813
|
-
fix: { action: "reject", explanation: err.message },
|
|
6814
|
-
retryable: err.code === "RATE_LIMITED"
|
|
6815
|
-
}
|
|
6816
|
-
};
|
|
6817
|
-
writeAdsJson(envelope);
|
|
6818
|
-
process.exit(1);
|
|
6819
|
-
}
|
|
6820
|
-
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
|
|
6821
|
-
process.exit(1);
|
|
6975
|
+
handleMetricsError(err);
|
|
6822
6976
|
}
|
|
6823
6977
|
}
|
|
6824
6978
|
});
|
|
@@ -7385,7 +7539,7 @@ async function validateArgs(args) {
|
|
|
7385
7539
|
}
|
|
7386
7540
|
function handleQueryError(err, finalQuery, customerId) {
|
|
7387
7541
|
if (err instanceof ApiError) {
|
|
7388
|
-
const envelope = parseApiError(err.message, finalQuery, customerId);
|
|
7542
|
+
const envelope = parseApiError(err.message, finalQuery, customerId, err.code);
|
|
7389
7543
|
envelope.error.gaqlExecuted = finalQuery;
|
|
7390
7544
|
writeAdsJson(envelope);
|
|
7391
7545
|
process.exit(1);
|
|
@@ -8990,6 +9144,9 @@ function handleLinkedinError(err) {
|
|
|
8990
9144
|
if (err.code === "NOT_FOUND") {
|
|
8991
9145
|
handleConnectionError("linkedin_ads", err.message);
|
|
8992
9146
|
}
|
|
9147
|
+
if (isNoAccountsSelectedError(err.code, err.message)) {
|
|
9148
|
+
handleConnectionError("linkedin_ads", err.message);
|
|
9149
|
+
}
|
|
8993
9150
|
const explanation = explainLinkedinError(err);
|
|
8994
9151
|
const envelope = {
|
|
8995
9152
|
ok: false,
|
|
@@ -9011,6 +9168,9 @@ function handleLinkedinError(err) {
|
|
|
9011
9168
|
writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message } });
|
|
9012
9169
|
process.exit(1);
|
|
9013
9170
|
}
|
|
9171
|
+
function isNoAccountsSelectedError(code, message) {
|
|
9172
|
+
return code === "VALIDATION_ERROR" && /no linkedin ad accounts selected/i.test(message);
|
|
9173
|
+
}
|
|
9014
9174
|
function explainLinkedinError(err) {
|
|
9015
9175
|
const lower = err.message.toLowerCase();
|
|
9016
9176
|
if (err.code === "VALIDATION_ERROR" && lower.includes("granularity") && lower.includes("daily")) {
|
|
@@ -13382,8 +13542,8 @@ function duplicateCommand2(entity, label) {
|
|
|
13382
13542
|
run: async ({ args }) => {
|
|
13383
13543
|
const { apiPost: apiPost2 } = await import("./client-R5ZSVIK3.js");
|
|
13384
13544
|
const { requireChatId: requireChatId2 } = await import("./env-3JMYIH25.js");
|
|
13385
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
13386
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
13545
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-KLK2GZXR.js");
|
|
13546
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-AXAXNKGE.js");
|
|
13387
13547
|
try {
|
|
13388
13548
|
const accountId = bareAccountId2(args);
|
|
13389
13549
|
const chatId = requireChatId2();
|
|
@@ -23550,7 +23710,10 @@ ${list}`
|
|
|
23550
23710
|
}
|
|
23551
23711
|
});
|
|
23552
23712
|
process.exit(1);
|
|
23553
|
-
} catch {
|
|
23713
|
+
} catch (err) {
|
|
23714
|
+
if (err instanceof ApiError && (err.code === "UNAUTHORIZED" || err.code === "NOT_FOUND")) {
|
|
23715
|
+
handleConnectionError("ga4", err.message);
|
|
23716
|
+
}
|
|
23554
23717
|
writeJsonEnvelope({
|
|
23555
23718
|
ok: false,
|
|
23556
23719
|
error: {
|
|
@@ -23613,6 +23776,9 @@ Examples:
|
|
|
23613
23776
|
writeJsonEnvelope(data);
|
|
23614
23777
|
} catch (err) {
|
|
23615
23778
|
if (err instanceof ApiError) {
|
|
23779
|
+
if (isNotConnectedError(err.code, err.message)) {
|
|
23780
|
+
handleConnectionError("ga4", err.message);
|
|
23781
|
+
}
|
|
23616
23782
|
writeJsonEnvelope({ ok: false, error: { code: err.code, message: err.message } });
|
|
23617
23783
|
process.exit(1);
|
|
23618
23784
|
}
|
|
@@ -23804,6 +23970,9 @@ function buildRequestBody(args, propertyId, useCache) {
|
|
|
23804
23970
|
}
|
|
23805
23971
|
function handleError(err) {
|
|
23806
23972
|
if (err instanceof ApiError) {
|
|
23973
|
+
if (isNotConnectedError(err.code, err.message)) {
|
|
23974
|
+
handleConnectionError("ga4", err.message);
|
|
23975
|
+
}
|
|
23807
23976
|
writeJsonEnvelope({ ok: false, error: { code: err.code, message: err.message } });
|
|
23808
23977
|
process.exit(1);
|
|
23809
23978
|
}
|
|
@@ -23990,7 +24159,10 @@ ${list}`
|
|
|
23990
24159
|
}
|
|
23991
24160
|
});
|
|
23992
24161
|
process.exit(1);
|
|
23993
|
-
} catch {
|
|
24162
|
+
} catch (err) {
|
|
24163
|
+
if (err instanceof ApiError && (err.code === "UNAUTHORIZED" || err.code === "NOT_FOUND")) {
|
|
24164
|
+
handleConnectionError("gsc", err.message);
|
|
24165
|
+
}
|
|
23994
24166
|
writeJsonEnvelope({
|
|
23995
24167
|
ok: false,
|
|
23996
24168
|
error: {
|
|
@@ -24092,6 +24264,9 @@ function buildRequestBody2(args, siteUrl, useCache) {
|
|
|
24092
24264
|
}
|
|
24093
24265
|
function handleError2(err) {
|
|
24094
24266
|
if (err instanceof ApiError) {
|
|
24267
|
+
if (isNotConnectedError(err.code, err.message)) {
|
|
24268
|
+
handleConnectionError("gsc", err.message);
|
|
24269
|
+
}
|
|
24095
24270
|
writeJsonEnvelope({ ok: false, error: { code: err.code, message: err.message } });
|
|
24096
24271
|
process.exit(1);
|
|
24097
24272
|
}
|
|
@@ -24228,6 +24403,9 @@ Examples:
|
|
|
24228
24403
|
writeJsonEnvelope({ ok: true, data });
|
|
24229
24404
|
} catch (err) {
|
|
24230
24405
|
if (err instanceof ApiError) {
|
|
24406
|
+
if (isNotConnectedError(err.code, err.message)) {
|
|
24407
|
+
handleConnectionError("gsc", err.message);
|
|
24408
|
+
}
|
|
24231
24409
|
writeJsonEnvelope({ ok: false, error: { code: err.code, message: err.message } });
|
|
24232
24410
|
process.exit(1);
|
|
24233
24411
|
}
|
|
@@ -30234,9 +30412,488 @@ var schemaCommand = defineCommand157({
|
|
|
30234
30412
|
}
|
|
30235
30413
|
});
|
|
30236
30414
|
|
|
30237
|
-
// src/commands/
|
|
30415
|
+
// src/commands/tag-manager/index.ts
|
|
30416
|
+
import { defineCommand as defineCommand161 } from "citty";
|
|
30417
|
+
|
|
30418
|
+
// src/commands/tag-manager/draft.ts
|
|
30238
30419
|
import { defineCommand as defineCommand158 } from "citty";
|
|
30239
30420
|
|
|
30421
|
+
// src/commands/tag-manager/shared.ts
|
|
30422
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
30423
|
+
function failValidation3(message) {
|
|
30424
|
+
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
30425
|
+
process.exit(1);
|
|
30426
|
+
}
|
|
30427
|
+
function requireTarget4(args, entity) {
|
|
30428
|
+
const positional = Array.isArray(args._) ? args._[0] : void 0;
|
|
30429
|
+
const target = args.id ?? args.target ?? positional;
|
|
30430
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
30431
|
+
failValidation3(`pass the ${entity} id or path as the positional argument`);
|
|
30432
|
+
}
|
|
30433
|
+
return target;
|
|
30434
|
+
}
|
|
30435
|
+
function loadJsonArg(args, flag = "json") {
|
|
30436
|
+
const inline = args[flag];
|
|
30437
|
+
const file = args.file;
|
|
30438
|
+
const raw = typeof file === "string" && file.length > 0 ? readFileSync12(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
|
|
30439
|
+
if (raw === void 0) {
|
|
30440
|
+
failValidation3(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
|
|
30441
|
+
}
|
|
30442
|
+
try {
|
|
30443
|
+
const parsed = JSON.parse(raw);
|
|
30444
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
30445
|
+
failValidation3(`--${flag} must be a JSON object`);
|
|
30446
|
+
}
|
|
30447
|
+
return parsed;
|
|
30448
|
+
} catch {
|
|
30449
|
+
return failValidation3(`--${flag} is not valid JSON`);
|
|
30450
|
+
}
|
|
30451
|
+
}
|
|
30452
|
+
var RETRYABLE_CODES = /* @__PURE__ */ new Set(["RATE_LIMITED", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
|
|
30453
|
+
function handleError3(err) {
|
|
30454
|
+
if (err instanceof ApiError) {
|
|
30455
|
+
writeJsonEnvelope({
|
|
30456
|
+
ok: false,
|
|
30457
|
+
error: {
|
|
30458
|
+
code: err.code,
|
|
30459
|
+
message: err.message,
|
|
30460
|
+
...err.code === "UNAUTHORIZED" ? {
|
|
30461
|
+
fix: {
|
|
30462
|
+
action: "request_connection",
|
|
30463
|
+
explanation: 'Tag Manager is not connected for this company yet, or no container has been picked. Do NOT send the user to Settings \u2014 call the `request_connection` tool with { platform: "google-tag-manager", reason } and they connect and pick the container from inside the chat. `request_tag_input` is NOT the route: that form manages the container snippet on the site, not what runs inside the container, and it cannot pick a container. If `request_connection` is not available to you, say so plainly and point them at dashboard \u2192 Brain \u2192 Integrations \u2192 Tools \u2192 Google Tag Manager, where they also pick the container. Carry on with the rest of the task meanwhile.'
|
|
30464
|
+
}
|
|
30465
|
+
} : {},
|
|
30466
|
+
retryable: RETRYABLE_CODES.has(err.code)
|
|
30467
|
+
}
|
|
30468
|
+
});
|
|
30469
|
+
process.exit(1);
|
|
30470
|
+
}
|
|
30471
|
+
writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error", retryable: true } });
|
|
30472
|
+
process.exit(1);
|
|
30473
|
+
}
|
|
30474
|
+
var STAGE_HINTS = [
|
|
30475
|
+
"Staged only \u2014 nothing has changed in Tag Manager yet. These apply when the chat completes, in dependency order, and close as a Tag Manager version. Whether that version goes live is a per-company setting, so never promise the user their tracking is live; say the changes are ready and will apply when you finish."
|
|
30476
|
+
];
|
|
30477
|
+
async function stageOp3(op) {
|
|
30478
|
+
const chatId = requireChatId();
|
|
30479
|
+
try {
|
|
30480
|
+
const data = await apiPost("/api/tag-manager/draft/stage", { chatId, op });
|
|
30481
|
+
writeJsonEnvelope({ ok: true, data, hints: STAGE_HINTS });
|
|
30482
|
+
} catch (err) {
|
|
30483
|
+
handleError3(err);
|
|
30484
|
+
}
|
|
30485
|
+
}
|
|
30486
|
+
async function draftAction2(path28, body) {
|
|
30487
|
+
const chatId = requireChatId();
|
|
30488
|
+
try {
|
|
30489
|
+
const data = await apiPost(path28, { chatId, ...body });
|
|
30490
|
+
writeJsonEnvelope({ ok: true, data });
|
|
30491
|
+
return data;
|
|
30492
|
+
} catch (err) {
|
|
30493
|
+
handleError3(err);
|
|
30494
|
+
}
|
|
30495
|
+
}
|
|
30496
|
+
function renderDraft(response) {
|
|
30497
|
+
if (response.count === 0) {
|
|
30498
|
+
return "No Tag Manager changes staged on this chat.";
|
|
30499
|
+
}
|
|
30500
|
+
const lines = [
|
|
30501
|
+
`${response.count} staged Tag Manager change(s)`,
|
|
30502
|
+
...response.ops.map((op) => {
|
|
30503
|
+
const status = op.result ? ` [${op.result.status}]` : "";
|
|
30504
|
+
return ` ${op.ref} ${op.summary}${status}`;
|
|
30505
|
+
})
|
|
30506
|
+
];
|
|
30507
|
+
if (response.versionId) {
|
|
30508
|
+
lines.push(
|
|
30509
|
+
"",
|
|
30510
|
+
response.published ? `Applied and published as Tag Manager version ${response.versionId}. These changes are live on the site.` : `Applied into Tag Manager version ${response.versionId}. It is NOT published \u2014 publish it in Tag Manager to go live.`
|
|
30511
|
+
);
|
|
30512
|
+
}
|
|
30513
|
+
if (response.compilerError) {
|
|
30514
|
+
lines.push("", `Tag Manager reported a problem building the version: ${response.compilerError}`);
|
|
30515
|
+
}
|
|
30516
|
+
return lines.join("\n");
|
|
30517
|
+
}
|
|
30518
|
+
async function draftList(json) {
|
|
30519
|
+
const chatId = requireChatId();
|
|
30520
|
+
try {
|
|
30521
|
+
const data = await apiPost("/api/tag-manager/draft", { chatId });
|
|
30522
|
+
if (json) {
|
|
30523
|
+
writeJsonEnvelope({ ok: true, data });
|
|
30524
|
+
return;
|
|
30525
|
+
}
|
|
30526
|
+
process.stdout.write(`${renderDraft(data)}
|
|
30527
|
+
`);
|
|
30528
|
+
} catch (err) {
|
|
30529
|
+
handleError3(err);
|
|
30530
|
+
}
|
|
30531
|
+
}
|
|
30532
|
+
|
|
30533
|
+
// src/commands/tag-manager/draft.ts
|
|
30534
|
+
registerSchema({
|
|
30535
|
+
command: "tagManager.draft",
|
|
30536
|
+
description: "Review and undo the Tag Manager changes staged on this chat. Use `list` to see everything staged, `show` to inspect one change in full before publish, `amend` to correct one in place, and `remove`/`clear` to drop them.",
|
|
30537
|
+
args: {
|
|
30538
|
+
json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false }
|
|
30539
|
+
}
|
|
30540
|
+
});
|
|
30541
|
+
var draftCommand3 = defineCommand158({
|
|
30542
|
+
meta: {
|
|
30543
|
+
name: "draft",
|
|
30544
|
+
description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat"
|
|
30545
|
+
},
|
|
30546
|
+
subCommands: {
|
|
30547
|
+
list: defineCommand158({
|
|
30548
|
+
meta: {
|
|
30549
|
+
name: "list",
|
|
30550
|
+
description: "Review everything staged on this chat (--json for the raw envelope)"
|
|
30551
|
+
},
|
|
30552
|
+
args: { json: { type: "boolean", description: "Print the raw JSON envelope", required: false } },
|
|
30553
|
+
run: async ({ args }) => {
|
|
30554
|
+
await draftList(args.json === true);
|
|
30555
|
+
}
|
|
30556
|
+
}),
|
|
30557
|
+
show: defineCommand158({
|
|
30558
|
+
meta: {
|
|
30559
|
+
name: "show",
|
|
30560
|
+
description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
|
|
30561
|
+
},
|
|
30562
|
+
args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
|
|
30563
|
+
run: async ({ args }) => {
|
|
30564
|
+
await draftAction2("/api/tag-manager/draft/show", {
|
|
30565
|
+
ref: requireTarget4(args, "change")
|
|
30566
|
+
});
|
|
30567
|
+
}
|
|
30568
|
+
}),
|
|
30569
|
+
amend: defineCommand158({
|
|
30570
|
+
meta: {
|
|
30571
|
+
name: "amend",
|
|
30572
|
+
description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-validates. Use this instead of remove + re-create."
|
|
30573
|
+
},
|
|
30574
|
+
args: {
|
|
30575
|
+
ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false },
|
|
30576
|
+
patch: { type: "string", description: "Inline JSON patch object", required: false },
|
|
30577
|
+
file: { type: "string", description: "JSON file with the patch object", required: false }
|
|
30578
|
+
},
|
|
30579
|
+
run: async ({ args }) => {
|
|
30580
|
+
await draftAction2("/api/tag-manager/draft/amend", {
|
|
30581
|
+
ref: requireTarget4(args, "change"),
|
|
30582
|
+
patch: loadJsonArg(args, "patch")
|
|
30583
|
+
});
|
|
30584
|
+
}
|
|
30585
|
+
}),
|
|
30586
|
+
remove: defineCommand158({
|
|
30587
|
+
meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
|
|
30588
|
+
args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
|
|
30589
|
+
run: async ({ args }) => {
|
|
30590
|
+
await draftAction2("/api/tag-manager/draft/remove", {
|
|
30591
|
+
ref: requireTarget4(args, "change")
|
|
30592
|
+
});
|
|
30593
|
+
}
|
|
30594
|
+
}),
|
|
30595
|
+
clear: defineCommand158({
|
|
30596
|
+
meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
|
|
30597
|
+
run: async () => {
|
|
30598
|
+
await draftAction2("/api/tag-manager/draft/clear", {});
|
|
30599
|
+
}
|
|
30600
|
+
})
|
|
30601
|
+
}
|
|
30602
|
+
});
|
|
30603
|
+
|
|
30604
|
+
// src/commands/tag-manager/read.ts
|
|
30605
|
+
import { defineCommand as defineCommand159 } from "citty";
|
|
30606
|
+
registerSchema({
|
|
30607
|
+
command: "tagManager.containers",
|
|
30608
|
+
description: "List the Google Tag Manager containers this company's connection can reach. The connected container is flagged. Start here to confirm which container you are managing.",
|
|
30609
|
+
args: {}
|
|
30610
|
+
});
|
|
30611
|
+
registerSchema({
|
|
30612
|
+
command: "tagManager.read",
|
|
30613
|
+
description: "Read what is currently inside a Tag Manager container: tags, triggers, variables, folders and enabled built-in variables. Start here before proposing any change, so you edit what exists instead of duplicating it. Compact by default; pass --full for raw Tag Manager objects.",
|
|
30614
|
+
args: {
|
|
30615
|
+
container: { type: "string", description: "Numeric container id (defaults to the connected one)", required: false },
|
|
30616
|
+
workspace: { type: "string", description: "Workspace id (defaults to the default workspace)", required: false },
|
|
30617
|
+
entities: {
|
|
30618
|
+
type: "string",
|
|
30619
|
+
description: "Comma-separated subset: tag,trigger,variable,folder,builtInVariable",
|
|
30620
|
+
required: false
|
|
30621
|
+
},
|
|
30622
|
+
full: { type: "boolean", description: "Include the raw Tag Manager object for each entity", required: false }
|
|
30623
|
+
}
|
|
30624
|
+
});
|
|
30625
|
+
var containersCommand = defineCommand159({
|
|
30626
|
+
meta: {
|
|
30627
|
+
name: "containers",
|
|
30628
|
+
description: `List Tag Manager containers reachable by this company's connection.
|
|
30629
|
+
|
|
30630
|
+
Start here:
|
|
30631
|
+
baker tag-manager containers`
|
|
30632
|
+
},
|
|
30633
|
+
run: async () => {
|
|
30634
|
+
try {
|
|
30635
|
+
const data = await apiGet("/api/tag-manager/containers");
|
|
30636
|
+
writeJsonEnvelope({ ok: true, data });
|
|
30637
|
+
} catch (err) {
|
|
30638
|
+
handleError3(err);
|
|
30639
|
+
}
|
|
30640
|
+
}
|
|
30641
|
+
});
|
|
30642
|
+
var readCommand = defineCommand159({
|
|
30643
|
+
meta: {
|
|
30644
|
+
name: "read",
|
|
30645
|
+
description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
|
|
30646
|
+
|
|
30647
|
+
Examples:
|
|
30648
|
+
baker tag-manager read
|
|
30649
|
+
baker tag-manager read --entities tag,trigger
|
|
30650
|
+
baker tag-manager read --full`
|
|
30651
|
+
},
|
|
30652
|
+
args: {
|
|
30653
|
+
container: { type: "string", description: "Numeric container id", required: false },
|
|
30654
|
+
workspace: { type: "string", description: "Workspace id", required: false },
|
|
30655
|
+
entities: { type: "string", description: "Comma-separated entity subset", required: false },
|
|
30656
|
+
full: { type: "boolean", description: "Include raw Tag Manager objects", required: false }
|
|
30657
|
+
},
|
|
30658
|
+
run: async ({ args }) => {
|
|
30659
|
+
const entities = typeof args.entities === "string" && args.entities.length > 0 ? args.entities.split(",").map((entry) => entry.trim()) : void 0;
|
|
30660
|
+
try {
|
|
30661
|
+
const data = await apiPost("/api/tag-manager/read", {
|
|
30662
|
+
containerId: args.container,
|
|
30663
|
+
workspaceId: args.workspace,
|
|
30664
|
+
entities,
|
|
30665
|
+
full: args.full === true
|
|
30666
|
+
});
|
|
30667
|
+
const hints = [];
|
|
30668
|
+
if (data.installedContainerMismatch) {
|
|
30669
|
+
hints.push(data.installedContainerMismatch);
|
|
30670
|
+
}
|
|
30671
|
+
hints.push(
|
|
30672
|
+
"Reference an existing trigger or variable by its numeric id or {{Name}}. To reference something you are staging in this same chat, use its gtm_temp_* ref and the executor resolves it at publish."
|
|
30673
|
+
);
|
|
30674
|
+
writeJsonEnvelope({ ok: true, data, hints });
|
|
30675
|
+
} catch (err) {
|
|
30676
|
+
handleError3(err);
|
|
30677
|
+
}
|
|
30678
|
+
}
|
|
30679
|
+
});
|
|
30680
|
+
|
|
30681
|
+
// src/commands/tag-manager/write-commands.ts
|
|
30682
|
+
import { defineCommand as defineCommand160 } from "citty";
|
|
30683
|
+
var ENTITIES = [
|
|
30684
|
+
{
|
|
30685
|
+
entity: "tag",
|
|
30686
|
+
noun: "tag",
|
|
30687
|
+
createHint: 'Payload needs name + type (e.g. "gaawe" for a GA4 event) and usually parameter[] and firingTriggerId[]. Reference a trigger by its numeric id, or by a gtm_temp_* ref if you are staging it in this same chat.',
|
|
30688
|
+
example: '{"name":"GA4 - Generate Lead","type":"gaawe","firingTriggerId":["gtm_temp_trigger_x_0"]}'
|
|
30689
|
+
},
|
|
30690
|
+
{
|
|
30691
|
+
entity: "trigger",
|
|
30692
|
+
noun: "trigger",
|
|
30693
|
+
createHint: 'Payload needs name + type (e.g. "pageview", "click", "customEvent"). Stage the trigger BEFORE the tag that fires on it, then reference it by its gtm_temp_* ref.',
|
|
30694
|
+
example: '{"name":"Form - Submit","type":"formSubmission"}'
|
|
30695
|
+
},
|
|
30696
|
+
{
|
|
30697
|
+
entity: "variable",
|
|
30698
|
+
noun: "variable",
|
|
30699
|
+
createHint: 'Payload needs name + type (e.g. "v" for a data layer variable, "c" for a constant). Other entities reference a variable by NAME as {{Variable Name}}.',
|
|
30700
|
+
example: '{"name":"DL - lead_id","type":"v","parameter":[{"type":"template","key":"name","value":"lead_id"}]}'
|
|
30701
|
+
},
|
|
30702
|
+
{
|
|
30703
|
+
entity: "folder",
|
|
30704
|
+
noun: "folder",
|
|
30705
|
+
createHint: "Payload needs name. Use folders to keep a large container legible.",
|
|
30706
|
+
example: '{"name":"Google Ads"}'
|
|
30707
|
+
}
|
|
30708
|
+
];
|
|
30709
|
+
for (const { entity, noun, createHint } of ENTITIES) {
|
|
30710
|
+
registerSchema({
|
|
30711
|
+
command: `tagManager.${entity}.create`,
|
|
30712
|
+
description: `Stage the creation of a Tag Manager ${noun}. ${createHint} Staged only \u2014 applies when the chat completes.`,
|
|
30713
|
+
args: {
|
|
30714
|
+
json: { type: "string", description: `Inline JSON ${noun} definition`, required: false },
|
|
30715
|
+
file: { type: "string", description: `Path to a JSON file with the ${noun} definition`, required: false },
|
|
30716
|
+
container: { type: "string", description: "Numeric container id", required: false }
|
|
30717
|
+
}
|
|
30718
|
+
});
|
|
30719
|
+
registerSchema({
|
|
30720
|
+
command: `tagManager.${entity}.update`,
|
|
30721
|
+
description: `Stage an update to an existing Tag Manager ${noun}. Pass the ${noun} id or path as the positional argument and the changed fields as JSON. Read the container first so you send the fields you mean to change.`,
|
|
30722
|
+
args: {
|
|
30723
|
+
json: { type: "string", description: "Inline JSON with the changed fields", required: false },
|
|
30724
|
+
file: { type: "string", description: "Path to a JSON file with the changed fields", required: false }
|
|
30725
|
+
}
|
|
30726
|
+
});
|
|
30727
|
+
registerSchema({
|
|
30728
|
+
command: `tagManager.${entity}.delete`,
|
|
30729
|
+
description: `Stage the deletion of a Tag Manager ${noun}. Pass its id or path as the positional argument. Deleting is irreversible once the resulting version is published \u2014 confirm with the user first.`,
|
|
30730
|
+
args: {}
|
|
30731
|
+
});
|
|
30732
|
+
}
|
|
30733
|
+
function entityCommand(entity, noun, example) {
|
|
30734
|
+
return defineCommand160({
|
|
30735
|
+
meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
|
|
30736
|
+
subCommands: {
|
|
30737
|
+
create: defineCommand160({
|
|
30738
|
+
meta: {
|
|
30739
|
+
name: "create",
|
|
30740
|
+
description: `Stage a new ${noun}
|
|
30741
|
+
|
|
30742
|
+
Examples:
|
|
30743
|
+
baker tag-manager ${entity} create --json '${example}'
|
|
30744
|
+
baker tag-manager ${entity} create --file ./${entity}.json`
|
|
30745
|
+
},
|
|
30746
|
+
args: {
|
|
30747
|
+
json: { type: "string", description: "Inline JSON definition", required: false },
|
|
30748
|
+
file: { type: "string", description: "Path to a JSON file", required: false },
|
|
30749
|
+
container: { type: "string", description: "Numeric container id", required: false }
|
|
30750
|
+
},
|
|
30751
|
+
run: async ({ args }) => {
|
|
30752
|
+
await stageOp3({
|
|
30753
|
+
kind: `tagManager.${entity}.create`,
|
|
30754
|
+
payload: loadJsonArg(args),
|
|
30755
|
+
...typeof args.container === "string" ? { containerId: args.container } : {}
|
|
30756
|
+
});
|
|
30757
|
+
}
|
|
30758
|
+
}),
|
|
30759
|
+
update: defineCommand160({
|
|
30760
|
+
meta: {
|
|
30761
|
+
name: "update",
|
|
30762
|
+
description: `Stage an update to an existing ${noun} (pass its id or path)`
|
|
30763
|
+
},
|
|
30764
|
+
args: {
|
|
30765
|
+
id: { type: "positional", description: `${noun} id or path`, required: false },
|
|
30766
|
+
json: { type: "string", description: "Inline JSON with changed fields", required: false },
|
|
30767
|
+
file: { type: "string", description: "Path to a JSON file", required: false },
|
|
30768
|
+
container: { type: "string", description: "Numeric container id", required: false }
|
|
30769
|
+
},
|
|
30770
|
+
run: async ({ args }) => {
|
|
30771
|
+
await stageOp3({
|
|
30772
|
+
kind: `tagManager.${entity}.update`,
|
|
30773
|
+
target: requireTarget4(args, noun),
|
|
30774
|
+
payload: loadJsonArg(args),
|
|
30775
|
+
...typeof args.container === "string" ? { containerId: args.container } : {}
|
|
30776
|
+
});
|
|
30777
|
+
}
|
|
30778
|
+
}),
|
|
30779
|
+
delete: defineCommand160({
|
|
30780
|
+
meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
|
|
30781
|
+
args: {
|
|
30782
|
+
id: { type: "positional", description: `${noun} id or path`, required: false },
|
|
30783
|
+
container: { type: "string", description: "Numeric container id", required: false }
|
|
30784
|
+
},
|
|
30785
|
+
run: async ({ args }) => {
|
|
30786
|
+
await stageOp3({
|
|
30787
|
+
kind: `tagManager.${entity}.delete`,
|
|
30788
|
+
target: requireTarget4(args, noun),
|
|
30789
|
+
...typeof args.container === "string" ? { containerId: args.container } : {}
|
|
30790
|
+
});
|
|
30791
|
+
}
|
|
30792
|
+
})
|
|
30793
|
+
}
|
|
30794
|
+
});
|
|
30795
|
+
}
|
|
30796
|
+
var exampleFor = (entity) => ENTITIES.find((e) => e.entity === entity)?.example ?? "{}";
|
|
30797
|
+
var tagCommand = entityCommand("tag", "tag", exampleFor("tag"));
|
|
30798
|
+
var triggerCommand2 = entityCommand("trigger", "trigger", exampleFor("trigger"));
|
|
30799
|
+
var variableCommand = entityCommand("variable", "variable", exampleFor("variable"));
|
|
30800
|
+
var folderCommand = entityCommand("folder", "folder", exampleFor("folder"));
|
|
30801
|
+
registerSchema({
|
|
30802
|
+
command: "tagManager.builtin",
|
|
30803
|
+
description: "Enable or disable Tag Manager built-in variables by type (e.g. clickUrl, pageUrl, formId). Built-in variables must be enabled before a trigger or tag can reference them as {{Click URL}}.",
|
|
30804
|
+
args: {
|
|
30805
|
+
types: { type: "string", description: "Comma-separated built-in variable types", required: true }
|
|
30806
|
+
}
|
|
30807
|
+
});
|
|
30808
|
+
function builtinTypes(args) {
|
|
30809
|
+
const raw = args.types;
|
|
30810
|
+
if (typeof raw !== "string" || raw.length === 0) {
|
|
30811
|
+
process.stdout.write(
|
|
30812
|
+
`${JSON.stringify({ ok: false, error: { code: "VALIDATION_ERROR", message: "pass --types with comma-separated built-in variable types" } }, null, 2)}
|
|
30813
|
+
`
|
|
30814
|
+
);
|
|
30815
|
+
process.exit(1);
|
|
30816
|
+
}
|
|
30817
|
+
return raw.split(",").map((entry) => entry.trim());
|
|
30818
|
+
}
|
|
30819
|
+
var builtinCommand = defineCommand160({
|
|
30820
|
+
meta: {
|
|
30821
|
+
name: "builtin",
|
|
30822
|
+
description: `Enable or disable built-in variables
|
|
30823
|
+
|
|
30824
|
+
Examples:
|
|
30825
|
+
baker tag-manager builtin enable --types clickUrl,clickText
|
|
30826
|
+
baker tag-manager builtin disable --types formId`
|
|
30827
|
+
},
|
|
30828
|
+
subCommands: {
|
|
30829
|
+
enable: defineCommand160({
|
|
30830
|
+
meta: { name: "enable", description: "Stage enabling built-in variables" },
|
|
30831
|
+
args: {
|
|
30832
|
+
types: { type: "string", description: "Comma-separated types", required: false },
|
|
30833
|
+
container: { type: "string", description: "Numeric container id", required: false }
|
|
30834
|
+
},
|
|
30835
|
+
run: async ({ args }) => {
|
|
30836
|
+
await stageOp3({
|
|
30837
|
+
kind: "tagManager.builtInVariable.enable",
|
|
30838
|
+
payload: { type: builtinTypes(args) },
|
|
30839
|
+
...typeof args.container === "string" ? { containerId: args.container } : {}
|
|
30840
|
+
});
|
|
30841
|
+
}
|
|
30842
|
+
}),
|
|
30843
|
+
disable: defineCommand160({
|
|
30844
|
+
meta: { name: "disable", description: "Stage disabling built-in variables" },
|
|
30845
|
+
args: {
|
|
30846
|
+
types: { type: "string", description: "Comma-separated types", required: false },
|
|
30847
|
+
container: { type: "string", description: "Numeric container id", required: false }
|
|
30848
|
+
},
|
|
30849
|
+
run: async ({ args }) => {
|
|
30850
|
+
await stageOp3({
|
|
30851
|
+
kind: "tagManager.builtInVariable.disable",
|
|
30852
|
+
payload: { type: builtinTypes(args) },
|
|
30853
|
+
...typeof args.container === "string" ? { containerId: args.container } : {}
|
|
30854
|
+
});
|
|
30855
|
+
}
|
|
30856
|
+
})
|
|
30857
|
+
}
|
|
30858
|
+
});
|
|
30859
|
+
|
|
30860
|
+
// src/commands/tag-manager/index.ts
|
|
30861
|
+
var tagManagerCommand = defineCommand161({
|
|
30862
|
+
meta: {
|
|
30863
|
+
name: "tag-manager",
|
|
30864
|
+
description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
|
|
30865
|
+
|
|
30866
|
+
Start here:
|
|
30867
|
+
baker tag-manager read \u2014 see what the container holds today
|
|
30868
|
+
|
|
30869
|
+
Then stage changes (nothing is sent to Tag Manager until publish):
|
|
30870
|
+
baker tag-manager trigger create --json '{"name":"Quote Submit","type":"customEvent"}'
|
|
30871
|
+
baker tag-manager tag create --json '{"name":"GA4 Quote","type":"gaawe","firingTriggerId":["gtm_temp_trigger_..."]}'
|
|
30872
|
+
baker tag-manager draft list \u2014 review everything staged
|
|
30873
|
+
|
|
30874
|
+
On publish, staged changes are written into a new Tag Manager version that is NOT published.
|
|
30875
|
+
Tell the user to publish that version in Tag Manager to make it live.
|
|
30876
|
+
|
|
30877
|
+
This owns the CONTENTS of the container. Installing the container snippet on the site is a
|
|
30878
|
+
different job \u2014 that is \`baker tags\` with the googleTagManager tag.
|
|
30879
|
+
|
|
30880
|
+
Full guide: __tooling__/docs/tools/baker/tag-manager.md`
|
|
30881
|
+
},
|
|
30882
|
+
subCommands: {
|
|
30883
|
+
containers: containersCommand,
|
|
30884
|
+
read: readCommand,
|
|
30885
|
+
tag: tagCommand,
|
|
30886
|
+
trigger: triggerCommand2,
|
|
30887
|
+
variable: variableCommand,
|
|
30888
|
+
folder: folderCommand,
|
|
30889
|
+
builtin: builtinCommand,
|
|
30890
|
+
draft: draftCommand3
|
|
30891
|
+
}
|
|
30892
|
+
});
|
|
30893
|
+
|
|
30894
|
+
// src/commands/tags/index.ts
|
|
30895
|
+
import { defineCommand as defineCommand162 } from "citty";
|
|
30896
|
+
|
|
30240
30897
|
// src/commands/tags/shared.ts
|
|
30241
30898
|
function failApi3(err) {
|
|
30242
30899
|
if (err instanceof ApiError) {
|
|
@@ -30301,7 +30958,7 @@ async function listTags(json) {
|
|
|
30301
30958
|
failApi3(err);
|
|
30302
30959
|
}
|
|
30303
30960
|
}
|
|
30304
|
-
var listCommand10 =
|
|
30961
|
+
var listCommand10 = defineCommand162({
|
|
30305
30962
|
meta: {
|
|
30306
30963
|
name: "list",
|
|
30307
30964
|
description: "Effective tags for this chat (production + staged), with each tag's full readable config (secrets excluded) \u2014 reuse a stored value to pre-fill a change rather than asking the user. Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
|
|
@@ -30320,7 +30977,7 @@ async function listDraft3() {
|
|
|
30320
30977
|
failApi3(err);
|
|
30321
30978
|
}
|
|
30322
30979
|
}
|
|
30323
|
-
var
|
|
30980
|
+
var draftCommand4 = defineCommand162({
|
|
30324
30981
|
meta: {
|
|
30325
30982
|
name: "draft",
|
|
30326
30983
|
description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create)."
|
|
@@ -30329,7 +30986,7 @@ var draftCommand3 = defineCommand158({
|
|
|
30329
30986
|
await listDraft3();
|
|
30330
30987
|
}
|
|
30331
30988
|
});
|
|
30332
|
-
var tagsCommand3 =
|
|
30989
|
+
var tagsCommand3 = defineCommand162({
|
|
30333
30990
|
meta: {
|
|
30334
30991
|
name: "tags",
|
|
30335
30992
|
description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
|
|
@@ -30347,7 +31004,7 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
|
30347
31004
|
},
|
|
30348
31005
|
subCommands: {
|
|
30349
31006
|
list: listCommand10,
|
|
30350
|
-
draft:
|
|
31007
|
+
draft: draftCommand4
|
|
30351
31008
|
},
|
|
30352
31009
|
run: async () => {
|
|
30353
31010
|
await listTags(false);
|
|
@@ -30355,10 +31012,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
|
|
|
30355
31012
|
});
|
|
30356
31013
|
|
|
30357
31014
|
// src/commands/testimonials/index.ts
|
|
30358
|
-
import { defineCommand as
|
|
31015
|
+
import { defineCommand as defineCommand166 } from "citty";
|
|
30359
31016
|
|
|
30360
31017
|
// src/commands/testimonials/get.ts
|
|
30361
|
-
import { defineCommand as
|
|
31018
|
+
import { defineCommand as defineCommand163 } from "citty";
|
|
30362
31019
|
registerSchema({
|
|
30363
31020
|
command: "testimonials.get",
|
|
30364
31021
|
description: "Get a single testimonial by ID",
|
|
@@ -30366,7 +31023,7 @@ registerSchema({
|
|
|
30366
31023
|
id: { type: "string", description: "Testimonial ID", required: true }
|
|
30367
31024
|
}
|
|
30368
31025
|
});
|
|
30369
|
-
var getCommand4 =
|
|
31026
|
+
var getCommand4 = defineCommand163({
|
|
30370
31027
|
meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
|
|
30371
31028
|
args: {
|
|
30372
31029
|
id: { type: "positional", description: "Testimonial ID", required: false },
|
|
@@ -30403,7 +31060,7 @@ var getCommand4 = defineCommand159({
|
|
|
30403
31060
|
});
|
|
30404
31061
|
|
|
30405
31062
|
// src/commands/testimonials/list.ts
|
|
30406
|
-
import { defineCommand as
|
|
31063
|
+
import { defineCommand as defineCommand164 } from "citty";
|
|
30407
31064
|
registerSchema({
|
|
30408
31065
|
command: "testimonials.list",
|
|
30409
31066
|
description: "List testimonials with optional filters.",
|
|
@@ -30433,7 +31090,7 @@ registerSchema({
|
|
|
30433
31090
|
limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
|
|
30434
31091
|
}
|
|
30435
31092
|
});
|
|
30436
|
-
var listCommand11 =
|
|
31093
|
+
var listCommand11 = defineCommand164({
|
|
30437
31094
|
meta: {
|
|
30438
31095
|
name: "list",
|
|
30439
31096
|
description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
|
|
@@ -30482,7 +31139,7 @@ var listCommand11 = defineCommand160({
|
|
|
30482
31139
|
});
|
|
30483
31140
|
|
|
30484
31141
|
// src/commands/testimonials/search.ts
|
|
30485
|
-
import { defineCommand as
|
|
31142
|
+
import { defineCommand as defineCommand165 } from "citty";
|
|
30486
31143
|
function languageBiasHint(results, requestedLanguage) {
|
|
30487
31144
|
if (requestedLanguage) {
|
|
30488
31145
|
return null;
|
|
@@ -30560,7 +31217,7 @@ function buildSearchRequest(query, args) {
|
|
|
30560
31217
|
}
|
|
30561
31218
|
return body;
|
|
30562
31219
|
}
|
|
30563
|
-
var searchCommand2 =
|
|
31220
|
+
var searchCommand2 = defineCommand165({
|
|
30564
31221
|
meta: {
|
|
30565
31222
|
name: "search",
|
|
30566
31223
|
description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
|
|
@@ -30616,7 +31273,7 @@ var searchCommand2 = defineCommand161({
|
|
|
30616
31273
|
var tagsCommand4 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
|
|
30617
31274
|
|
|
30618
31275
|
// src/commands/testimonials/index.ts
|
|
30619
|
-
var testimonialsCommand =
|
|
31276
|
+
var testimonialsCommand = defineCommand166({
|
|
30620
31277
|
meta: {
|
|
30621
31278
|
name: "testimonials",
|
|
30622
31279
|
description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
|
|
@@ -30638,10 +31295,10 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
|
|
|
30638
31295
|
});
|
|
30639
31296
|
|
|
30640
31297
|
// src/commands/videos/index.ts
|
|
30641
|
-
import { defineCommand as
|
|
31298
|
+
import { defineCommand as defineCommand171 } from "citty";
|
|
30642
31299
|
|
|
30643
31300
|
// src/commands/videos/delete.ts
|
|
30644
|
-
import { defineCommand as
|
|
31301
|
+
import { defineCommand as defineCommand167 } from "citty";
|
|
30645
31302
|
registerSchema({
|
|
30646
31303
|
command: "videos.delete",
|
|
30647
31304
|
description: "Delete a video by ID",
|
|
@@ -30655,7 +31312,7 @@ registerSchema({
|
|
|
30655
31312
|
}
|
|
30656
31313
|
}
|
|
30657
31314
|
});
|
|
30658
|
-
var deleteCommand3 =
|
|
31315
|
+
var deleteCommand3 = defineCommand167({
|
|
30659
31316
|
meta: {
|
|
30660
31317
|
name: "delete",
|
|
30661
31318
|
description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
|
|
@@ -30696,7 +31353,7 @@ var deleteCommand3 = defineCommand163({
|
|
|
30696
31353
|
});
|
|
30697
31354
|
|
|
30698
31355
|
// src/commands/videos/get.ts
|
|
30699
|
-
import { defineCommand as
|
|
31356
|
+
import { defineCommand as defineCommand168 } from "citty";
|
|
30700
31357
|
registerSchema({
|
|
30701
31358
|
command: "videos.get",
|
|
30702
31359
|
description: "Get a single video by ID",
|
|
@@ -30704,7 +31361,7 @@ registerSchema({
|
|
|
30704
31361
|
id: { type: "string", description: "Video ID", required: true }
|
|
30705
31362
|
}
|
|
30706
31363
|
});
|
|
30707
|
-
var getCommand5 =
|
|
31364
|
+
var getCommand5 = defineCommand168({
|
|
30708
31365
|
meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
|
|
30709
31366
|
args: {
|
|
30710
31367
|
id: { type: "positional", description: "Video ID", required: false },
|
|
@@ -30741,7 +31398,7 @@ var getCommand5 = defineCommand164({
|
|
|
30741
31398
|
});
|
|
30742
31399
|
|
|
30743
31400
|
// src/commands/videos/search.ts
|
|
30744
|
-
import { defineCommand as
|
|
31401
|
+
import { defineCommand as defineCommand169 } from "citty";
|
|
30745
31402
|
registerSchema({
|
|
30746
31403
|
command: "videos.search",
|
|
30747
31404
|
description: "Search videos by text query. Only returns ready videos.",
|
|
@@ -30751,7 +31408,7 @@ registerSchema({
|
|
|
30751
31408
|
tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
|
|
30752
31409
|
}
|
|
30753
31410
|
});
|
|
30754
|
-
var searchCommand3 =
|
|
31411
|
+
var searchCommand3 = defineCommand169({
|
|
30755
31412
|
meta: {
|
|
30756
31413
|
name: "search",
|
|
30757
31414
|
description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
|
|
@@ -30803,7 +31460,7 @@ var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
|
|
|
30803
31460
|
// src/commands/videos/upload.ts
|
|
30804
31461
|
import { readFile as readFile23, stat as stat7 } from "fs/promises";
|
|
30805
31462
|
import { extname as extname3 } from "path";
|
|
30806
|
-
import { defineCommand as
|
|
31463
|
+
import { defineCommand as defineCommand170 } from "citty";
|
|
30807
31464
|
var MIME_MAP = {
|
|
30808
31465
|
".mp4": "video/mp4",
|
|
30809
31466
|
".mov": "video/quicktime",
|
|
@@ -30837,7 +31494,7 @@ function detectContentType(filePath) {
|
|
|
30837
31494
|
}
|
|
30838
31495
|
return mime;
|
|
30839
31496
|
}
|
|
30840
|
-
var uploadCommand2 =
|
|
31497
|
+
var uploadCommand2 = defineCommand170({
|
|
30841
31498
|
meta: {
|
|
30842
31499
|
name: "upload",
|
|
30843
31500
|
description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
|
|
@@ -30891,7 +31548,7 @@ var uploadCommand2 = defineCommand166({
|
|
|
30891
31548
|
});
|
|
30892
31549
|
|
|
30893
31550
|
// src/commands/videos/index.ts
|
|
30894
|
-
var videosCommand =
|
|
31551
|
+
var videosCommand = defineCommand171({
|
|
30895
31552
|
meta: {
|
|
30896
31553
|
name: "videos",
|
|
30897
31554
|
description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
|
|
@@ -30915,10 +31572,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
|
|
|
30915
31572
|
});
|
|
30916
31573
|
|
|
30917
31574
|
// src/commands/winning-ads/index.ts
|
|
30918
|
-
import { defineCommand as
|
|
31575
|
+
import { defineCommand as defineCommand184 } from "citty";
|
|
30919
31576
|
|
|
30920
31577
|
// src/commands/winning-ads/advertisers.ts
|
|
30921
|
-
import { defineCommand as
|
|
31578
|
+
import { defineCommand as defineCommand172 } from "citty";
|
|
30922
31579
|
|
|
30923
31580
|
// src/commands/winning-ads/shared.ts
|
|
30924
31581
|
function splitList(value) {
|
|
@@ -30971,7 +31628,7 @@ function advertiserNormalizer(record, full) {
|
|
|
30971
31628
|
last_synced_at: record.last_synced_at ?? null
|
|
30972
31629
|
};
|
|
30973
31630
|
}
|
|
30974
|
-
var advertisersCommand2 =
|
|
31631
|
+
var advertisersCommand2 = defineCommand172({
|
|
30975
31632
|
meta: {
|
|
30976
31633
|
name: "advertisers",
|
|
30977
31634
|
description: 'List corpus advertisers by name or domain. Find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id / winners. Example: baker winning-ads advertisers "Deel" --output md'
|
|
@@ -31029,7 +31686,7 @@ var advertisersCommand2 = defineCommand168({
|
|
|
31029
31686
|
});
|
|
31030
31687
|
|
|
31031
31688
|
// src/commands/winning-ads/brief.ts
|
|
31032
|
-
import { defineCommand as
|
|
31689
|
+
import { defineCommand as defineCommand173 } from "citty";
|
|
31033
31690
|
registerSchema({
|
|
31034
31691
|
command: "winning-ads.brief",
|
|
31035
31692
|
description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
|
|
@@ -31075,7 +31732,7 @@ function parseDna(raw) {
|
|
|
31075
31732
|
}
|
|
31076
31733
|
return parsed;
|
|
31077
31734
|
}
|
|
31078
|
-
var briefCommand =
|
|
31735
|
+
var briefCommand = defineCommand173({
|
|
31079
31736
|
meta: {
|
|
31080
31737
|
name: "brief",
|
|
31081
31738
|
description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
|
|
@@ -31111,7 +31768,7 @@ var briefCommand = defineCommand169({
|
|
|
31111
31768
|
});
|
|
31112
31769
|
|
|
31113
31770
|
// src/commands/winning-ads/content.ts
|
|
31114
|
-
import { defineCommand as
|
|
31771
|
+
import { defineCommand as defineCommand174 } from "citty";
|
|
31115
31772
|
registerSchema({
|
|
31116
31773
|
command: "winning-ads.content",
|
|
31117
31774
|
description: "Read what's INSIDE one winning ad: the spoken transcript, the on-screen text, and the ad copy. Use this after `search`/`winners`/`feed` return a shortlist \u2014 pass an ad_id to understand a reference before reproducing it. Add --full for speech, pacing, and soundtrack detail. Video ads carry the transcript/on-screen text; static ads carry only the copy.",
|
|
@@ -31124,7 +31781,7 @@ registerSchema({
|
|
|
31124
31781
|
}
|
|
31125
31782
|
}
|
|
31126
31783
|
});
|
|
31127
|
-
var contentCommand =
|
|
31784
|
+
var contentCommand = defineCommand174({
|
|
31128
31785
|
meta: {
|
|
31129
31786
|
name: "content",
|
|
31130
31787
|
description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
|
|
@@ -31173,7 +31830,7 @@ var contentCommand = defineCommand170({
|
|
|
31173
31830
|
});
|
|
31174
31831
|
|
|
31175
31832
|
// src/commands/winning-ads/feed.ts
|
|
31176
|
-
import { defineCommand as
|
|
31833
|
+
import { defineCommand as defineCommand175 } from "citty";
|
|
31177
31834
|
function buildFeedParams(input) {
|
|
31178
31835
|
const params = {};
|
|
31179
31836
|
const advertiser = splitList(input.advertiser);
|
|
@@ -31225,7 +31882,7 @@ registerSchema({
|
|
|
31225
31882
|
format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
|
|
31226
31883
|
}
|
|
31227
31884
|
});
|
|
31228
|
-
var feedCommand =
|
|
31885
|
+
var feedCommand = defineCommand175({
|
|
31229
31886
|
meta: {
|
|
31230
31887
|
name: "feed",
|
|
31231
31888
|
description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
|
|
@@ -31310,7 +31967,7 @@ var feedCommand = defineCommand171({
|
|
|
31310
31967
|
});
|
|
31311
31968
|
|
|
31312
31969
|
// src/commands/winning-ads/follow.ts
|
|
31313
|
-
import { defineCommand as
|
|
31970
|
+
import { defineCommand as defineCommand176 } from "citty";
|
|
31314
31971
|
var PLATFORMS = ["meta", "linkedin"];
|
|
31315
31972
|
registerSchema({
|
|
31316
31973
|
command: "winning-ads.follow",
|
|
@@ -31325,7 +31982,7 @@ registerSchema({
|
|
|
31325
31982
|
label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
|
|
31326
31983
|
}
|
|
31327
31984
|
});
|
|
31328
|
-
var followCommand =
|
|
31985
|
+
var followCommand = defineCommand176({
|
|
31329
31986
|
meta: {
|
|
31330
31987
|
name: "follow",
|
|
31331
31988
|
description: 'Follow a brand to track ALL its ads \u2014 every platform and country. --platform is how we read your input, not a limit. A domain tracks both Meta + LinkedIn. Example: baker winning-ads follow "deel.com" --platform meta'
|
|
@@ -31372,7 +32029,7 @@ var followCommand = defineCommand172({
|
|
|
31372
32029
|
});
|
|
31373
32030
|
|
|
31374
32031
|
// src/commands/winning-ads/follow-competitors.ts
|
|
31375
|
-
import { defineCommand as
|
|
32032
|
+
import { defineCommand as defineCommand177 } from "citty";
|
|
31376
32033
|
var PLATFORMS2 = ["meta", "linkedin"];
|
|
31377
32034
|
var BATCH_TIMEOUT_MS = 3e5;
|
|
31378
32035
|
function buildFollowBatchBody(input) {
|
|
@@ -31405,7 +32062,7 @@ registerSchema({
|
|
|
31405
32062
|
}
|
|
31406
32063
|
}
|
|
31407
32064
|
});
|
|
31408
|
-
var followCompetitorsCommand =
|
|
32065
|
+
var followCompetitorsCommand = defineCommand177({
|
|
31409
32066
|
meta: {
|
|
31410
32067
|
name: "follow-competitors",
|
|
31411
32068
|
description: 'Follow many brands at once by domain \u2014 add every competitor in one call. Example: baker winning-ads follow-competitors "deel.com,notion.so,hubspot.com"'
|
|
@@ -31480,7 +32137,7 @@ var followCompetitorsCommand = defineCommand173({
|
|
|
31480
32137
|
});
|
|
31481
32138
|
|
|
31482
32139
|
// src/commands/winning-ads/following.ts
|
|
31483
|
-
import { defineCommand as
|
|
32140
|
+
import { defineCommand as defineCommand178 } from "citty";
|
|
31484
32141
|
registerSchema({
|
|
31485
32142
|
command: "winning-ads.following",
|
|
31486
32143
|
description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts.",
|
|
@@ -31513,7 +32170,7 @@ function followingNormalizer(record, full) {
|
|
|
31513
32170
|
platforms: Array.isArray(record.platforms) ? record.platforms : []
|
|
31514
32171
|
};
|
|
31515
32172
|
}
|
|
31516
|
-
var followingCommand =
|
|
32173
|
+
var followingCommand = defineCommand178({
|
|
31517
32174
|
meta: {
|
|
31518
32175
|
name: "following",
|
|
31519
32176
|
description: "List brands you follow, with status (ready / adding\u2026) and cached counts. Example: baker winning-ads following --output md"
|
|
@@ -31548,7 +32205,7 @@ var followingCommand = defineCommand174({
|
|
|
31548
32205
|
});
|
|
31549
32206
|
|
|
31550
32207
|
// src/commands/winning-ads/patterns.ts
|
|
31551
|
-
import { defineCommand as
|
|
32208
|
+
import { defineCommand as defineCommand179 } from "citty";
|
|
31552
32209
|
registerSchema({
|
|
31553
32210
|
command: "winning-ads.patterns",
|
|
31554
32211
|
description: "Mine what separates two cohorts of ads: pass a comma-list of winning ad ids (--winners) and a comma-list of weaker ad ids (--duds). Returns the discriminating DNA fields.",
|
|
@@ -31587,7 +32244,7 @@ function discriminatorRow(record) {
|
|
|
31587
32244
|
top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
|
|
31588
32245
|
};
|
|
31589
32246
|
}
|
|
31590
|
-
var patternsCommand =
|
|
32247
|
+
var patternsCommand = defineCommand179({
|
|
31591
32248
|
meta: {
|
|
31592
32249
|
name: "patterns",
|
|
31593
32250
|
description: "Discover what separates winning ads from weak ones. Example: baker winning-ads patterns --winners a_1,a_2,a_3 --duds a_9,a_8 --output md"
|
|
@@ -31643,7 +32300,7 @@ var patternsCommand = defineCommand175({
|
|
|
31643
32300
|
});
|
|
31644
32301
|
|
|
31645
32302
|
// src/commands/winning-ads/search.ts
|
|
31646
|
-
import { defineCommand as
|
|
32303
|
+
import { defineCommand as defineCommand180 } from "citty";
|
|
31647
32304
|
registerSchema({
|
|
31648
32305
|
command: "winning-ads.search",
|
|
31649
32306
|
description: "Search the ad-dna corpus of scored winning ads. Returns a lean shortlist (advertiser, summary, scores, media_url) to pick a reference to reproduce.",
|
|
@@ -31751,7 +32408,7 @@ function buildSearchBody(args) {
|
|
|
31751
32408
|
}
|
|
31752
32409
|
return body;
|
|
31753
32410
|
}
|
|
31754
|
-
var searchCommand4 =
|
|
32411
|
+
var searchCommand4 = defineCommand180({
|
|
31755
32412
|
meta: {
|
|
31756
32413
|
name: "search",
|
|
31757
32414
|
description: "Search winning reference ads. Example: baker winning-ads search 'B2B SaaS before/after AI automation' --platform meta --format static --winner-category winner --exclude-advertiser adv_123 --output md"
|
|
@@ -31866,7 +32523,7 @@ var searchCommand4 = defineCommand176({
|
|
|
31866
32523
|
});
|
|
31867
32524
|
|
|
31868
32525
|
// src/commands/winning-ads/seeds.ts
|
|
31869
|
-
import { defineCommand as
|
|
32526
|
+
import { defineCommand as defineCommand181 } from "citty";
|
|
31870
32527
|
function leanRow(r) {
|
|
31871
32528
|
return {
|
|
31872
32529
|
key: r.key,
|
|
@@ -31894,7 +32551,7 @@ function makeSeedCommand(opts) {
|
|
|
31894
32551
|
limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
|
|
31895
32552
|
}
|
|
31896
32553
|
});
|
|
31897
|
-
return
|
|
32554
|
+
return defineCommand181({
|
|
31898
32555
|
meta: { name: opts.name, description: opts.description },
|
|
31899
32556
|
args: {
|
|
31900
32557
|
platform: { type: "string", description: "Single platform to segment on", required: false },
|
|
@@ -31943,7 +32600,7 @@ var formatsCommand = makeSeedCommand({
|
|
|
31943
32600
|
});
|
|
31944
32601
|
|
|
31945
32602
|
// src/commands/winning-ads/unfollow.ts
|
|
31946
|
-
import { defineCommand as
|
|
32603
|
+
import { defineCommand as defineCommand182 } from "citty";
|
|
31947
32604
|
registerSchema({
|
|
31948
32605
|
command: "winning-ads.unfollow",
|
|
31949
32606
|
description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
|
|
@@ -31951,7 +32608,7 @@ registerSchema({
|
|
|
31951
32608
|
advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
|
|
31952
32609
|
}
|
|
31953
32610
|
});
|
|
31954
|
-
var unfollowCommand =
|
|
32611
|
+
var unfollowCommand = defineCommand182({
|
|
31955
32612
|
meta: {
|
|
31956
32613
|
name: "unfollow",
|
|
31957
32614
|
description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
|
|
@@ -31972,7 +32629,7 @@ var unfollowCommand = defineCommand178({
|
|
|
31972
32629
|
});
|
|
31973
32630
|
|
|
31974
32631
|
// src/commands/winning-ads/winners.ts
|
|
31975
|
-
import { defineCommand as
|
|
32632
|
+
import { defineCommand as defineCommand183 } from "citty";
|
|
31976
32633
|
registerSchema({
|
|
31977
32634
|
command: "winning-ads.winners",
|
|
31978
32635
|
description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
|
|
@@ -31982,7 +32639,7 @@ registerSchema({
|
|
|
31982
32639
|
platform: { type: "string", description: "Filter to a single platform: meta|linkedin", required: false }
|
|
31983
32640
|
}
|
|
31984
32641
|
});
|
|
31985
|
-
var winnersCommand =
|
|
32642
|
+
var winnersCommand = defineCommand183({
|
|
31986
32643
|
meta: {
|
|
31987
32644
|
name: "winners",
|
|
31988
32645
|
description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
|
|
@@ -32032,7 +32689,7 @@ var winnersCommand = defineCommand179({
|
|
|
32032
32689
|
});
|
|
32033
32690
|
|
|
32034
32691
|
// src/commands/winning-ads/index.ts
|
|
32035
|
-
var winningAdsCommand =
|
|
32692
|
+
var winningAdsCommand = defineCommand184({
|
|
32036
32693
|
meta: {
|
|
32037
32694
|
name: "winning-ads",
|
|
32038
32695
|
description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce, and manage the brands your library tracks. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
|
|
@@ -32088,7 +32745,7 @@ Full guide: __tooling__/docs/tools/baker/winning-ads.md`
|
|
|
32088
32745
|
});
|
|
32089
32746
|
|
|
32090
32747
|
// src/version.ts
|
|
32091
|
-
import { readFileSync as
|
|
32748
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
32092
32749
|
function packageJsonUrl() {
|
|
32093
32750
|
return new URL("../package.json", import.meta.url);
|
|
32094
32751
|
}
|
|
@@ -32100,15 +32757,15 @@ function parsePackageVersion(raw) {
|
|
|
32100
32757
|
throw new Error("Invalid CLI package.json: missing version");
|
|
32101
32758
|
}
|
|
32102
32759
|
function getCliVersion() {
|
|
32103
|
-
return parsePackageVersion(
|
|
32760
|
+
return parsePackageVersion(readFileSync13(packageJsonUrl(), "utf8"));
|
|
32104
32761
|
}
|
|
32105
32762
|
|
|
32106
32763
|
// src/cli.ts
|
|
32107
|
-
var main =
|
|
32764
|
+
var main = defineCommand185({
|
|
32108
32765
|
meta: {
|
|
32109
32766
|
name: "baker",
|
|
32110
32767
|
version: getCliVersion(),
|
|
32111
|
-
description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, marketing tags, account history, and ad platform data in Baker.
|
|
32768
|
+
description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, marketing tags, Tag Manager containers, account history, and ad platform data in Baker.
|
|
32112
32769
|
|
|
32113
32770
|
Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
|
|
32114
32771
|
Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
|
|
@@ -32132,6 +32789,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
32132
32789
|
testimonials: testimonialsCommand,
|
|
32133
32790
|
canvas: canvasCommand,
|
|
32134
32791
|
tags: tagsCommand3,
|
|
32792
|
+
"tag-manager": tagManagerCommand,
|
|
32135
32793
|
chats: chatsCommand,
|
|
32136
32794
|
history: historyCommand,
|
|
32137
32795
|
hubspot: hubspotCommand,
|