@koda-sl/baker-cli 0.131.0 → 0.132.1-dev.42a8955b3

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.
Files changed (32) hide show
  1. package/README.md +47 -0
  2. package/dist/chunk-7I2POXSJ.js +153 -0
  3. package/dist/chunk-7I2POXSJ.js.map +1 -0
  4. package/dist/{chunk-AVJ3B6LC.js → chunk-BFZELBTE.js} +4 -4
  5. package/dist/{chunk-AEBAUSIN.js → chunk-O3TH7JW5.js} +28 -5
  6. package/dist/chunk-O3TH7JW5.js.map +1 -0
  7. package/dist/{chunk-ISFSUDEQ.js → chunk-PEBP6G74.js} +3 -3
  8. package/dist/chunk-RK67WL4O.js +72 -0
  9. package/dist/{chunk-YTEAWSEM.js.map → chunk-RK67WL4O.js.map} +1 -1
  10. package/dist/{chunk-K47Q73CK.js → chunk-SCI57ZZ6.js} +40 -4
  11. package/dist/chunk-SCI57ZZ6.js.map +1 -0
  12. package/dist/cli.js +1491 -1313
  13. package/dist/cli.js.map +1 -1
  14. package/dist/client-N7XWYCHT.js +15 -0
  15. package/dist/engine/index.js +3 -2
  16. package/dist/env-3JMYIH25.js +11 -0
  17. package/dist/{output-2LGBISBQ.js → output-7M5VQPTZ.js} +5 -5
  18. package/dist/{shared-CQC3YRBA.js → shared-6SZHAUM2.js} +6 -6
  19. package/package.json +1 -1
  20. package/dist/chunk-5WRI5ZAA.js +0 -31
  21. package/dist/chunk-AEBAUSIN.js.map +0 -1
  22. package/dist/chunk-K47Q73CK.js.map +0 -1
  23. package/dist/chunk-YTEAWSEM.js +0 -39
  24. package/dist/client-PGOTU24X.js +0 -15
  25. package/dist/env-TD4VXCQ7.js +0 -10
  26. package/dist/shared-CQC3YRBA.js.map +0 -1
  27. /package/dist/{chunk-AVJ3B6LC.js.map → chunk-BFZELBTE.js.map} +0 -0
  28. /package/dist/{chunk-ISFSUDEQ.js.map → chunk-PEBP6G74.js.map} +0 -0
  29. /package/dist/{chunk-5WRI5ZAA.js.map → client-N7XWYCHT.js.map} +0 -0
  30. /package/dist/{client-PGOTU24X.js.map → env-3JMYIH25.js.map} +0 -0
  31. /package/dist/{env-TD4VXCQ7.js.map → output-7M5VQPTZ.js.map} +0 -0
  32. /package/dist/{output-2LGBISBQ.js.map → shared-6SZHAUM2.js.map} +0 -0
package/README.md CHANGED
@@ -44,6 +44,26 @@ export BAKER_CHAT_ID="<chat-id>"
44
44
  - `BAKER_X_ADS_ACCOUNT_ID` — default X Ads account ID (base36). Used when `--account-id` is not passed. If neither is set and exactly one X Ads account is connected, it is auto-selected.
45
45
  - `BAKER_CHAT_ID` — chat context for staged Work Action commands and staged Scheduled Action create/update/delete. `scheduled-actions trigger` does not require it.
46
46
 
47
+ ## Debug logging
48
+
49
+ Set `BAKER_DEBUG_LOG` to capture a full-fidelity trace of everything a command does — useful when reproducing or reporting an issue.
50
+
51
+ ```bash
52
+ export BAKER_DEBUG_LOG=1 # append to ./baker-cli-debug.jsonl
53
+ export BAKER_DEBUG_LOG=/tmp/baker.jsonl # append to a specific file
54
+ export BAKER_DEBUG_LOG=0 # disabled (also: false / off / no / unset)
55
+ ```
56
+
57
+ When enabled, each run appends JSONL entries for:
58
+
59
+ - **`http`** — every request/response for both the REST and canvas engine clients (method, URL, request body, status, response body, duration, and any network/timeout error).
60
+ - **`output`** — every chunk written to stdout and stderr.
61
+ - **`invocation`** — the command-line arguments and working directory.
62
+
63
+ Logging is fail-open — a logging error never affects the command — and has zero overhead when the variable is unset. The file is appended to across runs (delete it to start fresh) and rotates to `<file>.1` once it passes 64 MB so it can't fill the disk.
64
+
65
+ **Secret redaction is best-effort.** Before a line is written, known secret shapes are scrubbed: `Authorization: Bearer …` headers, `bk_` Baker keys, JWTs / id tokens, and Google/Meta ad-platform tokens. This is not exhaustive — a credential in an unrecognized shape (e.g. a bare API key or cookie with no recognizable prefix) can still be captured. Treat the log as sensitive, and prefer pointing `BAKER_DEBUG_LOG` at a path outside any tracked repo.
66
+
47
67
  ## Output Format
