Commit Graph

339 Commits

Author SHA1 Message Date
Jeff Emmett 2cbff8925d fix(layout): viewport-filling rApp layout — eliminate body scroll
Make #app a flex column with height:100vh so all rApps fill the viewport
exactly. Wrap module body in .rapp-content flex child. Replace all
hardcoded calc(100vh - Npx) with height:100% across 20+ components.
Remove sticky positioning from subnav/tabbar (now flex items).
Generalize mobile body-flex to all pages (not just canvas-layout).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:57:09 -07:00
Jeff Emmett 0a21caa5e5 feat(pwa): install banner + update notification for service worker
- Install banner appears above header when beforeinstallprompt fires
  (dismissed state persisted in localStorage, never shows again)
- Update banner appears when a new SW version is detected waiting
  (click "Update" → SKIP_WAITING message → SW activates → page reloads)
- SW no longer auto-skipWaiting on install; waits for client message
- Bumped SW cache version to v5 and registration to ?v=5
- Banner CSS: fixed at top, z-index above all chrome, slide-in animation
- Header/tab-row/app offsets adjust when banner visible

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:40:07 -07:00
Jeff Emmett 7888596623 refactor(shell): move minimize chevron from tab row to subnav bar
The minimize toggle now lives at the right edge of each rApp's subnav
bar instead of the tab row. When minimized, both header and tab row
slide up and the subnav becomes a thin fixed strip with just the
restore chevron. Every rApp already has a subnav (except canvas which
has its own chrome).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:23:42 -07:00
Jeff Emmett 6b6646af1a fix: add space-switcher dropdown to main landing page header
The rspace.online root page was missing the rstack-space-switcher
component that all other pages (module pages, space dashboard,
module landing pages) already include in their headers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 09:58:07 -07:00
Jeff Emmett b5c6477f47 feat(rtime): add timebank commitment pool & weaving dashboard rApp
Port hcc-mem-staging SPA into rSpace as the rTime module. Canvas-based
commitment pool with physics orbs, SVG weaving editor with hex nodes
and bezier wires, execution panel, and optional Cyclos timebank proxy.
Automerge CRDT persistence, demo seeding, and full landing page
explaining community-based ledgers and emergent collaboration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 23:42:49 -07:00
Jeff Emmett 36ae954da4 feat(shell): add header minimize toggle for more viewport space
Adds a [^] chevron button at the right end of the tab row that collapses
all header bars into a thin 24px restore strip. State persists via
localStorage across page reloads. Works on both desktop (fixed) and
mobile (sticky) layouts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 23:35:12 -07:00
Jeff Emmett df202df06c fix: bare-domain module URLs now show landing pages instead of demo hub
rspace.online/{moduleId} was rewriting to /demo/{moduleId}, serving the
internal nav hub. Now calls renderModuleLanding() with the module's rich
landing page when available, falling back to demo rewrite otherwise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 22:24:25 -07:00
Jeff Emmett f9457a0e11 perf(shell): add fragment mode for fast rApp tab switching
When switching rApps from the dropdown, TabCache now requests
?fragment=1 which returns a lightweight JSON payload (~200 bytes)
instead of re-rendering the full 2000-line shell HTML template.
This eliminates server-side shell rendering and client-side
DOMParser overhead. Also prefetches fragments on hover.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:28:09 +00:00
Jeff Emmett 5852b91f4c feat(mi): make MI aware of all 48 canvas shape types
- Expand MI system prompt "Available shape types" from 20 → 48 shapes,
  organized by category (Core, AI, Creative, Social, Decisions, Travel,
  Tokens, Geo, Video)
- Expand Shape Mapping Rules from 12 → 30 triage rules covering all
  shape types with prop hints
- Expand KNOWN_TRIAGE_SHAPES from 15 → 48 so Gemini triage no longer
  silently downgrades unknown shapes to folk-markdown
- Add 22 missing TOOL_HINTS to mi-tool-schema.ts (travel, tokens, CAD,
  creative, geo, meta shapes) for keyword-based chip suggestions
- Add all 48 shapes to SHAPE_ICONS in mi-triage-panel.ts (was 13)
- Register folk-image-studio and folk-transaction-builder in canvas.html
  (were ghost shapes — imported but never defined/registered)
