Commit Graph

220 Commits

Author SHA1 Message Date
Claude
e904fcbaf1 fix: prevent command text overflow in spell dialogs
Replace `break-all` with `break-words overflow-x-auto` to improve
text wrapping behavior in command preview areas. This prevents
words from breaking awkwardly in the middle while still allowing
long commands to be displayed properly.

Changes:
- CreateSpellDialog.tsx: Fixed command preview overflow
- SpellDialog.tsx: Fixed command display overflow
- SpellRenderer.tsx: Fixed detail view command overflow

The new approach breaks at word boundaries when possible and
provides horizontal scrolling for exceptionally long commands.
2025-12-22 17:00:24 +00:00
Alejandro
0d8f8b7807 Merge pull request #17 from purrgrammer/claude/applesauce-helpers-investigation-EWmaW
docs: add applesauce helpers investigation and refactoring plan
2025-12-22 15:19:41 +01:00
Claude
c40c4ae1f9 fix: TypeScript error in useStableFilters 2025-12-22 14:05:53 +00:00
Claude
912794f4e0 chore: lint fix 2025-12-22 14:04:46 +00:00
Claude
33539c291b refactor: use applesauce helpers for pointer parsing and filter comparison
Phase 2 & 3 of applesauce helpers refactoring plan.

**Phase 2: Replace manual pointer parsing**
- ReactionRenderer.tsx: replaced manual coordinate parsing with parseCoordinate helper
- Benefits: more robust, handles edge cases, consistent with applesauce patterns

**Phase 3: Improve filter comparison**
- useStable.ts: replaced JSON.stringify with isFilterEqual for filter comparison
- Benefits: handles undefined values correctly, supports NIP-ND AND operator
- Implementation uses ref pattern to maintain stable reference when filters are equal

All tests pass (607 tests).
2025-12-22 14:04:09 +00:00
Claude
4b7148510a refactor: remove unnecessary useMemo from applesauce helper calls
Phase 1 of applesauce helpers refactoring plan.

Removed useMemo from direct applesauce helper calls since these helpers
cache their results internally using symbol-based caching. This improves
code clarity without sacrificing performance.

Changes:
- ArticleRenderer.tsx: removed useMemo from getArticleTitle, getArticleSummary
- HighlightRenderer.tsx: removed useMemo from 6 highlight helpers
- HighlightDetailRenderer.tsx: removed useMemo from 6 highlight helpers
- CodeSnippetDetailRenderer.tsx: removed useMemo from 8 NIP-C0 helpers
- ChatView.tsx: removed useMemo from getNip10References, getTagValue

Kept useMemo in LiveActivityRenderer.tsx for parseLiveActivity and related
functions since these don't implement their own caching (noted for future
optimization).

All tests pass (607 tests).
2025-12-22 13:18:44 +00:00
Claude
2189d5a969 docs: add applesauce helpers investigation and refactoring plan
- Created APPLESAUCE_REFACTORING_PLAN.md with detailed analysis
- Updated CLAUDE.md with Applesauce Helpers & Caching section
- Enhanced applesauce-core skill with helper documentation

Key findings:
- Applesauce helpers cache internally using symbols
- No need for useMemo when calling applesauce helpers
- Identified 40+ useMemo instances that can be removed
- Documented available helpers and custom grimoire helpers
- Provided migration strategy and refactoring opportunities
2025-12-22 13:12:56 +00:00
Alejandro Gómez
32c895e150 chore: lint fix 2025-12-22 13:25:38 +01:00
Alejandro
ea3d0e1119 Merge pull request #16 from purrgrammer/claude/pluggable-storage-engine-F53Fc
Make storage engine pluggable for testing
2025-12-22 13:24:24 +01:00
Claude
729c83011e fix: add IndexedDB polyfill for test environment
Use fake-indexeddb to provide IndexedDB API in Node.js test environment.
This fixes 10 failing tests in spellbook-storage.test.ts that were
previously blocked by missing IndexedDB.

