- 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>
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>
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>
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>
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>
- Ensure SaveSpellbookDialog passes content to PublishSpellbookAction
- Refactor SpellDialog to use PublishSpellAction instead of manual logic
- Ensure published events are added to local EventStore for immediate UI update
- Clean up unused imports and variables in SpellDialog