fix(plugins): Fix GitHub install and update functionality for plugins installed from URLs (#167)

* fix(plugins): Fix GitHub install button for single plugin installation

- Clone install button before attaching event listener to prevent duplicate handlers
- Add safety checks for pluginStatusDiv element
- Move installFromCustomRegistry function definition earlier in file
- Add error logging when button/elements not found
- Ensure consistent button reference usage in event handlers

Fixes issue where Install button in 'Install Single Plugin' section
was not working properly.

* fix(plugins): Add button type and better logging for install button

- Add type='button' to install button to prevent form submission
- Add console logging to debug click handler attachment
- Add preventDefault and stopPropagation to click handler
- Improve error logging for debugging

* fix(plugins): Re-attach install button handler when section is shown

- Extract install button handler to separate function
- Re-attach handler when GitHub install section is toggled visible
- Add data attribute to prevent duplicate handler attachments
- Add comprehensive logging for debugging
- Handler now attaches even if section starts hidden

* fix(plugins): Add comprehensive logging to debug install button handler

- Add logging at function entry points
- Add logging when section is shown and handler re-attached
- Add logging before and after calling attachInstallButtonHandler
- Helps diagnose why handler isn't being attached

* fix(plugins): Expose GitHub install handlers globally and add fallback

- Expose setupGitHubInstallHandlers and attachInstallButtonHandler to window object
- Add fallback handler attachment after page load delay
- Fix typo in getElementById call
- Allows manual testing from browser console
- Ensures handlers are accessible even if IIFE scope issues occur

* fix(plugins): Add fallback handler attachment after page load

* fix(plugins): Ensure GitHub install handlers are set up even if already initialized

- Add check to verify setupGitHubInstallHandlers exists before calling
- Call setupGitHubInstallHandlers even if initializePlugins was already called
- Add comprehensive logging to track function execution
- Helps diagnose why handlers aren't being attached

* fix(plugins): Add more prominent logging markers for easier debugging

* fix(plugins): Add simple standalone handler for GitHub plugin installation

- Create handleGitHubPluginInstall() function defined early and globally
- Add inline onclick handler to button as fallback
- Bypasses complex initialization flow and IIFE scope issues
- Direct approach that works immediately without dependencies
- Provides clear error messages and logging

* chore: Update 7-segment-clock plugin submodule

- Update to latest version with scaling support
- Includes compatible_versions field fix for plugin store installation

* fix(plugins): Add update and uninstall handling to global event delegation fallback

- Add 'update' action handling in handleGlobalPluginAction fallback
- Add 'uninstall' action handling with confirmation dialog
- Fixes issue where update/uninstall buttons did nothing
- Buttons now work even if handlePluginAction isn't available yet

* fix(plugins): Improve error message for plugin updates from GitHub URLs

- Check if plugin is a git repository before checking registry
- Provide more accurate error messages for plugins installed from URLs
- Fixes misleading 'Plugin not found in registry' error for git-based plugins
- Update should work for plugins installed from GitHub URLs even if not in registry

* fix(plugins): Add detailed logging for plugin update failures

- Log git command that failed and return code
- Add logging before/after update attempt
- Log whether plugin is detected as git repository
- Helps diagnose why updates fail for plugins installed from URLs

* fix(plugins): Add better logging for plugin update detection

- Log when plugin is detected as git repository
- Log when plugin is not a git repository
- Provide helpful message for ZIP-installed plugins
- Helps diagnose why updates fail for plugins installed from URLs

* fix(plugins): Enable updates for plugins installed from GitHub URLs

- Get git remote URL from plugin directory even if .git is missing
- If plugin not in registry but has remote URL, reinstall as git repo
- Allows updating plugins installed from URLs even if git clone failed initially
- Falls back to reinstalling from original URL to enable future updates

* fix(plugins): Reinstall from git remote URL if plugin not in registry

- When plugin is not a git repo and not in registry, check for git remote URL
- If remote URL exists, reinstall plugin from that URL to enable future updates
- Handles case where plugin was installed from URL but git clone failed initially

* fix(plugins): Improve git update error handling and logging

- Make git fetch non-fatal (log warning but continue)
- Make git checkout non-fatal (log warning but continue)
- Add detailed error messages for common git failures
- Log which git command failed and return code
- Better handling of authentication, merge conflicts, and unrelated histories

* fix(plugins): Add detailed exception logging to update endpoint

- Log full traceback when update fails
- Log exception details in catch block
- Helps diagnose update failures from API endpoint

* fix(plugins): Handle untracked files during plugin update

- Remove .dependencies_installed marker file before pull (safe to regenerate)
- Stash untracked files using 'git stash -u' if they can't be removed
- Prevents 'untracked files would be overwritten' errors during update
- Fixes issue where .dependencies_installed blocks git pull

* chore: Update 7-segment-clock submodule with improved clone instructions

---------

Co-authored-by: Chuck <chuck@example.com>
This commit is contained in:
Chuck
2026-01-03 09:44:51 -05:00
committed by GitHub
parent 9f1711f9a3
commit a13bd971b3
6 changed files with 513 additions and 128 deletions

View File

@@ -2179,12 +2179,23 @@ def update_plugin():
current_commit = git_info_before.get('sha')
current_branch = git_info_before.get('branch')
# Check if plugin is a git repo first (for better error messages)
plugin_path_dir = Path(api_v3.plugin_store_manager.plugins_dir) / plugin_id
is_git_repo = False
if plugin_path_dir.exists():
git_info = api_v3.plugin_store_manager._get_local_git_info(plugin_path_dir)
is_git_repo = git_info is not None
if is_git_repo:
print(f"[UPDATE] Plugin {plugin_id} is a git repository, will update via git pull")
remote_info = api_v3.plugin_store_manager.get_plugin_info(plugin_id, fetch_latest_from_github=True)
remote_commit = remote_info.get('last_commit_sha') if remote_info else None
remote_branch = remote_info.get('branch') if remote_info else None
# Update the plugin
print(f"[UPDATE] Attempting to update plugin {plugin_id}...")
success = api_v3.plugin_store_manager.update_plugin(plugin_id)
print(f"[UPDATE] Update result for {plugin_id}: {success}")
if success:
updated_last_updated = current_last_updated
@@ -2259,9 +2270,18 @@ def update_plugin():
if not plugin_path_dir.exists():
error_msg += ': Plugin not found'
else:
plugin_info = api_v3.plugin_store_manager.get_plugin_info(plugin_id)
if not plugin_info:
error_msg += ': Plugin not found in registry'
# Check if it's a git repo (could be installed from URL, not in registry)
git_info = api_v3.plugin_store_manager._get_local_git_info(plugin_path_dir)
if git_info:
# It's a git repo, so update should have worked - provide generic error
error_msg += ': Update failed (check logs for details)'
else:
# Not a git repo, check if it's in registry
plugin_info = api_v3.plugin_store_manager.get_plugin_info(plugin_id)
if not plugin_info:
error_msg += ': Plugin not found in registry and not a git repository'
else:
error_msg += ': Update failed (check logs for details)'
if api_v3.operation_history:
api_v3.operation_history.record_operation(
@@ -2271,6 +2291,11 @@ def update_plugin():
error=error_msg
)
import traceback
error_details = traceback.format_exc()
print(f"[UPDATE] Update failed for {plugin_id}: {error_msg}")
print(f"[UPDATE] Traceback: {error_details}")
return error_response(
ErrorCode.PLUGIN_UPDATE_FAILED,
error_msg,
@@ -2278,6 +2303,11 @@ def update_plugin():
)
except Exception as e:
import traceback
error_details = traceback.format_exc()
print(f"[UPDATE] Exception in update_plugin endpoint: {str(e)}")
print(f"[UPDATE] Traceback: {error_details}")
from src.web_interface.errors import WebInterfaceError
error = WebInterfaceError.from_exception(e, ErrorCode.PLUGIN_UPDATE_FAILED)
if api_v3.operation_history: