Skip to content

Conversation

@evereq
Copy link
Member

@evereq evereq commented Jan 8, 2026

PR

Please note: we will close your PR without comment if you do not check the boxes above and provide ALL requested information.



Summary by cubic

Adds arch-specific update channels, a new password hashing module (scrypt by default with bcrypt compatibility), and a redesigned plugin upload flow. Also introduces a theme-aware custom tray icon for Desktop Timer and hardens plugin archive extraction security.

  • New Features

    • Arch-specific publish channels and updater feeds for desktop builds (linux/win32).
    • Theme-aware custom tray icon in Desktop Timer with IPC hooks; configurable via GAUZY_DESKTOP_TRAY_ICON; icon generator supports tray assets.
    • Upload selection modal and revamped “Add Plugin” UI with improved i18n and accessibility.
    • PasswordHashModule with strategy-based hashing (scrypt default, bcrypt legacy); auth/services and seeding updated to use PasswordHashService.
  • Bug Fixes

    • Secure plugin zip extraction: prevent path traversal, use robust stream pipelines, and cleanup incomplete files on errors.
    • Resolve desktop plugin table conflict by renaming to desktop_plugins.
    • Desktop tray setup corrected to use proper icon handling and avoid duplicated listeners.

Written for commit 1c8c714. Summary will update on new commits.

syns2191 and others added 27 commits December 29, 2025 21:03
fix: table name plugins conflict in desktop with integrated and sqlit…
* feat: desktop timer enhance tray ui with custom icon

* fix: handle theme color change

* fix: handled possible duplicated listener

* fix: add event update-tray-icon in remove listener

* fix: remove log
Adds a new menu item for advanced settings to the settings component. This allows users to access advanced configuration options that were previously not directly available in the UI.
Fix(settings): Add advanced settings menu item
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
chore(deps): bump nx from 20.8.0 to 21.1.0
…ypto

Fix/8504 replace bcrypt with crypto
fix(core): export PasswordHashModule and PasswordHashService
* feat(plugins): implement upload selection modal and intent handling

Introduces a new upload selection modal that allows users to choose between installing a plugin locally or publishing it to the marketplace.
This change includes:
- A new `UploadSelectionComponent` with its associated HTML, SCSS, and TypeScript files.
- New actions (`PluginUploadIntentActions`) and effects (`PluginUploadIntentEffects`) to manage the upload intent flow.
- Updates to `PluginMarketplaceComponent` to trigger the upload selection.
- New Akita store (`PluginUploadIntentStore`) and query (`PluginUploadIntentQuery`) to manage the upload intent state.
- Internationalization updates for the new upload selection options.
This refactors the previous direct "Upload" action in the plugin marketplace to provide a more guided user experience. The "Add Plugin" button's functionality is now integrated within the "Install Locally" flow of the new upload selection modal.

* feat(plugins): redesign add plugin modal

Refactors the add plugin modal to improve user experience and UI clarity.
The changes include:
- A new card-based design for installation options (local, CDN, NPM) with clear descriptions and icons.
- Improved form structure for CDN and NPM installations, including better input fields and error handling.
- Enhanced accessibility features such as ARIA labels and focus management.
- A new signal-based approach for managing component state.
- Refined styling for better responsiveness and visual appeal.
- Added a subtitle to the plugin modal header.

* feat(plugins): enhance plugin list and marketplace detail components with improved state handling and accessibility features

* feat(plugins): adjust nb-toggle label margin for improved layout consistency

* fix(i18n): remove unused upload translation

The "UPLOAD" translation key was no longer being used in the UI. Removing it helps to keep the i18n files clean and maintainable.

* fix(desktop-ui-lib): enable keyboard navigation for upload selection

Add keyboard event listeners for 'enter' and 'space' keys to the upload selection cards. This allows users to select an installation option using their keyboard, improving accessibility and usability.

* feat(plugins): translate add plugin options and aria-labels

Translate the descriptive text and ARIA labels for the "Install from Computer", "Install from CDN", and "Install from NPM" options within the add plugin component.
This change ensures that these options are properly localized and accessible to users who rely on translated interfaces. The `en.json` file has been updated with new translation keys for these strings.

* fix(add-plugin): correct conditional rendering logic

Update the template to use `@else if` for conditional rendering of plugin installation forms. This ensures that only one form is displayed at a time based on the context (CDN or NPM), preventing potential rendering issues and improving user experience.

* fix(desktop-ui-lib): refactor plugin settings styles to use theme variables

This commit refactors the SCSS styles for the plugin settings component in the desktop UI library. Instead of using hardcoded color and shadow values, it now utilizes theme variables. This change improves consistency across the application and makes it easier to manage the visual theme.
The specific changes include:
- Replacing hardcoded rgba shadows with `var(--gauzy-shadow)`.
- Replacing hardcoded rgba borders with `var(--border-basic-color-3)`.
- Replacing hardcoded rgba background colors with theme-specific variables like `var(--background-basic-color-2)`, `var(--color-primary-100)`, `var(--color-success-100)`, and `var(--color-danger-100)`.
- Replacing hardcoded focus outlines with `var(--color-primary-focus)`.
- Replacing hardcoded color values for icons and text with theme variables.
- Replacing hardcoded input border colors on hover and focus with theme variables.
- Replacing hardcoded background for the plugin details section with `var(--gauzy-card-2)`.

* fix(add-plugin): initialize npmModel with default structure

The `npmModel` was not being initialized with its default structure when the `reset` method was called. This commit ensures that `npmModel` is properly reset to its expected shape, preventing potential issues with form handling or state management.

* refactor(plugin-list): improve readability of template variable declarations

Break down the long `@let` declaration into multiple lines for better readability.
Add comments to explain the purpose of each state variable.

* fix(plugin-list): use theme variable for hover shadow

Replaces the hardcoded box-shadow value with the `--gauzy-shadow` CSS variable for the plugin list item hover effect. This ensures consistency with the application's theme and allows for easier global shadow management.

* fix(desktop-ui-lib): improve danger button styling and use inject

This commit refactors the `.danger` CSS class to use CSS variables for more maintainable and themeable background colors. It also updates the `PluginUploadIntentEffects` to use the `inject` function for dependency injection, which is a more modern Angular practice.

* chore: remove unused animation keyframes

The `@keyframes pulse` was defined but not used anywhere in the
component's stylesheet. This commit removes the unused animation
definition to clean up the code and reduce file size.

* fix(plugin-upload-intent): handle empty or null intents correctly

The previous implementation incorrectly returned an empty array or a single action without proper handling of null or undefined upload intents. This change ensures that the observable correctly emits `EMPTY` when no valid intent is provided, and uses `of()` for dispatching single actions to avoid unexpected behavior.

* fix(plugin-upload-intent): allow null for intent

The `intent` property in `PluginUploadIntentQuery` and `IPluginUploadIntentState` was previously typed as `UploadIntent`, implying it must always have a value. However, the `setIntent` method in `PluginUploadIntentStore` was intended to allow clearing the intent by not explicitly setting it.
This change updates the type definitions to `UploadIntent | null` to accurately reflect the possibility of the intent being null, allowing the clearing of the upload intent state.

* fix(ui): add role button to upload selection cards

Adds the `role="button"` attribute to the `nb-card` elements within the upload selection component. This improves accessibility by clearly indicating that these cards are interactive elements that can be activated using a mouse or keyboard.

* fix(desktop-ui-lib): update aria-label for close button

The aria-label for the close button in the upload selection component was previously hardcoded. This commit updates it to use the translated string 'BUTTONS.CLOSE' for better internationalization.

* feat(plugins): internationalize plugin marketplace details

This commit introduces internationalization for various text elements within the plugin marketplace detail view.
Key changes include:
- Translating labels such as "by", "downloads", "Free", "No description available", "Subscription Required", "Installing...", "Uninstalling...", "Trial", "Updated", "License", "Released", and "more tags".
- Localizing the dynamic text for install/uninstall progress.
- Translating the labels for the install toggle button based on plugin status and plan.
- Internationalizing the action menu items for plugins, including "View Details", "Settings", "Manage Subscription", "Manage Users", "Homepage", "Repository", "Edit Plugin", and "Delete".
This enhancement improves the accessibility and usability of the plugin marketplace for a global audience.

* fix(plugins): update scss for gradient and button alignment

Refactors the linear gradient calculation in `add-plugin.component.scss` to use `color-mix` for better theme integration. Adjusts `plugin-list.component.scss` to change `justify-content` from `stretch` to `flex-start` for improved button alignment.

* refactor(plugin-list): extract smart table settings to a method

Extract the `smartTableSettings` object into a dedicated `buildSmartTableSettings` method. This improves code organization and makes it easier to reinitialize settings, especially when the language changes.
This change also moves the call to `loadPlugins()` to `ngAfterViewInit` to ensure that the table settings are fully initialized before attempting to load plugins. This addresses a potential race condition.

* fix(ui): adjust button sizes and styling in plugin components

Update the `size` attribute for close buttons in both the `add-plugin` and `upload-selection` components from `tiny` to `small`. This ensures a consistent and more appropriately sized close button across these plugin-related UI elements.
Additionally, the SCSS for the `.close-button` in `add-plugin.component.scss` has been updated to use `var(--border-radius)` for its `border-radius` property, aligning with global theming. Padding has also been added to `.close-button` in both components for better visual spacing.

* fix(desktop-ui-lib): use theme variable for card shadows

Refactors the shadow styles in the upload selection component to use the `--gauzy-shadow` theme variable. This ensures consistency in the application's visual styling and makes it easier to manage shadows across different components.
* fix: improve error logging format in plugin subscription plan service

* fix(plugin-system): enhance zip extraction security

This commit introduces several security enhancements to the zip extraction process within the CDN download strategy.
Previously, there was a potential for path traversal vulnerabilities if a malicious zip file contained entries with paths that attempted to escape the designated extraction directory.
The following changes were implemented:
- Added a check to ensure the resolved file path of an entry is strictly within the base extraction directory. If it escapes, the entry is logged and skipped.
- Explicitly ensured that the parent directory for each file being extracted exists before attempting to write the file. This prevents errors and potential issues with nested directories within zip archives.
- Refactored `isSafePath` to more robustly handle Windows path separators, disallow absolute paths and drive letters, and ensure the resolved target path starts with the resolved root directory, preventing traversal.

* fix(plugin-category): simplify slug generation logic

* fix(cspell): add new words to the spell checker dictionary

* fix(cdn-download): use replaceAll for entry path normalization
fix(plugin-category): refine slug generation regex for leading/trailing dashes

* fix(cspell): remove duplicated word "Zrdm" from the spell checker dictionary

* fix(cdn-download): improve file extraction handling and add error tracking

* fix(cdn-download): correct path normalization logic in isSafePath method

* fix: arbitrary file access during archive extraction ("Zip Slip")

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix(cdn-download): enhance security by rejecting Unix-style absolute paths and removing redundant path validation

* fix(cdn-download): update import for finished stream utility and remove redundant baseExtractPath variable

* fix(cdn-download): improve path normalization

The previous regex ` /\\/g ` for normalizing Windows path separators in `entryPath` was overly broad and could lead to incorrect path normalization in certain edge cases.
This change updates the `replaceAll` method to use a literal backslash character `'\'` instead of a regex, ensuring only backslashes are replaced with forward slashes. This provides more precise and reliable path normalization.

* refactor(cdn-download): simplify archive extraction logic

Refactors the `CdnDownloadStrategy` to use dedicated helper methods for directory creation and file extraction. This improves readability and maintainability of the archive processing logic.
The changes include:
- Extracting directory creation into `createDirectory`.
- Extracting file writing logic into `extractFile`.
- Renaming `filePath` to `entryPath` for clarity.
- Using `path.resolve` for safer path handling.
- Ensuring `entry.autodrain()` is called in error scenarios.

* fix(cdn-download): prevent path traversal in zip extraction

Add validation to the `extractEntry` function to prevent path traversal vulnerabilities during the extraction of zip archives. The target path is now resolved against the base directory of the extraction to ensure it remains within the intended scope.
This change enhances security by ensuring that malicious zip archives cannot write files outside of their designated extraction directory.
The `baseDir` option is now passed to `extractEntry` and used to construct a safe target path.

* fix(plugin-system): improve error handling and stream management in cdn download

This commit addresses several issues in the `CdnDownloadStrategy` related to error handling and stream management during plugin downloads.
Key changes:
- **Robust Error Logging:** Error messages for directory creation and file extraction now include the full error stack or message for better debugging. They also explicitly convert non-Error objects to strings.
- **Stream Pipeline for Extraction:** The `entry.pipe(writeStream)` and `finished(writeStream)` combination has been replaced with `pipeline(entry, writeStream)`. This provides more reliable error propagation and ensures streams are properly cleaned up.
- **Resource Cleanup on Error:** In the `extractFile` method, if an error occurs during file extraction, the `entry` and `writeStream` are explicitly destroyed to release resources.
- **Incomplete File Removal:** If an error occurs during file extraction, any partially created target file is now removed to prevent leaving incomplete artifacts. This handles potential `ENOENT` errors gracefully.
- **Throwing Errors:** Errors are now consistently re-thrown after cleanup, ensuring that the calling code is aware of and can handle extraction failures.

* fix(cdn-download): re-throw stream write errors

The previous implementation of `CdnDownloadStrategy` caught stream write errors and autodrained the entry. This masked the underlying error and prevented `Promise.all` from rejecting, leading to silent failures when downloading plugin files.
This change re-throws the caught error. This ensures that any failure during the file writing process is propagated up to `Promise.all`, allowing the overall download operation to fail gracefully and be reported to the user.

* fix: Rethrowing here propagates the error, but the unzipper entry stream is no longer drained/destroyed on failure. A write error can leave the entry unread and stall the unzip parse. Drain (or destroy) the entry before rethrowing.

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix(cdn-download): improve error handling and resource cleanup

Add robust error handling to the CDN download strategy. This includes:
- Logging detailed error messages, including stack traces when available.
- Destroying pipe streams to release resources on error.
- Attempting to remove incomplete files to prevent corrupted downloads.
- Handling potential errors during file removal (e.g., if the file doesn't exist).
- Ensuring the `entry` stream is also handled correctly on error.

* fix(cdn-download): ensure error is thrown in stream pipe

The previous implementation incorrectly called `entry.autodrain()` before re-throwing the error. This prevented the error from being propagated correctly, potentially leading to unhandled promise rejections.
This change ensures that the error is thrown immediately, allowing the calling code to catch and handle it as expected.

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.24.0 to 1.25.2.
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](modelcontextprotocol/typescript-sdk@1.24.0...v1.25.2)

---
updated-dependencies:
- dependency-name: "@modelcontextprotocol/sdk"
  dependency-version: 1.25.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
)

Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.24.0 to 1.25.2.
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](modelcontextprotocol/typescript-sdk@1.24.0...v1.25.2)

---
updated-dependencies:
- dependency-name: "@modelcontextprotocol/sdk"
  dependency-version: 1.25.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@cla-assistant
Copy link

cla-assistant bot commented Jan 8, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
5 out of 6 committers have signed the CLA.

✅ syns2191
✅ evereq
✅ samuelmbabhazi
✅ rahul-rocket
✅ adkif
❌ dependabot[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@cla-assistant
Copy link

cla-assistant bot commented Jan 8, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
5 out of 6 committers have signed the CLA.

✅ syns2191
✅ evereq
✅ samuelmbabhazi
✅ rahul-rocket
✅ adkif
❌ dependabot[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@evereq evereq merged commit 1305983 into stage Jan 8, 2026
24 of 27 checks passed
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

3 similar comments
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 8, 2026

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

6 issues found across 124 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-list/plugin-list.component.html">

<violation number="1" location="packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-list/plugin-list.component.html:42">
P1: The 'Add Plugin' button has been removed during the refactoring. The original code had this button visible at all times (outside the `selected` condition), allowing users to add new plugins. This appears to be a regression that breaks core functionality.</violation>
</file>

<file name="apps/desktop-timer/src/index.ts">

<violation number="1" location="apps/desktop-timer/src/index.ts:812">
P1: Accessing `appSetting.timerStarted` without null check will throw a TypeError if `appSetting` is null/undefined. The existing code pattern in `before-quit` handler (line 622) shows this value should be guarded with `appSetting && appSetting.timerStarted`. Use optional chaining here.</violation>
</file>

<file name="packages/core/src/lib/app/app.module.ts">

<violation number="1" location="packages/core/src/lib/app/app.module.ts:322">
P1: This change passes the `Cacheable` instance instead of the array of raw Keyv stores, but the comment above states "cache-manager currently uses the raw Keyv stores directly". If the cache-manager module expects Keyv stores and not a Cacheable wrapper, this could break caching functionality. Either update the comment to reflect the new approach if `Cacheable` is now supported, or revert to passing `[cacheable.primary, cacheable.secondary]`.</violation>
</file>

<file name="package.json">

<violation number="1" location="package.json:316">
P2: Inconsistent architecture specification: `build:desktop-timer:windows` now explicitly includes `--x64`, while similar base Windows build scripts for other apps (desktop, gauzy-server, agent, etc.) don't specify an architecture. If this is intentional, consider applying the same pattern to other Windows build scripts for consistency. If not, the `--x64` flag should be removed to match the other scripts.</violation>
</file>

<file name="packages/desktop-lib/src/lib/plugin-system/data-access/strategies/cdn-download.strategy.ts">

<violation number="1" location="packages/desktop-lib/src/lib/plugin-system/data-access/strategies/cdn-download.strategy.ts:344">
P1: Missing final path containment verification after resolution. The inline checks only validate the entry path patterns, but unlike `isSafePath` and `extractFile`, this code doesn't verify that `resolvedFullPath.startsWith(path.resolve(extractDir) + path.sep)`. Add a containment check before writing files to ensure the resolved path stays within the extraction directory.</violation>
</file>

<file name="packages/desktop-ui-lib/src/lib/settings/plugins/component/add-plugin/add-plugin.component.html">

<violation number="1" location="packages/desktop-ui-lib/src/lib/settings/plugins/component/add-plugin/add-plugin.component.html:36">
P2: Missing `$event.preventDefault()` on `keydown.space` handler. When Space is pressed on this custom button element, the page will scroll in addition to triggering the action. Add `$event.preventDefault()` before the action call to prevent unwanted scrolling.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

} @else if (isPluginAvailable) {
<!-- Action Buttons -->
@if (selected) {
<div class="button-container" aria-label="Plugin actions">
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 8, 2026

Choose a reason for hiding this comment

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

P1: The 'Add Plugin' button has been removed during the refactoring. The original code had this button visible at all times (outside the selected condition), allowing users to add new plugins. This appears to be a regression that breaks core functionality.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-list/plugin-list.component.html, line 42:

<comment>The 'Add Plugin' button has been removed during the refactoring. The original code had this button visible at all times (outside the `selected` condition), allowing users to add new plugins. This appears to be a regression that breaks core functionality.</comment>

<file context>
@@ -1,86 +1,119 @@
+	} @else if (isPluginAvailable) {
+	<!-- Action Buttons -->
+	@if (selected) {
+	<div class="button-container" aria-label="Plugin actions">
+		<div class="button-hide">
+			@if (selected.renderer) {
</file context>
Fix with Cubic

const appSetting = LocalStore.getStore('appSetting');
timeTrackerWindow?.webContents?.send?.('custom_tray_icon', {
event: 'updateTheme',
isStopped: !appSetting.timerStarted
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 8, 2026

Choose a reason for hiding this comment

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

P1: Accessing appSetting.timerStarted without null check will throw a TypeError if appSetting is null/undefined. The existing code pattern in before-quit handler (line 622) shows this value should be guarded with appSetting && appSetting.timerStarted. Use optional chaining here.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop-timer/src/index.ts, line 812:

<comment>Accessing `appSetting.timerStarted` without null check will throw a TypeError if `appSetting` is null/undefined. The existing code pattern in `before-quit` handler (line 622) shows this value should be guarded with `appSetting && appSetting.timerStarted`. Use optional chaining here.</comment>

<file context>
@@ -798,3 +798,17 @@ app.on('browser-window-created', (_, window) => {
+	const appSetting = LocalStore.getStore('appSetting');
+	timeTrackerWindow?.webContents?.send?.('custom_tray_icon', {
+		event: 'updateTheme',
+		isStopped: !appSetting.timerStarted
+	});
+});
</file context>
Suggested change
isStopped: !appSetting.timerStarted
isStopped: !appSetting?.timerStarted
Fix with Cubic


return {
stores: [cacheable.primary, cacheable.secondary]
stores: cacheable
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 8, 2026

Choose a reason for hiding this comment

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

P1: This change passes the Cacheable instance instead of the array of raw Keyv stores, but the comment above states "cache-manager currently uses the raw Keyv stores directly". If the cache-manager module expects Keyv stores and not a Cacheable wrapper, this could break caching functionality. Either update the comment to reflect the new approach if Cacheable is now supported, or revert to passing [cacheable.primary, cacheable.secondary].

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/lib/app/app.module.ts, line 322:

<comment>This change passes the `Cacheable` instance instead of the array of raw Keyv stores, but the comment above states "cache-manager currently uses the raw Keyv stores directly". If the cache-manager module expects Keyv stores and not a Cacheable wrapper, this could break caching functionality. Either update the comment to reflect the new approach if `Cacheable` is now supported, or revert to passing `[cacheable.primary, cacheable.secondary]`.</comment>

<file context>
@@ -318,7 +319,7 @@ if (environment.THROTTLE_ENABLED) {
 
 								return {
-									stores: [cacheable.primary, cacheable.secondary]
+									stores: cacheable
 								};
 							} catch (error) {
</file context>
Suggested change
stores: cacheable
stores: [cacheable.primary, cacheable.secondary]
Fix with Cubic

const fullPath = path.join(extractDir, entryPath);
// Build the full output path from the normalized entry path
const fullPath = path.join(extractDir, normalizedEntryPath);
const resolvedFullPath = path.resolve(fullPath);
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 8, 2026

Choose a reason for hiding this comment

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

P1: Missing final path containment verification after resolution. The inline checks only validate the entry path patterns, but unlike isSafePath and extractFile, this code doesn't verify that resolvedFullPath.startsWith(path.resolve(extractDir) + path.sep). Add a containment check before writing files to ensure the resolved path stays within the extraction directory.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/desktop-lib/src/lib/plugin-system/data-access/strategies/cdn-download.strategy.ts, line 344:

<comment>Missing final path containment verification after resolution. The inline checks only validate the entry path patterns, but unlike `isSafePath` and `extractFile`, this code doesn't verify that `resolvedFullPath.startsWith(path.resolve(extractDir) + path.sep)`. Add a containment check before writing files to ensure the resolved path stays within the extraction directory.</comment>

<file context>
@@ -326,16 +339,69 @@ export class CdnDownloadStrategy implements IPluginDownloadStrategy {
-						const fullPath = path.join(extractDir, entryPath);
+						// Build the full output path from the normalized entry path
+						const fullPath = path.join(extractDir, normalizedEntryPath);
+						const resolvedFullPath = path.resolve(fullPath);
 
 						if (type === 'Directory') {
</file context>
Suggested change
const resolvedFullPath = path.resolve(fullPath);
const resolvedFullPath = path.resolve(fullPath);
// Final containment check: ensure resolved path stays within extraction directory
const resolvedExtractDir = path.resolve(extractDir);
if (!resolvedFullPath.startsWith(resolvedExtractDir + path.sep)) {
logger.warn(`Path escapes extraction directory, skipping: ${entryPath}`);
entry.autodrain();
return;
}
Fix with Cubic

"build:desktop-timer:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/desktop-timer",
"build:desktop-timer:linux:release:gh:x64": "yarn run pack --desktop=desktop-timer --arch=x64 --platform=linux && cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --linux --x64 --publish=always --project dist/apps/desktop-timer",
"build:desktop-timer:linux:release:gh:arm64": "yarn run pack --desktop=desktop-timer --arch=arm64 --platform=linux && cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --linux --arm64 --publish=always --project dist/apps/desktop-timer",
"build:desktop-timer:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 -c.extraMetadata.author.name=Ever build --windows --x64 --project dist/apps/desktop-timer",
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 8, 2026

Choose a reason for hiding this comment

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

P2: Inconsistent architecture specification: build:desktop-timer:windows now explicitly includes --x64, while similar base Windows build scripts for other apps (desktop, gauzy-server, agent, etc.) don't specify an architecture. If this is intentional, consider applying the same pattern to other Windows build scripts for consistency. If not, the --x64 flag should be removed to match the other scripts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 316:

<comment>Inconsistent architecture specification: `build:desktop-timer:windows` now explicitly includes `--x64`, while similar base Windows build scripts for other apps (desktop, gauzy-server, agent, etc.) don't specify an architecture. If this is intentional, consider applying the same pattern to other Windows build scripts for consistency. If not, the `--x64` flag should be removed to match the other scripts.</comment>

<file context>
@@ -311,13 +311,13 @@
-		"build:desktop-timer:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/desktop-timer",
+		"build:desktop-timer:linux:release:gh:x64": "yarn run pack --desktop=desktop-timer --arch=x64 --platform=linux && cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --linux --x64 --publish=always --project dist/apps/desktop-timer",
+		"build:desktop-timer:linux:release:gh:arm64": "yarn run pack --desktop=desktop-timer --arch=arm64 --platform=linux && cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 build --linux --arm64 --publish=always --project dist/apps/desktop-timer",
+		"build:desktop-timer:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 -c.extraMetadata.author.name=Ever build --windows --x64 --project dist/apps/desktop-timer",
 		"build:desktop-timer:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=12288 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer",
 		"build:desktop-timer:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=38.2.2 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer",
</file context>
Fix with Cubic

[class.disabled]="installing"
(click)="!installing && localPluginInstall()"
(keydown.enter)="!installing && localPluginInstall()"
(keydown.space)="!installing && localPluginInstall()"
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 8, 2026

Choose a reason for hiding this comment

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

P2: Missing $event.preventDefault() on keydown.space handler. When Space is pressed on this custom button element, the page will scroll in addition to triggering the action. Add $event.preventDefault() before the action call to prevent unwanted scrolling.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/desktop-ui-lib/src/lib/settings/plugins/component/add-plugin/add-plugin.component.html, line 36:

<comment>Missing `$event.preventDefault()` on `keydown.space` handler. When Space is pressed on this custom button element, the page will scroll in addition to triggering the action. Add `$event.preventDefault()` before the action call to prevent unwanted scrolling.</comment>

<file context>
@@ -1,176 +1,273 @@
+					[class.disabled]="installing"
+					(click)="!installing && localPluginInstall()"
+					(keydown.enter)="!installing && localPluginInstall()"
+					(keydown.space)="!installing && localPluginInstall()"
+					[tabindex]="installing ? -1 : 0"
+					[attr.aria-label]="'BUTTONS.LOAD_PLUGIN' | translate"
</file context>
Suggested change
(keydown.space)="!installing && localPluginInstall()"
(keydown.space)="$event.preventDefault(); !installing && localPluginInstall()"
Fix with Cubic

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

11 similar comments
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 8, 2026

Too many files changed for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants