shared/ ← Core: models, DAO interfaces, SQLite impl
commonMain ← Interfaces + models (all targets)
desktopMain ← JVM SQLite driver
nativeAppMain ← Native SQLite driver
app/ ← Desktop GUI (JVM + Compose, unchanged)
cli/ ← Native CLI binary (direct SQLite access)
chrome/ ← Chrome Extension (future, JS target, in-memory)
Chrome extension supports the same task/data model but without persistence — acts as a lightweight entry point that funnels users to the desktop app for full functionality.
Motivation
The current CLI architecture (#3828, PR #3829 closed) uses an HTTP bridge to communicate with the running JVM app. This has fundamental problems:
crosspaste historycommand/usr/local/binneeds root, macOS/Windows need app to run firstNew Architecture
Leverage Kotlin Multiplatform's multi-target compilation to share
commonMaincode across Desktop, Native CLI, and Chrome Extension:DAO Interface Abstraction
All DAOs are interface-based, enabling different storage backends:
SqlPasteDaoSqlPasteDaoMemoryPasteDaoChrome extension supports the same task/data model but without persistence — acts as a lightweight entry point that funnels users to the desktop app for full functionality.
Implementation Plan (20 Steps)
Phase 1: SQLDelight Migration to shared (Steps 1-4)
native-sqlite-drivertogradle/libs.versions.toml(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)shared/build.gradle.kts(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950).sqfiles + migrations fromapp/toshared/; remove SQLDelight fromapp/build.gradle.kts(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)DriverFactoryinterface +Int2LongAdapterto shared (PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)Phase 2: Move Model Classes (Steps 5-8)
AppInfo,PasteTask,TaskStatus,TaskType,SyncState,ChangeType(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)SecureIO,SearchContentService,PasteExportParam,TaskSubmitter(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)SyncInfo,EndpointInfo(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)SyncRuntimeInfo,PasteResourceInfo(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)Phase 3: DAO Interface Extraction + Migration (Steps 9-12)
PasteTagDaointerface +SqlPasteTagDaoimpl, move to shared (PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)SecureDao→SqlSecureDao+TaskDao→SqlTaskDaointerfaces and impls (PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)SyncRuntimeInfoDao: removenet.filterdependency, extract interface +SqlSyncRuntimeInfoDaoimpl, introduceConnectInfo(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)PasteDaointerface +SqlPasteDaoimpl, move to shared (PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)Phase 4: Native Driver + CLI Foundation (Steps 13-15)
NativeDriverFactoryinshared/nativeAppMain(PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)cli/build.gradle.kts: addshareddependency, link system sqlite3 (PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)CliAdapters(CliReadOnlyAppConfig, CliConfigManager, CliPlatformUserDataPathProvider),NoOpServices, full DAO registrations including SecureIO (PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)Phase 5: Rewrite CLI Commands (Steps 16-18)
history,search,paste,status(HTTP → direct DAO)delete,fav,tagsconfig+devicescommandsPhase 6: Cleanup (Steps 19-20)
CliRouting,CliTokenManager,CliSymlinkService, CLI DTOs (PR 🔨 Move SQLDelight to shared module, extract DAO interfaces, remove CLI bridge #3950)Key Technical Decisions
app.cash.sqldelight:native-driver) for Kotlin/Native SQLite access