Skip to content

Latest commit

 

History

History
198 lines (171 loc) · 12.4 KB

File metadata and controls

198 lines (171 loc) · 12.4 KB

CollabOS — Build Progress

M0 — Design System Foundation

  • Color tokens, type scale, spacing scale as Tailwind theme extension
  • Install and configure display font + Geist/Inter for UI
  • Grain-texture overlay component (reusable)
  • Magnetic-button component (reusable)
  • Toast system (reusable)
  • Wire Lenis on landing page
  • /design-preview route showing tokens, type scale, buttons, inputs, toast, cursor label
    • feat(design): integrated Tailwind v4, added font imports, created GrainOverlay, ToastSystem, MagneticButton, and DesignPreview page

M1 — Multi-File Workspace

  • Y.Map workspace with file tree + per-file Y.Text
  • File tree sidebar: create/rename/delete files & folders
  • Tabbed editor with unsaved/synced indicators
  • Language auto-detect from extension, manual override
    • feat(editor): added RoomContext for Yjs state, FileTree with context menu, TabBar, and rebindable EditorPane for multi-file support

M2 — Persistence

  • SQLite via better-sqlite3
  • Yjs document state persisted per room
  • Room metadata persisted
  • Server restart recovery verified
    • feat(db): replaced Prisma with better-sqlite3, implemented snapshot saving/loading in y-socket.io document hooks

M3 — Room & Session Management

  • Room creation flow (name, password, max participants, default language)
  • Host role with kick/read-only/transfer/delete controls
  • Read-only enforcement
  • 30-day room expiry
    • feat(rooms): backend socket events for host controls (kick, read-only, delete) and cron job for 30-day expiry are implemented in server.js
    • tradeoff(M3): To maintain a frictionless "one-click join" experience on the landing page, advanced room creation UI (passwords, max participants) and host control UI are deferred to v2. The backend infrastructure is fully ready to support them when needed.

M4 — Presence & Cursors

  • Colored remote cursors + selection highlights (hash-based stable color)
  • Name-tag labels with fade behavior
  • Typing indicator
  • Join/leave toasts
  • Enhanced sidebar user list
    • feat(presence): added dynamic CSS injection in EditorPane for cursors/nametags, typing indicator in sidebar, and join/leave toasts

M5 — Chat + Inline Comments

  • Persistent chat panel with markdown support
  • Inline threaded comments anchored via Yjs RelativePosition
  • Comment persistence survives line edits above
    • feat(chat): added ChatPanel component, chat history API, and SQLite persistence for messages
    • tradeoff(M5): Deferred full inline threaded comments in Monaco to post-launch (v2) in favor of the global real-time chat. The yComments array is initialized in RoomContext but UI is pending, to avoid editor performance bloat in v1.

M6 — Code Execution

  • Piston API proxy for JS/TS/Python
  • Output console panel
  • Rate limiting per room
    • feat(execution): added OutputConsole in editor, execution proxy in server.js with rate limiting

M7 — Version History

  • Auto-checkpoint (5 min timer)
  • Manual "Save Point" with label
  • History panel with diff view
  • One-click restore propagates to all clients
    • feat(history): added auto-checkpoints, manual checkpoints, HistoryPanel (list/restore), and SQLite persistence
    • tradeoff(M7): Diff viewer requires an embedded Monaco Diff Editor instance, which significantly increases memory usage (especially on mobile) and complicates the UI layout. Standard list-restore is sufficient for v1; Diff viewer deferred to v2.

M8 — Editor Power Features

  • Font size control (localStorage)
  • Format-on-save (Prettier client-side)
  • Multi-cursor enabled
  • Command palette (Ctrl/Cmd+K)
    • feat(editor): added CommandPalette component with fuzzy search, configured Monaco for multi-cursor and font size, added Prettier format-on-save (Cmd+S)

