Commit Graph

49 Commits

Author SHA1 Message Date
Jeff Emmett f0d893c53a Merge branch 'dev' 2026-02-24 18:12:00 -08:00
Jeff Emmett 10accc6092 fix: use live transcript directly instead of batch API re-transcription
The batch Whisper API was producing worse results than the live Web
Speech API transcript. Now the live text is used as-is when recording
stops. Audio still uploads for the AUDIO note attachment. Parakeet.js
offline fallback only triggers if no live transcript was captured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:11:51 -08:00
Jeff Emmett 6fc4bd7c17 Merge dev into main: add rVoice PWA + browser extension voice recorder
Resolves merge conflicts between dev (voice/transcription features) and
main (logseq import/export, memory cards, attachments). Both feature
sets coexist cleanly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:47:31 -08:00
Jeff Emmett d236b81a11 feat: add /voice PWA route with 3-tier live transcription
Dedicated standalone voice recorder page at /voice that works as an
installable PWA. Records audio with three transcription tiers running
in parallel: WebSocket streaming (live segments), Web Speech API (live
local), and batch Whisper API (high quality). Falls back to offline
Parakeet.js if all network tiers fail. Includes editable transcript,
notebook selection, copy-to-clipboard, and keyboard shortcuts.

PWA manifest updated with Voice Note shortcut for quick access from
taskbar right-click menu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:43:04 -08:00
Jeff Emmett 5ff6c9d832 feat: add rVoice popup recorder with 3-tier transcription to browser extension
Adds a standalone voice recording popup (voice.html) accessible via the
extension popup button or Ctrl+Shift+V hotkey. Records audio, uploads to
rNotes, and transcribes with a 3-tier cascade: server Whisper API, live
Web Speech API (real-time text while recording), and offline Parakeet.js
(NVIDIA 0.6B, ~634MB cached in IndexedDB). Saves as AUDIO notes with
editable transcript and notebook selection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:43:57 -08:00
Jeff Emmett 3d77eae16b feat: add voice note recorder to browser extension
Adds voice recording popup with keyboard shortcut (Alt+Shift+V),
microphone access, and Voice Note button in the extension popup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:42:34 -08:00
Jeff Emmett 17f2d49f12 feat: add article unlock feature for paywalled content
Multi-strategy approach to find readable versions of paywalled articles:
1. Wayback Machine (check existing + Save Page Now)
2. Google Web Cache
3. archive.ph (read-only check for existing snapshots)

