onyx-tasks/PLAN.md
Claude 5019706055
Refactor plan: Backend/Frontend separation with CLI-first approach
Major architectural changes:
- Reorganized as Cargo workspace with 3 crates:
  - bevy-tasks-core: Pure Rust library (no UI dependencies)
  - bevy-tasks-cli: Command-line interface
  - bevy-tasks-gui: Graphical frontend (framework TBD)

CLI-First Development Strategy:
- Phase 1: Build core library + CLI MVP (validate backend)
- Phase 2: Add WebDAV sync to backend + CLI
- Phase 3: Build GUI MVP using chosen framework
- Phases 4-6: Mobile, polish, and advanced features

Comprehensive Frontend Framework Comparison:
Added detailed analysis of 8 frontend options:
1. Bevy (game engine) - best for polish, harder for standard UI
2. egui (immediate mode) - RECOMMENDED for MVP (fast, simple)
3. Iced (Elm-inspired) - good for desktop, mobile experimental
4. Dioxus (React-like) - web-friendly, mobile uses webview
5. Tauri (web + Rust) - uses system webview, slower startup
6. Slint (declarative) - clean but smaller community
7. Flutter (Dart) - best mobile but not Rust
8. Native UIs - best native feel but 5x development effort

Recommendation: Start with egui for Phase 3 MVP, optionally migrate
to Bevy in Phase 6 for game-like polish. Backend separation makes
this possible without rewriting business logic.

Benefits of this approach:
- Test backend thoroughly before GUI complexity
- CLI useful for power users and automation
- Clean API boundaries
- Easy to swap frontend frameworks
- Parallel development possible after Phase 2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 00:14:19 +00:00

32 KiB

Bevy Tasks - Project Plan

Vision

A local-first, cross-platform tasks application inspired by Google Tasks, built with Bevy for high performance and future game-like UX polish. The application will launch near-instantly on all platforms and support both local file storage and WebDAV synchronization.

Core Principles

  1. Local-First: All data is stored locally by default, with optional sync
  2. Performance: Sub-second cold start time on all platforms
  3. Cross-Platform: Native support for Windows, Linux, macOS, iOS, and Android
  4. Privacy: User data stays on their devices and chosen storage locations
  5. Future-Proof: Built on Bevy to enable advanced UI/UX features later

Target Platforms

  • Desktop: Windows, Linux, macOS
  • Mobile: iOS, Android

Technology Stack

Project Structure: Workspace with Backend/Frontend Separation

The project is organized as a Cargo workspace with three main crates:

  1. bevy-tasks-core (Library): Pure Rust business logic, no UI dependencies
  2. bevy-tasks-cli (Binary): Command-line interface for power users and testing
  3. bevy-tasks-gui (Binary): Graphical frontend (framework TBD - see Frontend Comparison)

This separation provides:

  • Clean architecture with testable core logic
  • Multiple interfaces to the same backend
  • Ability to develop and validate backend before frontend work
  • CLI tool useful for automation, scripting, and CI/CD

Backend/Core Library

  • serde: Serialization/deserialization
  • pulldown-cmark or markdown: Markdown parsing
  • serde_yaml: YAML frontmatter parsing (Obsidian-style metadata)
  • directories: Cross-platform path handling
  • tokio: Async runtime for I/O operations
  • reqwest + dav-client: WebDAV support
  • uuid: Unique identifiers for tasks
  • chrono: Date/time handling
  • anyhow: Error handling

CLI Frontend

  • clap: Command-line argument parsing
  • colored: Terminal colors for better UX
  • indicatif: Progress bars for sync operations

GUI Frontend

See "Frontend Framework Comparison" section below for detailed options.

Performance Optimization

  • Lazy loading: Load only visible data
  • Minimal dependencies: Keep binary size small
  • Release optimizations: LTO, strip symbols
  • Backend separation: Core logic has zero UI overhead

Architecture

Data Model

Tasks are stored as individual .md (Markdown) files, with metadata in YAML frontmatter (Obsidian-compatible format).

