Commit Graph

49 Commits

Author SHA1 Message Date
Jeff Emmett f475ed0462 feat: integrate encrypted IPFS file storage
- Add src/lib/ipfs.ts: AES-256-GCM encryption + kubo upload/download
- Add /api/ipfs/[cid] proxy route: decrypt + serve with LRU cache
- Upload route: encrypt + pin to IPFS alongside local disk (fallback)
- Prisma: add ipfsCid/ipfsEncKey fields to File model
- FileUpload: prefer IPFS proxy URL when available
- Feature-flagged via IPFS_ENABLED env var

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 17:21:53 -07:00
Jeff Emmett 77302e1a6e feat: add InfoPopup with landing page content on first visit
Shows an informational popup with rich landing page content on first
visit, re-openable via a fixed info button (bottom-right corner).
Dismissible via X button, overlay click, or Escape key. Uses
localStorage to track first-visit state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 04:51:34 +00:00
Jeff Emmett ce05a51960 brand: add (you)r* prefix to landing page title
Reinforces the r-suite "your tools" philosophy across all rApp landing pages.
Also normalizes title separators to em-dash for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 04:24:03 +00:00
Jeff Emmett 75278ef730 feat: update hero title and move feature shortcuts to banner
Update headline to "Capture Everything, Find Anything, and Share your
Insights" with emphasis on Share. Move the three action buttons (Open
Notebook, Unlock Article, Transcribe) from header into the hero banner,
replacing the old Create Notebook / Quick Note buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 16:45:19 -08:00
Jeff Emmett ede11d8568 feat: standardize header, categories, cross-app spaces
- AppSwitcher: rTube/rSwag → Creating, rSocials → Sharing, rData → Observing
- EcosystemFooter: updated link order to match new categories
- UserMenu: 🔑 Sign In button, 🔐 lock when logged in
- SpaceSwitcher: reads EncryptID token, sends Bearer header
- /api/spaces proxy: forwards to rspace.online (canonical spaces)
- /api/me: verifies EncryptID token for auth status
- Header.tsx: standardized bg-slate-900/85 across all apps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:16:56 -08:00
Jeff Emmett cce178671b Add feature shortcuts to header, remove AI branding, reorganize app categories
- Add Open Notebook, Unlock Article, and Transcribe buttons to header
- Move search bar to center of header across all pages
- Rename "AI Notebook" to "Open Notebook" throughout
- Support ?type= query param on /notes/new for deep-linking
- Reorganize AppSwitcher categories (Creating, Sharing, Observing)
- Move rTube and rSwag to Creating category
- Update EcosystemFooter link order to match new categories
- Update header bg to bg-slate-900/85
- Add key emojis to UserMenu sign-in states

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:36:28 -08:00
Jeff Emmett 5cc17e05e7 feat: add space subdomain routing and ownership support
- Traefik wildcard HostRegexp for <space>.r*.online subdomains
- Middleware subdomain extraction and path rewriting
- Provision endpoint with owner_did acknowledgement
- Registry enforces space ownership via EncryptID JWT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:20:01 -08:00
Jeff Emmett 7306447d8d Add internal seed endpoint for demo data
Creates 3 notebooks (research/meetings/ideas) with 9 notes, tags,
and parent-child note hierarchy showing the memory card system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 01:02:34 -08:00
Jeff Emmett ea88aa180c Add internal provision endpoint for rSpace Registry
Auth-free POST /api/internal/provision creates default Notebook + system User
+ OWNER collaborator scoped to workspace slug.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:30:11 -08:00
Jeff Emmett 802091a84f refactor: move Header to layout for all sub-routes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:04:49 -08:00
Jeff Emmett 5672bc1c61 feat: standardize header with AppSwitcher, SpaceSwitcher, and UserMenu
- Replace inline nav/Navbar with shared Header component
- Header pattern: AppSwitcher dropdown / SpaceSwitcher / actions / Sign In
- SpaceSwitcher and UserMenu work without SDK dependency
- Consistent across all r*Apps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:03:00 -08:00
Jeff Emmett ea0ffda8a9 feat: standardize AppSwitcher and EcosystemFooter across all rApps
- Update AppSwitcher with all 26 r*Apps in 8 categories
- Add EcosystemFooter component with consistent ecosystem links
- Categories: Creating, Planning, Communicating, Deciding,
  Funding & Commerce, Social & Media, Work & Productivity,
  Identity & Infrastructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:47:55 -08:00
Jeff Emmett d060e99698 feat: add plain Markdown export/import API endpoints
Export notes as .md files with YAML frontmatter (single or ZIP batch).
Import .md files or ZIP archives with frontmatter parsing and dual-write.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:29:40 -08:00
Jeff Emmett c27290ee80 feat: add username-based personal subdomains (<username>.rnotes.online)
Implements workspace-scoped data isolation via subdomain routing:

- Schema: add workspaceSlug to Notebook model + migration
- Middleware: extract subdomain → x-workspace-slug header
- API: filter notebooks/notes/search by workspace on subdomains
- AppSwitcher: generate <username>.r*.online links when logged in
- Sessions: SubdomainSession component syncs auth across subdomains
  via .rnotes.online domain-wide cookie
- Auth: auto-migrate unscoped notebooks to user's workspace
- New /api/me endpoint for client-side auth + workspace state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:46:24 -08:00
Jeff Emmett 4eb24038b6 feat: add Alt+P keyboard shortcut for PiP pop-out
- Alt+P toggles Picture-in-Picture floating recorder on /voice page
- Works from both main window and PiP window
- Footer shows new shortcut hint when PiP is supported
- Browser extension Ctrl+Shift+V now opens PWA /voice page (with PiP)
  instead of extension-local voice.html

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:25:38 -08:00
Jeff Emmett a6ae90fd62 fix: dark background + emoji favicon for rStack design consistency
Standardize to dark background (#0f172a / slate-900) and add emoji
data URI favicon matching the rStack ecosystem.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:19:09 -08:00
Jeff Emmett be06e1f03e feat: add Picture-in-Picture pop-out to rVoice recorder
Adds a "Pop Out" button that opens a compact floating mini-recorder
using the Document Picture-in-Picture API. The floating window stays
on top of all other apps and includes: record/stop button, timer,
live transcript, copy/save/discard actions, and keyboard shortcuts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:16:21 -08:00
Jeff Emmett 1a01d698e0 feat: add install app + offline model download to rVoice page
Adds "Download app for offline use" button that triggers PWA install
prompt, then automatically starts downloading the Parakeet.js offline
transcription model (~634MB, cached in IndexedDB). Shows purple progress
bar during download. Header shows install/offline-mode/checkmark badges
based on current state. Idle screen shows contextual CTAs for install
or model download.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:10:53 -08:00
Jeff Emmett bf8d6d9d07 Merge dev: add rApp/Space switcher dropdowns to all headers
Resolves merge conflicts to keep both new features from main
(bodyJson, cardType, parent notes, OpenNotebookEmbed, attachments)
and the new shared Header with AppSwitcher + SpaceSwitcher dropdowns.
Also excludes scripts/ from tsconfig to fix pre-existing type errors
and regenerates Prisma client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:31:30 -08:00
Jeff Emmett 3232ced90f feat: add rApp and Space switcher dropdowns to all page headers
Replaces per-page inline navbars with a shared Header component that
includes AppSwitcher (18 rApps grouped by category) and SpaceSwitcher
(fetches user spaces from /api/spaces) dropdowns — matching the
rspace.online header pattern. All 9 pages updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:27:51 -08:00
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 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 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 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 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 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 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 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 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 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 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