Project Documentation
Developer reference for human and agent contributors. Keep this file up to date as the project evolves.
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.
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; 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 reusable <confirm-dialog> component replaces browser
confirm() for destructive actions. Currently wired up for project
deletion only.
This is a loose reminder, not a fixed backlog. Things we know are missing or
incomplete: a file manager inside the editor (create, rename, delete files and
folders from the tree); 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-HTML files in the tree are visible but not openable;
and there is no real-time multi-user collaboration yet.
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.
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.
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).