Task File Format (my-task-name.md):
---
id: 550e8400-e29b-41d4-a716-446655440000
status: in-progress
due: 2025-11-15T14:00:00Z
created: 2025-10-26T10:00:00Z
updated: 2025-10-26T12:30:00Z
parent: 550e8400-e29b-41d4-a716-446655440001
position: 1
tags: [work, urgent]
---

Task description and notes go here in **markdown** format.

- Can include lists
- Rich formatting
- Links, etc.

In-Memory Model:

Task {
    id: Uuid,
    title: String,              // Derived from filename
    notes: String,              // Markdown content
    status: TaskStatus,         // From frontmatter
    due_date: Option<DateTime>, // From frontmatter
    created_at: DateTime,       // From frontmatter
    updated_at: DateTime,       // From frontmatter
    parent_id: Option<Uuid>,    // From frontmatter
    position: i32,              // From frontmatter
    tags: Vec<String>,          // From frontmatter
}

TaskList {
    id: Uuid,
    title: String,              // Derived from folder name
    tasks: Vec<Task>,
    created_at: DateTime,
    updated_at: DateTime,
    position: i32,
}

AppConfig {
    storage_type: StorageType,  // Local or WebDAV
    local_path: Option<PathBuf>,
    webdav_url: Option<String>,
    webdav_credentials: Option<Credentials>,
    theme: Theme,
    last_sync: Option<DateTime>,
}

Workspace Structure

bevy-tasks/
├── Cargo.toml                    # Workspace definition
├── PLAN.md
├── README.md
│
├── crates/
│   ├── bevy-tasks-core/          # Core library (backend)
│   │   ├── Cargo.toml
│   │   ├── src/
│   │   │   ├── lib.rs
│   │   │   ├── task.rs           # Task model
│   │   │   ├── task_list.rs      # TaskList model
│   │   │   ├── config.rs         # AppConfig
│   │   │   ├── repository.rs     # High-level API
│   │   │   ├── storage/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── local.rs      # Local file I/O
│   │   │   │   ├── markdown.rs   # Markdown parser
│   │   │   │   └── webdav.rs     # WebDAV sync
│   │   │   └── error.rs          # Error types
│   │   └── tests/
│   │       ├── integration.rs
│   │       └── fixtures/
│   │
│   ├── bevy-tasks-cli/           # CLI frontend
│   │   ├── Cargo.toml
│   │   ├── src/
│   │   │   ├── main.rs
│   │   │   ├── commands/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── add.rs
│   │   │   │   ├── list.rs
│   │   │   │   ├── complete.rs
│   │   │   │   ├── sync.rs
│   │   │   │   └── init.rs
│   │   │   └── ui.rs             # Terminal formatting
│   │   └── README.md
│   │
│   └── bevy-tasks-gui/           # GUI frontend
│       ├── Cargo.toml
│       ├── src/
│       │   ├── main.rs           # App entry point
│       │   ├── app.rs            # Framework setup
│       │   ├── ui/
│       │   │   ├── mod.rs
│       │   │   ├── screens/
│       │   │   │   ├── task_list.rs
│       │   │   │   ├── task_detail.rs
│       │   │   │   └── settings.rs
│       │   │   └── components/
│       │   │       ├── task_item.rs
│       │   │       ├── task_input.rs
│       │   │       └── list_selector.rs
│       │   └── state.rs          # UI state management
│       ├── assets/
│       │   ├── fonts/
│       │   └── icons/
│       └── README.md
│
└── docs/
    ├── API.md
    ├── CLI.md
    └── DEVELOPMENT.md

Core Library API Design

The bevy-tasks-core library will expose a clean, high-level API:

// Main repository interface
pub struct TaskRepository {
    storage: Box<dyn Storage>,
}

impl TaskRepository {
    pub fn new(config: Config) -> Result<Self>;
    pub fn init(path: PathBuf) -> Result<Self>;

    // Task operations
    pub fn create_task(&mut self, list_id: Uuid, task: Task) -> Result<Task>;
    pub fn get_task(&self, id: Uuid) -> Result<Task>;
    pub fn update_task(&mut self, task: Task) -> Result<()>;
    pub fn delete_task(&mut self, id: Uuid) -> Result<()>;
    pub fn list_tasks(&self, list_id: Uuid) -> Result<Vec<Task>>;

