@koda-sl/baker-cli 0.26.0 → 0.27.1-dev.bcbc31f8
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 +146 -0
- package/dist/cli.js +1 -1
- package/dist/commands/actions/create.d.ts.map +1 -1
- package/dist/commands/actions/create.js +10 -2
- package/dist/commands/actions/create.js.map +1 -1
- package/dist/commands/ads/index.d.ts.map +1 -1
- package/dist/commands/ads/index.js +7 -3
- package/dist/commands/ads/index.js.map +1 -1
- package/dist/commands/ads/linkedin/account.d.ts +20 -0
- package/dist/commands/ads/linkedin/account.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/account.js +39 -0
- package/dist/commands/ads/linkedin/account.js.map +1 -0
- package/dist/commands/ads/linkedin/accounts.d.ts +20 -0
- package/dist/commands/ads/linkedin/accounts.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/accounts.js +56 -0
- package/dist/commands/ads/linkedin/accounts.js.map +1 -0
- package/dist/commands/ads/linkedin/analytics.d.ts +84 -0
- package/dist/commands/ads/linkedin/analytics.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/analytics.js +249 -0
- package/dist/commands/ads/linkedin/analytics.js.map +1 -0
- package/dist/commands/ads/linkedin/audience-size.d.ts +28 -0
- package/dist/commands/ads/linkedin/audience-size.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/audience-size.js +75 -0
- package/dist/commands/ads/linkedin/audience-size.js.map +1 -0
- package/dist/commands/ads/linkedin/audit.d.ts +35 -0
- package/dist/commands/ads/linkedin/audit.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/audit.js +136 -0
- package/dist/commands/ads/linkedin/audit.js.map +1 -0
- package/dist/commands/ads/linkedin/bid-pricing.d.ts +38 -0
- package/dist/commands/ads/linkedin/bid-pricing.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/bid-pricing.js +76 -0
- package/dist/commands/ads/linkedin/bid-pricing.js.map +1 -0
- package/dist/commands/ads/linkedin/campaign-groups.d.ts +32 -0
- package/dist/commands/ads/linkedin/campaign-groups.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/campaign-groups.js +50 -0
- package/dist/commands/ads/linkedin/campaign-groups.js.map +1 -0
- package/dist/commands/ads/linkedin/campaigns.d.ts +36 -0
- package/dist/commands/ads/linkedin/campaigns.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/campaigns.js +57 -0
- package/dist/commands/ads/linkedin/campaigns.js.map +1 -0
- package/dist/commands/ads/linkedin/conversation.d.ts +36 -0
- package/dist/commands/ads/linkedin/conversation.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/conversation.js +77 -0
- package/dist/commands/ads/linkedin/conversation.js.map +1 -0
- package/dist/commands/ads/linkedin/conversions.d.ts +2 -0
- package/dist/commands/ads/linkedin/conversions.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/conversions.js +102 -0
- package/dist/commands/ads/linkedin/conversions.js.map +1 -0
- package/dist/commands/ads/linkedin/creatives.d.ts +36 -0
- package/dist/commands/ads/linkedin/creatives.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/creatives.js +57 -0
- package/dist/commands/ads/linkedin/creatives.js.map +1 -0
- package/dist/commands/ads/linkedin/demographics.d.ts +40 -0
- package/dist/commands/ads/linkedin/demographics.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/demographics.js +117 -0
- package/dist/commands/ads/linkedin/demographics.js.map +1 -0
- package/dist/commands/ads/linkedin/facets.d.ts +2 -0
- package/dist/commands/ads/linkedin/facets.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/facets.js +95 -0
- package/dist/commands/ads/linkedin/facets.js.map +1 -0
- package/dist/commands/ads/linkedin/forecast.d.ts +50 -0
- package/dist/commands/ads/linkedin/forecast.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/forecast.js +83 -0
- package/dist/commands/ads/linkedin/forecast.js.map +1 -0
- package/dist/commands/ads/linkedin/index.d.ts +19 -0
- package/dist/commands/ads/linkedin/index.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/index.js +83 -0
- package/dist/commands/ads/linkedin/index.js.map +1 -0
- package/dist/commands/ads/linkedin/leads.d.ts +40 -0
- package/dist/commands/ads/linkedin/leads.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/leads.js +75 -0
- package/dist/commands/ads/linkedin/leads.js.map +1 -0
- package/dist/commands/ads/linkedin/presets.d.ts +40 -0
- package/dist/commands/ads/linkedin/presets.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/presets.js +193 -0
- package/dist/commands/ads/linkedin/presets.js.map +1 -0
- package/dist/commands/ads/linkedin/presets.test.d.ts +2 -0
- package/dist/commands/ads/linkedin/presets.test.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/presets.test.js +98 -0
- package/dist/commands/ads/linkedin/presets.test.js.map +1 -0
- package/dist/commands/ads/linkedin/schemas.d.ts +2 -0
- package/dist/commands/ads/linkedin/schemas.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/schemas.js +300 -0
- package/dist/commands/ads/linkedin/schemas.js.map +1 -0
- package/dist/commands/ads/linkedin/shared.d.ts +17 -0
- package/dist/commands/ads/linkedin/shared.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/shared.js +116 -0
- package/dist/commands/ads/linkedin/shared.js.map +1 -0
- package/dist/commands/ads/linkedin/top-companies.d.ts +44 -0
- package/dist/commands/ads/linkedin/top-companies.d.ts.map +1 -0
- package/dist/commands/ads/linkedin/top-companies.js +86 -0
- package/dist/commands/ads/linkedin/top-companies.js.map +1 -0
- package/dist/env.d.ts +1 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +4 -0
- package/dist/env.js.map +1 -1
- package/dist/error-handler.d.ts +1 -1
- package/dist/error-handler.d.ts.map +1 -1
- package/dist/error-handler.js +3 -0
- package/dist/error-handler.js.map +1 -1
- package/dist/output.d.ts +1 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { apiPost } from "../../../client.js";
|
|
3
|
+
import { writeAdsJson, writeAdsOutput } from "../output.js";
|
|
4
|
+
import { ALL_LEVELS, ALL_PIVOTS, composeFields, isLevel, isPivot, listIntents, MEMBER_PIVOTS, } from "./presets.js";
|
|
5
|
+
import { csvOrJson, daysAgoIso, handleLinkedinError, resolveAccountIdArg, todayIso } from "./shared.js";
|
|
6
|
+
function commaSplit(input) {
|
|
7
|
+
if (!input)
|
|
8
|
+
return undefined;
|
|
9
|
+
return input
|
|
10
|
+
.split(",")
|
|
11
|
+
.map((s) => s.trim())
|
|
12
|
+
.filter(Boolean);
|
|
13
|
+
}
|
|
14
|
+
function parseGranularity(raw) {
|
|
15
|
+
const v = (raw ?? "DAILY").toUpperCase();
|
|
16
|
+
if (v === "DAILY" || v === "MONTHLY" || v === "YEARLY" || v === "ALL") {
|
|
17
|
+
return v;
|
|
18
|
+
}
|
|
19
|
+
handleLinkedinError(new Error(`Invalid --granularity "${raw}". Use DAILY | MONTHLY | YEARLY | ALL.`));
|
|
20
|
+
}
|
|
21
|
+
function parseLevel(raw) {
|
|
22
|
+
const v = raw ?? "account";
|
|
23
|
+
if (!isLevel(v)) {
|
|
24
|
+
handleLinkedinError(new Error(`Invalid --level "${raw}". Use one of: ${ALL_LEVELS.join(", ")}.`));
|
|
25
|
+
}
|
|
26
|
+
return v;
|
|
27
|
+
}
|
|
28
|
+
function parsePivot(raw) {
|
|
29
|
+
const v = raw ?? "none";
|
|
30
|
+
if (!isPivot(v)) {
|
|
31
|
+
handleLinkedinError(new Error(`Invalid --pivot "${raw}". Use one of: ${ALL_PIVOTS.join(", ")}.`));
|
|
32
|
+
}
|
|
33
|
+
return v;
|
|
34
|
+
}
|
|
35
|
+
function parseIntent(raw) {
|
|
36
|
+
const v = (raw ?? "baseline");
|
|
37
|
+
const known = [
|
|
38
|
+
"baseline",
|
|
39
|
+
"revenue",
|
|
40
|
+
"funnel",
|
|
41
|
+
"engagement",
|
|
42
|
+
"video",
|
|
43
|
+
"lead-gen",
|
|
44
|
+
"inmail",
|
|
45
|
+
"document",
|
|
46
|
+
"ranking",
|
|
47
|
+
"identity",
|
|
48
|
+
];
|
|
49
|
+
if (!known.includes(v)) {
|
|
50
|
+
handleLinkedinError(new Error(`Invalid --intent "${raw}". Run --list-intents to see options.`));
|
|
51
|
+
}
|
|
52
|
+
return v;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Resolve start/end dates. Precedence:
|
|
56
|
+
* 1. --start + --end (explicit window)
|
|
57
|
+
* 2. --last-days N → end=today, start=today-N
|
|
58
|
+
* 3. default: last 7 days
|
|
59
|
+
*/
|
|
60
|
+
function resolveDateRange(args) {
|
|
61
|
+
const start = args.start;
|
|
62
|
+
const end = args.end;
|
|
63
|
+
if (start) {
|
|
64
|
+
return { start, end };
|
|
65
|
+
}
|
|
66
|
+
const lastDaysRaw = args["last-days"];
|
|
67
|
+
const days = lastDaysRaw ? Number(lastDaysRaw) : 7;
|
|
68
|
+
if (!Number.isFinite(days) || days < 1 || days > 730) {
|
|
69
|
+
handleLinkedinError(new Error(`Invalid --last-days "${lastDaysRaw}". Use a positive number ≤ 730.`));
|
|
70
|
+
}
|
|
71
|
+
return { start: daysAgoIso(days), end: todayIso() };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Resolve scope IDs. Each level expects a different flag — but we accept
|
|
75
|
+
* --account-id at every level when level=account, and --campaign-id /
|
|
76
|
+
* --campaign-group-id / --creative-id otherwise. CSV-encoded for multi-id.
|
|
77
|
+
*/
|
|
78
|
+
function resolveScopeIds(args, level) {
|
|
79
|
+
if (level === "account") {
|
|
80
|
+
const id = resolveAccountIdArg(args);
|
|
81
|
+
return [id];
|
|
82
|
+
}
|
|
83
|
+
if (level === "campaign-group") {
|
|
84
|
+
const raw = args["campaign-group-id"] ?? args.ids;
|
|
85
|
+
if (!raw) {
|
|
86
|
+
handleLinkedinError(new Error("Pass --campaign-group-id (CSV for multi) when --level campaign-group."));
|
|
87
|
+
}
|
|
88
|
+
return commaSplit(raw) ?? [];
|
|
89
|
+
}
|
|
90
|
+
if (level === "campaign") {
|
|
91
|
+
const raw = args["campaign-id"] ?? args.ids;
|
|
92
|
+
if (!raw) {
|
|
93
|
+
handleLinkedinError(new Error("Pass --campaign-id (CSV for multi) when --level campaign."));
|
|
94
|
+
}
|
|
95
|
+
return commaSplit(raw) ?? [];
|
|
96
|
+
}
|
|
97
|
+
// creative
|
|
98
|
+
const raw = args["creative-id"] ?? args.ids;
|
|
99
|
+
if (!raw) {
|
|
100
|
+
handleLinkedinError(new Error("Pass --creative-id (CSV for multi) when --level creative."));
|
|
101
|
+
}
|
|
102
|
+
return commaSplit(raw) ?? [];
|
|
103
|
+
}
|
|
104
|
+
/** Sort rows by spend desc when present, otherwise by impressions desc. */
|
|
105
|
+
function sortRows(rows) {
|
|
106
|
+
return [...rows].sort((a, b) => {
|
|
107
|
+
const cs = numberOf(b.costInUsd) - numberOf(a.costInUsd);
|
|
108
|
+
if (cs !== 0)
|
|
109
|
+
return cs;
|
|
110
|
+
return numberOf(b.impressions) - numberOf(a.impressions);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function numberOf(v) {
|
|
114
|
+
if (typeof v === "number")
|
|
115
|
+
return Number.isFinite(v) ? v : 0;
|
|
116
|
+
if (typeof v === "string") {
|
|
117
|
+
const n = Number(v);
|
|
118
|
+
return Number.isFinite(n) ? n : 0;
|
|
119
|
+
}
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
export const analyticsCommand = defineCommand({
|
|
123
|
+
meta: {
|
|
124
|
+
name: "analytics",
|
|
125
|
+
description: `Performance reporting — the workhorse for AI agents.
|
|
126
|
+
|
|
127
|
+
Three-axis design (LinkedIn's superpower over Meta/Google):
|
|
128
|
+
--level account | campaign-group | campaign | creative
|
|
129
|
+
--intent baseline | revenue | funnel | engagement | video | lead-gen | inmail | document | ranking | identity
|
|
130
|
+
--pivot none | job-title | company | industry | seniority | function | company-size | country | region
|
|
131
|
+
| device | placement | serving-location | card-index | objective
|
|
132
|
+
| conversation-node | conversation-node-button
|
|
133
|
+
|
|
134
|
+
Smart defaults:
|
|
135
|
+
--level account, --intent baseline, --pivot none, --granularity DAILY, last 7 days
|
|
136
|
+
Pivot on a MEMBER_* dim → granularity auto-forced to ALL (LinkedIn rejects DAILY+demographic)
|
|
137
|
+
Demographic data delayed 12-24h with ≥3-event privacy floor — the CLI flags this in warnings.
|
|
138
|
+
Derived metrics injected client-side: ctr, cpc, cpm, frequency, leadCompletionRate
|
|
139
|
+
|
|
140
|
+
Examples — common AI questions:
|
|
141
|
+
# "How is this account doing this week?"
|
|
142
|
+
baker ads linkedin analytics
|
|
143
|
+
|
|
144
|
+
# "Who are we reaching, by job title?" (the LinkedIn killer)
|
|
145
|
+
baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot job-title --intent baseline --last-days 30
|
|
146
|
+
|
|
147
|
+
# "Top companies seeing my ads" (ABM feedback loop)
|
|
148
|
+
baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot company --last-days 30
|
|
149
|
+
|
|
150
|
+
# "Revenue by campaign over Q1"
|
|
151
|
+
baker ads linkedin analytics --level campaign --campaign-id 1,2,3 --intent revenue --start 2026-01-01 --end 2026-03-31 --granularity MONTHLY
|
|
152
|
+
|
|
153
|
+
# "How is the lead form converting?"
|
|
154
|
+
baker ads linkedin analytics --level campaign --campaign-id 1234 --intent lead-gen
|
|
155
|
+
|
|
156
|
+
# Custom field set (escape hatch)
|
|
157
|
+
baker ads linkedin analytics --metrics impressions,clicks,oneClickLeads --intent identity`,
|
|
158
|
+
},
|
|
159
|
+
args: {
|
|
160
|
+
level: { type: "string", description: "Object scope (default: account)" },
|
|
161
|
+
"account-id": { type: "string", description: "Account ID — numeric or urn:li:sponsoredAccount:N (level=account)" },
|
|
162
|
+
"account-urn": { type: "string", description: "Alias for --account-id (URN form)" },
|
|
163
|
+
"campaign-group-id": { type: "string", description: "Comma-separated IDs (level=campaign-group)" },
|
|
164
|
+
"campaign-id": { type: "string", description: "Comma-separated IDs (level=campaign)" },
|
|
165
|
+
"creative-id": { type: "string", description: "Comma-separated IDs (level=creative)" },
|
|
166
|
+
ids: { type: "string", description: "Generic CSV of IDs at the chosen level (alternative to per-level flags)" },
|
|
167
|
+
intent: {
|
|
168
|
+
type: "string",
|
|
169
|
+
description: "baseline|revenue|funnel|engagement|video|lead-gen|inmail|document|ranking|identity",
|
|
170
|
+
},
|
|
171
|
+
pivot: { type: "string", description: "Pivot dim. Default: none. See `--list-pivots`." },
|
|
172
|
+
metrics: { type: "string", description: "CSV metric override — bypass --intent's bundle" },
|
|
173
|
+
"list-intents": { type: "boolean", description: "Print intent definitions and exit" },
|
|
174
|
+
"list-pivots": { type: "boolean", description: "Print pivot slugs and exit" },
|
|
175
|
+
start: { type: "string", description: "Start date YYYY-MM-DD (overrides --last-days)" },
|
|
176
|
+
end: { type: "string", description: "End date YYYY-MM-DD" },
|
|
177
|
+
"last-days": { type: "string", description: "Window relative to today (default: 7)" },
|
|
178
|
+
granularity: { type: "string", description: "DAILY|MONTHLY|YEARLY|ALL (default: DAILY)" },
|
|
179
|
+
limit: { type: "string", description: "Max rows (default: 1000)" },
|
|
180
|
+
"no-sort": { type: "boolean", description: "Skip default sort by costInUsd desc" },
|
|
181
|
+
"skip-cache": { type: "boolean", description: "Bypass server-side cache" },
|
|
182
|
+
output: { type: "string", description: "Output format json|csv|jsonl|md", default: "json" },
|
|
183
|
+
},
|
|
184
|
+
run: async ({ args }) => {
|
|
185
|
+
if (args["list-intents"]) {
|
|
186
|
+
writeAdsJson({ ok: true, data: listIntents() });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (args["list-pivots"]) {
|
|
190
|
+
writeAdsJson({ ok: true, data: ALL_PIVOTS });
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const level = parseLevel(args.level);
|
|
194
|
+
const intent = parseIntent(args.intent);
|
|
195
|
+
const pivot = parsePivot(args.pivot);
|
|
196
|
+
let granularity = parseGranularity(args.granularity);
|
|
197
|
+
// CLI-side mirror of the backend's pivot/granularity guard. Backend will
|
|
198
|
+
// also enforce — this lets us echo the auto-correction in stderr early.
|
|
199
|
+
if (MEMBER_PIVOTS.has(pivot) && granularity === "DAILY") {
|
|
200
|
+
process.stderr.write(`note: pivot=${pivot} forces --granularity ALL (LinkedIn rejects DAILY + demographic).\n`);
|
|
201
|
+
granularity = "ALL";
|
|
202
|
+
}
|
|
203
|
+
const ids = resolveScopeIds(args, level);
|
|
204
|
+
if (ids.length === 0) {
|
|
205
|
+
handleLinkedinError(new Error(`No IDs resolved for --level ${level}`));
|
|
206
|
+
}
|
|
207
|
+
const range = resolveDateRange(args);
|
|
208
|
+
const metrics = commaSplit(args.metrics);
|
|
209
|
+
const limit = args.limit ? Number(args.limit) : 1000;
|
|
210
|
+
const request = {
|
|
211
|
+
level,
|
|
212
|
+
ids,
|
|
213
|
+
intent,
|
|
214
|
+
pivot,
|
|
215
|
+
metrics,
|
|
216
|
+
start: range.start,
|
|
217
|
+
end: range.end,
|
|
218
|
+
granularity,
|
|
219
|
+
limit,
|
|
220
|
+
};
|
|
221
|
+
try {
|
|
222
|
+
const data = await apiPost("/api/ads/linkedin/analytics", {
|
|
223
|
+
request,
|
|
224
|
+
skipCache: Boolean(args["skip-cache"]),
|
|
225
|
+
});
|
|
226
|
+
const rows = args["no-sort"] ? data.rows : sortRows(data.rows);
|
|
227
|
+
const fmt = csvOrJson(args);
|
|
228
|
+
if (fmt !== "json") {
|
|
229
|
+
writeAdsOutput(rows, fmt, data.fields);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
writeAdsJson({
|
|
233
|
+
ok: true,
|
|
234
|
+
data: {
|
|
235
|
+
rows,
|
|
236
|
+
fields: data.fields,
|
|
237
|
+
warnings: data.warnings,
|
|
238
|
+
query: data.query,
|
|
239
|
+
// Echo composed fields so an offline agent can pre-flight w/o this network call.
|
|
240
|
+
composedFields: composeFields(intent, level, metrics),
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
handleLinkedinError(err);
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../../src/commands/ads/linkedin/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const audienceSizeCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly "account-id": {
|
|
3
|
+
readonly type: "string";
|
|
4
|
+
readonly description: "Numeric account ID or urn:li:sponsoredAccount:N";
|
|
5
|
+
};
|
|
6
|
+
readonly "account-urn": {
|
|
7
|
+
readonly type: "string";
|
|
8
|
+
readonly description: "Alias for --account-id";
|
|
9
|
+
};
|
|
10
|
+
readonly targeting: {
|
|
11
|
+
readonly type: "string";
|
|
12
|
+
readonly description: "Inline JSON targetingCriteria payload";
|
|
13
|
+
};
|
|
14
|
+
readonly "targeting-file": {
|
|
15
|
+
readonly type: "string";
|
|
16
|
+
readonly description: "Path to JSON file with targetingCriteria";
|
|
17
|
+
};
|
|
18
|
+
readonly "skip-cache": {
|
|
19
|
+
readonly type: "boolean";
|
|
20
|
+
readonly description: "Bypass server-side cache";
|
|
21
|
+
};
|
|
22
|
+
readonly output: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly description: "json";
|
|
25
|
+
readonly default: "json";
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
28
|
+
//# sourceMappingURL=audience-size.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audience-size.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/linkedin/audience-size.ts"],"names":[],"mappings":"AAsCA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;EA0C9B,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { defineCommand } from "citty";
|
|
3
|
+
import { apiPost } from "../../../client.js";
|
|
4
|
+
import { writeAdsJson } from "../output.js";
|
|
5
|
+
import { handleLinkedinError, resolveAccountIdArg } from "./shared.js";
|
|
6
|
+
/**
|
|
7
|
+
* Read targeting JSON from --targeting-file, --targeting (inline JSON), or
|
|
8
|
+
* stdin. Returns the parsed object — failure exits via handleLinkedinError.
|
|
9
|
+
*/
|
|
10
|
+
function loadTargeting(args) {
|
|
11
|
+
const inline = args.targeting;
|
|
12
|
+
if (inline) {
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(inline);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
handleLinkedinError(new Error("--targeting must be valid JSON. See LinkedIn 'targetingCriteria' shape."));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const file = args["targeting-file"];
|
|
21
|
+
if (file) {
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
handleLinkedinError(new Error(`Failed to read --targeting-file: ${e instanceof Error ? e.message : "I/O error"}`));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
handleLinkedinError(new Error("Pass --targeting-file <path> or --targeting '{...JSON...}'"));
|
|
30
|
+
}
|
|
31
|
+
export const audienceSizeCommand = defineCommand({
|
|
32
|
+
meta: {
|
|
33
|
+
name: "audience-size",
|
|
34
|
+
description: `Estimate audience size for a targeting payload — pre-launch sanity check.
|
|
35
|
+
|
|
36
|
+
Returns total + active counts plus playbook §04 warnings:
|
|
37
|
+
size <20K → too narrow (will not deliver)
|
|
38
|
+
size <50K → outside the 50K–500K sweet spot
|
|
39
|
+
size >500K → outside the sweet spot
|
|
40
|
+
size >1M → too broad, refine ICP
|
|
41
|
+
|
|
42
|
+
The targeting payload must follow LinkedIn's 'targetingCriteria' shape — an
|
|
43
|
+
include/exclude tree of and/or boolean operators with adTargetingFacet keys.
|
|
44
|
+
The simplest form:
|
|
45
|
+
{ "include": { "and": [{ "or": { "urn:li:adTargetingFacet:locations": ["urn:li:geo:103644278"] }}]}}
|
|
46
|
+
|
|
47
|
+
Examples:
|
|
48
|
+
baker ads linkedin audience-size --account-id 503001492 --targeting-file targeting.json
|
|
49
|
+
baker ads linkedin audience-size --account-id 503001492 --targeting '{"include":{"and":[]}}'`,
|
|
50
|
+
},
|
|
51
|
+
args: {
|
|
52
|
+
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
53
|
+
"account-urn": { type: "string", description: "Alias for --account-id" },
|
|
54
|
+
targeting: { type: "string", description: "Inline JSON targetingCriteria payload" },
|
|
55
|
+
"targeting-file": { type: "string", description: "Path to JSON file with targetingCriteria" },
|
|
56
|
+
"skip-cache": { type: "boolean", description: "Bypass server-side cache" },
|
|
57
|
+
output: { type: "string", description: "json", default: "json" },
|
|
58
|
+
},
|
|
59
|
+
run: async ({ args }) => {
|
|
60
|
+
const accountId = resolveAccountIdArg(args);
|
|
61
|
+
const targetingCriteria = loadTargeting(args);
|
|
62
|
+
try {
|
|
63
|
+
const data = await apiPost("/api/ads/linkedin/audience-size", {
|
|
64
|
+
accountId,
|
|
65
|
+
targetingCriteria,
|
|
66
|
+
skipCache: Boolean(args["skip-cache"]),
|
|
67
|
+
});
|
|
68
|
+
writeAdsJson({ ok: true, data });
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
handleLinkedinError(err);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=audience-size.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audience-size.js","sourceRoot":"","sources":["../../../../src/commands/ads/linkedin/audience-size.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQvE;;;GAGG;AACH,SAAS,aAAa,CAAC,IAA6B;IAClD,MAAM,MAAM,GAAG,IAAI,CAAC,SAA+B,CAAC;IACpD,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB,CAAC,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAuB,CAAC;IAC1D,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,mBAAmB,CACjB,IAAI,KAAK,CAAC,oCAAoC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAC9F,CAAC;QACJ,CAAC;IACH,CAAC;IACD,mBAAmB,CAAC,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC;IAC/C,IAAI,EAAE;QACJ,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE;;;;;;;;;;;;;;;+FAe8E;KAC5F;IACD,IAAI,EAAE;QACJ,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iDAAiD,EAAE;QAChG,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE;QACxE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE;QACnF,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;QAC7F,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,0BAA0B,EAAE;QAC1E,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;KACjE;IACD,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,iBAAiB,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAqB,iCAAiC,EAAE;gBAChF,SAAS;gBACT,iBAAiB;gBACjB,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;aACvC,CAAC,CAAC;YACH,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare const auditCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly "account-id": {
|
|
3
|
+
readonly type: "string";
|
|
4
|
+
readonly description: "Numeric account ID or urn:li:sponsoredAccount:N";
|
|
5
|
+
};
|
|
6
|
+
readonly "account-urn": {
|
|
7
|
+
readonly type: "string";
|
|
8
|
+
readonly description: "Alias for --account-id";
|
|
9
|
+
};
|
|
10
|
+
readonly "campaign-id": {
|
|
11
|
+
readonly type: "string";
|
|
12
|
+
readonly description: "Narrow scope to a single campaign";
|
|
13
|
+
};
|
|
14
|
+
readonly "window-days": {
|
|
15
|
+
readonly type: "string";
|
|
16
|
+
readonly description: "Lookback window for performance checks (default: 30)";
|
|
17
|
+
};
|
|
18
|
+
readonly severity: {
|
|
19
|
+
readonly type: "string";
|
|
20
|
+
readonly description: "CSV severity filter: critical,high,medium,low";
|
|
21
|
+
};
|
|
22
|
+
readonly area: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly description: "CSV area filter: Settings,Tracking,Audience,Campaigns,Creative,Performance,Bidding,Compliance,Hygiene";
|
|
25
|
+
};
|
|
26
|
+
readonly format: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
readonly description: "Output format: json | md (default: json)";
|
|
29
|
+
};
|
|
30
|
+
readonly "skip-cache": {
|
|
31
|
+
readonly type: "boolean";
|
|
32
|
+
readonly description: "Bypass server-side cache";
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/linkedin/audit.ts"],"names":[],"mappings":"AAwGA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuEvB,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { apiPost } from "../../../client.js";
|
|
3
|
+
import { writeAdsJson } from "../output.js";
|
|
4
|
+
import { handleLinkedinError, resolveAccountIdArg } from "./shared.js";
|
|
5
|
+
const SEVERITY_RANK = {
|
|
6
|
+
critical: 0,
|
|
7
|
+
high: 1,
|
|
8
|
+
medium: 2,
|
|
9
|
+
low: 3,
|
|
10
|
+
};
|
|
11
|
+
const STATUS_RANK = {
|
|
12
|
+
fail: 0,
|
|
13
|
+
warn: 1,
|
|
14
|
+
partial: 2,
|
|
15
|
+
pass: 3,
|
|
16
|
+
n_a: 4,
|
|
17
|
+
};
|
|
18
|
+
function filterFindings(findings, severity, area) {
|
|
19
|
+
return findings.filter((f) => {
|
|
20
|
+
if (severity && !severity.includes(f.severity))
|
|
21
|
+
return false;
|
|
22
|
+
if (area && !area.includes(f.area))
|
|
23
|
+
return false;
|
|
24
|
+
return true;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function sortFindings(findings) {
|
|
28
|
+
return [...findings].sort((a, b) => {
|
|
29
|
+
const sa = STATUS_RANK[a.status] - STATUS_RANK[b.status];
|
|
30
|
+
if (sa !== 0)
|
|
31
|
+
return sa;
|
|
32
|
+
return SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity];
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Render the audit as a markdown table that mirrors
|
|
37
|
+
* google-ads-playbook/10-audit-summary.md so the agent can drop it into a
|
|
38
|
+
* client deliverable as-is.
|
|
39
|
+
*/
|
|
40
|
+
function renderMarkdown(result) {
|
|
41
|
+
const lines = [];
|
|
42
|
+
lines.push(`# LinkedIn Ads Audit — ${result.account.name} (${result.account.id})`);
|
|
43
|
+
lines.push("");
|
|
44
|
+
lines.push(`**Scope:** ${result.scope.campaigns} campaigns, ${result.scope.creatives} creatives, last ${result.scope.windowDays}d`);
|
|
45
|
+
lines.push("");
|
|
46
|
+
lines.push(`**Summary:** ${result.summary.pass} pass • ${result.summary.critical} critical • ${result.summary.high} high • ${result.summary.medium} medium • ${result.summary.low} low • ${result.summary.n_a} n/a (${result.summary.totalChecks} total)`);
|
|
47
|
+
lines.push("");
|
|
48
|
+
lines.push("| # | Area | Check | Status | Severity | Notes |");
|
|
49
|
+
lines.push("|---|------|-------|--------|----------|-------|");
|
|
50
|
+
result.findings.forEach((f, idx) => {
|
|
51
|
+
const note = noteOf(f);
|
|
52
|
+
lines.push(`| ${idx + 1} | ${f.area} | ${escapeMd(f.check)} | ${f.status.toUpperCase()} | ${f.severity} | ${escapeMd(note)} |`);
|
|
53
|
+
});
|
|
54
|
+
return lines.join("\n");
|
|
55
|
+
}
|
|
56
|
+
function escapeMd(text) {
|
|
57
|
+
return text.replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
58
|
+
}
|
|
59
|
+
function noteOf(f) {
|
|
60
|
+
if (f.status === "pass")
|
|
61
|
+
return "";
|
|
62
|
+
const ev = f.evidence ? JSON.stringify(f.evidence) : "";
|
|
63
|
+
const fix = f.fix?.explanation ?? "";
|
|
64
|
+
return [fix, ev].filter(Boolean).join(" — ");
|
|
65
|
+
}
|
|
66
|
+
export const auditCommand = defineCommand({
|
|
67
|
+
meta: {
|
|
68
|
+
name: "audit",
|
|
69
|
+
description: `Run a LinkedIn Ads playbook audit — 30+ checks across Settings, Tracking,
|
|
70
|
+
Audience, Campaigns, Creative, Performance, Bidding, and Compliance.
|
|
71
|
+
|
|
72
|
+
Each finding has {id, area, check, status, severity, evidence, fix} fields with
|
|
73
|
+
playbook citations. The default JSON output is agent-friendly; --format md
|
|
74
|
+
renders a deliverable-ready table that mirrors the google-ads-playbook
|
|
75
|
+
10-audit-summary.md style.
|
|
76
|
+
|
|
77
|
+
Exit code 0 always. Use the JSON 'summary' counts to decide if action is needed.
|
|
78
|
+
|
|
79
|
+
Examples:
|
|
80
|
+
baker ads linkedin audit --account-id 503001492
|
|
81
|
+
baker ads linkedin audit --account-id 503001492 --campaign-id 1234 # narrow scope
|
|
82
|
+
baker ads linkedin audit --account-id 503001492 --window-days 90
|
|
83
|
+
baker ads linkedin audit --account-id 503001492 --severity critical,high
|
|
84
|
+
baker ads linkedin audit --account-id 503001492 --area Settings,Tracking
|
|
85
|
+
baker ads linkedin audit --account-id 503001492 --format md`,
|
|
86
|
+
},
|
|
87
|
+
args: {
|
|
88
|
+
"account-id": { type: "string", description: "Numeric account ID or urn:li:sponsoredAccount:N" },
|
|
89
|
+
"account-urn": { type: "string", description: "Alias for --account-id" },
|
|
90
|
+
"campaign-id": { type: "string", description: "Narrow scope to a single campaign" },
|
|
91
|
+
"window-days": { type: "string", description: "Lookback window for performance checks (default: 30)" },
|
|
92
|
+
severity: { type: "string", description: "CSV severity filter: critical,high,medium,low" },
|
|
93
|
+
area: {
|
|
94
|
+
type: "string",
|
|
95
|
+
description: "CSV area filter: Settings,Tracking,Audience,Campaigns,Creative,Performance,Bidding,Compliance,Hygiene",
|
|
96
|
+
},
|
|
97
|
+
format: { type: "string", description: "Output format: json | md (default: json)" },
|
|
98
|
+
"skip-cache": { type: "boolean", description: "Bypass server-side cache" },
|
|
99
|
+
},
|
|
100
|
+
run: async ({ args }) => {
|
|
101
|
+
const accountId = resolveAccountIdArg(args);
|
|
102
|
+
const windowDays = args["window-days"] ? Number(args["window-days"]) : 30;
|
|
103
|
+
if (!Number.isFinite(windowDays) || windowDays < 1 || windowDays > 365) {
|
|
104
|
+
handleLinkedinError(new Error("--window-days must be 1..365"));
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const data = await apiPost("/api/ads/linkedin/audit", {
|
|
108
|
+
accountId,
|
|
109
|
+
campaignId: args["campaign-id"] ? String(args["campaign-id"]) : undefined,
|
|
110
|
+
windowDays,
|
|
111
|
+
skipCache: Boolean(args["skip-cache"]),
|
|
112
|
+
});
|
|
113
|
+
const severityFilter = args.severity
|
|
114
|
+
?.split(",")
|
|
115
|
+
.map((s) => s.trim().toLowerCase())
|
|
116
|
+
.filter(Boolean);
|
|
117
|
+
const areaFilter = args.area
|
|
118
|
+
?.split(",")
|
|
119
|
+
.map((s) => s.trim())
|
|
120
|
+
.filter(Boolean);
|
|
121
|
+
const filtered = filterFindings(data.findings, severityFilter, areaFilter);
|
|
122
|
+
const sorted = sortFindings(filtered);
|
|
123
|
+
const result = { ...data, findings: sorted };
|
|
124
|
+
const fmt = args.format ?? "json";
|
|
125
|
+
if (fmt === "md") {
|
|
126
|
+
process.stdout.write(`${renderMarkdown(result)}\n`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
writeAdsJson({ ok: true, data: result });
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
handleLinkedinError(err);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../../src/commands/ads/linkedin/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const bidPricingCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly "account-id": {
|
|
3
|
+
readonly type: "string";
|
|
4
|
+
readonly description: "Numeric account ID or urn:li:sponsoredAccount:N";
|
|
5
|
+
};
|
|
6
|
+
readonly "account-urn": {
|
|
7
|
+
readonly type: "string";
|
|
8
|
+
readonly description: "Alias for --account-id";
|
|
9
|
+
};
|
|
10
|
+
readonly objective: {
|
|
11
|
+
readonly type: "string";
|
|
12
|
+
readonly description: "Objective type (e.g. WEBSITE_CONVERSION, LEAD_GENERATION)";
|
|
13
|
+
readonly required: true;
|
|
14
|
+
};
|
|
15
|
+
readonly "cost-type": {
|
|
16
|
+
readonly type: "string";
|
|
17
|
+
readonly description: "CPC | CPM | CPV | CPS";
|
|
18
|
+
readonly required: true;
|
|
19
|
+
};
|
|
20
|
+
readonly targeting: {
|
|
21
|
+
readonly type: "string";
|
|
22
|
+
readonly description: "Inline JSON targetingCriteria";
|
|
23
|
+
};
|
|
24
|
+
readonly "targeting-file": {
|
|
25
|
+
readonly type: "string";
|
|
26
|
+
readonly description: "Path to JSON file with targetingCriteria";
|
|
27
|
+
};
|
|
28
|
+
readonly "skip-cache": {
|
|
29
|
+
readonly type: "boolean";
|
|
30
|
+
readonly description: "Bypass server-side cache";
|
|
31
|
+
};
|
|
32
|
+
readonly output: {
|
|
33
|
+
readonly type: "string";
|
|
34
|
+
readonly description: "json";
|
|
35
|
+
readonly default: "json";
|
|
36
|
+
};
|
|
37
|
+
}>;
|
|
38
|
+
//# sourceMappingURL=bid-pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bid-pricing.d.ts","sourceRoot":"","sources":["../../../../src/commands/ads/linkedin/bid-pricing.ts"],"names":[],"mappings":"AAyCA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+C5B,CAAC"}
|