@koda-sl/baker-cli 0.456.0-dev.fb98ea199 → 0.457.0-dev.f1df1f4e9

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
@@ -67709,6 +67709,30 @@ function unsourcedFigureLines(spec, knowledge2) {
67709
67709
  return claims.length > 0 ? [{ text: line.text, claims }] : [];
67710
67710
  });
67711
67711
  }
67712
+ var QUOTED_RUN = 5;
67713
+ var SIGNING_ROLE = /^(attribution|author|byline|name|reviewer|source|signature)$/i;
67714
+ var SIGNED2 = new RegExp("(?:^|\\s)[\u2014\u2013-]\\s*\\p{Lu}", "u");
67715
+ var quoteWords = (text3) => text3.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
67716
+ function quotes(line, quote) {
67717
+ const said = ` ${quoteWords(line).join(" ")} `;
67718
+ const words2 = quoteWords(quote);
67719
+ for (let i = 0; i + QUOTED_RUN <= words2.length; i++) {
67720
+ if (said.includes(` ${words2.slice(i, i + QUOTED_RUN).join(" ")} `)) return true;
67721
+ }
67722
+ return false;
67723
+ }
67724
+ function unattributedQuotes(spec, said) {
67725
+ const signedApart = spec.copy.some((line) => SIGNING_ROLE.test(line.role ?? ""));
67726
+ return spec.copy.flatMap((line) => {
67727
+ if (signedApart || SIGNED2.test(line.text)) return [];
67728
+ const by = said.find((q) => quotes(line.text, q.quote));
67729
+ if (!by) return [];
67730
+ const name = by.author ? `"\u2014 ${by.author}"` : '"\u2014 <their first name and initial>"';
67731
+ return [
67732
+ `"${line.text}" sets a customer's words with no name on them: add ${name} to the line (or a line of its own with role "attribution"); the review blocks a quote nobody signed.`
67733
+ ];
67734
+ });
67735
+ }
67712
67736
  function claimsWithoutSource(spec, knowledge2) {
67713
67737
  return [...new Set(unsourcedFigureLines(spec, knowledge2).flatMap((l) => l.claims))];
67714
67738
  }
@@ -71142,6 +71166,7 @@ function parseInsight(id, markdown) {
71142
71166
  const force = text2(fm.force);
71143
71167
  const persona = text2(fm.persona);
71144
71168
  const sourceKind = text2(fm.sourceKind);
71169
+ const author = markdown.replace(/^---[\s\S]*?\n---/, "").match(/\bby ([\p{Lu}][\p{L}'’-]*\.?(?: [\p{Lu}][\p{L}'’-]*\.?)?)/u)?.[1]?.replace(new RegExp("(\\p{L}{2,})\\.$", "u"), "$1");
71145
71170
  return {
71146
71171
  id,
71147
71172
  type: text2(fm.type) ?? "other",
@@ -71150,7 +71175,8 @@ function parseInsight(id, markdown) {
71150
71175
  status: evidenceStatus(oneOf(EVIDENCE_LEVELS, fm.status) ?? "observed", quote, source),
71151
71176
  ...sourceKind ? { sourceKind } : {},
71152
71177
  ...force ? { force } : {},
71153
- ...persona ? { persona } : {}
71178
+ ...persona ? { persona } : {},
71179
+ ...author ? { author } : {}
71154
71180
  };
71155
71181
  }
