CLAUDE.md - Project Notes
February 11, 2026 · View on GitHub
Important Guidelines
- NEVER commit changes unless the user explicitly requests it - Always wait for user confirmation before creating commits
Project Structure
- Monorepo with packages in
packages/directory - Main package:
packages/xcfreader- GIMP XCF file parser - Uses TypeScript with ESLint for linting
Lint Configuration
- Root
.eslintrc.jsondefines comprehensive ESLint rules with@typescript-eslint - Package-level config was duplicating plugin definitions causing conflicts
Issues Found & Fixed
-
ESLint plugin conflict - Both root and
packages/xcfreader/.eslintrc.jsonwere defining the@typescript-eslintplugin, causing ESLint to fail. Fixed by addingroot: trueto the package config. -
console.log in test file -
src/tests/13-create-image-from-layers.tsusedconsole.loginstead of the project'sLogger.log. Fixed by importingLoggerfrom../lib/logger.jsand usingLogger.log. -
Incorrect relative paths in tests - Tests 13-17 used raw relative paths (
"../../../../example-xcf/...") instead ofpath.resolve(__dirname, ...). This caused tests to fail because paths were resolved from the wrong directory. Fixed by:- Adding
pathandfileURLToPathimports - Creating
__dirnamefromimport.meta.url(ES modules) - Using
path.resolve(__dirname, "../../../../example-xcf/...")for all file paths
- Adding
-
Path depth error - All test files had
../../../../../example-xcf(5 levels up) but should be../../../../example-xcf(4 levels up) fromdist/tests/to repo root.
Code Conventions
-
Use
Logger.log()instead ofconsole.log()for test output -
Tests throw on failure, log "PASS:" messages on success
-
Test runner in
src/tests/runner.tsexecutes all test functions -
Test files should use
path.resolve(__dirname, ...)for file paths in ES modules:import path from "path"; import { fileURLToPath } from "url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const xcfPath = path.resolve(__dirname, "../../../../example-xcf/file.xcf");
-
ui-xcfimage serve from monorepo root -
servewas running frompackages/ui-xcfimage/so/example-xcf/404'd. Fixed by:- Playwright config:
cwdpoints to monorepo root (path.resolve(__dirname, '../..')) demo.html: script paths use absolute root paths (/packages/ui-xcfimage/dist/...)- Test: navigates to
/packages/ui-xcfimage/demo.html package.jsonserve script:npx serve -l 3000 ../..- Also fixed Windows
cwdpath bug (fileURLToPathinstead ofURL.pathname) and port conflicts (explicit port 3333,reuseExistingServer: false)
- Playwright config:
-
DataView allocation performance issue - Creating new DataView objects for every channel read caused 4x rendering slowdown. Fixed by:
-
Changed
readChannelValue()to accept a reusable DataView parameter -
Create single DataView per tile buffer at start of
copyTile()method -
Pass the DataView to all
readChannelValue()calls within the tile processing loop -
IMPORTANT: Never create DataView objects inside tight loops - always create once and reuse
-
Result: fullColour.xcf rendering improved from 906ms to 305ms (66% faster)
-
Pattern to follow:
// ✅ Good: Create DataView once per buffer const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); for (let i = 0; i < iterations; i++) { const value = view.getUint16(offset + i * 2, false); } // ❌ Bad: Creates millions of DataView objects for (let i = 0; i < iterations; i++) { const view = new DataView(buffer.buffer, buffer.byteOffset + offset + i * 2, 2); const value = view.getUint16(0, false); }
-
Packages
packages/xcfreader- Core XCF parser (Node + browser)packages/ui-xcfimage- Web component<gpp-xcfimage>using Playwright for testspackages/ha-xcfimage-card- Home Assistant custom card with entity-based layer control
Commands
packages/xcfreader
npm run lint- Run linternpm run lint:fix- Run linter with auto-fixnpm run test- Build and run testsnpm run build- Compile TypeScript
packages/ui-xcfimage
npm run build- Build web component (tsc + esbuild)npm run test- Run Playwright browser testsnpm run serve- Serve demo locally
packages/ha-xcfimage-card
npm run build- Build Home Assistant card (tsc + esbuild)npm run dev- Watch mode for developmentnpm run serve- Serve dist folder with CORSnpm run lint- Run linternpm run lint:fix- Run linter with auto-fix