Files
photo-renamer/CLAUDE.md
T

3.7 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

npm start          # Run the Electron app in development
npm run build      # Build macOS app bundle (no DMG, arm64 + x64)
npm run dist       # Build and package as DMG for distribution
./setup.sh         # First-time setup: npm install + npm start

There are no tests or linting configured.

Architecture

This is a macOS Electron desktop app for batch-renaming photo files. It follows strict Electron security practices: contextIsolation: true, nodeIntegration: false.

Process boundary: All filesystem access lives exclusively in src/main/ (main process). The renderer never touches fs directly.

File structure

src/
├── main/
│   ├── index.js          # Main process entry point; creates BrowserWindow, calls registerAll()
│   └── ipc/
│       ├── index.js      # registerAll(mainWindow) — delegates to folder and files modules
│       ├── folder.js     # select-folder, reveal-folder
│       └── files.js      # list-images, read-image, rename-files
├── preload/
│   └── index.js          # Bridges IPC to window.api via contextBridge (isolated context)
└── renderer/
    ├── index.html        # App shell (dark theme, CSS variables in :root)
    ├── style.css         # All CSS
    ├── renderer.js       # Main renderer logic; imports state and handlers
    ├── state.js          # Shared mutable state: files[], currentFolder, selectedIdxs, sortMode
    └── handlers/
        ├── drag-drop.js  # Card drag-and-drop reorder (single and multi-card)
        ├── selection.js  # Rubber-band selection, Shift-click, Cmd+click
        ├── pinch-zoom.js # Trackpad pinch to resize thumbnails (CSS --thumb-size, 150400px)
        └── hover-preview.js # Hover preview overlay

IPC surface

Defined in src/main/ipc/, bridged via src/preload/index.js as window.api:

Channel Direction Description
select-folder invoke Opens native folder picker, returns path or null
list-images invoke Reads directory, returns {name, path, mtime, size}[] filtered to image extensions, sorted by filename
read-image invoke Reads file, returns base64 data URL for display
rename-files({folderPath, files, prefix, digits}) invoke Two-phase rename: temp names first, then final names to avoid collisions
reveal-folder invoke Opens folder in Finder via shell.openPath
fullscreen-change push (main→renderer) Sent on enter-full-screen / leave-full-screen window events

Renderer (src/renderer/)

Uses ES module imports (type="module"). No framework.

State (src/renderer/state.js):

  • files[] — ordered array of file objects; order determines rename sequence
  • selectedIdxsSet<number> of selected card indices
  • currentFolder — active directory path
  • sortMode'name' | 'date' | null

Thumbnail loading: Uses IntersectionObserver with rootMargin: '400px 0px' — images load lazily as cards enter the viewport. DOM card elements are created immediately without src; the observer fills in img.src on entry. Drag-and-drop reorder remaps existing card elements via card.dataset.filepath to avoid re-fetching images.

Styling: All CSS lives in src/renderer/index.html. Dark theme with CSS variables defined in :root. The macOS traffic-light buttons sit in #titlebar with -webkit-app-region: drag.

Build output: electron-builder targets DMG for arm64 and x64. The app icon must be at assets/icon.icns.