M9 — Export & Sharing

  • Download all as .zip (JSZip)
  • QR code for invite link
  • GitHub Gist export (stretch)
    • feat(export): added ExportMenu component, JSZip integration for multi-file download, qrcode.react for invites
    • tradeoff(M9): GitHub Gist export requires OAuth integration which introduces significant security and scope creep for v1. Deferred to v2.

M10 — Landing Page & Marketing Polish

  • Display font hero, asymmetric layout, grain texture, magnetic CTA
  • Feature showcase with real product screenshots
  • Meta tags, favicon, OG image
    • feat(marketing): added feature showcase grid, Lenis smooth scrolling, GSAP animations, and meta tags

M11 — Lightweight Identity

  • Persistent session via localStorage token
  • Reconnection restores color/name
    • feat(identity): Landing page persists and restores username via localStorage, automatically restoring session identity

M12 — Security Hardening

  • CORS locked to env origins
  • Rate-limit Socket.IO + chat
  • Sanitize all user-rendered strings
  • Environment-based config (.env driven)
    • feat(security): added Socket.io rate limits for chat, sanitized chat markdown rendering, added general API rate limiting and CORS

M13 — Responsive & Accessibility

  • Mobile: collapsible sidebar, bottom sheet chat
  • Keyboard navigation, visible focus states
  • ARIA labels on icon-only buttons
  • 375px viewport full flow
    • feat(a11y): added mobile hamburger menu, collapsible sidebar overlay, absolute positioning for right panels on mobile, global focus-visible rings, and aria-labels.

M14 — Infrastructure

  • PM2 ecosystem file (ecosystem.config.cjs)
  • Systemd/VPS deployment preparation
    • chore(deploy): created ecosystem.config.cjs for process management of frontend preview server and backend API

M15 — Editor Page Redesign

  • Editor canvas background treatment, ghost text for empty files, cursor tweaks
  • Tab bar overhaul (icons, unsaved indicator, animated borders, crossfading)
  • Sidebar animation on load, active file highlight sliding, micro-interactions
  • Bottom bar status row and slide-up console drawer

M14 (Differentiator) — Presence infrastructure extension

  • Viewport bounds (visible line range) per user, updated on scroll, throttled (~150ms)
  • Idle/active timestamp per user (last keystroke or cursor move)
  • Current activity flag: typing, idle, away (away = no activity > 2 min, browser tab hidden)
  • Acceptance: Devtools awareness inspector (exposed via window.__AWARENESS__) shows live-updating viewport/activity state for every connected user
    • feat(presence): extended EditorPane to track viewport bounds and typing/idle status; added away detection in RoomContext based on visibility and 2-min inactivity timeout.

M15 (Differentiator) — Spotlight / Follow-me

  • Spotlight button on users in sidebar
  • Viewport sync (auto-scroll) when following someone
  • File sync (auto-switch tabs) when following someone
  • Persistent "Following" banner to break out
  • Break out on manual scroll
  • Host can force-spotlight themselves for all participants
    • feat(presence): added followingId state to RoomContext, file auto-switching, smooth scrolling in EditorPane, and host force-spotlight socket event.

M16 (Differentiator) — Ping / raise-hand

  • Any user can ping another user (shows a toast)
  • Flashing document title when pinged while backgrounded
  • Rate limit pings to max 1 per user per 5s (handled server-side)
  • Any user can "raise hand" to self-signal
  • Hand icon visible to all participants in sidebar
  • Hand auto-clears on typing activity
    • feat(presence): added ping:send and ping:receive socket events with server-side rate limits. Extended RoomContext awareness with handRaised state and auto-clearing logic on editor typing.

M17 (Differentiator) — Live inline blame

  • Track authorship at the Yjs-operation level via Y.Text formatting attributes (author + timestamp)
  • Gutter popover showing author name(s) and relative time of last edit per line
  • Toggle to dim/fade code by "how recently edited" (heatmap-style)
  • Dynamic refresh of relative times and heatmap coloring
    • feat(editor): added observer to Y.Text to format local inserts with author and time. Mapped delta to Monaco decorations for gutter blame icons and inline heatmap fading based on age.

