@koda-sl/baker-cli 0.325.1 → 0.327.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 +2 -1
- package/dist/{chunk-GJVXXYCX.js → chunk-4VP5WWPR.js} +13 -2
- package/dist/chunk-4VP5WWPR.js.map +1 -0
- package/dist/{chunk-HPRKO6P2.js → chunk-FFOURYP5.js} +7 -5
- package/dist/chunk-FFOURYP5.js.map +1 -0
- package/dist/{chunk-UWFF6WEV.js → chunk-JWMLQSGK.js} +4 -4
- package/dist/{chunk-MSZSDYOJ.js → chunk-KGDL7F7M.js} +3 -3
- package/dist/{chunk-6BD32M7K.js → chunk-PWGY347J.js} +26 -3
- package/dist/chunk-PWGY347J.js.map +1 -0
- package/dist/{chunk-KAE5M5R7.js → chunk-XPUSSDLR.js} +3 -3
- package/dist/cli.js +151 -26
- package/dist/cli.js.map +1 -1
- package/dist/{client-XUSSAB6O.js → client-PWRZOA3Q.js} +4 -4
- package/dist/engine/index.js +3 -3
- package/dist/{env-VIA5U56G.js → env-TQTHWLBN.js} +2 -2
- package/dist/{output-ZPACGSH2.js → output-HD63GTWI.js} +5 -5
- package/dist/{shared-OHOCOE2L.js → shared-5662SBDW.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-6BD32M7K.js.map +0 -1
- package/dist/chunk-GJVXXYCX.js.map +0 -1
- package/dist/chunk-HPRKO6P2.js.map +0 -1
- /package/dist/{chunk-UWFF6WEV.js.map → chunk-JWMLQSGK.js.map} +0 -0
- /package/dist/{chunk-MSZSDYOJ.js.map → chunk-KGDL7F7M.js.map} +0 -0
- /package/dist/{chunk-KAE5M5R7.js.map → chunk-XPUSSDLR.js.map} +0 -0
- /package/dist/{client-XUSSAB6O.js.map → client-PWRZOA3Q.js.map} +0 -0
- /package/dist/{env-VIA5U56G.js.map → env-TQTHWLBN.js.map} +0 -0
- /package/dist/{output-ZPACGSH2.js.map → output-HD63GTWI.js.map} +0 -0
- /package/dist/{shared-OHOCOE2L.js.map → shared-5662SBDW.js.map} +0 -0
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
handleConnectionError,
|
|
3
3
|
needsConnectionFix,
|
|
4
4
|
writeAdsJson
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KGDL7F7M.js";
|
|
6
6
|
import {
|
|
7
7
|
ApiError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XPUSSDLR.js";
|
|
9
9
|
import {
|
|
10
10
|
getEnv
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-4VP5WWPR.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/ads/meta/shared.ts
|
|
14
14
|
var DAY_MS = 864e5;
|
|
@@ -108,4 +108,4 @@ export {
|
|
|
108
108
|
csvOrJson,
|
|
109
109
|
resolveEffectiveStatus
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-JWMLQSGK.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ApiError,
|
|
3
3
|
apiGet
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XPUSSDLR.js";
|
|
5
5
|
import {
|
|
6
6
|
getEnv
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4VP5WWPR.js";
|
|
8
8
|
|
|
9
9
|
// src/error-handler.ts
|
|
10
10
|
var REQUEST_CONNECTION_PLATFORM = {
|
|
@@ -294,4 +294,4 @@ export {
|
|
|
294
294
|
writeAdsOutput,
|
|
295
295
|
resolveCustomerId
|
|
296
296
|
};
|
|
297
|
-
//# sourceMappingURL=chunk-
|
|
297
|
+
//# sourceMappingURL=chunk-KGDL7F7M.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
debugLogSetting
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4VP5WWPR.js";
|
|
4
4
|
|
|
5
5
|
// src/debugLog.ts
|
|
6
6
|
import { appendFileSync, mkdirSync, renameSync, statSync } from "fs";
|
|
@@ -12,7 +12,10 @@ var MAX_BYTES = 64 * 1024 * 1024;
|
|
|
12
12
|
var REDACTIONS = [
|
|
13
13
|
[/Bearer\s+[A-Za-z0-9._-]+/g, "Bearer [redacted]"],
|
|
14
14
|
// Authorization headers
|
|
15
|
-
|
|
15
|
+
// Both prefixes, captured rather than listed twice: `bkr_` does not contain
|
|
16
|
+
// the literal `bk_`, so the company-key rule matched no part of the read-only
|
|
17
|
+
// credential a Session review runs with.
|
|
18
|
+
[/\b(bkr?)_[A-Za-z0-9]+/g, "$1_[redacted]"],
|
|
16
19
|
// Baker API keys
|
|
17
20
|
[/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, "[redacted-jwt]"],
|
|
18
21
|
// JWTs / id tokens
|
|
@@ -92,9 +95,28 @@ function errorToPlain(err) {
|
|
|
92
95
|
}
|
|
93
96
|
return { message: String(err) };
|
|
94
97
|
}
|
|
98
|
+
var invocationStartedAt;
|
|
95
99
|
function logInvocation(argv) {
|
|
100
|
+
invocationStartedAt = Date.now();
|
|
96
101
|
append({ kind: "invocation", argv, cwd: process.cwd() });
|
|
97
102
|
}
|
|
103
|
+
function logExit(code) {
|
|
104
|
+
append({
|
|
105
|
+
kind: "exit",
|
|
106
|
+
code,
|
|
107
|
+
...invocationStartedAt === void 0 ? {} : { durationMs: Date.now() - invocationStartedAt }
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
var exitHookInstalled = false;
|
|
111
|
+
function installExitRecord() {
|
|
112
|
+
if (exitHookInstalled || !isDebugLogEnabled()) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
exitHookInstalled = true;
|
|
116
|
+
process.on("exit", (code) => {
|
|
117
|
+
logExit(typeof code === "number" ? code : 0);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
98
120
|
function debugLogHttp(entry) {
|
|
99
121
|
if (!isDebugLogEnabled()) {
|
|
100
122
|
return;
|
|
@@ -146,8 +168,9 @@ function installStreamTaps() {
|
|
|
146
168
|
|
|
147
169
|
export {
|
|
148
170
|
logInvocation,
|
|
171
|
+
installExitRecord,
|
|
149
172
|
debugLogHttp,
|
|
150
173
|
readBodyForLog,
|
|
151
174
|
installStreamTaps
|
|
152
175
|
};
|
|
153
|
-
//# sourceMappingURL=chunk-
|
|
176
|
+
//# sourceMappingURL=chunk-PWGY347J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/debugLog.ts"],"sourcesContent":["// Full-fidelity debug capture for the whole CLI.\n//\n// Set BAKER_DEBUG_LOG to turn it on:\n// BAKER_DEBUG_LOG=1 -> appends to ./baker-cli-debug.jsonl\n// BAKER_DEBUG_LOG=/tmp/baker.jsonl -> appends to that file\n// BAKER_DEBUG_LOG=0|false|off|no -> disabled (same as unset)\n//\n// When enabled, every HTTP request/response (both the REST client and the\n// canvas engine client), every byte written to stdout/stderr, and the command\n// invocation are appended as JSONL entries. Known secret shapes are redacted\n// before anything is written (best-effort — see redactSecrets). Logging is\n// always fail-open: a logging error is swallowed so it can never break a\n// command. The file rotates once past MAX_BYTES so an always-on capture cannot\n// fill the disk.\n\nimport { appendFileSync, mkdirSync, renameSync, statSync } from \"node:fs\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { debugLogSetting } from \"./env.ts\";\n\nconst DEFAULT_FILE = \"baker-cli-debug.jsonl\";\nconst BOOLEAN_ON = new Set([\"1\", \"true\", \"on\", \"yes\"]);\nconst BOOLEAN_OFF = new Set([\"0\", \"false\", \"off\", \"no\"]);\n\n// Rotate once the active file passes this size (one older generation, `<file>.1`,\n// is kept). Bounds growth for the always-on sandbox capture without a per-write stat.\nconst MAX_BYTES = 64 * 1024 * 1024;\n\n// Best-effort redaction. Response/request bodies are stored as escaped strings, so\n// key/value matching is unreliable there; instead we scrub the token *values*\n// themselves (quote-agnostic) plus the auth header and Baker keys. This is not\n// exhaustive — a secret in an unrecognized shape can still be written. See README.\nconst REDACTIONS: ReadonlyArray<readonly [RegExp, string]> = [\n [/Bearer\\s+[A-Za-z0-9._-]+/g, \"Bearer [redacted]\"], // Authorization headers\n // Both prefixes, captured rather than listed twice: `bkr_` does not contain\n // the literal `bk_`, so the company-key rule matched no part of the read-only\n // credential a Session review runs with.\n [/\\b(bkr?)_[A-Za-z0-9]+/g, \"$1_[redacted]\"], // Baker API keys\n [/eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+/g, \"[redacted-jwt]\"], // JWTs / id tokens\n [/ya29\\.[A-Za-z0-9._-]+/g, \"[redacted-google-token]\"], // Google OAuth access tokens\n [/1\\/\\/[A-Za-z0-9._-]+/g, \"[redacted-google-refresh]\"], // Google refresh tokens\n [/EAA[A-Za-z0-9]{20,}/g, \"[redacted-meta-token]\"], // Meta/Facebook access tokens\n];\n\nexport function redactSecrets(input: string): string {\n let out = input;\n for (const [pattern, replacement] of REDACTIONS) {\n out = out.replace(pattern, replacement);\n }\n return out;\n}\n\nfunction resolveTarget(): string | undefined {\n const raw = debugLogSetting();\n if (!raw) {\n return undefined;\n }\n const lower = raw.toLowerCase();\n if (BOOLEAN_OFF.has(lower)) {\n return undefined;\n }\n const target = BOOLEAN_ON.has(lower) ? DEFAULT_FILE : raw;\n return isAbsolute(target) ? target : resolve(process.cwd(), target);\n}\n\nexport function isDebugLogEnabled(): boolean {\n return resolveTarget() !== undefined;\n}\n\nlet sessionId: string | undefined;\nfunction getSessionId(): string {\n if (!sessionId) {\n sessionId = `${process.pid}-${Date.now()}`;\n }\n return sessionId;\n}\n\n// Per-resolved-path bookkeeping so the hot path skips redundant syscalls: the\n// directory is ensured once and the current size is read once (via statSync),\n// then tracked in-process. Resets when the resolved path changes.\nlet trackedPath: string | undefined;\nlet bytesInFile = 0;\n\nfunction ensureReady(filePath: string): void {\n if (trackedPath !== filePath) {\n trackedPath = filePath;\n mkdirSync(dirname(filePath), { recursive: true });\n try {\n bytesInFile = statSync(filePath).size;\n } catch {\n bytesInFile = 0;\n }\n }\n}\n\nfunction append(entry: Record<string, unknown>): void {\n const filePath = resolveTarget();\n if (!filePath) {\n return;\n }\n try {\n const payload = { ts: new Date().toISOString(), session: getSessionId(), ...entry };\n const line = `${redactSecrets(JSON.stringify(payload))}\\n`;\n ensureReady(filePath);\n const size = Buffer.byteLength(line);\n if (bytesInFile + size > MAX_BYTES) {\n renameSync(filePath, `${filePath}.1`);\n bytesInFile = 0;\n }\n appendFileSync(filePath, line);\n bytesInFile += size;\n } catch {\n // Fail-open: debug logging must never break a command.\n }\n}\n\nfunction errorToPlain(err: unknown): Record<string, unknown> {\n if (err instanceof Error) {\n const code = (err as { code?: unknown }).code;\n return { name: err.name, message: err.message, ...(typeof code === \"string\" ? { code } : {}) };\n }\n return { message: String(err) };\n}\n\nlet invocationStartedAt: number | undefined;\n\nexport function logInvocation(argv: string[]): void {\n invocationStartedAt = Date.now();\n append({ kind: \"invocation\", argv, cwd: process.cwd() });\n}\n\n/**\n * Close an invocation with its outcome and its wall time.\n *\n * Until this existed the log could say what was called and what every HTTP hop\n * cost, and nothing at all about whether the command succeeded or how long the\n * whole thing took — so \"this verb is slow\" and \"this verb fails half the time\"\n * were both unanswerable from the one record that sees every call. `durationMs`\n * is measured from `logInvocation`, which runs before any command does.\n */\nexport function logExit(code: number): void {\n append({\n kind: \"exit\",\n code,\n ...(invocationStartedAt === undefined ? {} : { durationMs: Date.now() - invocationStartedAt }),\n });\n}\n\nlet exitHookInstalled = false;\n\n/**\n * Write the exit record however the process ends.\n *\n * `process.on(\"exit\")` is the only hook that sees all of them — a clean return, a\n * `process.exit` from the error handler, an unhandled rejection — and it is\n * synchronous-only, which is exactly what `appendFileSync` needs. Installed once,\n * and only when logging is on, so the disabled path adds no listener at all.\n */\nexport function installExitRecord(): void {\n if (exitHookInstalled || !isDebugLogEnabled()) {\n return;\n }\n exitHookInstalled = true;\n process.on(\"exit\", (code) => {\n logExit(typeof code === \"number\" ? code : 0);\n });\n}\n\nexport type HttpLogEntry = {\n source: \"cli\" | \"canvas\";\n method: string;\n url: string;\n requestBody?: unknown;\n status?: number;\n ok?: boolean;\n responseBody?: string;\n durationMs?: number;\n error?: unknown;\n};\n\nexport function debugLogHttp(entry: HttpLogEntry): void {\n if (!isDebugLogEnabled()) {\n return;\n }\n append({\n kind: \"http\",\n source: entry.source,\n method: entry.method,\n url: entry.url,\n durationMs: entry.durationMs,\n request: entry.requestBody,\n status: entry.status,\n ok: entry.ok,\n response: entry.responseBody,\n error: entry.error === undefined ? undefined : errorToPlain(entry.error),\n });\n}\n\n// Reads a response body for logging without consuming it for the real caller.\nexport async function readBodyForLog(response: Response): Promise<string | undefined> {\n if (!isDebugLogEnabled()) {\n return undefined;\n }\n try {\n return await response.clone().text();\n } catch {\n return undefined;\n }\n}\n\n// Method syntax (bivariant) so a real `process.stdout`/`stderr` and a plain\n// test double both satisfy it.\ntype Writable = { write(...args: unknown[]): boolean };\n\n// Wraps a stream's `write` so every chunk is mirrored into the debug log while\n// the original write semantics (args + return value) are preserved. A single\n// streaming TextDecoder per stream decodes byte chunks so a multi-byte character\n// split across two writes is reassembled instead of garbled.\nexport function tapStream(name: string, stream: Writable): void {\n const original = stream.write.bind(stream) as (...args: unknown[]) => boolean;\n const decoder = new TextDecoder(\"utf-8\");\n stream.write = ((chunk: unknown, ...rest: unknown[]): boolean => {\n try {\n const text =\n typeof chunk === \"string\"\n ? chunk\n : chunk instanceof Uint8Array\n ? decoder.decode(chunk, { stream: true })\n : String(chunk);\n append({ kind: \"output\", stream: name, text });\n } catch {\n // ignore capture failures\n }\n return original(chunk, ...rest);\n }) as typeof stream.write;\n}\n\nlet tapsInstalled = false;\n\n// Mirrors everything written to stdout/stderr into the debug log. Installed once,\n// only when enabled, so the common (disabled) path leaves the streams untouched.\nexport function installStreamTaps(): void {\n if (tapsInstalled || !isDebugLogEnabled()) {\n return;\n }\n tapsInstalled = true;\n tapStream(\"stdout\", process.stdout);\n tapStream(\"stderr\", process.stderr);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
debugLogHttp,
|
|
3
3
|
readBodyForLog
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PWGY347J.js";
|
|
5
5
|
import {
|
|
6
6
|
getEnv
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4VP5WWPR.js";
|
|
8
8
|
|
|
9
9
|
// src/client.ts
|
|
10
10
|
var MAX_RATE_LIMIT_RETRIES = 3;
|
|
@@ -205,4 +205,4 @@ export {
|
|
|
205
205
|
apiGet,
|
|
206
206
|
apiPost
|
|
207
207
|
};
|
|
208
|
-
//# sourceMappingURL=chunk-
|
|
208
|
+
//# sourceMappingURL=chunk-XPUSSDLR.js.map
|
package/dist/cli.js
CHANGED
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
validateCanvasDeep,
|
|
68
68
|
withoutCastName,
|
|
69
69
|
ytDlpBlockSignal
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-FFOURYP5.js";
|
|
71
71
|
import {
|
|
72
72
|
csvOrJson,
|
|
73
73
|
daysAgoIso,
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
resolveAccountIdArg,
|
|
77
77
|
resolveEffectiveStatus,
|
|
78
78
|
todayIso
|
|
79
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-JWMLQSGK.js";
|
|
80
80
|
import {
|
|
81
81
|
buildQueryCacheKey,
|
|
82
82
|
cacheGet,
|
|
@@ -92,18 +92,19 @@ import {
|
|
|
92
92
|
writeAdsJson,
|
|
93
93
|
writeAdsOutput,
|
|
94
94
|
writeJsonEnvelope
|
|
95
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-KGDL7F7M.js";
|
|
96
96
|
import {
|
|
97
97
|
ApiError,
|
|
98
98
|
apiGet,
|
|
99
99
|
apiGetWithHeaders,
|
|
100
100
|
apiPost,
|
|
101
101
|
validateConvexId
|
|
102
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-XPUSSDLR.js";
|
|
103
103
|
import {
|
|
104
|
+
installExitRecord,
|
|
104
105
|
installStreamTaps,
|
|
105
106
|
logInvocation
|
|
106
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-PWGY347J.js";
|
|
107
108
|
import {
|
|
108
109
|
captureBudgetMs,
|
|
109
110
|
captureProxyCredentials,
|
|
@@ -117,7 +118,7 @@ import {
|
|
|
117
118
|
requireChatId,
|
|
118
119
|
resolveChatId,
|
|
119
120
|
shouldEscalate
|
|
120
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-4VP5WWPR.js";
|
|
121
122
|
|
|
122
123
|
// src/cli.ts
|
|
123
124
|
import { defineCommand as defineCommand244, runMain } from "citty";
|
|
@@ -955,7 +956,11 @@ var winnersSearchResponseSchema = z2.object({
|
|
|
955
956
|
// the dashboard then falls back to a single non-paged page.
|
|
956
957
|
offset: z2.number().nullable(),
|
|
957
958
|
total: z2.number().nullable(),
|
|
958
|
-
has_more: z2.boolean().nullable()
|
|
959
|
+
has_more: z2.boolean().nullable(),
|
|
960
|
+
// Ads the corpus holds for each requested `country`; null when the search did
|
|
961
|
+
// not filter by country. Tells "no winners matched" apart from "unsupported"
|
|
962
|
+
// (an unknown code is refused outright).
|
|
963
|
+
country_coverage: z2.array(z2.object({ code: z2.string(), ads: z2.number() })).nullable()
|
|
959
964
|
});
|
|
960
965
|
var advertiserPlatformSchema = z2.object({
|
|
961
966
|
platform: z2.string(),
|
|
@@ -4928,7 +4933,33 @@ var adEffectSchema = z13.object({
|
|
|
4928
4933
|
*/
|
|
4929
4934
|
outcome: z13.enum(["applied", "simulated", "failed", "skipped"]).nullable(),
|
|
4930
4935
|
/** Why it failed, verbatim from the platform. Null unless the op failed. */
|
|
4931
|
-
error: z13.string().nullable()
|
|
4936
|
+
error: z13.string().nullable(),
|
|
4937
|
+
/**
|
|
4938
|
+
* Why the publish never attempted it — a dependency that failed first, a
|
|
4939
|
+
* connection that went read-only. Distinct from `error`, which is the
|
|
4940
|
+
* provider's refusal of an op that was actually sent: a reader that cannot
|
|
4941
|
+
* tell the two apart reads "we never tried" as "the platform said no".
|
|
4942
|
+
*/
|
|
4943
|
+
skippedBecause: z13.string().nullable().optional()
|
|
4944
|
+
});
|
|
4945
|
+
var configEffectSchema = z13.object({
|
|
4946
|
+
op: effectOpSchema,
|
|
4947
|
+
staged: z13.boolean(),
|
|
4948
|
+
/** The full stored op kind, e.g. `tagManager.tag.create`, `ga4.keyEvent.update`. */
|
|
4949
|
+
operation: z13.string(),
|
|
4950
|
+
/** The entity class the op acts on, e.g. `tag`, `customDimension`. */
|
|
4951
|
+
entity: z13.string().nullable(),
|
|
4952
|
+
summary: z13.string(),
|
|
4953
|
+
ref: z13.string(),
|
|
4954
|
+
outcome: z13.enum(["applied", "failed", "skipped"]).nullable(),
|
|
4955
|
+
error: z13.string().nullable(),
|
|
4956
|
+
skippedBecause: z13.string().nullable(),
|
|
4957
|
+
/**
|
|
4958
|
+
* The post-publish read-back, when one ran. Annotation only — Tag Manager can
|
|
4959
|
+
* answer 200 to a write it silently dropped, so a fresh read is the only
|
|
4960
|
+
* thing that distinguishes "applied" from "accepted and discarded".
|
|
4961
|
+
*/
|
|
4962
|
+
verified: z13.boolean().nullable()
|
|
4932
4963
|
});
|
|
4933
4964
|
var creativeEffectSchema = z13.object({
|
|
4934
4965
|
op: effectOpSchema,
|
|
@@ -4948,7 +4979,51 @@ var chatEffectsSchema = z13.object({
|
|
|
4948
4979
|
linkedin: z13.array(adEffectSchema),
|
|
4949
4980
|
x: z13.array(adEffectSchema)
|
|
4950
4981
|
}),
|
|
4951
|
-
creatives: z13.array(creativeEffectSchema)
|
|
4982
|
+
creatives: z13.array(creativeEffectSchema),
|
|
4983
|
+
tagManager: z13.array(configEffectSchema),
|
|
4984
|
+
ga4: z13.array(configEffectSchema)
|
|
4985
|
+
});
|
|
4986
|
+
var publishSurfaceFailureSchema = z13.object({
|
|
4987
|
+
summary: z13.string(),
|
|
4988
|
+
/** The provider's own words, trimmed. Empty when it said nothing. */
|
|
4989
|
+
error: z13.string()
|
|
4990
|
+
});
|
|
4991
|
+
var publishSurfaceOutcomeSchema = z13.object({
|
|
4992
|
+
surface: z13.string(),
|
|
4993
|
+
label: z13.string(),
|
|
4994
|
+
total: z13.number(),
|
|
4995
|
+
landed: z13.number(),
|
|
4996
|
+
failed: z13.number(),
|
|
4997
|
+
/** True while this surface is still applying — not yet a verdict either way. */
|
|
4998
|
+
running: z13.boolean(),
|
|
4999
|
+
failures: z13.array(publishSurfaceFailureSchema)
|
|
5000
|
+
});
|
|
5001
|
+
var chatPublishSummarySchema = z13.object({
|
|
5002
|
+
complete: z13.boolean(),
|
|
5003
|
+
running: z13.boolean(),
|
|
5004
|
+
failedTotal: z13.number(),
|
|
5005
|
+
surfaces: z13.array(publishSurfaceOutcomeSchema)
|
|
5006
|
+
});
|
|
5007
|
+
var chatActivityEntrySchema = z13.object({
|
|
5008
|
+
action: z13.string(),
|
|
5009
|
+
actorType: z13.string(),
|
|
5010
|
+
createdAt: z13.number(),
|
|
5011
|
+
threadId: z13.string().nullable(),
|
|
5012
|
+
/** Compact truncates this; `--full` returns it whole. */
|
|
5013
|
+
metadata: z13.unknown().optional()
|
|
5014
|
+
});
|
|
5015
|
+
var chatThreadUsageSchema = z13.object({
|
|
5016
|
+
threadId: z13.string(),
|
|
5017
|
+
costUsd: z13.number(),
|
|
5018
|
+
model: z13.string().nullable()
|
|
5019
|
+
});
|
|
5020
|
+
var chatUsageSchema = z13.object({
|
|
5021
|
+
threads: z13.array(chatThreadUsageSchema),
|
|
5022
|
+
totalCostUsd: z13.number(),
|
|
5023
|
+
inputTokens: z13.number(),
|
|
5024
|
+
outputTokens: z13.number(),
|
|
5025
|
+
cacheReadTokens: z13.number(),
|
|
5026
|
+
cacheWriteTokens: z13.number()
|
|
4952
5027
|
});
|
|
4953
5028
|
var chatDetailSchema = z13.object({
|
|
4954
5029
|
id: z13.string(),
|
|
@@ -4967,7 +5042,15 @@ var chatDetailSchema = z13.object({
|
|
|
4967
5042
|
threads: z13.array(chatThreadSummarySchema),
|
|
4968
5043
|
commits: z13.array(chatCommitSummarySchema),
|
|
4969
5044
|
/** True when a real file-level diff is available via `baker chats diff`. */
|
|
4970
|
-
diffAvailable: z13.boolean()
|
|
5045
|
+
diffAvailable: z13.boolean(),
|
|
5046
|
+
/** What the Publish did on each external surface. Absent when nothing was ever published. */
|
|
5047
|
+
publish: chatPublishSummarySchema.optional(),
|
|
5048
|
+
/** Why the Publish itself failed, as the backend recorded it. */
|
|
5049
|
+
publishFailureReason: z13.string().nullable().optional(),
|
|
5050
|
+
/** The chat's own timeline: status changes, publish start/fail, sandbox recoveries, timeouts. */
|
|
5051
|
+
activity: z13.array(chatActivityEntrySchema).optional(),
|
|
5052
|
+
/** What the Session cost, per thread and in total. */
|
|
5053
|
+
usage: chatUsageSchema.optional()
|
|
4971
5054
|
});
|
|
4972
5055
|
var chatsViewResponseSchema = z13.object({
|
|
4973
5056
|
ok: z13.literal(true),
|
|
@@ -24823,10 +24906,10 @@ Example: baker ads meta ads retag 120252158038400247 --url-tags "utm_source={{si
|
|
|
24823
24906
|
}
|
|
24824
24907
|
},
|
|
24825
24908
|
run: async ({ args: args4 }) => {
|
|
24826
|
-
const { apiPost: apiPost2 } = await import("./client-
|
|
24827
|
-
const { requireChatId: requireChatId2 } = await import("./env-
|
|
24828
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
24829
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
24909
|
+
const { apiPost: apiPost2 } = await import("./client-PWRZOA3Q.js");
|
|
24910
|
+
const { requireChatId: requireChatId2 } = await import("./env-TQTHWLBN.js");
|
|
24911
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-HD63GTWI.js");
|
|
24912
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-5662SBDW.js");
|
|
24830
24913
|
try {
|
|
24831
24914
|
const accountId = bareAccountId2(args4);
|
|
24832
24915
|
const urlTags = typeof args4["url-tags"] === "string" ? args4["url-tags"] : void 0;
|
|
@@ -24971,10 +25054,10 @@ function duplicateCommand2(entity, label) {
|
|
|
24971
25054
|
replace: { type: "boolean", description: "Pause the original once the copy publishes" }
|
|
24972
25055
|
},
|
|
24973
25056
|
run: async ({ args: args4 }) => {
|
|
24974
|
-
const { apiPost: apiPost2 } = await import("./client-
|
|
24975
|
-
const { requireChatId: requireChatId2 } = await import("./env-
|
|
24976
|
-
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-
|
|
24977
|
-
const { handleMetaError: handleMetaError2 } = await import("./shared-
|
|
25057
|
+
const { apiPost: apiPost2 } = await import("./client-PWRZOA3Q.js");
|
|
25058
|
+
const { requireChatId: requireChatId2 } = await import("./env-TQTHWLBN.js");
|
|
25059
|
+
const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-HD63GTWI.js");
|
|
25060
|
+
const { handleMetaError: handleMetaError2 } = await import("./shared-5662SBDW.js");
|
|
24978
25061
|
try {
|
|
24979
25062
|
const accountId = bareAccountId2(args4);
|
|
24980
25063
|
const chatId = requireChatId2();
|
|
@@ -43909,7 +43992,7 @@ var canvasCommand = defineCommand118({
|
|
|
43909
43992
|
name: "canvas",
|
|
43910
43993
|
description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
|
|
43911
43994
|
|
|
43912
|
-
Auth: BAKER_API_KEY (
|
|
43995
|
+
Auth: BAKER_API_KEY (bk_ or bkr_) + BAKER_API_URL (your Convex .convex.site URL).
|
|
43913
43996
|
|
|
43914
43997
|
Subcommands:
|
|
43915
43998
|
baker canvas validate <file.json> \u2014 schema/registry check + composition-meta deep check + cost preview
|
|
@@ -44119,12 +44202,12 @@ var listCommand13 = defineCommand120({
|
|
|
44119
44202
|
});
|
|
44120
44203
|
registerSchema({
|
|
44121
44204
|
command: "chats.view",
|
|
44122
|
-
description: "Inspect one Session's FULL picture of what it changed \u2014 the unified `effects`: git content (landings, creatives, flows, knowledge, brand), plus DB-only effects that never touch the repo \u2014 Actions, Scheduled Actions, Tags, and ad-platform writes \u2014 each resolved to real detail (names, descriptions, priorities, tag types, ad operations). Also the kickoff (how it was asked), threads, and commits. Effects are `staged` (in-progress draft) or applied. Use after `baker chats list` to decide whether to reuse it. Read-only.",
|
|
44205
|
+
description: "Inspect one Session's FULL picture of what it changed \u2014 the unified `effects`: git content (landings, creatives, flows, knowledge, brand), plus DB-only effects that never touch the repo \u2014 Actions, Scheduled Actions, Tags, Tag Manager, Google Analytics, and ad-platform writes \u2014 each resolved to real detail (names, descriptions, priorities, tag types, ad operations). Also `publish` (what each external surface actually did, with the provider's own error), `activity` (the chat's own timeline: status changes, publish start/fail, workspace recoveries, timeouts), `usage` (per-thread cost and the Session's token totals), the kickoff (how it was asked), threads, and commits. Effects are `staged` (in-progress draft) or applied. A completed Session is NOT proof its external changes landed \u2014 read `publish`. Use after `baker chats list` to decide whether to reuse it. Read-only.",
|
|
44123
44206
|
args: {
|
|
44124
44207
|
id: { type: "positional", description: "The Session id (from `baker chats list`)", required: true },
|
|
44125
44208
|
full: {
|
|
44126
44209
|
type: "boolean",
|
|
44127
|
-
description: "
|
|
44210
|
+
description: "Untruncated effect lists and full activity metadata (compact caps each list at 25)",
|
|
44128
44211
|
required: false,
|
|
44129
44212
|
default: false
|
|
44130
44213
|
}
|
|
@@ -44146,6 +44229,12 @@ var viewCommand = defineCommand120({
|
|
|
44146
44229
|
...args4.full ? { full: true } : {}
|
|
44147
44230
|
});
|
|
44148
44231
|
const hints2 = [];
|
|
44232
|
+
if (response.data.publish && !response.data.publish.complete) {
|
|
44233
|
+
const failed = response.data.publish.failedTotal;
|
|
44234
|
+
hints2.push(
|
|
44235
|
+
`This Session's publish left ${failed} change${failed === 1 ? "" : "s"} behind \u2014 see \`publish.surfaces\` for the platform's own words. Do not report those changes as live.`
|
|
44236
|
+
);
|
|
44237
|
+
}
|
|
44149
44238
|
if (response.data.diffAvailable) {
|
|
44150
44239
|
hints2.push("See the real file-level diff of the git content with `baker chats diff <id> --full`.");
|
|
44151
44240
|
} else if (response.data.status === "in_progress" || response.data.status === "publishing") {
|
|
@@ -66301,7 +66390,11 @@ registerSchema({
|
|
|
66301
66390
|
description: "Comma list: unaware,problem_aware,solution_aware,product_aware,most_aware",
|
|
66302
66391
|
required: false
|
|
66303
66392
|
},
|
|
66304
|
-
country: {
|
|
66393
|
+
country: {
|
|
66394
|
+
type: "string",
|
|
66395
|
+
description: "Comma list of ISO country codes (US,GB) \u2014 an unknown code is refused with the codes that have ads",
|
|
66396
|
+
required: false
|
|
66397
|
+
},
|
|
66305
66398
|
language: { type: "string", description: "Comma list of language codes", required: false },
|
|
66306
66399
|
"advertiser-id": {
|
|
66307
66400
|
type: "string",
|
|
@@ -66374,6 +66467,32 @@ function buildSearchBody2(args4) {
|
|
|
66374
66467
|
}
|
|
66375
66468
|
return body;
|
|
66376
66469
|
}
|
|
66470
|
+
var UNKNOWN_COUNTRY_RE = /Unknown country code\(s\): ([^.]+)\. Countries with ads: ([^.]+)\./;
|
|
66471
|
+
function unknownCountryFix(message) {
|
|
66472
|
+
const match = UNKNOWN_COUNTRY_RE.exec(message);
|
|
66473
|
+
if (!match) {
|
|
66474
|
+
return null;
|
|
66475
|
+
}
|
|
66476
|
+
const unknownCountries = splitList2(match[1]);
|
|
66477
|
+
const validCountries = splitList2(match[2]);
|
|
66478
|
+
if (unknownCountries.length === 0 || validCountries.length === 0) {
|
|
66479
|
+
return null;
|
|
66480
|
+
}
|
|
66481
|
+
return {
|
|
66482
|
+
action: "retry_with_a_valid_country",
|
|
66483
|
+
explanation: `${unknownCountries.join(", ")} is not a country the winning-ads library holds ads for. Re-run with codes from \`validCountries\`, or drop --country to search every market.`,
|
|
66484
|
+
unknownCountries,
|
|
66485
|
+
validCountries
|
|
66486
|
+
};
|
|
66487
|
+
}
|
|
66488
|
+
function reportSearchError(err) {
|
|
66489
|
+
const fix = err instanceof ApiError ? unknownCountryFix(err.message) : null;
|
|
66490
|
+
if (err instanceof ApiError && fix) {
|
|
66491
|
+
writeJson({ ok: false, error: { code: err.code, message: err.message, fix } });
|
|
66492
|
+
process.exit(1);
|
|
66493
|
+
}
|
|
66494
|
+
reportError2(err);
|
|
66495
|
+
}
|
|
66377
66496
|
var searchCommand5 = defineCommand239({
|
|
66378
66497
|
meta: {
|
|
66379
66498
|
name: "search",
|
|
@@ -66406,7 +66525,11 @@ var searchCommand5 = defineCommand239({
|
|
|
66406
66525
|
required: false
|
|
66407
66526
|
},
|
|
66408
66527
|
awareness: { type: "string", description: "Comma list of awareness stages", required: false },
|
|
66409
|
-
country: {
|
|
66528
|
+
country: {
|
|
66529
|
+
type: "string",
|
|
66530
|
+
description: "Comma list of ISO country codes (US,GB) \u2014 an unknown code is refused with the codes that have ads",
|
|
66531
|
+
required: false
|
|
66532
|
+
},
|
|
66410
66533
|
language: { type: "string", description: "Comma list of language codes", required: false },
|
|
66411
66534
|
"advertiser-id": { type: "string", description: "Restrict to these advertiser ids", required: false },
|
|
66412
66535
|
"exclude-advertiser": {
|
|
@@ -66470,7 +66593,8 @@ var searchCommand5 = defineCommand239({
|
|
|
66470
66593
|
results,
|
|
66471
66594
|
pool_size: data?.pool_size ?? null,
|
|
66472
66595
|
match_confidence: data?.match_confidence ?? null,
|
|
66473
|
-
below_floor_count: data?.below_floor_count ?? null
|
|
66596
|
+
below_floor_count: data?.below_floor_count ?? null,
|
|
66597
|
+
country_coverage: data?.country_coverage ?? null
|
|
66474
66598
|
}
|
|
66475
66599
|
});
|
|
66476
66600
|
return;
|
|
@@ -66483,7 +66607,7 @@ var searchCommand5 = defineCommand239({
|
|
|
66483
66607
|
winningAdNormalizer
|
|
66484
66608
|
);
|
|
66485
66609
|
} catch (err) {
|
|
66486
|
-
|
|
66610
|
+
reportSearchError(err);
|
|
66487
66611
|
}
|
|
66488
66612
|
}
|
|
66489
66613
|
});
|
|
@@ -66660,7 +66784,7 @@ var winningAdsCommand = defineCommand243({
|
|
|
66660
66784
|
name: "winning-ads",
|
|
66661
66785
|
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.
|
|
66662
66786
|
|
|
66663
|
-
Auth: BAKER_API_KEY (
|
|
66787
|
+
Auth: BAKER_API_KEY (bk_ or bkr_) + BAKER_API_URL (your Convex .convex.site URL).
|
|
66664
66788
|
|
|
66665
66789
|
Subcommands:
|
|
66666
66790
|
baker winning-ads search "<free text>" \u2014 semantic search across the corpus; lean shortlist (advertiser, summary, scores, media_url)
|
|
@@ -66939,6 +67063,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
|
|
|
66939
67063
|
process.argv = [...process.argv.slice(0, 2), ...normalizeCacheFlag(process.argv.slice(2))];
|
|
66940
67064
|
installStreamTaps();
|
|
66941
67065
|
logInvocation(process.argv.slice(2));
|
|
67066
|
+
installExitRecord();
|
|
66942
67067
|
refuseUnknownFlags(main, process.argv.slice(2));
|
|
66943
67068
|
process.argv = [...process.argv.slice(0, 2), ...cacheFlagForParser(process.argv.slice(2))];
|
|
66944
67069
|
runMain(main);
|