floatnote 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.beads/config.json +6 -0
  2. package/.beads/issues/floatnote-1.md +21 -0
  3. package/.beads/issues/floatnote-10.md +28 -0
  4. package/.beads/issues/floatnote-11.md +36 -0
  5. package/.beads/issues/floatnote-12.md +25 -0
  6. package/.beads/issues/floatnote-13.md +37 -0
  7. package/.beads/issues/floatnote-14.md +22 -0
  8. package/.beads/issues/floatnote-15.md +22 -0
  9. package/.beads/issues/floatnote-16.md +20 -0
  10. package/.beads/issues/floatnote-17.md +20 -0
  11. package/.beads/issues/floatnote-18.md +21 -0
  12. package/.beads/issues/floatnote-19.md +19 -0
  13. package/.beads/issues/floatnote-2.md +32 -0
  14. package/.beads/issues/floatnote-20.md +22 -0
  15. package/.beads/issues/floatnote-3.md +50 -0
  16. package/.beads/issues/floatnote-4.md +31 -0
  17. package/.beads/issues/floatnote-5.md +28 -0
  18. package/.beads/issues/floatnote-6.md +30 -0
  19. package/.beads/issues/floatnote-7.md +38 -0
  20. package/.beads/issues/floatnote-8.md +29 -0
  21. package/.beads/issues/floatnote-9.md +32 -0
  22. package/CLAUDE.md +61 -0
  23. package/README.md +95 -0
  24. package/bin/floatnote.js +218 -0
  25. package/coverage/base.css +224 -0
  26. package/coverage/bin/floatnote.js.html +739 -0
  27. package/coverage/bin/index.html +116 -0
  28. package/coverage/block-navigation.js +87 -0
  29. package/coverage/favicon.png +0 -0
  30. package/coverage/index.html +131 -0
  31. package/coverage/lcov-report/base.css +224 -0
  32. package/coverage/lcov-report/bin/floatnote.js.html +739 -0
  33. package/coverage/lcov-report/bin/index.html +116 -0
  34. package/coverage/lcov-report/block-navigation.js +87 -0
  35. package/coverage/lcov-report/favicon.png +0 -0
  36. package/coverage/lcov-report/index.html +131 -0
  37. package/coverage/lcov-report/prettify.css +1 -0
  38. package/coverage/lcov-report/prettify.js +2 -0
  39. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  40. package/coverage/lcov-report/sorter.js +210 -0
  41. package/coverage/lcov-report/src/index.html +146 -0
  42. package/coverage/lcov-report/src/main.js.html +1483 -0
  43. package/coverage/lcov-report/src/preload.js.html +361 -0
  44. package/coverage/lcov-report/src/renderer.js.html +8767 -0
  45. package/coverage/lcov.info +3273 -0
  46. package/coverage/prettify.css +1 -0
  47. package/coverage/prettify.js +2 -0
  48. package/coverage/sort-arrow-sprite.png +0 -0
  49. package/coverage/sorter.js +210 -0
  50. package/coverage/src/index.html +146 -0
  51. package/coverage/src/main.js.html +1483 -0
  52. package/coverage/src/preload.js.html +361 -0
  53. package/coverage/src/renderer.js.html +8767 -0
  54. package/jest.config.js +48 -0
  55. package/package.json +59 -0
  56. package/src/icon-template.png +0 -0
  57. package/src/index.html +296 -0
  58. package/src/main.js +494 -0
  59. package/src/preload.js +96 -0
  60. package/src/renderer.js +3203 -0
  61. package/src/styles.css +1448 -0
  62. package/tests/cli/floatnote.test.js +167 -0
  63. package/tests/main/main.test.js +287 -0
  64. package/tests/mocks/electron.js +126 -0
  65. package/tests/mocks/fs.js +17 -0
  66. package/tests/preload/preload.test.js +218 -0
  67. package/tests/renderer/history.test.js +234 -0
  68. package/tests/renderer/notes.test.js +262 -0
  69. package/tests/renderer/settings.test.js +178 -0