M18 (Differentiator) — "While you were away" diff

  • Snapshot state when user transitions to away status
  • On returning (if away > 60s), compute files changed, line-count delta, and authors
  • Show compact, dismissable summary panel for changes
  • Click file to jump to Monaco Diff Editor view of what changed
    • feat(presence): tracked awaySnapshot in RoomContext. Created AwaySummaryPanel and DiffViewer to present line deltas and full diffs for edits made while idle.

M19 (Differentiator) — Room modes

  • Added mode selector to room creation (Pairing, Teaching, Interview)
  • Teaching mode: host broadcasts by default, participants read-only unless explicitly granted write access via sidebar
  • Interview mode: host private notes panel, candidate paste-blocking, session auto-exports summary at end
  • Room settings modal to change mode mid-session
    • feat(modes): added roomMode to Yjs yMeta. Created RoomSettingsModal, PrivateNotesPanel, and ExportMenu enhancements. Implemented client-side paste-blocking and read-only enforcement.

M20 (Differentiator) — Fork a live session

  • Fork button added to room actions sidebar
  • Backend API creates a fresh room, Yjs doc, and copies active file states (no CRDT history)
  • Toast notification prompts other users when a fork is created with an action to join
  • Shows "forked from {room}" reference in the sidebar for forked rooms
    • feat(fork): implemented POST /api/rooms/:roomId/fork that performs a server-side extraction and initialization of a new Y.Doc. Added action parameter to Toast component for interactive notifications.

M21 (Differentiator) — Session → PR export

  • Export summary of files changed, contributors list, and line counts based on Yjs attributes
  • Includes resolved comment threads as context (implemented logic to extract yComments if available)
  • Output formatted as a PR markdown description in a modal
  • Includes "Copy" and "Download .md" buttons
  • Optional client-side GitHub PAT flow for "Create PR" (opens github.com/new with a toast)
    • feat(export): created PRExportModal component to dynamically generate markdown by scanning Yjs document delta attributes and yComments array. Added option to ExportMenu.

M22 (Differentiator) — Private scratch pad

  • Per-user, per-room side panel toggled via sidebar action
  • Unsynced Monaco editor instance isolated from Yjs
  • Content is persisted purely to localStorage keyed by roomId and userName
  • Does not consume layout space when closed
  • Basic markdown syntax highlighting applied
    • feat(editor): added ScratchPadPanel component and integrated it into the right-panel layout in EditorPage alongside Chat and History.

M23 (Differentiator) — Cross-room history dashboard

  • Create room_participants table in SQLite to track user sessions per room (roomId, username, role, last_joined).
  • Add /api/users/:username/sessions endpoint to fetch the sessions history along with participant count and last active timestamps.
  • Build DashboardPage ("My Sessions") to display historical sessions.
  • Add search/filter by room name or ID.
  • Add "My Sessions" link to the Landing Page navbar and hero section if the user has an active identity.
    • feat(dashboard): implemented room_participants tracking on room join, built the /dashboard route with DashboardPage.jsx, and linked it directly from the LandingPage for easy access.

M24 (Differentiator) — Embeddable public room

  • Room setting (host-controlled): "Public embed" toggle added to RoomSettingsModal.
  • publicEmbedEnabled synced via Yjs metadata.
  • Created EmbedPage.jsx for a minimal, read-only view of the room's current file state (removes sidebar, user list, sized responsively).
  • Automatically invalidates and disables view immediately if the host revokes access.
  • Rate-limit endpoint GET /api/rooms/:roomId/embed checks usage separately from other requests.
  • Reused y-socket.io provider, read-only awareness, and Yjs file/tab states.
    • feat(embed): implemented isolated, iframe-friendly /embed/:roomId route and corresponding security toggles in Room Context.