- Add SHAPE_DEFAULTS for folk-social-thread/campaign/newsletter,
  folk-design-agent, folk-image-studio

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:45:11 -07:00
Jeff Emmett 9084de7adb feat(rsocials): wire social shapes into all cross-rApp systems
- Add GET /api/threads, /api/threads/:id, /api/campaigns, /api/campaigns/:id
  REST endpoints so other rApps can fetch rsocials data
- Register folk-social-thread/campaign/newsletter in MI triage panel,
  tool schema, system prompt, and KNOWN_TRIAGE_SHAPES
- Add rsocials MODULE_PORTS (threads-out, campaigns-out, post-published,
  campaign-data) and WIDGET_API to folk-rapp for embed/widget mode
- Add rsocials to folk-feed FEED_ENDPOINTS (threads, campaigns, newsletter)
  and normalize response arrays (threads, campaigns, drafts)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:25:26 -07:00
Jeff Emmett 77ac0c1e32 feat(rsocials): newsletter drafts, subscribers + MI route updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:11:31 -07:00
Jeff Emmett f966f02909 feat(spaces,rsocials): invite-based member adds + clickable campaign content
Space invites: Convert both username-add and email-invite (existing user)
paths from direct-add to invite flow — creates space_invite via EncryptID,
sends invite email with Accept button, dispatches space_invite notification
with Accept/Decline buttons in the notification bell. No one gets forcefully
added to a space anymore.

rSocials content linking: All generated campaign content now links through
to actual editable content. Draft post cards in thread gallery are clickable
(thread editor or campaign view). Campaign manager post cards expand on click
and thread badges link to thread editor. Wizard success screen shows
individual thread links. CampaignPost schema gains threadId field, stored on
commit so posts maintain their thread association.

Also includes canvas social media tools, social shape components
(folk-social-thread, folk-social-campaign, folk-social-newsletter),
and MI context-aware suggestion registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:03:52 -07:00
Jeff Emmett ad75781efd fix(spaces): set clf and bcrg to permissioned on startup
One-shot migration to fix visibility for spaces that were changed
by stale client sync. Also imports updateSpaceMeta in index.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:08:51 -07:00
Jeff Emmett c0b4250e96 fix(spaces): pin visibility and ownerDID as server-authoritative
Automerge CRDT sync could overwrite space visibility when a client
with a stale cached doc reconnects and merges. Now the server
snapshots visibility and ownerDID before processing sync messages
and reverts any client-side changes to these fields.

These fields can only be changed through the authenticated API
(PATCH /api/spaces/:slug), not through CRDT sync.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:03:43 -07:00
Jeff Emmett dce608ae1b fix: cache-bust sw.js registration + no-cache header for SW/manifest
- Add ?v=4 to all SW registration URLs to bypass stale CF CDN cache
- Set Cache-Control: no-cache for sw.js and manifest.json so future
  SW updates are never blocked by CDN caching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:02:14 -07:00
Jeff Emmett 23083c32b0 fix: serve sw.js and manifest.json with no-cache header
Cloudflare was caching sw.js for 4 hours (default JS caching),
preventing service worker updates from reaching clients.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:55:52 -07:00
Jeff Emmett c4972079dd fix(cad): CSS containment + Scribus image gen for all CAD shapes
- KiCad, FreeCAD, Blender, Scribus: add .wrapper flex container with
  height:100% + min-height:0 so content stays within element bounds
- KiCad assembler: regex fallback for non-JSON tool results (SVG, Gerber, PDF)
- Scribus image gen: actually write downloaded fal.ai images to disk
  (was creating imagePath but never saving bytes)
- Mount rspace-files volume in scribus-novnc so generated images are
  accessible from both containers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:53:42 -07:00
Jeff Emmett 92629e239e fix(blender,freecad): contain render in element, fix FreeCAD file serving
Blender: add wrapper with height:100%, min-height:0 for flex shrink,
object-fit:contain on img — render stays within shape bounds.