@@ -0,0 +1,6 @@
1
+ {
2
+ "prefix": "floatnote",
3
+ "nextId": 21,
4
+ "created": "2026-01-15T09:12:00.000Z",
5
+ "version": "1.0.0"
6
+ }
@@ -0,0 +1,21 @@
1
+ # floatnote-1: Set up testing infrastructure
2
+
3
+ **Status:** closed
4
+ **Priority:** high
5
+ **Labels:** infrastructure, testing
6
+
7
+ ## Description
8
+ Set up Jest and Electron testing infrastructure for the Floatnote project.
9
+
10
+ ## Tasks
11
+ - [ ] Install Jest and testing dependencies
12
+ - [ ] Configure Jest for Electron (main + renderer)
13
+ - [ ] Set up test directory structure
14
+ - [ ] Add test scripts to package.json
15
+ - [ ] Configure code coverage reporting
16
+ - [ ] Set up mock for Electron APIs
17
+
18
+ ## Acceptance Criteria
19
+ - `npm test` runs all tests
20
+ - `npm run test:coverage` shows coverage report
21
+ - Tests can run in CI environment
@@ -0,0 +1,28 @@
1
+ # floatnote-10: Test renderer - Clipboard and paste
2
+
3
+ **Status:** open
4
+ **Priority:** medium
5
+ **Labels:** testing, renderer, clipboard
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for clipboard and paste functionality.
10
+
11
+ ## Functions to Test
12
+ - `setupClipboardPaste()` - Paste event handler
13
+ - `paste()` - Handle paste action
14
+ - `pasteImage()` - Paste image from clipboard
15
+ - `pasteText()` - Paste text from clipboard
16
+ - `setupImageResize()` - Image resize handles
17
+
18
+ ## Test Cases
19
+ - [ ] Cmd+V triggers paste
20
+ - [ ] Paste detects image content
21
+ - [ ] Paste detects text content
22
+ - [ ] Pasted image creates DOM element
23
+ - [ ] Pasted image positioned correctly
24
+ - [ ] Pasted image can be dragged
25
+ - [ ] Pasted image can be resized
26
+ - [ ] Pasted text creates text item
27
+ - [ ] Images saved to images array
28
+ - [ ] Restored images match saved data
@@ -0,0 +1,36 @@
1
+ # floatnote-11: Test renderer - Settings and persistence
2
+
3
+ **Status:** open
4
+ **Priority:** medium
5
+ **Labels:** testing, renderer, settings
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for settings panel and data persistence.
10
+
11
+ ## Functions to Test
12
+ - `setupSettings()` - Settings panel setup
13
+ - `toggleSettings()` - Show/hide panel
14
+ - `hideSettings()` / `showSettings()`
15
+ - `saveData()` - Persist all data
16
+ - `loadSavedData()` - Restore saved data
17
+ - `autoSave()` - Debounced save
18
+
19
+ ## Test Cases
20
+ ### Settings Panel
21
+ - [ ] Cmd+, opens settings
22
+ - [ ] Close button hides settings
23
+ - [ ] Escape key hides settings
24
+ - [ ] Click outside hides settings
25
+ - [ ] Toggle changes update settings object
26
+ - [ ] Background mode changes apply
27
+
28
+ ### Persistence
29
+ - [ ] saveData includes all notes
30
+ - [ ] saveData includes settings
31
+ - [ ] saveData includes transform
32
+ - [ ] loadSavedData restores notes
33
+ - [ ] loadSavedData restores settings
34
+ - [ ] loadSavedData handles legacy format
35
+ - [ ] Clean slate setting creates new note
36
+ - [ ] autoSave debounces multiple calls
@@ -0,0 +1,25 @@
1
+ # floatnote-12: Test renderer - Context menu
2
+
3
+ **Status:** open
4
+ **Priority:** low
5
+ **Labels:** testing, renderer, ui
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for right-click context menus.
10
+
11
+ ## Functions to Test
12
+ - `setupContextMenu()` - Context menu setup
13
+ - `showContextMenu()` - Display menu at position
14
+ - `hideContextMenu()` - Hide menu
15
+
16
+ ## Test Cases
17
+ - [ ] Right-click on canvas shows general menu
18
+ - [ ] Right-click on object shows object menu
19
+ - [ ] General menu has zoom options
20
+ - [ ] General menu has settings option
21
+ - [ ] Object menu has copy option
22
+ - [ ] Object menu has delete option
23
+ - [ ] Menu positioned at click location
24
+ - [ ] Click elsewhere hides menu
25
+ - [ ] Menu actions trigger correct functions
@@ -0,0 +1,37 @@
1
+ # floatnote-13: Test preload.js IPC bridge
2
+
3
+ **Status:** open
4
+ **Priority:** medium
5
+ **Labels:** testing, preload, ipc
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for the preload script IPC bridge.
10
+
11
+ ## Functions to Test
12
+ - `onFocusChange()` - Focus event listener
13
+ - `closeWindow()` - Close IPC
14
+ - `hideWindow()` - Hide IPC
15
+ - `setPinned()` - Pin state IPC
16
+ - `setWindowSize()` - Size IPC
17
+ - `setBackgroundMode()` - Background IPC
18
+ - `getClipboardContent()` - Read clipboard
19
+ - `readClipboardImage()` - Read image
20
+ - `readClipboardText()` - Read text
21
+ - `saveData()` - Save IPC
22
+ - `loadData()` - Load IPC
23
+ - `resizeWindowLeft()` - Resize IPC
24
+
25
+ ## Test Cases
26
+ - [ ] onFocusChange registers callback
27
+ - [ ] closeWindow sends correct IPC
28
+ - [ ] hideWindow sends correct IPC
29
+ - [ ] setPinned sends boolean value
30
+ - [ ] setWindowSize sends size string
31
+ - [ ] setBackgroundMode sends mode string
32
+ - [ ] getClipboardContent returns image data
33
+ - [ ] getClipboardContent returns text data
34
+ - [ ] getClipboardContent returns null if empty
35
+ - [ ] saveData invokes IPC handler
36
+ - [ ] loadData invokes IPC handler
37
+ - [ ] resizeWindowLeft sends delta value
@@ -0,0 +1,22 @@
1
+ # floatnote-14: Multi-select with drag box
2
+
3
+ **Status:** closed
4
+ **Priority:** high
5
+ **Labels:** feature, selection
6
+
7
+ ## Description
8
+ Allow users to click-hold-drag with the select tool to draw a selection rectangle and select all objects within it.
9
+
10
+ ## Requirements
11
+ - In select mode, click and drag creates a selection rectangle
12
+ - All objects (drawings, text, images) within the rectangle are selected
13
+ - Visual feedback showing the selection rectangle while dragging
14
+ - Selected objects highlighted with selection indicator
15
+ - Works with existing selection (shift to add to selection?)
16
+
17
+ ## Implementation
18
+ - Add `selectionRect` state for drag selection
19
+ - Track mousedown position as start point
20
+ - Draw selection rectangle overlay during drag
21
+ - On mouseup, find all objects intersecting rectangle
22
+ - Add to `selectedObjects` array
@@ -0,0 +1,22 @@
1
+ # floatnote-15: Note pagination UI island
2
+
3
+ **Status:** closed
4
+ **Priority:** high
5
+ **Labels:** feature, ui
6
+
7
+ ## Description
8
+ Add a visible pagination control island showing prev/next buttons and current page number. Pinned to the right side, follows same visibility rules as toolbar.
9
+
10
+ ## Requirements
11
+ - Island pinned to right side of screen
12
+ - Shows: [<] [1/5] [>] style controls
13
+ - Same show/hide rules as toolbar (visible on hover/focus)
14
+ - Click < for previous note
15
+ - Click > for next note
16
+ - Page number shows current/total
17
+
18
+ ## Implementation
19
+ - Add `#pagination-island` element to HTML
20
+ - Style similar to other control islands
21
+ - Wire up to previousNote/nextNote functions
22
+ - Update display when notes change
@@ -0,0 +1,20 @@
1
+ # floatnote-16: Inactive background options
2
+
3
+ **Status:** closed
4
+ **Priority:** medium
5
+ **Labels:** feature, appearance
6
+
7
+ ## Description
8
+ Allow choosing a background style for when the window is not focused (inactive). Same options as active: transparent, blur, dark.
9
+
10
+ ## Requirements
11
+ - Settings panel has "Active background" and "Inactive background" sections
12
+ - Same three options: Clear, Blur, Dark
13
+ - Window switches between backgrounds on focus/blur events
14
+ - Persisted in settings
15
+
16
+ ## Implementation
17
+ - Add `inactiveBgMode` to settings
18
+ - Add UI controls in settings panel
19
+ - Update focus/blur handlers to switch background
20
+ - Call setBackgroundMode with appropriate mode
@@ -0,0 +1,20 @@
1
+ # floatnote-17: Background opacity controls
2
+
3
+ **Status:** closed
4
+ **Priority:** medium
5
+ **Labels:** feature, appearance
6
+
7
+ ## Description
8
+ Allow setting opacity for both active and inactive backgrounds.
9
+
10
+ ## Requirements
11
+ - Opacity slider (0-100%) for active background
12
+ - Opacity slider (0-100%) for inactive background
13
+ - Real-time preview as slider moves
14
+ - Persisted in settings
15
+
16
+ ## Implementation
17
+ - Add `activeBgOpacity` and `inactiveBgOpacity` to settings
18
+ - Add range sliders to settings panel
19
+ - Apply opacity via CSS or window opacity
20
+ - Update on focus/blur events
@@ -0,0 +1,21 @@
1
+ # floatnote-18: Auto-save notes to ~/.floatnote folder
2
+
3
+ **Status:** closed
4
+ **Priority:** medium
5
+ **Labels:** feature, storage
6
+
7
+ ## Description
8
+ Add a setting to automatically save notes to ~/.floatnote folder for backup and external access.
9
+
10
+ ## Requirements
11
+ - Toggle setting: "Auto-save notes to ~/.floatnote"
12
+ - On save, write note JSON to `~/.floatnote/note-{id}.json`
13
+ - Create directory if it doesn't exist
14
+ - Only save when setting is enabled
15
+
16
+ ## Implementation
17
+ - Add `autoSaveToFolder` setting
18
+ - Add IPC handler `export-to-floatnote` in main.js
19
+ - Add preload bridge function
20
+ - Add toggle in settings UI
21
+ - Call export on each autoSave() if enabled
@@ -0,0 +1,19 @@
1
+ # floatnote-19: Open notes folder in Finder
2
+
3
+ **Status:** closed
4
+ **Priority:** medium
5
+ **Labels:** feature, ui
6
+
7
+ ## Description
8
+ Add a button in settings to open the ~/.floatnote folder in Finder.
9
+
10
+ ## Requirements
11
+ - Button: "Open Notes Folder" in settings panel
12
+ - Opens ~/.floatnote in Finder
13
+ - Creates folder if it doesn't exist
14
+
15
+ ## Implementation
16
+ - Add IPC handler `open-floatnote-folder` in main.js
17
+ - Use shell.openPath() from Electron
18
+ - Add preload bridge function
19
+ - Add button in settings UI
@@ -0,0 +1,32 @@
1
+ # floatnote-2: Test CLI entry point (bin/floatnote.js)
2
+
3
+ **Status:** open
4
+ **Priority:** high
5
+ **Labels:** testing, cli
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ 100% test coverage for the CLI entry point that downloads and launches the app.
10
+
11
+ ## Functions to Test
12
+ - `getLatestRelease()` - GitHub API call
13
+ - `downloadFile()` - File download with redirects
14
+ - `formatBytes()` - Byte formatting utility
15
+ - `main()` - CLI argument handling
16
+
17
+ ## Test Cases
18
+ - [ ] --version flag shows version
19
+ - [ ] --help flag shows help text
20
+ - [ ] --uninstall removes app directory
21
+ - [ ] --update forces download
22
+ - [ ] Handles missing releases gracefully
23
+ - [ ] Handles download failures
24
+ - [ ] Handles redirect responses (301, 302)
25
+ - [ ] Creates app directory if missing
26
+ - [ ] Launches app after download
27
+ - [ ] Skips download if version matches
28
+
29
+ ## Mocks Required
30
+ - https module (GitHub API, downloads)
31
+ - fs module (file operations)
32
+ - child_process (spawn for app launch)
@@ -0,0 +1,22 @@
1
+ # floatnote-20: Export note as PNG with Cmd+S
2
+
3
+ **Status:** closed
4
+ **Priority:** high
5
+ **Labels:** feature, export
6
+
7
+ ## Description
8
+ Map Cmd+S to export the current note as a flattened PNG image.
9
+
10
+ ## Requirements
11
+ - Cmd+S opens save dialog
12
+ - Export canvas + text + images as PNG
13
+ - User chooses destination
14
+ - Flatten all layers to single image
15
+
16
+ ## Implementation
17
+ - Add Cmd+S handler in setupKeyboardShortcuts()
18
+ - Create exportAsPNG() method
19
+ - Use canvas.toDataURL() for drawing
20
+ - Render text and images to canvas before export
21
+ - Add IPC handler `export-png` with dialog.showSaveDialog()
22
+ - Add preload bridge function
@@ -0,0 +1,50 @@
1
+ # floatnote-3: Test main process (src/main.js)
2
+
3
+ **Status:** open
4
+ **Priority:** high
5
+ **Labels:** testing, electron, main-process
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ 100% test coverage for the Electron main process.
10
+
11
+ ## Functions to Test
12
+ - `createWindow()` - Window creation and configuration
13
+ - `createTray()` - Tray icon and menu setup
14
+ - `toggleFloatnote()` - Show/hide window
15
+ - IPC handlers (save-data, load-data, set-pinned, etc.)
16
+
17
+ ## Test Cases
18
+ ### Window Management
19
+ - [ ] Creates window with correct dimensions
20
+ - [ ] Window is transparent and always-on-top
21
+ - [ ] Window positioned on correct display
22
+ - [ ] Single instance lock works
23
+ - [ ] Second instance focuses existing window
24
+ - [ ] Close confirmation dialog works
25
+ - [ ] Hide window handler works
26
+
27
+ ### Tray
28
+ - [ ] Tray icon created with correct image
29
+ - [ ] Tray tooltip shows "Floatnote"
30
+ - [ ] Context menu has all items
31
+ - [ ] Left-click shows/focuses window
32
+ - [ ] Right-click shows context menu
33
+
34
+ ### IPC Handlers
35
+ - [ ] save-data writes to file
36
+ - [ ] load-data reads from file
37
+ - [ ] set-pinned updates always-on-top
38
+ - [ ] set-window-size resizes correctly
39
+ - [ ] set-background-mode changes vibrancy
40
+ - [ ] resize-window-left adjusts bounds
41
+ - [ ] hide-window hides window
42
+
43
+ ### Global Shortcuts
44
+ - [ ] Cmd+Shift+G toggles window
45
+ - [ ] Alt+Space toggles window
46
+ - [ ] Ctrl+\` toggles window
47
+
48
+ ## Mocks Required
49
+ - Electron modules (BrowserWindow, Tray, Menu, etc.)
50
+ - fs module for data persistence
@@ -0,0 +1,31 @@
1
+ # floatnote-4: Test renderer - Drawing functionality
2
+
3
+ **Status:** open
4
+ **Priority:** high
5
+ **Labels:** testing, renderer, drawing
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for canvas drawing functionality in renderer.js.
10
+
11
+ ## Functions to Test
12
+ - `setupCanvas()` - Canvas initialization
13
+ - `setupDrawing()` - Mouse event handlers
14
+ - `startDrawing()` - Begin stroke
15
+ - `draw()` - Continue stroke
16
+ - `stopDrawing()` - End stroke
17
+ - `drawLine()` - Render line to canvas
18
+ - `redraw()` - Full canvas redraw
19
+ - `smoothLine()` - Line smoothing algorithm
20
+
21
+ ## Test Cases
22
+ - [ ] Canvas resizes to window dimensions
23
+ - [ ] Mouse down starts drawing in draw mode
24
+ - [ ] Mouse move creates points
25
+ - [ ] Mouse up ends stroke and saves line
26
+ - [ ] Lines grouped by objectId within timeout
27
+ - [ ] Drawing respects current color
28
+ - [ ] Drawing respects current stroke width
29
+ - [ ] Redraw renders all saved lines
30
+ - [ ] Line smoothing reduces point count
31
+ - [ ] Drawing disabled in select/text mode
@@ -0,0 +1,28 @@
1
+ # floatnote-5: Test renderer - Text mode functionality
2
+
3
+ **Status:** open
4
+ **Priority:** high
5
+ **Labels:** testing, renderer, text
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for text annotation functionality.
10
+
11
+ ## Functions to Test
12
+ - `setupTextMode()` - Text mode initialization
13
+ - `createTextItem()` - Create new text element
14
+ - `restoreTextItem()` - Restore text from saved data
15
+ - `setupTextDrag()` - Dragging text items
16
+ - `setupTextResize()` - Resizing text items
17
+
18
+ ## Test Cases
19
+ - [ ] Click in text mode creates text item
20
+ - [ ] Text item positioned at click location
21
+ - [ ] Text item has editable contenteditable
22
+ - [ ] Text uses current color
23
+ - [ ] Text item can be dragged
24
+ - [ ] Text item can be resized
25
+ - [ ] Empty text items are removed on blur
26
+ - [ ] Text items saved to textItems array
27
+ - [ ] Restored text items match saved data
28
+ - [ ] Selected text item has visual indicator
@@ -0,0 +1,30 @@
1
+ # floatnote-6: Test renderer - Select mode and object manipulation
2
+
3
+ **Status:** open
4
+ **Priority:** high
5
+ **Labels:** testing, renderer, selection
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for selection and object manipulation.
10
+
11
+ ## Functions to Test
12
+ - `selectObject()` - Select drawing object
13
+ - `deselectObject()` - Clear selection
14
+ - `findObjectAtPoint()` - Hit testing
15
+ - `deleteObject()` - Delete selected object
16
+ - `copyObject()` - Copy to clipboard
17
+ - `selectAll()` - Select all objects
18
+ - `deleteSelected()` - Bulk delete
19
+
20
+ ## Test Cases
21
+ - [ ] Click on object selects it
22
+ - [ ] Click elsewhere deselects
23
+ - [ ] Selection highlight renders correctly
24
+ - [ ] Hit testing finds correct object
25
+ - [ ] Delete removes object from lines array
26
+ - [ ] Copy stores object in clipboard
27
+ - [ ] Cmd+A selects all objects
28
+ - [ ] D key deletes selected
29
+ - [ ] Bulk delete removes multiple objects
30
+ - [ ] Selection state persists across redraws
@@ -0,0 +1,38 @@
1
+ # floatnote-7: Test renderer - Zoom, pan, and gestures
2
+
3
+ **Status:** open
4
+ **Priority:** medium
5
+ **Labels:** testing, renderer, gestures
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for zoom, pan, rotation and gesture handling.
10
+
11
+ ## Functions to Test
12
+ - `setupZoom()` - Zoom controls setup
13
+ - `setupGestures()` - Trackpad gesture handlers
14
+ - `zoomIn()` / `zoomOut()` - Zoom operations
15
+ - `resetZoom()` - Reset to 100%
16
+ - `applyTransform()` - Apply CSS transforms
17
+
18
+ ## Test Cases
19
+ ### Zoom
20
+ - [ ] Zoom in increases zoomLevel
21
+ - [ ] Zoom out decreases zoomLevel
22
+ - [ ] Zoom respects min/max bounds
23
+ - [ ] Reset zoom sets to 1.0
24
+ - [ ] Cmd++ zooms in
25
+ - [ ] Cmd+- zooms out
26
+ - [ ] Cmd+0 resets zoom
27
+
28
+ ### Pan
29
+ - [ ] Two-finger pan updates panX/panY
30
+ - [ ] Pan disabled when setting is off
31
+
32
+ ### Rotation
33
+ - [ ] Rotation gesture updates rotation
34
+ - [ ] Rotation disabled when setting is off
35
+
36
+ ### Transforms
37
+ - [ ] applyTransform sets correct CSS
38
+ - [ ] Transform includes zoom, pan, rotation
@@ -0,0 +1,29 @@
1
+ # floatnote-8: Test renderer - Undo/redo and history
2
+
3
+ **Status:** open
4
+ **Priority:** high
5
+ **Labels:** testing, renderer, history
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for undo/redo functionality.
10
+
11
+ ## Functions to Test
12
+ - `saveState()` - Save current state to history
13
+ - `undo()` - Restore previous state
14
+ - `redo()` - Restore next state
15
+ - `restoreState()` - Apply state from history
16
+
17
+ ## Test Cases
18
+ - [ ] saveState adds to history array
19
+ - [ ] History limited to maxHistorySize
20
+ - [ ] Undo decrements historyIndex
21
+ - [ ] Undo restores previous lines
22
+ - [ ] Undo restores previous textItems
23
+ - [ ] Redo increments historyIndex
24
+ - [ ] Redo restores next state
25
+ - [ ] Redo unavailable at latest state
26
+ - [ ] Undo unavailable at oldest state
27
+ - [ ] Cmd+Z triggers undo
28
+ - [ ] Cmd+Shift+Z triggers redo
29
+ - [ ] New action clears redo stack
@@ -0,0 +1,32 @@
1
+ # floatnote-9: Test renderer - Multi-note system
2
+
3
+ **Status:** open
4
+ **Priority:** high
5
+ **Labels:** testing, renderer, notes
6
+ **Depends:** floatnote-1
7
+
8
+ ## Description
9
+ Test coverage for multi-note navigation system.
10
+
11
+ ## Functions to Test
12
+ - `createEmptyNote()` - Create blank note
13
+ - `previousNote()` - Navigate backward
14
+ - `nextNote()` - Navigate forward or create new
15
+ - `saveCurrentNoteState()` - Save before switch
16
+ - `loadCurrentNote()` - Load note content
17
+ - `clearDisplay()` - Clear current display
18
+ - `updateNoteIndicator()` - Show note position
19
+
20
+ ## Test Cases
21
+ - [ ] createEmptyNote has correct structure
22
+ - [ ] previousNote decrements currentNoteIndex
23
+ - [ ] previousNote does nothing at index 0
24
+ - [ ] nextNote increments if more notes exist
25
+ - [ ] nextNote creates new note at end
26
+ - [ ] loadCurrentNote restores lines
27
+ - [ ] loadCurrentNote restores textItems
28
+ - [ ] loadCurrentNote restores images
29
+ - [ ] clearDisplay removes text elements
30
+ - [ ] Note indicator shows correct position
31
+ - [ ] [ key goes to previous note
32
+ - [ ] ] key goes to next note
package/CLAUDE.md ADDED
@@ -0,0 +1,61 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Floatnote is a transparent always-on-top drawing and note-taking overlay for macOS, built with Electron. It provides a floating canvas that stays above all other windows for annotations, drawing, and text notes.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ npm start # Run the app
13
+ npm run dev # Run with logging enabled
14
+ npm run build # Build distributable (electron-builder)
15
+ npm test # Run all tests
16
+ npm run test:watch # Run tests in watch mode
17
+ npm run test:coverage # Run tests with coverage report
18
+ ```
19
+
20
+ Run a single test file:
21
+ ```bash
22
+ npx jest tests/renderer/notes.test.js
23
+ ```
24
+
25
+ Run tests for a specific project (main, renderer, cli, preload):
26
+ ```bash
27
+ npx jest --selectProjects=renderer
28
+ ```
29
+
30
+ ## Architecture
31
+
32
+ ### Electron Process Model
33
+
34
+ - **Main process** (`src/main.js`): Window management, global shortcuts, IPC handlers, tray menu, data persistence. Single-window architecture with `requestSingleInstanceLock()`.
35
+
36
+ - **Preload** (`src/preload.js`): Exposes `window.glassboard` API via contextBridge. Handles IPC communication, clipboard access, and file operations.
37
+
38
+ - **Renderer** (`src/renderer.js`): The `Glassboard` class manages the entire UI - canvas drawing, text overlays, multi-note system, gestures, undo/redo, and settings.
39
+
40
+ ### Key Data Structures
41
+
42
+ Notes are stored as objects with `lines`, `textItems`, `images`, and `attachments` arrays. The current note is accessed via getters that delegate to `this.notes[this.currentNoteIndex]`.
43
+
44
+ Data persists to `~/.config/floatnote/floatnote-data.json` (via Electron's userData path). Notes can also be exported to `~/.floatnote/`.
45
+
46
+ ### IPC Communication
47
+
48
+ Main ↔ Renderer communication uses named channels:
49
+ - `close-window`, `hide-window`, `set-pinned`, `set-window-size`, `set-background-mode` (send)
50
+ - `save-data`, `load-data`, `export-to-floatnote`, `export-png` (invoke/handle)
51
+ - `window-focus`, `background-mode-changed`, `window-toggled-open` (events to renderer)
52
+
53
+ ### Testing
54
+
55
+ Jest with separate projects for different contexts:
56
+ - `main`: Uses electron mock (`tests/mocks/electron.js`)
57
+ - `renderer`: Uses jsdom environment
58
+ - `preload`: Uses electron mock
59
+ - `cli`: Node environment for CLI tests
60
+
61
+ The electron mock simulates BrowserWindow, app, globalShortcut, and other Electron APIs.