@koda-sl/baker-cli 0.290.2 → 0.290.3
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 -0
- package/dist/cli.js +18 -4
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5870,6 +5870,8 @@ baker landing critique spring-offer summer-offer claude # score three landings
|
|
|
5870
5870
|
|
|
5871
5871
|
- **Positioning integrity is scored too, and it is the one copy rule that blocks on a single sentence.** `competitor-concession` fires when the page ranks somebody else above the client, or says the client does not lead at what the page sells ("su constructor es mejor que el nuestro", "we're not the best"). Every other prose rule waits for a cluster because one AI tell proves nothing; this one is the whole defect on its own — the page is paid traffic, and it is arguing the visitor should leave. Two shapes that read identically are exempt by design: a concession about **price**, in either direction ("we are not the cheapest / the most expensive, and here is why" is premium positioning), and a superlative flipped by a negation ("ningún equipo trabaja más rápido que el nuestro"), which is the strongest claim *for* the client. Its warn-tier sibling `competitor-named-in-comparison` fires when a name from `src/content/competitors/` appears in a comparative sentence outside a `<table>` — a comparison table is a section the landing skill teaches, but naming a rival anywhere else on paid traffic is the client's call, not the build's. Spanish, Portuguese and English.
|
|
5872
5872
|
|
|
5873
|
+
- **Comments are not markup, and no rule reads one.** Astro expression comments (`{/* … */}`) and HTML comments (`<!-- … -->`) are blanked before detection, offsets preserved so `file:line` stays exact. A shared scaffold component explaining its `preconnect` in prose that spelled `<img>` twice was read as two broken images — block-tier — so every landing rendering a video failed the publish gate on a file the client cannot edit. Comment prose is also where a component's reasoning lives, em-dashes and buzzwords included, so reading it inflated the count-threshold tells too.
|
|
5874
|
+
|
|
5873
5875
|
- **Copy held in component frontmatter is read like markup copy.** Astro landings keep FAQ pairs, testimonial quotes, feature cards and pricing rows as a `const items = [{ q, a }]` array above the `---` fence and render them in a `.map()`, so a critic that blanked the whole block was blind to a large share of every page's actual words. Prose string literals in that block now feed every copy rule; imports, class strings, URLs and config do not, and the bar is deliberately high in that direction — a Tailwind class list in front of the copy rules is worse than one missed tell.
|
|
5874
5876
|
|
|
5875
5877
|
Output is the standard envelope `{ ok, data, hints }` with `data = { advisory, slug, overall, counts, dimensions, findings }`. `dimensions` scores seven design families (typography, color, borders_depth, motion, spacing, copy, integrity) 0–1 (higher is better); `counts` is the block/warn/advisory tally.
|
package/dist/cli.js
CHANGED
|
@@ -48982,6 +48982,20 @@ function blankAstroFrontmatter(text2) {
|
|
|
48982
48982
|
}
|
|
48983
48983
|
return kept.join("") + text2.slice(cut);
|
|
48984
48984
|
}
|
|
48985
|
+
function blankUnrenderedSource(text2) {
|
|
48986
|
+
return blankTemplateComments(blankAstroFrontmatter(text2));
|
|
48987
|
+
}
|
|
48988
|
+
function blankTemplateComments(text2) {
|
|
48989
|
+
const out = text2.split("");
|
|
48990
|
+
const pattern = /\{\s*\/\*[\s\S]*?\*\/\s*\}|<!--[\s\S]*?-->/g;
|
|
48991
|
+
for (const m of text2.matchAll(pattern)) {
|
|
48992
|
+
const start = m.index ?? 0;
|
|
48993
|
+
for (let i = start; i < start + m[0].length && i < out.length; i++) {
|
|
48994
|
+
if (out[i] !== "\n") out[i] = " ";
|
|
48995
|
+
}
|
|
48996
|
+
}
|
|
48997
|
+
return out.join("");
|
|
48998
|
+
}
|
|
48985
48999
|
function frontmatterLength(text2) {
|
|
48986
49000
|
if (!text2.startsWith("---")) return 0;
|
|
48987
49001
|
const lines = text2.split("\n");
|
|
@@ -49355,7 +49369,7 @@ function distinctCompetitorNames(competitors) {
|
|
|
49355
49369
|
return [...byFold.values()];
|
|
49356
49370
|
}
|
|
49357
49371
|
function mentionsInSource(source, names) {
|
|
49358
|
-
const text2 =
|
|
49372
|
+
const text2 = blankUnrenderedSource(source.text);
|
|
49359
49373
|
const visible = blankHtmlKeepingOffsets(text2);
|
|
49360
49374
|
const tables = tableRanges(text2);
|
|
49361
49375
|
const out = [];
|
|
@@ -49395,7 +49409,7 @@ function escapeRegExp(value) {
|
|
|
49395
49409
|
}
|
|
49396
49410
|
function detectSource(source) {
|
|
49397
49411
|
const file = source.path;
|
|
49398
|
-
const text2 =
|
|
49412
|
+
const text2 = blankUnrenderedSource(source.text);
|
|
49399
49413
|
const findings = [];
|
|
49400
49414
|
const lines = text2.split("\n");
|
|
49401
49415
|
for (const matcher of LINE_MATCHERS) {
|
|
@@ -49413,7 +49427,7 @@ function detectSource(source) {
|
|
|
49413
49427
|
}
|
|
49414
49428
|
function detectPage(sources) {
|
|
49415
49429
|
if (sources.length === 0) return [];
|
|
49416
|
-
const combined = sources.map((s) =>
|
|
49430
|
+
const combined = sources.map((s) => blankUnrenderedSource(s.text)).join("\n");
|
|
49417
49431
|
const pageFile = sources.find((s) => s.path === "index.astro" || s.path.endsWith("/index.astro"))?.path ?? sources[0]?.path ?? "index.astro";
|
|
49418
49432
|
const findings = [];
|
|
49419
49433
|
for (const analyzer of ANALYZERS) {
|
|
@@ -49493,7 +49507,7 @@ function describeCounts(findings) {
|
|
|
49493
49507
|
// src/commands/landing/snapshot.ts
|
|
49494
49508
|
import { mkdir as mkdir9, rename as rename2, writeFile as writeFile13 } from "fs/promises";
|
|
49495
49509
|
import path31 from "path";
|
|
49496
|
-
var CRITIC_VERSION = "
|
|
49510
|
+
var CRITIC_VERSION = "4";
|
|
49497
49511
|
function critiqueCacheDir(projectRoot) {
|
|
49498
49512
|
return path31.join(projectRoot, ".cache", "landing-critique");
|
|
49499
49513
|
}
|