    // List operations
    pub fn create_list(&mut self, name: String) -> Result<TaskList>;
    pub fn get_lists(&self) -> Result<Vec<TaskList>>;
    pub fn delete_list(&mut self, id: Uuid) -> Result<()>;

    // Sync operations
    pub fn sync_push(&mut self) -> Result<SyncResult>;
    pub fn sync_pull(&mut self) -> Result<SyncResult>;
    pub fn sync_status(&self) -> Result<SyncStatus>;
}

// Storage trait for local and WebDAV implementations
pub trait Storage {
    fn read_task(&self, list_id: Uuid, task_id: Uuid) -> Result<Task>;
    fn write_task(&mut self, list_id: Uuid, task: &Task) -> Result<()>;
    // ... more methods
}

Storage Strategy

Local Storage

  • Location: User-selectable folder OR platform-specific app data directory
    • Windows: %APPDATA%/bevy-tasks/ (default)
    • Linux: ~/.local/share/bevy-tasks/ (default)
    • macOS: ~/Library/Application Support/bevy-tasks/ (default)
    • iOS: App sandbox documents directory
    • Android: Internal storage app directory
    • User can select any folder with read/write permissions
  • Format: Markdown files with YAML frontmatter (Obsidian-compatible)
  • Structure:
    data/
    ├── .bevy-tasks/
    │   ├── config.json          # App configuration
    │   └── metadata.json        # List ordering, sync state
    ├── My Tasks/                # Task list folder
    │   ├── Buy groceries.md
    │   ├── Call dentist.md
    │   └── Project X/           # Subtask folder (optional)
    │       └── Design mockup.md
    └── Work/                    # Another task list
        ├── Review PRs.md
        └── Team meeting prep.md
    

Benefits of Markdown Format:

  • Human-readable and editable in any text editor
  • Compatible with Obsidian, Logseq, and other markdown tools
  • Easy to version control (git-friendly)
  • Future-proof format
  • Enables external editing and scripting
  • Natural organization with folders

WebDAV Sync

  • Conflict Resolution: Last-write-wins with timestamp
  • Sync Strategy:
    • On app start (if connected)
    • On background timer (every 5 minutes when active)
    • On task modification (debounced)
  • Offline Support: All operations work offline, sync when online

Performance Strategy

Fast Startup Requirements

  1. Minimal initialization: Load only essential systems
  2. Lazy UI rendering: Render visible items first
  3. Background loading: Load non-critical data after first frame
  4. Asset optimization: Embed minimal assets, load rest async
  5. Incremental parsing: Stream large data files

Startup Sequence

  1. Initialize Bevy minimal plugins (< 50ms)
  2. Load config from disk (< 20ms)
  3. Render splash/empty state (first frame < 100ms)
  4. Load task lists in background
  5. Render tasks as they load
  6. Start WebDAV sync (if configured)

Memory Optimization

  • Use Vec instead of HashMap for small collections
  • Limit rendered tasks to visible viewport
  • Unload non-visible screens from memory

Feature Roadmap

Phase 1: Core Library & CLI MVP

Goal: Build and validate the backend with a functional CLI

Features:

  • Project workspace setup (bevy-tasks-core, bevy-tasks-cli, bevy-tasks-gui)
  • Data models (Task, TaskList, AppConfig)
  • Markdown file I/O with YAML frontmatter parsing
  • Local storage implementation
  • Repository pattern and public API
  • CLI: init, add, list, complete, delete, edit commands
  • CLI: Basic task listing and formatting
  • Comprehensive unit and integration tests

Deliverables:

  • bevy-tasks-core library with stable API
  • Functional CLI that can manage tasks via command line
  • Data persists as Obsidian-compatible .md files
  • Well-tested backend (>80% coverage)

CLI Example:

bevy-tasks init ~/my-tasks
bevy-tasks add "Buy groceries" --list "Personal"
bevy-tasks list
bevy-tasks complete <task-id>

Phase 2: WebDAV Sync (Backend + CLI)

