diff --git a/package-manager-template/README.md b/package-manager-template/README.md index 8ee7d217c7..314b4e5430 100644 --- a/package-manager-template/README.md +++ b/package-manager-template/README.md @@ -52,6 +52,7 @@ author: "Author Name" version: "1.0.0" lastUpdated: "2025-04-08" tags: ["tag1", "tag2"] +sourceUrl: "https://github.com/username/repo" # Optional URL for the "view source" button ``` ## Testing diff --git a/package-manager-template/mcp-servers/file-analyzer/metadata.yml b/package-manager-template/mcp-servers/file-analyzer/metadata.yml index fb841de24a..a0af98a760 100644 --- a/package-manager-template/mcp-servers/file-analyzer/metadata.yml +++ b/package-manager-template/mcp-servers/file-analyzer/metadata.yml @@ -4,4 +4,5 @@ type: "mcp-server" author: "Roo Team" version: "1.0.0" lastUpdated: "2025-04-08" -tags: ["file-analyzer", "code-quality", "security", "performance"] \ No newline at end of file +tags: ["file-analyzer", "code-quality", "security", "performance"] +sourceUrl: "https://github.com/roo-team/file-analyzer-server" \ No newline at end of file diff --git a/package-manager-template/roles/developer-role/metadata.yml b/package-manager-template/roles/developer-role/metadata.yml index 4f79230eae..c9c0627502 100644 --- a/package-manager-template/roles/developer-role/metadata.yml +++ b/package-manager-template/roles/developer-role/metadata.yml @@ -4,4 +4,5 @@ type: "role" author: "Roo Team" version: "1.0.0" lastUpdated: "2025-04-08" -tags: ["developer", "full-stack", "web", "database", "api"] \ No newline at end of file +tags: ["developer", "full-stack", "web", "database", "api"] +sourceUrl: "https://github.com/roo-team/developer-resources" \ No newline at end of file diff --git a/package-manager-template/storage-systems/github-storage/metadata.yml b/package-manager-template/storage-systems/github-storage/metadata.yml index 404e7052b4..b943653865 100644 --- a/package-manager-template/storage-systems/github-storage/metadata.yml +++ b/package-manager-template/storage-systems/github-storage/metadata.yml @@ -4,4 +4,5 @@ type: "storage" author: "Roo Team" version: "1.0.0" lastUpdated: "2025-04-08" -tags: ["storage", "github", "git", "repository"] \ No newline at end of file +tags: ["storage", "github", "git", "repository"] +sourceUrl: "https://github.com/roo-team/github-storage-system" \ No newline at end of file diff --git a/src/services/package-manager/GitFetcher.ts b/src/services/package-manager/GitFetcher.ts index 7430f71a5a..a694c1de32 100644 --- a/src/services/package-manager/GitFetcher.ts +++ b/src/services/package-manager/GitFetcher.ts @@ -276,6 +276,7 @@ export class GitFetcher { const type = metadataContent.match(/type:\s*["']?([^"'\n]+)["']?/)?.[1] || dirType.type; const author = metadataContent.match(/author:\s*["']?([^"'\n]+)["']?/)?.[1]; const version = metadataContent.match(/version:\s*["']?([^"'\n]+)["']?/)?.[1]; + const sourceUrl = metadataContent.match(/sourceUrl:\s*["']?([^"'\n]+)["']?/)?.[1]; // Parse tags if present const tagsMatch = metadataContent.match(/tags:\s*\[(.*?)\]/); @@ -291,7 +292,8 @@ export class GitFetcher { repoUrl, author, tags, - version + version, + sourceUrl }; items.push(item); diff --git a/src/services/package-manager/types.ts b/src/services/package-manager/types.ts index c9280f28c0..e0bfa6cb14 100644 --- a/src/services/package-manager/types.ts +++ b/src/services/package-manager/types.ts @@ -13,6 +13,7 @@ export interface PackageManagerItem { lastUpdated?: string; stars?: number; downloads?: number; + sourceUrl?: string; // Optional URL to use for the "view source" button } /** diff --git a/webview-ui/src/components/package-manager/PackageManagerView.tsx b/webview-ui/src/components/package-manager/PackageManagerView.tsx index 7e873bfc1f..0dafd5f2f4 100644 --- a/webview-ui/src/components/package-manager/PackageManagerView.tsx +++ b/webview-ui/src/components/package-manager/PackageManagerView.tsx @@ -38,9 +38,13 @@ const PackageManagerView = ({ onDone }: PackageManagerViewProps) => { // Track if we're currently fetching items to prevent duplicate requests const [isFetching, setIsFetching] = useState(false); + // Track if the fetch was manually triggered by a refresh button + const isManualRefresh = useRef(false); // Use a ref to track if we've already fetched items const hasInitialFetch = useRef(false); + // Track the last sources we fetched to avoid duplicate fetches + const lastSourcesKey = useRef(null); // Fetch function without debounce for immediate execution const fetchPackageManagerItems = useCallback(() => { @@ -88,10 +92,19 @@ const PackageManagerView = ({ onDone }: PackageManagerViewProps) => { itemsLength: items.length }); - // Only fetch if packageManagerSources changes and we're not already fetching - if (packageManagerSources && hasInitialFetch.current && !isFetching) { - console.log("DEBUG: Calling fetchPackageManagerItems due to sources change"); - fetchPackageManagerItems(); + // Only fetch if packageManagerSources changes, we're not already fetching, and this isn't the initial render + if (packageManagerSources && hasInitialFetch.current && !isFetching && packageManagerSources.length > 0) { + // Generate a key based on the current sources + const sourcesKey = JSON.stringify(packageManagerSources.map(s => s.url)); + + // Only fetch if the sources have changed and it's not a manual refresh + if (sourcesKey !== lastSourcesKey.current && !isManualRefresh.current) { + console.log("DEBUG: Calling fetchPackageManagerItems due to sources change"); + lastSourcesKey.current = sourcesKey; + fetchPackageManagerItems(); + } else { + console.log("DEBUG: Skipping fetch because sources haven't changed or manual refresh is in progress"); + } } }, [packageManagerSources, fetchPackageManagerItems, isFetching]); @@ -147,12 +160,23 @@ const PackageManagerView = ({ onDone }: PackageManagerViewProps) => { // Force a new array reference to ensure React detects the change setItems([...receivedItems]); - setIsFetching(false); - console.log("DEBUG: States updated - items:", receivedItems.length, "isFetching: false"); + + // Update the fetching state in a separate call to avoid triggering another fetch + setTimeout(() => { + setIsFetching(false); + isManualRefresh.current = false; // Reset the manual refresh flag + console.log("DEBUG: States updated - items:", receivedItems.length, "isFetching: false, isManualRefresh: false"); + }, 0); } else { console.log("DEBUG: Received empty items array"); setItems([]); - setIsFetching(false); + + // Update the fetching state in a separate call to avoid triggering another fetch + setTimeout(() => { + setIsFetching(false); + isManualRefresh.current = false; // Reset the manual refresh flag + console.log("DEBUG: States updated - items: 0, isFetching: false, isManualRefresh: false"); + }, 0); } } } @@ -317,6 +341,7 @@ const PackageManagerView = ({ onDone }: PackageManagerViewProps) => {

No package manager items found