opening an old chat, unless manually dismissed
bDS2
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 specs in specs/ remain the behavioral contract for the rewrite. For end-user operation, see DOCUMENTATION.md. For the scripting surface, see API.md.
Current Status
The major architectural rework is in place.
- 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/ into 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.
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.
Architecture Overview
Runtime
BDS.Application is the supervision root. It starts the Phoenix endpoint, database, preview and publishing workers, task supervisors, scripting jobs, and the desktop server/window adapters.
At a high level, the stack is:
- Native windowing through the
:desktopintegration. - 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.
Desktop Shell
The desktop workbench lives under lib/bds/desktop/. The main screen is BDS.Desktop.ShellLive, with feature-specific editors and sidebar logic under lib/bds/desktop/shell_live/.
If you are tracing UI behavior, start there first:
- 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/.
Domain Modules
Most application behavior lives under 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 and the ui domain. Locale normalization lives in BDS.I18n, and the desktop shell binds the active UI locale through BDS.Desktop.UILocale.
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/ for Gettext catalogs
- 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/ for Tailwind-based CSS modules
- assets/js/ for LiveView hooks, bridges, Monaco integration, and UI helpers
- 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: Mix project definition, aliases, releases, and dependencies
- config/: runtime, dev, test, and asset configuration
- lib/bds/: core application modules
- lib/bds/desktop/: desktop endpoint, shell, menus, controllers, and window integration
- assets/: Tailwind and esbuild source
- priv/repo/: Ecto migrations and snapshots
- priv/gettext/: UI and render translation catalogs
- specs/: Allium behavior specs
- DOCUMENTATION.md: end-user guide
- API.md: generated scripting API reference
macOS Development Setup
If you are setting up a new macOS machine, install the toolchain first.
1. Install Xcode Command Line Tools
xcode-select --install
2. Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
3. Install Erlang, Elixir, and SQLite
brew update
brew install erlang elixir sqlite
4. Fetch Dependencies And Set Up The App
cd /Users/gb/Projects/bDS2
mix setup
mix assets.setup
Development Workflow
Useful commands:
mix compile --warnings-as-errors
mix test
mix dialyzer
mix assets.build
Notes for developers:
- Specs in specs/ define the intended product behavior.
- DOCUMENTATION.md is for end users, not implementation details.
- 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.