Goal: Enable cross-device synchronization via CLI

Features:

  • WebDAV client implementation in core library
  • Credential storage (platform keychain)
  • Bi-directional sync (push/pull/auto)
  • Conflict resolution (last-write-wins)
  • Offline queue for pending operations
  • CLI: sync setup, push, pull, status commands
  • CLI: Progress indicators for sync operations

Deliverables:

  • Working WebDAV sync in backend
  • CLI can sync with remote WebDAV server
  • Reliable conflict resolution tested with real servers (Nextcloud, ownCloud)

CLI Example:

bevy-tasks sync --setup
bevy-tasks sync --push
bevy-tasks sync --pull
bevy-tasks sync --status

Phase 3: GUI MVP (Desktop)

Goal: Build graphical interface on desktop platforms

Frontend Decision: Choose frontend framework (see Frontend Comparison section)

Features:

  • GUI framework integration
  • Basic task list view
  • Create/edit/delete tasks
  • Mark tasks complete
  • Settings screen (storage location, WebDAV config)
  • Desktop support (Windows, Linux, macOS)
  • Sync status indicators

Deliverables:

  • Functional desktop GUI app
  • Sub-second startup time
  • Clean, minimal UI
  • Feature parity with CLI

Phase 4: GUI Advanced Features (Desktop)

Goal: Feature parity with Google Tasks

Features:

  • Multiple task lists (folders)
  • Switch between lists
  • Subtasks support
  • Due dates with date picker
  • Rich markdown editor for task notes
  • Drag & drop reordering
  • Move tasks between lists
  • Folder picker for custom storage
  • Keyboard shortcuts
  • Search functionality

Deliverables:

  • Full-featured desktop task manager
  • Polished UX
  • Keyboard-driven workflow

Phase 5: Mobile Support

Goal: Deploy to iOS and Android

Features:

  • Touch-optimized UI
  • iOS build pipeline
  • Android build pipeline
  • Mobile-specific UX (swipe gestures, pull-to-refresh)
  • Background sync on mobile
  • Mobile file system integration
  • Share extension (share to tasks)
  • Native mobile feel

Deliverables:

  • Working iOS app
  • Working Android app
  • Consistent UX across mobile and desktop

Phase 6: Polish & Advanced Features

Goal: Differentiate from Google Tasks, add unique features

Features:

  • Themes and customization
  • Advanced animations and transitions (if using Bevy)
  • Full-text search across tasks
  • Filters and smart lists
  • Task templates
  • Recurring tasks
  • Statistics and insights
  • Export/import (backup)
  • Plugin system for extensions (optional)
  • Game-like achievements (optional, if using Bevy)

Deliverables:

  • Polished, delightful UX
  • Unique features not in Google Tasks
  • Distribution to all app stores

Development Guidelines

Performance Budgets

  • Cold start: < 500ms on desktop, < 1s on mobile
  • First render: < 100ms
  • Task creation: < 50ms
  • Sync operation: < 2s for typical dataset (< 1000 tasks)
  • Memory usage: < 50MB on mobile, < 100MB on desktop

Testing Strategy

  • Unit tests: Data models and business logic
  • Integration tests: Storage layer operations
  • E2E tests: Critical user flows
  • Performance tests: Startup time, large datasets
  • Platform tests: Verify each platform build

Build & Release

  • CI/CD: GitHub Actions for all platforms
  • Initial Distribution:
    • Desktop: Direct downloads and sideloading
      • Linux: AppImage, .tar.gz
      • macOS: DMG
      • Windows: MSI, portable .exe
    • Mobile: Sideloading only
      • iOS: .ipa for TestFlight/direct install
      • Android: .apk
  • Future Distribution Channels (Phase 5+):
    • F-Droid: FOSS Android app store
    • Flathub: Linux Flatpak repository
    • Google Play Store: Android
    • Apple App Store: iOS and macOS
    • Microsoft Store: Windows
  • Version scheme: Semantic versioning (0.1.0 → 1.0.0)
  • Release notes: Auto-generated from commits

Technical Challenges & Solutions

Challenge 1: Fast Startup with Bevy