71156
71182
  function evidenceList(value2) {
@@ -71779,6 +71805,7 @@ async function staticSpecGate(canvas, canvasDir) {
71779
71805
  };
71780
71806
  const root = await findBrandRoot(canvasDir) ?? findWorkspaceRoot(canvasDir) ?? canvasDir;
71781
71807
  const records = await readRecords(root);
71808
+ const ours = (await readInsights(root)).filter(sourcesClaims);
71782
71809
  const gates = spec.native ? [
71783
71810
  concept,
71784
71811
  {
@@ -71797,7 +71824,7 @@ async function staticSpecGate(canvas, canvasDir) {
71797
71824
  concept,
71798
71825
  {
71799
71826
  code: "proof_without_source",
71800
- problems: proofProblems(spec, records),
71827
+ problems: [...proofProblems(spec, records), ...unattributedQuotes(spec, ours)],
71801
71828
  fix: proofFix(claimsWithoutSource(spec, records))
71802
71829
  }
71803
71830
  ];
@@ -71805,7 +71832,7 @@ async function staticSpecGate(canvas, canvasDir) {
71805
71832
  }
71806
71833
  function proofFix(claims) {
71807
71834
  const named = claims.length > 0 ? `drop ${claims.map((c) => `"${c}"`).join(", ")} or source it in the Knowledge, and ` : "";
71808
- return `In prompt.json, ${named}wire the badge or drop any other claim named above, everywhere it appears (copy and scene).`;
71835
+ return `In prompt.json, ${named}wire the badge or drop any other claim named above, everywhere it appears (copy and scene), and sign each customer quote named above with the name given.`;
71809
71836
  }
71810
71837
  function oneRefusal(gates) {
71811
71838
  const first = gates[0];
@@ -81125,17 +81152,17 @@ function customerTruth(insights) {
81125
81152
  for (const insight of insights) byType[insight.type] = (byType[insight.type] ?? 0) + 1;
81126
81153
  const observed = insights.filter((i) => i.status === "observed");
81127
81154
  const seen = /* @__PURE__ */ new Set();
81128
- const quotes = [];
81155
+ const quotes2 = [];
81129
81156
  for (const insight of observed) {
81130
- if (seen.has(insight.type) || quotes.length >= MAX_QUOTES) continue;
81157
+ if (seen.has(insight.type) || quotes2.length >= MAX_QUOTES) continue;
81131
81158
  seen.add(insight.type);
81132
- quotes.push({
81159
+ quotes2.push({
81133
81160
  id: insight.id,
81134
81161
  type: insight.type,
81135
81162
  quote: insight.quote.length > 140 ? `${insight.quote.slice(0, 137)}...` : insight.quote
81136
81163
  });
81137
81164
  }
81138
- return { total: insights.length, observed: observed.length, thin: observed.length < MIN_OBSERVED, byType, quotes };
81165
+ return { total: insights.length, observed: observed.length, thin: observed.length < MIN_OBSERVED, byType, quotes: quotes2 };
81139
81166
  }
81140
81167
  var MAX_SAYING = 6;
81141
81168
  var SAME_ANGLE = 0.4;
@@ -102049,14 +102076,14 @@ function insightSlug(type, quote) {
102049
102076
  return [type.replace(/_/g, "-"), ...asciiWords(quote).slice(0, SLUG_WORDS)].join("-");
102050
102077
  }
102051
102078
  function planInsightWrites(insights, existing, limit) {
102052
- const quotes = new Set(existing.map((e) => foldWithOffsets(e.quote).folded));
102079
+ const quotes2 = new Set(existing.map((e) => foldWithOffsets(e.quote).folded));
102053
102080
  const ids2 = new Set(existing.map((e) => e.id));
102054
102081
  const ranked = [...insights].sort((a, b) => INSIGHT_TYPES.indexOf(a.type) - INSIGHT_TYPES.indexOf(b.type));
102055
102082
  const writes = [];
102056
102083
  let skippedExisting = 0;
102057
102084
  for (const insight of ranked) {
102058
102085
  const folded2 = foldWithOffsets(insight.quote).folded;
102059
- if (quotes.has(folded2)) {
102086
+ if (quotes2.has(folded2)) {
102060
102087
  skippedExisting++;
102061
102088
  continue;
102062
102089
  }
@@ -102064,7 +102091,7 @@ function planInsightWrites(insights, existing, limit) {
102064
102091
  const base = insightSlug(insight.type, insight.quote);
102065
102092
  let id = base;
102066
102093
  for (let n = 2; ids2.has(id); n++) id = `${base}-${n}`;
102067
- quotes.add(folded2);
102094
+ quotes2.add(folded2);
102068
102095
  ids2.add(id);
102069
102096
  writes.push({ id, insight });
102070
102097
  }