Comprehensive design doc covering discovery-to-uninstall lifecycle: - System modification tracking for clean reversible uninstalls - Sorted by complexity from quick wins to major features - Covers FUSE wizard, autostart, MIME types, catalog browser, portable mode, batch operations, and more
27 KiB
Driftwood Feature Roadmap - Design Document
Goal: Add 26 features to make Driftwood the definitive AppImage manager for Linux newcomers coming from Windows, covering the full lifecycle from discovery to clean uninstall.
Architecture: All features build on the existing GTK4/libadwaita/Rust stack. Every system modification (desktop files, icons, MIME associations, autostart entries) is tracked in a central system_modifications table and fully reversed on app removal. Features are ordered from simplest to most complex.
Tech Stack: Rust, gtk4-rs, libadwaita-rs, rusqlite, gio, notify crate, pkexec/polkit for privileged operations, XDG specs (Desktop Entry, Autostart, MIME Applications), AppImage feed.json catalog.
Core Architecture: System Modification Tracking
Every feature that touches system files MUST use this tracking system. No exceptions.
New Database Table
CREATE TABLE IF NOT EXISTS system_modifications (
id INTEGER PRIMARY KEY AUTOINCREMENT,
appimage_id INTEGER REFERENCES appimages(id) ON DELETE CASCADE,
mod_type TEXT NOT NULL,
file_path TEXT NOT NULL,
previous_value TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_system_mods_appimage
ON system_modifications(appimage_id);
mod_type values: desktop_file, icon, autostart, mime_default, mime_entry, system_desktop, system_icon, system_binary
Core Functions (src/core/integrator.rs)
pub fn register_modification(db: &Database, appimage_id: i64, mod_type: &str, file_path: &str, previous_value: Option<&str>) -> Result<()>
pub fn undo_modification(db: &Database, mod_id: i64) -> Result<()>
pub fn undo_all_modifications(db: &Database, appimage_id: i64) -> Result<()>
Uninstall Flow
- Query
system_modificationsfor the appimage_id - For each modification (in reverse order):
desktop_file/autostart/icon: delete the filemime_default: restore previous_value viaxdg-mime default {previous_value} {mime_type}system_*: delete viapkexec rm
- Run
update-desktop-database ~/.local/share/applications/ - Run
gtk-update-icon-cache ~/.local/share/icons/hicolor/(if icons were removed) - Optionally delete app data paths (with user confirmation)
- Delete the AppImage file
- Delete DB record (CASCADE handles system_modifications rows)
CLI Purge Command
driftwood purge - removes ALL system modifications for ALL managed apps, for when Driftwood itself is being removed from the system.
Feature Specifications (Sorted: Easiest to Most Complex)
F1. Auto-Set Executable Permission on Existing Files
Complexity: Trivial (15 min)
Problem: Files already in scan directories skip chmod during drag-and-drop. Non-executable AppImages found during scan aren't fixed.
Files: src/ui/drop_dialog.rs, src/core/discovery.rs
Changes:
drop_dialog.rs: In thein_scan_dirbranch ofregister_dropped_files(), add permission check and fix:if !std::os::unix::fs::PermissionsExt::mode(&metadata.permissions()) & 0o111 != 0 { std::fs::set_permissions(&final_path, std::fs::Permissions::from_mode(0o755))?; }discovery.rs: After scan finds a non-executable AppImage, auto-fix permissions and log it
F2. Move-or-Copy Option for Drag-and-Drop (+ Keep in Place)
Complexity: Easy (30 min)
Problem: Always copies file, wasting disk. No option to keep in place.
Files: src/ui/drop_dialog.rs
Changes:
- Replace 3-button dialog with 4 response options:
"cancel"- Cancel"keep-in-place"- Keep in place (register at current location, set executable, no copy)"copy-only"- Copy to Applications (current "Just add" behavior)"copy-and-integrate"- Copy & add to menu (current "Add to app menu", suggested/default)
register_dropped_files()receives a newcopy_modeenum:KeepInPlace,CopyOnly,CopyAndIntegrateKeepInPlace: set executable on original path, register in DB at original location, optionally integrate- Dialog text updated: "Where should this AppImage live?"
F3. Version Rollback
Complexity: Easy (1 hr)
Problem: No way to go back if an update breaks things.
Files: src/core/updater.rs, src/ui/detail_view.rs, src/core/database.rs
Changes:
- New DB column:
previous_version_path TEXTon appimages - In
updater.rsupdate flow: before replacing, rename old to{path}.prevand store path inprevious_version_path - Detail view system tab: "Rollback to previous version" button (visible only when
previous_version_pathis set) - Rollback: swap current and .prev files, update DB fields, re-run analysis
- Cleanup: delete .prev file when user explicitly confirms or after configurable retention
F4. Source Tracking
Complexity: Easy (1 hr)
Problem: Users can't tell where an AppImage was downloaded from.
Files: src/ui/detail_view.rs, src/core/database.rs, src/ui/drop_dialog.rs
Changes:
- New DB column:
source_url TEXTon appimages - Auto-detect from
update_infofield (already stored): parse GitHub/GitLab URLs - Display "Source: github.com/obsidianmd/obsidian" on detail view overview tab
- Drop dialog: optional "Where did you download this?" text field (pre-filled if detected)
- Catalog installs (F26): automatically set source_url from catalog entry
F5. Launch Statistics Dashboard
Complexity: Easy (1-2 hrs)
Problem: Launch data is tracked but never shown.
Files: src/ui/dashboard.rs, src/core/database.rs
Changes:
- New DB queries:
get_top_launched(limit: i32) -> Vec<(String, u64)>- most launched appsget_launch_count_since(since: &str) -> u64- total launches since dateget_recent_launches(limit: i32) -> Vec<(String, String)>- recent launch events with timestamps
- Dashboard: new "Activity" section showing:
- Top 5 most-launched apps with launch counts
- "X launches this week" summary stat
- "Last launched: AppName, 2 hours ago"
F6. Batch Operations
Complexity: Medium (2-3 hrs)
Problem: Can't select multiple AppImages for bulk actions.
Files: src/ui/library_view.rs, src/ui/app_card.rs, src/window.rs
Changes:
- Library view header: "Select" toggle button
- When active: app cards show checkboxes, bottom action bar slides up
- Action bar buttons: "Integrate" / "Remove Integration" / "Delete" / "Export"
- Each action confirms with count: "Integrate 5 AppImages?"
- Delete uses the full uninstall flow (F14/system_modifications cleanup)
- Selection state stored in a
HashSet<i64>of record IDs on the LibraryView
F7. Automatic Desktop Integration on Scan
Complexity: Easy (30 min)
Problem: Users forget to integrate after scanning.
Files: src/window.rs, src/ui/preferences.rs
Changes:
- GSettings key
auto-integratealready exists (default false) - Wire it up: after scan completes in
window.rs, if setting is true, iterate newly discovered apps and callintegrator::integrate()for each - Register all created files via
register_modification() - Preferences: add toggle in Behavior page (already may be there, verify)
F8. Autostart Manager
Complexity: Medium (2 hrs)
Problem: No way to set AppImages to start at login.
Spec: XDG Autostart - .desktop file in ~/.config/autostart/
Files: src/core/integrator.rs, src/ui/detail_view.rs, src/core/database.rs
Changes:
- New DB column:
autostart INTEGER NOT NULL DEFAULT 0 - New functions in
integrator.rs:pub fn enable_autostart(db: &Database, record: &AppImageRecord) -> Result<PathBuf> pub fn disable_autostart(db: &Database, record_id: i64) -> Result<()> enable_autostart: creates~/.config/autostart/driftwood-{id}.desktopwith:[Desktop Entry] Type=Application Name={app_name} Exec={appimage_path} Icon={icon_path} X-GNOME-Autostart-enabled=true X-Driftwood-AppImage-ID={id}- Registers modification with mod_type
autostart - Detail view system tab: "Start at login" switch row
disable_autostart: deletes the file, removes from system_modifications- Uninstall flow: handled by
undo_all_modifications()
F9. System Notification Integration
Complexity: Medium (2 hrs)
Problem: Toasts vanish, important events get missed.
Files: src/core/notification.rs, src/window.rs
Changes:
- Use
gio::Application::send_notification(id, notification)for:- App crash on launch (high priority)
- Updates available after background check (normal priority)
- Security vulnerabilities found (high priority if critical/high severity)
- Keep toasts for minor confirmations (copied, integrated, etc.)
- Notification click opens Driftwood and navigates to relevant view
notification.rsalready has the logic for CVE notifications - extend to use gio::Notification instead of/in addition to libnotify
F10. Storage Dashboard per App
Complexity: Medium (2 hrs)
Problem: Users don't know total disk usage per app.
Files: src/ui/detail_view.rs, src/core/footprint.rs, src/core/database.rs
Changes:
footprint.rs: new functionget_total_footprint(db: &Database, record_id: i64) -> FootprintSummarypub struct FootprintSummary { pub binary_size: u64, pub config_size: u64, pub cache_size: u64, pub data_size: u64, pub state_size: u64, pub total_size: u64, }- Detail view storage tab: visual breakdown with labeled size bars
- Each category shows path and size: "Config (~/.config/MyApp) - 12 MB"
- "Clean cache" button per category (deletes cache paths only)
- Library list view: optional "Total size" column
F11. Background Update Checks
Complexity: Medium (2-3 hrs)
Problem: No automatic update awareness.
Files: src/window.rs, src/ui/dashboard.rs, src/ui/library_view.rs, GSettings schema
Changes:
- New GSettings key:
update-check-interval-hourstype i, default 24, range 1-168 - New GSettings key:
last-update-checktype s, default '' - On startup: if
auto-check-updatesis true and enough time has passed, spawn background check - Background check: iterate all apps with update_info, call
check_appimage_for_update()per app - Results: update
update_availablecolumn in DB, send gio::Notification if updates found - Dashboard: show "X updates available" with timestamp "Last checked: 2h ago"
- Library view: badge on apps with updates
- Preferences: toggle + interval dropdown
F12. One-Click Update All
Complexity: Medium (3-4 hrs)
Problem: Can only update one app at a time.
Files: src/ui/dashboard.rs, new src/ui/batch_update_dialog.rs, src/core/updater.rs
Changes:
- Dashboard: "Update All (N)" button when updates are available
- Opens batch update dialog showing list of apps to update with checkboxes
- Progress: per-app progress bar, overall progress bar
- Each update: download new version, save old as .prev (F3 rollback), replace, re-analyze
- On completion: summary toast "Updated 5 apps successfully, 1 failed"
- Failed updates: show error per app, keep old version
- Cancel: stops remaining updates, already-updated apps stay updated
F13. Full Uninstall with Data Cleanup
Complexity: Medium (3 hrs)
Problem: Deleting AppImage leaves config/cache/data behind.
Files: src/ui/detail_view.rs, new confirmation dialog logic, src/core/footprint.rs
Changes:
- Delete button in detail view triggers new uninstall flow:
- Show dialog with FootprintSummary (from F10):
- "Delete MyApp?" with breakdown:
- AppImage file (245 MB)
- Configuration (~/.config/MyApp) - 12 MB
- Cache (~/.cache/MyApp) - 89 MB
- Data (~/.local/share/MyApp) - 1.2 GB
- Total: 1.5 GB will be freed
- All checked by default, user can uncheck to keep data
- On confirm:
- Call
undo_all_modifications()(removes .desktop, icons, autostart, MIME defaults) - Delete selected data paths
- Delete the AppImage file
- Remove DB record
- Call
- Show dialog with FootprintSummary (from F10):
- Batch delete (F6) uses same flow with aggregated summary
F14. Theme/Icon Preview in Drop Dialog
Complexity: Medium (2 hrs)
Problem: Users don't see what the app looks like before integrating.
Files: src/ui/drop_dialog.rs, src/core/inspector.rs
Changes:
- New function in inspector:
extract_icon_fast(path: &Path) -> Option<PathBuf>- Runs
unsquashfs -lto find icon file, then extracts just that one file - Much faster than full inspection
- Runs
- Drop dialog: after registration, show preview card:
- App icon (from fast extraction)
- App name (from filename initially, updated after full analysis)
- "This is how it will appear in your app menu"
- If icon extraction fails, show default AppImage icon
F15. FUSE Fix Wizard
Complexity: Significant (4-5 hrs)
Problem: #1 support issue - FUSE not installed, AppImages won't run.
Files: src/core/fuse.rs, new src/ui/fuse_wizard.rs, src/ui/dashboard.rs, new data/app.driftwood.Driftwood.policy
Changes:
- New distro detection in
fuse.rs:pub struct DistroInfo { pub id: String, // "ubuntu", "fedora", "arch", etc. pub id_like: Vec<String>, pub version_id: String, } pub fn detect_distro() -> Option<DistroInfo> // parses /etc/os-release pub fn get_fuse_install_command(distro: &DistroInfo) -> Option<String> - Install commands by distro family:
- Debian/Ubuntu:
apt install -y libfuse2t64(24.04+) orapt install -y libfuse2(older) - Fedora/RHEL:
dnf install -y fuse-libs - Arch/Manjaro:
pacman -S --noconfirm fuse2 - openSUSE:
zypper install -y libfuse2
- Debian/Ubuntu:
- Polkit policy file (
data/app.driftwood.Driftwood.policy):<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "https://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd"> <policyconfig> <action id="app.driftwood.Driftwood.install-fuse"> <description>Install FUSE library for AppImage support</description> <message>Authentication is required to install the FUSE library</message> <defaults> <allow_any>auth_admin</allow_any> <allow_inactive>auth_admin</allow_inactive> <allow_active>auth_admin</allow_active> </defaults> </action> </policyconfig> - Wizard dialog (NavigationPage-style multi-step):
- "FUSE is not installed" - explanation of what FUSE is and why it's needed
- "We detected {distro}. Install with:
{command}" - shows exact command - "Install now" button runs
pkexec sh -c "{command}"and shows output - Re-check: calls
detect_system_fuse()and shows success/failure
- Dashboard: yellow banner when FUSE is missing with "Fix now" button
F16. File Type Association Manager
Complexity: Significant (4 hrs)
Problem: AppImages don't register MIME types, so files don't open with them.
Spec: XDG MIME Applications - ~/.local/share/applications/mimeapps.list
Files: src/core/integrator.rs, src/ui/detail_view.rs
Changes:
inspector.rsalready extracts desktop entry content including MimeType= field- New function:
parse_mime_types(desktop_entry: &str) -> Vec<String>- extracts MimeType= values - When integrating: include
MimeType=in generated .desktop file - Detail view overview tab: "Supported file types" section listing MIME types
- Per-type toggle: "Set as default for .png files"
- Setting default:
- Query current default:
xdg-mime query default {mime_type} - Store in
system_modificationswithprevious_value= current default - Set new:
xdg-mime default driftwood-{id}.desktop {mime_type}
- Query current default:
- Removing: restore previous default from
previous_value - Uninstall: handled by
undo_all_modifications()
F17. Taskbar/Panel Icon Fix (StartupWMClass)
Complexity: Significant (3 hrs)
Problem: Running AppImages show wrong/generic icon in taskbar.
Files: src/core/integrator.rs, src/core/wayland.rs, src/ui/detail_view.rs
Changes:
- During inspection: extract
StartupWMClass=from embedded .desktop entry - Store in new DB column:
startup_wm_class TEXT - When generating .desktop file for integration, include StartupWMClass if available
- After launch + Wayland analysis: read
/proc/{pid}/environforGDK_BACKEND, check window list viaxdotoolorxpropfor WM_CLASS - If WM_CLASS doesn't match StartupWMClass: log warning, offer to patch .desktop file
- Detail view system tab: show detected WM_CLASS, allow manual override
F18. Download Verification Helper
Complexity: Significant (4 hrs)
Problem: No way to verify AppImage authenticity.
Files: New src/core/verification.rs, src/ui/detail_view.rs, src/ui/drop_dialog.rs
Changes:
- AppImage signature spec: GPG signature embedded at offset stored in ELF section
- New module
verification.rs:pub enum VerificationStatus { SignedValid { signer: String }, SignedInvalid { reason: String }, Unsigned, ChecksumMatch, ChecksumMismatch, NotChecked, } pub fn check_embedded_signature(path: &Path) -> VerificationStatus pub fn verify_sha256(path: &Path, expected: &str) -> VerificationStatus check_embedded_signature: runsunsquashfs -lto check for.sha256or signature files, or uses the AppImage --appimage-signature flag- Drop dialog: after adding, show verification badge
- Detail view: "Verification: Signed by ..." or "Unsigned - verify manually"
- Manual verification: paste SHA256 hash, compare with computed hash
- New DB column:
verification_status TEXTon appimages
F19. First-Run Permission Summary
Complexity: Medium (3 hrs)
Problem: Users don't know what an AppImage can access before running it.
Files: New src/ui/permission_dialog.rs, src/ui/detail_view.rs
Changes:
- Before first launch of any AppImage (check
launch_eventscount = 0):- Show permission dialog:
- "MyApp will run with full access to your files and system"
- Icon + app name
- If
has_firejail(): offer sandbox options- "Run without restrictions" (default for now)
- "Run in Firejail sandbox (recommended)"
- "Don't show this again" checkbox (stored per-app in DB)
- If user chooses Firejail: set
sandbox_mode = 'firejail'in DB
- Show permission dialog:
- New DB column:
first_run_prompted INTEGER NOT NULL DEFAULT 0 - Skip dialog if
first_run_prompted = 1 - Preferences: global toggle to disable first-run prompts
F20. Default App Selector
Complexity: Medium (3 hrs)
Problem: Can't set AppImage as default browser, mail client, etc.
Files: src/ui/detail_view.rs, src/core/integrator.rs
Changes:
- Detect app capabilities from categories:
WebBrowser-> can be default web browserEmail-> can be default email clientFileManager-> can be default file managerTerminalEmulator-> can be default terminal
- Detail view overview tab: "Set as default" section (only shown for applicable categories)
- Setting defaults:
- Browser:
xdg-settings set default-web-browser driftwood-{id}.desktop - Email:
xdg-mime default driftwood-{id}.desktop x-scheme-handler/mailto - File manager:
xdg-mime default driftwood-{id}.desktop inode/directory
- Browser:
- Before setting: query current default, store in
system_modificationswithprevious_value - Uninstall: restore previous defaults via
undo_all_modifications() - Requirements: app must be integrated first (needs .desktop file)
F21. Multi-User / System-Wide Install
Complexity: Significant (4 hrs)
Problem: Can't install for all users on a shared computer.
Files: src/core/integrator.rs, src/ui/detail_view.rs, polkit policy
Changes:
- Reuses polkit policy from F15 (add new action
app.driftwood.Driftwood.system-install) - "Install system-wide" option in detail view (requires app to be integrated first)
- Flow:
pkexec cp {appimage} /opt/driftwood-apps/{filename}pkexec chmod 755 /opt/driftwood-apps/{filename}- Generate system .desktop in
/usr/share/applications/driftwood-{id}.desktop pkexec cp {desktop_file} /usr/share/applications/- Copy icon to
/usr/share/icons/hicolor/via pkexec pkexec update-desktop-database /usr/share/applications/
- Register all paths as
system_desktop,system_icon,system_binaryin system_modifications - Uninstall system-wide:
pkexec rmfor each tracked path - DB flag:
system_wide INTEGER NOT NULL DEFAULT 0
F22. CLI Enhancements
Complexity: Medium (3 hrs)
Problem: Missing install-from-URL and update-all commands.
Files: src/cli.rs
New commands:
driftwood install <url>- Download from URL, validate, move to ~/Applications, set executable, register, optionally integratedriftwood update --all- Check all apps, download and apply available updatesdriftwood autostart <path> --enable/--disable- Toggle autostart for an AppImagedriftwood purge- Remove ALL system modifications for all managed apps (for Driftwood removal)driftwood verify <path>- Check embedded signature or compare SHA256
F23. Portable Mode / USB Drive Support
Complexity: Major (6-8 hrs)
Problem: Can't manage AppImages on removable media.
Files: New src/core/portable.rs, src/ui/library_view.rs, src/window.rs, src/core/database.rs
Changes:
- New GSettings key:
watch-removable-mediatype b, default false portable.rs:pub fn detect_removable_mounts() -> Vec<MountInfo> pub fn scan_mount_for_appimages(mount: &MountInfo) -> Vec<DiscoveredAppImage> pub fn is_path_on_removable(path: &Path) -> bool- Detection: parse
/proc/mountsfor removable media (type vfat, exfat, ntfs on /media/ or /run/media/) - Alternative: use
gio::VolumeMonitorto watch for mount/unmount events - DB changes:
- New column:
is_portable INTEGER DEFAULT 0 - New column:
mount_point TEXT
- New column:
- Library view: "Portable" filter/section showing apps on removable media
- When drive unmounts: grey out those apps, mark as unavailable
- When drive mounts: re-scan and refresh
- Portable apps skip the "copy to ~/Applications" step - they stay on the drive
- Integration: .desktop files use the full path (may break when unmounted - show warning)
F24. "Similar to..." Recommendations
Complexity: Medium (3 hrs, depends on F26)
Problem: No app discovery within the tool.
Files: src/ui/detail_view.rs, src/core/database.rs
Changes:
- Requires catalog data from F26 (catalog_apps table populated)
- New DB query:
find_similar_apps(categories: &[String], exclude_id: i64, limit: i32) -> Vec<CatalogApp> - Matches on shared categories, weighted by specificity
- Detail view overview tab: "You might also like" section at the bottom
- Shows up to 5 catalog apps with icon, name, one-line description
- Click opens catalog detail page (F26)
- Falls back to nothing if catalog is empty
F25. AppImageHub In-App Catalog Browser
Complexity: Major (8-12 hrs)
Problem: No way to discover and install new AppImages from within the app.
Data source: https://appimage.github.io/feed.json (~1500 apps)
Files: New src/ui/catalog_view.rs, new src/ui/catalog_detail.rs, src/core/database.rs, src/window.rs
Architecture:
Data Layer
- Fetch
feed.jsonand parse intocatalog_appstable (already exists in DB schema) - Store in
catalog_sourcesas source record - Fields mapped from feed.json:
name->namedescription->descriptioncategories->categories(joined with ;)authors[0].name->authorlicense->licenselinks(type=GitHub) ->repository_urllinks(type=Download) ->download_urlicons[0]->icon_url(prefix withhttps://appimage.github.io/database/)screenshots->screenshots(JSON array)
- Refresh: on first open, then daily if enabled
- New GSettings key:
catalog-last-refreshedtype s, default ''
Catalog Browse View (NavigationPage)
- Header: search bar + category filter chips
- Categories from feed: AudioVideo, Development, Education, Game, Graphics, Network, Office, Science, System, Utility
- Grid of catalog app cards (reuse app_card pattern):
- Icon (fetched from URL, cached locally)
- App name
- Short description (first line)
- Category badge
- Pagination: load 50 at a time, "Load more" button
- Search: filters by name and description (client-side, data is local)
Catalog App Detail (NavigationPage pushed on click)
- App icon (large)
- Name, author, license
- Full description
- Screenshots carousel (if available)
- "Install" button (suggested style)
- Source link (opens GitHub/website in browser)
Install Flow
- User clicks "Install"
- Resolve download URL:
- If
download_urlpoints to GitHub releases page: fetch latest release via GitHub API (https://api.github.com/repos/{owner}/{repo}/releases/latest), find .AppImage asset - If direct link: use as-is
- If
- Download with progress bar (reqwest or gio file download)
- Validate: check AppImage magic bytes
- Move to ~/Applications, set executable
- Register in DB with
source_urlset - Run full analysis pipeline
- Optionally integrate (based on
auto-integratesetting) - Navigate to the app's detail view in library
Navigation
- Main sidebar/navigation: add "Catalog" entry alongside Dashboard and Library
- Or: floating action button on library view "Browse catalog"
New GSettings Keys Summary
| Key | Type | Default | Range/Choices | Feature |
|---|---|---|---|---|
update-check-interval-hours |
i | 24 | 1-168 | F11 |
last-update-check |
s | '' | - | F11 |
catalog-last-refreshed |
s | '' | - | F25 |
watch-removable-media |
b | false | - | F23 |
show-first-run-prompt |
b | true | - | F19 |
New Database Columns Summary
| Table | Column | Type | Default | Feature |
|---|---|---|---|---|
| appimages | previous_version_path | TEXT | NULL | F3 |
| appimages | source_url | TEXT | NULL | F4 |
| appimages | autostart | INTEGER | 0 | F8 |
| appimages | startup_wm_class | TEXT | NULL | F17 |
| appimages | verification_status | TEXT | NULL | F18 |
| appimages | first_run_prompted | INTEGER | 0 | F19 |
| appimages | system_wide | INTEGER | 0 | F21 |
| appimages | is_portable | INTEGER | 0 | F23 |
| appimages | mount_point | TEXT | NULL | F23 |
New Files Summary
| File | Feature | Purpose |
|---|---|---|
src/ui/fuse_wizard.rs |
F15 | FUSE installation wizard dialog |
src/ui/batch_update_dialog.rs |
F12 | Batch update progress dialog |
src/ui/permission_dialog.rs |
F19 | First-run permission summary |
src/ui/catalog_view.rs |
F25 | Catalog browse/search page |
src/ui/catalog_detail.rs |
F25 | Catalog app detail page |
src/core/verification.rs |
F18 | Signature and checksum verification |
src/core/portable.rs |
F23 | Removable media detection and management |
data/app.driftwood.Driftwood.policy |
F15, F21 | Polkit policy for privileged operations |
Implementation Order
The features are numbered F1-F25 in order of complexity. Implement sequentially - some later features depend on earlier ones:
- F25 (Catalog) depends on nothing but is largest
- F24 (Similar to) depends on F25
- F12 (Update All) depends on F11 (Background checks)
- F13 (Full Uninstall) depends on system_modifications table (core architecture)
- F20 (Default App) depends on F16 (MIME associations)
Critical path: Core architecture (system_modifications) -> F1-F7 quick wins -> F8-F14 medium features -> F15-F22 significant features -> F23-F25 major features