@koda-sl/baker-cli 0.345.0 → 0.347.0-dev.043fc924c

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/dist/cli.js CHANGED
@@ -67,7 +67,7 @@ import {
67
67
  validateCanvasDeep,
68
68
  withoutCastName,
69
69
  ytDlpBlockSignal
70
- } from "./chunk-FFOURYP5.js";
70
+ } from "./chunk-D5P4COPD.js";
71
71
  import {
72
72
  csvOrJson,
73
73
  daysAgoIso,
@@ -789,6 +789,50 @@ var actionsUpdateRequestSchema = z.object({
789
789
  var actionsUpdateResponseSchema = okOnlySchema();
790
790
  var ACTION_COMPLETE_NOTE_MIN = 20;
791
791
  var actionsCompleteNoteMessage = `A completion note (\u2265${ACTION_COMPLETE_NOTE_MIN} chars) describing what was done is required: what changed, where, and the outcome.`;
792
+ var ACCOUNT_CONTEXT = "(?:account|accounts|cuenta|cuentas|customer|cliente|property|propiedad|meta|facebook|google|ads|linkedin|ga4|analytics|gtm|tag manager|id)";
793
+ var COMPLETION_NOTE_INTERNALS = [
794
+ // Repo paths: rooted in a workspace directory, or a path or lowercase file name
795
+ // ending in a source extension (a product name like "Next.js" is not a file).
796
+ /(?:\.{0,2}\/)?(?:src|public|__tooling__|\.claude)\/[^\s,;:)`'"]*[^\s,;:)`'".]/g,
797
+ /(?:[\w.-]*\/[\w./-]*|\b[a-z_][\w-]*)\.(?:mdx?|astro|tsx?|jsx?|mjs|json|ya?ml)\b/g,
798
+ // Meta ad-account ids, Tag Manager containers and GA4 measurement ids.
799
+ /\bact_\d+\b/g,
800
+ /\bGTM-[A-Z0-9]{4,}\b/g,
801
+ /\bG-[A-Z0-9]{6,}\b/g,
802
+ // Google Ads customer ids (386-508-3115), LinkedIn, GA4 and bare Google Ads ids:
803
+ // a long number named next to a platform or an account, so a phone number or
804
+ // a figure elsewhere in the note is not one.
805
+ new RegExp(
806
+ String.raw`(?<=\b${ACCOUNT_CONTEXT}\b[^.\n\d]{0,20})(?<![\w-])(?:\d{3}-\d{3}-\d{4}|\d{7,})(?![\w-])`,
807
+ "gi"
808
+ ),
809
+ // Error codes: SCREAMING_SNAKE in the shapes platforms and Baker return them
810
+ // (NO_GOOGLE_ADS_CONNECTION, PERMISSION_DENIED, INVALID_ACCOUNT_ID).
811
+ /\b(?:(?:ERR|INVALID|MISSING)(?:_[A-Z0-9]+)+|[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*_(?:ERROR|CONNECTION|FAILED|NOT_FOUND|DENIED|REQUIRED|INVALID|EXPIRED|UNAVAILABLE|EXCEEDED|UNREACHABLE|UNAUTHORIZED|FORBIDDEN|TIMEOUT|TOKEN)|BAD_REQUEST|NOT_FOUND|RATE_LIMITED)\b/g,
812
+ // CLI invocations (`baker analytics flow`).
813
+ /\bbaker [a-z][a-z-]*/g
814
+ ];
815
+ function completionNoteInternals(note) {
816
+ const hits = [];
817
+ for (const pattern of COMPLETION_NOTE_INTERNALS) {
818
+ for (const match of note.matchAll(pattern)) {
819
+ const index = match.index ?? 0;
820
+ hits.push({ index, end: index + match[0].length, text: match[0] });
821
+ }
822
+ }
823
+ hits.sort((a, b) => a.index - b.index || b.end - a.end);
824
+ const found = [];
825
+ let coveredUntil = -1;
826
+ for (const hit of hits) {
827
+ if (hit.index < coveredUntil) continue;
828
+ found.push(hit.text);
829
+ coveredUntil = hit.end;
830
+ }
831
+ return found;
832
+ }
833
+ function completionNoteInternalsMessage(internals) {
834
+ return `The completion note is read by the client on the Task, and it carries internal details they cannot use: ${internals.join(", ")}. Rewrite it in product terms \u2014 name the page, campaign or Knowledge entry instead of a file, the platform instead of an account id, and say what is missing instead of an error code.`;
835
+ }
792
836
  var actionsCompleteRequestSchema = z.object({
793
837
  chatId: z.string(),
794
838
  actionRef: z.string().min(1, "actionRef is required"),
@@ -796,6 +840,11 @@ var actionsCompleteRequestSchema = z.object({
796
840
  }).transform((body) => ({ ...body, note: (body.note ?? "").trim() })).refine((body) => body.note.length >= ACTION_COMPLETE_NOTE_MIN, {
797
841
  message: actionsCompleteNoteMessage,
798
842
  path: ["note"]
843
+ }).superRefine((body, ctx) => {
844
+ const internals = completionNoteInternals(body.note);
845
+ if (internals.length > 0) {
846
+ ctx.addIssue({ code: "custom", message: completionNoteInternalsMessage(internals), path: ["note"] });
847
+ }
799
848
  });
800
849
  var actionsCompleteResponseSchema = okOnlySchema();
801
850
  var actionsDiscardRequestSchema = z.object({
@@ -8460,12 +8509,12 @@ var claimCommand = defineCommand({
8460
8509
  import { defineCommand as defineCommand2 } from "citty";
8461
8510
  registerSchema({
8462
8511
  command: "actions.complete",
8463
- description: "Stage completion of an action (it was DONE). Accepts a real action ID (must be claimed) or a temp ID from the same draft. The action becomes completed when the chat is published. --note is REQUIRED and must describe what you actually did to resolve it (what changed, where, and the outcome) \u2014 it is the client-facing record surfaced by `baker actions log`. Do NOT use this to drop an action you no longer want \u2014 to remove a staged op use `actions draft remove`, to close an unwanted published action use `actions discard`.",
8512
+ description: 'Stage completion of an action (it was DONE). Accepts a real action ID (must be claimed) or a temp ID from the same draft. The action becomes completed when the chat is published. --note is REQUIRED and must describe what you actually did to resolve it (what changed, where, and the outcome) \u2014 it is the client-facing record shown on the Task in Tasks and surfaced by `baker actions log`, so write it for a marketer, in the client\'s language and product terms: a few lines, no file paths, account ids, error codes or `baker` commands ("Weekly review saved in your Knowledge; Google Ads and LinkedIn are not connected yet", not "written to src/content/audits/\u2026md; NO_GOOGLE_ADS_CONNECTION"). A note carrying those is refused. Do NOT use this to drop an action you no longer want \u2014 to remove a staged op use `actions draft remove`, to close an unwanted published action use `actions discard`.',
8464
8513
  args: {
8465
8514
  id: { type: "string", description: "Action ID or temp ID", required: true },
8466
8515
  note: {
8467
8516
  type: "string",
8468
- description: "REQUIRED. Detailed description of what you did to resolve this: what changed, where, and the outcome. This is the durable, client-facing record shown by `baker actions log`.",
8517
+ description: "REQUIRED. What you did to resolve this \u2014 what changed, where (in product terms: the page, the campaign, Knowledge), and the outcome \u2014 in a few lines. The client reads it on the Task: no file paths, account ids, error codes or `baker` commands.",
8469
8518
  required: true
8470
8519
  }
8471
8520
  }
@@ -8480,7 +8529,7 @@ var completeCommand = defineCommand2({
8480
8529
  "action-id": { type: "string", description: "Action ID or temp ID", required: false },
8481
8530
  note: {
8482
8531
  type: "string",
8483
- description: "REQUIRED. What you did to resolve this: what changed, where, and the outcome.",
8532
+ description: "REQUIRED. What you did, where (in product terms) and the outcome \u2014 read by the client, so no file paths, account ids or error codes.",
8484
8533
  required: false
8485
8534
  }
8486
8535
  },
@@ -8499,6 +8548,10 @@ var completeCommand = defineCommand2({
8499
8548
  `--note is required and must describe what you did (\u2265${ACTION_COMPLETE_NOTE_MIN} chars): what changed, where, and the outcome. This becomes the client-facing record surfaced by \`baker actions log\`.`
8500
8549
  );
8501
8550
  }
8551
+ const internals = completionNoteInternals(note);
8552
+ if (internals.length > 0) {
8553
+ failValidation(`--note: ${completionNoteInternalsMessage(internals)} Then run the same command again.`);
8554
+ }
8502
8555
  const chatId = requireChatId();
8503
8556
  await apiPost("/api/actions/complete", { chatId, actionRef: id, note });
8504
8557
  writeOk();