FreeCAD: update assembleFreecadResult to scan all tool results for file
paths (.step, .stl, .png), not just execute_python_script JSON parsing.
Add preview PNG rendering instruction to system prompt. Add subdirectory
file serving routes for /data/files/generated/:subdir/:filename. Add
STEP/STL/SVG/PDF mime types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:40:25 -07:00
Jeff Emmett 8d4e1fd0ff fix(mi,canvas): filter disabled modules from MI assistant and eliminate app-switcher flash
MI now loads space doc to filter module list, capabilities, and fallback
by enabledModules. Canvas fetches /api/modules and space modules in
parallel via Promise.all, calling setModules once with filtered list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:26:07 -07:00
Jeff Emmett ac028cbe04 fix(blender): use shutil.move for cross-fs copy, disable denoiser
os.rename fails across Docker volume boundaries (different filesystems).
Debian Blender 3.4 lacks OpenImageDenoiser — disable denoising in prompt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:21:53 -07:00
Jeff Emmett 555a51f8a7 fix(blender): add EGL/GL libs and use Cycles CPU renderer
EEVEE needs GPU; Cycles CPU works headless. Added libegl1, libgl1-mesa-dri,
libglx-mesa0 to Dockerfile. Updated Gemini prompt to specify Cycles engine
with 64 samples.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:17:34 -07:00
Jeff Emmett aa02473d0d fix(shell): evict tab pane from cache on script load failure
When a module script (e.g. canvas-*.js) fails to load (502 during
deploy, network error), the pane stayed in cache with a blank canvas.
Subsequent tab switches showed the broken cached pane instead of
re-fetching. Now script onerror removes the failed tag and evicts
the pane, so the next switchTo does a fresh fetch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:10:23 -07:00
Jeff Emmett 101cc3b848 fix(shell): show rApp info popup once per module, then only via icon
Extract autoShowIfFirstVisit() so it runs both on initial page load
and on SPA tab switches. Uses localStorage rapp_info_seen_{moduleId}
to ensure each rApp's landing popup shows exactly once.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:01:54 -07:00
Jeff Emmett c046acf9ce fix(blender): switch from Ollama to Gemini Flash for script generation
Ollama runs CPU-only on Netcup — 7B models take minutes, exceeding
Cloudflare's 100s timeout (524). Gemini 2.0 Flash responds in seconds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:51:35 -07:00
Jeff Emmett 0db5addc17 fix(rdesign): switch to StreamableHTTP transport, fix KiCad Python path
SSE transport crashes on concurrent connections (supergateway
single-session limit). StreamableHTTP supports multiple sessions.
Also set KICAD_PYTHON=/usr/bin/python3 for existsSync validation
and install missing requests package.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:48:11 -07:00
Jeff Emmett 1c338529bf fix(presence): relay presence-leave messages and clean up listener on disconnect
- Server now relays presence-leave alongside presence messages for immediate peer removal
- Overlay properly unsubscribes leave listener on disconnectedCallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:42:49 -07:00
Jeff Emmett 2f8ce08e3c feat: add rDesign module metadata, collab presence-leave cleanup
- Register rDesign in folk-rapp MODULE_META and shell FAVICON_BADGE_MAP
- Handle explicit presence-leave messages for immediate peer cleanup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:35:10 -07:00
Jeff Emmett 6b81f808f5 feat(canvas): mobile toolbar flush, zoom icon toggle, SW update banner
- Mobile toolbar collapsed position now flush with bottom-toolbar (bottom: 8px)
- Toolbar defaults to collapsed on mobile (<768px)
- Zoom expand/minimize uses distinct icons (magnifier +/-) instead of CSS rotation
- SW update banner on all pages: "New version available — Tap to update"
  - Detects controllerchange + updatefound events
  - Purple gradient bar, dismissible, reloads on tap
  - Added to both shell.ts (module pages) and canvas.html (standalone)
