@koda-sl/baker-cli 0.361.0-dev.5e38b7534 → 0.361.0-dev.a5e33d211

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 CHANGED
@@ -3567,6 +3567,7 @@ See everything a chat can reach — managed integrations, custom servers, and co
3567
3567
  baker mcp connected
3568
3568
  baker mcp list
3569
3569
  baker mcp add --name weather --url https://mcp.example.com/mcp
3570
+ baker mcp add --name acme --url https://acme.dev/mcp --header "Authorization: Bearer sk-…"
3570
3571
  baker mcp add --name mine --url https://my.dev/mcp --scope user
3571
3572
  baker mcp remove --name weather
3572
3573
  ```
@@ -3578,7 +3579,7 @@ baker mcp remove --name weather
3578
3579
  - `--scope org` — everyone across the org; needs an admin API key.
3579
3580
  - `--scope user` — only you, in this company; binds to the current message sender (requires a chat turn — the bridge supplies the sender via `BAKER_ACTING_USER_ID`).
3580
3581
  - `--scope user_org` — only you, across every company in the org; also binds to the sender (no admin needed — it only affects your own turns).
3581
- - Repeat `--header "Key: Value"` for extra request headers. Never pass a key, token or password with it, and never ask the user for one in chat: a server that needs a key is added by the user in the dashboard (Brain → Integrations → MCPs → Add custom server), where the model never sees it. Header values are stored server-side and ride the MCP transport — `list` returns only the header keys, never the values.
3582
+ - Repeat `--header "Key: Value"` for multiple auth headers. Header values are stored server-side and ride the MCP transport — `list` returns only the header keys, never the values.
3582
3583
 
3583
3584
  ---
3584
3585
 
@@ -5419,7 +5420,7 @@ Validate, then execute the graph. Blocks until done. Logs one line per node. Ret
5419
5420
 
5420
5421
  **Run history streams live.** The run posts its plan (every node + its dependency edges) the moment validation passes, then re-posts a progress snapshot as each node starts and settles — the dashboard's creative workflow graph shows nodes flipping pending → running → done in real time, with each node's outputs attached as they land. A failed run keeps its per-node trail (what completed, what died). All best-effort: an unreachable backend never changes the run's outcome.
5421
5422
 
5422
- **Failures don't abandon sibling work.** Nodes in a layer run under the concurrency cap and every one **settles** — a failed clip no longer kills its in-flight siblings, whose finished results still land in the content-addressed cache. One failure re-throws as-is; several are reported together (each failed node named). Re-running `baker canvas run` resumes from the cache and re-executes **only** the failed nodes and their descendants — never hand-orchestrate per-node renders. Long `video_generate` clips execute as **backend jobs** (the CLI polls; a CDN/proxy timeout can no longer kill a generation mid-flight).
5423
+ **Failures don't abandon sibling work.** Nodes in a layer run under the concurrency cap and every one **settles** — a failed clip no longer kills its in-flight siblings, whose finished results still land in the content-addressed cache. One failure re-throws as-is; several are reported together (each failed node named). Re-running `baker canvas run` resumes from the cache and re-executes **only** the failed nodes and their descendants — never hand-orchestrate per-node renders. **One render per canvas at a time:** a `run` of a canvas that another live process in the same workspace is still rendering (a backgrounded render, or a subagent's) is refused with `CONFLICT` instead of sharing its run — wait for it and use its result. Long `video_generate` clips execute as **backend jobs** (the CLI polls; a CDN/proxy timeout can no longer kill a generation mid-flight).
5423
5424
 
5424
5425
  #### `baker canvas scaffold-video <video> [flags]`
5425
5426
 
package/dist/cli.js CHANGED
@@ -40880,6 +40880,7 @@ async function clearCreativeDirty(slug, base) {
40880
40880
  }
40881
40881
 
40882
40882
  // src/commands/canvas/run-resume.ts
40883
+ import { readFileSync as readFileSync14 } from "fs";
40883
40884
  import { mkdir as mkdir4, readFile as readFile9, rm as rm4, writeFile as writeFile6 } from "fs/promises";
40884
40885
  import path13 from "path";
40885
40886
  function markerKey(canvasPath) {
@@ -40902,9 +40903,12 @@ function classifyRemoteRun(run, now) {
40902
40903
  }
40903
40904
  async function resolveRunId(opts) {
40904
40905
  if (opts.explicitRunId) return { runId: opts.explicitRunId, resumed: false };
40906
+ const existing = await readMarker(opts.outputsDir, opts.canvasPath);
40907
+ if (existing?.pid !== void 0 && existing.pid !== process.pid && (opts.isRendering ?? isRenderProcess)(existing.pid)) {
40908
+ return { runId: existing.runId, resumed: false, rendering: { runId: existing.runId, pid: existing.pid } };
40909
+ }
40905
40910
  if (!opts.fresh) {
40906
- const existing = await readMarkerRunId(opts.outputsDir, opts.canvasPath);
40907
- if (existing) return { runId: existing, resumed: true, source: "local" };
40911
+ if (existing) return { runId: existing.runId, resumed: true, source: "local" };
40908
40912
  if (opts.remote) {
40909
40913
  try {
40910
40914
  const active = await opts.remote.getActiveRun(opts.remote.creativeSlug, opts.remote.canvasSha);
@@ -40924,22 +40928,31 @@ async function resolveRunId(opts) {
40924
40928
  }
40925
40929
  return { runId: `r_${ulid()}`, resumed: false };
40926
40930
  }
40927
- async function readMarkerRunId(outputsDir, canvasPath) {
40931
+ async function readMarker(outputsDir, canvasPath) {
40928
40932
  for (const key of [markerKey(canvasPath), legacyMarkerKey(canvasPath)]) {
40929
40933
  try {
40930
40934
  const raw = await readFile9(markerFile(outputsDir, key), "utf8");
40931
40935
  const parsed = JSON.parse(raw);
40932
- if (typeof parsed.runId === "string" && parsed.runId.length > 0) return parsed.runId;
40936
+ if (typeof parsed.runId === "string" && parsed.runId.length > 0) {
40937
+ return { runId: parsed.runId, ...Number.isInteger(parsed.pid) ? { pid: parsed.pid } : {} };
40938
+ }
40933
40939
  } catch {
40934
40940
  }
40935
40941
  }
40936
40942
  return null;
40937
40943
  }
40944
+ function isRenderProcess(pid) {
40945
+ try {
40946
+ return readFileSync14(`/proc/${pid}/cmdline`, "utf8").includes("canvas");
40947
+ } catch {
40948
+ return false;
40949
+ }
40950
+ }
40938
40951
  async function markRunInFlight(outputsDir, canvasPath, runId) {
40939
40952
  try {
40940
40953
  const file = markerFile(outputsDir, markerKey(canvasPath));
40941
40954
  await mkdir4(path13.dirname(file), { recursive: true });
40942
- await writeFile6(file, JSON.stringify({ runId, canvasPath: path13.resolve(canvasPath), startedAt: Date.now() }));
40955
+ await writeFile6(file, JSON.stringify({ runId, pid: process.pid, canvasPath: path13.resolve(canvasPath), startedAt: Date.now() }));
40943
40956
  } catch {
40944
40957
  }
40945
40958
  }
@@ -41897,13 +41910,31 @@ ${describeRewrites(healed.rewrites)}
41897
41910
  const creativeSlug = creativeSlugFromCanvasPath(filePath) ?? void 0;
41898
41911
  const client = opts.record === false ? null : buildBackendClient();
41899
41912
  const outputsDir = opts.outputsDir ? path16.resolve(opts.outputsDir) : path16.resolve("canvas");
41900
- const { runId, resumed, source, concurrentRunId } = await resolveRunId({
41913
+ const { runId, resumed, source, concurrentRunId, rendering } = await resolveRunId({
41901
41914
  explicitRunId: opts.runId,
41902
41915
  fresh: opts.fresh === true,
41903
41916
  outputsDir,
41904
41917
  canvasPath: filePath,
41905
41918
  remote: client && creativeSlug ? { creativeSlug, canvasSha, getActiveRun: (slug, sha) => client.getActiveRun(slug, sha) } : void 0
41906
41919
  });
41920
+ if (rendering) {
41921
+ process.stderr.write(
41922
+ `${JSON.stringify(
41923
+ {
41924
+ ok: false,
41925
+ error: {
41926
+ code: "CONFLICT",
41927
+ message: `This canvas is already rendering in another process (run ${rendering.runId}, pid ${rendering.pid}).`,
41928
+ fix: "Wait for that render to finish and use its result instead of starting a second one: two renders of one canvas share a run and overwrite each other. If you started it in the background, read its output when it completes."
41929
+ }
41930
+ },
41931
+ null,
41932
+ 2
41933
+ )}
41934
+ `
41935
+ );
41936
+ process.exit(2);
41937
+ }
41907
41938
  if (resumed) {
41908
41939
  process.stdout.write(
41909
41940
  `[resume] continuing interrupted run ${runId}${source === "remote" ? " (adopted from run history)" : ""} \u2014 in-flight jobs re-attach, cached nodes skip
