chore: cleaned up documents about plan and status

This commit is contained in:
2026-07-18 21:50:27 +02:00
parent e5080b7282
commit d88aaf111f
9 changed files with 229 additions and 1874 deletions

View File

@@ -25,6 +25,7 @@ Invariants and behaviours in the allium spec should be covered by unit tests of
## Important facts
- update `README.md` whenever a user-visible feature is added, removed, or materially changed; keep it a compact overview with relevant pointers
- published posts don't have body in the database, the body content is only in the file
- functionality you implement have to be tied to UI
- UI you implement has to be tied to functionality

40
README.md Normal file
View File

@@ -0,0 +1,40 @@
# RuDS
RuDS is a native Rust blogging desktop application and the successor to bDS2. It manages local projects from authoring through preview, static-site generation, integrity checks, and publishing while preserving the existing bDS filesystem and SQLite formats.
The project is under active development. Core blogging workflows are broadly available; remaining core work and optional extensions are tracked separately.
## Available Features
- Native Iced desktop workspace with localized menus, tabs, sidebars, dialogs, tasks, and embedded Wry previews.
- Post and translation authoring with draft/published lifecycle, metadata, tags, categories, links, and media.
- Media import, thumbnails, metadata translations, filters, validation, and post assignment.
- Template and Lua script management using a custom Ropey/Syntect/Cosmic Text editor.
- SQLite and filesystem persistence with frontmatter, sidecars, rebuild, metadata diff/repair, and FTS5 search.
- Markdown/Liquid rendering with native macros, multilingual routes, feeds, sitemap, Pagefind, and incremental site generation.
- Local preview in the app or system browser.
- Optional one-shot AI translation, description, analysis, taxonomy, and language-detection operations using online or local OpenAI-compatible endpoints with airplane-mode gating.
- SSH-agent-based SCP or rsync publishing.
- Site, media, and translation validation plus Blogmark capture and Lua transforms.
RuDS uses no JavaScript application runtime and loads no CSS or JavaScript from CDNs. The preview is served by the Rust application and displayed by the operating-system webview.
## Repository Map
- `crates/bds-core` — data, engines, rendering, AI, publishing, and Lua
- `crates/bds-editor` — reusable syntax-highlighting editor
- `crates/bds-ui` — desktop application and platform integration
- `crates/bds-cli` — planned automation CLI
- `specs` — authoritative Allium behavior specifications
- `fixtures` — compatibility projects and generated-site fixtures
- `locales` — UI and native-menu translations
## Plans and References
- [Core plan and current status](RUST_PLAN_CORE.md)
- [Extension plan and current status](RUST_PLAN_EXTENSION.md)
- [Specification index](SPECIFICATION_INDEX.md)
- [UI style guide](docs/UI_STYLE_GUIDE.md)
- `../bDS2` — reference implementation when an Allium contract is ambiguous
Contributor workflow and project invariants are documented in [AGENTS.md](AGENTS.md).

View File

@@ -1,98 +0,0 @@
# bDS Rust Rewrite — Compatibility Matrix Template
## Purpose
This document is the required inventory of persisted fields and compatibility-sensitive behaviors. Fill it before engine implementation starts, then keep it current as the rewrite proceeds.
One row per persisted field or compatibility-sensitive artifact.
## How To Use
1. Start with posts, translations, media, templates, project metadata, menus, and generated outputs.
2. Record the baseline (bDS2, `../bDS2/`) behavior first; the allium specs in `specs/` are the contract.
3. Record the intended Rust behavior only if it is identical or explicitly approved as a divergence.
4. Link every row to tests or golden fixtures once available.
## Field Matrix
| Domain | Entity | Field / Artifact | Type | Current Source Of Truth | Persisted In | Read Path | Write Path | Rebuild From Files | Metadata Diff | Publish Impact | Generation Impact | Rust Status | Fixture / Test | Notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| posts | Post | id | string | DB + frontmatter | DB, frontmatter | | | | | | | not-started | | |
| posts | Post | title | string | | | | | | | | | not-started | | |
| posts | Post | slug | string | | | | | | | | | not-started | | |
| posts | Post | excerpt | string? | | | | | | | | | not-started | | |
| posts | Post | content body | markdown | published body in file; draft body per current app rules | DB?, markdown file | | | | | | | not-started | | |
| posts | Post | status | enum | | | | | | | | | not-started | | |
| posts | Post | author | string? | | | | | | | | | not-started | | |
| posts | Post | language | string? | | | | | | | | | not-started | | |
| posts | Post | do_not_translate | bool | | | | | | | | | not-started | | |
| posts | Post | tags | list | | | | | | | | | not-started | | |
| posts | Post | categories | list | | | | | | | | | not-started | | |
| posts | Post | template_slug | string? | | | | | | | | | not-started | | |
| posts | Post | checksum | string? | | | | | | | | | not-started | | |
| translations | PostTranslation | translation_for | string | | | | | | | | | not-started | | |
| media | Media | alt | string? | | | | | | | | | not-started | | |
| media | Media | caption | string? | | | | | | | | | not-started | | |
| media | MediaTranslation | translationFor | string | | DB | | | | | | | not-started | | |
| media | MediaTranslation | language | string | | DB | | | | | | | not-started | | |
| media | MediaTranslation | title | string? | | DB | | | | | | | not-started | | |
| media | MediaTranslation | alt | string? | | DB | | | | | | | not-started | | |
| media | MediaTranslation | caption | string? | | DB | | | | | | | not-started | | |
| posts | PostLink | sourcePostId | string | | DB | | | | | | | not-started | | |
| posts | PostLink | targetPostId | string | | DB | | | | | | | not-started | | |
| posts | PostLink | linkText | string? | | DB | | | | | | | not-started | | |
| templates | Template | file content | liquid | | | | | | | | | not-started | | |
| scripts | Script | runtime | runtime | Python in current app, Lua in Rust app | app behavior | | | n/a | n/a | yes | yes | approved-divergence | | Explicit break |
| scripts | BlogmarkTransform | transform chain | runtime | Python in current app | app behavior | | | n/a | n/a | no | no | deferred | | Deferred to extension Bucket H |
| menus | MenuDocument | source document | opml/xml | | | | | | | | | not-started | | |
| generation | SiteOutput | route path | path | | generated files | | | n/a | n/a | yes | yes | not-started | | |
| generation | Feed | rss/atom output | xml | | generated files | | | n/a | n/a | yes | yes | not-started | | |
| generation | Sitemap | sitemap output | xml | | generated files | | | n/a | n/a | yes | yes | not-started | | |
| generation | GeneratedFileHash | content hash | string | DB | DB | | | n/a | n/a | yes | yes | not-started | | Skip-unchanged-writes optimization |
| search | PostsFts | FTS5 index | virtual table | DB | DB (FTS5) | | | rebuild | n/a | no | no | not-started | | |
| search | MediaFts | FTS5 index | virtual table | DB | DB (FTS5) | | | rebuild | n/a | no | no | not-started | | |
| search | ClientSearch | search index | binary | generated files | generated files | | | n/a | n/a | yes | yes | not-started | | Determine in M0: integrate via `pagefind` crate library API |
| media | Thumbnail | generated thumbnail | image file | filesystem | filesystem | | | regenerate | n/a | yes | yes | not-started | | `image` crate; verify size/format matches current `sharp` output |
| macros | BuiltInMacro | gallery | Rust-native | app code | n/a | | | n/a | n/a | no | yes | not-started | | Was JS in TS app; Rust in Rust app |
| macros | BuiltInMacro | youtube | Rust-native | app code | n/a | | | n/a | n/a | no | yes | not-started | | Was JS in TS app; Rust in Rust app |
| macros | BuiltInMacro | vimeo | Rust-native | app code | n/a | | | n/a | n/a | no | yes | not-started | | Was JS in TS app; Rust in Rust app |
| macros | BuiltInMacro | photo_archive | Rust-native | app code | n/a | | | n/a | n/a | no | yes | not-started | | Was JS in TS app; Rust in Rust app |
| macros | BuiltInMacro | tag_cloud | Rust-native | app code | n/a | | | n/a | n/a | no | yes | not-started | | Was JS in TS app; Rust in Rust app |
## Behavior Matrix
Use this for compatibility-sensitive behaviors that are not a single persisted field.
| Area | Behavior | Current App Rule | Rust Target Rule | Allowed Divergence | Validation Method | Status | Notes |
|---|---|---|---|---|---|---|---|
| posts | published body storage | body not stored in DB when published | identical | no | fixture DB + file assertions | not-started | |
| localization | UI locale | follows OS locale | identical | no | manual + integration test | not-started | |
| localization | render language | follows project setting | identical | no | preview/generation tests | not-started | |
| menus | native menu routing | current app uses native menus | native menus via muda (cross-platform: NSMenu, Win32, GTK) | implementation changes, behavior identical | menu integration tests | not-started | |
| scripts | user Python scripts | supported in current app | unsupported in Rust app | yes | migration note + runtime detection tests | approved-divergence | |
| rendering | built-in macros | JS server-side (gallery, youtube, vimeo, photo_archive, tag_cloud) | Rust-native in bds-core/render | implementation language changes, output must match | golden-generated-site comparisons | not-started | These are NOT Python macros |
| rendering | Liquid feature subset | liquidjs 10.25 (full spec available) | Rust Liquid (scoped to used subset) | implementation may differ for unused features | template compatibility suite | not-started | Only ~35% of spec used by default templates |
| slugs | slug generation | `transliteration` npm package | `deunicode` Rust crate | possible edge-case differences | slug corpus tests in M0 fixtures | not-started | Verify against real content |
| editor | content editing | Markdown editor + rendered preview | syntax-highlighting Markdown editor (bds-editor: ropey + syntect + cosmic-text) + rendered preview | no | editor + preview integration tests | not-started | |
| preview | asset sourcing | local assets only | identical | no | HTML assertions | not-started | |
| runtime | JS dependency | Electron (Chromium + Node.js) | no JavaScript anywhere — pure Rust + native APIs | yes (intentional) | build verification: no JS in dependency tree | approved-divergence | Supply-chain security constraint |
| runtime | async executor | Node.js event loop | tokio | yes (internal) | n/a | approved-divergence | Used for preview server, publish, file watching |
| media | thumbnail generation | `sharp` (libvips) | `image` crate | output dimensions and format must match | golden-file comparison of thumbnails | not-started | Fallback to `libvips-rs` if quality/perf insufficient |
| generation | client-side search | determine in M0 | `pagefind` crate library API (`PagefindIndex`) | output must match | golden-generated-site comparisons | not-started | Rust library dep, no CLI binary |
| generation | parallel rendering | single-threaded in current app | `rayon` for parallel page rendering | yes (faster, same output) | golden-generated-site comparisons | approved-divergence | Output must be identical regardless of parallelism |
| ai | one-shot AI operations | not in current app | `reqwest` against configurable OpenAI-compatible endpoint | yes (new feature) | mocked endpoint tests | approved-divergence | Translation, alt text, title suggestion. Entirely optional — app works without endpoint configured |
## Status Values
- `not-started`
- `in-progress`
- `verified`
- `approved-divergence`
- `blocked`
## Sign-Off Checklist
- every persisted field used by core is represented
- every approved divergence is explicit
- every row links to a fixture or test before release
- metadata diff, rebuild, and publish implications are filled in for all relevant rows