Adds archiveUrl field to Note model, /api/articles/unlock endpoint,
unlock button on note detail page, and browser extension integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:32:37 -08:00
Jeff Emmett 4c939bc45e feat: wire rnotes to pull secrets from Infisical at startup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:35:15 -08:00
Jeff Emmett c4141802cc Host Open Notebook at /opennotebook with wildcard subdomain support
Add /opennotebook route embedding Open Notebook via iframe with space-aware
nav breadcrumb. Middleware detects subdomain (e.g. cca.rnotes.online) and sets
rnotes-space cookie. /ai redirects to /opennotebook. Traefik wildcard router
at priority 100 catches *.rnotes.online subdomains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:45:31 +00:00
Jeff Emmett 3a1366f422 Embed OpenNotebook AI in rNotes — tab + standalone /ai route
Adds AI Notebook tab to notebook detail pages and a full-page /ai route,
both embedding the existing OpenNotebook instance via iframe at
opennotebook.rnotes.online. CSP frame-src header added for security.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 05:55:38 +00:00
Jeff Emmett 7a934a8a93 Add Memory Cards section and inclusion credit to landing page
Six feature cards: card types, hierarchy & properties, Logseq interop,
dual format storage, structured attachments, and FUN model.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 23:42:02 +00:00
Jeff Emmett 6da2cee425 Add Traefik priority 130 to ensure standalone routing over rSpace
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:53:12 +00:00
Jeff Emmett 2c3e28b8d1 fix: use Array.from for Map iteration (ES5 target compat)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:37:45 +00:00
Jeff Emmett 26602e4197 fix: relax ExportNote.children type for Prisma select compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:37:01 +00:00
Jeff Emmett 9735be83ff fix: cast TipTapDoc to InputJsonValue for Prisma compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:36:22 +00:00
Jeff Emmett 94a5c1bccc fix: use Prisma.DbNull for JSON null filter in backfill script
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:35:17 +00:00
Jeff Emmett 7b1d120379 feat: implement Memory Card spec — hierarchy, dual-format body, Logseq interop
Evolve rNotes schema and API to support the Memory Card data model:
- Add parentId self-relation for note hierarchy (NoteTree)
- Dual-format body storage (bodyJson + bodyMarkdown) with HTML fallback
- New cardType field (note/link/file/task/person/idea/reference)
- Structured properties (Logseq-compatible key-value JSON)
- Soft-delete via archivedAt (FUN model: Forget, not Delete)
- File + CardAttachment models for structured attachments
- Tag model evolved with spaceId for scoped tags
- Content conversion library (HTML/JSON/Markdown bidirectional)
- Logseq import/export (ZIP with pages/ + assets/)
- NoteEditor emits TipTap JSON as canonical format
- NoteCard shows cardType badges, child count, properties
- Canvas sync enriched with Memory Card fields
- Backfill script for existing notes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:33:48 +00:00
Jeff Emmett adc68d06e1 Add .dockerignore for optimized Docker builds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:59:43 -07:00
Jeff Emmett a6293dec40 Add rData analytics tracking and ecosystem footer link
- Inject rdata.online/collect.js tracking script in layout
- Add rData link to ecosystem footer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 18:57:08 +00:00
Jeff Emmett e3be857703 feat: add live transcription demo to landing page and demo page
Interactive Web Speech API transcription widget on the homepage
("Try Live Transcription") and demo page. Zero-download, no auth
needed — works instantly in Chrome/Edge/Safari. Updated feature
cards to highlight live transcribe, audio/video, and offline privacy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:05:48 +00:00
Jeff Emmett fd51c06304 feat: standardize ecosystem footer with all 16 r-suite apps
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 09:43:01 +00:00
Jeff Emmett fbbe8d38d1 Replace Whisper-tiny offline fallback with Parakeet.js (NVIDIA 0.6B v2)
Swap @xenova/transformers (whisper-tiny, ~45MB) for parakeet.js
(Parakeet TDT 0.6B v2, ~634MB) loaded from CDN at runtime. Much higher
transcription accuracy at the cost of larger initial model download.
Uses indirect dynamic import to avoid Next.js/webpack bundling issues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 23:48:48 +01:00
Jeff Emmett d1bdb126af chore: backlog TASK-14 SpaceRole bridge (Done)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:35:12 -07:00
Jeff Emmett 5e21e0fa5c feat: add SpaceRole bridge for cross-module membership sync
Maps notebook collaborator roles (OWNER/EDITOR/VIEWER) to SpaceRoles
(ADMIN/PARTICIPANT/VIEWER). Falls back to EncryptID server for
cross-space membership when notebook is linked via canvasSlug.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 14:32:17 -07:00
Jeff Emmett 4e8d12f593 docs: add MODULE_SPEC.md with permission model and capabilities
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:30:14 -07:00
Jeff Emmett b2b4c11960 chore: add rInbox to r* Ecosystem footer
Add rinbox.online link to the ecosystem footer navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:31:21 -07:00
Jeff Emmett 0e847a48a8 chore: add backlog task files for TASK-11, TASK-12, TASK-13
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:17:00 -07:00
Jeff Emmett 441403fd14 feat: add offline Whisper transcription fallback via Transformers.js
When both WebSocket streaming and server batch API are unavailable,
falls back to in-browser Whisper (Xenova/whisper-tiny, ~45MB, cached).
Shows download progress bar and transcription status during processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:38:15 -07:00
Jeff Emmett e6fb53bf15 fix: replace /s regex flag with [\s\S] for ES2017 compat
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:49:49 -07:00
Jeff Emmett 560dceec0f feat: live streaming transcription via WebSocket + diarization UI
Add AudioWorklet-based PCM16 streaming to VoiceRecorder with WebSocket
connection for near-real-time transcription. Segments appear as finalized
text that never shifts. Add speaker diarization button on audio notes
with color-coded speaker labels. Graceful fallback to batch transcription
when WebSocket unavailable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:48:40 -07:00
Jeff Emmett 30f3383d1b feat: rewrite demo page with live rSpace data via useDemoSync
Replace static mock data with real-time WebSocket connection to the
shared demo community. Notes are expandable, packing items toggleable,
all changes sync across the r* ecosystem in real-time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:39:07 -07:00
Jeff Emmett 2c329d7ca4 feat: add demo page and ecosystem footer
Add interactive demo page showing Team Knowledge Base with notebooks,
rich notes, tags, code blocks, and canvas sync indicators.
Update landing page footer with all 10 r* ecosystem apps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 08:58:52 -07:00
Jeff Emmett 463cb99888 feat: add PWA support with install-to-homescreen banner
- manifest.json with app metadata and icons
- Service worker (network-first for pages, skip APIs)
- PWAInstall component with native install prompt + fallback instructions
- Generated 192/512 PNG icons and apple-touch-icon
- PWA meta tags in layout (apple-web-app, theme-color, manifest link)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 08:36:32 -07:00
Jeff Emmett d7a2372a56 feat: add AUDIO note type with voice recording and transcription
- Add AUDIO to NoteType enum, duration field to Note model
- New VoiceRecorder component (MediaRecorder API, upload, transcribe)
- New /api/voice/transcribe proxy route to voice-command-api container
- Audio MIME types added to upload whitelist
- Audio player + transcript display on note detail page
- AUDIO type button on new note page with recorder UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 08:34:50 -07:00
Jeff Emmett e450381e2f Add emoji favicon (📝) for browser tab
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 19:13:37 -07:00
Jeff Emmett c701e3245e chore: update TASK-6 web clipper to Done
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:17:38 -07:00
Jeff Emmett 32475bdf34 feat: add rNotes Web Clipper browser extension (TASK-6)
Chrome extension (Manifest V3) forked from PKMN Quick Capture:
- Clip pages, text selections, links, and images to rNotes
- Notebook selection dropdown with remembered last-used
- Tags input for organizing clips
- Context menu integration (right-click to save)
- EncryptID auth via token paste flow
- Image upload through /api/uploads then IMAGE note creation
- Amber/orange theme matching rNotes design