- folk-rapp: filter picker/switcher by enabled modules
- server/shell: react to modules-changed event for runtime module toggling
- collab-presence: minor overlay updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:34:48 -07:00
Jeff Emmett 395623af66 feat(rdesign): deploy KiCad & FreeCAD MCP as Docker sidecars
Switch from broken StdioClientTransport (child process) to
SSEClientTransport (HTTP to sidecar containers via supergateway).
Both sidecars share rspace-files volume so generated CAD files
(STEP, STL, Gerber, SVG) are directly servable without copying.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:25:23 -07:00
Jeff Emmett 55b973ebc2 fix(blender): use correct Ollama model (qwen2.5-coder:7b)
qwen2.5:14b doesn't exist on the server, causing silent 404 from
Ollama and 502 to the client. Also added error logging for non-ok
Ollama responses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:10:11 -07:00
Jeff Emmett aa23108f5f fix(invites): redirect to invited space, improve invite emails
- Fix invite accept fetch URL in shell.ts (was missing /api/spaces prefix)
- After accepting invite, redirect to the invited space instead of reloading
- Notification actionUrls now point to the space subdomain (https://slug.rspace.online)
- Direct-add email includes inviter name, role, and space description
- Identity invite email includes space name/role context when inviting to a space

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:39:58 -07:00
Jeff Emmett 2f3a4a13dc fix(blender): make RunPod optional, fix script-only generation
RunPod was hard-gated — returned 503 when RUNPOD_API_KEY missing,
blocking even LLM script generation. Now generates script via Ollama
regardless, only attempts RunPod render if key is configured. Health
check returns warnings (non-blocking) vs issues (blocking). Default
model switched to qwen2.5:14b (available on server). Regex also
handles non-python-tagged code blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:38:49 -07:00
Jeff Emmett 59d2cc9933 feat(spaces): add visibility/description to settings panel, merge invite sources
- Space Settings section in dropdown with visibility (public/permissioned/private)
  and description fields, matching the full edit space modal
- GET /api/spaces/:slug now includes description field
- listSpaceInvites merges both space_invites and identity_invites tables
  so email invites appear in Pending Invites
- revokeSpaceInvite falls through to identity_invites table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:29:33 -07:00
Jeff Emmett 32be9d7b94 fix(ui): bump subnav sticky top to avoid header overlap
Increase .rapp-subnav top from 92px to 93px so pill buttons
don't clip under the fixed header + tab-row border.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:54:23 -07:00
Jeff Emmett c2d7e8b238 fix(shell): prevent infinite loop when rapidly switching tabs
Abort previous in-flight fetch when switchTo() is called again, and
guard the shell's fallback navigation against stale callbacks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:44:38 -07:00
Jeff Emmett 22b5c00a13 fix(routing): prevent domain stacking and remove Try Demo button
- Fix server-side redirect to always use canonical rspace.online as base
  domain instead of deriving from hostClean (prevents demo.rspace.rspace.online)
- Fix bare-domain check to exact match instead of .includes() (prevents
  stacked subdomains from triggering bare-domain routing)
- Fix client-side rspaceNavUrl to guard against reserved subdomain names
  being used as space subdomains (e.g. rspace.rspace.online)
- Fix identity component _navUrl with same canonical domain guards
- Remove "Try Demo" header button from all shell rendering functions
- Remove demo-btn CSS styles
- Fix pre-existing SchemaType error in Gemini tool declarations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:16:46 -07:00
Jeff Emmett dd46905e12 feat(mi): agentic upgrade — multi-turn loop, LiteLLM, media gen, live data
Transform MI from single-shot chat into an agentic system:

- LiteLLM provider with Claude Sonnet/Haiku models via proxy
- Agentic loop (max 5 turns): stream → parse actions → execute server-side → feed results back
- Server-side media generation (fal.ai + Gemini) as first-class MI actions
- Module data queries (rnotes, rtasks, rcal) read directly from Automerge
- System prompt enriched with recent notes, open tasks, and calendar events
- Client handles new NDJSON types (turn, action-start, action-result)
- Extracted shared media helpers, refactored image/video endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:26:56 -07:00
Jeff Emmett a5c7eef466 fix(startup): move space alias provisioning after loadAllDocs
The IIFE raced with doc loading so listCommunities returned empty.
Moved into the .then() callback to ensure all docs are loaded first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:06:06 -07:00
Jeff Emmett 193588443e fix(routing): eliminate /{space} from paths on subdomain routing
On subdomain routing (e.g. demo.rspace.online), the space slug belongs
only in the subdomain — never in the URL path. This fixes all server
and client code that was generating /{space}/module paths on subdomains.

Server fixes:
- index.ts: notification actionUrls, template/disabled-module redirects,
  subdomain passthrough (now redirects HTML, rewrites API), WS notifications
- output-list.ts: subdomain-aware path prefix for hrefs and fetch URLs
- shell.ts: dashboard pushState URL

Client fixes (basePath getter pattern):
- folk-book-shelf.ts, folk-splat-viewer.ts: _basePath getter
- folk-campaign-wizard.ts: basePath subdomain check
- folk-trips-planner.ts: use __rspaceNavUrl for canvas export
- rschedule/landing.ts: onclick handlers use __rspaceNavUrl
- rsplat/mod.ts: legacy view redirect subdomain check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:45:16 -07:00
Jeff Emmett 75ad3f8194 feat(rinbox): per-space email forwarding via Mailcow aliases
Provision {space}@rspace.online forwarding aliases that route to
opted-in members' personal emails. Admins/mods opted in by default;
regular members can opt in via PUT /api/spaces/:slug/email-forwarding/me.

New: space-alias-service.ts, schema tables, 8 DB functions, 6 API routes.
Hooks: rinbox onSpaceCreate/Delete, spaces.ts member lifecycle, startup migration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:40:29 -07:00
Jeff Emmett 41051715b9 feat(rtasks): ClickUp two-way sync integration
Add bidirectional sync between rTasks and ClickUp:
- API client with 100 req/min rate limiter
- OAuth2 + personal API token connection flows
- Import wizard (workspace → space → list picker)
- Outbound push queue (5s intervals, 10-item batches)
- Inbound webhook with HMAC-SHA256 validation
- Field-level conflict detection (rTasks wins)
- Source badges (purple CU) with sync status dots on task cards
- Sync status indicator in board header for connected boards

Also fix 6 pre-existing TS errors across crowdsurf, rcal, rnotes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:37:01 -07:00
Jeff Emmett 677a69645e debug(shell): add console logging to trace tab-switch failure for rspace
Adds diagnostic console.log to layer-switch handler, TabCache.switchTo,
fetchAndInject, and reconcileRemoteLayers to identify why clicking the
rspace tab closes all tabs and shows the dashboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:32:57 -07:00
Jeff Emmett 433833da0c fix(shell): prevent remote sync from wiping all tabs and showing dashboard
reconcileRemoteLayers() could wipe all local tabs when Automerge sync
or BroadcastChannel delivered empty layer data (CRDT initial state,
sync race). This caused clicking tabs to show an infinite-loading
dashboard. Now: empty remote layers are rejected when an active module
exists, and the current module always stays in the tab list.

Also adds 10s fetch timeout to TabCache.fetchAndInject() to prevent
infinite loading spinners on slow/failed module fetches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:23:45 -07:00
Jeff Emmett 3655632e0f fix(auth): check cross-subdomain cookie in access gate and dashboard redirects
The access gate and space dashboard redirect scripts checked only
localStorage, which is per-origin. When navigating between subdomains
(e.g. demo → jeff), the session wasn't found. Now both scripts also
check the eid_token cross-subdomain cookie and sync it to localStorage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 14:24:30 -07:00
Jeff Emmett bf0661fab2 feat(cad): LLM-orchestrated MCP tool-calling for KiCad and FreeCAD
Add Gemini Flash agentic loop that converts natural language prompts
into real MCP tool call sequences for PCB design (KiCad) and parametric
CAD (FreeCAD). Dynamic schema conversion from MCP tools to Gemini
function declarations, 8-turn/60s loop with real execution and result
feedback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 14:07:19 -07:00
Jeff Emmett d8736ba341 fix(rcal): add post-load migration for tags field on existing events
Automerge docs created before the tags schema don't have the field.
The migration runs 5s after startup (after loadAllDocs completes),
patches missing tags onto events, and assigns known demo event tags.
Also removes debug endpoint and tracing logs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 14:01:01 -07:00
Jeff Emmett 9ae88e14b7 debug: add tags tracing logs 2026-03-24 13:56:22 -07:00
Jeff Emmett 2dd5e764cd feat(rcal): MI calendar awareness, tags, saved views, MCP server
Phase 1: MI now knows the current date/time and upcoming events (14-day
lookahead, 5 events max) via direct Automerge read — no HTTP overhead.

Phase 2: Tags (string[] | null) on CalendarEvent for first-class filtering.
Saved views (named filter presets) with full CRUD API. Tag filter on
GET /api/events via comma-separated AND logic. Demo events seeded with tags.

Phase 3: Calendar MCP server (5 tools: cal_list_events, cal_get_event,
cal_list_sources, cal_list_views, cal_create_event) registered in .mcp.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 13:28:02 -07:00
Jeff Emmett f2c3245240 fix: ensure demo community visibility is always public on startup
The demo Automerge doc had visibility: "private" from initial creation.
ensureDemoCommunity now forces visibility to "public" on every startup
if it drifted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 13:21:59 -07:00
Jeff Emmett 7f327eb07a fix: whitelist rvote GET API as public + guard campaign wizard auth client-side
1. Add GET /rvote/api/* to public endpoint whitelist so proposal
   listings work on private/permissioned spaces without auth.
2. Campaign wizard now checks for auth token before POSTing,
   showing "Please sign in" instead of a cryptic 401.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 12:58:21 -07:00