From 5282fcd241846c79a368b4204a2eb3352a13648c Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Mon, 4 May 2026 13:11:23 +0200 Subject: [PATCH] chore: update docs --- README.md | 166 ++++++++++----- TAILWIND.md | 577 ---------------------------------------------------- 2 files changed, 113 insertions(+), 630 deletions(-) delete mode 100644 TAILWIND.md diff --git a/README.md b/README.md index 9057cbf..f5c06d1 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,122 @@ # bDS2 -bDS2 is the Elixir rewrite of bDS, the offline-first desktop blogging workspace in [../bDS](/Users/gb/Projects/bDS). The repository now contains a substantial BEAM application: Ecto persistence, filesystem-backed content workflows, rendering/generation/publishing pipelines, AI and MCP integrations, and a bundled desktop shell served by the Elixir runtime. +bDS2 is the Elixir rewrite of bDS, the offline-first desktop blogging workspace. It is no longer just a rewrite scaffold: the repository now contains the main desktop runtime, Ecto persistence, filesystem-backed content workflows, rendering and publishing pipelines, Lua scripting, AI and MCP integration, and a Phoenix LiveView shell embedded in a native desktop window. -The Allium specifications in [specs/](/Users/gb/Projects/bDS2/specs) remain the behavioral contract for the rewrite. For current implementation status and the parity roadmap, see [PLAN.md](/Users/gb/Projects/bDS2/PLAN.md). +The Allium specs in [specs/](/Users/gb/Projects/bDS2/specs) remain the behavioral contract for the rewrite. For end-user operation, see [DOCUMENTATION.md](/Users/gb/Projects/bDS2/DOCUMENTATION.md). For the scripting surface, see [API.md](/Users/gb/Projects/bDS2/API.md). -## Scope +## Current Status -The rewrite aims to preserve the product behavior of bDS while replacing the technical stack. +The major architectural rework is in place. -Behaviour that should remain stable includes: +- The desktop UI is served by Phoenix LiveView inside the desktop shell rather than by a separate handwritten frontend runtime. +- Assets use Phoenix-default Tailwind and esbuild tooling from [assets/](/Users/gb/Projects/bDS2/assets) into [priv/static/](/Users/gb/Projects/bDS2/priv/static). +- Core editorial flows are implemented in the main application: posts, media, tags, templates, scripts, imports, preview, generation, publishing, maintenance, AI, and MCP. +- Localization is now a first-class architectural concern rather than an afterthought: UI chrome and rendered site output have separate locale flows, and post/media translation workflows are built into the domain model. -- Offline-first editorial workflows. -- Filesystem-backed content with stable frontmatter, media sidecars, templates, scripts, and menu formats. -- Project, post, media, translation, tag, template, generation, preview, publishing, AI, and MCP workflows. -- Generated site output, search behavior, metadata synchronization, and rebuild behavior where those are part of the product contract. +The rewrite still aims to preserve the product behavior of bDS while replacing the technical stack. The contract is product behavior, not the old implementation language or framework choices. -The following are intentionally not part of the behavioral contract: +## Architecture Overview -- The implementation language. -- Desktop container or UI framework. -- ORM choice. -- Internal state management, concurrency model, or runtime libraries. +### Runtime -## Scripting Direction +[BDS.Application](/Users/gb/Projects/bDS2/lib/bds/application.ex) is the supervision root. It starts the Phoenix endpoint, database, preview and publishing workers, task supervisors, scripting jobs, and the desktop server/window adapters. -bDS2 should use Lua as its user-facing scripting language. +At a high level, the stack is: -The reason is host fit, not language fashion: Lua has a better embedding story for the BEAM than Python does, while still being small, expressive, and suitable for user-authored macros, transforms, and utility scripts. The current direction is: +- Native windowing through the `:desktop` integration. +- Phoenix endpoint and LiveView shell for the actual app UI. +- Ecto + SQLite for indexed state, editor state, and app data. +- Filesystem-backed project data for published content, media, sidecars, scripts, templates, generated output, and rebuild workflows. -- Lua script files as the persisted user script format. -- A BEAM-hosted execution boundary with explicit host capabilities instead of unrestricted runtime access. -- Bounded but long-running script execution for user-authored code, with explicit progress reporting through host APIs. +### Desktop Shell -The initial runtime baseline in this repository uses a dedicated Elixir scripting boundary with a Luerl-backed Lua adapter. The goal is to keep scripting integration native to the BEAM while making sandboxing and host capability exposure explicit at the application boundary. +The desktop workbench lives under [lib/bds/desktop/](/Users/gb/Projects/bDS2/lib/bds/desktop). The main screen is [BDS.Desktop.ShellLive](/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live.ex), with feature-specific editors and sidebar logic under [lib/bds/desktop/shell_live/](/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live). -This keeps the scripting surface lightweight and aligned with the Elixir host application. Python remains a possible integration boundary for specialized tasks, but it is no longer the default scripting model for the rewrite. +If you are tracing UI behavior, start there first: -## Repository Layout +- LiveView event routing, workbench state, overlays, and menu handling live in the desktop shell modules. +- HEEx templates under the same tree now own most common layout and state styling. +- Monaco remains a vendor drop under [priv/ui/monaco/](/Users/gb/Projects/bDS2/priv/ui/monaco). -- [mix.exs](/Users/gb/Projects/bDS2/mix.exs): Mix project definition. -- [config/](/Users/gb/Projects/bDS2/config): Elixir and Ecto configuration. -- [lib/](/Users/gb/Projects/bDS2/lib): application bootstrap and shared runtime modules. -- [priv/repo/](/Users/gb/Projects/bDS2/priv/repo): Ecto migrations. -- [specs/](/Users/gb/Projects/bDS2/specs): Allium specs distilled from the existing bDS product and being normalized for implementation-agnostic use. +### Domain Modules + +Most application behavior lives under [lib/bds/](/Users/gb/Projects/bDS2/lib/bds): + +- posts, media, tags, templates, scripts, and project settings +- metadata, frontmatter, sidecars, rebuild, and maintenance +- rendering, generation, preview, and publishing +- AI runtimes, chat tooling, embeddings, and MCP +- scripting capabilities and generated API docs + +The repo has been pushed toward smaller feature-focused modules rather than one large mixed runtime. For new work, prefer finding the owning feature module instead of adding more behavior to broad catch-all files. + +### Storage Model + +The database is important, but it is not the whole source of truth. + +- Ecto models hold app state, indexes, editor state, and workflow data. +- The filesystem holds published content artifacts and sidecar metadata that must stay stable and reviewable. +- Rebuild and metadata-diff flows exist because database state and filesystem state are expected to stay in sync. + +When you change persisted behavior, think in both directions: database writes and filesystem writes/readback. + +## Localization And i18n + +Localization now has two separate layers, and confusing them causes bugs. + +### 1. UI Localization + +UI chrome, menus, dashboard text, editor labels, and toasts use Gettext through [BDS.Gettext](/Users/gb/Projects/bDS2/lib/bds/gettext.ex) and the `ui` domain. Locale normalization lives in [BDS.I18n](/Users/gb/Projects/bDS2/lib/bds/i18n.ex), and the desktop shell binds the active UI locale through [BDS.Desktop.UILocale](/Users/gb/Projects/bDS2/lib/bds/desktop/ui_locale.ex). + +In practice, this is the language of the app itself. + +### 2. Render Localization + +Rendered site output uses a separate locale flow. Archive labels, pagination text, template-facing render strings, and generated site language handling use the `render` Gettext domain and the project's `main_language` and `blog_languages` settings. + +In practice, this is the language of the blog output, not necessarily the UI. + +### 3. Content Translation + +Posts and media have translation-aware workflows. Post translations and media metadata translations are modeled explicitly, and generation/preview/publishing use the project's configured languages when building output. + +Relevant translation resources live under: + +- [priv/gettext/](/Users/gb/Projects/bDS2/priv/gettext) for Gettext catalogs +- [priv/i18n/](/Users/gb/Projects/bDS2/priv/i18n) for additional locale data used by the app + +If you touch i18n-sensitive behavior, check whether the change belongs to UI locale, render locale, or content translation. They are related, but they are not interchangeable. + +## Frontend And Assets + +Frontend source now follows the Phoenix asset layout: + +- [assets/css/](/Users/gb/Projects/bDS2/assets/css) for Tailwind-based CSS modules +- [assets/js/](/Users/gb/Projects/bDS2/assets/js) for LiveView hooks, bridges, Monaco integration, and UI helpers +- [priv/static/assets/](/Users/gb/Projects/bDS2/priv/static/assets) for generated outputs + +The rule of thumb is simple: + +- common layout, spacing, state, and typography belong in HEEx and small shared UI primitives +- authored CSS stays for tokens and desktop-specific selectors +- JavaScript stays focused on LiveView hooks, editor integration, drag/drop, and browser APIs + +## Repository Map + +- [mix.exs](/Users/gb/Projects/bDS2/mix.exs): Mix project definition, aliases, releases, and dependencies +- [config/](/Users/gb/Projects/bDS2/config): runtime, dev, test, and asset configuration +- [lib/bds/](/Users/gb/Projects/bDS2/lib/bds): core application modules +- [lib/bds/desktop/](/Users/gb/Projects/bDS2/lib/bds/desktop): desktop endpoint, shell, menus, controllers, and window integration +- [assets/](/Users/gb/Projects/bDS2/assets): Tailwind and esbuild source +- [priv/repo/](/Users/gb/Projects/bDS2/priv/repo): Ecto migrations and snapshots +- [priv/gettext/](/Users/gb/Projects/bDS2/priv/gettext): UI and render translation catalogs +- [specs/](/Users/gb/Projects/bDS2/specs): Allium behavior specs +- [DOCUMENTATION.md](/Users/gb/Projects/bDS2/DOCUMENTATION.md): end-user guide +- [API.md](/Users/gb/Projects/bDS2/API.md): generated scripting API reference ## macOS Development Setup -If you are setting up a new macOS machine, start with the toolchain. +If you are setting up a new macOS machine, install the toolchain first. ### 1. Install Xcode Command Line Tools @@ -56,8 +126,6 @@ xcode-select --install ### 2. Install Homebrew -If Homebrew is not already installed: - ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``` @@ -69,36 +137,28 @@ brew update brew install erlang elixir sqlite ``` -Verify the installation: - -```bash -elixir --version -mix --version -sqlite3 --version -``` - -### 4. Fetch Dependencies +### 4. Fetch Dependencies And Set Up The App ```bash cd /Users/gb/Projects/bDS2 -mix deps.get +mix setup +mix assets.setup ``` -### 5. Create the Local Database - -```bash -mix ecto.create -mix ecto.migrate -``` - -### 6. Run Tests +## Development Workflow + +Useful commands: ```bash +mix compile --warnings-as-errors mix test +mix dialyzer +mix assets.build ``` -## Development Notes +Notes for developers: -- Use `mix test` for validation during development. -- The application behavior is defined by the Allium specs in [specs/](/Users/gb/Projects/bDS2/specs). -- Use [PLAN.md](/Users/gb/Projects/bDS2/PLAN.md) for implementation status and the parity roadmap. +- Specs in [specs/](/Users/gb/Projects/bDS2/specs) define the intended product behavior. +- [DOCUMENTATION.md](/Users/gb/Projects/bDS2/DOCUMENTATION.md) is for end users, not implementation details. +- [API.md](/Users/gb/Projects/bDS2/API.md) is generated from the live scripting capability map and should stay in sync with runtime changes. +- When changing persistence or localization behavior, check both the database side and the filesystem/render side before assuming the change is complete. diff --git a/TAILWIND.md b/TAILWIND.md deleted file mode 100644 index 76bdf14..0000000 --- a/TAILWIND.md +++ /dev/null @@ -1,577 +0,0 @@ -# Tailwind And Phoenix Asset Tooling For bDS2 Desktop - -## Purpose - -This document describes the target styling architecture for a Tailwind-integrated Phoenix LiveView desktop app in this repository. - -It is written as a handoff for a coding agent that will perform the implementation. - -This is not a migration guide from a public web app. It is a target-state guide for a Phoenix LiveView desktop shell with local assets, dense editor surfaces, overlays, resizable panes, and desktop-specific titlebar behavior. - -## Verified Current State - -The current app does not use the default Phoenix asset pipeline. - -- CSS is served directly from `priv/ui/app.css`. -- JS is served directly from `priv/ui/live.js`. -- Static assets are served from `priv/ui` in `lib/bds/desktop/endpoint.ex`. -- The root layout links `/assets/app.css` in `lib/bds/desktop/layouts.ex`, but that path is currently backed by `priv/ui/app.css`, not by generated Phoenix assets. -- There is no `:tailwind` or `:esbuild` setup in `mix.exs`. - -Relevant files: - -- `lib/bds/desktop/endpoint.ex` -- `lib/bds/desktop/layouts.ex` -- `mix.exs` -- `priv/ui/app.css` -- `priv/ui/live.js` - -## Official Phoenix Facts - -The implementation target should follow Phoenix defaults where they fit the desktop shell. - -Official Phoenix references: - -- Phoenix Asset Management: https://hexdocs.pm/phoenix/asset_management.html -- Phoenix Components and HEEx: https://hexdocs.pm/phoenix/components.html -- Phoenix.Component reference: https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html - -Facts from Phoenix docs and generator templates: - -- Phoenix v1.7+ defaults to Tailwind for CSS and esbuild for JS. -- The default CSS source entrypoint is `assets/css/app.css`. -- The default generated CSS output is `priv/static/assets/css/app.css`. -- The default generated JS output is `priv/static/assets/js/app.js`. -- Phoenix promotes function components and HEEx as the main rendering model. -- Phoenix does not prescribe per-component CSS modules. Tailwind-first HEEx plus shared source CSS is a valid Phoenix-default shape. - -## Target Outcome - -The target outcome is a solid Phoenix-default asset setup with Tailwind as the main styling system and a generated production stylesheet. - -The target should look like this: - -- Tailwind source lives in `assets/css/app.css` and imported CSS modules. -- The final stylesheet is generated into `priv/static/assets/css/app.css`. -- LiveView JS entrypoint lives in `assets/js/app.js` and builds to `priv/static/assets/js/app.js`. -- The desktop endpoint serves static assets from `priv/static`. -- Layouts reference the generated CSS and JS outputs. -- HEEx markup carries most layout, spacing, typography, responsive, and state classes. -- Authored CSS remains for global tokens, app-region behavior, pseudo-elements, scrollbars, Monaco integration, hard selectors, and overlay mechanics. - -## Architecture Rules - -### 1. Tailwind Owns The Common Case - -Use Tailwind utility classes directly in HEEx for: - -- flex and grid layout -- spacing -- typography -- borders and radii -- colors and opacity -- active, selected, disabled, and hover states -- responsive breakpoints -- overflow and truncation - -Do not preserve large semantic wrapper classes when they only encode simple layout decisions. - -Good examples to move into HEEx classes: - -- tab rows -- button rows -- editor header layout -- metadata field layout -- sidebar list row spacing -- status bar item alignment - -### 2. Authored CSS Owns The Desktop-Specific Case - -Keep authored CSS source files for: - -- `app-region` and `-webkit-app-region` -- pseudo-elements used for icons, handles, and active markers -- custom scrollbars -- Monaco/editor iframe or host integration -- absolute overlay stacks and backdrops -- drag and drop affordances -- complex attribute selectors -- hard-to-read repeated combinations that should become shared component classes - -Do not force these into giant utility strings if readability drops. - -### 3. Keep A Thin Semantic CSS Layer - -It is acceptable to keep a small number of semantic component classes when they encode a repeated desktop UI primitive. - -Examples of valid semantic classes in the target state: - -- `.window-titlebar` -- `.resizable-panel-divider` -- `.overlay-root` -- `.monaco-host` -- `.panel-entry` -- `.btn-base`, `.btn-theme-primary`, `.btn-theme-danger` - -These classes should be implemented in Tailwind source CSS using `@layer components` and should remain small, stable, and reusable. - -### 4. Tokens Must Be Centralized - -The current stylesheet relies heavily on VS Code-like CSS variables. Preserve that idea. - -The new `assets/css/app.css` must define the design tokens once, using Tailwind v4 `@theme` plus any required raw CSS custom properties for runtime-driven values. - -Examples from the current app that must survive: - -- shell/background colors -- tab active/inactive colors -- status bar colors -- focus border color -- input background and border colors -- sidebar width -- assistant width -- font family and font size - -### 5. Desktop Layout Constraints Must Stay Intact - -The styling rewrite must preserve these runtime constraints: - -- the app occupies full window width and height -- the shell uses `overflow: hidden` at the top level -- the main workbench uses `min-height: 0` and `min-width: 0` correctly -- resizable sidebars remain width-variable -- titlebar remains draggable except for interactive controls -- overlays render above the shell without breaking keyboard focus or pointer behavior - -## Proposed Asset Layout - -Use the standard Phoenix asset layout. - -```text -assets/ - css/ - app.css - shell.css - sidebar.css - tabs.css - editor.css - forms.css - overlays.css - panel.css - assistant.css - menu_editor.css - media_editor.css - utilities.css - js/ - app.js - ... -priv/ - static/ - assets/ - css/ - js/ -``` - -Recommended responsibilities: - -- `assets/css/app.css`: Tailwind import, `@source`, tokens, base layer, imports -- `assets/css/shell.css`: app shell, titlebar, activity bar, pane shells, status bar -- `assets/css/sidebar.css`: sidebar filters, search, chips, calendar tree, load more -- `assets/css/tabs.css`: workbench tabs and editor tabs -- `assets/css/editor.css`: common editor frame, toolbar, meta column, shared form shell -- `assets/css/forms.css`: shared input, textarea, tag chip, picker, inline action primitives -- `assets/css/overlays.css`: overlay root, modal backdrop, dialog shells, gallery/lightbox -- `assets/css/panel.css`: panel tabs, panel entry cards, tasks, output, git log -- `assets/css/assistant.css`: assistant sidebar and chat-specific shared surfaces -- `assets/css/menu_editor.css`: menu tree, drag/drop indicators, picker lists -- `assets/css/media_editor.css`: media preview, linked post picker, detail forms -- `assets/css/utilities.css`: a very small set of custom utilities that are truly reused - -## Proposed Phoenix Asset Tooling - -The implementation should introduce the standard Phoenix aliases and configs. - -### mix.exs - -Add: - -- `{:tailwind, "~> 0.3", runtime: Mix.env() == :dev}` -- `{:esbuild, "~> 0.10", runtime: Mix.env() == :dev}` - -Add aliases similar to: - -- `assets.setup` -- `assets.build` -- `assets.deploy` - -### Versioning (mandatory) - -The Elixir `:tailwind` wrapper still defaults to Tailwind v3. The plan in this document assumes **Tailwind v4** syntax (`@import "tailwindcss"`, `@theme`, `@source`, `@layer components`). Pin both tools explicitly in `config/config.exs`: - -- `config :tailwind, version: "4.1.14"` (or current 4.1.x) -- `config :esbuild, version: "0.25.4"` (or current 0.25.x) - -Without an explicit v4 pin the build will silently install Tailwind v3 and v4 directives will not resolve. - -### No Node.js policy - -The Elixir `:tailwind` and `:esbuild` wrappers download self-contained binaries and do **not** require Node.js. The implementation MUST stay Node-free unless a third-party Tailwind plugin is later required (in which case the custom `assets/build.js` route from the Phoenix asset_management guide is used). No `package.json` is added under `assets/`. - -### config/config.exs - -Configure Tailwind input and output paths. - -Target output: - -- `assets/css/app.css` -> `priv/static/assets/css/app.css` - -Configure esbuild for: - -- `assets/js/app.js` -> `priv/static/assets/js/app.js` - -esbuild profile must include `--bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/*` and `nodePaths: [Mix.Project.build_path() <> "/../../deps"]` so `phoenix`, `phoenix_html`, and `phoenix_live_view` resolve from `deps/` without an `npm install`. - -### config/dev.exs - -Add Phoenix watchers for: - -- Tailwind `--watch` -- esbuild `--watch` - -### No phx.digest in desktop builds - -This is a desktop app served through an embedded WebView, not a public web app behind a CDN. - -- Do NOT run `mix phx.digest` as part of `assets.deploy`. -- Output filenames stay stable (`app.css`, `app.js`) so the layout can link them by fixed path. -- `assets.deploy` for this repo is: `tailwind default --minify`, `esbuild default --minify`. Nothing else. - -### endpoint/layout changes - -Update the desktop endpoint and root layout to serve and link generated assets from `priv/static/assets` instead of `priv/ui`. - -Specifically: - -- Replace the existing `Plug.Static` for `/assets` with `from: {:bds, "priv/static/assets"}` and `only` listing the generated `css` and `js` directories. -- Drop the `/vendor/phoenix` and `/vendor/live_view` `Plug.Static` blocks; those scripts are now bundled by esbuild from `deps/`. -- Add a dedicated `Plug.Static` for `/monaco` pointing at `priv/ui/monaco` (or move it to `priv/static/monaco`). Monaco is a prebuilt vendor drop and MUST NOT be passed through esbuild. -- Remove the `