fix: switch all module shell themes from light to dark
The light theme was causing the header bar to render with a white background, clashing with the dark-themed module content underneath. All modules and both shell renderers now default to dark theme. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f84e45fc5a
commit
346b406b80
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
id: m-0
|
||||
title: "Canvas → rSpace Migration"
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Complete migration of all custom shapes and functionality from canvas-website (tldraw) to rspace-online (Web Components). rspace-online replaces canvas-website as the production platform.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
id: m-1
|
||||
title: "rSpace App Ecosystem"
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Transform rSpace from a flat shape canvas into a composable app ecosystem with data pipes, event broadcasting, semantic grouping, shape nesting, and cross-app embedding from the r-ecosystem (rWallet, rVote, rMaps, etc.).
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
id: TASK-21
|
||||
title: Offline-first support with IndexedDB persistence and Service Worker
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:39'
|
||||
labels:
|
||||
- feature
|
||||
- offline
|
||||
- infrastructure
|
||||
dependencies: []
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Added full offline-first capability to rSpace apps. Automerge documents and sync state now persist to IndexedDB via a new OfflineStore class, enabling instant load from cache, offline editing, and automatic incremental merge on reconnect. A Service Worker caches the app shell (HTML/JS/WASM) for loading without network.
|
||||
|
||||
## Changes
|
||||
- **lib/offline-store.ts** (new): IndexedDB wrapper storing Automerge doc binary + SyncState per community slug, with debounced saves
|
||||
- **lib/community-sync.ts**: Integrated offline persistence — initFromCache(), #scheduleSave(), #persistSyncState(), saveBeforeUnload(), infinite reconnect with capped backoff
|
||||
- **website/sw.ts** (new): Service Worker — cache-first for hashed assets, network-first for HTML, skip WS/API
|
||||
- **website/canvas.html**: SW registration, OfflineStore init, offline/online status UI, beforeunload save
|
||||
- **vite.config.ts**: build-sw plugin to produce dist/sw.js without content hash
|
||||
- **tsconfig.json**: Excluded sw.ts from main typecheck (WebWorker types)
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 IndexedDB persists Automerge doc binary per community slug
|
||||
- [ ] #2 Cached content loads instantly on page refresh (before WebSocket connects)
|
||||
- [ ] #3 Offline editing works — shapes can be created/moved/deleted without network
|
||||
- [ ] #4 Changes merge automatically on reconnect via Automerge sync protocol
|
||||
- [ ] #5 Service Worker caches HTML/JS/WASM for offline app shell loading
|
||||
- [ ] #6 Reconnect retries indefinitely (30s max backoff) when offline store is present
|
||||
- [ ] #7 beforeunload saves pending changes immediately
|
||||
<!-- AC:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Implemented offline-first support for rSpace. Created OfflineStore (IndexedDB wrapper) and Service Worker. Integrated into CommunitySync with debounced saves after every doc mutation, SyncState persistence for incremental reconnect, and infinite retry with capped backoff. Canvas UI shows offline/online status. Build produces dist/sw.js alongside main app. Pushed to Gitea main branch (6b06168).
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: TASK-22
|
||||
title: Add offline-first section to rSpace landing page
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:41'
|
||||
labels:
|
||||
- website
|
||||
- content
|
||||
dependencies: []
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Added an "Offline-First" feature card to the hero grid and a dedicated content section on the rSpace.online landing page explaining local IndexedDB persistence, Automerge auto-merge, and incremental sync. Matches existing visual style with pillars and identity cards.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Added 4th feature card (Offline-First) to hero grid, updated grid to 4 columns (2 on mobile), and added a new section with 3 pillars (Local Persistence, Auto-Merge, Incremental Sync) plus a "How it works" explanation card. Pushed to Gitea main (ea8f1b3).
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
id: TASK-23
|
||||
title: 'Feature parity audit: 13 overlapping shapes'
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:49'
|
||||
labels:
|
||||
- audit
|
||||
- phase-0
|
||||
milestone: m-0
|
||||
dependencies: []
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Compare each of the 13 shapes that exist in both canvas-website (tldraw) and rspace-online (folk-*) side-by-side. Document missing features in the rspace versions.
|
||||
|
||||
Pairs to audit:
|
||||
1. ChatBox ↔ folk-chat
|
||||
2. VideoChat ↔ folk-video-chat
|
||||
3. Embed ↔ folk-embed
|
||||
4. Markdown ↔ folk-markdown
|
||||
5. Slide ↔ folk-slide
|
||||
6. Prompt ↔ folk-prompt
|
||||
7. ObsNote ↔ folk-obs-note
|
||||
8. Transcription ↔ folk-transcription
|
||||
9. ImageGen ↔ folk-image-gen
|
||||
10. VideoGen ↔ folk-video-gen
|
||||
11. GoogleItem ↔ folk-google-item
|
||||
12. Map ↔ folk-map
|
||||
13. WorkflowBlock ↔ folk-workflow-block
|
||||
|
||||
For each pair: read both implementations, note feature gaps, classify as critical/nice-to-have.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 All 13 shape pairs compared side-by-side
|
||||
- [ ] #2 Feature gaps documented with severity (critical/nice-to-have)
|
||||
- [ ] #3 Critical gaps identified for immediate fix
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
id: TASK-24
|
||||
title: Add infrastructure dependencies for shape migration
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:49'
|
||||
labels:
|
||||
- infrastructure
|
||||
- phase-1
|
||||
milestone: m-0
|
||||
dependencies: []
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Install npm dependencies required by shapes being ported from canvas-website:
|
||||
- h3-js (HolonShape geospatial)
|
||||
- @xterm/xterm + @xterm/addon-fit (Multmux terminal)
|
||||
- safe-apps-sdk or ethers (TransactionBuilder, if needed)
|
||||
|
||||
Also verify existing deps like perfect-freehand are sufficient for Drawfast.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 All required npm packages installed
|
||||
- [ ] #2 No build errors after adding dependencies
|
||||
- [ ] #3 WASM plugins configured if needed (h3-js)
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
id: TASK-25
|
||||
title: Add server API proxy endpoints for new shapes
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:49'
|
||||
labels:
|
||||
- infrastructure
|
||||
- phase-1
|
||||
- server
|
||||
milestone: m-0
|
||||
dependencies: []
|
||||
references:
|
||||
- rspace-online/server/index.ts
|
||||
- canvas-website/src/shapes/ImageGenShapeUtil.tsx (API pattern reference)
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Add API routes to server/index.ts for shapes that call external services:
|
||||
- POST /api/blender-gen — Proxy to Blender generation service
|
||||
- POST /api/mycrozine — Proxy for zine generation LLM calls
|
||||
- POST /api/fathom/* — Proxy to Fathom API (meeting transcripts)
|
||||
- POST /api/obsidian/* — Local Obsidian vault file operations
|
||||
- POST /api/holon/* — HoloSphere network queries
|
||||
- WebSocket endpoint for terminal sessions (Multmux)
|
||||
|
||||
Follow existing pattern from /api/image-gen endpoint.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 All proxy endpoints return expected responses
|
||||
- [ ] #2 WebSocket terminal endpoint accepts connections
|
||||
- [ ] #3 Error handling and auth middleware applied
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
id: TASK-26
|
||||
title: Port folk-blender-gen shape (3D procedural generation)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:49'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-2
|
||||
- ai
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
- TASK-25
|
||||
references:
|
||||
- canvas-website/src/shapes/BlenderGenShapeUtil.tsx
|
||||
- rspace-online/lib/folk-image-gen.ts (pattern reference)
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port BlenderGenShapeUtil from canvas-website to rspace-online as a FolkShape Web Component.
|
||||
|
||||
Source: canvas-website/src/shapes/BlenderGenShapeUtil.tsx (693 lines)
|
||||
Target: rspace-online/lib/folk-blender-gen.ts
|
||||
|
||||
Features to implement:
|
||||
- Blender script editor textarea
|
||||
- LLM code generation (prompt → Blender Python script)
|
||||
- 3D preview iframe/canvas
|
||||
- Model download button
|
||||
- Loading/error states
|
||||
|
||||
Follow folk-image-gen.ts pattern for API-calling shape with loading/result states.
|
||||
Needs /api/blender-gen server endpoint (TASK-25).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Shape renders with script editor and 3D preview
|
||||
- [ ] #2 LLM code generation produces valid Blender scripts
|
||||
- [ ] #3 Results sync across clients via Automerge
|
||||
- [ ] #4 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
id: TASK-27
|
||||
title: Port folk-mycrozine-template shape (zine template picker)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-2
|
||||
- ai
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
references:
|
||||
- canvas-website/src/shapes/MycrozineTemplateShapeUtil.tsx
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port MycrozineTemplateShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/MycrozineTemplateShapeUtil.tsx (80 lines)
|
||||
Target: rspace-online/lib/folk-mycrozine-template.ts
|
||||
|
||||
Features: Template gallery picker, preview panel, template selection that launches MycroZineGenerator.
|
||||
Small shape — mostly a launcher UI for the generator.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Template gallery displays available templates
|
||||
- [ ] #2 Selecting a template creates/configures a MycroZineGenerator shape
|
||||
- [ ] #3 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
id: TASK-28
|
||||
title: Port folk-mycrozine-gen shape (AI zine generator)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-2
|
||||
- ai
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
- TASK-25
|
||||
references:
|
||||
- canvas-website/src/shapes/MycroZineGeneratorShapeUtil.tsx
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port MycroZineGeneratorShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/MycroZineGeneratorShapeUtil.tsx (1,222 lines)
|
||||
Target: rspace-online/lib/folk-mycrozine-gen.ts
|
||||
|
||||
Features to implement:
|
||||
- Prompt input for zine content
|
||||
- Style and layout settings UI
|
||||
- AI-powered multi-page zine generation via LLM
|
||||
- Page preview/navigation
|
||||
- Export/download functionality
|
||||
|
||||
Largest AI shape to port. Needs /api/mycrozine server endpoint (TASK-25).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Prompt input generates zine pages via LLM
|
||||
- [ ] #2 Multi-page navigation works
|
||||
- [ ] #3 Style/layout settings affect output
|
||||
- [ ] #4 Results sync across clients via Automerge
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
id: TASK-29
|
||||
title: Port folk-drawfast shape (collaborative drawing/gesture recognition)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-2
|
||||
- creative
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
references:
|
||||
- canvas-website/src/shapes/DrawfastShapeUtil.tsx
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port DrawfastShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/DrawfastShapeUtil.tsx (652 lines)
|
||||
Target: rspace-online/lib/folk-drawfast.ts
|
||||
|
||||
Features to implement:
|
||||
- Freehand sketch input canvas
|
||||
- Gesture recognition (circles, lines, rectangles, arrows)
|
||||
- Shape detection and conversion
|
||||
- Real-time collaborative drawing
|
||||
- May use perfect-freehand (already in rspace deps)
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Freehand drawing works with pointer/touch input
|
||||
- [ ] #2 Gesture recognition detects basic shapes
|
||||
- [ ] #3 Drawing state syncs across clients
|
||||
- [ ] #4 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
id: TASK-30
|
||||
title: Port folk-holon shape (H3 geospatial hex hierarchy)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-3
|
||||
- data-integration
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
- TASK-25
|
||||
references:
|
||||
- canvas-website/src/shapes/HolonShapeUtil.tsx
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port HolonShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/HolonShapeUtil.tsx (1,216 lines)
|
||||
Target: rspace-online/lib/folk-holon.ts
|
||||
|
||||
Features to implement:
|
||||
- H3 geospatial hexagonal hierarchy visualization
|
||||
- HoloSphere network connection (real-time)
|
||||
- Multi-lens data viewing (switch between data perspectives)
|
||||
- In-place editing with auto-resize
|
||||
- Location props: latitude, longitude, resolution
|
||||
- Content props: name, description, holonId
|
||||
- State: isConnected, isEditing, selectedLens, data, connections
|
||||
|
||||
Dependencies: h3-js (TASK-24), /api/holon/* endpoints (TASK-25)
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 H3 hex hierarchy renders correctly
|
||||
- [ ] #2 HoloSphere network connection works
|
||||
- [ ] #3 Multi-lens data switching functional
|
||||
- [ ] #4 Geospatial props sync across clients
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
id: TASK-31
|
||||
title: Port folk-holon-browser shape (Holon network browser)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-3
|
||||
- data-integration
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-30
|
||||
references:
|
||||
- canvas-website/src/shapes/HolonBrowserShapeUtil.tsx
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port HolonBrowserShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/HolonBrowserShapeUtil.tsx (202 lines)
|
||||
Target: rspace-online/lib/folk-holon-browser.ts
|
||||
|
||||
Features: Network visualization, search, filtering through Holon data. Companion to folk-holon — shares HoloSphere service client.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Browse/search Holon network data
|
||||
- [ ] #2 Visualization renders network graph
|
||||
- [ ] #3 Can open individual Holons from browser
|
||||
- [ ] #4 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
id: TASK-32
|
||||
title: Port folk-obsidian-browser shape (Obsidian vault explorer)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-3
|
||||
- data-integration
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-25
|
||||
references:
|
||||
- canvas-website/src/shapes/ObsidianBrowserShapeUtil.tsx
|
||||
- canvas-website/src/components/ObsidianVaultBrowser.tsx
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port ObsidianBrowserShapeUtil + ObsidianVaultBrowser component from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/ObsidianBrowserShapeUtil.tsx (413 lines) + canvas-website/src/components/ObsidianVaultBrowser.tsx (1,694 lines)
|
||||
Target: rspace-online/lib/folk-obsidian-browser.ts
|
||||
|
||||
Total: 2,107 lines — one of the largest ports.
|
||||
|
||||
Features to implement:
|
||||
- Obsidian vault file tree navigation
|
||||
- Full-text search across vault
|
||||
- Backlink preview and navigation
|
||||
- Note opening (creates folk-obs-note shapes)
|
||||
- Vault metadata display
|
||||
|
||||
Needs /api/obsidian/* server endpoints for local vault file operations (TASK-25).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 File tree renders vault directory structure
|
||||
- [ ] #2 Full-text search returns matching notes
|
||||
- [ ] #3 Backlink preview displays on hover/click
|
||||
- [ ] #4 Selecting a note creates folk-obs-note shape
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
id: TASK-33
|
||||
title: Port folk-fathom-browser shape (Fathom meetings integration)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-3
|
||||
- data-integration
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-25
|
||||
references:
|
||||
- canvas-website/src/shapes/FathomMeetingsBrowserShapeUtil.tsx
|
||||
- canvas-website/src/components/FathomMeetingsPanel.tsx
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port FathomMeetingsBrowserShapeUtil + FathomMeetingsPanel from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/FathomMeetingsBrowserShapeUtil.tsx (549 lines) + canvas-website/src/components/FathomMeetingsPanel.tsx (705 lines)
|
||||
Target: rspace-online/lib/folk-fathom-browser.ts
|
||||
|
||||
Features to implement:
|
||||
- Fathom API integration (meeting list, transcripts)
|
||||
- Meeting list with search/filter
|
||||
- Transcript search with speaker identification
|
||||
- Open individual meetings as folk-fathom-note shapes
|
||||
|
||||
Needs /api/fathom/* proxy endpoints (TASK-25).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Fathom API returns meeting list
|
||||
- [ ] #2 Search/filter meetings works
|
||||
- [ ] #3 Speaker identification displayed
|
||||
- [ ] #4 Selecting meeting creates folk-fathom-note
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
id: TASK-34
|
||||
title: Port folk-fathom-note shape (individual meeting note)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-3
|
||||
- data-integration
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-33
|
||||
references:
|
||||
- canvas-website/src/shapes/FathomNoteShapeUtil.tsx
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port FathomNoteShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/FathomNoteShapeUtil.tsx (667 lines)
|
||||
Target: rspace-online/lib/folk-fathom-note.ts
|
||||
|
||||
Features to implement:
|
||||
- Individual meeting note display
|
||||
- Speaker clips with timestamps
|
||||
- Timestamp linking (click to jump)
|
||||
- Note editing and annotation
|
||||
- Created by folk-fathom-browser when user selects a meeting
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Meeting note renders with transcript content
|
||||
- [ ] #2 Speaker clips display correctly
|
||||
- [ ] #3 Timestamp links navigate within transcript
|
||||
- [ ] #4 Note editing syncs across clients
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
id: TASK-35
|
||||
title: Port folk-multmux shape (xterm.js terminal emulator)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-4
|
||||
- dev-tools
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
- TASK-25
|
||||
references:
|
||||
- canvas-website/src/shapes/MultmuxShapeUtil.tsx
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port MultmuxShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/MultmuxShapeUtil.tsx (850 lines)
|
||||
Target: rspace-online/lib/folk-multmux.ts
|
||||
|
||||
Features to implement:
|
||||
- xterm.js terminal emulator in a shape
|
||||
- WebSocket session management with auto-reconnect
|
||||
- Session naming and persistence
|
||||
- Fit addon for responsive terminal sizing
|
||||
- Shape migration support (versioning)
|
||||
|
||||
Dependencies: @xterm/xterm, @xterm/addon-fit (TASK-24)
|
||||
Needs WebSocket terminal endpoint on server (TASK-25).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Terminal renders with xterm.js
|
||||
- [ ] #2 WebSocket connection to terminal session works
|
||||
- [ ] #3 Auto-reconnect on disconnect
|
||||
- [ ] #4 Session state persists across page reloads
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
id: TASK-36
|
||||
title: Port folk-private-workspace shape (data sovereignty zone)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:50'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-4
|
||||
- privacy
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
references:
|
||||
- canvas-website/src/shapes/PrivateWorkspaceShapeUtil.tsx
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port PrivateWorkspaceShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/PrivateWorkspaceShapeUtil.tsx (370 lines)
|
||||
Target: rspace-online/lib/folk-private-workspace.ts
|
||||
|
||||
Features to implement:
|
||||
- Data sovereignty container zone
|
||||
- Visibility badges (public/private indicators)
|
||||
- Private data compartmentalization
|
||||
- Works with existing folk-google-item shape
|
||||
- Drag-in/drag-out items to change privacy scope
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Workspace zone renders with privacy boundary
|
||||
- [ ] #2 Visibility badges display correctly
|
||||
- [ ] #3 Items inside zone respect privacy scope
|
||||
- [ ] #4 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
id: TASK-37
|
||||
title: Port folk-transaction-builder shape (Safe multisig)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:51'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-4
|
||||
- web3
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
references:
|
||||
- canvas-website/src/shapes/TransactionBuilderShapeUtil.tsx
|
||||
- canvas-website/src/components/safe/TransactionComposer.tsx
|
||||
- canvas-website/src/components/safe/PendingTransactions.tsx
|
||||
- canvas-website/src/components/safe/TransactionHistory.tsx
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port TransactionBuilderShapeUtil + Safe components from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/TransactionBuilderShapeUtil.tsx (157 lines) + canvas-website/src/components/safe/ (585 lines total: SafeHeader, TransactionComposer, PendingTransactions, TransactionHistory)
|
||||
Target: rspace-online/lib/folk-transaction-builder.ts
|
||||
|
||||
Features to implement:
|
||||
- Transaction composition UI (select recipient, amount, data)
|
||||
- Pending transaction queue display
|
||||
- Transaction history view
|
||||
- Mode switching: compose/pending/history
|
||||
- Safe wallet integration
|
||||
|
||||
May need safe-apps-sdk or ethers.js dependency (TASK-24).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Transaction composer creates valid transactions
|
||||
- [ ] #2 Pending queue displays waiting transactions
|
||||
- [ ] #3 History view shows past transactions
|
||||
- [ ] #4 Mode switching works (compose/pending/history)
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
id: TASK-38
|
||||
title: Port folk-calendar-event shape (calendar event sub-shape)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:51'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-4
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
references:
|
||||
- canvas-website/src/shapes/CalendarEventShapeUtil.tsx
|
||||
- rspace-online/lib/folk-calendar.ts
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port CalendarEventShapeUtil from canvas-website to rspace-online.
|
||||
|
||||
Source: canvas-website/src/shapes/CalendarEventShapeUtil.tsx (457 lines)
|
||||
Target: rspace-online/lib/folk-calendar-event.ts
|
||||
|
||||
Features to implement:
|
||||
- Individual calendar event display
|
||||
- Time/date formatting and display
|
||||
- Recurrence info visualization
|
||||
- Color coding by event type/calendar
|
||||
- Created by existing folk-calendar when user drags out an event
|
||||
|
||||
Companion to existing folk-calendar shape.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Event renders with title, time, and color
|
||||
- [ ] #2 Recurrence info displays correctly
|
||||
- [ ] #3 folk-calendar can create calendar-event shapes
|
||||
- [ ] #4 Event data syncs across clients
|
||||
- [ ] #5 Toolbar button added to canvas.html
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
id: TASK-39
|
||||
title: Port MycelialIntelligence system (global AI bar + shape)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:51'
|
||||
labels:
|
||||
- shape-port
|
||||
- phase-5
|
||||
- ai
|
||||
- infrastructure
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-25
|
||||
references:
|
||||
- canvas-website/src/ui/MycelialIntelligenceBar.tsx
|
||||
- canvas-website/src/shapes/MycelialIntelligenceShapeUtil.tsx
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port the MycelialIntelligence system from canvas-website to rspace-online. This is a GLOBAL UI element (not just a shape).
|
||||
|
||||
Sources:
|
||||
- canvas-website/src/ui/MycelialIntelligenceBar.tsx (2,231 lines) — the main AI bar
|
||||
- canvas-website/src/shapes/MycelialIntelligenceShapeUtil.tsx (69 lines) — backward-compat shape
|
||||
|
||||
Target: rspace-online/lib/mycelial-intelligence-bar.ts (Web Component) + rspace-online/lib/folk-mycelial-intelligence.ts (shape)
|
||||
|
||||
This is the largest single migration item. Implement in phases:
|
||||
|
||||
Phase A: Basic chat UI bar (fixed bottom bar with prompt input + response display)
|
||||
Phase B: Canvas context awareness (knows selected shapes, viewport contents)
|
||||
Phase C: Shape creation/modification via AI commands (create shapes, edit properties)
|
||||
Phase D: Full tool integration (all AI capabilities available through bar)
|
||||
|
||||
The bar should be added as a persistent element in canvas.html, independent of the shape system.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 AI bar renders as persistent bottom UI element
|
||||
- [ ] #2 Chat prompt sends to LLM and displays responses
|
||||
- [ ] #3 Bar is context-aware of selected shapes and canvas state
|
||||
- [ ] #4 Can create/modify shapes via AI commands
|
||||
- [ ] #5 Backward-compat folk-mycelial-intelligence shape exists
|
||||
- [ ] #6 Toolbar button toggles bar visibility
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
id: TASK-40
|
||||
title: Port workflow engine (propagators + execution)
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 19:51'
|
||||
labels:
|
||||
- infrastructure
|
||||
- phase-6
|
||||
- workflow
|
||||
milestone: m-0
|
||||
dependencies:
|
||||
- TASK-24
|
||||
references:
|
||||
- canvas-website/src/lib/workflow/
|
||||
- canvas-website/src/propagators/WorkflowPropagator.ts
|
||||
- canvas-website/src/propagators/ScopedPropagators.ts
|
||||
- rspace-online/lib/folk-workflow-block.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Port the workflow execution engine from canvas-website to rspace-online. This powers the existing folk-workflow-block shape with actual data flow and execution.
|
||||
|
||||
Source files (3,676 lines total):
|
||||
- canvas-website/src/lib/workflow/types.ts (159 lines) — type definitions
|
||||
- canvas-website/src/lib/workflow/blockRegistry.ts (438 lines) — block definition registry
|
||||
- canvas-website/src/lib/workflow/executor.ts (548 lines) — block execution engine
|
||||
- canvas-website/src/lib/workflow/portBindings.ts (464 lines) — port connection logic
|
||||
- canvas-website/src/lib/workflow/validation.ts (417 lines) — graph validation
|
||||
- canvas-website/src/lib/workflow/serialization.ts (571 lines) — save/load workflows
|
||||
- canvas-website/src/propagators/WorkflowPropagator.ts (326 lines) — real-time data flow
|
||||
|
||||
Target: rspace-online/lib/workflow/ directory
|
||||
|
||||
Key adaptation needed: canvas-website uses tldraw store for state; rspace-online uses Automerge. The execution engine needs to read/write shape data through CommunitySync instead of tldraw's store.
|
||||
|
||||
Also port relevant propagator concepts:
|
||||
- canvas-website/src/propagators/ScopedPropagators.ts (314 lines)
|
||||
- canvas-website/src/propagators/SpatialIndex.ts (164 lines)
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Block registry loads available block types
|
||||
- [ ] #2 Port connections transfer data between blocks
|
||||
- [ ] #3 Execution engine runs blocks in correct order
|
||||
- [ ] #4 Validation catches invalid graph configurations
|
||||
- [ ] #5 Workflows serialize/deserialize through Automerge
|
||||
- [ ] #6 Real-time propagation updates connected blocks
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
id: TASK-41
|
||||
title: Build dynamic Shape Registry to replace hardcoded switch statements
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 20:06'
|
||||
labels:
|
||||
- infrastructure
|
||||
- phase-0
|
||||
- ecosystem
|
||||
milestone: m-1
|
||||
dependencies: []
|
||||
references:
|
||||
- rspace-online/lib/folk-shape.ts
|
||||
- rspace-online/website/canvas.html
|
||||
- rspace-online/lib/community-sync.ts
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Replace the 170-line switch statement in canvas.html's `createShapeElement()` and the 100-line type-switch in community-sync.ts's `#updateShapeElement()` with a dynamic ShapeRegistry.
|
||||
|
||||
Create lib/shape-registry.ts with:
|
||||
- ShapeRegistration interface (tagName, elementClass, defaults, category, portDescriptors, eventDescriptors)
|
||||
- ShapeRegistry class with register(), createElement(), updateElement(), listAll(), getByCategory()
|
||||
- Each folk-*.ts gets a static `registration` property and static `fromData()` method
|
||||
|
||||
This is the prerequisite for all other ecosystem features (pipes, events, groups, nesting, embedding).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 ShapeRegistry class created with register/createElement/updateElement methods
|
||||
- [ ] #2 All 30+ folk-*.ts shapes have static registration property
|
||||
- [ ] #3 canvas.html switch statement replaced with registry.createElement()
|
||||
- [ ] #4 community-sync.ts type-switch replaced with registry.updateElement()
|
||||
- [ ] #5 All existing shapes still create and sync correctly
|
||||
- [ ] #6 No regression in shape creation or remote sync
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
id: TASK-42
|
||||
title: 'Implement Data Pipes: typed data flow through arrows'
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 20:06'
|
||||
labels:
|
||||
- feature
|
||||
- phase-1
|
||||
- ecosystem
|
||||
milestone: m-1
|
||||
dependencies:
|
||||
- TASK-41
|
||||
references:
|
||||
- rspace-online/lib/folk-arrow.ts
|
||||
- rspace-online/lib/folk-shape.ts
|
||||
- rspace-online/lib/folk-image-gen.ts
|
||||
- rspace-online/lib/folk-prompt.ts
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Transform folk-arrow from visual-only connector into a typed data conduit between shapes.
|
||||
|
||||
New file lib/data-types.ts:
|
||||
- DataType enum: string, number, boolean, image-url, video-url, text, json, trigger, any
|
||||
- Type compatibility matrix and isCompatible() function
|
||||
|
||||
Add port mixin to FolkShape:
|
||||
- ports map, getPort(), setPortValue(), onPortValueChanged()
|
||||
- Port values stored in Automerge: doc.shapes[id].ports[name].value
|
||||
- 100ms debounce on port propagation to prevent keystroke thrashing
|
||||
|
||||
Enhance folk-arrow:
|
||||
- sourcePort/targetPort fields referencing named ports
|
||||
- Listen for port-value-changed on source, push to target
|
||||
- Type compatibility check before pushing
|
||||
- Visual: arrows tinted by data type, flow animation when active
|
||||
- Port handle UI during connect mode
|
||||
|
||||
Add port descriptors to AI shapes:
|
||||
- folk-image-gen: input "prompt" (text), output "image" (image-url)
|
||||
- folk-video-gen: input "prompt" (text), input "image" (image-url), output "video" (video-url)
|
||||
- folk-prompt: input "context" (text), output "response" (text)
|
||||
- folk-transcription: output "transcript" (text)
|
||||
|
||||
Example pipeline: Transcription →[text]→ Prompt →[text]→ ImageGen →[image-url]→ VideoGen
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 DataType system with compatibility matrix works
|
||||
- [ ] #2 Shapes can declare input/output ports via registration
|
||||
- [ ] #3 setPortValue() writes to Automerge and dispatches event
|
||||
- [ ] #4 folk-arrow pipes data from source port to target port
|
||||
- [ ] #5 Type incompatible connections show warning
|
||||
- [ ] #6 Arrows visually indicate data type and active flow
|
||||
- [ ] #7 Port values sync to remote clients via Automerge
|
||||
- [ ] #8 100ms debounce prevents thrashing on rapid changes
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
id: TASK-43
|
||||
title: 'Implement Event Broadcasting: canvas-wide pub/sub system'
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 20:06'
|
||||
labels:
|
||||
- feature
|
||||
- phase-2
|
||||
- ecosystem
|
||||
milestone: m-1
|
||||
dependencies:
|
||||
- TASK-41
|
||||
references:
|
||||
- rspace-online/lib/community-sync.ts
|
||||
- rspace-online/server/community-store.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Add a pub/sub event system so shapes can broadcast and subscribe to named events across the canvas.
|
||||
|
||||
New file lib/event-bus.ts:
|
||||
- CanvasEventBus class with emit(), subscribe(), unsubscribe(), getSubscribers()
|
||||
- Events written to CRDT doc.eventLog (bounded ring buffer, last 100 entries)
|
||||
- Remote users see events replayed via Automerge patch application
|
||||
- Re-entrancy guard kills chains after 10 levels to prevent infinite loops
|
||||
|
||||
Automerge schema additions:
|
||||
- doc.eventLog: EventEntry[] (id, channel, sourceShapeId, payload, timestamp)
|
||||
- shapes[id].subscriptions: string[] (channel names)
|
||||
|
||||
Shapes opt in with onEventReceived(channel, payload) method.
|
||||
|
||||
Example: Timer emits "timer:done" → all subscribed Budget shapes recalculate.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 CanvasEventBus emits events to CRDT eventLog
|
||||
- [ ] #2 Shapes can subscribe to channels and receive events
|
||||
- [ ] #3 Events sync to remote users via Automerge
|
||||
- [ ] #4 Ring buffer bounded at 100 entries with GC
|
||||
- [ ] #5 Re-entrancy guard prevents infinite event loops
|
||||
- [ ] #6 Works offline (events queued in CRDT, replayed on reconnect)
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
id: TASK-44
|
||||
title: 'Implement Semantic Grouping: named shape clusters with templates'
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 20:06'
|
||||
labels:
|
||||
- feature
|
||||
- phase-3
|
||||
- ecosystem
|
||||
milestone: m-1
|
||||
dependencies:
|
||||
- TASK-41
|
||||
references:
|
||||
- rspace-online/lib/DOMRectTransform.ts
|
||||
- rspace-online/lib/community-sync.ts
|
||||
- rspace-online/server/community-store.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Add the ability to group shapes into named clusters that can be collapsed, moved together, and saved as reusable templates.
|
||||
|
||||
New file lib/group-manager.ts:
|
||||
- GroupManager class: createGroup(), dissolveGroup(), addToGroup(), removeFromGroup()
|
||||
- collapseGroup() / expandGroup() — hide members, show summary card
|
||||
- moveGroup(groupId, dx, dy) — moves all members by delta
|
||||
- saveAsTemplate() / instantiateTemplate() — serialize group as reusable JSON template
|
||||
|
||||
Automerge schema additions:
|
||||
- doc.groups: { [groupId]: GroupData } — top-level CRDT entity
|
||||
- GroupData: id, name, color, icon, memberShapeIds[], collapsed, x, y, width, height
|
||||
- shapes[id].groupId: string — which group a shape belongs to
|
||||
|
||||
Visual rendering:
|
||||
- folk-group-frame — lightweight overlay element (NOT a FolkShape), dashed border + header bar
|
||||
- Recalculates bounds from member shapes on each animation frame
|
||||
- Uses existing DOMRectTransform.ts for rotated shape bounding boxes
|
||||
- Collapse button, group name, color indicator
|
||||
|
||||
Canvas.html additions:
|
||||
- Rubber-band or shift-click multi-select → right-click "Group"
|
||||
- Group context menu (rename, change color, collapse, save as template, dissolve)
|
||||
- Template library panel for saved templates
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 GroupManager creates/dissolves groups stored in Automerge
|
||||
- [ ] #2 Moving group header moves all member shapes together
|
||||
- [ ] #3 Collapse hides members and shows summary card
|
||||
- [ ] #4 Expand restores all members to original positions
|
||||
- [ ] #5 Groups sync to remote users via Automerge
|
||||
- [ ] #6 Save as template serializes group + internal arrows as JSON
|
||||
- [ ] #7 Instantiate template creates new shapes from template
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
id: TASK-45
|
||||
title: 'Implement Shape Nesting: shapes containing shapes + recursive canvas'
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 20:06'
|
||||
labels:
|
||||
- feature
|
||||
- phase-4
|
||||
- ecosystem
|
||||
milestone: m-1
|
||||
dependencies:
|
||||
- TASK-44
|
||||
references:
|
||||
- rspace-online/lib/folk-shape.ts
|
||||
- rspace-online/lib/community-sync.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Allow shapes to contain other shapes, including a recursive canvas shape.
|
||||
|
||||
Automerge schema additions (flat references, NOT nested objects):
|
||||
- shapes[id].parentId: string — nested inside this shape
|
||||
- shapes[id].childIds: string[] — contains these shapes
|
||||
|
||||
New shape lib/folk-canvas.ts:
|
||||
- A shape that IS a canvas — renders child shapes inside scrollable/zoomable container
|
||||
- Optional linkedCommunitySlug to show shapes from another community (cross-canvas embedding)
|
||||
- Own zoom/pan controls within the mini-canvas
|
||||
|
||||
Coordinate system:
|
||||
- Children store ABSOLUTE canvas coordinates in CRDT (simplifies sync, prevents jitter)
|
||||
- folk-canvas applies CSS transform offset so children appear inside it
|
||||
- When parent moves, nesting manager applies delta to all children
|
||||
- Nesting is a render-time concern, not a data-model concern
|
||||
|
||||
FolkShape additions:
|
||||
- parentShape getter, childShapes getter
|
||||
- addChild(), removeChild()
|
||||
- toParentCoords(), toCanvasCoords() for coordinate transforms
|
||||
|
||||
Canvas.html: drag-drop shape onto folk-canvas to nest it.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Shapes can be nested inside folk-canvas via drag-drop
|
||||
- [ ] #2 Nested shapes move with parent when parent is moved
|
||||
- [ ] #3 folk-canvas has its own zoom/pan controls
|
||||
- [ ] #4 parentId/childIds sync correctly via Automerge
|
||||
- [ ] #5 Un-nesting a shape restores it to top-level canvas
|
||||
- [ ] #6 No coordinate jitter when two users move parent and child simultaneously
|
||||
- [ ] #7 Optional cross-canvas linking via linkedCommunitySlug
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
id: TASK-46
|
||||
title: 'Implement Cross-App Embedding: r-ecosystem apps in rSpace canvases'
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-02-18 20:07'
|
||||
labels:
|
||||
- feature
|
||||
- phase-5
|
||||
- ecosystem
|
||||
milestone: m-1
|
||||
dependencies:
|
||||
- TASK-41
|
||||
- TASK-42
|
||||
references:
|
||||
- rspace-online/lib/shape-registry.ts
|
||||
- rspace-online/server/index.ts
|
||||
- rspace-online/website/canvas.html
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Allow r-ecosystem apps (rWallet, rVote, rMaps, etc.) to embed their live UI into rSpace canvases via dynamically loaded Web Components.
|
||||
|
||||
Ecosystem App Manifest Protocol:
|
||||
- Each app hosts /.well-known/rspace-manifest.json
|
||||
- Manifest declares: appId, name, icon, moduleUrl, shapes[] (tagName, defaults, portDescriptors, eventDescriptors)
|
||||
|
||||
New file lib/ecosystem-bridge.ts:
|
||||
- EcosystemBridge class: loadManifest(), loadModule(), createSandboxedEmbed()
|
||||
- Two embedding modes:
|
||||
1. Trusted (Web Component): dynamic import(), shares CRDT directly, full port/event access
|
||||
2. Sandboxed (iframe): postMessage bridge for untrusted apps, limited API
|
||||
|
||||
New Automerge shape type:
|
||||
- type: "ecosystem-embed", appId, moduleUrl, config, sandboxed boolean
|
||||
|
||||
Server additions:
|
||||
- GET /api/ecosystem/:appId/manifest — proxy to avoid CORS
|
||||
- Server pre-fetches and caches ecosystem manifests
|
||||
|
||||
Canvas.html additions:
|
||||
- Dynamic toolbar section for ecosystem apps (loaded from manifests)
|
||||
- Lazy module loading on first use
|
||||
- Service Worker caches modules for offline
|
||||
|
||||
Runtime:
|
||||
1. Server fetches ecosystem manifests → toolbar shows app buttons
|
||||
2. User adds ecosystem shape → module import()-ed → Web Component registered → shape created
|
||||
3. Remote sync: create-shape for ecosystem-embed triggers lazy module load on other clients
|
||||
4. Embedded components participate in port/event system like native shapes
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Ecosystem manifest protocol defined and documented
|
||||
- [ ] #2 EcosystemBridge loads manifests and dynamic imports modules
|
||||
- [ ] #3 Trusted Web Components share CRDT and port/event system
|
||||
- [ ] #4 Sandboxed iframe mode works with postMessage bridge
|
||||
- [ ] #5 Server proxy avoids CORS for manifest/module loading
|
||||
- [ ] #6 Toolbar dynamically shows ecosystem app buttons
|
||||
- [ ] #7 Remote clients lazy-load modules when ecosystem shapes appear
|
||||
- [ ] #8 Service Worker caches ecosystem modules for offline
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
id: TASK-48
|
||||
title: Fix TypeScript build errors blocking deployment
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-02-24 03:51'
|
||||
labels:
|
||||
- bugfix
|
||||
- typescript
|
||||
- build
|
||||
dependencies: []
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Resolved all TypeScript compilation errors that were preventing `npm run build` from succeeding on the server. The build command `tsc --noEmit && vite build` was failing with ~50 errors across multiple modules.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 tsc --noEmit passes with zero errors
|
||||
- [ ] #2 vite build completes successfully
|
||||
- [ ] #3 Docker build and deploy succeeds on Netcup
|
||||
<!-- AC:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Fixed ~50 TypeScript errors across the codebase:\n\n- **9 modules** (cal, cart, forum, inbox, notes, providers, trips, vote, work): Changed `unknown[]` → `any[]` for `sql.unsafe()` parameter arrays. The postgres.js `ParameterOrJSON<never>` type was too restrictive when no custom types are defined.\n- **website/sw.ts**: Excluded from tsconfig — service worker needs WebWorker types, not DOM types, and is built separately by Vite.\n- **src/lib/demo-sync.ts**: Excluded from tsconfig — React hook for external consumers, React not a project dependency.\n- **modules/splat**: Fixed Hono context `c.get()` typing via cast, `instanceof File` via `unknown` cast, and inline sql.unsafe arrays.\n- **modules/swag/folk-swag-designer.ts**: Renamed `private title` → `private designTitle` to avoid collision with `HTMLElement.title`.\n- **types/gaussian-splats-3d.d.ts**: Added type declaration stub for CDN-loaded package.\n\nCommit: b2f1beb on main. Deployed to Netcup successfully.
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
id: TASK-49
|
||||
title: Add admin dashboard at /admin with space overview
|
||||
status: Done
|
||||
assignee:
|
||||
- '@claude'
|
||||
created_date: '2026-02-24 23:29'
|
||||
labels:
|
||||
- feature
|
||||
- admin
|
||||
- frontend
|
||||
dependencies: []
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Added an admin dashboard page at /admin that shows all rSpace spaces with detailed stats including shape count, member count, file size on disk, visibility, creation date, and owner DID. Includes search, filter by visibility, and sort controls. Also added /api/spaces/admin API endpoint returning all space data.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Admin page accessible at /admin
|
||||
- [ ] #2 Shows all spaces with shape count, member count, file size
|
||||
- [ ] #3 Search bar filters by name/slug/owner
|
||||
- [ ] #4 Visibility filter buttons work
|
||||
- [ ] #5 Sort dropdown works (date, name, shapes, size)
|
||||
- [ ] #6 API endpoint at /api/spaces/admin returns detailed space data
|
||||
- [ ] #7 Vite build includes admin.html
|
||||
- [ ] #8 Consistent styling with existing rSpace dark theme
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
---
|
||||
id: TASK-50
|
||||
title: Implement nested spaces architecture with permission cascade
|
||||
status: Done
|
||||
assignee:
|
||||
- '@claude'
|
||||
created_date: '2026-02-25 02:27'
|
||||
updated_date: '2026-02-25 02:43'
|
||||
labels:
|
||||
- architecture
|
||||
- spaces
|
||||
- permissions
|
||||
- encryptid
|
||||
dependencies: []
|
||||
references:
|
||||
- server/community-store.ts
|
||||
- server/spaces.ts
|
||||
- src/encryptid/server.ts
|
||||
- lib/community-sync.ts
|
||||
documentation:
|
||||
- docs/SPACE-ARCHITECTURE.md
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Spaces are now nestable — any space can embed references to other spaces via SpaceRef, with a permission cascade model (most-restrictive-wins at each nesting boundary). Every EncryptID registration auto-provisions a sovereign space at <username>.rspace.online with consent-based nesting controls.
|
||||
|
||||
Core principle: a space is a space is a space. No type field distinguishing personal vs community. The "personal" quality emerges from ownership + permissions, not a schema distinction.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 NestPolicy type with consent levels (open/members/approval/closed)
|
||||
- [ ] #2 SpaceRef CRUD endpoints on /api/spaces/:slug/nest
|
||||
- [ ] #3 Permission cascade via intersection (most-restrictive-wins)
|
||||
- [ ] #4 Approval flow for nest requests with admin review
|
||||
- [ ] #5 Source space admins can always revoke nestings (sovereignty guarantee)
|
||||
- [ ] #6 Auto-provision <username>.rspace.online on EncryptID registration
|
||||
- [ ] #7 defaultPermissions ceiling caps requested permissions
|
||||
- [ ] #8 Allowlist/blocklist per space
|
||||
- [ ] #9 Reverse lookup (nested-in) endpoint
|
||||
- [ ] #10 Client-side types for nested space rendering
|
||||
- [ ] #11 TypeScript compiles clean
|
||||
- [ ] #12 Full architecture spec at docs/SPACE-ARCHITECTURE.md
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
Phase 3-5 implemented and pushed to dev:
|
||||
- Phase 3: folk-canvas nested space shape with live WS, auto-scaling, collapsed/expanded views
|
||||
- Phase 4: WS cascade enforcement — nest filter on broadcasts, addShapes/deleteShapes checks
|
||||
- Phase 5: AES-256-GCM at-rest encryption with transparent encrypt/decrypt and API endpoints
|
||||
- All phases type-check clean (npx tsc --noEmit)
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
## Phase 1+2 Implementation Complete
|
||||
|
||||
### Schema changes (community-store.ts)
|
||||
- New types: NestPermissions, NestNotifications, NestPolicy, SpaceRef, SpaceRefFilter, PendingNestRequest
|
||||
- Default policies: DEFAULT_USER_NEST_POLICY (approval consent) and DEFAULT_COMMUNITY_NEST_POLICY (members consent)
|
||||
- Updated CommunityMeta with enabledModules, description, avatar, nestPolicy, encrypted fields
|
||||
- Updated CommunityDoc with nestedSpaces map
|
||||
- CRUD: addNestedSpace, updateNestedSpace, removeNestedSpace, getNestPolicy, updateNestPolicy, setEnabledModules
|
||||
- Permission logic: capPermissions (ceiling), cascadePermissions (intersection)
|
||||
- Reverse lookup: findNestedIn
|
||||
|
||||
### REST API (spaces.ts)
|
||||
- GET/PATCH /:slug/nest-policy
|
||||
- GET/POST /:slug/nest (with full consent flow)
|
||||
- GET/PATCH/DELETE /:slug/nest/:refId
|
||||
- GET /:slug/nested-in
|
||||
- GET/PATCH /:slug/nest-requests (approval flow)
|
||||
|
||||
### Auto-provisioning (encryptid/server.ts)
|
||||
- After registration, creates <username>.rspace.online with members_only visibility, user nest policy, default modules
|
||||
|
||||
### Remaining phases
|
||||
- Phase 3: folk-canvas shape renderer for SpaceRef entries
|
||||
- Phase 4: Full cascade enforcement on WebSocket writes
|
||||
- Phase 5: Encryption integration
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
|
|
@ -223,7 +223,7 @@ routes.get("/", async (c) => {
|
|||
<folk-book-shelf id="shelf"></folk-book-shelf>
|
||||
`,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
head: `<link rel="stylesheet" href="/modules/books/books.css">`,
|
||||
scripts: `
|
||||
<script type="module">
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "cal",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/cal/cal.css">`,
|
||||
body: `<folk-calendar-view space="${space}"></folk-calendar-view>`,
|
||||
scripts: `<script type="module" src="/modules/cal/folk-calendar-view.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ routes.get("/", async (c) => {
|
|||
spaceSlug,
|
||||
body: canvasBody,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
scripts: `<script type="module" src="/canvas-module.js"></script>`,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -446,7 +446,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "cart",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/cart/cart.css">`,
|
||||
body: `<folk-cart-shop></folk-cart-shop>`,
|
||||
scripts: `<script type="module" src="/modules/cart/folk-cart-shop.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "choices",
|
||||
spaceSlug,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/choices/choices.css">`,
|
||||
body: `<folk-choices-dashboard space="${spaceSlug}"></folk-choices-dashboard>`,
|
||||
scripts: `<script type="module" src="/modules/choices/folk-choices-dashboard.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "data",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/data/data.css">`,
|
||||
body: `<folk-analytics-view space="${space}"></folk-analytics-view>`,
|
||||
scripts: `<script type="module" src="/modules/data/folk-analytics-view.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "files",
|
||||
spaceSlug,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/files/files.css">`,
|
||||
body: `<folk-file-browser space="${spaceSlug}"></folk-file-browser>`,
|
||||
scripts: `<script type="module" src="/modules/files/folk-file-browser.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "forum",
|
||||
spaceSlug,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/forum/forum.css">`,
|
||||
body: `<folk-forum-dashboard space="${spaceSlug}"></folk-forum-dashboard>`,
|
||||
scripts: `<script type="module" src="/modules/forum/folk-forum-dashboard.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "funds",
|
||||
spaceSlug,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: fundsStyles,
|
||||
body: `<folk-funds-app space="${spaceSlug}"></folk-funds-app>`,
|
||||
scripts: fundsScripts,
|
||||
|
|
@ -216,7 +216,7 @@ routes.get("/demo", (c) => {
|
|||
moduleId: "funds",
|
||||
spaceSlug,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: fundsStyles,
|
||||
body: `<folk-funds-app space="${spaceSlug}" mode="demo"></folk-funds-app>`,
|
||||
scripts: fundsScripts,
|
||||
|
|
@ -232,7 +232,7 @@ routes.get("/flow/:flowId", (c) => {
|
|||
moduleId: "funds",
|
||||
spaceSlug,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: fundsStyles,
|
||||
body: `<folk-funds-app space="${spaceSlug}" flow-id="${flowId}"></folk-funds-app>`,
|
||||
scripts: fundsScripts,
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "inbox",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/inbox/inbox.css">`,
|
||||
body: `<folk-inbox-client space="${space}"></folk-inbox-client>`,
|
||||
scripts: `<script type="module" src="/modules/inbox/folk-inbox-client.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "maps",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/maps/maps.css">`,
|
||||
body: `<folk-map-viewer space="${space}"></folk-map-viewer>`,
|
||||
scripts: `<script type="module" src="/modules/maps/folk-map-viewer.js"></script>`,
|
||||
|
|
@ -154,7 +154,7 @@ routes.get("/:room", (c) => {
|
|||
moduleId: "maps",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/maps/maps.css">`,
|
||||
body: `<folk-map-viewer space="${space}" room="${room}"></folk-map-viewer>`,
|
||||
scripts: `<script type="module" src="/modules/maps/folk-map-viewer.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "network",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/network/network.css">`,
|
||||
body: `<folk-graph-viewer space="${space}"></folk-graph-viewer>`,
|
||||
scripts: `<script type="module" src="/modules/network/folk-graph-viewer.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "notes",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/notes/notes.css">`,
|
||||
body: `<folk-notes-app space="${space}"></folk-notes-app>`,
|
||||
scripts: `<script type="module" src="/modules/notes/folk-notes-app.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "providers",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/providers/providers.css">`,
|
||||
body: `<folk-provider-directory></folk-provider-directory>`,
|
||||
scripts: `<script type="module" src="/modules/providers/folk-provider-directory.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ routes.get("/", async (c) => {
|
|||
<folk-pubs-editor id="editor"></folk-pubs-editor>
|
||||
`,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
head: `<link rel="stylesheet" href="/modules/pubs/pubs.css">`,
|
||||
scripts: `
|
||||
<script type="module">
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "swag",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/swag/swag.css">`,
|
||||
body: `<folk-swag-designer></folk-swag-designer>`,
|
||||
scripts: `<script type="module" src="/modules/swag/folk-swag-designer.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ routes.get("/routes", (c) => {
|
|||
moduleId: "trips",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/trips/route-planner.css">`,
|
||||
body: `<folk-route-planner></folk-route-planner>`,
|
||||
scripts: `<script type="module" src="/modules/trips/folk-route-planner.js"></script>`,
|
||||
|
|
@ -258,7 +258,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "trips",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/trips/trips.css">`,
|
||||
body: `<folk-trips-planner space="${space}"></folk-trips-planner>`,
|
||||
scripts: `<script type="module" src="/modules/trips/folk-trips-planner.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "tube",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/tube/tube.css">`,
|
||||
body: `<folk-video-player space="${space}"></folk-video-player>`,
|
||||
scripts: `<script type="module" src="/modules/tube/folk-video-player.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "vote",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/vote/vote.css">`,
|
||||
body: `<folk-vote-dashboard space="${space}"></folk-vote-dashboard>`,
|
||||
scripts: `<script type="module" src="/modules/vote/folk-vote-dashboard.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "wallet",
|
||||
spaceSlug,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/wallet/wallet.css">`,
|
||||
body: `<folk-wallet-viewer space="${spaceSlug}"></folk-wallet-viewer>`,
|
||||
scripts: `<script type="module" src="/modules/wallet/folk-wallet-viewer.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ routes.get("/", (c) => {
|
|||
moduleId: "work",
|
||||
spaceSlug: space,
|
||||
modules: getModuleInfoList(),
|
||||
theme: "light",
|
||||
theme: "dark",
|
||||
styles: `<link rel="stylesheet" href="/modules/work/work.css">`,
|
||||
body: `<folk-work-board space="${space}"></folk-work-board>`,
|
||||
scripts: `<script type="module" src="/modules/work/folk-work-board.js"></script>`,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
"@aws-sdk/client-s3": "^3.700.0",
|
||||
"@encryptid/sdk": "file:../encryptid-sdk",
|
||||
"@lit/reactive-element": "^2.0.4",
|
||||
"@x402/core": "^2.3.1",
|
||||
"@x402/evm": "^2.3.1",
|
||||
"hono": "^4.11.7",
|
||||
"imapflow": "^1.0.170",
|
||||
"mailparser": "^3.7.2",
|
||||
|
|
@ -58,6 +60,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@adraffy/ens-normalize": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz",
|
||||
"integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@automerge/automerge": {
|
||||
"version": "2.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@automerge/automerge/-/automerge-2.2.9.tgz",
|
||||
|
|
@ -1845,6 +1854,43 @@
|
|||
"@lit-labs/ssr-dom-shim": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/ciphers": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz",
|
||||
"integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
|
||||
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/hashes": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
|
||||
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@pinojs/redact": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz",
|
||||
|
|
@ -2219,6 +2265,81 @@
|
|||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@scure/base": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
|
||||
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz",
|
||||
"integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/curves": "~1.9.0",
|
||||
"@noble/hashes": "~1.8.0",
|
||||
"@scure/base": "~1.2.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32/node_modules/@noble/curves": {
|
||||
"version": "1.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz",
|
||||
"integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip39": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz",
|
||||
"integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "~1.8.0",
|
||||
"@scure/base": "~1.2.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip39/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@selderee/plugin-htmlparser2": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
|
||||
|
|
@ -2964,6 +3085,49 @@
|
|||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@spruceid/siwe-parser": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@spruceid/siwe-parser/-/siwe-parser-2.1.2.tgz",
|
||||
"integrity": "sha512-d/r3S1LwJyMaRAKQ0awmo9whfXeE88Qt00vRj91q5uv5ATtWIQEGJ67Yr5eSZw5zp1/fZCXZYuEckt8lSkereQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.1.2",
|
||||
"apg-js": "^4.3.0",
|
||||
"uri-js": "^4.4.1",
|
||||
"valid-url": "^1.0.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/binary": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz",
|
||||
"integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stablelib/int": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/int": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz",
|
||||
"integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@stablelib/random": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.2.tgz",
|
||||
"integrity": "sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stablelib/binary": "^1.0.1",
|
||||
"@stablelib/wipe": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/wipe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz",
|
||||
"integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@swc/core": {
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz",
|
||||
|
|
@ -3235,6 +3399,42 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@x402/core": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@x402/core/-/core-2.4.0.tgz",
|
||||
"integrity": "sha512-g4K5dAVjevQftxCcpFlUDjO2AHE43FkO43VxwLCQ8ET3ki4aj2fzCcgvnXEj2eloJoocFS/Evt4pSTnP/4cFJw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@x402/evm": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@x402/evm/-/evm-2.4.0.tgz",
|
||||
"integrity": "sha512-k9qIEhJ5m8jZLPA44hcLEP9I1WC8nF375A7pX/3XGPA+H2UPUoY8fzBaQA2U+4lMv/eIyfz05klSj/8LzP1saA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@x402/core": "~2.4.0",
|
||||
"@x402/extensions": "~2.4.0",
|
||||
"viem": "^2.39.3",
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@x402/extensions": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@x402/extensions/-/extensions-2.4.0.tgz",
|
||||
"integrity": "sha512-tg/mSAS+NgwUaOdjt8agSjVkO1s9NYy+kSPubVlZf/Fy884qu7dSW81Ixu1NRYEz+vBk0rtz6b+eEvS0v72tMQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scure/base": "^1.2.6",
|
||||
"@x402/core": "~2.4.0",
|
||||
"ajv": "^8.17.1",
|
||||
"siwe": "^2.3.2",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"viem": "^2.43.5",
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@zone-eu/mailsplit": {
|
||||
"version": "5.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@zone-eu/mailsplit/-/mailsplit-5.4.8.tgz",
|
||||
|
|
@ -3246,6 +3446,56 @@
|
|||
"libqp": "2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/abitype": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz",
|
||||
"integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/wevm"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.4",
|
||||
"zod": "^3.22.0 || ^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
},
|
||||
"zod": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/aes-js": {
|
||||
"version": "4.0.0-beta.5",
|
||||
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz",
|
||||
"integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
"json-schema-traverse": "^1.0.0",
|
||||
"require-from-string": "^2.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/apg-js": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/apg-js/-/apg-js-4.4.0.tgz",
|
||||
"integrity": "sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==",
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/atomic-sleep": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
|
||||
|
|
@ -3448,6 +3698,87 @@
|
|||
"@esbuild/win32-x64": "0.25.12"
|
||||
}
|
||||
},
|
||||
"node_modules/ethers": {
|
||||
"version": "6.16.0",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz",
|
||||
"integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/ethers-io/"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://www.buymeacoffee.com/ricmoo"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@adraffy/ens-normalize": "1.10.1",
|
||||
"@noble/curves": "1.2.0",
|
||||
"@noble/hashes": "1.3.2",
|
||||
"@types/node": "22.7.5",
|
||||
"aes-js": "4.0.0-beta.5",
|
||||
"tslib": "2.7.0",
|
||||
"ws": "8.17.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ethers/node_modules/@types/node": {
|
||||
"version": "22.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
|
||||
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/ethers/node_modules/tslib": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
|
||||
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
|
||||
"license": "0BSD",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ethers/node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/fast-xml-parser": {
|
||||
"version": "5.3.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz",
|
||||
|
|
@ -3621,6 +3952,27 @@
|
|||
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/isows": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz",
|
||||
"integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wevm"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"ws": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/leac": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
|
||||
|
|
@ -3743,6 +4095,69 @@
|
|||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ox": {
|
||||
"version": "0.12.4",
|
||||
"resolved": "https://registry.npmjs.org/ox/-/ox-0.12.4.tgz",
|
||||
"integrity": "sha512-+P+C7QzuwPV8lu79dOwjBKfB2CbnbEXe/hfyyrff1drrO1nOOj3Hc87svHfcW1yneRr3WXaKr6nz11nq+/DF9Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wevm"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@adraffy/ens-normalize": "^1.11.0",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/curves": "1.9.1",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"@scure/bip32": "^1.7.0",
|
||||
"@scure/bip39": "^1.6.0",
|
||||
"abitype": "^1.2.3",
|
||||
"eventemitter3": "5.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/ox/node_modules/@adraffy/ens-normalize": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz",
|
||||
"integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ox/node_modules/@noble/curves": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz",
|
||||
"integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/ox/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/parseley": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz",
|
||||
|
|
@ -3895,6 +4310,15 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode.js": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
|
|
@ -3919,6 +4343,15 @@
|
|||
"node": ">= 12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-from-string": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.58.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.58.0.tgz",
|
||||
|
|
@ -4051,6 +4484,21 @@
|
|||
"is-arrayish": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/siwe": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/siwe/-/siwe-2.3.2.tgz",
|
||||
"integrity": "sha512-aSf+6+Latyttbj5nMu6GF3doMfv2UYj83hhwZgUF20ky6fTS83uVhkQABdIVnEuS8y1bBdk7p6ltb9SmlhTTlA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@spruceid/siwe-parser": "^2.1.2",
|
||||
"@stablelib/random": "^1.0.1",
|
||||
"uri-js": "^4.4.1",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ethers": "^5.6.8 || ^6.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/smart-buffer": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||
|
|
@ -4159,11 +4607,17 @@
|
|||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tweetnacl": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
|
||||
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
|
||||
"license": "Unlicense"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
|
@ -4186,6 +4640,15 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
|
|
@ -4199,6 +4662,89 @@
|
|||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/valid-url": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
|
||||
"integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA=="
|
||||
},
|
||||
"node_modules/viem": {
|
||||
"version": "2.46.3",
|
||||
"resolved": "https://registry.npmjs.org/viem/-/viem-2.46.3.tgz",
|
||||
"integrity": "sha512-2LJS+Hyh2sYjHXQtzfv1kU9pZx9dxFzvoU/ZKIcn0FNtOU0HQuIICuYdWtUDFHaGXbAdVo8J1eCvmjkL9JVGwg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wevm"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/curves": "1.9.1",
|
||||
"@noble/hashes": "1.8.0",
|
||||
"@scure/bip32": "1.7.0",
|
||||
"@scure/bip39": "1.6.0",
|
||||
"abitype": "1.2.3",
|
||||
"isows": "1.0.7",
|
||||
"ox": "0.12.4",
|
||||
"ws": "8.18.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/viem/node_modules/@noble/curves": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz",
|
||||
"integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/viem/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/viem/node_modules/ws": {
|
||||
"version": "8.18.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
||||
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
|
||||
|
|
@ -4313,6 +4859,37 @@
|
|||
"peerDependencies": {
|
||||
"vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.25.76",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export function renderShell(opts: ShellOptions): string {
|
|||
scripts = "",
|
||||
styles = "",
|
||||
modules,
|
||||
theme = "light",
|
||||
theme = "dark",
|
||||
head = "",
|
||||
} = opts;
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ export function renderStandaloneShell(opts: {
|
|||
theme?: "dark" | "light";
|
||||
head?: string;
|
||||
}): string {
|
||||
const { title, body, scripts = "", styles = "", theme = "light", head = "" } = opts;
|
||||
const { title, body, scripts = "", styles = "", theme = "dark", head = "" } = opts;
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
|
|
|||
Loading…
Reference in New Issue