From a97c2a403472ea0c25ef31bb694b1c3c05fc9a17 Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 23:53:14 +0000 Subject: [PATCH] fix(rules): stop rendering the skills paragraph's markup as text `skillsText` is written into the page with `set:html`, because its copy carries a `.agents/skills/`. It was missing from the island's HTML_KEYS list, so the language pass rewrote the node with `textContent` on load -- and every visitor to /rules/ read a literal `` tag in the middle of the sentence. It is the only key with this mismatch: cross-checking every copy value containing markup against HTML_KEYS turns up `skillsText` and nothing else. Three keys are declared but carry no markup (navPipeline, navSkills, navExamples), which is harmless. Also teaches rendered-text-diff.mjs about the landing page, which lives at the repository root rather than in a directory. It was requesting /index/index.html and diffing against a 404, which reported a clean four spans. With the path fixed the landing page really is clean, 36 of 36. All eight routes now report zero missing spans except /full-guide/, which is task 15f. Co-Authored-By: Claude Opus 5 --- .agents/scripts/rendered-text-diff.mjs | 10 +++++++--- src/components/islands/RulesInteractive.astro | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.agents/scripts/rendered-text-diff.mjs b/.agents/scripts/rendered-text-diff.mjs index 1d5a88e..be48504 100644 --- a/.agents/scripts/rendered-text-diff.mjs +++ b/.agents/scripts/rendered-text-diff.mjs @@ -22,11 +22,15 @@ import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { chromium } from 'playwright'; +// `index` is the landing page: it lives at the repository root, not in a +// directory of its own, so it needs a different path on the legacy side. const route = process.argv[2]; if (!route) { - console.error('usage: rendered-text-diff.mjs e.g. full-guide'); + console.error('usage: rendered-text-diff.mjs e.g. full-guide, or index'); process.exit(2); } +const legacyPath = route === 'index' ? 'index.html' : `${route}/index.html`; +const astroPath = route === 'index' ? '' : `${route}/`; // The built site expects to be served under the configured base path. const staging = mkdtempSync(join(tmpdir(), 'af-rtd-')); @@ -75,8 +79,8 @@ try { return spans; }; - const legacy = await grab(`http://localhost:4197/${route}/index.html`); - const astro = await grab(`http://localhost:4196/ai-for-dummies/${route}/`); + const legacy = await grab(`http://localhost:4197/${legacyPath}`); + const astro = await grab(`http://localhost:4196/ai-for-dummies/${astroPath}`); await browser.close(); const rendered = new Set(astro); diff --git a/src/components/islands/RulesInteractive.astro b/src/components/islands/RulesInteractive.astro index 79c23c7..b3f09b3 100644 --- a/src/components/islands/RulesInteractive.astro +++ b/src/components/islands/RulesInteractive.astro @@ -403,8 +403,13 @@ fix(api): scope session query select('[data-skill]', id, 'skill'); } + // Keys whose copy carries markup, so the swap must write innerHTML. + // `skillsText` was missing while the markup renders it with `set:html`: + // the island rewrote it as text on load and every visitor saw a literal + // `.agents/skills/` in the paragraph. const HTML_KEYS = { heroTitle: 1, + skillsText: 1, pipelineTitle: 1, skillsTitle: 1, ratchetTitle: 1,