Skip to content

refactor: restructure agents directory and unify comparison pipeline#193

Merged
let-sunny merged 5 commits intomainfrom
claude/refactor-agent-structure-ALY90
Mar 30, 2026
Merged

refactor: restructure agents directory and unify comparison pipeline#193
let-sunny merged 5 commits intomainfrom
claude/refactor-agent-structure-ALY90

Conversation

@let-sunny
Copy link
Copy Markdown
Owner

@let-sunny let-sunny commented Mar 30, 2026

Summary

#1911단계: 리팩토링 + 기반 작업. ablation을 calibration에 통합하기 전에, 공용 모듈을 추출하고 디렉토리 구조를 정리합니다.

2단계 작업은 #194 에서 진행 예정.

이 PR에서 한 것

1. src/core/design-tree/ 디렉토리 신설

이유: design-tree 관련 파일이 engine/ 안에 rule-engine, scoring, visual-compare 등과 섞여 있었음. 순수 데이터 변환 모듈로 분리.

2. src/experiments/ablation/ 으로 이동

  • src/agents/ablation/src/experiments/ablation/
  • 5개 파일 이동: helpers.ts, run-phase1.ts, run-condition.ts, run-responsive.ts, recompare.ts

이유: ablation 스크립트는 npx tsx로 직접 실행하는 독립 실험이지, calibration pipeline의 에이전트가 아님. agents/에 있으면 역할이 혼동됨.

3. 비교 파이프라인 통합

  • compareScreenshots()CompareOptions 추가:
    • sizeMismatch: "pad" | "crop" — 캘리브레이션은 pad(기존), 실험은 crop(기존)
    • threshold: number — pixelmatch threshold (기존 0.1 하드코딩 → 옵션화)
  • cropPng() 헬퍼 추가 (기존 padPng()과 대칭)
  • renderAndCompare()ablation/helpers.ts에서 core/engine/visual-compare.ts로 이동. 캘리브레이션 + 실험 공용.

이유: 같은 "렌더 → 비교" 작업인데 crop/pad 방식이 두 곳에 하드코딩. 옵션 기반으로 통합하면 어디서든 원하는 방식 선택 가능.

4. 공용 유틸 추출

  • core/engine/html-utils.ts 신규extractHtml, sanitizeHtml, injectLocalFont, processHtml
  • core/engine/fixture-helpers.ts 신규getDesignTreeOptions, getFixtureScreenshotPath, copyFixtureImages
  • experiments/ablation/helpers.ts — 위 공용 함수 제거, re-export만 유지. API 호출/실험 설정만 남음.

이유: HTML 처리와 fixture 관리는 실험 전용이 아닌 공통 기능. 다음 PR에서 calibration이 strip 실행할 때 바로 사용 가능.

이 PR에서 하지 않은 것 (다음 PR → #194)

  • calibration 파이프라인에 strip 실행 연결
  • conversion.json 포맷 변경 (stripDeltas 필드)
  • evaluation agent의 delta 기반 difficulty 사용
  • threshold 조정 (MIN_RATIO_SAMPLES 등)

디렉토리 구조 (변경 후)

src/
├── core/
│   ├── design-tree/          ← NEW (engine/에서 이동 + delta.ts 추가)
│   ├── engine/               ← visual-compare 통합 + html-utils, fixture-helpers 추가
│   ├── rules/
│   ├── contracts/
│   ├── adapters/
│   ├── report-html/
│   └── monitoring/
├── agents/                   ← calibration pipeline만 남음
├── experiments/              ← NEW (agents/ablation/에서 이동)
│   └── ablation/
├── cli/
└── mcp/

Test plan

  • pnpm build — 빌드 통과
  • pnpm test:run — 38 files, 654 tests 통과
  • pnpm lint — tsc --noEmit 통과
  • CodeRabbit review

https://claude.ai/code/session_015dAVYmRnXTxnYLwQcZDqPf

Summary by CodeRabbit

  • Documentation

    • Updated ablation experiment usage examples, CLI snippets, and calibration pipeline docs to reflect the new project layout and deterministic behavior.
  • New Features

    • Added HTML extraction/sanitization and local-font handling for rendered outputs.
    • Introduced a render-and-compare workflow and configurable comparison options (size-handling: pad|crop, adjustable threshold).
  • Refactor

    • Reorganized design-tree, comparison, and ablation utilities into dedicated modules for clearer structure.

claude added 2 commits March 30, 2026 04:25
…191)