Problem: Bevy's plugin system can add overhead

Solutions:

  • Use MinimalPlugins instead of DefaultPlugins
  • Add only required plugins (rendering, input)
  • Lazy-load audio, asset server if not needed immediately
  • Profile startup and optimize hot paths

Challenge 2: Mobile Platform Support

Problem: iOS and Android have different requirements

Solutions:

  • Use conditional compilation for platform-specific code
  • Test early and often on real devices
  • Follow platform guidelines (iOS HIG, Material Design)
  • Use platform-specific file pickers and sharing

Challenge 3: WebDAV Reliability

Problem: Network can be unreliable, auth can be complex

Solutions:

  • Implement robust retry logic with exponential backoff
  • Cache credentials securely (see Authentication Options below)
  • Queue operations when offline
  • Provide clear sync status to user
  • Support multiple WebDAV servers (Nextcloud, ownCloud, etc.)

Challenge 4: Data Migration

Problem: Schema changes need to preserve user data

Solutions:

  • Version frontmatter schema from day one
  • Write migration scripts for each version bump
  • Markdown format is naturally forward/backward compatible
  • Users handle their own backups (external to app)
  • Migration can be done in-place by updating frontmatter

Frontend Framework Comparison

Now that we have backend/frontend separation, we can evaluate multiple GUI framework options. The backend (bevy-tasks-core) is framework-agnostic.

Option 1: Bevy (Game Engine)

Language: Rust Architecture: ECS (Entity Component System)

Pros:

  • True cross-platform (Windows, Linux, macOS, iOS, Android, WASM)
  • Excellent performance (60+ FPS easily)
  • Future game-like polish and animations
  • Active community and development
  • Full control over rendering
  • Single codebase for all platforms
  • Fast startup possible with MinimalPlugins

Cons:

  • UI system is still maturing (bevy_ui improving but limited)
  • More code required for standard widgets
  • Steeper learning curve (ECS paradigm)
  • Larger binary size (~5-10MB stripped)
  • Text input handling requires extra work
  • Not designed for traditional UIs

Best for: If you want game-like polish, animations, and are willing to build custom UI components.

Startup time estimate: 200-500ms Binary size: 5-10MB (stripped)


Option 2: egui (Immediate Mode GUI)

Language: Rust Integration: Standalone or with eframe

Pros:

  • True cross-platform (desktop, WASM, can run on mobile)
  • Very simple API (immediate mode)
  • Rich built-in widgets
  • Excellent text editing support
  • Small binary size (~2-3MB)
  • Fast development iteration
  • Mature and stable
  • Good performance
  • Works with multiple backends (glow, wgpu)

Cons:

  • Mobile support exists but less mature
  • Immediate mode can be unusual coming from retained mode
  • Less flexibility for custom animations
  • Harder to achieve "game-like" polish
  • Less native feel on each platform

Best for: Quick development, standard UI needs, if you don't need game-like features.

Startup time estimate: 100-200ms Binary size: 2-3MB (stripped)


Option 3: Iced (Elm-inspired)

Language: Rust Architecture: The Elm Architecture (TEA)

Pros:

  • Cross-platform (Windows, Linux, macOS, WASM)
  • Declarative, reactive UI (similar to SwiftUI/Flutter)
  • Clean architecture with clear state management
  • Type-safe
  • Good widget library
  • Native-feeling widgets
  • Async support built-in
  • Medium binary size (~3-5MB)

Cons:

  • Mobile support experimental (iOS/Android not production-ready)
  • Smaller community than egui or Bevy
  • Still evolving (breaking changes possible)
  • Limited animation capabilities
  • Less documentation than mature frameworks

Best for: If you like reactive/declarative UIs and primarily target desktop + WASM.

Startup time estimate: 150-300ms Binary size: 3-5MB (stripped)


Option 4: Dioxus (React-like)

Language: Rust Architecture: Virtual DOM with React-like hooks

Pros:

  • Cross-platform (desktop, web, mobile via TUI or webview)
  • React-like API (familiar to web devs)
  • Hot reload support
  • Component-based architecture
  • Fast development
  • Can target web with same code
  • Active development

