@koda-sl/baker-cli 0.298.0-dev.fd66d4f19 → 0.298.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 +0 -1
- package/dist/{chunk-HVITCN7H.js → chunk-YFQWCJX4.js} +4 -4
- package/dist/chunk-YFQWCJX4.js.map +1 -0
- package/dist/cli.js +117 -29
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-HVITCN7H.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
ulid,
|
|
59
59
|
validateCanvasDeep,
|
|
60
60
|
ytDlpBlockSignal
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-YFQWCJX4.js";
|
|
62
62
|
import {
|
|
63
63
|
csvOrJson,
|
|
64
64
|
daysAgoIso,
|
|
@@ -1427,6 +1427,7 @@ var TEMP_REF_PREFIX = "li_temp_";
|
|
|
1427
1427
|
var TEMP_REF_REGEX = /^li_temp_[A-Za-z0-9_-]{4,}$/;
|
|
1428
1428
|
var NUMERIC_ID_REGEX = /^\d+$/;
|
|
1429
1429
|
var URN_REGEX = /^urn:li:[a-zA-Z]+:.+$/;
|
|
1430
|
+
var CONVERSION_URN_REGEX = /^urn:lla:llaPartnerConversion:\d+$/;
|
|
1430
1431
|
var SPONSORED_ACCOUNT_URN_REGEX = /^urn:li:sponsoredAccount:\d+$/;
|
|
1431
1432
|
var IMAGE_URN_REGEX = /^urn:li:image:.+$/;
|
|
1432
1433
|
var VIDEO_URN_REGEX = /^urn:li:video:.+$/;
|
|
@@ -2006,12 +2007,44 @@ var LINKEDIN_DRAFT_OP_KINDS = [
|
|
|
2006
2007
|
"audience.uploadList",
|
|
2007
2008
|
"conversion.create",
|
|
2008
2009
|
"conversion.update",
|
|
2010
|
+
"conversion.associateCampaign",
|
|
2011
|
+
"conversion.dissociateCampaign",
|
|
2009
2012
|
"leadForm.create",
|
|
2010
2013
|
"leadForm.update"
|
|
2011
2014
|
];
|
|
2012
2015
|
var linkedinDraftOpKindSchema = z3.enum(LINKEDIN_DRAFT_OP_KINDS);
|
|
2013
2016
|
var accountIdSchema = z3.string().regex(NUMERIC_ID_REGEX, "accountId must be the bare numeric ad account id");
|
|
2014
2017
|
var updateTargetSchema = z3.union([z3.string().regex(URN_REGEX), z3.string().regex(NUMERIC_ID_REGEX), tempRefSchema]);
|
|
2018
|
+
var conversionCampaignTargetSchema = z3.union([
|
|
2019
|
+
// LinkedIn's own namespace for a conversion rule is `urn:lla:` — it is what
|
|
2020
|
+
// the `campaignConversions` key and the CAPI payload use, and what LinkedIn's
|
|
2021
|
+
// docs show — while `conversions list` prints Baker's `urn:li:` spelling of
|
|
2022
|
+
// the same rule. `URN_REGEX` is urn:li: only, so accept the other one here
|
|
2023
|
+
// rather than have the agent translate between two names for one rule.
|
|
2024
|
+
z3.string().regex(CONVERSION_URN_REGEX),
|
|
2025
|
+
z3.string().regex(URN_REGEX),
|
|
2026
|
+
z3.string().regex(NUMERIC_ID_REGEX),
|
|
2027
|
+
tempRefSchema
|
|
2028
|
+
]);
|
|
2029
|
+
var conversionCampaignSchema = z3.object({
|
|
2030
|
+
campaign: z3.union([z3.string().regex(URN_REGEX), z3.string().regex(NUMERIC_ID_REGEX), tempRefSchema])
|
|
2031
|
+
});
|
|
2032
|
+
function conversionCampaignOp(kind) {
|
|
2033
|
+
return z3.object({
|
|
2034
|
+
kind: z3.literal(kind),
|
|
2035
|
+
accountId: accountIdSchema,
|
|
2036
|
+
target: conversionCampaignTargetSchema,
|
|
2037
|
+
payload: conversionCampaignSchema
|
|
2038
|
+
}).superRefine((op, ctx) => {
|
|
2039
|
+
if (TEMP_REF_REGEX.test(op.target)) {
|
|
2040
|
+
ctx.addIssue({
|
|
2041
|
+
code: "custom",
|
|
2042
|
+
path: ["target"],
|
|
2043
|
+
message: "a conversion rule staged in this same chat has no id yet, so it cannot be linked to a campaign \u2014 stage the rule with associateAllCampaigns, or link it once this chat has published"
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2046
|
+
});
|
|
2047
|
+
}
|
|
2015
2048
|
function createOp(kind, payload) {
|
|
2016
2049
|
return z3.object({ kind: z3.literal(kind), accountId: accountIdSchema, payload });
|
|
2017
2050
|
}
|
|
@@ -2039,6 +2072,8 @@ var linkedinDraftOpInputSchema = z3.discriminatedUnion("kind", [
|
|
|
2039
2072
|
createOp("audience.uploadList", audienceUploadListSchema),
|
|
2040
2073
|
createOp("conversion.create", conversionCreateSchema),
|
|
2041
2074
|
updateOp("conversion.update", conversionUpdateSchema),
|
|
2075
|
+
conversionCampaignOp("conversion.associateCampaign"),
|
|
2076
|
+
conversionCampaignOp("conversion.dissociateCampaign"),
|
|
2042
2077
|
createOp("leadForm.create", leadFormCreateSchema),
|
|
2043
2078
|
updateOp("leadForm.update", leadFormUpdateSchema)
|
|
2044
2079
|
]);
|
|
@@ -7339,16 +7374,7 @@ var SURFACE_RULES = [
|
|
|
7339
7374
|
/\bhotjar\b/i,
|
|
7340
7375
|
/\bgtm\s+snippet\b/i,
|
|
7341
7376
|
/\bcapi\b/i,
|
|
7342
|
-
/\b(?:install|add|remove|swap|instalar|colocar
|
|
7343
|
-
// The product's own word for this object, in both languages. A tracking
|
|
7344
|
-
// script named in Spanish ("el código de seguimiento de HubSpot", "una
|
|
7345
|
-
// etiqueta tipo hubspot") matched none of the signals above, so the one
|
|
7346
|
-
// Task that most needed the redirect — file it, or show the form? — was
|
|
7347
|
-
// filed. `tag-manager` is evaluated first and still claims the container.
|
|
7348
|
-
/\btracking\s+(?:code|script|snippet|tag)\b/i,
|
|
7349
|
-
/\bcodigos?\s+de\s+seguimiento\b/i,
|
|
7350
|
-
/\bscripts?\s+de\s+seguimiento\b/i,
|
|
7351
|
-
/\betiquetas?\s+(?:de\s+seguimiento|de\s+medicion|tipo\s+\w+)\b/i
|
|
7377
|
+
/\b(?:install|add|remove|swap|instalar|colocar)\b[\s\S]*\b(?:snippet|script|tag)\b/i
|
|
7352
7378
|
],
|
|
7353
7379
|
// Two vetoes. A structured snippet is a Google Ads extension, not a script
|
|
7354
7380
|
// on the page — `ads-write` claims it above, and this stops both rules
|
|
@@ -18288,6 +18314,24 @@ registerSchema({
|
|
|
18288
18314
|
file: { type: "string", description: "JSON file with fields to change", required: false }
|
|
18289
18315
|
}
|
|
18290
18316
|
});
|
|
18317
|
+
registerSchema({
|
|
18318
|
+
command: "ads.linkedin.conversions.associate-campaign",
|
|
18319
|
+
description: "Count an existing conversion rule for one ad set. Which ad sets a rule counts for is a separate LinkedIn record, not a field on the rule \u2014 `conversions update` cannot change it, and `--associate-all-campaigns` exists only on create. Staged until publish.",
|
|
18320
|
+
args: {
|
|
18321
|
+
id: { type: "positional", description: "Conversion rule id or URN", required: true },
|
|
18322
|
+
...writeAccountArgs,
|
|
18323
|
+
campaign: { type: "string", description: "Ad set (campaign) id or URN", required: true }
|
|
18324
|
+
}
|
|
18325
|
+
});
|
|
18326
|
+
registerSchema({
|
|
18327
|
+
command: "ads.linkedin.conversions.dissociate-campaign",
|
|
18328
|
+
description: "Stop counting an existing conversion rule for one ad set. Staged until publish.",
|
|
18329
|
+
args: {
|
|
18330
|
+
id: { type: "positional", description: "Conversion rule id or URN", required: true },
|
|
18331
|
+
...writeAccountArgs,
|
|
18332
|
+
campaign: { type: "string", description: "Ad set (campaign) id or URN", required: true }
|
|
18333
|
+
}
|
|
18334
|
+
});
|
|
18291
18335
|
registerSchema({
|
|
18292
18336
|
command: "ads.linkedin.lead-forms.create",
|
|
18293
18337
|
description: "Stage a new Lead Gen Form from a JSON file: {name, headline \u226460, description? \u2264160, privacyPolicyUrl, questions[] \u226412 (playbook: \u22644 for completion), thankYou?, legalDisclaimer?}. Staged until publish.",
|
|
@@ -19092,6 +19136,57 @@ Example: baker ads linkedin conversions update 104988516 --post-click-window 30
|
|
|
19092
19136
|
});
|
|
19093
19137
|
}
|
|
19094
19138
|
});
|
|
19139
|
+
var CONVERSION_CAMPAIGN_EXPLAINER = `Which ad sets a conversion rule counts for is a separate LinkedIn record, not a field on the rule \u2014 \`conversions update\` cannot change it, and \`--associate-all-campaigns\` only exists on create.`;
|
|
19140
|
+
function conversionCampaignArgs() {
|
|
19141
|
+
return {
|
|
19142
|
+
id: { type: "positional", description: "Conversion rule id or URN", required: true },
|
|
19143
|
+
...accountArgs,
|
|
19144
|
+
campaign: { type: "string", description: "Ad set (campaign) id or URN", required: true }
|
|
19145
|
+
};
|
|
19146
|
+
}
|
|
19147
|
+
function requireCampaignArg(args) {
|
|
19148
|
+
const campaign = args.campaign;
|
|
19149
|
+
if (typeof campaign !== "string" || campaign.length === 0) {
|
|
19150
|
+
failWriteValidation2("--campaign is required \u2014 pass the ad set id or URN this conversion should count for");
|
|
19151
|
+
}
|
|
19152
|
+
return campaign;
|
|
19153
|
+
}
|
|
19154
|
+
var conversionsAssociateCommand = defineCommand33({
|
|
19155
|
+
meta: {
|
|
19156
|
+
name: "associate-campaign",
|
|
19157
|
+
description: `Count an existing conversion rule for one ad set. ${STAGED_NOTE}
|
|
19158
|
+
${CONVERSION_CAMPAIGN_EXPLAINER}
|
|
19159
|
+
Example: baker ads linkedin conversions associate-campaign 104988516 --campaign 337643194`
|
|
19160
|
+
},
|
|
19161
|
+
args: conversionCampaignArgs(),
|
|
19162
|
+
run: async ({ args }) => {
|
|
19163
|
+
const accountId = bareAccountId(args);
|
|
19164
|
+
await stageOp({
|
|
19165
|
+
kind: "conversion.associateCampaign",
|
|
19166
|
+
accountId,
|
|
19167
|
+
target: requireTarget2(args, "conversion rule"),
|
|
19168
|
+
payload: { campaign: requireCampaignArg(args) }
|
|
19169
|
+
});
|
|
19170
|
+
}
|
|
19171
|
+
});
|
|
19172
|
+
var conversionsDissociateCommand = defineCommand33({
|
|
19173
|
+
meta: {
|
|
19174
|
+
name: "dissociate-campaign",
|
|
19175
|
+
description: `Stop counting an existing conversion rule for one ad set. ${STAGED_NOTE}
|
|
19176
|
+
${CONVERSION_CAMPAIGN_EXPLAINER}
|
|
19177
|
+
Example: baker ads linkedin conversions dissociate-campaign 104988516 --campaign 337643194`
|
|
19178
|
+
},
|
|
19179
|
+
args: conversionCampaignArgs(),
|
|
19180
|
+
run: async ({ args }) => {
|
|
19181
|
+
const accountId = bareAccountId(args);
|
|
19182
|
+
await stageOp({
|
|
19183
|
+
kind: "conversion.dissociateCampaign",
|
|
19184
|
+
accountId,
|
|
19185
|
+
target: requireTarget2(args, "conversion rule"),
|
|
19186
|
+
payload: { campaign: requireCampaignArg(args) }
|
|
19187
|
+
});
|
|
19188
|
+
}
|
|
19189
|
+
});
|
|
19095
19190
|
var leadFormsCreateCommand = defineCommand33({
|
|
19096
19191
|
meta: {
|
|
19097
19192
|
name: "create",
|
|
@@ -20224,13 +20319,17 @@ var conversionsCommand2 = defineCommand43({
|
|
|
20224
20319
|
Subcommands:
|
|
20225
20320
|
list \u2014 every rule on the account
|
|
20226
20321
|
health \u2014 playbook \xA707 5-point health check
|
|
20227
|
-
create / update \u2014 stage a conversion-rule write (applies on chat publish)
|
|
20322
|
+
create / update \u2014 stage a conversion-rule write (applies on chat publish)
|
|
20323
|
+
associate-campaign / dissociate-campaign
|
|
20324
|
+
\u2014 which ad sets a rule counts for (its own LinkedIn record, not a field on the rule)`
|
|
20228
20325
|
},
|
|
20229
20326
|
subCommands: {
|
|
20230
20327
|
list: listCmd,
|
|
20231
20328
|
health: healthCmd,
|
|
20232
20329
|
create: conversionsCreateCommand,
|
|
20233
|
-
update: conversionsUpdateCommand
|
|
20330
|
+
update: conversionsUpdateCommand,
|
|
20331
|
+
"associate-campaign": conversionsAssociateCommand,
|
|
20332
|
+
"dissociate-campaign": conversionsDissociateCommand
|
|
20234
20333
|
}
|
|
20235
20334
|
});
|
|
20236
20335
|
|
|
@@ -57841,12 +57940,6 @@ function renderEffectiveEntry(entry) {
|
|
|
57841
57940
|
return configLines.length > 0 ? `${header}
|
|
57842
57941
|
${configLines.join("\n")}` : header;
|
|
57843
57942
|
}
|
|
57844
|
-
function tagsListHints() {
|
|
57845
|
-
return [
|
|
57846
|
-
"To create, edit or delete a tag, call the `request_tag_input` approval form (tool `mcp__baker_ui__request_tag_input`, server `baker_ui`) \u2014 it is attached to every turn of this chat and collects any secret values itself.",
|
|
57847
|
-
"Do NOT conclude the form is unavailable from your tool list: call it, and report what it returns. And never file a tag change as a Task \u2014 a Task hands the user work this chat can stage in one call."
|
|
57848
|
-
];
|
|
57849
|
-
}
|
|
57850
57943
|
|
|
57851
57944
|
// src/commands/tags/index.ts
|
|
57852
57945
|
registerSchema({
|
|
@@ -57860,21 +57953,16 @@ async function listTags(json) {
|
|
|
57860
57953
|
try {
|
|
57861
57954
|
const chatId = requireChatId();
|
|
57862
57955
|
const response = await apiPost("/api/tags/list", { chatId });
|
|
57863
|
-
const hints2 = tagsListHints();
|
|
57864
57956
|
if (json) {
|
|
57865
|
-
writeJson({ ok: true, data: response
|
|
57957
|
+
writeJson({ ok: true, data: response });
|
|
57866
57958
|
return;
|
|
57867
57959
|
}
|
|
57868
57960
|
if (response.tags.length === 0) {
|
|
57869
|
-
process.stdout.write("No tags configured.\n");
|
|
57870
|
-
|
|
57871
|
-
process.stdout.write(`${response.tags.map(renderEffectiveEntry).join("\n")}
|
|
57872
|
-
`);
|
|
57961
|
+
process.stdout.write("No tags configured. Propose one with the request_tag_input tool (baker_ui).\n");
|
|
57962
|
+
return;
|
|
57873
57963
|
}
|
|
57874
|
-
|
|
57875
|
-
process.stderr.write(`${hint}
|
|
57964
|
+
process.stdout.write(`${response.tags.map(renderEffectiveEntry).join("\n")}
|
|
57876
57965
|
`);
|
|
57877
|
-
}
|
|
57878
57966
|
} catch (err) {
|
|
57879
57967
|
failApi3(err);
|
|
57880
57968
|
}
|
|
@@ -57896,7 +57984,7 @@ async function listDraft4(chat) {
|
|
|
57896
57984
|
try {
|
|
57897
57985
|
const chatId = resolveChatId(chat);
|
|
57898
57986
|
const response = await apiPost("/api/tags/draft", { chatId });
|
|
57899
|
-
writeJson({ ok: true, data: response
|
|
57987
|
+
writeJson({ ok: true, data: response });
|
|
57900
57988
|
} catch (err) {
|
|
57901
57989
|
failApi3(err);
|
|
57902
57990
|
}
|