Changes:
- Add fake-indexeddb as dev dependency
- Create vitest setup file that imports the polyfill
- Update vitest.config.ts to use setup file
- Fix relay-selection.test.ts to clear cache between tests for isolation
2025-12-22 12:18:38 +00:00
Alejandro
2fda75ef71 Merge pull request #15 from purrgrammer/claude/documentation-EeWQZ
docs: add codebase analysis and accessibility plan
2025-12-22 13:14:00 +01:00
Alejandro
addea243d1 Merge pull request #12 from purrgrammer/claude/kind-utilities-EeWQZ
feat: add centralized nostr kind utilities
2025-12-22 13:12:52 +01:00
Alejandro
d35345f720 Merge pull request #13 from purrgrammer/claude/useprofile-race-fix-EeWQZ
fix: prevent race conditions in useProfile hook
2025-12-22 13:12:25 +01:00
Claude
a86b783f58 docs: add plan for pluggable storage engine
Analyze test failures due to missing IndexedDB in Node environment.
Present two options: fake-indexeddb polyfill vs full storage abstraction.
Recommend fake-indexeddb as pragmatic solution.
2025-12-22 12:11:33 +00:00
Alejandro
8862695ee6 Merge pull request #14 from purrgrammer/claude/stabilization-hooks-EeWQZ
feat: add dependency stabilization hooks
2025-12-22 13:10:51 +01:00
Claude
cdad01dc03 docs: add codebase analysis and accessibility plan
CODEBASE_ANALYSIS.md:
- Comprehensive architecture review
- State management analysis (Jotai + EventStore + Dexie)
- Component patterns assessment
- Security audit findings (zero vulnerabilities)
- Performance analysis
- 12-week S-tier improvement roadmap

ACCESSIBILITY_PLAN.md:
- Current state assessment (16% ARIA coverage)
- WCAG 2.1 AA compliance roadmap
- Phased implementation plan:
  - Phase 1: Foundation (keyboard nav, focus management)
  - Phase 2: Screen reader support
  - Phase 3: Visual accessibility
  - Phase 4: Advanced features
- Component-specific accessibility requirements
2025-12-22 12:03:33 +00:00
Claude
645e12cddc fix: prevent race conditions in useProfile hook
- Replace mounted boolean flag with AbortController pattern
- Check abort signal before initiating database writes
- Proper cleanup on unmount/pubkey change

This prevents stale data from being written to IndexedDB when:
- Component unmounts during async operations
- Pubkey changes while a fetch is in progress
2025-12-22 12:02:03 +00:00
Claude
bdfc634c54 feat: add dependency stabilization hooks
- Create src/hooks/useStable.ts with:
  - useStableValue<T>() - stabilizes any value using JSON.stringify
  - useStableArray<T>() - stabilizes string arrays (uses JSON.stringify
    for safety, handles arrays with commas in elements)
  - useStableFilters<T>() - specialized for Nostr filters

- Update timeline hooks to use stabilization:
  - useTimeline.ts - use useStableFilters for filter dependencies
  - useReqTimeline.ts - use useStableValue for filter dependencies
  - useLiveTimeline.ts - use useStableArray for relay dependencies

Prevents unnecessary re-renders and subscription restarts when
filter/relay objects are recreated with the same content.
2025-12-22 12:00:42 +00:00
Alejandro Gómez
62676feeba fix: respect zap message 2025-12-22 12:59:56 +01:00
Claude
96216450f4 feat: add centralized nostr kind utilities
- Create src/lib/nostr-kinds.ts with:
  - Re-exports from nostr-tools/kinds (isRegularKind, isReplaceableKind, etc.)
  - New isParameterizedReplaceableKind() function
  - New isAddressableKind() for determining naddr vs nevent encoding
  - NIP-01 boundary constants with clarifying comments
  - getKindCategory() for display purposes

- Update KindRenderer.tsx to use shared utilities:
  - Replace inline range checks with helper functions
  - Fix "Regular Lists" -> "Replaceable Events" naming
  - Simplify redundant condition (isReplaceableKind includes kinds 0, 3)

- Update BaseEventRenderer.tsx to use isAddressableKind()

- Add comprehensive tests for all utilities
2025-12-22 11:58:46 +00:00
Alejandro Gómez
64002ed1ec fix: zap sender in compact zaps 2025-12-22 12:49:28 +01:00
Alejandro Gómez
a9ae32ad01 fix: clickable spellbook link 2025-12-22 12:38:37 +01:00
Alejandro Gómez
e7a7bb05a4 feat: clickable spell and spellbook links 2025-12-22 12:38:37 +01:00
Alejandro
de063c8bfe Merge pull request #11 from purrgrammer/claude/add-since-until-spells-xluIg
fix: include since/until in spell filter JSON display
2025-12-22 12:37:24 +01:00
Alejandro
81566ab136 Merge pull request #10 from purrgrammer/claude/fix-placeholder-styling-7Yo4G
fix: remove custom font size from placeholders and hide embeds in previews
2025-12-22 12:36:54 +01:00
Claude
412ebccc4f fix: include since/until in spell filter JSON display
The filter JSON in SpellDetailRenderer was missing since/until
fields when they were in relative format (e.g., "7d", "now").
This happened because decodeSpell only adds these fields to
the filter object when they're unix timestamps.