View File

@@ -1,456 +0,0 @@
# bDS Rust Rewrite — Execution Backlog
## Purpose
This document converts the core and extension plans into execution order. It is organized by milestone first and by crate second.
Rules:
1. Do not pull work forward from a later milestone unless it directly unblocks the current milestone.
2. Keep tasks vertically sliced where possible: engine + UI + tests.
3. Compatibility tasks outrank polish tasks.
4. The allium specs in `specs/` (synced from `../bDS2/specs/` on 2026-07-18) are the behaviour contract. When a task references a spec file, implement what the spec says and cover its invariants with unit tests.
## Status (2026-07-18)
- M0M2: complete (items marked DONE below).
- M3: implemented (all views and the editor exist in `crates/bds-ui/src/views/`); items below are not individually ticked — verify against tests before re-doing anything.
- M4: in progress per git history ("M4 closing" commits). `bds-core/src/render/` exists (generation, macros, markdown, page renderer, routes, site, template lookup). `bds-core/src/ai/` does **not** exist yet — the one-shot AI client is unstarted.
- M5: not started (`bds-core/src/scripting/` is an empty stub; no PublishEngine).
- M6 (below): new — code-vs-spec gaps introduced by the bDS2 spec sync. Fold these in as the milestones they touch come up; none of them should wait for "later" if the code they touch is being written now.
## Milestone M0: Compatibility Baseline
### `bds-core`
- ~~create workspace and crate boundaries (bds-core, bds-editor, bds-ui, bds-cli)~~ **DONE**
- ~~add typed SQLite connection and query layer via `diesel`~~ **DONE**
- ~~add embedded migration loader via `diesel_migrations`~~ **DONE**
- ~~define initial shared model modules with `serde` derives~~ **DONE**
- ~~add checksum (`sha2`) and slug (`deunicode`) utilities~~ **DONE**
- ~~establish error handling conventions: `thiserror` for bds-core, `anyhow` for bds-ui/bds-cli~~ **DONE**
- ~~add `tokio` runtime as workspace dependency (used by bds-ui and bds-cli, not directly by bds-core engine code)~~ **DONE**
### `bds-editor`
- ~~create crate with ropey, syntect, cosmic-text dependencies~~ **DONE**
- ~~implement basic rope buffer wrapper with edit operations~~ **DONE**
- ~~implement syntect integration for markdown highlighting~~ **DONE**
- ~~implement cosmic-text layout for rendering highlighted text~~ **DONE** (measured monospace font metrics via cosmic-text FontSystem/Buffer; OnceLock-cached MonoMetrics replaces hardcoded constants)
- ~~implement basic cursor model (position, move, place by click)~~ **DONE** (up/down/left/right/home/end + click placement)
- ~~implement basic text insertion and deletion~~ **DONE** (insert, backspace, delete forward, enter)
- ~~implement Iced custom widget that composes buffer + highlight + layout + cursor~~ **DONE** (CodeEditor widget with gutter, text, cursor rendering + keyboard/mouse events)
- ~~implement basic vertical scrolling with viewport-aware rendering~~ **DONE** (scroll_by, ensure_cursor_visible, mouse wheel, viewport-clipped rendering)
- ~~verify IME composition events work through winit (early risk check)~~ **DONE** (verified: winit/Iced delivers composed chars via Key::Character; pre-edit display deferred to M3)
### `bds-ui`
- ~~create app entry point with Iced `Application` impl~~ **DONE**
- ~~wire Iced window creation~~ **DONE**
- ~~wire muda menu bar with skeleton App/File/Edit/View/Window/Help menus~~ **DONE** (stub)
- ~~wire macOS lifecycle shim via objc2 (application:openFile:, application:openURLs:) behind cfg gate~~ **DONE** (stub)
- ~~wire muda `MenuEvent` receiver as Iced `Subscription`~~ **DONE** (platform/menu.rs menu_subscription + app.rs subscription)
### `fixtures` and `docs`
- ~~collect representative fixture projects from current app~~ **DONE** (fixtures/compatibility-projects/rfc1437-sample/)
- ~~capture golden generated output for those fixtures~~ **DONE** (fixtures/golden-generated-sites/rfc1437-sample/ — subset from live TypeScript-generated site: 3 post pages × 2 languages, structural files, assets, feeds, sitemap, category page)
- ~~create initial compatibility inventory from the matrix template (must include `mediaTranslations`, `postLinks`, FTS5 tables)~~ **DONE** (docs/COMPATIBILITY_INVENTORY.md)
- ~~create Liquid feature inventory from default templates~~ **DONE** (docs/LIQUID_FEATURE_INVENTORY.md)
- ~~determine whether current app uses Pagefind or another client-side search index — if Pagefind, plan for `pagefind` crate library integration (not CLI binary)~~ **DONE** (confirmed: TypeScript app uses pagefind_extended CLI; Rust will use pagefind crate library API)
- ~~create slug compatibility test suite comparing `deunicode` vs `transliteration` output on fixture content~~ **DONE**
- ~~create Iced architecture patterns document (message design, subscription model, custom widget patterns)~~ **DONE** (docs/ICED_ARCHITECTURE_PATTERNS.md)
### Validation
- ~~DB readability tests (all tables including `mediaTranslations`, `postLinks`, FTS5, and AI/catalog tables)~~ **DONE** (59 unit tests + 29 fixture integration tests)
- ~~app launch smoke test (Iced window + muda menus)~~ **DONE** (tests/app_smoke.rs — type-level tests; muda requires main thread so full launch tested via `cargo run`)
- ~~bds-editor PoC test: renders highlighted markdown, accepts keyboard input, cursor moves~~ **DONE** (tests/editor_poc.rs — 11 integration tests covering highlight + input + cursor + scroll)
- ~~fixture harness test~~ **DONE** (tests/fixture_readability.rs)
- ~~slug compatibility tests~~ **DONE**
## Milestone M1: Data Fidelity
### `bds-core/db`
- ~~verify schema compatibility against existing projects~~ **DONE**
- ~~add FTS5 virtual tables (`posts_fts`, `media_fts`) for in-app full-text search~~ **DONE** (multi-column schema: title/excerpt/content/tags/categories with per-language snowball stemming, 24 languages)
- ~~verify `mediaTranslations` table read/write~~ **DONE**
- ~~verify `postLinks` table read/write~~ **DONE**
### `bds-core/engine`
- ~~implement `ProjectEngine`~~ **DONE**
- ~~implement `PostEngine`~~ **DONE**
- ~~implement `MediaEngine`~~ **DONE**
- ~~implement `PostMediaEngine`~~ **DONE**
- ~~implement `TagEngine`~~ **DONE**
- ~~implement `MetaEngine`~~ **DONE**
- ~~implement metadata diff flow (posts, media, scripts, templates)~~ **DONE**
- ~~implement rebuild-from-filesystem flow~~ **DONE**
### `bds-core/util`
- ~~frontmatter parser/writer via `serde_yaml`~~ **DONE**
- ~~translation file parser/writer~~ **DONE**
- ~~sidecar parser/writer~~ **DONE**
- ~~content hashing support via `sha2`~~ **DONE**
- ~~thumbnail generation via `image` crate (resize, WEBP encoding)~~ **DONE**
- ~~recursive directory traversal via `walkdir` (for rebuild-from-filesystem)~~ **DONE**
### Validation
- ~~round-trip persistence tests~~ **DONE** (38 m1_validation integration tests)
- ~~rebuild tests~~ **DONE**
- ~~metadata diff tests~~ **DONE** (full coverage matrix: 13 post fields, 6 media, 4 template, 5 script)
- ~~golden-file comparisons for written files~~ **DONE**
## Milestone M2: Native Workspace
### `bds-ui/platform`
- ~~muda menu bar: full menu tree with accelerators~~ **DONE** (platform/menu.rs with muda MenuBar, menu_subscription, accelerators)
- ~~menu enable/disable validation synced to app state~~ **DONE** (sync_menu_state() evaluates has_project/has_tab/offline_mode after every state change)
- ~~menu event routing as `Message` variants~~ **DONE** (MenuEvent → Message mapping in app.rs subscription)
- ~~rfd integration for file/folder open and save dialogs~~ **DONE** (platform/dialog.rs with i18n-aware pick_folder/pick_media_files)
- ~~macOS lifecycle shim: file-open and URL-open events forwarded as `Message` variants~~ **DONE** (objc2 BdsAppDelegate with application:openFile: and application:openURLs: → mpsc channel → Message::FileOpenRequested/UrlOpenRequested)
### `bds-ui/app`
- ~~root `Message` enum and `update()` dispatcher~~ **DONE** (Message enum with menu, lifecycle, sidebar, tab, editor variants + update dispatcher)
- ~~app state model~~ **DONE** (AppState with project, sidebar, editor, output panel state; sidebar post list with 500-post limit)
- ~~task surface model~~ **DONE** (engine/task.rs TaskManager with concurrency limit, FIFO queue, progress reporting, cancel support)
### `bds-ui/views`
- ~~workspace layout~~ **DONE** (three-panel layout: sidebar + editor + optional right panel)
- ~~sidebar~~ **DONE** (post list with search, status filter, category/tag counts)
- ~~activity bar~~ **DONE** (VS Code-style 50px bar with SVG icons for Posts/Pages/Media/Scripts/Templates/Tags/Chat/Import/Git/Settings)
- ~~tab bar~~ **DONE** (editor tab bar with open/close/switch)
- ~~status bar~~ **DONE** (bottom bar with project name, task progress)
- ~~project selector~~ **DONE** (project open dialog and recent projects)
- ~~toast notifications~~ **DONE** (overlay toast stack with auto-dismiss, 4 severity levels, i18n messages; replaces output-only notifications)
### Validation
- ~~menu event → `Message` routing integration tests~~ **DONE** (tests/menu_routing.rs — 4 tests: i18n key prefix, all-locale coverage, action count, no duplicates)
- ~~keyboard shortcut integration tests~~ **DONE** (tests/m2_validation.rs — 15 accelerator-bound actions verified)
- ~~rfd dialog invocation tests~~ **DONE** (tests/m2_validation.rs — dialog i18n keys in all 5 locales)
- ~~fixture project open flow test~~ **DONE** (tests/project_flow.rs — 6 tests: create, switch, delete, directory, meta files)
- ~~toast notification tests~~ **DONE** (tests/m2_validation.rs — toast id monotonicity, levels, expiry, message preservation, i18n keys)
- ~~menu enable/disable rule tests~~ **DONE** (tests/m2_validation.rs — project-gated 11 items, tab-gated 4 items, offline-gated 2 items)
## Milestone M3: Authoring
### `bds-editor` (maturation)
- full cursor movement (arrows, word, line, page, home/end)
- selection (shift+movement, click-and-drag, double-click word select)
- system clipboard integration (copy/cut/paste)
- undo/redo with edit grouping
- line numbers gutter
- incremental syntax rehighlighting on edits
- IME input handling for CJK and other input methods
- configurable soft wrap
- additional syntax grammars: Liquid/HTML, Lua, YAML, JSON
### `bds-core/engine`
- expose editor-safe save APIs
- expose publish/unpublish/discard flows
- expose template validation APIs
- expose script validation APIs
### `bds-ui/views`
- sidebar post filtering: text search box, status filter, tag/category filter dropdowns, language filter, year/month selectors, date range picker — wired to existing `PostSearchFilters` / `search_posts_filtered()` in bds-core. The 500 post limit applies AFTER filtering, not before.
- dashboard
- post editor (bds-editor with markdown + YAML frontmatter highlighting)
- translation editor (bds-editor)
- media browser
- media editor
- tags view
- settings view
- templates view and editor (bds-editor with Liquid/HTML highlighting)
- scripts view and editor (bds-editor with Lua highlighting)
### `bds-ui/components`
- inputs
- modals
- reusable list rows and panels
### Validation
- entity create/edit/save flows
- template validation flow
- script validation flow
- editor widget tests: cursor movement, selection, undo/redo, clipboard, IME
## Milestone M4: Rendering Parity
### `bds-core/render`
- markdown render pipeline via `pulldown-cmark`
- Liquid render pipeline via `liquid` crate (scoped to the feature subset documented in the Liquid inventory: `if`/`elsif`/`else`, `for`, `assign`, `render`, whitespace stripping, plus filters: `default`, `escape`, `url_encode`, `append`; `.size` is property access on arrays, not a pipe filter)
- custom Liquid filter: `i18n` (translation lookup by key and language)
- custom Liquid filter: `markdown` (markdown-to-HTML with macro expansion, URL rewriting, media path canonicalization)
- built-in macro renderers: `gallery`, `youtube`, `vimeo`, `photo_archive`, `tag_cloud` (native Rust, not Lua)
- template resolution rules
- URL rewriting
- RSS/Atom feed generation via `quick-xml`
- sitemap generation via `quick-xml`
- generated file hash tracking (`generatedFileHashes` table for skip-unchanged-writes)
- Pagefind search index generation via `pagefind` crate library API (`PagefindIndex::add_html_file()` + `get_files()`) — if required for parity (determine in M0 inventory)
### `bds-core/ai`
- one-shot AI client: `reqwest` + `serde_json` against OpenAI-compatible Chat Completions endpoint
- two-endpoint configuration: online endpoint (URL, API key, model) + airplane mode endpoint (URL, model)
- AI translate post operation (title, excerpt, content to target language)
- AI translate media metadata operation (title, alt, caption to target language)
- AI image description / alt text generation operation
- AI post analysis operation (title, excerpt, slug suggestion)
- AI taxonomy analysis operation (tag, category suggestions)
- AI language detection operation
- API key storage via OS keychain (macOS Keychain, Windows DPAPI, Linux libsecret)
- airplane mode gating: block online endpoint, use airplane endpoint or show toast
- error handling: surface failures as user-visible feedback, never silent
### `bds-core/engine`
- `TemplateEngine`
- `PageRenderer` (parallelize rendering via `rayon`)
- `BlogGenerationEngine`
- `PreviewServer` (localhost HTTP via `axum` on `tokio`)
- `SearchIndexEngine` only if required for parity
### `bds-ui/views`
- internal Markdown/Preview switch backed by Wry, plus external Open in Browser command
- generation progress display
- render errors and diagnostics
- AI operation triggers in post editor (analysis, taxonomy), translation editor (translate), and media editor (alt text, translate)
- AI endpoint configuration in settings view (online + airplane mode endpoints)
### Validation
- golden generated-site comparisons
- preview route coverage
- template compatibility suite
- one-shot AI client tests (mocked endpoint: all 6 operations)
- AI endpoint configuration persistence tests
- AI airplane mode gating tests
## Milestone M5: Operate And Ship
### `bds-core/engine`
- `PublishEngine` (SSH/SCP via `ssh2`, rsync via child process)
- validation and integrity services
- filesystem watcher via `notify` (if needed for detecting external changes to open content)
### `bds-core/scripting`
- `ScriptEngine`
- `LuaRuntime` via `mlua` (Lua 5.4, vendored) — user-authored scripts only; built-in macros are native Rust in `bds-core/render`
- `LuaApi` (expose post, media, tag, and project data to Lua scripts via `mlua::UserData` trait)
- user-authored Lua macro execution at render time
- user-authored transform and utility script execution
- scripting docs generator
### `bds-ui/views`
- publish workflow screens
- publish progress and failure surfaces
- script docs access points if needed for core usability
### Validation
- publish end-to-end tests
- Lua API bridge tests
- built-in macro compatibility tests
- docs sync tests
## Milestone M6: bDS2 Spec Parity
Code-vs-spec gaps from the 2026-07-18 spec sync. Each task names its authoritative spec. Schema changes go through generated Diesel migrations, and every new metadata field must be wired into publishing, metadata-diff, and rebuild-from-filesystem together.
### `bds-core/util`
- slug uniqueness: unbounded numeric suffix `{slug}-2, -3, …` — remove the 999 cap and timestamp fallback in `util/slug.rs` (post.allium)
### `bds-core/db`
- migration: add `cache_read_tokens` and `cache_write_tokens` (nullable integers) to `ai_usage` (schema.allium)
- migration: rename `npm``package_ref` and align `provider_npm` naming (schema.allium)
- media FTS search: accept structured `filters` alongside the query (search.allium `SearchMediaRequested(query, filters)`)
### `bds-core/engine`
- project open: discover `data_path` from the location of `meta/project.json`; never persist it in project.json; keep a machine-local project registry under the OS app-data dir (project.allium `DiscoverProjectDataPath`, `DataPathNotPersistedInProjectJson`)
- verify public/private data placement matches project.allium (`PublicContentLivesInProjectFolder`, `PrivateArtifactsLiveInOsAppDir`): DB, embeddings index, model cache, registry, and window state in the OS app-data dir; everything user-owned in the project folder
- menu: file-only model (no DB table), `HomeAlwaysFirst` normalization, `SyncMenuFromFilesystem` flow (menu.allium)
- media: optional import metadata (title, alt, caption, author, language, tags), `ReplaceMediaFile` flow, batch-import linked-image processing (media.allium)
- metadata diff: compare only translation-specific fields for translation files; per-item repair direction; `embedding` entity type (metadata_diff.allium)
- translations: `ReopenPublishedTranslation` on edit; `TranslationFilesCarryFullMetadata` (translation.allium)
- auto-translation pipeline: `ScheduleAutoTranslation`, `AutoTranslatePost`, `AutoTranslateMediaCascade`, `FillMissingTranslations` — gated by configured AI endpoint and airplane mode, skips `doNotTranslate`, fills only missing languages (translation.allium; depends on M4 AI client)
- task manager: allow cancelling `pending` (queued) tasks, not only running ones (task.allium)
### `bds-core/render` (fold into M4)
- implement rendering.allium as the shared render-assigns contract for preview and generation; content language only, never UI locale
- expose `slugify` as a custom Liquid filter alongside `i18n` and `markdown` (rendering.allium)
- generation task structure: task group with one task per section (Site Core, Single Posts, Category/Tag/Date Archives) + final Build Search Index task; stream one progress message per written page — "Generated /url (n/total)" or "Rewrote …" for validation apply (generation.allium)
- enforce `GenerationPublishedOnly` and the specified language variant selection (generation.allium)
### `bds-core/ai` (fold into M4)
- honour ai.allium invariants in the one-shot client and settings: endpoint add/remove rules, advisory model catalog with conditional refresh, provider detection, vision capability gate, airplane-mode model swap
- record cache token usage in `ai_usage` (schema.allium)
### `bds-core/scripting` (fold into M5)
- configurable `script_extension` (default "lua"): file path `scripts/{slug}.{extension}`; entrypoint default "render" for macros, "main" otherwise (script.allium, frontmatter.allium)
- sandboxed Lua runtime: no filesystem mutation, process control, or package loading; host capabilities only via explicit `bds.*` API (script.allium `SandboxedExecution`, `ExplicitHostCapabilities`)
- enforce config limits: macro timeout 10s; transform toasts max 5/script, 20 total, 300 chars; blogmark title ≤ 200, URL ≤ 2048 (script.allium)
### `bds-ui`
- settings: technology section (semantic similarity toggle), data section (rebuild buttons: posts/media/scripts/templates/links/thumbnails/embedding + Open Data Folder), agent integrations (Claude Code + GitHub Copilot; others disabled with "not supported yet" note), image import concurrency (18, default 4), default editor mode, settings in a separate tab (editor_settings.allium)
- media search filter UI wired to the filtered media search
- auto-translation and repair-direction UI hooks for the engine flows above
### Validation
- unit tests for every invariant and rule named above, per AGENTS.md spec-coverage requirement
- re-run `allium check specs/*.allium` after any spec edit
## Extension Backlog
### Bucket A: Git And Validation
#### `bds-core`
- `GitEngine` via `git2` (shell out for LFS operations)
- richer site validation service support
#### `bds-ui`
- Git sidebar
- diff view
- richer metadata diff UI
### Bucket B: Import
#### `bds-core`
- WXR parser
- import analysis
- import execution
- import definitions
#### `bds-ui`
- import wizard
- import progress and result views
### Bucket C: AI Chat And Tool Use
#### `bds-core`
- streaming client extension (SSE parsing on top of core `reqwest` client)
- tool execution framework (tool definitions, call routing, result formatting)
- multi-turn conversation management
#### `bds-ui`
- chat sidebar
- chat panel
- provider settings UI (extends core AI endpoint configuration)
### Bucket D: Embeddings And Duplicates
#### `bds-core`
- embedding engine via `ort` (ONNX Runtime)
- vector index via `usearch` (HNSW)
- duplicate detection logic
#### `bds-ui`
- semantic search UI
- duplicates view
### Bucket E: Translation QA And Docs UX
#### `bds-core`
- translation validation engine
#### `bds-ui`
- translation validation view
- documentation browser
### Bucket F: Menu Editing And Deep Links
#### `bds-core`
- menu editing services
- deep-link flow support beyond core shell hooks
#### `bds-ui`
- menu editor UI
### Bucket G: MCP And Automation
#### `bds-cli`
- CLI command set per cli.allium: `rebuild | repair | render | upload | push | pull | post | media | gallery | config | project | lua` — same database, settings, and cache as the GUI; no listeners, no window; logging redirected to the rotating log file
- MCP server surface per mcp.allium (incl. translation tools, stats/media resources, proposal status)
- CLI-to-app synchronization via the domain event bus (events.allium): entity mutations broadcast `(entity, entity_id, action)` on one topic shape covering in-app and external writes
#### `bds-core`
- domain event bus (events.allium): broadcast after every successful mutation of posts, media, tags, templates, scripts; `SettingsChangedEvent` for global settings
### Bucket K: Headless Server Mode (server.allium)
#### `bds-core` / `bds-cli`
- boot modes desktop | server | tui resolved from an env var at start
- headless server: no window; SSH transport for remote TUI/GUI clients
- SSH key material generated on first boot in the private app-data dir (host key + empty authorized_keys, mode 600) — never in the repo or project folder
### Bucket L: Terminal UI (tui.allium)
#### new crate `bds-tui` (or feature in `bds-cli`)
- TUI as a second renderer over the same shared UI core: sidebar views (posts/media/templates/scripts/tags/settings/git), sidebar/editor focus model, vim-style + arrow navigation skipping section headers
- post editor drives the same workflow as the GUI: canonical-language edits update the post, other languages update translations; publish routes through the same pipeline
- subscribes to the domain event bus (Bucket G) for live updates
### Bucket H: Blogmark And Transforms
#### `bds-core`
- `BlogmarkTransformService`
- transform script chain execution
#### `bds-ui`
- external content capture workflow
### Bucket J: A2UI Surfaces
#### `bds-ui`
- A2UI component renderer
- A2UI surface manager
- AI assistant dynamic surface integration
## Exit Rule
Do not start extension buckets until Milestones M5 and M6 are complete and the Rust app is already a credible replacement for the baseline authoring and publishing workflow.