Cons:

  • Mobile support uses webview (not truly native)
  • Still young and evolving
  • Less mature than other options
  • Performance not as good as native solutions
  • Webview adds overhead on mobile

Best for: Web developers wanting familiar patterns, prioritizing web deployment.

Startup time estimate: 200-400ms (desktop), slower on mobile (webview) Binary size: 4-8MB (includes webview on mobile)


Option 5: Tauri (Web Tech + Rust Backend)

Language: HTML/CSS/JavaScript (or any web framework) + Rust Architecture: Webview with Rust backend

Pros:

  • Use any web framework (React, Vue, Svelte, etc.)
  • Rapid UI development with web technologies
  • Small binary size (uses system webview)
  • Desktop support excellent (Windows, Linux, macOS)
  • Mobile support coming (Tauri Mobile)
  • Large ecosystem of web UI libraries
  • Familiar to web developers
  • Hot reload support

Cons:

  • Depends on system webview (consistency issues)
  • Mobile support still in beta
  • Not truly native look/feel
  • Performance worse than native solutions
  • Startup time slower (webview initialization)
  • Requires web dev skills
  • More complex build process

Best for: Teams with web dev experience, if you want to use React/Vue/Svelte.

Startup time estimate: 300-800ms (webview initialization) Binary size: 1-3MB (uses system webview)


Option 6: Slint (Declarative UI)

Language: Slint language + Rust Architecture: Declarative markup language

Pros:

  • True cross-platform (desktop, embedded, mobile coming)
  • Declarative UI with .slint files
  • Native rendering (no webview)
  • Good performance
  • Design tools available
  • Small binary size
  • Good documentation
  • Business-backed (SixtyFPS GmbH)

Cons:

  • Mobile support experimental
  • Smaller community
  • Need to learn new markup language
  • Less flexible than code-based solutions
  • Dual licensing (GPL or commercial)

Best for: If you want declarative UI with good tooling and don't mind learning new syntax.

Startup time estimate: 100-250ms Binary size: 2-4MB


Option 7: Flutter (Dart)

Language: Dart (not Rust!) Architecture: Widget tree

Pros:

  • Best mobile support (iOS, Android)
  • Very mature and stable
  • Huge widget library
  • Excellent documentation
  • Great tooling and dev experience
  • Desktop support good
  • Beautiful UIs out of the box
  • Fast startup on mobile

Cons:

  • Not Rust! (breaks our stack)
  • Requires Dart FFI to call Rust backend
  • Larger binary size (10-20MB)
  • Different language/ecosystem
  • More complex integration

Best for: If mobile is top priority and you're willing to use Dart + Rust FFI.

Startup time estimate: 200-400ms Binary size: 10-20MB


Option 8: Native Platform UIs (Platform-specific)

Language: Rust + platform bindings Options: gtk-rs (Linux), windows-rs (Windows), cacao (macOS), UIKit bindings (iOS), Android NDK

Pros:

  • True native look and feel per platform
  • Best platform integration
  • Smallest binaries per platform
  • Fastest startup time
  • Platform features "just work"

Cons:

  • Separate codebase per platform
  • 5x development effort
  • Hard to maintain consistency
  • Need to learn each platform
  • More testing required

Best for: If native feel is paramount and you have resources for multiple codebases.

Startup time estimate: 50-150ms (native) Binary size: 1-3MB per platform


Frontend Framework Recommendation

Based on your requirements (fast startup, cross-platform, potential for game-like polish):

Why egui?

  1. Fastest time to market: Rich widgets out of the box
  2. Good performance: Fast startup, low overhead
  3. Cross-platform: Desktop works great, mobile possible
  4. Simple integration: Easy to connect to bevy-tasks-core
  5. Validate UX: Test core app experience quickly
  6. Path forward: Can always switch to Bevy later if you want game-like features

Alternative path: Bevy for unique polish

Choose Bevy if:

  • You want game-like animations from the start
  • You're excited about building custom UI
  • You value long-term flexibility over short-term speed
  • You want a unique, polished look