@@ -48257,11 +48288,11 @@ var addSideEffectCommand = defineCommand125({
48257
48288
  });
48258
48289
 
48259
48290
  // src/commands/flows/map.ts
48260
- import { readFileSync as readFileSync15 } from "fs";
48291
+ import { readFileSync as readFileSync16 } from "fs";
48261
48292
  import { defineCommand as defineCommand126 } from "citty";
48262
48293
 
48263
48294
  // src/commands/flows/value-expression.ts
48264
- import { existsSync as existsSync6, readFileSync as readFileSync14 } from "fs";
48295
+ import { existsSync as existsSync6, readFileSync as readFileSync15 } from "fs";
48265
48296
  import { join as join4 } from "path";
48266
48297
  var PREFIXES2 = ["field", "tracking", "global", "code"];
48267
48298
  function splitParts(raw) {
@@ -48348,7 +48379,7 @@ function trackingFieldIds() {
48348
48379
  const path48 = join4(flowsDir(), "..", "tracking.ts");
48349
48380
  if (!existsSync6(path48)) return null;
48350
48381
  try {
48351
- const source = readFileSync14(path48, "utf-8");
48382
+ const source = readFileSync15(path48, "utf-8");
48352
48383
  const block2 = source.match(/TRACKING_FIELD_IDS\s*=\s*\[([\s\S]*?)\]\s*as const/)?.[1];
48353
48384
  if (!block2) return null;
48354
48385
  const ids = [...block2.matchAll(/"(tracking\.[a-z0-9_]+)"/g)].map((match) => match[1]);
@@ -48925,7 +48956,7 @@ function specsFromFile(parsed) {
48925
48956
  function readSpecFile(path48) {
48926
48957
  let raw;
48927
48958
  try {
48928
- raw = path48 === "-" ? readFileSync15(0, "utf-8") : readFileSync15(path48, "utf-8");
48959
+ raw = path48 === "-" ? readFileSync16(0, "utf-8") : readFileSync16(path48, "utf-8");
48929
48960
  } catch (error) {
48930
48961
  refuse(
48931
48962
  `Could not read ${path48 === "-" ? "the mapping from stdin" : `"${path48}"`}: ${error instanceof Error ? error.message : String(error)}`
@@ -49624,7 +49655,7 @@ Full guide: __tooling__/docs/tools/baker/flows.md`
49624
49655
  });
49625
49656
 
49626
49657
  // src/commands/funnel/index.ts
49627
- import { readFileSync as readFileSync16 } from "fs";
49658
+ import { readFileSync as readFileSync17 } from "fs";
49628
49659
  import { defineCommand as defineCommand130 } from "citty";
49629
49660
 
49630
49661
  // src/commands/funnel/formMoments.ts
@@ -50420,7 +50451,7 @@ function workspaceForms() {
50420
50451
  const forms = [];
50421
50452
  for (const slug of listFlowSlugs()) {
50422
50453
  try {
50423
- forms.push({ slug, tree: JSON.parse(readFileSync16(flowDataPath(slug), "utf-8")) });
50454
+ forms.push({ slug, tree: JSON.parse(readFileSync17(flowDataPath(slug), "utf-8")) });
50424
50455
  } catch {
50425
50456
  }
50426
50457
  }
@@ -50555,7 +50586,7 @@ Examples:
50555
50586
  import { defineCommand as defineCommand132 } from "citty";
50556
50587
 
50557
50588
  // src/commands/ga4/shared.ts
50558
- import { readFileSync as readFileSync17 } from "fs";
50589
+ import { readFileSync as readFileSync18 } from "fs";
50559
50590
  function failValidation3(message) {
50560
50591
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
50561
50592
  process.exit(1);
@@ -50571,7 +50602,7 @@ function requireTarget5(args5, entity) {
50571
50602
  function readJsonSource(args5, flag) {
50572
50603
  const inline = args5[flag];
50573
50604
  const file = args5.file;
50574
- const raw = typeof file === "string" && file.length > 0 ? readFileSync17(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
50605
+ const raw = typeof file === "string" && file.length > 0 ? readFileSync18(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
50575
50606
  if (raw === void 0) {
50576
50607
  failValidation3(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
50577
50608
  }
@@ -50922,7 +50953,7 @@ Examples:
50922
50953
  });
50923
50954
 
50924
50955
  // src/commands/ga4/query.ts
50925
- import { appendFileSync as appendFileSync2, existsSync as existsSync7, readFileSync as readFileSync18, writeFileSync as writeFileSync4 } from "fs";
50956
+ import { appendFileSync as appendFileSync2, existsSync as existsSync7, readFileSync as readFileSync19, writeFileSync as writeFileSync4 } from "fs";
50926
50957
  import { resolve as resolve2 } from "path";
50927
50958
  import { defineCommand as defineCommand135 } from "citty";
50928
50959
 
@@ -51013,7 +51044,7 @@ function writeRowsToFile2(filePath, rows, append) {
51013
51044
  writeFileSync4(filePath, content, "utf-8");
51014
51045
  }
51015
51046
  } else if (append && existsSync7(filePath)) {
51016
- const existing = JSON.parse(readFileSync18(filePath, "utf-8"));
51047
+ const existing = JSON.parse(readFileSync19(filePath, "utf-8"));
51017
51048
  writeFileSync4(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
51018
51049
  } else {
51019
51050
  writeFileSync4(filePath, JSON.stringify(rows, null, 2), "utf-8");
@@ -51865,7 +51896,7 @@ Full guide: __tooling__/docs/tools/baker/ga4.md`
51865
51896
  import { defineCommand as defineCommand141 } from "citty";
51866
51897
 
51867
51898
  // src/commands/gsc/query.ts
51868
- import { appendFileSync as appendFileSync3, existsSync as existsSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync5 } from "fs";
51899
+ import { appendFileSync as appendFileSync3, existsSync as existsSync8, readFileSync as readFileSync20, writeFileSync as writeFileSync5 } from "fs";
51869
51900
  import { resolve as resolve3 } from "path";
51870
51901
  import { defineCommand as defineCommand138 } from "citty";
51871
51902
 
@@ -52013,7 +52044,7 @@ function writeRowsToFile3(filePath, rows, append) {
52013
52044
  writeFileSync5(filePath, content, "utf-8");
52014
52045
  }
52015
52046
  } else if (append && existsSync8(filePath)) {
52016
- const existing = JSON.parse(readFileSync19(filePath, "utf-8"));
52047
+ const existing = JSON.parse(readFileSync20(filePath, "utf-8"));
52017
52048
  writeFileSync5(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
52018
52049
  } else {
52019
52050
  writeFileSync5(filePath, JSON.stringify(rows, null, 2), "utf-8");
@@ -61836,7 +61867,6 @@ var listCommand16 = defineCommand183({
61836
61867
  }
61837
61868
  }
61838
61869
  });
61839
- var HEADER_DESCRIPTION = 'Extra request header "Key: Value" (repeatable). Never a key, token or password: never ask the user for one in chat \u2014 a server that needs a key is added by the user in the dashboard (Brain \u2192 Integrations \u2192 MCPs \u2192 Add custom server).';
61840
61870
  registerSchema({
61841
61871
  command: "mcp.add",
61842
61872
  description: "Register a custom MCP server. Tools appear as mcp__<name>__* on the next message. URL must be HTTPS. Scope: company (default, all chats) | org (org admin key) | user (only the current sender).",
@@ -61848,7 +61878,7 @@ registerSchema({
61848
61878
  required: true
61849
61879
  },
61850
61880
  scope: { type: "string", description: "user | user_org | company | org (default company)", required: false },
61851
- header: { type: "string", description: HEADER_DESCRIPTION, required: false }
61881
+ header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
61852
61882
  }
61853
61883
  });
61854
61884
  var addCommand2 = defineCommand183({
@@ -61860,6 +61890,7 @@ Scope: company (default \u2014 every chat in the company) | org (all companies i
61860
61890
 
61861
61891
  Examples:
61862
61892
  baker mcp add --name weather --url https://mcp.example.com/mcp
61893
+ baker mcp add --name acme --url https://acme.dev/mcp --header "Authorization: Bearer sk-\u2026"
61863
61894
  baker mcp add --name mine --url https://my.dev/mcp --scope user`
61864
61895
  },
61865
61896
  args: {
@@ -61870,7 +61901,7 @@ Examples:
61870
61901
  required: true
61871
61902
  },
61872
61903
  scope: { type: "string", description: "user | user_org | company | org (default company)", required: false },
61873
- header: { type: "string", description: HEADER_DESCRIPTION, required: false }
61904
+ header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
61874
61905
  },
61875
61906
  run: async ({ args: args5, rawArgs }) => {
61876
61907
  try {
@@ -61937,6 +61968,7 @@ Start here:
61937
61968
 
61938
61969
  Examples:
61939
61970
  baker mcp add --name weather --url https://mcp.example.com/mcp
61971
+ baker mcp add --name acme --url https://acme.dev/mcp --header "Authorization: Bearer sk-\u2026"
61940
61972
  baker mcp remove --name weather
61941
61973
  Full guide: __tooling__/docs/tools/baker/mcp.md`
61942
61974
  },
@@ -65646,7 +65678,7 @@ import { defineCommand as defineCommand221 } from "citty";
65646
65678
  import { defineCommand as defineCommand218 } from "citty";
65647
65679
 
65648
65680
  // src/commands/tag-manager/shared.ts
65649
- import { readFileSync as readFileSync20 } from "fs";
65681
+ import { readFileSync as readFileSync21 } from "fs";
65650
65682
  function failValidation5(message) {
65651
65683
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
65652
65684
  process.exit(1);
@@ -65662,7 +65694,7 @@ function requireTarget6(args5, entity) {
65662
65694
  function loadJsonArg2(args5, flag = "json") {
65663
65695
  const inline = args5[flag];
65664
65696
  const file = args5.file;
65665
- const raw = typeof file === "string" && file.length > 0 ? readFileSync20(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
65697
+ const raw = typeof file === "string" && file.length > 0 ? readFileSync21(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
65666
65698
  if (raw === void 0) {
65667
65699
  failValidation5(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
65668
65700
  }
@@ -69065,7 +69097,7 @@ function outputFlagForCommand(root, argv) {
69065
69097
  }
69066
69098
 
69067
69099
  // src/version.ts
69068
- import { readFileSync as readFileSync21 } from "fs";
69100
+ import { readFileSync as readFileSync22 } from "fs";
69069
69101
  function packageJsonUrl() {
69070
69102
  return new URL("../package.json", import.meta.url);
69071
69103
  }
@@ -69077,7 +69109,7 @@ function parsePackageVersion(raw) {
69077
69109
  throw new Error("Invalid CLI package.json: missing version");
69078
69110
  }
69079
69111
  function getCliVersion() {
69080
- return parsePackageVersion(readFileSync21(packageJsonUrl(), "utf8"));
69112
+ return parsePackageVersion(readFileSync22(packageJsonUrl(), "utf8"));
69081
69113
  }
69082
69114
 
69083
69115
  // src/cli.ts