Also updates signin page to show extension token when
?extension=true query param is present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:17:19 -07:00
Jeff Emmett 49afc5db6e chore: update TASK-9 canvas sync to Done
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:04:18 -07:00
Jeff Emmett d64d8a0d57 feat: add internal API key for rSpace service-to-service auth
pushShapesToCanvas now sends X-Internal-Key header from
RSPACE_INTERNAL_KEY env var for authenticated canvas writes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:02:20 -07:00
Jeff Emmett 5575be9290 chore: update backlog task statuses
- TASK-7 (auth): already done
- TASK-9 (canvas sync): in progress, blocked on rSpace shapes API
- TASK-10 (mobile responsive): done

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:47:21 -07:00
Jeff Emmett 57c703d253 fix: correct SDK path in Dockerfile for file: dependency resolution
package.json uses file:../encryptid-sdk which resolves relative to
/app, so SDK must be at /encryptid-sdk not /app/encryptid-sdk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:42:19 -07:00
Jeff Emmett cf27a54caa feat: mobile-responsive UI + canvas sync callback
- Responsive navigation: compact buttons with icons on mobile, hidden
  search bar (moved to dedicated row below nav on mobile)
- Responsive typography: hero text scales from 3xl to 5xl
- Responsive grids: sm:grid-cols-2 breakpoint for cards
- Canvas split view: full-screen overlay on mobile with close button
- Breadcrumbs collapse on mobile, truncate long titles
- Buttons show icon-only on small screens (add, delete, pin)
- Wire up onShapeUpdate callback in notebook detail page for
  bidirectional canvas sync (rSpace → rnotes via /api/sync)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:39:01 -07:00