Best of both worlds:

  1. Build Phase 3 MVP with egui (fast iteration)
  2. Validate UX, backend API, and app concept
  3. If you want more polish, rebuild with Bevy in Phase 6
  4. Backend stays the same (clean separation!)

This de-risks the project while keeping options open.

Quick Decision Matrix

Framework Startup Binary Mobile Dev Speed Polish Potential Learning Curve
Bevy ⚠️ Medium ⚠️ Large Good ⚠️ Slow Hard
egui Fast Small ⚠️ OK Fast Easy
Iced Fast Small Poor Good Medium
Dioxus ⚠️ Medium ⚠️ Medium ⚠️ Webview Fast Easy (if React)
Tauri Slow Small ⚠️ Beta Very Fast Easy (web)
Slint Fast Small ⚠️ Exp ⚠️ Medium Medium
Flutter Fast ⚠️ Large Very Fast Medium (Dart)
Native Very Slow Very Hard

Dependencies

Workspace Structure (Cargo.toml)

[workspace]
members = [
    "crates/bevy-tasks-core",
    "crates/bevy-tasks-cli",
    "crates/bevy-tasks-gui",
]
resolver = "2"

[workspace.dependencies]
# Shared dependencies
serde = { version = "1.0", features = ["derive"] }
uuid = { version = "1.0", features = ["serde", "v4"] }
chrono = { version = "0.4", features = ["serde"] }
anyhow = "1.0"
tokio = { version = "1.40", features = ["full"] }

Core Library (bevy-tasks-core/Cargo.toml)

[package]
name = "bevy-tasks-core"
version = "0.1.0"
edition = "2024"

[dependencies]
serde = { workspace = true }
serde_json = "1.0"
serde_yaml = "0.9"  # YAML frontmatter parsing
pulldown-cmark = "0.12"  # Markdown parsing
uuid = { workspace = true }
chrono = { workspace = true }
directories = "5.0"  # Cross-platform paths
tokio = { workspace = true }
anyhow = { workspace = true }

# WebDAV support
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
# TODO: Evaluate dav-client or implement custom WebDAV

# Credential storage
keyring = "3.0"  # Cross-platform keychain

[dev-dependencies]
tempfile = "3.0"  # For testing file operations

CLI (bevy-tasks-cli/Cargo.toml)

[package]
name = "bevy-tasks-cli"
version = "0.1.0"
edition = "2024"

[[bin]]
name = "bevy-tasks"
path = "src/main.rs"

[dependencies]
bevy-tasks-core = { path = "../bevy-tasks-core" }
clap = { version = "4.5", features = ["derive", "env"] }
colored = "2.0"  # Terminal colors
indicatif = "0.17"  # Progress bars
anyhow = { workspace = true }
tokio = { workspace = true }

GUI (bevy-tasks-gui/Cargo.toml)

[package]
name = "bevy-tasks-gui"
version = "0.1.0"
edition = "2024"

[dependencies]
bevy-tasks-core = { path = "../bevy-tasks-core" }
anyhow = { workspace = true }

# GUI framework - TBD based on chosen option
# Option 1: Bevy
# bevy = { version = "0.16", default-features = false, features = ["bevy_ui", "bevy_render", "bevy_winit"] }

# Option 2: egui (Recommended for MVP)
# eframe = "0.31"
# egui = "0.31"

# Option 3: Iced
# iced = { version = "0.13", features = ["tokio"] }

# Option 4: Dioxus
# dioxus = "0.6"
# dioxus-desktop = "0.6"

# Platform-specific
[target.'cfg(target_os = "android")'.dependencies]
# Android-specific deps

[target.'cfg(target_os = "ios")'.dependencies]
# iOS-specific deps

Getting Started

Prerequisites

  • Rust 1.75+ (2024 edition)
  • Platform-specific tools (for mobile builds later):
    • iOS: macOS + Xcode
    • Android: Android SDK + NDK

Development Setup

# Clone repository
git clone <repository-url>
cd bevy-tasks

# Build all workspace members
cargo build

# Run tests for core library
cargo test -p bevy-tasks-core