Now we extract the raw since/until values from event tags and
include them in a displayFilter object for the JSON viewer,
ensuring users see the complete filter regardless of format.

The command preview already worked correctly since it uses
the reconstructed command string which includes these values.
2025-12-22 10:01:42 +00:00
Claude
470c802364 fix: ensure compact previews properly truncate RichText to single line
- Add line-clamp-1 to all compact preview components for consistent truncation
- Fix DefaultCompactPreview, GenericRepostCompactPreview, ZapCompactPreview
- Fix Kind1111Renderer parent event preview truncation
- Apply auto-formatting fixes from linter
2025-12-22 09:38:27 +00:00
Claude
41b012ae3e fix: remove custom font size from placeholders and hide embeds in previews
- Remove text-sm from MediaPlaceholder and EventPlaceholder to inherit parent font size
- Add options to hide media and event embeds in HighlightRenderer preview
- Ensures placeholders like [image], [note] match surrounding text size
2025-12-22 09:33:09 +00:00
Alejandro Gómez
125052f4c9 fix: spellbook preview or direct behavior 2025-12-21 22:47:24 +01:00
Alejandro Gómez
7f92277986 config: add vercel url rewrite 2025-12-21 22:39:07 +01:00
Alejandro Gómez
3c62a0e236 ui: share spellbook dialog improvements 2025-12-21 22:18:37 +01:00
Alejandro Gómez
fc63b3c685 fix: event publication 2025-12-21 21:50:09 +01:00
Alejandro Gómez
64212121bd ui: compact view tweaks 2025-12-21 21:19:31 +01:00
Alejandro Gómez
6481f1e04f feat: add voice message support (NIP-A0) and legacy video kinds
- Add VoiceMessageRenderer for kinds 1222 (voice message) and 1244 (voice reply)
- Add compact preview components with mic icon for voice messages
- Support legacy NIP-71 video kinds 34235/34236 via existing video renderers
- Add fallback URL tag parsing for video events
- Replace music note icon with mic icon for audio embeds
- Remove border/padding from audio player for cleaner display
- Add kind metadata (names, icons) for voice and legacy video kinds

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:36:53 +01:00
Alejandro Gómez
3346a2077d feat(req): add --view flag for list/compact display mode
- Add -v, --view <list|compact> flag to req command
- Remove UI toggle controls from ReqViewer header
- View mode is now set via command flag instead of runtime toggle
- Update man page with new flag documentation and example

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:29:32 +01:00
Alejandro Gómez
78a8c8e5b2 chore: apply prettier formatting fixes
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:12:40 +01:00
Alejandro Gómez
f4d0e86f09 feat: complete spellbook UX overhaul with enhanced state tracking
- Redesign SpellbookDropdown with clear status indicators (ownership, storage)
- Add SpellbookStatus component showing you/other and local/published/network
- Enhance activeSpellbook type with source, localId, isPublished fields
- Fix PublishSpellbook action to properly yield events (caller handles side-effects)
- Add k tags extraction from REQ windows for kind-based filtering/discovery
- Update terminology from "Layout" to "Spellbook" consistently
- Add comprehensive tests for k tags and source tracking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 19:19:24 +01:00
Alejandro Gómez
be01c7d882 refactor: repo link 2025-12-21 18:19:36 +01:00
Alejandro Gómez
fffb80cd5c ui: remove icon 2025-12-21 18:13:46 +01:00
Alejandro Gómez
21335a5849 WIP 2025-12-21 18:08:10 +01:00
Alejandro Gómez
6ebc501309 fix: restore async generator pattern for PublishSpellbook
Problem:
- Function signature was accidentally changed to curried pattern
- Tests were failing because they expected async generator pattern

Solution:
- Restore async function* signature that takes hub and options
- Matches test expectations and existing usage patterns
- Linter also fixed property destructuring in spellbook-storage

Tests:
-  All publish-spellbook tests passing (14/14)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 18:08:10 +01:00
Alejandro Gómez
f1ba39a65e fix: prevent spellbook duplication when saving
Problem:
- Saving active spellbooks was creating duplicates each time
- No deduplication logic for spellbooks with same slug + pubkey

