Some checks failed
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Blogging Desktop Server (bDS)
Desktop-first blogging workspace built with Electron + TypeScript + React + SQLite (Drizzle), with filesystem-based content as source of truth.
Current State (March 2026)
Implemented and actively used:
- Offline-first by default — full local editing, preview, generation, and git-based workflows; all online features are optional
- Multi-project workflow with active project switching and optional custom data paths
- Post & page management (draft/published/archived), pagination, filtering, multi-language full-text search (Snowball stemming), canonical URL handling, inter-post link graph with backlinks/outlinks, drag-and-drop and paste image insertion directly into the editor
- Post translation system — dedicated translation records per post (title, excerpt, content) stored separately from canonical posts; AI-powered translation via
translatePost; translation panel in the editor showing existing translations, missing languages, and language badges;availableLanguagesexposed across all APIs;doNotTranslateflag for posts that should remain single-language - Media pipeline with import, metadata sidecars, three thumbnail sizes (Sharp), linked-media references, cleanup tooling, and AI-assisted metadata suggestions (title, alt text, caption from image vision)
- Media translation system — language-specific metadata (title, alt, caption) stored in separate translation records and
.lang.metasidecars; AI-powered metadata translation with language detection; automatic cascade from post translation to linked media; translation panel in the media editor - Tag management including merge/rename/sync from content, color support
- Menu editor for hierarchical site navigation (OPML-based), with page picker and submenu nesting
- WordPress WXR import pipeline (analysis, import definitions, 4-phase execution with progress tracking, HTML-to-Markdown conversion)
- Blogmark deep links —
bds://new-postcustom protocol for one-click bookmark saving from any browser, with bookmarklet generation and transform script pipeline - Multi-language blog rendering — configurable
blogLanguageslist in project settings; main language keeps flat routes, additional languages get/{lang}/prefixed subtrees with their own feeds; combinedsitemap.xmlwithhreflangalternates; language switcher in templates; automatic translation on post create/update; "Fill Missing Translations" batch tool;doNotTranslateposts excluded from alternative language subtrees; preview server serves language-prefixed routes matching generated output - Static site generation — full blog output with single-post pages, paginated category/tag/date archive routes, standalone page routes, plus
sitemap.xml,rss.xml,atom.xml, andcalendar.json; content-hash-based incremental writes - Site validation — compares sitemap against generated HTML, detects missing/extra/stale pages, and auto-repairs with targeted re-rendering
- SSH publishing via
scporrsyncwith parallel upload of HTML, thumbnails, and media - Preview server with local assets only, Liquid templates, macro processing, archive routes, draft preview support, and style preview
- Style & theming — 19 Pico CSS color themes with live preview (auto/light/dark modes), all assets served locally
- Template management — user-facing Liquid template editor with CRUD, YAML frontmatter, validation, draft/published workflow, and Git reconciliation; template kinds: post, list, not-found, partial
- Python scripting (Pyodide WebAssembly runtime) — three script kinds:
- Transform scripts — modify incoming blogmark posts before creation
- Macro scripts — custom
[[macro_name ...]]blocks that expand during preview/generation, with full access to the bDS Python API (~116 methods across 11 modules) - Utility scripts — general-purpose Python automation
- Built-in macros —
youtube,vimeo,gallery(lightbox),photo_archive,tag_cloud(D3 word cloud) - Liquid template system for all generated pages with i18n support (English, German, French, Italian, Spanish) and custom Markdown filter with internal link rewriting
- AI assistant (OpenCode Zen API, Mistral direct API, Ollama local models) with streaming responses, tool use (search/read/update posts, media analysis including image vision, blog stats, post and media translation), AI-powered taxonomy analysis, and rich interactive responses via the A2UI protocol (charts, tables, forms, cards, metrics, lists, tabs)
- MCP server — full Model Context Protocol integration exposing the blog to external coding agents; 10 tools, 13 resources, 3 prompts, and interactive review views; supports Streamable HTTP transport (in-app) and stdio transport (standalone CLI); auto-configures into Claude Code, Claude Desktop, GitHub Copilot, Gemini CLI, OpenCode, Mistral Vibe, and OpenAI Codex agent configs
- Model catalog — fetches and caches model metadata from models.dev with conditional GET refresh; provides pricing, context windows, capabilities, and modalities; works fully offline after first fetch
- Secure key storage — API keys encrypted via OS keychain (macOS Keychain, Windows DPAPI, Linux libsecret) using Electron safeStorage
- Git integration (status, diff, commit history with sync status, fetch/pull/push, init, .gitignore management, LFS configure/prune, branch operations)
- Metadata diff tooling for comparing filesystem metadata vs database metadata with sync in either direction, including post and media translation records
- Rich editing — Milkdown WYSIWYG Markdown editor for posts, Monaco code editor for Python scripts and Liquid templates
- Task system for background progress reporting across long-running operations with grouping, cancellation, and status bar integration
- In-app documentation — rendered user guide with navigable table of contents and heading anchors
- i18n — UI language follows OS locale; render/preview language from project preferences; 5 supported languages
Architecture
src/
├── cli/
│ └── bds-mcp.ts # Standalone MCP stdio server (runs without Electron)
├── main/
│ ├── database/ # Drizzle schema, migrations, connection
│ ├── engine/ # Core business logic (no UI)
│ │ ├── PostEngine # Post CRUD, FTS indexing, link graph, translations
│ │ ├── MediaEngine # Media files, Sharp thumbnails, translations
│ │ ├── PostMediaEngine # Post ↔ media linking
│ │ ├── ProjectEngine # Multi-project management
│ │ ├── MetaEngine # Project metadata, categories
│ │ ├── TagEngine # Tag CRUD, merge, rename, colors
│ │ ├── ScriptEngine # Python script management & Git sync
│ │ ├── TemplateEngine # Liquid template CRUD, validation, Git sync
│ │ ├── MenuEngine # OPML-based navigation menus
│ │ ├── PreviewServer # Local HTTP preview with Liquid, language-prefixed routes
│ │ ├── BlogGenerationEngine # Static site generation, multi-language subtrees
│ │ ├── PublishEngine # SSH upload (scp / rsync)
│ │ ├── SiteValidationDiffService # Sitemap ↔ HTML validation
│ │ ├── Import* engines # WXR parsing, analysis, execution
│ │ ├── Blogmark* services # Deep link handling, transforms
│ │ ├── PythonMacroWorkerRuntime # Pyodide macro execution
│ │ ├── GitEngine # Git operations (simple-git)
│ │ ├── MetadataDiffEngine # DB ↔ file metadata comparison (posts, media, translations)
│ │ ├── ChatEngine # AI chat with streaming & tool use
│ │ ├── MCPServer # Model Context Protocol server (HTTP + stdio)
│ │ ├── MCPAgentConfigEngine # Auto-configure MCP into coding agents
│ │ ├── ModelCatalogEngine # Model metadata from models.dev
│ │ ├── SecureKeyStore # OS keychain encryption for API keys
│ │ ├── NotificationWatcher # CLI ↔ app DB change synchronization
│ │ └── TaskManager # Background task queue
│ ├── a2ui/ # A2UI protocol: types, catalog, generator
│ ├── ipc/ # IPC handlers; bridges renderer to engines
│ ├── shared/ # Shared contracts/types (Electron API)
│ └── main.ts # Electron app + menu + window lifecycle
└── renderer/
├── components/ # UI (editor, sidebars, panels, modals, views)
├── a2ui/ # A2UI surface rendering (17 component types)
├── store/ # Zustand app state
├── macros/ # Macro authoring/runtime support
├── python/ # Python scripting UI integration
├── navigation/ # Activity routing, tab policy, sidebar views
└── App.tsx # App composition + event wiring
Data Model & Storage
- Primary DB:
{userData}/bds.db - Projects: stored in DB with an active project
- Per-project data:
- default/internal:
{userData}/projects/{projectId}/ - optional custom
dataPath(posts/media/meta/thumbnails live together)
- default/internal:
- Filesystem remains source of truth for post/media files; DB is query/index/state layer
Typical per-project folders:
{projectDataDir}/
├── posts/
├── media/
├── meta/ # tags, categories, menu.opml
├── scripts/ # Python scripts (.py with YAML frontmatter)
└── thumbnails/ # small / medium / large
Menu / Shortcuts (Cross-Platform)
Key shortcuts (defined as CmdOrCtrl):
CmdOrCtrl+NNew postCmdOrCtrl+IImport mediaCmdOrCtrl+SSaveCmdOrCtrl+1Posts viewCmdOrCtrl+2Media viewCmdOrCtrl+BToggle sidebarCmdOrCtrl+JToggle panelCmdOrCtrl+Shift+PPublish selectedCmdOrCtrl+Shift+VPreview active post in browser
Development
Prerequisites
- Node.js 18+
- npm
Install
npm install
Run (Development)
# Runs main TypeScript watch, Vite dev server, and Electron together
npm run dev
Alternative renderer+Electron flow:
npm start
Tests
npm test
npm run test:watch
npm run test:coverage
Build
# Generates drizzle artifacts, builds main process and renderer
npm run build
# Package app directory only (no installer)
npm run package
# Package distributables for all supported systems
npm run dist
# Package by target platform
npm run dist:mac
npm run dist:win
npm run dist:linux
Distribution Notes
- Custom protocol
bds://is declared in electron-builder metadata for packaged apps. - Build targets: macOS (DMG+ZIP, arm64, notarized), Windows (NSIS, x64+arm64), Linux (AppImage/deb/rpm).
- macOS signing/notarization is scaffolded via
scripts/notarize.mjsand runs when these env vars are set:APPLE_IDAPPLE_APP_SPECIFIC_PASSWORDAPPLE_TEAM_ID
Further Documentation
- DOCUMENTATION.md — end-user guide covering workflows, macros, scripting, AI assistant, and editorial best practices
- API.md — full Python runtime API reference for macro and utility scripts (
bds_apimodule) - VISION.md — long-term product vision and design notes
License
MIT
Languages
TypeScript
94.8%
CSS
4.6%
Liquid
0.3%
JavaScript
0.2%