# Run CLI
cargo run -p bevy-tasks-cli -- --help
cargo run -p bevy-tasks-cli -- init ~/test-tasks

# Run GUI (once implemented)
cargo run -p bevy-tasks-gui

# Build for release
cargo build --release -p bevy-tasks-cli
cargo build --release -p bevy-tasks-gui

# Run all tests
cargo test --workspace

Development Workflow (Phase 1)

  1. Start with Core Library:
cd crates/bevy-tasks-core
cargo test --watch  # with cargo-watch
  1. Build CLI to test backend:
cd crates/bevy-tasks-cli
cargo run -- init ~/my-tasks
cargo run -- add "Test task"
cargo run -- list
  1. Iterate on API:
  • Add features to core library
  • Test via CLI
  • Write integration tests
  • Document public API
  1. Add GUI later (Phase 3):
cd crates/bevy-tasks-gui
cargo run

Questions & Decisions

1. Frontend Framework Choice

Status: See "Frontend Framework Comparison" section above for detailed analysis.

Current Recommendation: Start with egui for Phase 3 (fast MVP), optionally migrate to Bevy in Phase 6 for polish.


2. Authentication Options for WebDAV

Option A: Platform Keychain/Keyring

Implementation: Use keyring crate for cross-platform credential storage

Pros:

  • Most secure option
  • OS-managed encryption
  • Follows platform security best practices
  • Auto-locks with system
  • Works on all platforms:
    • Windows: Credential Manager
    • macOS: Keychain
    • Linux: Secret Service API (gnome-keyring/kwallet)
    • iOS: Keychain
    • Android: Keystore

Cons:

  • Requires user to unlock keychain
  • May prompt for permissions
  • Linux requires D-Bus and secret service

Security:

Option B: Encrypted Local Storage

Implementation: Encrypt credentials in config file using a master password or device key

Pros:

  • Works offline always
  • No external dependencies
  • Full control over encryption

Cons:

  • Need to manage encryption keys
  • Vulnerable if key is compromised
  • Need to prompt user for password
  • Harder to implement correctly

Security: (if done right)

Option C: App-Generated Token + Keychain

Implementation: User authenticates once via OAuth/app-specific password, store token in keychain

Pros:

  • More secure than passwords
  • Supports modern auth flows
  • Can revoke tokens
  • Works with Nextcloud, ownCloud app passwords

Cons:

  • Requires OAuth flow implementation
  • More complex initial setup
  • Depends on server support

Security:

Option D: Store Username + Prompt for Password

Implementation: Store username in config, prompt for password on each sync

Pros:

  • Simple implementation
  • No credential storage
  • Maximum security

Cons:

  • Terrible UX
  • Not practical for background sync
  • Users will hate it

Security: (but unusable)

Recommendation

Primary: Option A (Platform Keychain) using the keyring crate

  • Store WebDAV username + password in system keychain
  • Key: com.bevy-tasks.webdav.{server-domain}
  • Graceful fallback if keychain is unavailable

Fallback: Option B (Encrypted storage) for platforms where keychain fails

  • Use ChaCha20-Poly1305 for encryption
  • Derive key from device identifier + app secret

Future: Option C (Token-based) for servers that support it

  • Implement OAuth flow for Nextcloud/ownCloud
  • Store tokens in keychain

3. Backup Strategy

Decision: User-managed backups via external tools

Rationale:

  • Markdown format is already backup-friendly
  • Users can use existing tools:
    • Git for version control
    • Dropbox/Google Drive/OneDrive for cloud backup
    • Time Machine (macOS) / File History (Windows)
    • rsync, rclone, etc.
  • WebDAV itself serves as a backup when enabled
  • Keeps app simple and focused

App Responsibilities:

  • Don't corrupt data
  • Write atomically (temp file + rename)
  • Graceful handling of sync conflicts
  • Clear documentation on backup best practices

Optional Future Feature:

  • Export all tasks to single file (.zip of markdown)
  • Import from backup
  • Git integration for automatic versioning

Resources

License

To be determined.


Last Updated: 2025-10-27 Document Version: 2.0 Status: Planning Phase - Backend/Frontend Separation Decided