Skip to content

refactor(plugin install): speed up plugin installation with native ZIP extraction - #2715

Open
codewithchai0605 wants to merge 6 commits into
Acode-Foundation:mainfrom
codewithchai0605:feat/better-plugin-installer
Open

refactor(plugin install): speed up plugin installation with native ZIP extraction#2715
codewithchai0605 wants to merge 6 commits into
Acode-Foundation:mainfrom
codewithchai0605:feat/better-plugin-installer

Conversation

@codewithchai0605

Copy link
Copy Markdown

Summary

This PR improves plugin installation performance, especially for plugins containing many small files such as file/folder icon providers.

The previous installer extracted archive entries in JavaScript with a concurrency limit of 2. This caused significant overhead from repeated JS-to-native filesystem calls.

This change moves archive extraction to native Android code and writes files directly from the ZIP archive.

Changes

  • Extract plugin ZIP archives natively using ZipFile.
  • Stream archive entries directly to a staging directory.
  • Activate updates through a directory swap, preserving the existing plugin if extraction fails.
  • Restore the previous plugin installation if an earlier update was interrupted during the swap.
  • Prevent concurrent installations of the same plugin.
  • Validate plugin IDs and archive paths to prevent path traversal.
  • Add archive size and entry-count limits.
  • Optimize extraction for many small files:
    • shared 64 KiB buffer
    • direct output streams
    • no per-entry canonical filesystem lookup

@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR moves plugin ZIP extraction into the Android native layer and activates extracted plugins through staging and backup directory swaps.

  • Adds native archive validation, extraction limits, and same-plugin concurrency prevention.
  • Adds interrupted-swap recovery and cleanup of matching backup and staging directories.
  • Replaces incremental JavaScript extraction with a cached archive passed through Cordova.

Confidence Score: 3/5

The PR is not yet safe to merge because failed fresh installs are retained and interrupted staging directories can remain indefinitely without another installation of the same plugin.

The post-activation existence check makes fresh-install cleanup unreachable, while interrupted-artifact recovery is scoped to later extractions for the same destination and therefore does not reliably reclaim abandoned storage.

Files Needing Attention: src/lib/installPlugin.js; src/plugins/pluginContext/src/android/Tee.java

Important Files Changed

Filename Overview
src/lib/installPlugin.js Native extraction integration fixes recovered-update deletion but records prior installation state too late, disabling cleanup after failed fresh-plugin loads.
src/plugins/pluginContext/src/android/Tee.java Adds guarded native extraction and directory-swap recovery, but orphan staging cleanup remains dependent on another installation of the same plugin.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Download plugin ZIP] --> B[Native extraction]
  B --> C[Create plugin-scoped staging directory]
  C --> D[Extract entries and write manifest]
  D --> E[Move existing destination to backup]
  E --> F[Activate staging as destination]
  F --> G[Load plugin]
  G -->|Failure on fresh install| H[Cleanup condition]
  H -->|pluginWasInstalled already true| I[Broken directory remains]
  C -->|Process terminated| J[Orphan staging directory]
  J -->|Same plugin installed again| K[Scoped recovery deletes orphan]
  J -->|No later same-plugin install| L[Orphan remains]
Loading

Reviews (2): Last reviewed commit: "fix: prevent recovered-update misclassif..." | Re-trigger Greptile

Comment thread src/lib/installPlugin.js Outdated
Comment thread src/plugins/pluginContext/src/android/Tee.java
@UnschooledGamer UnschooledGamer added community and removed enhancement New feature or request labels Aug 14, 2026
…ulation

installPlugin.js: Move pluginWasInstalled check to after extractPluginArchive so that native recovery (restoreInterruptedInstall) has already run before the flag is recorded. Previously, a recovered update could be misclassified as a fresh install, causing the error handler to delete the restored directory.

Tee.java: Expand restoreInterruptedInstall to also clean up orphaned .install-* staging directories alongside .backup-* directories, preventing indefinite storage accumulation from interrupted extractions.
@codewithchai0605

Copy link
Copy Markdown
Author

@greptile-apps review

Comment thread src/lib/installPlugin.js
Comment on lines +204 to +205
extractionComplete = true;
pluginWasInstalled = await fsOperation(pluginDir).exists();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Fresh-install cleanup is unreachable

When a newly installed plugin fails during script loading or initialization, pluginWasInstalled has already been measured after native activation and is therefore true, so the catch block retains the broken plugin directory instead of removing the failed fresh installation.

Knowledge Base Used: Plugin System

Comment on lines +329 to +332
private static void restoreInterruptedInstall(File parent, File destination) throws IOException {
String backupPrefix = "." + destination.getName() + ".backup-";
String stagingPrefix = "." + destination.getName() + ".install-";
File[] children = parent.listFiles();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Staging cleanup requires reinstallation

When Android terminates an extraction and the user does not reinstall or update that same plugin, recovery never runs for its plugin-scoped staging prefix, leaving the abandoned extraction and its potentially hundreds of megabytes on disk indefinitely.

Knowledge Base Used: Plugin System

@codewithchai0605 codewithchai0605 changed the title speed up plugin installation with native ZIP extraction refactor(plugin install): speed up plugin installation with native ZIP extraction Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

3 participants