Arcology Engine

Linux Desktop Port - Development Plan

Contents

Overview

Port the arcology2go Android app to Linux desktop using Compose Multiplatform, maintaining the existing Material3 UI design with a responsive/tablet-style interface. The goal is a native Linux desktop application for browsing and editing org-roam files, with full-text search and spaced repetition quiz features.

This plan follows the same philosophy as the Android app: incremental development, test-driven, focusing on core features first.

Remember contributing.org tells you how to make design decisions. Consult it often.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                   Desktop App Module                         │
├─────────────────────────────────────────────────────────────┤
│  UI Layer (Compose Multiplatform)                            │
│  ┌──────────┐  ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │SearchScr │  │EditorScr │ │ FilesScr │ │ QuizScr  │       │
│  └────┬─────┘  └────┬─────┘ └────┬─────┘ └────┬─────┘       │
│       │             │            │             │            │
│  ┌────┴─────────────┴────────────┴─────────────┴────┐       │
│  │              ViewModels (Shared - Koin)          │       │
│  │  SearchVM │ EditorVM │ FilesVM │ QuizVM │ ...    │       │
│  └──────────────────────┬───────────────────────────┘       │
├─────────────────────────┼───────────────────────────────────┤
│  Shared Module (commonMain + jvmMain)                        │
│  ┌──────────────────────┴────────────────────────┐          │
│  │  OrgDocumentEditor  │  RoamRepository     │          │
│  │  SearchService      │  FlowFileIndexer        │          │
│  │  OrgFileParser      │  JvmFileSystem          │          │
│  └───────────────────────────────────────────────┘          │
└─────────────────────────────────────────────────────────────┘

Already Multiplatform-Ready

The following components are already in commonMain or jvmMain and require no changes:

  • orgmode-kmp parser library (already multiplatform)

  • SQLDelight database with FTS5 search (JVM driver exists)

  • RoamRepository with async/suspend API

  • SearchService with BM25-ranked search

  • FlowFileIndexer with progress streaming

  • OrgDocumentEditor with property/body/refile operations

  • JvmFileSystem using Java NIO (already works for desktop!)

  • All domain models (OrgNode, OrgFile, OrgLink, OrgTag)

  • All business logic (parsing, indexing, search, quiz, flashcards)

