---
id: TASK-46
title: 'Implement Cross-App Embedding: r-ecosystem apps in rSpace canvases'
status: In Progress
assignee: []
created_date: '2026-02-18 20:07'
updated_date: '2026-02-26 03:50'
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
- [x] #6 Toolbar dynamically shows ecosystem app buttons
- [x] #7 Remote clients lazy-load modules when ecosystem shapes appear
- [ ] #8 Service Worker caches ecosystem modules for offline
<!-- AC:END -->

## Implementation Notes

<!-- SECTION:NOTES:BEGIN -->
POC implemented in commit 50f0e11: folk-rapp shape type embeds live rApp modules as iframes on the canvas. Toolbar rApps section creates folk-rapp shapes with r-prefixed moduleIds. Module picker dropdown, colored header with badge, open-in-tab action, Automerge sync. Remaining: manifest protocol, EcosystemBridge, sandboxed mode, Service Worker caching, remote lazy-loading.

Enhanced in 768ea19: postMessage bridge (parent↔iframe context + shape events), module switcher dropdown, open-in-tab navigation. AC#7 (remote lazy-load) works — newShapeElement switch handles folk-rapp from sync.
<!-- SECTION:NOTES:END -->