- Move design-tree files to dedicated src/core/design-tree/ directory
- Move ablation experiments from src/agents/ablation/ to src/experiments/ablation/
- Unify compareScreenshots with sizeMismatch option ("pad" | "crop") and configurable threshold
- Extract renderAndCompare to core/engine/visual-compare.ts for shared use
- Add stripDeltaToDifficulty() for objective difficulty measurement foundation
- Update all imports and CLAUDE.md documentation

https://claude.ai/code/session_015dAVYmRnXTxnYLwQcZDqPf
- Move extractHtml, sanitizeHtml, injectLocalFont, processHtml to core/engine/html-utils.ts
- Move getDesignTreeOptions, getFixtureScreenshotPath, copyFixtureImages to core/engine/fixture-helpers.ts
- helpers.ts now re-exports from core (experiment scripts unchanged)
- Only API calls and experiment config remain in experiments/ablation/helpers.ts

https://claude.ai/code/session_015dAVYmRnXTxnYLwQcZDqPf
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

This PR restructures design-tree, comparison, and fixture utilities into new core modules, moves ablation experiment code from src/agents/ablation/ to src/experiments/ablation/, updates import paths across CLI/tools, and introduces delta→difficulty mapping plus HTML/comparison helpers and tests.

Changes

Cohort / File(s) Summary
Documentation
CLAUDE.md
Updated docs to reflect moved modules and new src/experiments/ablation/ CLI examples.
Design-tree Core
src/core/design-tree/delta.ts, src/core/design-tree/delta.test.ts, src/core/design-tree/index.ts, src/core/design-tree/strip.test.ts
Added stripDeltaToDifficulty() and tests; added index re-export; updated tests to new import paths.
Core Barrel Export
src/core/index.ts
Replaced engine-based design-tree exports with ./design-tree/index.js.
HTML Processing
src/core/comparison/html-utils.ts
New HTML extraction/sanitization/local-font injection and pipeline helpers for LLM responses.
Visual Comparison
src/core/comparison/visual-compare-helpers.ts, src/core/comparison/visual-compare.ts
Added CompareOptions (sizeMismatch/threshold), cropPng(), options-aware compareScreenshots(), and a new renderAndCompare() API supporting options.{suffix,sizeMismatch,threshold}.
Fixture Utilities
src/core/utils/fixture-helpers.ts
New helpers: getDesignTreeOptions(), getFixtureScreenshotPath(), copyFixtureImages().
Ablation Experiments
src/experiments/ablation/helpers.ts, src/experiments/ablation/*
Moved ablation helpers and scripts to src/experiments/ablation/; new Anthropic wrappers, fixture parsing, and re-exports; updated run scripts and renderAndCompare call sites to options object (including sizeMismatch: "crop").
Removed Agent Helpers
src/agents/ablation/helpers.ts
Deleted legacy 214-line ablation helpers module (functionality migrated to core/experiments modules).
Import Updates (CLI/Tools/Agents)
src/cli/commands/design-tree.ts, src/cli/commands/implement.ts, src/cli/commands/visual-compare.ts, src/agents/code-renderer.ts, src/mcp/server.ts
Updated dynamic import paths to new src/core/design-tree/ and src/core/comparison/ locations; no behavioral changes beyond import targets.
Ablation render/compare call-site edits
src/experiments/ablation/{recompare,run-phase1,run-condition,run-responsive}.ts
Changed renderAndCompare invocations from positional suffix string to options object { suffix, sizeMismatch: "crop" } and updated imports to core comparison helpers.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰
Hopping through imports I go,
Trees of design now in a row,
Helpers moved to tidy nests,
Delta maps decide the tests,
A little hop — experiments grow.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring work: restructuring the agents directory (moving ablation experiments to src/experiments/) and unifying the comparison pipeline with configurable options.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/refactor-agent-structure-ALY90

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLAUDE.md`:
- Around line 136-140: Add a blank line before the fenced code block that starts
with "```bash" under the heading "**`run-phase1.ts` — Strip experiments**" in
CLAUDE.md so the fenced block is surrounded by blank lines per MD031; locate the
block labeled with the bash fence and insert a single empty line immediately
above the "```bash" line.

In `@src/core/design-tree/delta.test.ts`:
- Around line 4-7: Add a unit test for negative delta values for
stripDeltaToDifficulty to document expected behavior when stripped similarity
exceeds baseline; specifically add an assertion like
expect(stripDeltaToDifficulty(-2)).toBe("easy") (or the appropriate difficulty
your implementation should return) alongside the existing cases so negatives are
covered and the intended mapping for values < 0 is explicit.

In `@src/core/engine/fixture-helpers.ts`:
- Around line 39-40: The loop over readdirSync in fixture-helpers.ts currently
calls copyFileSync for every entry unconditionally; update the loop that
iterates readdirSync(fixtureImagesDir) to skip entries that are not regular
files by using fs.lstatSync or fs.statSync on join(fixtureImagesDir, f) and
checking isFile() (or otherwise filtering out directories/symlinks) before
calling copyFileSync to join(runImagesDir, f); keep references to readdirSync,
copyFileSync, join, fixtureImagesDir and runImagesDir so it's easy to locate and
ensure only files are copied.

In `@src/core/engine/html-utils.ts`:
- Line 45: Replace the manual file:// string interpolation when building fontCss
with a proper file URL: import pathToFileURL from 'node:url' (or use require)
and call pathToFileURL(fontPath).href to produce the URL; update the
construction of fontCss (the constant named fontCss that currently uses
`file://${fontPath}`) to use that href so special characters and Windows paths
are encoded correctly.
- Around line 31-35: The current regex-based sanitization that mutates the
result string (the series of result.replace(...) calls) is incomplete and allows
unquoted on* handlers and dangerous protocols in src/xlink:href to survive;
replace this fragile approach by parsing the HTML into a DOM (or using a vetted
library like DOMPurify) and then remove any attributes whose name starts with
"on" (case-insensitive), strip style attributes, and reject or rewrite attribute
values for href/src/xlink:href that use dangerous schemes (javascript:,
vbscript:, data:) after decoding entities and normalizing case; ensure you
update the code where result is produced (the replace(...) sanitization block)
to perform DOM-based sanitization or call the library sanitizer so no executable
vectors remain.

In `@src/experiments/ablation/helpers.ts`:
- Around line 73-97: requireApiKey currently returns
process.env["ANTHROPIC_API_KEY"] as-is allowing whitespace-only or padded keys;
update requireApiKey to read process.env["ANTHROPIC_API_KEY"], apply .trim() to
the value, then validate that the trimmed string is non-empty (log the same
error and process.exit(1) if empty) and return the trimmed key; reference the
requireApiKey function and process.env["ANTHROPIC_API_KEY"] when making the
change.
- Around line 57-59: In the catch block that currently does const status = (err
as { status?: number }).status and then checks (status === 429 || status ===
529) && attempt < MAX_RETRIES, first ensure err is non-null and an object before
reading .status (e.g. check err !== null && typeof err === "object" or use 'in'
to test for "status"), then safely extract status into a local variable
(fallback to undefined if guard fails) and use that guarded status in the
existing retry condition; update the catch around the MAX_RETRIES/attempt logic
(the same scope where MAX_RETRIES and attempt are used) so a null/undefined err
cannot cause a TypeError.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 357a7bd1-11b7-40e5-9a2e-b206d8f27fb9

📥 Commits

Reviewing files that changed from the base of the PR and between 81e1999 and 94ea84d.

📒 Files selected for processing (21)
  • CLAUDE.md
  • src/agents/ablation/helpers.ts
  • src/cli/commands/design-tree.ts
  • src/cli/commands/implement.ts
  • src/core/design-tree/delta.test.ts
  • src/core/design-tree/delta.ts
  • src/core/design-tree/design-tree.test.ts
  • src/core/design-tree/design-tree.ts
  • src/core/design-tree/index.ts
  • src/core/design-tree/strip.test.ts
  • src/core/design-tree/strip.ts
  • src/core/engine/fixture-helpers.ts
  • src/core/engine/html-utils.ts
  • src/core/engine/visual-compare-helpers.ts
  • src/core/engine/visual-compare.ts
  • src/core/index.ts
  • src/experiments/ablation/helpers.ts
  • src/experiments/ablation/recompare.ts
  • src/experiments/ablation/run-condition.ts
  • src/experiments/ablation/run-phase1.ts
  • src/experiments/ablation/run-responsive.ts
💤 Files with no reviewable changes (1)
  • src/agents/ablation/helpers.ts

Comment on lines +39 to +40
for (const f of readdirSync(fixtureImagesDir)) {
copyFileSync(join(fixtureImagesDir, f), join(runImagesDir, f));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard against directories before copying image entries.

Line 39 iterates all entries, and Line 40 blindly calls copyFileSync; this throws if any entry is a subdirectory/symlink, causing avoidable run failures.

Suggested fix
-import { existsSync, mkdirSync, copyFileSync, readdirSync } from "node:fs";
+import { existsSync, mkdirSync, copyFileSync, readdirSync } from "node:fs";
@@
-    for (const f of readdirSync(fixtureImagesDir)) {
-      copyFileSync(join(fixtureImagesDir, f), join(runImagesDir, f));
+    for (const entry of readdirSync(fixtureImagesDir, { withFileTypes: true })) {
+      if (!entry.isFile()) continue;
+      copyFileSync(join(fixtureImagesDir, entry.name), join(runImagesDir, entry.name));
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/engine/fixture-helpers.ts` around lines 39 - 40, The loop over
readdirSync in fixture-helpers.ts currently calls copyFileSync for every entry
unconditionally; update the loop that iterates readdirSync(fixtureImagesDir) to
skip entries that are not regular files by using fs.lstatSync or fs.statSync on
join(fixtureImagesDir, f) and checking isFile() (or otherwise filtering out
directories/symlinks) before calling copyFileSync to join(runImagesDir, f); keep
references to readdirSync, copyFileSync, join, fixtureImagesDir and runImagesDir
so it's easy to locate and ensure only files are copied.

Comment on lines +31 to +35
result = result.replace(/<script[\s\S]*?<\/script>/gi, "");
result = result.replace(/\s+on\w+\s*=\s*"[^"]*"/gi, "");
result = result.replace(/\s+on\w+\s*=\s*'[^']*'/gi, "");
result = result.replace(/href\s*=\s*"javascript:[^"]*"/gi, 'href="#"');
result = result.replace(/href\s*=\s*'javascript:[^']*'/gi, "href='#'");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Sanitization is bypassable and leaves executable HTML vectors.

Lines 31-35 remove only a subset of dangerous patterns; unquoted on*= handlers and javascript: in src/xlink:href can survive and execute when rendered.

Suggested hardening
 export function sanitizeHtml(html: string): string {
   let result = html;
   result = result.replace(/^\/\/\s*filename:.*\n/i, "");
   result = result.replace(/<script[\s\S]*?<\/script>/gi, "");
-  result = result.replace(/\s+on\w+\s*=\s*"[^"]*"/gi, "");
-  result = result.replace(/\s+on\w+\s*=\s*'[^']*'/gi, "");
-  result = result.replace(/href\s*=\s*"javascript:[^"]*"/gi, 'href="#"');
-  result = result.replace(/href\s*=\s*'javascript:[^']*'/gi, "href='#'");
+  result = result.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, "");
+  result = result.replace(
+    /\s+(?:href|src|xlink:href)\s*=\s*(?:"\s*javascript:[^"]*"|'\s*javascript:[^']*'|javascript:[^\s>]+)/gi,
+    ' href="#"'
+  );
   return result;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/engine/html-utils.ts` around lines 31 - 35, The current regex-based
sanitization that mutates the result string (the series of result.replace(...)
calls) is incomplete and allows unquoted on* handlers and dangerous protocols in
src/xlink:href to survive; replace this fragile approach by parsing the HTML
into a DOM (or using a vetted library like DOMPurify) and then remove any
attributes whose name starts with "on" (case-insensitive), strip style
attributes, and reject or rewrite attribute values for href/src/xlink:href that
use dangerous schemes (javascript:, vbscript:, data:) after decoding entities
and normalizing case; ensure you update the code where result is produced (the
replace(...) sanitization block) to perform DOM-based sanitization or call the
library sanitizer so no executable vectors remain.

export function injectLocalFont(html: string): string {
const fontPath = resolve("assets/fonts/Inter.var.woff2");
if (!existsSync(fontPath)) return html;
const fontCss = `@font-face { font-family: "Inter"; src: url("file://${fontPath}") format("woff2"); font-weight: 100 900; }`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current implementation uses manual file:// interpolation and not pathToFileURL
rg -n 'file://\$\{fontPath\}|pathToFileURL' src/core/engine/html-utils.ts -C2

Repository: let-sunny/canicode

Length of output: 402


🏁 Script executed:

#!/bin/bash
# Check the full context of the function and existing imports
head -60 src/core/engine/html-utils.ts | cat -n

Repository: let-sunny/canicode

Length of output: 3072


🏁 Script executed:

#!/bin/bash
# Check if pathToFileURL is already imported anywhere in the file
rg -n 'import.*pathToFileURL|from.*node:url' src/core/engine/html-utils.ts

Repository: let-sunny/canicode

Length of output: 44


🏁 Script executed:

#!/bin/bash
# Verify pathToFileURL is the correct API from node:url
node -e "const { pathToFileURL } = require('url'); console.log(typeof pathToFileURL); const testPath = '/path/with spaces/file.txt'; console.log(pathToFileURL(testPath).href);"

Repository: let-sunny/canicode

Length of output: 106


Use pathToFileURL instead of manual file:// concatenation.

Line 45 builds a file URL via string interpolation, which doesn't properly encode special characters (spaces, etc.) or handle Windows path separators. Use pathToFileURL(fontPath).href from the node:url module to generate correct file URLs.

Suggested fix
+import { pathToFileURL } from "node:url";
 import { existsSync } from "node:fs";
 import { resolve } from "node:path";
@@
-  const fontCss = `@font-face { font-family: "Inter"; src: url("file://${fontPath}") format("woff2"); font-weight: 100 900; }`;
+  const fontUrl = pathToFileURL(fontPath).href;
+  const fontCss = `@font-face { font-family: "Inter"; src: url("${fontUrl}") format("woff2"); font-weight: 100 900; }`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fontCss = `@font-face { font-family: "Inter"; src: url("file://${fontPath}") format("woff2"); font-weight: 100 900; }`;
import { pathToFileURL } from "node:url";
import { existsSync } from "node:fs";
import { resolve } from "node:path";
const fontUrl = pathToFileURL(fontPath).href;
const fontCss = `@font-face { font-family: "Inter"; src: url("${fontUrl}") format("woff2"); font-weight: 100 900; }`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/engine/html-utils.ts` at line 45, Replace the manual file:// string
interpolation when building fontCss with a proper file URL: import pathToFileURL
from 'node:url' (or use require) and call pathToFileURL(fontPath).href to
produce the URL; update the construction of fontCss (the constant named fontCss
that currently uses `file://${fontPath}`) to use that href so special characters
and Windows paths are encoded correctly.

claude added 2 commits March 30, 2026 06:27
…191)

- core/engine/ → analysis only (rule-engine, scoring, loader, config-store)
- core/comparison/ → visual-compare, visual-compare-helpers, html-utils
- core/utils/ → fixture-helpers
- Update all imports across codebase and CLAUDE.md

https://claude.ai/code/session_015dAVYmRnXTxnYLwQcZDqPf
- Add negative delta test case for stripDeltaToDifficulty
- Guard against directories in copyFixtureImages (withFileTypes)
- Use pathToFileURL for font URL construction
- Harden sanitizeHtml: cover unquoted on* handlers and src/xlink:href
- Guard err type before reading .status in callApi catch
- Trim whitespace from API key in requireApiKey
- Fix markdown blank line before fenced code block in CLAUDE.md

https://claude.ai/code/session_015dAVYmRnXTxnYLwQcZDqPf
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/core/comparison/html-utils.ts`:
- Around line 34-37: The current replace call in html-utils.ts uses a regex that
matches attributes but always substitutes ' href="#"', which wrongly changes
other attributes like src to href; update the regex to capture the attribute
name and use a backreference in the replacement so the same attribute is
preserved (e.g., change the pattern to capture the attribute name like
/(\b(?:href|src|xlink:href))\s*=\s*(?:"\s*javascript:[^"]*"|'\s*javascript:[^']*'|javascript:[^\s>]+)/gi
and change the replacement to '$1="#"'), keeping the rest of the surrounding
code in result.replace unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1f711d34-19ba-407a-9ea9-bb9d4a79d2aa

📥 Commits

Reviewing files that changed from the base of the PR and between 94ea84d and 068e06f.

📒 Files selected for processing (15)
  • CLAUDE.md
  • src/agents/code-renderer.ts
  • src/cli/commands/visual-compare.ts
  • src/core/comparison/html-utils.ts
  • src/core/comparison/visual-compare-helpers.ts
  • src/core/comparison/visual-compare.test.ts
  • src/core/comparison/visual-compare.ts
  • src/core/design-tree/delta.test.ts
  • src/core/utils/fixture-helpers.ts
  • src/experiments/ablation/helpers.ts
  • src/experiments/ablation/recompare.ts
  • src/experiments/ablation/run-condition.ts
  • src/experiments/ablation/run-phase1.ts
  • src/experiments/ablation/run-responsive.ts
  • src/mcp/server.ts

Use capture group to keep original attribute (src, href, xlink:href)
instead of always replacing with href="#".

https://claude.ai/code/session_015dAVYmRnXTxnYLwQcZDqPf
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/core/comparison/html-utils.ts`:
- Around line 44-46: The path resolution in injectLocalFont() uses
resolve("assets/fonts/Inter.var.woff2") which is cwd-dependent; change it to
compute a module-relative path using import.meta.url (e.g., new
URL('../../assets/fonts/Inter.var.woff2', import.meta.url).pathname or similar)
so the file lookup is independent of the process CWD, then use existsSync on
that resolved path; update the fontPath assignment in injectLocalFont to use
this import.meta.url-based resolution so the function works when re-exported and
called from different contexts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 90e4c578-fb91-40ca-9e5a-e34bdf61d571

📥 Commits

Reviewing files that changed from the base of the PR and between 068e06f and beec438.

📒 Files selected for processing (1)
  • src/core/comparison/html-utils.ts

@let-sunny let-sunny merged commit e41eb29 into main Mar 30, 2026
3 checks passed
@let-sunny let-sunny deleted the claude/refactor-agent-structure-ALY90 branch March 30, 2026 06:43
let-sunny pushed a commit that referenced this pull request Mar 30, 2026
- Add Number.isFinite guard in stripDeltaToDifficulty to reject NaN/Infinity
- Fix MD031 markdown lint (blank line after fenced code block in CLAUDE.md)
- Note: html-utils.ts and fixture-helpers.ts fixes are on main (#193), not this branch

https://claude.ai/code/session_01L3j7oeNw6hKdvX4HJnrGwE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants