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-kmpparser library (already multiplatform)SQLDelight database with FTS5 search (JVM driver exists)
RoamRepositorywith async/suspend APISearchServicewith BM25-ranked searchFlowFileIndexerwith progress streamingOrgDocumentEditorwith property/body/refile operationsJvmFileSystemusing 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 structureAdd Compose Desktop dependencies in
build.gradle.ktsCreate main entry point
DesktopApp.ktSet up desktop window configuration (size, theme)
Verify app launches with blank screen
TODO Implement DesktopPreferences
Create
DesktopPreferencesclass implementingAppPreferencesInterfaceUse Java Properties file stored in
~/.config/arcology2go/preferences.propertiesImplement all preference methods (directory path, settings, etc.)
Write unit tests using
AppPreferencesTestDoublepattern from contributing.org
TODO Implement DesktopBackgroundService
Create
DesktopBackgroundServicefor background indexingUse
CoroutineScope(Dispatchers.Default)instead of WorkManagerImplement file watching using
java.nio.file.WatchServiceTrigger re-indexing on file system events (vs. time-based threshold)
TODO Wire up Koin DI for Desktop
Create
DesktopModulewith desktop-specific dependenciesWire up
DesktopPreferences,JvmFileSystem,DesktopBackgroundServiceConfigure 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
PlatformContextinterface incommonMainresolveUri(uri: String): ByteArray(for images)shareText(text: String)(for sharing)getAttachmentBasePath(): String(for attachments)
Create
AndroidPlatformContextinandroidMainCreate
DesktopPlatformContextindesktopMain(file:// paths)
TODO Migrate Compose screens to Multiplatform
Convert all imports from =androidx.compose.= to =org.jetbrains.compose.=
Replace
LocalContext.currentwithPlatformContextinjectionTest 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
JvmFileSystemon Linux (should work as-is)Verify file browser navigation works with traditional paths
Test file reading/writing/creation
Test attachment handling with file:// URIs
TODO Full-Text Search
Verify
SearchServiceworks 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
QuizViewModelworks on desktopTest 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.WatchServiceAuto-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:
// 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:
// 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:00ZWindow 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
AppPreferencesTestDoublepattern for preferencesUse test file system (
TestFileSystemincommonTest)Test
DesktopBackgroundServicefile watching logicTest
DesktopPreferencespersistence
Desktop Integration Tests
Test
JvmFileSystemon actual Linux file systemTest 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)
*Window size: Start with tablet dimensions (1280x800) or native desktop size? 2. File system: Use
~/org-roamby 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/