Requires Desktop-Specific Implementation

  • DesktopPreferences (properties file-based, no SharedPreferences)

  • DesktopBackgroundService (coroutine-based, no WorkManager)

  • DesktopPlatformContext (file:// URIs, no SAF)

  • DesktopNotificationManager (system tray, no NotificationManager)

  • Compose Desktop window management and lifecycle

Implementation Tasks

TODO Phase 1: Foundation (4-6 hours)

TODO Create desktop-app module

  • Create desktop-app/ directory structure

  • Add Compose Desktop dependencies in build.gradle.kts

  • Create main entry point DesktopApp.kt

  • Set up desktop window configuration (size, theme)

  • Verify app launches with blank screen

TODO Implement DesktopPreferences

  • Create DesktopPreferences class implementing AppPreferencesInterface

  • Use Java Properties file stored in ~/.config/arcology2go/preferences.properties

  • Implement all preference methods (directory path, settings, etc.)

  • Write unit tests using AppPreferencesTestDouble pattern from contributing.org

TODO Implement DesktopBackgroundService

  • Create DesktopBackgroundService for background indexing

  • Use CoroutineScope(Dispatchers.Default) instead of WorkManager

  • Implement file watching using java.nio.file.WatchService

  • Trigger re-indexing on file system events (vs. time-based threshold)

TODO Wire up Koin DI for Desktop

  • Create DesktopModule with desktop-specific dependencies

  • Wire up DesktopPreferences, JvmFileSystem, DesktopBackgroundService

  • Configure database path in user home directory

  • Test DI graph resolution

TODO Phase 2: Core UI Migration (20-30 hours)

TODO Extract platform-specific dependencies

  • Create PlatformContext interface in commonMain

    • resolveUri(uri: String): ByteArray (for images)

    • shareText(text: String) (for sharing)

    • getAttachmentBasePath(): String (for attachments)

  • Create AndroidPlatformContext in androidMain

  • Create DesktopPlatformContext in desktopMain (file:// paths)

TODO Migrate Compose screens to Multiplatform

  • Convert all imports from =androidx.compose.= to =org.jetbrains.compose.=

  • Replace LocalContext.current with PlatformContext injection

  • Test each screen individually on desktop:

    • SearchScreen (should work immediately)

    • OrgDocumentEditorScreen (needs PlatformContext)

    • FilesScreen (needs JvmFileSystem)

    • QuizScreen (should work immediately)

    • SettingsScreen (needs DesktopPreferences)

    • LocationMapScreen (needs geolocation service - consider desktop map view)

    • GraphScreen (should work immediately with Kuiver)

TODO Port ViewModels to Desktop

  • Extract any remaining Android dependencies from ViewModels

  • All ViewModels should work once DI is configured

  • Test each ViewModel on desktop:

    • SearchViewModel

    • OrgDocumentEditorViewModel

    • FilesViewModel

    • QuizViewModel

    • IndexingViewModel

TODO Handle desktop window lifecycle

  • Implement proper window close handling

  • Save window size/position preferences

  • Handle app icon and window title

  • Test window resizing (responsive layout)

TODO Phase 3: Must-Have Features (10-15 hours)

TODO File Browsing and Editing

  • Test JvmFileSystem on Linux (should work as-is)

  • Verify file browser navigation works with traditional paths

  • Test file reading/writing/creation

  • Test attachment handling with file:// URIs

  • Verify SearchService works on desktop (no changes needed)

  • Test search performance on large org-roam directories

  • Test search modes (all/title/content/file/tags)

  • Test tag filtering

TODO Spaced Repetition (Quiz)

  • Verify QuizViewModel works on desktop

  • Test org-fc flashcard parsing (no changes needed)

  • Test SM-2 algorithm

  • Test quiz session flow (idle/active/completed)

  • Implement system tray notifications for due cards

DONE Phase 4: Polish (Optional, 10-20 hours)

TODO Desktop Menu Bar

  • Add application menu (File/Edit/View/Help)

  • Add keyboard shortcuts (standard desktop shortcuts)

  • Add recent files menu

  • Add preferences menu item

TODO Advanced Desktop Features

  • System tray icon with due card count

  • File watching with java.nio.file.WatchService

  • Auto-reload on file change

  • Desktop notifications (system tray, not Android notifications)

TODO Desktop Packaging

  • Create jpackage configuration for Linux

  • Generate standalone executable

  • Test on multiple Linux distros (Ubuntu, Fedora, Arch)

  • Create .desktop file for application launcher

  • Consider snap/flatpak packaging (optional)

TODO Desktop Testing

  • Write desktop-specific unit tests

  • Create integration tests for file system operations

  • Test responsive layout on different window sizes

  • Performance testing on large org-roam directories (5000+ files)

Key Design Decisions

Platform Abstraction Strategy

Use expect/actual and interface abstraction for platform-specific code:

kotlin
// commonMain
interface PlatformContext {
    fun resolveUri(uri: String): ByteArray
    fun shareText(text: String)
}

//androidMain
class AndroidPlatformContext(val context: Context) : PlatformContext {
    override fun resolveUri(uri: String): ByteArray = 
        context.contentResolver.openInputStream(Uri.parse(uri))?.readBytes()!!
}

// desktopMain
class DesktopPlatformContext : PlatformContext {
    override fun resolveUri(uri: String): ByteArray = File(uri).readBytes()
}

File System Paths

Android uses Storage Access Framework with content:// URIs. Desktop uses traditional file:// paths:

  • Android: content://com.android.externalstorage.documents/tree/...

  • Desktop: ~/org-roam (configurable in preferences)

The FileSystemInterface abstraction already handles this. Desktop uses JvmFileSystem which accepts any file path.

Background Tasks

Android uses WorkManager for background indexing. Desktop uses coroutines:

kotlin
// Desktop background service
class DesktopBackgroundService(
    private val indexer: FlowFileIndexer
) {
    private val scope = CoroutineScope(Dispatchers.Default)
    
    fun startFileWatcher(rootPath: String) = scope.launch {
        val watchService = FileSystems.getDefault().newWatchService()
        Path(rootPath).register(watchService, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE)
        
        while (isActive) {
            val key = watchService.take()
            key.pollEvents().forEach { event ->
                // Trigger re-indexing
                indexer.indexFile(event.context().toString())
            }
            key.reset()
        }
    }
}

Preferences Storage

Android uses SharedPreferences. Desktop uses Java Properties:

# ~/.config/arcology2go/preferences.properties
org.directory=/home/user/org-roam
capture.subdirectory=journals
last.indexed=2026-04-04T12:00:00Z

Window Configuration

Desktop app should have sensible defaults for window size:

  • Default: 1280x800 (similar to Android tablet)

  • Minimum: 800x600

  • Remember last window size/position in preferences

Testing Strategy

Desktop Unit Tests

Follow the same patterns as Android tests (ViewModel tests in app/src/test/):

  • Use AppPreferencesTestDouble pattern for preferences

  • Use test file system (TestFileSystem in commonTest)

  • Test DesktopBackgroundService file watching logic

  • Test DesktopPreferences persistence

Desktop Integration Tests

  • Test JvmFileSystem on actual Linux file system

  • Test database creation in ~/.local/share/arcology2go/

  • Test file watching with actual file modifications

  • Test large directory performance (5000+ files)

Manual Testing Checklist

After Phase 1:

  • App launches with blank screen

  • Window can be resized

  • Window close works properly

After Phase 2:

  • Can browse org directory

  • Can open and edit org files

  • Can create new nodes

  • Can search files

  • Can take quiz

After Phase 3:

  • Search is fast and accurate

  • Quiz notifications work

  • All core features stable

After Phase 4:

  • System tray icon shows due cards

  • File watching auto-reloads

  • Menu bar has all shortcuts

  • App packages as standalone executable

Future Enhancements (Out of Scope for Initial Port)

WAITING Desktop geolocation integration

  • Integrate with Linux geolocation services (Geoclue)

  • Add desktop map view with native tile rendering

WAITING Desktop theming integration

  • Integrate with GTK theme colors

  • Add dark/light mode toggle following system theme

WAITING Multiple window support

  • Open nodes in separate windows

  • Side-by-side editing

WAITING Desktop collaboration

  • Real-time collaboration using CRDTs

  • Multi-user editing

WAITING Plugin system

  • Allow users to extend functionality

  • Custom export formats

  • Integration with other Linux tools

Risk Mitigation

Performance on Large Directories

Risk: Desktop may have different performance characteristics than Android.

Mitigation:

  • Test early with large org-roam directories (5000+ files)

  • Profile indexing performance on Linux

  • Optimize file system watching (debounce, batch updates)

Desktop-Specific UX

Risk: Tablet UI may not feel native on desktop.

Mitigation:

  • Add desktop-specific features early (menus, shortcuts)

  • Test with desktop users

  • Iterate on responsive layout

  • Consider optional compact/expanded views

File System Permissions

Risk: Linux file permissions may differ from Android SAF.

Mitigation:

  • Test on multiple Linux distros

  • Provide clear error messages for permission issues

  • Document file system requirements

Key Questions (To Be Resolved)

  1. *Window size: Start with tablet dimensions (1280x800) or native desktop size? 2. File system: Use ~/org-roam by default or let user configure? 3. Background tasks: File watching vs. manual indexing button? 4. Packaging: jpackage vs. snap/flatpak vs. all three? 5. Location features: Skip for MVP or integrate with Geoclue? 6. Graph view*: Keep Kuiver or use desktop-specific graph library?

References

  • app/index.org - Original Android development plan

  • contributing.org - Development guidelines and axioms

  • orgmode-kmp documentation - Parser library usage

  • Compose Multiplatform docs - https://www.jetbrains.com/lp/compose-multiplatform/

  • SQLDelight multiplatform - https://cashapp.github.io/SQLDelight/