diff --git a/backlog/tasks/task-2 - Phase-1-FolkJS-Foundation-Port-Simple-Shapes.md b/backlog/tasks/task-2 - Phase-1-FolkJS-Foundation-Port-Simple-Shapes.md new file mode 100644 index 0000000..066b3f6 --- /dev/null +++ b/backlog/tasks/task-2 - Phase-1-FolkJS-Foundation-Port-Simple-Shapes.md @@ -0,0 +1,37 @@ +--- +id: task-2 +title: 'Phase 1: FolkJS Foundation - Port Simple Shapes' +status: To Do +assignee: [] +created_date: '2026-01-02 14:42' +labels: + - foundation + - migration + - shapes +dependencies: [] +priority: high +--- + +## Description + + +Port the 4 simplest shapes from canvas-website to FolkJS web components: +- SlideShapeUtil (passive display) +- ChatBoxShapeUtil (real-time chat) +- GoogleItemShapeUtil (data display) +- SharedPianoShapeUtil (interactive music) + +Key simplifications vs tldraw: +- No BaseBoxShapeUtil inheritance, use FolkShape directly +- No React - pure web components with lit-style templates +- Hooks become class methods or standalone utilities +- StandardizedToolWrapper already ported as FolkWrapper + + +## Acceptance Criteria + +- [ ] #1 folk-slide component created +- [ ] #2 folk-chat component created +- [ ] #3 folk-google-item component created +- [ ] #4 folk-piano component created + diff --git a/backlog/tasks/task-3 - Phase-2-Core-Data-Shapes-Embed,-Markdown,-Calendar,-Map.md b/backlog/tasks/task-3 - Phase-2-Core-Data-Shapes-Embed,-Markdown,-Calendar,-Map.md new file mode 100644 index 0000000..70ebe9f --- /dev/null +++ b/backlog/tasks/task-3 - Phase-2-Core-Data-Shapes-Embed,-Markdown,-Calendar,-Map.md @@ -0,0 +1,46 @@ +--- +id: task-3 +title: 'Phase 2: Core Data Shapes - Embed, Markdown, Calendar, Map' +status: To Do +assignee: [] +created_date: '2026-01-02 14:42' +labels: + - migration + - shapes + - core +dependencies: [] +priority: high +--- + +## Description + + +Port medium-complexity shapes that form the core data visualization layer: + +1. **folk-embed** (565 LOC) - URL embeds (YouTube, Maps, Twitter) + - URL transformation patterns + - Interaction state management + +2. **folk-calendar** (644 LOC) - Unified calendar widget + - Browser/widget/year views + - Event detection from CalendarPanel/YearViewPanel + +3. **folk-map** (2,168 LOC - LARGEST) - Collaborative Mapbox/MapLibre + - Real-time presence cursors + - Drawing annotations (markers, lines, areas) + - Search via Nominatim, routing via OSRM + - GPS location sharing + +Simplifications: +- Replace React state with reactive properties +- Replace context providers with event-based communication +- Calendar/Map can be separate packages imported as needed + + +## Acceptance Criteria + +- [ ] #1 folk-embed component with URL detection +- [ ] #2 folk-calendar with month/year views +- [ ] #3 folk-map with MapLibre integration +- [ ] #4 Real-time presence on map working + diff --git a/backlog/tasks/task-4 - Phase-3-AI-Integration-Shapes.md b/backlog/tasks/task-4 - Phase-3-AI-Integration-Shapes.md new file mode 100644 index 0000000..33ea6c8 --- /dev/null +++ b/backlog/tasks/task-4 - Phase-3-AI-Integration-Shapes.md @@ -0,0 +1,52 @@ +--- +id: task-4 +title: 'Phase 3: AI Integration Shapes' +status: To Do +assignee: [] +created_date: '2026-01-02 15:54' +labels: + - migration + - shapes + - ai +dependencies: [] +priority: medium +--- + +## Description + + +Port AI-powered shapes using existing MCP servers and APIs: + +1. **folk-image-gen** - Image generation (fal.ai Flux) + - Prompt input, image history thread + - Loading states, error handling + - Uses: mcp__fal-ai__fal_generate_image + +2. **folk-video-gen** - Video generation (WAN 2.1) + - Image-to-video, text-to-video + - Duration control, queue polling + - Uses: mcp__fal-ai__fal_generate_video + +3. **folk-prompt** - LLM prompt executor + - Agent binding, multiple personalities + - Output streaming + - Uses: mcp__gemini__gemini_generate or direct Anthropic API + +4. **folk-transcription** - Audio transcription (Whisper) + - Real-time transcription, pause/resume + - Speaker diarization + - Uses: Web Speech API fallback + Whisper API + +Simplifications: +- Use MCP tools directly instead of custom API clients +- Simplify loading states to CSS classes +- Remove complex React hooks, use async/await patterns + + +## Acceptance Criteria + +- [ ] #1 folk-image-gen with fal.ai integration +- [ ] #2 folk-video-gen with video generation +- [ ] #3 folk-prompt with LLM streaming +- [ ] #4 folk-transcription with Whisper + diff --git a/backlog/tasks/task-5 - Phase-4-Advanced-Shapes-Video-Chat,-Notes,-Workflows.md b/backlog/tasks/task-5 - Phase-4-Advanced-Shapes-Video-Chat,-Notes,-Workflows.md new file mode 100644 index 0000000..868c84a --- /dev/null +++ b/backlog/tasks/task-5 - Phase-4-Advanced-Shapes-Video-Chat,-Notes,-Workflows.md @@ -0,0 +1,53 @@ +--- +id: task-5 +title: 'Phase 4: Advanced Shapes - Video Chat, Notes, Workflows' +status: To Do +assignee: [] +created_date: '2026-01-02 16:04' +labels: + - migration + - shapes + - advanced +dependencies: [] +priority: medium +--- + +## Description + + +Port remaining complex shapes: + +1. **folk-video-chat** - Video conferencing (Daily.co) + - Meeting creation, recording, permissions + - WebRTC integration + +2. **folk-obs-note** - Rich markdown from Obsidian + - MDX editing, vault sync + - Change detection, save/sync + +3. **folk-holon** - Holosphere node with H3 geo-indexing + - Hierarchical geospatial indexing + - Connection management + +4. **folk-workflow-block** - Visual workflow automation + - Typed input/output ports + - Connection support via folk-arrow + - Execution state visualization + +5. **folk-zine-generator** - AI zine creation + - 5-phase workflow + - Page generation with feedback loop + +Simplifications: +- Use existing folk-arrow for connections +- Workflows use event-based execution instead of complex state machines +- Obsidian sync can be optional/pluggable + + +## Acceptance Criteria + +- [ ] #1 folk-video-chat with Daily.co +- [ ] #2 folk-obs-note with markdown editing +- [ ] #3 folk-workflow-block with typed ports +- [ ] #4 Workflow execution via folk-arrow connections + diff --git a/backlog/tasks/task-6 - Mobile-touch-support-for-canvas.md b/backlog/tasks/task-6 - Mobile-touch-support-for-canvas.md new file mode 100644 index 0000000..a2db6b7 --- /dev/null +++ b/backlog/tasks/task-6 - Mobile-touch-support-for-canvas.md @@ -0,0 +1,34 @@ +--- +id: task-6 +title: Mobile touch support for canvas +status: To Do +assignee: [] +created_date: '2026-01-02 16:07' +labels: + - feature + - mobile + - ux +dependencies: [] +priority: medium +--- + +## Description + + +Enable touch interactions on mobile devices: +- Touch drag for moving shapes +- Pinch-to-zoom for canvas +- Two-finger pan for canvas navigation +- Touch-friendly resize handles (larger hit areas) +- Long-press for context menu + +FolkShape already has touchmove handler, needs enhancement for multi-touch gestures. + + +## Acceptance Criteria + +- [ ] #1 Single touch drag works on shapes +- [ ] #2 Pinch-to-zoom works on canvas +- [ ] #3 Two-finger pan works +- [ ] #4 Tested on iOS Safari and Android Chrome + diff --git a/backlog/tasks/task-7 - Real-time-presence-cursors.md b/backlog/tasks/task-7 - Real-time-presence-cursors.md new file mode 100644 index 0000000..b850834 --- /dev/null +++ b/backlog/tasks/task-7 - Real-time-presence-cursors.md @@ -0,0 +1,34 @@ +--- +id: task-7 +title: Real-time presence cursors +status: To Do +assignee: [] +created_date: '2026-01-02 16:08' +labels: + - feature + - collaboration + - sync +dependencies: [] +priority: medium +--- + +## Description + + +Show other users cursors and selections in real-time: +- Broadcast cursor position via WebSocket presence messages +- Display colored cursor with username label +- Show selection highlight when user has shape selected +- Fade out cursors after inactivity +- Different cursor colors per user + +WebSocket already handles presence messages (see server/index.ts line 221-235), needs client-side rendering. + + +## Acceptance Criteria + +- [ ] #1 Cursor position broadcasts on mousemove +- [ ] #2 Other users cursors visible with name labels +- [ ] #3 Selection state shared between users +- [ ] #4 Cursors fade after 5s inactivity + diff --git a/backlog/tasks/task-8 - Port-shared-hooks-as-FolkJS-utilities.md b/backlog/tasks/task-8 - Port-shared-hooks-as-FolkJS-utilities.md new file mode 100644 index 0000000..b51c229 --- /dev/null +++ b/backlog/tasks/task-8 - Port-shared-hooks-as-FolkJS-utilities.md @@ -0,0 +1,42 @@ +--- +id: task-8 +title: Port shared hooks as FolkJS utilities +status: To Do +assignee: [] +created_date: '2026-01-02 16:10' +labels: + - foundation + - utilities + - migration +dependencies: [] +priority: high +--- + +## Description + + +Convert canvas-website React hooks to FolkJS-compatible utilities: + +1. **useMaximize** → maximizeShape(shape) utility + - Store original dimensions + - Animate to viewport fill + - Restore on toggle + +2. **usePinnedToView** → PinnedViewManager class + - Keep shape fixed as camera moves + - Support multiple pin positions + - Zero-lag with requestAnimationFrame + +3. **Shape serialization** - toJSON/fromJSON pattern + - Already implemented in folk-markdown + - Standardize across all shapes + +These utilities enable the StandardizedToolWrapper features (maximize, pin, close) across all FolkJS shapes. + + +## Acceptance Criteria + +- [ ] #1 maximizeShape utility working +- [ ] #2 PinnedViewManager class working +- [ ] #3 All shapes have consistent toJSON/fromJSON + diff --git a/docs/MIGRATION-PLAN.md b/docs/MIGRATION-PLAN.md new file mode 100644 index 0000000..41e6929 --- /dev/null +++ b/docs/MIGRATION-PLAN.md @@ -0,0 +1,172 @@ +# Canvas-Website to FolkJS Migration Plan + +## Overview + +This document outlines the transition from canvas-website (React + tldraw) to rspace-online (FolkJS web components). The goal is to simplify the architecture while preserving core functionality. + +## Architecture Comparison + +| Aspect | canvas-website (tldraw) | rspace-online (FolkJS) | +|--------|------------------------|------------------------| +| **Framework** | React 18 + tldraw v3 | Web Components (Lit-style) | +| **State** | tldraw store + Jotai atoms | Reactive properties + Automerge | +| **Sync** | Cloudflare Durable Objects | WebSocket + Automerge CRDT | +| **Shapes** | BaseBoxShapeUtil classes | FolkShape subclasses | +| **Styling** | CSS-in-JS / CSS modules | CSS in template literals | +| **Hooks** | React hooks (9 shared) | Class methods + utilities | + +## Key Simplifications + +### 1. No React +- **Before**: JSX, useState, useEffect, useCallback, useMemo +- **After**: Template literals, reactive properties, event listeners + +### 2. No tldraw Abstraction Layer +- **Before**: BaseBoxShapeUtil, editor.updateShape(), shape migrations +- **After**: FolkShape base class, direct property updates, Automerge patches + +### 3. Simpler State Management +- **Before**: tldraw store → Automerge → tldraw store (bidirectional sync) +- **After**: FolkShape → Automerge → FolkShape (direct sync via CommunitySync) + +### 4. Web-Native APIs +- **Before**: React context providers for auth, notifications, file system +- **After**: Custom events, localStorage, native browser APIs + +## Shape Porting Pattern + +### tldraw Shape (Before) +```tsx +export class MyShapeUtil extends BaseBoxShapeUtil { + static type = 'my-shape' + + getDefaultProps(): MyShape['props'] { + return { w: 300, h: 200, content: '' } + } + + component(shape: MyShape) { + const { content } = shape.props + const handleChange = useCallback((e) => { + this.editor.updateShape({ id: shape.id, props: { content: e.target.value } }) + }, [shape.id]) + + return ( + + + + ` + // Event listeners... + return root + } +} +``` + +## Migration Phases + +### Phase 1: Foundation (4 shapes) +**Status**: To Do +- folk-slide (passive display) +- folk-chat (real-time chat) +- folk-google-item (data display) +- folk-piano (interactive music) + +### Phase 2: Core Data (4 shapes) +**Status**: To Do +- folk-embed (URL embeds) +- folk-markdown (already done!) +- folk-calendar (date picker + events) +- folk-map (Mapbox/MapLibre collaborative maps) + +### Phase 3: AI Integration (4 shapes) +**Status**: To Do +- folk-image-gen (fal.ai Flux) +- folk-video-gen (WAN 2.1) +- folk-prompt (LLM execution) +- folk-transcription (Whisper) + +### Phase 4: Advanced (5+ shapes) +**Status**: To Do +- folk-video-chat (Daily.co) +- folk-obs-note (Obsidian sync) +- folk-holon (H3 geo-indexing) +- folk-workflow-block (visual workflows) +- folk-zine-generator (AI zine creation) + +## Shared Utilities to Port + +| React Hook | FolkJS Equivalent | Status | +|------------|-------------------|--------| +| useMaximize | maximizeShape() utility | To Do | +| usePinnedToView | PinnedViewManager class | To Do | +| useCalendarEvents | CalendarService class | To Do | +| useWhisperTranscription | WhisperService class | To Do | +| useLiveImage | LiveImageService class | To Do | + +## Already Completed + +- [x] FolkShape base class with drag/resize/rotate +- [x] FolkMarkdown (markdown editing) +- [x] FolkWrapper (standardized header/actions) +- [x] FolkArrow (shape connections) +- [x] CommunitySync (Automerge integration) +- [x] Server with WebSocket sync +- [x] Subdomain routing for communities + +## External Dependencies + +### Keep (MCP or direct API) +- fal.ai (image/video gen) - via MCP +- Gemini (text gen) - via MCP +- MapLibre GL (maps) +- Daily.co (video chat) +- Whisper API (transcription) + +### Replace/Simplify +- MDXEditor → simpler markdown renderer (already done) +- tldraw → FolkJS (in progress) +- React contexts → custom events + services + +### Remove (tldraw-specific) +- BaseBoxShapeUtil +- Shape migrations +- tldraw editor commands +- tldraw store subscriptions + +## Success Criteria + +1. All 28 shapes ported to FolkJS web components +2. Real-time collaboration working via Automerge +3. Mobile touch support +4. Presence cursors showing other users +5. No React dependencies in runtime +6. Bundle size < 500KB (vs ~2MB current)