Solution:
- Add findExistingSpellbook() to match by slug and pubkey
- Update saveSpellbook() to detect and update existing spellbooks:
  * For local-only: match by slug (no pubkey)
  * For published: match by slug AND pubkey
  * For updates: use provided ID
- SaveSpellbookDialog now passes existing ID in update mode

Testing:
- Added comprehensive spellbook-storage.test.ts
- Tests verify deduplication logic (requires jsdom environment)
- Existing tests still pass (14/14 for publish-spellbook)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 18:08:10 +01:00
Alejandro Gómez
0f7f154b80 feat: complete Phase 2 network features for spellbooks
Sharing Enhancements:
- Install qrcode library for QR code generation
- Create ShareSpellbookDialog with tabbed interface
- Support multiple share formats: Web URL, naddr, nevent
- QR code generation and download for each format
- Quick copy buttons with visual feedback
- Integrated into SpellbookDetailRenderer

Network Discovery:
- Add "Discover" filter to browse spellbooks from other users
- Query AGGREGATOR_RELAYS for network spellbook discovery
- Show author names using UserName component
- Conditional UI: hide owner actions for discovered spellbooks
- Support viewing and applying layouts from the community

Preview Route Polish:
- Loading states with spinner during NIP-05 resolution
- 10-second timeout for NIP-05 resolution
- Error banners for resolution failures
- Author name and creation date in preview banner
- Copy link button in preview mode

Conflict Resolution:
- compareSpellbookVersions() function in spellbook-manager
- ConflictResolutionDialog component for version conflicts
- Side-by-side comparison of local vs network versions
- Show workspace/window counts and timestamps

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 18:08:10 +01:00
Alejandro Gómez
6d89a9d342 fix: description 2025-12-21 18:08:10 +01:00
Alejandro Gómez
f272f935a3 feat: text inline when embeds are off 2025-12-21 18:08:10 +01:00
Alejandro Gómez
005605b385 feat: enhance preview route and add conflict resolution for spellbooks
Improve the preview route UX with better loading states, error handling, and metadata display. Add version comparison logic and conflict resolution dialog for handling local vs network spellbook conflicts.

Changes:
- Enhanced preview route in Home.tsx:
  - Add loading state with spinner while resolving actor
  - Add NIP-05 resolution timeout (10 seconds)
  - Display error banner for resolution failures
  - Show author name and creation date in preview banner
  - Add copy link button to share spellbook easily
  - Improve banner layout with metadata

- Add compareSpellbookVersions() in spellbook-manager.ts:
  - Detects conflicts between local and network versions
  - Compares timestamps, workspace counts, window counts
  - Identifies newer version and content differences
  - Returns structured comparison data

- Create ConflictResolutionDialog component:
  - Side-by-side comparison of local vs network versions
  - Shows metadata: timestamps, counts, author, publish status
  - Clear explanation of resolution choices
  - Accessible UI with proper button hierarchy

TypeScript compilation successful 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 18:08:10 +01:00
Alejandro Gómez
784add4f52 refactor: migrate spellbook publishing to applesauce action patterns
Refactor PublishSpellbookAction from class-based to async generator pattern
following official applesauce-actions patterns. This provides better integration
with ActionHub and enables proper reactive event publishing.

Changes:
- Add publishEvent function to ActionHub with relay selection fallback strategy
  (outbox relays → seen relays → error)
- Convert PublishSpellbookAction to PublishSpellbook async generator
- Update SaveSpellbookDialog and SpellbooksViewer to use hub.run()
- Add comprehensive test suite (14 tests covering validation, event creation,
  slug generation, factory integration, and workspace selection)
- Improve error handling with specific error messages
- Add JSDoc documentation with usage examples

All tests passing  (14/14)
TypeScript compilation successful 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 18:08:10 +01:00
Alejandro Gómez
e47fde9158 feat: better layout rendering 2025-12-21 18:08:10 +01:00
Alejandro Gómez
f255cded75 feat: refine spellbook preview and session management logic
- Implement smart banner visibility (only from client-side transitions)
- Add 'Apply to Dashboard' and 'Add to Library' to SpellbookDropdown
- Support updating layouts via standardized dialog
- Fix build errors and type mismatches
2025-12-21 18:08:10 +01:00
Alejandro Gómez
588980a827 feat: enhance spell/spellbook renderers with clickable titles and inferred kinds
- Use ClickableEventTitle for spell and spellbook titles in all views
- Infer event kinds from spellbook windows and display KindBadges in feed/detail views
- Ensure consistent styling and navigation across spell/spellbook components
2025-12-21 18:08:10 +01:00