- CompletedToggle: 5 tests for checkbox rendering, state, and interaction
- SearchBar: 7 tests for input, placeholder, recent searches dropdown
- TagInput: 6 tests for rendering with various tag configurations
- Update vitest-setup-client.ts with $app/state, preferences, recentSearches mocks
- All component tests run in real Chromium browser via Playwright
- Test empty input handling
- Test query filter (min 2 chars, case insensitive, title OR content)
- Test tag filter (AND logic, case insensitive)
- Test type filter (task/thought/all)
- Test date range filter (start, end, both)
- Test combined filters
- Test generic type preservation
17 tests covering filterEntries.ts with 100% coverage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a tag is deleted as orphaned, it's now automatically removed
from the active filter selection.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tags that are no longer associated with any entry are automatically
deleted from the database when a tag is removed from an entry.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove auto-parsing on collapse
- Add "Scan for #tags" button that parses from current textarea content
- Always show tags section with delete buttons
- Show help text when no tags exist
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move tag parsing from textarea blur to entry collapse action.
This prevents incomplete tags from being created while editing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Parse hashtags when content textarea loses focus (blur)
- Parse hashtags when QuickCapture form is submitted
- Add tag display with delete buttons in expanded entry view
- Remove automatic hashtag parsing during typing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tags are now automatically extracted from #hashtags in content text.
Removed TagInput from entry editing, keeping it only in FilterBar.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update db/index.ts to read data directory from env var
- Update storage.ts to read data directory from env var
- Both default to ./data for local development
- Add searchQuery prop to EntryCard for text highlighting
- Use {@html highlightText()} for title and content in collapsed view
- Integrate SearchBar and FilterBar in +page.svelte
- Add search/filter state with reactive sync to filters.query
- Pass recentSearches store to SearchBar
- Update filterEntries to use generics for type preservation
- Add filters and searchQuery props to EntryList
- Apply filterEntries via $derived for reactive filtering
- Display flat list (no pinned separation) when filtering
- Show search-specific empty state when no matches
- Pass searchQuery to EntryCard for highlighting
- Add recentSearches persisted store with 5-item limit
- Add addRecentSearch() function for deduplication
- Update SearchBar with recentSearches dropdown
- Show dropdown on focus when input empty
- Use onmousedown to handle selection before blur
- Add to recent searches on blur with >= 2 chars
- Wrap matching text in <mark> tags with bold styling
- Escape HTML before highlighting to prevent XSS
- 2-character minimum query requirement
- Uses bg-transparent (no background per CONTEXT.md)
- Debounced value binding (300ms delay via $effect cleanup)
- Only trigger search when query >= 2 chars OR cleared to empty
- Bindable value prop for parent integration
- '/' keyboard shortcut to focus search (GitHub-style)
- Native event listener to avoid Svelte 5 keydown bug
- Add SearchFilters type and utilities (search.ts)
- Implement filterEntries with query, tags, type, dateRange filters
- Case-insensitive text search with 2-character minimum
- AND logic for tag filtering
- Date range inclusive of end date
- Add SearchFilters interface for query, tags, type, dateRange
- Add defaultFilters constant with empty/default values
- Add hasActiveFilters() to detect when filters are active
- Add getDatePreset() helper for today/week/month presets
- Create TagInput.svelte with Svelecte for multi-select autocomplete
- Support creating new tags inline via creatable mode
- Display tags on collapsed entry cards (max 3 with +N indicator)
- Add TagInput in expanded view for editing entry tags
- Pass availableTags through EntryList to EntryCard
- Handle tag changes with immediate save via updateTags action
- Add pin button in expanded view with toggle functionality
- Add due date picker in expanded view with date input
- Show pin indicator and due date in collapsed view
- Separate EntryList into pinned and unpinned sections
- Pinned section appears at top with header label
- Add TagRepository interface with findOrCreate, getAll, getById, getByEntryId, updateEntryTags
- Implement SQLiteTagRepository with case-insensitive tag lookup
- updateEntryTags atomically replaces all tags for an entry
- Export tagRepository singleton
- Add tags table with nanoid PK and case-insensitive unique index on name
- Add entry_tags junction table with composite PK and cascade deletes
- Export lower() helper function for case-insensitive queries
- Export Tag, NewTag, EntryTag types for TypeScript inference
- Remove CameraCapture modal which required getUserMedia (HTTPS only)
- Use native file input with capture="environment" attribute
- Opens camera directly via OS file picker on mobile
- Works over HTTP during development
- Simpler implementation with better browser compatibility
- Show image count indicator in collapsed entry view
- Add horizontal scrolling gallery in expanded view
- Edit mode reveals delete buttons on images
- Add ImageUpload and Camera button for adding images
- CameraCapture modal for mobile photo capture
- Updated EntryList to pass entries with images
- Add image button next to submit button
- Show pending image preview with filename
- Allow removing pending image before submit
- Upload image after entry creation with new entry ID
- Disable button during upload to prevent duplicates
- Clean up object URLs properly
- Full-screen camera modal with live preview via getUserMedia
- Photo capture using canvas.toBlob (JPEG at 0.9 quality)
- Preview captured photo with retake/confirm flow
- Camera stream properly stopped on close and after capture
- Switch camera button for front/back camera toggle
- Upload integration via ?/uploadImage form action
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add drag-and-drop zone for image uploads
- Show optimistic preview during upload
- Support keyboard navigation (Enter/Space to trigger)
- Handle upload via fetch to ?/uploadImage action
- Clean up object URLs after upload completes
- Provide callbacks for upload lifecycle events
- Add storage.ts with directory management and file I/O
- Add thumbnails.ts with EXIF-aware thumbnail generation
- Thumbnails always output as JPEG with 80% quality
- Replace svelte-gestures with native touch event handlers
- Add invalidateAll() after save/delete for seamless list updates
- Add $effect to sync edit state when entry prop changes
- Improve swipe animation with isSwiping state tracking
- Install svelte-gestures package for touch gesture support
- Add useSwipe hook to EntryCard for left-swipe detection
- Implement delete confirmation overlay on swipe
- Add red delete background revealed during swipe
- Maintain desktop delete button in expanded view
- Create CompletedToggle component with checkbox UI
- Add showCompleted URL param to +page.server.ts load function
- Update +page.svelte to sync preferences with URL
- Toggle state persists in localStorage via preferences store
- Clicking toggle updates URL and invalidates data for server filter
- Add expanded state for expand/collapse toggle
- Implement inline editing for title, content, and type
- Add 400ms debounced auto-save using fetch to ?/update
- Show 'Saving...' indicator during save
- Add delete button with confirmation dialog
- Use Svelte slide transition for smooth expand/collapse
- Fix button nesting by restructuring layout
- QuickCapture fixed at bottom with type selector and submit button
- Uses enhance for progressive form enhancement
- Persists last used type via preferences store
- Clears form on successful submit
- Main page composes EntryList and QuickCapture
- Adequate bottom padding (pb-40) for capture bar clearance
- Sticky header with app title
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- EntryCard displays entry with type indicator (checkbox/badge)
- Tasks have checkbox for toggle completion via form action
- Thoughts show purple "T" badge indicator
- Completed tasks show strikethrough styling
- EntryList renders entries with mobile compact/desktop card layout
- Type badge shows blue for task, purple for thought
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Install svelte-persisted-store for localStorage persistence
- Create preferences store with lastEntryType and showCompleted
- Sticky type preference across sessions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getOrdered(options?) method to EntryRepository interface
- Implement filtering for completed entries (showCompleted option)
- Order by type ASC (task before thought), then createdAt DESC
- Import asc, ne operators from drizzle-orm
- Implement EntryRepository interface with create, getById, getAll, update, delete, count
- SQLiteEntryRepository class using Drizzle ORM
- Automatic ID generation with nanoid
- Automatic timestamp management (createdAt, updatedAt)
- Pagination support via limit/offset
- Singleton pattern for consistent access
- SvelteKit minimal template with TypeScript
- Tailwind CSS v4 with @tailwindcss/vite plugin
- ESLint and Prettier for code quality
- Dependencies: better-sqlite3, drizzle-orm, nanoid, zod
- Dev server runs on localhost:5173