Jeff Emmett 2351339241 feat: integrate EncryptID SDK for passkey authentication
Wire up EncryptID SDK for user authentication with WebAuthn passkeys.
All write API routes (POST/PUT/DELETE) now require auth, while reads
remain public. First user auto-claims orphaned notebooks/notes.

New files:
- src/lib/auth.ts: getAuthUser, requireAuth, getNotebookRole helpers
- src/lib/authFetch.ts: client-side fetch wrapper with JWT token
- src/components/AuthProvider.tsx: EncryptIDProvider wrapper
- src/components/UserMenu.tsx: sign in/out UI for nav bar
- src/app/auth/signin/page.tsx: passkey login/register page

Protected routes: notebooks CRUD, notes CRUD, canvas create, uploads.
Ownership checks: notebook collaborator roles, note author verification.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:20:00 -07:00
Jeff Emmett c6a8d1f1f2 chore: initialize backlog with completed tasks and future work
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:39:55 -07:00
Jeff Emmett f5bec85336 feat: upgrade to TipTap WYSIWYG rich text editor
Replace plain Markdown textarea with TipTap editor featuring:
- Toolbar with bold, italic, strike, code, headings, lists, tasks,
  blockquotes, code blocks, links, images, undo/redo
- Keyboard shortcuts (Ctrl+B, Ctrl+I, etc.)
- Task list with checkboxes
- Inline image embedding
- Code type notes still use plain textarea for monospace editing
- Note detail view now renders HTML content from TipTap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:36:21 -07:00
Jeff Emmett a065388bbf feat: add file/image upload support with drag-and-drop
- Upload API at /api/uploads with 50MB limit, MIME type validation, and
  path traversal protection
- Serve uploaded files at /api/uploads/[filename] with immutable caching
- FileUpload component with drag-and-drop, progress, and preview
- IMAGE notes show uploaded image preview in detail view
- FILE notes show download button in detail view
- Docker volume for persistent upload storage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:33:49 -07:00
Jeff Emmett f7fa7bc7a1 feat: upgrade search to PostgreSQL full-text with GIN index
Replace Prisma contains-based search with raw SQL using ts_vector/ts_query
for ranked results and headline snippets with <mark> highlighting. Falls
back to ILIKE for partial matches. GIN index applied to production DB.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:30:30 -07:00
Jeff Emmett 118710999b Add full application: schema, API routes, components, pages
- Prisma schema: User, Notebook, Note (6 types), Tag, SharedAccess
- API: CRUD for notebooks/notes, full-text search, canvas sync
- Components: CanvasEmbed, NoteEditor, NoteCard, NotebookCard, SearchBar, TagBadge
- Pages: landing, notebooks list/new/detail/canvas, notes new/detail
- Canvas integration: bidirectional sync with rSpace (folk-notebook, folk-note shapes)
- Amber/orange theme consistent across all pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:00:44 -07:00
Jeff Emmett 445a282ef1 Initial scaffold: Next.js 14 + Prisma + Docker
Project structure matching rTrips-online pattern:
- Multi-stage Dockerfile with nextjs user
- Phase 3 hardened docker-compose (cap_drop ALL, read_only)
- Traefik labels for rnotes.online routing
- PostgreSQL 16-alpine on internal network

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:53:52 -07:00