48
68
 
49
69
  All commands return a JSON envelope:
@@ -934,6 +954,33 @@ Each finding: `{id, area, check, status, severity, evidence, fix: {explanation,
934
954
 
935
955
  ---
936
956
 
957
+ ### Landing Analytics (`baker analytics`)
958
+
959
+ First-party analytics for every published landing page — pageviews, unique visitors, sessions, and form submits, collected by a built-in consent-aware beacon (no setup, no third-party script) and stored in Tinybird. Read-only; scoped to the API key's company.
960
+
961
+ ```bash
962
+ baker analytics # = overview, last 28 days
963
+ baker analytics overview --period 7d
964
+ baker analytics timeseries --period 28d --output md
965
+ baker analytics pages --period 28d --limit 20
966
+ baker analytics sources --period 90d
967
+ baker analytics events --period 7d
968
+ ```
969
+
970
+ | Subcommand | Returns |
971
+ |---|---|
972
+ | `overview` | pageviews, visitors, sessions, form_submits |
973
+ | `timeseries` | daily pageviews/visitors/form_submits |
974
+ | `pages` | top pages by pageviews |
975
+ | `sources` | top traffic sources (utm_source → referrer domain → direct) |
976
+ | `events` | non-pageview events (form_submit + custom) |
977
+
978
+ Flags: `--period today|7d|28d|90d` (default `28d`), `--limit 1-100` (list reports), `--output json|files|md`, `--fields a,b`.
979
+
980
+ Backend env: `TINYBIRD_TOKEN` (read token) and optional `TINYBIRD_HOST` on the Convex deployment — unset, commands return a clean "not configured" error. See `tinybird/README.md`.
981
+
982
+ ---
983
+
937
984
  ### Google Analytics 4 (`baker ga4`)
938
985
 
939
986
  GA4 commands for multi-channel audits. Playbook-aligned presets, property health audits, and free-form Data API queries.
@@ -0,0 +1,153 @@
1
+ import {
2
+ debugLogSetting
3
+ } from "./chunk-RK67WL4O.js";
4
+
5
+ // src/debugLog.ts
6
+ import { appendFileSync, mkdirSync, renameSync, statSync } from "fs";
7
+ import { dirname, isAbsolute, resolve } from "path";
8
+ var DEFAULT_FILE = "baker-cli-debug.jsonl";
9
+ var BOOLEAN_ON = /* @__PURE__ */ new Set(["1", "true", "on", "yes"]);
10
+ var BOOLEAN_OFF = /* @__PURE__ */ new Set(["0", "false", "off", "no"]);
11
+ var MAX_BYTES = 64 * 1024 * 1024;
12
+ var REDACTIONS = [
13
+ [/Bearer\s+[A-Za-z0-9._-]+/g, "Bearer [redacted]"],
14
+ // Authorization headers
15
+ [/bk_[A-Za-z0-9]+/g, "bk_[redacted]"],
16
+ // Baker API keys
17
+ [/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, "[redacted-jwt]"],
18
+ // JWTs / id tokens
19
+ [/ya29\.[A-Za-z0-9._-]+/g, "[redacted-google-token]"],
20
+ // Google OAuth access tokens
21
+ [/1\/\/[A-Za-z0-9._-]+/g, "[redacted-google-refresh]"],
22
+ // Google refresh tokens
23
+ [/EAA[A-Za-z0-9]{20,}/g, "[redacted-meta-token]"]
24
+ // Meta/Facebook access tokens
25
+ ];
26
+ function redactSecrets(input) {
27
+ let out = input;
28
+ for (const [pattern, replacement] of REDACTIONS) {
29
+ out = out.replace(pattern, replacement);
30
+ }
31
+ return out;
32
+ }
33
+ function resolveTarget() {
34
+ const raw = debugLogSetting();
35
+ if (!raw) {
36
+ return void 0;
37
+ }
38
+ const lower = raw.toLowerCase();
39
+ if (BOOLEAN_OFF.has(lower)) {
40
+ return void 0;
41
+ }
42
+ const target = BOOLEAN_ON.has(lower) ? DEFAULT_FILE : raw;
43
+ return isAbsolute(target) ? target : resolve(process.cwd(), target);
44
+ }
45
+ function isDebugLogEnabled() {
46
+ return resolveTarget() !== void 0;
47
+ }
48
+ var sessionId;
49
+ function getSessionId() {
50
+ if (!sessionId) {
51
+ sessionId = `${process.pid}-${Date.now()}`;
52
+ }
53
+ return sessionId;
54
+ }
55
+ var trackedPath;
56
+ var bytesInFile = 0;
57
+ function ensureReady(filePath) {
58
+ if (trackedPath !== filePath) {
59
+ trackedPath = filePath;
60
+ mkdirSync(dirname(filePath), { recursive: true });
61
+ try {
62
+ bytesInFile = statSync(filePath).size;
63
+ } catch {
64
+ bytesInFile = 0;
65
+ }
66
+ }
67
+ }
68
+ function append(entry) {
69
+ const filePath = resolveTarget();
70
+ if (!filePath) {
71
+ return;
72
+ }
73
+ try {
74
+ const payload = { ts: (/* @__PURE__ */ new Date()).toISOString(), session: getSessionId(), ...entry };
75
+ const line = `${redactSecrets(JSON.stringify(payload))}
76
+ `;
77
+ ensureReady(filePath);
78
+ const size = Buffer.byteLength(line);
79
+ if (bytesInFile + size > MAX_BYTES) {
80
+ renameSync(filePath, `${filePath}.1`);
81
+ bytesInFile = 0;
82
+ }
83
+ appendFileSync(filePath, line);
84
+ bytesInFile += size;
85
+ } catch {
86
+ }
87
+ }
88
+ function errorToPlain(err) {
89
+ if (err instanceof Error) {
90
+ const code = err.code;
91
+ return { name: err.name, message: err.message, ...typeof code === "string" ? { code } : {} };
92
+ }
93
+ return { message: String(err) };
94
+ }
95
+ function logInvocation(argv) {
96
+ append({ kind: "invocation", argv, cwd: process.cwd() });
97
+ }
98
+ function debugLogHttp(entry) {
99
+ if (!isDebugLogEnabled()) {
100
+ return;
101
+ }
102
+ append({
103
+ kind: "http",
104
+ source: entry.source,
105
+ method: entry.method,
106
+ url: entry.url,
107
+ durationMs: entry.durationMs,
108
+ request: entry.requestBody,
109
+ status: entry.status,
110
+ ok: entry.ok,
111
+ response: entry.responseBody,
112
+ error: entry.error === void 0 ? void 0 : errorToPlain(entry.error)
113
+ });
114
+ }
115
+ async function readBodyForLog(response) {
116
+ if (!isDebugLogEnabled()) {
117
+ return void 0;
118
+ }
119
+ try {
120
+ return await response.clone().text();
121
+ } catch {
122
+ return void 0;
123
+ }
124
+ }
125
+ function tapStream(name, stream) {
126
+ const original = stream.write.bind(stream);
127
+ const decoder = new TextDecoder("utf-8");
128
+ stream.write = ((chunk, ...rest) => {
129
+ try {
130
+ const text = typeof chunk === "string" ? chunk : chunk instanceof Uint8Array ? decoder.decode(chunk, { stream: true }) : String(chunk);
131
+ append({ kind: "output", stream: name, text });
132
+ } catch {
133
+ }
134
+ return original(chunk, ...rest);
135
+ });
136
+ }
137
+ var tapsInstalled = false;
138
+ function installStreamTaps() {
139
+ if (tapsInstalled || !isDebugLogEnabled()) {
140
+ return;
141
+ }
142
+ tapsInstalled = true;
143
+ tapStream("stdout", process.stdout);
144
+ tapStream("stderr", process.stderr);
145
+ }
146
+
147
+ export {
148
+ logInvocation,
149
+ debugLogHttp,
150
+ readBodyForLog,
151
+ installStreamTaps
152
+ };
153
+ //# sourceMappingURL=chunk-7I2POXSJ.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 [/bk_[A-Za-z0-9]+/g, \"bk_[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\nexport function logInvocation(argv: string[]): void {\n append({ kind: \"invocation\", argv, cwd: process.cwd() });\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,13 +1,13 @@
1
1
  import {
2
2
  handleConnectionError,
3
3
  writeAdsJson
4
- } from "./chunk-ISFSUDEQ.js";
4
+ } from "./chunk-PEBP6G74.js";
5
5
  import {
6
6
  ApiError
7
- } from "./chunk-K47Q73CK.js";
7
+ } from "./chunk-SCI57ZZ6.js";
8
8
  import {
9
9
  getEnv
10
- } from "./chunk-YTEAWSEM.js";
10
+ } from "./chunk-RK67WL4O.js";
11
11
 
12
12
  // src/commands/ads/meta/shared.ts
13
13
  var DAY_MS = 864e5;
@@ -94,4 +94,4 @@ export {
94
94
  csvOrJson,
95
95
  resolveEffectiveStatus
96
96
  };
97
- //# sourceMappingURL=chunk-AVJ3B6LC.js.map
97
+ //# sourceMappingURL=chunk-BFZELBTE.js.map
@@ -1,11 +1,15 @@
1
+ import {
2
+ debugLogHttp,
3
+ readBodyForLog
4
+ } from "./chunk-7I2POXSJ.js";
1
5
  import {
2
6
  __commonJS,
3
7
  __toESM
4
- } from "./chunk-5WRI5ZAA.js";
8
+ } from "./chunk-RK67WL4O.js";
5
9
 
6
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
10
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/index.js
7
11
  var require_safe_stable_stringify = __commonJS({
8
- "../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
12
+ "../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/index.js"(exports, module) {
9
13
  "use strict";
10
14
  var { hasOwnProperty } = Object.prototype;
11
15
  var stringify = configure2();
@@ -679,6 +683,7 @@ var HttpClient = class {
679
683
  else signal.addEventListener("abort", onAbort, { once: true });
680
684
  }
681
685
  const timer = setTimeout(() => controller.abort(new Error("timeout")), this.timeoutMs);
686
+ const startedAt = Date.now();
682
687
  try {
683
688
  const res = await this.fetchFn(url, {
684
689
  method,
@@ -686,11 +691,29 @@ var HttpClient = class {
686
691
  body: method === "GET" ? void 0 : JSON.stringify(body),
687
692
  signal: controller.signal
688
693
  });
694
+ debugLogHttp({
695
+ source: "canvas",
696
+ method,
697
+ url,
698
+ requestBody: method === "GET" ? void 0 : body,
699
+ status: res.status,
700
+ ok: res.ok,
701
+ responseBody: await readBodyForLog(res),
702
+ durationMs: Date.now() - startedAt
703
+ });
689
704
  if (res.ok) return { kind: "value", value: await res.json() };
690
705
  const err = await parseErrorBody(res);
691
706
  if (attempt < this.maxRetries && shouldRetry(err)) return { kind: "retry" };
692
707
  return { kind: "throw", error: new BackendHttpError(err) };
693
708
  } catch (e) {
709
+ debugLogHttp({
710
+ source: "canvas",
711
+ method,
712
+ url,
713
+ requestBody: method === "GET" ? void 0 : body,
714
+ durationMs: Date.now() - startedAt,
715
+ error: e
716
+ });
694
717
  return this.handleAttemptException(e, attempt, signal, method);
695
718
  } finally {
696
719
  clearTimeout(timer);
@@ -979,7 +1002,7 @@ function describeCause(c) {
979
1002
  }
980
1003
  }
981
1004
 
982
- // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
1005
+ // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/810146e81bae4e3a061fe487864f2fde80c4b03b886877dc0f1fffbc6480b67e/node_modules/safe-stable-stringify/esm/wrapper.js
983
1006
  var import__ = __toESM(require_safe_stable_stringify(), 1);
984
1007
  var configure = import__.default.configure;
985
1008
  var wrapper_default = import__.default;
@@ -7696,4 +7719,4 @@ export {
7696
7719
  defaultRegistry,
7697
7720
  createEngineFromEnv
7698
7721
  };
7699
- //# sourceMappingURL=chunk-AEBAUSIN.js.map
7722
+ //# sourceMappingURL=chunk-O3TH7JW5.js.map