Project Documentation

Roject

Developer reference for human and agent contributors. Keep this file up to date as the project evolves.

Project Outline

What it is

Roject is a self-hosted, browser-based CMS for creating, editing, and storing HTML documents with assets, organised into projects. It is designed for individual developers or small teams who want a lightweight authoring environment with no external database dependency.

What exists now

User accounts with registration, login, logout, and account deletion. Groups and projects with member management (viewer / editor / admin roles). Each project gets a real directory on disk at storage/<uuid>/root/ with a default index.html on creation.

A full editor page (/editor.html) with a 3-panel resizable layout (Left / Center / Right). Each panel holds one or more sections side by side, each section holds a <tab-container>. Tabs are draggable between containers. The Left panel shows the file tree with create, rename, and delete for files and folders. The Center panel holds the WYSIWYG HTML editor (iframe, contenteditable, MutationObserver, undo/redo, Ctrl+S save). The Right panel is empty by default and receives dropped tabs.

A FileEditorRegistry routes files to the correct panel by suffix. HTML files open in html-editor-panel; all other known text formats open in code-panel (CodeMirror 5, syntax highlighting, dark theme, Pin/Undo/Redo/Save toolbar). The registry checks an optional project-level workspace/editor/file-editors.json first, then falls back to in-memory defaults. Unknown extensions show an error in the file tree instead of attempting to open.

A rojo-chat-panel provides a streaming AI chat interface backed by a LangChain + OpenAI-compatible model. Each panel instance holds its own conversation session in memory. A reusable <confirm-dialog> component replaces browser confirm() for destructive actions (currently project deletion).

What still needs work

This is a loose reminder, not a fixed backlog. Things we know are missing or incomplete: the Right panel has no default content and relies on manual tab dragging to populate; portrait mode's secondary section switcher (when a panel has multiple side-by-side sections) is not yet wired up; the member list UI shows raw UUIDs instead of usernames; the group editor and account delete button still use the browser confirm() instead of the custom dialog; non-text files (images, PDFs) in the tree are visible but not openable (a MediaViewerPanel is planned); and there is no real-time multi-user collaboration yet.

Technical Implementation

Backend

Node.js + Express, TypeScript compiled on the fly with ts-node. No database — all data lives as JSON files in data/ (auto-created on first run). Auth uses express-session + bcryptjs. All entity IDs are UUIDs via crypto.randomUUID() — no central counter, safe for parallel instances. Start the server with npm start.

Node.js Express ts-node express-session bcryptjs UUID IDs

Frontend

Vanilla HTML, raw CSS (no Tailwind, no framework). Every UI component is a custom element with its own .ts and .css file in src/components/<name>/. CSS uses the element tag as root selector with display: block. TypeScript compiles to public/components/ via tsconfig.client.json (module: ESNext, moduleResolution: bundler, no bundler). HTML pages load components with <script type="module">. Shared state uses a module-level singleton (editor-state.ts) rather than globals. Build with npm run build.

Web Components raw CSS module: ESNext no bundler tsc --build

Shared Library

A personal TypeScript library lives as a git submodule at src/library-ts/. It has two parts: browser/ (DOM-capable) and node/ (Node.js only). The browser part is compiled separately via TypeScript project references (src/library-ts/browser/tsconfig.roject.json, strict: false) into public/library-ts/browser/. The node part is included by tsconfig.ts-node.json (extends server config, strictNullChecks: false).

git submodule src/library-ts/ project references composite: true