- Add strict Content Security Policy to protect against XSS attacks
- Implement custom app:// protocol for production builds with proper headers
- Enable secure cross-origin isolation for SharedArrayBuffer support
- Remove insecure --enable-features bypass flag
- Add proper COOP/COEP/CORP headers for all resources
- Allow Pyodide workers to function in production builds
This fixes critical security vulnerabilities while maintaining full
functionality including Pyodide web workers and SharedArrayBuffer.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The src/assets directory only contained a react.svg file that was not referenced anywhere in the codebase. This appears to be leftover boilerplate from the project initialization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The pyodideLoader was superseded by the worker-based pattern converter (client.ts and worker.ts) which runs Pyodide in a background thread. This legacy code is no longer referenced anywhere in the codebase.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Define semantic color theme in App.css using @theme directive
- Primary (blue), Success (green), Warning (amber), Danger (red)
- Info (cyan), Accent (purple), Secondary (orange), Tertiary (teal)
- Semantic colors reference Tailwind color variables via var()
- Media query-based dark mode for canvas colors
- Migrate all 16 components from direct Tailwind colors to semantic names
- Create cssVariables.ts utility for Konva canvas color access
- Update KonvaComponents to use CSS variables dynamically
- Replace @apply with CSS variables in index.css for v4 compatibility
- Remove unused designTokens.ts file
- Improve light mode contrast with gray-300 app background
- Adjust canvas and info box backgrounds to gray-200
Benefits:
- Easy theme customization by updating App.css @theme block
- Consistent semantic naming across all components
- Proper dark mode support via media queries
- No visual regressions, all colors maintained
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Auto-formatted by linter:
- Single quotes → double quotes
- Line wrapping for better readability
No logic changes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This hook was replaced by useMachineStore (Zustand) and is no longer
used anywhere in the codebase. All functionality has been migrated to
the centralized machine store.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented proper time calculation matching the Brother app algorithm:
- 150ms per stitch + 3000ms startup time per color block
- Calculate total and elapsed time by summing across color blocks
- This fixes the "999 seconds" issue by calculating time accurately
Created timeCalculation utility with:
- convertStitchesToMinutes: Convert stitches to minutes using PP1 formula
- calculatePatternTime: Calculate total/elapsed time per color blocks
Updated ProgressMonitor to show:
- Total Time (calculated from all color blocks)
- Elapsed Time / Total Time (based on current stitch position)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When the machine reports 0 total stitches in patternInfo, fall back to
using the PEN data stitch count (penStitches.stitches.length) for UI
display. This ensures progress percentage and stitch counts display
correctly even when the machine hasn't fully initialized pattern info.
Updated ProgressMonitor to use derived totalStitches value that prefers
patternInfo.totalStitches but falls back to PEN data when needed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed redundant patternUploaded state from PatternStore and replaced
it with a derived selector usePatternUploaded() in MachineStore that
computes it from patternInfo !== null.
This eliminates duplicate state, removes the need for synchronization
logic, and ensures a single source of truth for pattern upload status.
Updated all components (App, LeftSidebar, FileUpload, PatternCanvas,
WorkflowStepper) to use the derived selector.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extracted App.tsx (469 lines → 91 lines) into 5 new components:
- ErrorPopover: Displays error details with solutions (84 lines)
- AppHeader: Machine status, workflow stepper, errors (207 lines)
- ConnectionPrompt: Connect button or browser warning (67 lines)
- LeftSidebar: Conditional rendering of controls (42 lines)
- PatternPreviewPlaceholder: Empty state for preview (46 lines)
This improves code organization, maintainability, and reusability.
Each component now has a single, clear responsibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Created shared PatternInfo component for displaying pattern statistics
(size, stitch count, colors) used in both FileUpload and PatternSummaryCard.
Reduces code duplication and ensures consistency across the UI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Shows actual machine stitch count (including lock stitches) in both
FileUpload and PatternSummaryCard components, with original PES count
in lighter gray when they differ.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Detects if the browser supports Web Bluetooth API and displays an
informative warning when unsupported. Provides users with clear
options: use a compatible browser or download the desktop app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Detects if the browser supports Web Bluetooth API and displays an
informative warning when unsupported. Provides users with clear
options: use a compatible browser or download the desktop app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds conditions to build and upload jobs to only run when triggered by pushes to the main branch, preventing unnecessary builds on pull requests.
Changes:
- Updated build-web job condition to include `github.ref == 'refs/heads/main'`
- Updated build-release job condition to include `github.ref == 'refs/heads/main'`
- Updated upload-to-release job condition to include `github.ref == 'refs/heads/main'`
This ensures:
- Pull requests only update the draft release notes (via release-drafter)
- Actual builds and artifact uploads only happen on main branch pushes
- More efficient CI/CD pipeline with reduced unnecessary builds
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Renames the workflow file to better reflect its purpose of creating and maintaining draft releases.
Changes:
- Renamed .github/workflows/release.yml to .github/workflows/draft-release.yml
- Updated workflow name from "Release" to "Draft Release"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Moves web app build from publish-pages workflow to release workflow to ensure version consistency and better artifact management.
Changes:
- Added build-web job to release.yml that:
- Updates package.json with the release version
- Builds the web app with proper base path
- Creates a versioned zip artifact (respira-web-{version}.zip)
- Uploads as a release asset alongside desktop builds
- Updated publish-pages.yml to:
- Remove the build-web job (no longer needed)
- Download the pre-built web artifact from the release
- Extract and deploy the versioned build
Benefits:
- All artifacts (desktop + web) built together with same version
- Web app now includes correct version number in package.json
- Simpler and faster publish-pages workflow (no rebuild needed)
- Better caching and consistency across deployments
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The application now properly detects when a Brother PP1 machine is not paired with the operating system. Previously, the connection would appear successful but commands would fail silently.
Changes:
- Enhanced sendCommand() to check for empty or invalid responses during initial connection
- Updated connect() to validate the connection with a test command (getMachineState)
- Properly disconnect and clean up when pairing is not established
- Throw BluetoothPairingError with helpful instructions for the user
When the machine is not paired, users now see a clear error message instructing them to:
1. Long-press the Bluetooth button on the machine
2. Pair via the operating system's Bluetooth settings
3. Try connecting again
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The COLOR_END and CUT commands must be on the same stitch, not separate stitches.
This was causing the machine to execute an extra stitch with the new color before
the jump to the new position.
Changes:
- Combine COLOR_END (X flag) and CUT (Y flag) into single stitch at old position
- Machine now correctly pauses after cut, before jumping to new color section
- Update all color change tests to expect combined COLOR_END+CUT stitch
The correct sequence is now:
1. Finishing lock stitches (old color)
2. COLOR_END+CUT stitch (old color) ← Machine pauses here
3. Jump to new position (new color)
4. Starting lock stitches (new color)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The encoder now adds 8 lock stitches at the very beginning of every pattern,
matching the behavior of the original C# PesxToPen.cs code (Nuihajime_TomeDataPlus
is called when counter <= 2).
Key changes:
- Find first non-MOVE stitch for lock stitch placement
- Add 8 starting lock stitches before main encoding loop
- Calculate forward-looking direction for optimal knot hiding
- Update all 30 tests to account for starting lock stitches
Also added tests to verify:
- DATA_END flag is automatically added to last stitch
- Starting lock stitches are correctly placed at pattern start
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added tests to verify the encoder correctly handles pattern termination:
- Test that DATA_END flag is added to last stitch even without END flag
- Test that DATA_END flag is added when input has explicit END flag
This ensures patterns are always properly terminated in PEN format,
regardless of whether the input stitches have an END marker.
All 29 tests passing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Renamed and restructured PEN parsing to match encoder pattern:
Changes:
- Renamed pen/parser.ts → pen/decoder.ts (consistent with encoder.ts)
- Created pen/types.ts for PEN-specific type definitions
- Moved types out of machine.ts (they're format-specific, not machine-specific)
- Unified decoder with encoder test helpers (encoder.test.ts now uses decoder)
New structure:
- decodePenStitch() - decode single 4-byte stitch
- decodeAllPenStitches() - decode all stitches from bytes
- decodePenData() - full decode with color blocks and bounds
- getStitchColor() - helper to get color for a stitch index
Type definitions:
- DecodedPenStitch - individual stitch with coordinates and flags
- PenColorBlock - color block (stitch range for one thread)
- DecodedPenData - complete decoded pattern data
Backward compatibility:
- Added compatibility aliases (isJump, flags, startStitch, endStitch)
- Maintains API compatibility with existing UI code
Also added dist-electron to eslint ignore list.
All tests passing (27/27), build successful, lint clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Moved embroidery format-related code from utils to new formats folder:
Structure:
- src/formats/pen/ - PEN format encoding and parsing
- encoder.ts (was utils/penEncoder.ts)
- encoder.test.ts (was utils/penEncoder.test.ts)
- parser.ts (was utils/penParser.ts)
- PEN constants moved inline to encoder.ts
- src/formats/import/ - Pattern import/conversion (currently PES)
- worker.ts (was workers/patternConverter.worker.ts)
- client.ts (was utils/patternConverterClient.ts)
- pesImporter.ts (was utils/pystitchConverter.ts)
- pyodideLoader.ts (was utils/pyodideLoader.ts)
- constants.ts (PyStitch/pyembroidery constants)
Benefits:
- Better separation of concerns
- PEN encoder is co-located with PEN parser
- Import logic is in one place and extensible for other formats
- Removed utils/embroideryConstants.ts - split into appropriate locations
- Updated all 18 import references across the codebase
All tests passing, build successful.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added npm run test:run to GitHub Actions build workflow
- Updated workflow name to reflect testing is included
- Tests now run between lint and build steps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhanced penEncoder test suite with byte-level sequence verification:
- Added helper functions to decode PEN bytes for detailed assertions
- Replaced length-only tests with precise operation order verification
- Added tests for color change sequences (same position and with jump)
- Added test for color change followed by explicit JUMP command
- Added test for long jump sequences with lock stitches
- Verified exact placement of lock stitches, cuts, jumps, and color markers
All 27 tests passing with comprehensive coverage of PEN format encoding.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract PEN encoding logic into separate testable module (penEncoder.ts)
- Implement 24 comprehensive tests covering:
- Position encoding and coordinate shifting
- Lock stitch direction calculation (forward/backward)
- Lock stitch generation with rotation
- Full PEN encoding with color changes, jumps, and bounds
- Edge cases (empty arrays, single stitches, TRIM flags)
- Setup vitest for testing
- Refactor pattern converter worker to use extracted penEncoder module
- Fix bounds calculation to include non-MOVE stitches (not just STITCH)
- Remove duplicate function definitions from worker
- Add test scripts: npm run test, npm run test:ui, npm run test:run
All tests passing (24/24) and build successful.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>