View File

@@ -1,120 +0,0 @@
# bDS Rust Rewrite Plan
bDS is a blogging desktop system. The behavioural baseline is **bDS2**, an Elixir (Phoenix LiveView) implementation living in:
../bDS2/
This project (RuDS) rewrites it in Rust. For any implementation detail, look into ../bDS2/ — the Elixir code there is "the truth" about the current implementation. The old TypeScript app at ../bDS is historical and no longer the reference.
## Spec Baseline
The authoritative behaviour contract is the allium spec set in `specs/`, synced wholesale from `../bDS2/specs/` on 2026-07-18 (46 files, all pass `allium check`). Rules:
- When spec and Rust code disagree, the spec wins; when the spec is ambiguous, the bDS2 Elixir code wins.
- Five specs are new with the bDS2 sync and have **no Rust implementation yet**: `rendering.allium` (core scope — render assigns/filters/macros shared by preview and generation), `cli.allium`, `events.allium`, `server.allium`, `tui.allium` (all extension scope).
- The concrete code-vs-spec gaps are tracked in RUST_EXECUTION_BACKLOG.md under "Milestone M6: bDS2 Spec Parity".
- When re-syncing specs from bDS2, re-run `allium check specs/*.allium` and refresh the M6 gap list.
This plan is split into multiple documents:
- [RUST_PLAN_CORE.md](RUST_PLAN_CORE.md) — the shipping core. This must already be a fully functioning blogging app: create, edit, preview, generate, and publish content using the exact same on-disk and generated formats as the current app.
- [RUST_PLAN_EXTENSION.md](RUST_PLAN_EXTENSION.md) — parity work and advanced tooling that can land after the core app is usable.
- [RUST_EXECUTION_BACKLOG.md](RUST_EXECUTION_BACKLOG.md) — implementation backlog grouped by milestone and crate.
- [RUST_COMPATIBILITY_MATRIX_TEMPLATE.md](RUST_COMPATIBILITY_MATRIX_TEMPLATE.md) — template for the required persistence and compatibility inventory.
## Non-Negotiable Constraints
1. **Content compatibility is exact.** Existing SQLite data, markdown/frontmatter, translation files, media sidecars, templates, menu documents, generated HTML structure, feeds, and sitemaps must remain readable and writable by the Rust app.
2. **No JavaScript application runtime.** No npm, Node.js, Electron, or remotely loaded application assets. The required in-editor and style preview panels use Wry to display the localhost-only Rust preview server in the operating system webview; the separate Open in Browser command opens the same preview in the system browser. Pagefind is integrated as a Rust library dependency (`pagefind` crate), not as an external binary.
3. **Script compatibility is intentionally broken.** Python/Pyodide is removed. Rust bDS is a green-field app and uses Lua for user-authored scripting. Existing Python scripts are not carried forward as compatible runtime artifacts. Built-in macros (gallery, youtube, vimeo, photo_archive, tag_cloud) are re-implemented as native Rust, not routed through Lua.
4. **Core release ships as a native desktop app.** Primary target is macOS, but the UI stack (Iced + muda + rfd) is cross-platform from day one. Native menus, key handling, open-file/deep-link handling, and platform command routing are part of core scope, not follow-up polish.
5. **Template editing is core scope.** Template rendering without template management UI is not sufficient.
6. **Script API docs remain mandatory.** The runtime changes to Lua, but the app still ships and generates proper scripting API documentation.
7. **Split localization is mandatory.** UI locale follows the OS. Rendered and previewed content language follows project settings.
## UI Technology Stack
The application uses the following UI and platform integration stack:
| Layer | Technology | Purpose |
|---|---|---|
| UI framework | **Iced** (Elm architecture) | Application layout, views, widgets, event loop |
| Text editing | **ropey** + **syntect** + **cosmic-text** | Custom syntax-highlighting editor widget for markdown, Liquid templates, and Lua scripts |
| Native menus | **muda** | Cross-platform native menu bar (NSMenu on macOS, Win32 menus on Windows, GTK/dbus on Linux) |
| File dialogs | **rfd** | Cross-platform native file/folder dialogs (NSOpenPanel/NSSavePanel on macOS, equivalents elsewhere) |
| Internal preview | **wry** | Embedded post and style preview panels backed only by the localhost Rust preview server |
| Platform lifecycle | **objc2** (macOS only, cfg-gated) | Thin shim for `application:openFile:`, `application:openURLs:`, and other `NSApplicationDelegate` hooks |
### Why this stack
- **Iced** is a published crate with versioned releases, proper documentation, and a stable API. It uses wgpu for GPU-accelerated rendering and follows the Elm architecture (Message → update → view).
- **muda** and **rfd** render through real platform APIs (NSMenu, NSOpenPanel, etc.) with zero fidelity loss versus hand-rolled platform code, while providing cross-platform support from day one.
- **wry** preserves the baseline app's internal Markdown/Preview workflow using the operating system webview. It is a presentation surface for the loopback preview server, not the application runtime; external-browser preview remains available separately.
- **ropey + syntect + cosmic-text** gives full control over the editor experience: rope-based efficient text storage, Sublime Text syntax grammars (markdown, Liquid, Lua), and proper font shaping and layout via the same engine used by cosmic-DE.
- The only platform-specific code is a small (~50 line) lifecycle shim for macOS app delegate hooks, conditionally compiled via `cfg(target_os = "macos")`. Linux and Windows equivalents are bounded and isolated to the same module.
## Workspace Shape
```text
bds-rust/
├── Cargo.toml
├── crates/
│ ├── bds-core/ # engines, models, rendering, publishing
│ ├── bds-editor/ # custom Iced editor widget (ropey + syntect + cosmic-text)
│ ├── bds-ui/ # Iced application, views, platform integration (muda, rfd)
│ └── bds-cli/ # later, optional automation surface
├── migrations/
├── locales/
├── assets/
└── docs/
└── scripting/ # generated Lua API docs + guides
```
### Crate responsibilities
- **bds-core**: all engines, models, persistence, rendering, publishing — zero UI dependencies.
- **bds-editor**: reusable Iced custom widget for syntax-highlighting text editing. Depends on ropey, syntect, cosmic-text, and iced. Does not depend on bds-core. Can be extracted as a standalone crate.
- **bds-ui**: application shell, Iced views and components, embedded localhost preview (wry), message routing, platform integration (muda for menus, rfd for dialogs, objc2 shim for macOS lifecycle). Depends on bds-core and bds-editor.
- **bds-cli**: headless automation surface. Depends on bds-core only.
## Distribution Characteristics
- **Single application binary.** No Electron or Node.js runtime. Lua and SQLite are compiled into the binary; internal preview uses the operating system webview supplied by the target platform.
- **Binary size:** ~1525 MB.
- **Memory usage / startup:** no BEAM VM or bundled browser engine — one native application process plus the operating system webview used while preview is visible.
- **Platform prerequisites:** macOS uses the system WebKit runtime. Windows/Linux packaging must account for Wry's platform webview prerequisites without adding an application-managed JavaScript runtime.
## Split Rationale
The old single-file plan mixed three categories of work:
- work required to ship a real replacement for the current app
- work required for eventual feature parity
- work that is valuable but not on the critical path to replacing the baseline app
The new split keeps the shipping path narrow. Core is only the work needed to replace the current app for everyday authoring and publishing. Extensions carry the rest.
## Release Gates
The Rust rewrite is not considered successful until the core release can do all of the following with existing bDS project data:
1. Open a real project created by the baseline app.
2. Create and edit posts, translations, media, tags, templates, and settings.
3. Preview drafts and published content both in the post editor's internal preview panel and in the external system browser.
4. Generate a complete site whose output matches the current app modulo approved normalization differences.
5. Publish the generated output to a remote target.
6. Rebuild the database from files and run metadata diff without losing information.
7. Operate as a native desktop application with native menus and command handling.
## Verification Baseline
Both plan documents assume the same verification baseline:
1. Fixture projects exported from the current app are the compatibility corpus.
2. Golden-file tests compare Rust-written files against baseline-written files.
3. Golden-output tests compare generated sites between the current app and the Rust app.
4. No feature is complete until both UI behavior and underlying engine behavior are covered.
## Repository Strategy
This repository (RuDS) is the Rust rewrite, kept separate from the baseline. `../bDS2` remains the stable reference implementation and fixture source; compatibility fixtures are pulled from it on a controlled cadence and generated output is compared here.

