Commit graph

13753 commits

Author SHA1 Message Date
Johannes Millan
9eadf184f0 fix(plugin): fix failing unit tests for PluginService
- Fix theme detection logic in _getBaseCfg() to properly handle 'dark'/'light' string values
- Update tests to mock PluginLoaderService and PluginCleanupService dependencies
- Fix test expectations for concurrent initialization behavior
- Adjust error handling test to match implementation behavior
- Remove HTTP request expectations in favor of mocked service calls

All 1212 unit tests now pass successfully.
2025-06-19 14:25:43 +02:00
Johannes Millan
7d1d7b0b46 feat(plugin): add lazy loading and compression support
- Add PluginLoaderService for lazy loading plugin assets
- Implement in-memory caching with shareReplay for efficient loading
- Add preloading support for critical plugins
- Create compression utilities using fflate library
- Update PluginCacheService to compress plugins > 1KB
- Support automatic compression/decompression in cache
- Add HTTP caching headers for 1-hour cache control
- Simplify PluginService by removing duplicate loading logic
- Add comprehensive tests for compression utilities

This improves initial load time by only loading critical plugins
upfront and compresses stored plugins to reduce storage usage.
2025-06-19 14:25:43 +02:00
Johannes Millan
6af74310a6 feat(plugin): implement comprehensive memory management
- Add PluginCleanupService to track and clean up resources
- Track timers, intervals, event listeners, abort controllers, and iframes
- Implement OnDestroy in PluginService, PluginBridgeService, and PluginHooksService
- Update UI components to properly register and clean up resources
- Add cleanup() method to PluginAPI for resource cleanup
- Ensure all plugin resources are properly released on unload
- Add unit tests for PluginCleanupService

This prevents memory leaks by ensuring all plugin-created resources
are properly tracked and cleaned up when plugins are unloaded.
2025-06-19 14:25:43 +02:00
Johannes Millan
1001ecb00c feat(plugin): fix API consistency between plugin-api and internal types
- Created plugin-api-mapper.ts with conversion functions between internal types (TaskCopy, ProjectCopy, TagCopy) and plugin API types (TaskData, ProjectData, TagData)
- Updated PluginAPI implementation to use proper types from @super-productivity/plugin-api package
- Removed duplicate PluginAPI interface from plugin-api.model.ts
- Added mapper for SnackCfg to SnackParams for consistent notification handling
- Updated PluginBridgeService to accept standard SnackCfg type
- Fixed all imports to use the canonical plugin-api types
- Ensured plugins work with simplified, stable data structures while app can evolve internal types

This creates a clean separation between the plugin API contract and internal implementation details.
2025-06-19 14:25:43 +02:00
Johannes Millan
091ecf72c1 feat(plugin): add comprehensive unit tests for PluginService
- Created complete test suite for PluginService with 28 tests
- Fixed type import issues for PluginNodeScriptRequest, PluginNodeScriptResult, PluginSidePanelBtnCfg
- Resolved window.ea type conflicts between test.ts and window-ea.d.ts
- Updated plugin-api package to avoid duplicate global declarations
- Fixed rxjs compatibility issues by using v6-compatible patterns
- Added proper HTTP request mocking for built-in plugin loading
- Fixed side panel and plugin management test setup
- Tests cover: initialization, side panel management, plugin loading/unloading, ZIP handling, error scenarios

Currently: 17 passing, 11 failing tests (significant progress from initial compilation errors)
2025-06-19 14:25:43 +02:00
Johannes Millan
b005b6cc65 security(plugin): implement enhanced plugin sandboxing
- Replace insecure Function constructor with multi-layered sandbox
- Add prototype pollution protection by freezing core prototypes
- Implement dangerous pattern detection for plugin code validation
- Add timeout protection for plugin execution (5 seconds)
- Enhance global variable shadowing with null assignments
- Add comprehensive security validation patterns
- Prevent constructor chain access and eval usage
- Isolate plugin execution context with Object.create(null)

This addresses critical security vulnerabilities where plugins could
escape the sandbox via constructor chains, prototype pollution, and
other JavaScript injection techniques.
2025-06-19 14:25:43 +02:00
Johannes Millan
05589b86c3 refactor(plugin): improve side panel plugin implementation
- Add comprehensive error handling and loading states to plugin-panel-container
- Show spinner while loading and error messages when plugin fails to load
- Add type safety improvements to plugin-iframe utilities
- Add security check to prevent calling private methods
- Add active state styling to side panel buttons
- Support toggle behavior - clicking active button closes the panel
- Add proper lifecycle management - close panel when plugin is unloaded/removed
- Add JSDoc documentation to all new components and utilities
- Auto-register side panel button for plugins with sidePanel flag
- Update test plugin to demonstrate auto-registration

The implementation now provides better user feedback, improved security,
and handles edge cases like plugin removal and errors gracefully.
2025-06-19 14:25:43 +02:00
Johannes Millan
4401e40058 feat(plugin): implement side panel functionality for plugins
- Add sidePanel flag to PluginManifest type
- Create PluginSidePanelBtnCfg interface for side panel buttons
- Implement plugin-side-panel-btns component for rendering buttons in main header
- Add plugin-panel-container component for rendering plugin iframes in right panel
- Update RightPanelComponent to support plugin panels
- Add activeSidePanelPlugin$ observable to PluginService
- Create reusable iframe utilities to avoid code duplication
- Update plugin API to support registerSidePanelButton method
- Skip menu entry registration for plugins with sidePanel flag
- Add test-side-panel-plugin to demonstrate functionality

When a plugin has 'sidePanel': true in its manifest, it will:
1. Not create a menu entry (unless explicitly registered)
2. Allow registration of side panel buttons via registerSidePanelButton
3. Load its iframe in the RightPanelComponent when activated
2025-06-19 14:25:43 +02:00
Johannes Millan
5b05192e2e refactor(plugin): improve type safety by removing 'as any' castings
- Create window-ea.d.ts to properly type window.ea (ElectronAPI)
- Replace all 'as any' castings with proper types
- Update all any[] to unknown[] for better type safety
- Import proper types (PluginManifest) in electron files
- Update plugin-api types to use unknown instead of any
- Fix app.getPath type casting with proper parameter types
- Rebuild plugin-api dist files with updated types
2025-06-19 14:25:43 +02:00
Johannes Millan
83ba3450fc feat(plugin): improve Node.js execution security and error handling
- Enhanced sandboxing with frozen prototypes and constructor removal
- Added comprehensive input validation for script requests
- Improved error handling with line/column information
- Added resource usage tracking (memory monitoring)
- Added cleanup method for plugin resources
- Better path traversal protection with ID sanitization
- Enhanced dangerous globals removal (fs, crypto, etc.)
- Added structured error types with error codes
- Built and updated plugin-api dist files
2025-06-19 14:25:43 +02:00
Johannes Millan
dfec172788 feat(plugin): add Node.js script execution API for plugins
- Implement secure Node.js script executor in Electron main process
- Add sandboxed execution environment with memory/timeout limits
- Create two-stage consent dialog for nodeExecution permission
- Add plugin registration/unregistration with main process
- Integrate executeNodeScript method into plugin API
- Add IPC handlers for plugin-to-main communication
- Ensure consent is checked when enabling plugins
- Add proper cleanup on plugin unload

Security features:
- Dangerous globals removed from execution context
- Plugin-specific working directories
- Configurable memory and timeout limits
- Persistent consent storage
- Only available in Electron environment
2025-06-19 14:25:43 +02:00
Johannes Millan
30d5604805 fix(plugin): resolve TypeScript compilation errors
Fixed compilation errors by restoring the proper plugin API interface
structure that maintains separation between app types and plugin types.

- Restored plugin-api.model.ts to re-export both package and app types
- Fixed import statements in plugin-bridge.service.ts
- Maintained backward compatibility with existing plugin code
- All TypeScript compilation errors resolved
2025-06-19 14:25:42 +02:00
Johannes Millan
f17cca22ca feat(plugin): update markdown converter to create proper subtasks
Modified the markdown-list-to-task plugin to create subtasks using
the parentId field instead of the subTasks array. This ensures
subtasks are properly linked to their parent tasks in the system.

- Changed task creation to first create parent task, then subtasks
- Use parentId field when creating subtasks
- Removed unused createTasksFromParsedData function
- Maintain support for deep nesting as notes
2025-06-19 14:25:42 +02:00
Johannes Millan
5a4f51b69b refactor(plugin): consolidate type definitions into plugin-api package
Moved all plugin-related type definitions from plugin-api.model.ts
to the @super-productivity/plugin-api package to eliminate duplication
and maintain a single source of truth for plugin types.

- Moved TaskCopy, ProjectCopy, TagCopy type aliases to plugin-api
- Moved PluginHeaderBtnCfg interface to plugin-api package
- Moved SnackCfgLimited type alias to plugin-api package
- Updated all imports to use types from the plugin-api package
- Simplified plugin-api.model.ts to just re-export from package
2025-06-19 14:25:42 +02:00
Johannes Millan
6f04b28684 fix(plugin): fix TypeScript imports for plugin-api types
- Changed from re-export to import-then-export pattern
- This ensures TypeScript can find the types when used within the same file
- Fixes 'Cannot find name' errors for plugin-api types
2025-06-19 14:25:42 +02:00
Johannes Millan
9fa0540296 fix(plugin-api): export PluginHooks as value not just type
- PluginHooks is an enum that needs to be used as a value in runtime code
- Changed from type-only export to regular export to fix TypeScript errors
- Keeps Hooks as type-only export since it's just a type alias
2025-06-19 14:25:42 +02:00
Johannes Millan
fb35183dec fix(plugin): fix enable/disable toggle only working once
- Change unloadPlugin to keep a disabled placeholder instead of removing the plugin entirely
- Update plugin state immediately when disabling to provide instant UI feedback
- This ensures plugins can be re-enabled after being disabled without issues
2025-06-19 14:25:42 +02:00
Johannes Millan
7493f35d03 fix(plugin): prevent default plugins from vanishing on reload
- Remove redundant logic that was preventing built-in plugins from being re-added to the loaded plugins list
- The _loadPlugin method already handles adding plugins to the list correctly
- This ensures built-in plugins remain visible after clicking the reload button
2025-06-19 14:25:42 +02:00
Johannes Millan
e8986208a3 refactor(plugin): export types from @super-productivity/plugin-api package
- Import shared types from the plugin-api package to avoid duplication
- Keep app-specific types (TaskCopy, ProjectCopy, etc.) that differ from plugin API
- Maintain custom PluginAPI interface that uses app-specific types
2025-06-19 14:25:42 +02:00
Johannes Millan
cd7c1e987e feat(plugin): add markdown plugin 2025-06-19 14:25:42 +02:00
Johannes Millan
8477724b97 feat(plugin): feat add current task change hook 2025-06-19 14:25:42 +02:00
Johannes Millan
1255301b0b feat(plugin): prepare api package 2025-06-19 14:25:42 +02:00
Johannes Millan
2fdd27e030 feat(plugin): make svg icons work for sidenav 2025-06-19 14:25:42 +02:00
Johannes Millan
917b214bbb feat(plugin): add SVG icon support for plugins and update menu entry rendering 2025-06-19 14:25:42 +02:00
Johannes Millan
87e20ec412 feat(plugin): implement dynamic plugin navigation and add animation transitions 2025-06-19 14:25:42 +02:00
Johannes Millan
8e8a7e9a2a feat(plugin): add super basic last tasks plugin 2025-06-19 14:25:39 +02:00
Johannes Millan
78a380ebb9 feat(plugin): add ID support for keyboard shortcuts and update execution logic 2025-06-19 14:25:24 +02:00
Johannes Millan
d96ee85df6 feat(plugin): simplify permission strings in manifest and security plugin 2025-06-19 14:25:24 +02:00
Johannes Millan
edc8e72b22 feat(plugin): update keyboard form with live plugin shortcuts and improve change detection 2025-06-19 14:25:24 +02:00
Johannes Millan
81a6ca0648 feat(plugin): add dynamic keyboard shortcuts for plugins and enhance configuration 2025-06-19 14:25:24 +02:00
Johannes Millan
1d59a5a911 refactor(plugin): rename CreateTaskData to PluginCreateTaskData for clarity 2025-06-19 14:25:24 +02:00
Johannes Millan
0fac82f349 feat(plugin): enhance security in plugin execution and clean up HTML 2025-06-19 14:25:24 +02:00
Johannes Millan
1d2fe60179 feat(plugin): various improvements and dialogs 2025-06-19 14:25:24 +02:00
Johannes Millan
ac803e3574 test(plugin): add integration tests 2025-06-19 14:25:24 +02:00
Johannes Millan
a50a51934d feat(plugin): move btns 2025-06-19 14:25:24 +02:00
Johannes Millan
d431ed9963 feat(plugin): enable auto-register menu entry 2025-06-19 14:25:24 +02:00
Johannes Millan
9360387e2b test(plugin): fix 2025-06-19 14:25:24 +02:00
Johannes Millan
c0900f19d8 feat(plugin): make loading index.html work 2025-06-19 14:25:24 +02:00
Johannes Millan
0b70368d7a feat(plugin): prepare loading index.html to iframe 2025-06-19 14:25:24 +02:00
Johannes Millan
52783c343a feat(plugin): add max sizes 2025-06-19 14:25:24 +02:00
Johannes Millan
0ba01ac30c feat(plugin): refactor plugin data management and introduce user and metadata persistence 2025-06-19 14:25:24 +02:00
Johannes Millan
acbf880772 feat(plugin): improve on plugin management 2025-06-19 14:25:24 +02:00
Johannes Millan
38ac35fefc feat(plugin): unregister plugins before deleting 2025-06-19 14:25:24 +02:00
Johannes Millan
82021795a1 refactor(plugin): rename getAllTasks to getTasks and implement archived tasks retrieval 2025-06-19 14:25:24 +02:00
Johannes Millan
e95f9ed4ea feat(plugin): add plugin description 2025-06-19 14:25:24 +02:00
Johannes Millan
e88fdfafa2 refactor(plugin): move plugin management 2025-06-19 14:25:24 +02:00
Johannes Millan
d5182607c9 feat(plugin): handle disabled plugins with placeholder instances 2025-06-19 14:25:23 +02:00
Johannes Millan
a26e840361 feat(plugin): cache plugins 2025-06-19 14:25:23 +02:00
Johannes Millan
e2d1b135d8 feat(plugin): add support for uploading and loading plugins from ZIP files 2025-06-19 14:25:23 +02:00
Johannes Millan
503af8d4fc feat(plugin): add Hello World button and menu entry with success message 2025-06-19 14:25:23 +02:00