diff --git a/src/renderer/index.html b/src/renderer/index.html
index 885f4065..da009c30 100644
--- a/src/renderer/index.html
+++ b/src/renderer/index.html
@@ -62,7 +62,16 @@
-
+
@@ -91,6 +100,13 @@
+
+
+
+
@@ -185,7 +210,16 @@
-
+
@@ -723,7 +757,7 @@
Tool Settings
-
+
diff --git a/src/renderer/modules/toolsSidebarManagement.ts b/src/renderer/modules/toolsSidebarManagement.ts
index 0f4e347a..b9b003a5 100644
--- a/src/renderer/modules/toolsSidebarManagement.ts
+++ b/src/renderer/modules/toolsSidebarManagement.ts
@@ -14,6 +14,8 @@ import { launchTool } from "./toolManagement";
let activeToolContextMenu: { menu: HTMLElement; anchor: HTMLElement; cleanup: () => void } | null = null;
+type CheckboxElement = HTMLInputElement & { _pptbBound?: boolean };
+
/**
* Load and display installed tools in the sidebar
*/
@@ -62,13 +64,15 @@ export async function loadSidebarTools(): Promise
{
const categoryFilter = document.getElementById("tools-category-filter") as HTMLSelectElement | null;
const authorFilter = document.getElementById("tools-author-filter") as HTMLSelectElement | null;
const sortSelect = document.getElementById("tools-sort-select") as HTMLSelectElement | null;
+ const updateRequiredFilter = document.getElementById("tools-update-required-filter") as CheckboxElement | null;
const searchTerm = searchInput?.value ? searchInput.value.toLowerCase() : "";
const selectedCategory = categoryFilter?.value || "";
const selectedAuthor = authorFilter?.value || "";
+ const showUpdateRequiredOnly = !!updateRequiredFilter?.checked;
// Update filter button indicator and one-click clear button visibility
- const hasDropdownFilters = !!(selectedCategory || selectedAuthor);
+ const hasDropdownFilters = !!(selectedCategory || selectedAuthor || showUpdateRequiredOnly);
const toolsFilterBtn = document.getElementById("tools-filter-btn");
if (toolsFilterBtn) {
toolsFilterBtn.classList.toggle("has-active-filters", hasDropdownFilters);
@@ -112,6 +116,11 @@ export async function loadSidebarTools(): Promise {
return false;
}
+ // Update required filter
+ if (showUpdateRequiredOnly && !t.hasUpdate) {
+ return false;
+ }
+
// Deprecated filter
if (t.status === "deprecated") {
if (deprecatedToolsVisibility === "hide-all" || deprecatedToolsVisibility === "show-marketplace") {
@@ -151,7 +160,7 @@ export async function loadSidebarTools(): Promise {
// Empty state when no matches after filtering
if (sortedTools.length === 0) {
const hasSearchTerm = searchTerm.length > 0;
- const hasActiveFilters = hasSearchTerm || selectedCategory || selectedAuthor;
+ const hasActiveFilters = hasSearchTerm || selectedCategory || selectedAuthor || showUpdateRequiredOnly;
const emptyMessage = hasSearchTerm ? `No installed tools match "${searchTerm}".` : hasActiveFilters ? "No tools match the current filters." : "Try a different search term.";
toolsList.innerHTML = `
@@ -268,7 +277,7 @@ export async function loadSidebarTools(): Promise
{
${toolIconHtml}
@@ -281,9 +290,12 @@ export async function loadSidebarTools(): Promise {
`
: ""
}
-
+
${authorsDisplay}
@@ -299,7 +311,7 @@ export async function loadSidebarTools(): Promise
{
${toolIconHtml}
@@ -312,9 +324,12 @@ export async function loadSidebarTools(): Promise {
`
: ""
}
-
+
${description}
@@ -408,6 +423,7 @@ export async function loadSidebarTools(): Promise {
const searchInput = document.getElementById("tools-search-input") as HTMLInputElement | null;
const categoryFilter = document.getElementById("tools-category-filter") as HTMLSelectElement | null;
const authorFilter = document.getElementById("tools-author-filter") as HTMLSelectElement | null;
+ const updateRequiredFilter = document.getElementById("tools-update-required-filter") as CheckboxElement | null;
if (searchInput && !(searchInput as any)._pptbBound) {
(searchInput as any)._pptbBound = true;
@@ -431,6 +447,13 @@ export async function loadSidebarTools(): Promise {
});
}
+ if (updateRequiredFilter && !updateRequiredFilter._pptbBound) {
+ updateRequiredFilter._pptbBound = true;
+ updateRequiredFilter.addEventListener("change", () => {
+ loadSidebarTools();
+ });
+ }
+
// Setup sort event listener
const sortSelect = document.getElementById("tools-sort-select") as HTMLSelectElement | null;
if (sortSelect && !(sortSelect as any)._pptbBound) {
@@ -724,12 +747,17 @@ function clearAllFilters(): void {
authorFilter.value = "";
}
+ const updateRequiredFilter = document.getElementById("tools-update-required-filter") as CheckboxElement | null;
+ if (updateRequiredFilter) {
+ updateRequiredFilter.checked = false;
+ }
+
// Reload the sidebar tools to reflect the cleared filters
loadSidebarTools();
}
/**
- * Clear only the dropdown filter selections (category, author) for installed tools.
+ * Clear only the dropdown filter selections (category, author) and the "Update Available" checkbox for installed tools.
* Leaves the search input unchanged.
*/
export function clearInstalledToolsDropdownFilters(): void {
@@ -745,6 +773,11 @@ export function clearInstalledToolsDropdownFilters(): void {
authorFilter.value = "";
}
+ const updateRequiredFilter = document.getElementById("tools-update-required-filter") as CheckboxElement | null;
+ if (updateRequiredFilter) {
+ updateRequiredFilter.checked = false;
+ }
+
// Reload the sidebar tools to reflect the cleared filters
loadSidebarTools();
}
diff --git a/src/renderer/styles.scss b/src/renderer/styles.scss
index 97041f7b..f3ead13f 100644
--- a/src/renderer/styles.scss
+++ b/src/renderer/styles.scss
@@ -469,7 +469,9 @@ body {
border-radius: 10px;
padding: 16px 18px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
+ transition:
+ border-color 0.2s ease,
+ box-shadow 0.2s ease;
}
.settings-section-card:hover {
@@ -1645,7 +1647,9 @@ body.dark-theme .settings-section-card {
cursor: pointer;
color: var(--text-color);
opacity: 0.7;
- transition: opacity 0.2s, background-color 0.2s;
+ transition:
+ opacity 0.2s,
+ background-color 0.2s;
z-index: 10;
flex-shrink: 0;
}
@@ -1785,7 +1789,9 @@ body.dark-theme .settings-section-card {
line-height: 1;
border-radius: 3px;
opacity: 0;
- transition: opacity 0.2s, background-color 0.2s;
+ transition:
+ opacity 0.2s,
+ background-color 0.2s;
}
.tool-tab:hover .tool-tab-close {
@@ -1807,7 +1813,9 @@ body.dark-theme .settings-section-card {
line-height: 1;
border-radius: 3px;
opacity: 0;
- transition: opacity 0.2s, background-color 0.2s;
+ transition:
+ opacity 0.2s,
+ background-color 0.2s;
display: flex;
align-items: center;
justify-content: center;
@@ -2033,7 +2041,9 @@ body.dark-theme .settings-section-card {
text-decoration: none;
cursor: pointer;
border-left: 3px solid transparent;
- transition: background 0.15s, color 0.15s;
+ transition:
+ background 0.15s,
+ color 0.15s;
}
.settings-nav-link:hover {
@@ -2462,7 +2472,10 @@ body.dark-theme .settings-vscode-item:hover {
opacity: 0;
pointer-events: none;
visibility: hidden;
- transition: opacity 0.2s ease, background-color 0.2s ease, color 0.2s ease;
+ transition:
+ opacity 0.2s ease,
+ background-color 0.2s ease,
+ color 0.2s ease;
}
.sidebar-search-input-wrapper:has(.search-input:not(:placeholder-shown)) .search-clear-btn {
@@ -2489,7 +2502,6 @@ body.dark-theme .settings-vscode-item:hover {
flex-shrink: 0;
}
-
.search-filter-btn {
padding: 6px 8px;
background: none;
@@ -2570,6 +2582,25 @@ body.dark-theme .search-filter-btn.active img {
padding: 8px 12px;
}
+.filter-checkbox-label {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ cursor: pointer;
+ font-size: 13px;
+ color: var(--text-color);
+ user-select: none;
+}
+
+.filter-checkbox-input {
+ width: 16px;
+ height: 16px;
+ margin: 0;
+ cursor: pointer;
+ accent-color: var(--accent-color, #6a00ff);
+ flex-shrink: 0;
+}
+
.filter-section-title {
font-size: 11px;
font-weight: 600;
@@ -2695,7 +2726,10 @@ body.dark-theme .search-filter-btn.active img {
background: var(--card-background);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
cursor: pointer;
- transition: background-color 0.2s, box-shadow 0.2s, border-color 0.2s;
+ transition:
+ background-color 0.2s,
+ box-shadow 0.2s,
+ border-color 0.2s;
}
.tool-item-pptb-local {
@@ -2728,10 +2762,23 @@ body.dark-theme .search-filter-btn.active img {
.tool-item-header-right-pptb {
display: flex;
- align-items: center;
+ align-items: flex-start;
gap: 8px;
}
+.tool-item-menu-stack-pptb {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+}
+
+.tool-favorite-icon {
+ display: block;
+ align-self: flex-start;
+ margin-top: 0;
+}
+
.tool-item-icon-pptb {
font-size: 16px;
width: 30px;
@@ -2784,7 +2831,9 @@ img.tool-item-icon-img {
border: none;
cursor: pointer;
padding: 2px 4px;
- transition: transform 0.2s, opacity 0.2s;
+ transition:
+ transform 0.2s,
+ opacity 0.2s;
display: flex;
align-items: center;
justify-content: center;
@@ -2877,10 +2926,10 @@ img.tool-item-icon-img {
}
.tool-update-badge {
- display: inline-block;
+ display: block;
font-size: 12px;
- color: #0078d4;
- margin-left: 6px;
+ line-height: 1;
+ color: var(--accent-color, #6a00ff);
animation: pulse 2s infinite;
}
@@ -3037,7 +3086,10 @@ img.tool-item-icon-img {
border-radius: 8px;
background: var(--card-background);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
- transition: background-color 0.2s, box-shadow 0.2s, border-color 0.2s;
+ transition:
+ background-color 0.2s,
+ box-shadow 0.2s,
+ border-color 0.2s;
}
.marketplace-item-pptb:hover {
@@ -3107,7 +3159,11 @@ img.tool-item-icon-img {
color: var(--text-color);
padding: 0;
cursor: pointer;
- transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
+ transition:
+ background-color 0.2s ease,
+ border-color 0.2s ease,
+ color 0.2s ease,
+ transform 0.2s ease;
}
body.dark-theme .install-button {
@@ -3242,7 +3298,10 @@ body.light-theme .install-button:focus-visible img {
border-radius: 8px;
background: var(--card-background);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
- transition: background-color 0.2s, box-shadow 0.2s, border-color 0.2s;
+ transition:
+ background-color 0.2s,
+ box-shadow 0.2s,
+ border-color 0.2s;
margin-bottom: 10px;
}
@@ -3911,8 +3970,8 @@ body.dark-theme .home-container::-webkit-scrollbar-thumb:hover {
content: "";
position: absolute;
inset: 0;
- background: radial-gradient(circle at 10% 10%, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0) 60%),
- radial-gradient(circle at 90% 90%, rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0) 70%);
+ background:
+ radial-gradient(circle at 10% 10%, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0) 60%), radial-gradient(circle at 90% 90%, rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0) 70%);
pointer-events: none;
}
body.dark-theme #tool-detail-modal .modal-content.tool-detail-modern {
@@ -4735,7 +4794,9 @@ fluent-badge {
border-radius: 3px;
font-size: 13px;
cursor: pointer;
- transition: background-color 0.2s, color 0.2s;
+ transition:
+ background-color 0.2s,
+ color 0.2s;
white-space: nowrap;
}
@@ -5102,7 +5163,9 @@ body.dark-theme .csp-warning ul {
align-items: flex-start;
gap: 12px;
animation: slideInRight 0.3s ease-out;
- transition: opacity 0.2s ease-out, transform 0.2s ease-out;
+ transition:
+ opacity 0.2s ease-out,
+ transform 0.2s ease-out;
max-width: 100%;
}
@@ -5707,7 +5770,6 @@ body.dark-theme .global-search-item-badge.badge-settings {
}
}
-
/* Export button on category group header */
.connection-group-export-btn {
background: none;