File diff suppressed because it is too large Load Diff

View File

@@ -1,263 +1,132 @@
# bDS Rust Rewrite — Extension Plan
# RuDS Extension Plan
## Goal
Deliver the rest of current-app parity and the advanced tooling that is valuable, but not required to ship a production-capable Rust replacement for everyday authoring and publishing.
Extensions add migration, collaboration, automation, alternate clients, and advanced discovery on top of the core blogging workflow. They must reuse core engines and formats, remain reachable through real UI or automation surfaces, and preserve airplane-mode and localization rules.
Extensions begin only after the core plan is already usable end to end.
Status describes the current source code as of 2026-07-18. Core one-shot AI, publishing, rendering, and integrity work is tracked in [RUST_PLAN_CORE.md](RUST_PLAN_CORE.md).
## Extension Principles
## Current Extension Status
1. No extension may break the core compatibility contract.
2. Extensions must reuse core models, engines, and persistence rules rather than invent parallel formats.
3. UI features must still be tied to underlying functionality; no placeholder shells.
4. AI features remain gated by offline mode and must prefer local models or provide explicit user feedback when unavailable. One-shot AI operations (6 operations: translate post/media, image alt text, post analysis, taxonomy analysis, language detection) are part of core with two configurable OpenAI-compatible endpoints (online + airplane mode), and respect the same offline gating.
5. Extensions use the same Iced + muda + rfd platform stack as core. No additional UI frameworks.
### Git and richer validation — Partly done
## Extension Buckets
Done:
### Bucket A: Git And Validation Tooling
- Site, media, translation, and metadata-diff engines and UI views.
#### Scope
Open:
- `GitEngine` via `git2` crate (shell out for LFS operations — no LFS library binding)
- Git sidebar
- diff view
- commit, fetch, pull, push
- richer site validation views
- richer metadata diff UI
- `GitEngine`, repository status, history, diff view, commit, fetch, pull, push, and LFS command integration.
- Replace the Git sidebar and Git log placeholders with working flows.
#### Why extension
### WordPress import — Open
Helpful for operators, but not required to create, preview, generate, and publish content.
Open:
#### Done when
- WXR parsing, import analysis, recoverable execution, saved import definitions, and import UI.
- The existing media importer is core functionality and does not implement this workflow.
- users can inspect repo state and diffs from within the app
- Git actions work reliably enough to replace the current Git tooling
### Conversational AI and agent tools — Open
### Bucket B: Import And Migration Tooling
Open:
#### Scope
- Conversation persistence and chat UI.
- Streaming OpenAI-compatible responses and tool-call parsing.
- Tools over posts, media, templates, search, and other core engines.
- Agent integrations such as Claude Code and Copilot where required by the specs.
- Replace the current Chat placeholders with the working feature.
- WXR parser
- import analysis
- import execution
- saved import definitions
Core endpoint settings, offline gating, key storage, model discovery, and six one-shot operations are already implemented.
#### Why extension
### Embeddings, semantic search, and duplicates — Open
Important onboarding feature, but not required to operate existing bDS projects.
Existing source contains schema placeholders only.
#### Done when
Open:
- WordPress import flows are usable and recoverable
- import results match the current app's expectations closely enough for fixture-based tests
- Embedding generation and persistence.
- Vector index and semantic search.
- Duplicate detection, dismissed-pair handling, metadata integrity, and UI.
- Replace the Find Duplicates placeholder.
### Bucket C: AI Chat And Tool Use
### Translation QA and documentation UX — Partly done
#### Scope
Done:
- chat UI (sidebar panel with conversation history)
- streaming responses via `reqwest` (SSE / chunked transfer)
- tool use against local engines (post lookup, media search, template info, etc.)
- multi-turn conversation management
- model and credential settings UI (extends the core AI endpoint configuration)
- Translation validation engine and report view.
One-shot AI operations (translation, image alt text, title suggestion) are already in core scope. This bucket adds the interactive, conversational AI layer on top.
Open:
The AI client extends the core `reqwest` + `serde_json` client with streaming support and tool-call parsing. Works with any OpenAI-compatible endpoint: OpenAI, Anthropic-via-proxy, local Ollama, etc.
- In-app project documentation browser.
- Browsable Lua API documentation and examples.
- Replace Documentation and API Documentation placeholders.
#### Hard constraints
The generated Lua documentation itself is a core requirement.
- offline mode gates all automatic AI work
- cloud providers are disabled when offline mode is enabled
- local providers remain usable when allowed
- unavailable operations produce explicit user-visible feedback
### Menu editor and deep links — Partly done
#### Done when
Done:
- AI chat is useful for content-related queries and actions without weakening the app's offline guarantees
- Streaming and tool use work reliably with at least one OpenAI-compatible provider
- Menu file parsing/rendering, Home-first normalization, macOS URL plumbing, and Blogmark deep-link parsing.
### Bucket D: Search, Embeddings, And Duplicate Detection
Open:
#### Scope
- OPML/menu editor UI.
- Remaining application deep-link parity flows.
- Replace the Menu Editor placeholder.
- ONNX embeddings via `ort` (ONNX Runtime Rust bindings)
- HNSW vector index via `usearch`
- semantic search UI
- duplicate detection UI
### CLI, MCP, and domain events — Open
#### Why extension
Open:
Improves discovery and cleanup, but not required for core publishing flows.
- Implement `bds-cli`; its current binary is only a stub.
- Commands from `cli.allium` and `cli_sync.allium` using the same project, database, engines, and settings as the desktop app.
- MCP tools/resources and proposal-based writes from `mcp.allium`.
- Domain event bus from `events.allium` for desktop, CLI, TUI, and future remote clients.
- Replace the MCP settings placeholder.
#### Done when
### Blogmark and transform pipeline — Mostly done
- near-duplicate detection and semantic search are trustworthy on real projects
Done:
### Bucket E: Translation QA And Documentation UX
- Blogmark deep-link parsing, content capture, post import, transform selection, and Lua transform execution.
#### Scope
Open:
- translation validation engine and report view
- in-app documentation browser
- richer scripting docs browser and examples
- Complete the dedicated user-facing capture/review workflow where the current implicit flow does not cover the bDS2 behavior.
- Close remaining transform-chain differences found against the specs and bDS2.
#### Why extension
### Headless server — Open
Operationally valuable, but the core release can ship with generated markdown docs and without dedicated browsing surfaces.
Open:
#### Done when
- Desktop/server/TUI boot-mode selection.
- Headless engine host and SSH transport.
- Private host-key and authorized-key management.
- Desktop connection flow for remote projects.
- translation integrity issues are discoverable before publish
- docs are comfortably browsable in-app
### Terminal UI — Open
### Bucket F: Menu Editing And Deep Links
Open:
#### Scope
- Terminal renderer over shared application workflows.
- Sidebar/editor navigation, editing, publishing, and live domain-event updates.
- Remote operation through the headless server.
- menu editor UI for OPML/menu documents
- deep-link protocol handling beyond core app-open behaviors
### A2UI surfaces — Open
#### Why extension
Open:
Core must read menu documents for rendering compatibility, but editing them can follow once the main authoring path is stable.
- A2UI component renderer, surface state/data flow, and AI-assistant integration.
#### Done when
## Suggested Order
- users can inspect and edit menus from the Rust app
- deep links cover parity flows from the current app
1. Git workflow and WordPress import.
2. CLI, MCP, and domain events.
3. Conversational AI and agent tools.
4. Embeddings and duplicate detection.
5. Documentation and menu UX.
6. Headless server and TUI.
7. A2UI after conversational AI exists.
### Bucket G: MCP And Automation Surfaces
#### Scope
- workspace CLI per `cli.allium`: `rebuild | repair | render | upload | push | pull | post | media | gallery | config | project | lua` — boots the same repo, settings, and database as the desktop app, with no listeners and no window; logging to the rotating log file
- MCP server per `mcp.allium` (translation tools, stats and media resources, proposal workflow)
- domain event bus per `events.allium`: every successful entity mutation (posts, media, tags, templates, scripts) broadcasts `(entity, entity_id, action)`; global settings changes broadcast a settings event. One topic/payload shape covers in-app mutations and external CLI writes, replacing the old `db_notifications` polling design. The bus also feeds the TUI (Bucket L) and any future multi-client sync.
#### Why extension
Useful ecosystem surface, not required to replace the desktop app itself.
#### Done when
- automation consumers can drive the Rust app safely and consistently
- CLI changes are detected and surfaced to the running desktop app via the event bus
### Bucket H: Blogmark And Transform Pipeline
#### Scope
- `BlogmarkTransformService`
- external content capture (bookmarklet) workflow
- transform script execution chain
- integration with Lua transform scripts
#### Why extension
Secondary content-capture workflow. Not required for core authoring with existing projects.
#### Done when
- external content can be captured and transformed into posts via the Blogmark pipeline
- transform scripts execute reliably
### Bucket K: Headless Server Mode
#### Scope
Per `server.allium`:
- boot modes `desktop | server | tui` resolved from an environment variable at application start
- headless server: full engine, no window, SSH transport for remote TUI/GUI clients
- SSH key material (host key + authorized_keys, mode 600) generated on first boot into the private OS app-data dir — never the repo or the project folder
- GUI "connect to server" flow
#### Why extension
Client/server split is new bDS2 capability, not needed to replace the desktop app for local use.
#### Done when
- the app can run headless and accept an SSH-transported client session against real project data
### Bucket L: Terminal UI
#### Scope
Per `tui.allium` — a second renderer over the same shared UI core:
- sidebar views (posts, media, templates, scripts, tags, settings, git) with sidebar/editor focus model and vim-style + arrow navigation that skips section headers
- post editor driving the same workflow as the GUI: canonical-language edits update the post, other languages update translations, publish routes through the same pipeline
- live updates via the domain event bus (Bucket G)
#### Why extension
Second renderer; requires the shared UI core and (for remote use) Bucket K.
#### Done when
- everyday authoring (browse, edit, publish) works in a terminal against the same project data as the GUI
### Bucket J: A2UI Server-Driven Surfaces
#### Scope
- A2UI component renderer (layout, input, display, chart, etc.)
- A2UI surface manager for bidirectional data flow
- integration with AI assistant outputs
#### Why extension
Tightly coupled to the AI feature set (Bucket C). Not required until AI features are active.
#### Done when
- AI-generated dynamic UI surfaces render correctly in the app
## Suggested Extension Ordering
```text
Bucket A Git + Validation
Bucket B Import
Bucket C AI
Bucket D Embeddings + Duplicates
Bucket E Translation QA + Docs UX
Bucket F Menu Editing + Deep Links
Bucket G MCP + Automation
Bucket H Blogmark + Transforms
Bucket K Headless Server Mode
Bucket L Terminal UI (after Buckets G + K)
Bucket J A2UI Surfaces (after Bucket C)
```
The ordering is pragmatic, not mandatory. Git and validation are the closest to operational parity, so they should land first after core.
## Extension Verification
Every extension still inherits the core verification baseline plus extension-specific tests:
- Git fixtures for repo state and diff rendering
- WXR fixtures for import
- mocked SSE and provider fixtures for AI
- embedding fixtures for semantic search and duplicate detection
- translation fixture projects with intentional integrity failures
- OPML fixtures for menu editing
## Out Of Scope For Now
- cross-platform packaging polish beyond what the core and extension work naturally require
- feature work that introduces new persistence formats before full parity is reached
The order may change when an extension directly unlocks a concrete user workflow; it must not create a parallel data model or bypass core engines.

View File

@@ -207,11 +207,8 @@ Diese Datei dient als Index zu allen Allium-Spezifikationen und Schema-Inventari
| Datei | Beschreibung |
|-------|--------------|
| `RUST_PLAN.md` | Haupt-Plan mit Non-Negotiable Constraints |
| `RUST_PLAN_CORE.md` | Detaillierter Core-Plan (886 Zeilen) |
| `RUST_PLAN_EXTENSION.md` | Extension Buckets A-J |
| `RUST_EXECUTION_BACKLOG.md` | Milestone-basierte Aufgabenliste |
| `RUST_COMPATIBILITY_MATRIX_TEMPLATE.md` | Vorlage für Metadata-Inventory |
| `RUST_PLAN_CORE.md` | Core-Umfang mit aktuellem Implementierungsstand und offenen Punkten |
| `RUST_PLAN_EXTENSION.md` | Extensions mit aktuellem Implementierungsstand und offenen Punkten |
## Spezifikations-Abdeckungs-Analyse

View File

@@ -1,106 +0,0 @@
# bDS Compatibility Inventory: TypeScript vs Rust
Tracks feature parity between the TypeScript bDS app and the Rust rewrite (RuDS).
Legend: `[x]` implemented/verified, `[ ]` not yet implemented
---
## Database Schema
- [x] projects table
- [x] posts table (with published_* legacy columns)
- [x] post_translations table
- [x] media table
- [x] media_translations table (mediaTranslations)
- [x] tags table
- [x] templates table (with kind/status defaults matching TypeScript)
- [x] scripts table (with kind/status defaults matching TypeScript)
- [x] post_links table (postLinks)
- [x] post_media table
- [x] settings table
- [x] generated_file_hashes table
- [x] db_notifications table
- [x] chat_conversations table
- [x] chat_messages table
- [x] ai_providers table
- [x] ai_models table
- [x] ai_model_modalities table
- [x] ai_catalog_meta table
- [x] embedding_keys table
- [x] dismissed_duplicate_pairs table
- [x] import_definitions table
- [x] All 10 unique indexes
- [x] FTS5 virtual tables (posts_fts, media_fts) -- present in fixture DB, runtime creation deferred to M1
- [x] Default values match TypeScript (status, kind, enabled, version, entrypoint)
## File Formats
- [ ] Post frontmatter (YAML) read/write
- [ ] Translation file format (posts/YYYY/MM/slug.lang.md)
- [ ] Media sidecar (.meta) read/write
- [ ] Template frontmatter read/write
- [ ] Script frontmatter read/write
- [ ] meta/tags.json
- [ ] meta/project.json
- [ ] meta/categories.json
- [ ] meta/category-meta.json
- [ ] meta/publishing.json
- [ ] meta/menu.opml
## Slug Generation
- [x] Basic transliteration (Unicode to ASCII, lowercase, hyphens, trim)
- [x] German umlauts: ae/oe/ue/ss/Ae/Oe/Ue (matches TypeScript transliteration npm)
- [x] Uniqueness: base, then {slug}-2..999, then {slug}-{timestamp}
## Content Location
- [x] Published posts have NULL content in DB, body in filesystem .md
- [x] Draft posts have content in DB
- [x] Published translations have NULL content in DB
- [x] Published templates have NULL content in DB
- [x] Published scripts have NULL content in DB
## Rendering
- [ ] Liquid template rendering (subset: if/elsif/else, for, assign, render, whitespace stripping)
- [ ] Liquid filters: escape, url_encode, default, append, i18n, markdown
- [ ] Markdown rendering via pulldown-cmark
- [ ] Built-in macros: gallery, youtube, vimeo, photo_archive, tag_cloud
- [ ] RSS/Atom feed generation
- [ ] Sitemap generation
- [ ] Generated file hash tracking (incremental)
- [ ] Pagefind search index generation (via pagefind crate library API)
## Search
- [ ] FTS5 post indexing with Snowball stemmers (24 languages)
- [ ] FTS5 media indexing
- [ ] Cross-language stemming
## Publishing
- [ ] SSH/SCP upload
- [ ] Rsync upload
- [ ] Three parallel upload targets (html, thumbnails, media)
- [ ] .meta files excluded from upload
## AI Integration
- [ ] Two-endpoint model (online + airplane)
- [ ] One-shot operations (translate, analyze, etc.)
- [ ] Chat with tool use
- [ ] Model catalog refresh
- [ ] Secure key storage (OS keychain)
## Thumbnails
- [ ] Small (150px), Medium (400px), Large (800px), AI (448x448 JPEG)
- [ ] WEBP output
## MCP Server
- [ ] HTTP + stdio transports
- [ ] Read-only tools
- [ ] Proposal-based write tools