Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/app/_components/DownloadedScriptsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ export function DownloadedScriptsTab({ onInstallScript }: DownloadedScriptsTabPr

// Update scripts with download status and filter to only downloaded scripts
const downloadedScripts = React.useMemo((): ScriptCardType[] => {
// Helper to normalize identifiers so underscores vs hyphens don't break matches
const normalizeId = (s?: string): string => (s ?? '')
.toLowerCase()
.replace(/\.(sh|bash|py|js|ts)$/g, '')
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '');

return combinedScripts
.map(script => {
if (!script?.name) {
Expand All @@ -178,9 +185,13 @@ export function DownloadedScriptsTab({ onInstallScript }: DownloadedScriptsTabPr
// Check if there's a corresponding local script
const hasLocalVersion = localScriptsData?.scripts?.some(local => {
if (!local?.name) return false;
const localName = local.name.replace(/\.sh$/, '');
return localName.toLowerCase() === script.name.toLowerCase() ||
localName.toLowerCase() === (script.slug ?? '').toLowerCase();
const normalizedLocal = normalizeId(local.name);
const matchesNameOrSlug = (
normalizedLocal === normalizeId(script.name) ||
normalizedLocal === normalizeId(script.slug)
);
const matchesInstallBasename = (script as any)?.install_basenames?.some((base: string) => normalizeId(base) === normalizedLocal) ?? false;
return matchesNameOrSlug || matchesInstallBasename;
}) ?? false;

return {
Expand Down
17 changes: 14 additions & 3 deletions src/app/_components/ScriptsGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,13 @@ export function ScriptsGrid({ onInstallScript }: ScriptsGridProps) {

// Update scripts with download status
const scriptsWithStatus = React.useMemo((): ScriptCardType[] => {
// Helper to normalize identifiers for robust matching
const normalizeId = (s?: string): string => (s ?? '')
.toLowerCase()
.replace(/\.(sh|bash|py|js|ts)$/g, '')
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '');

return combinedScripts.map(script => {
if (!script?.name) {
return script; // Return as-is if invalid
Expand All @@ -208,9 +215,13 @@ export function ScriptsGrid({ onInstallScript }: ScriptsGridProps) {
// Check if there's a corresponding local script
const hasLocalVersion = localScriptsData?.scripts?.some(local => {
if (!local?.name) return false;
const localName = local.name.replace(/\.sh$/, '');
return localName.toLowerCase() === script.name.toLowerCase() ||
localName.toLowerCase() === (script.slug ?? '').toLowerCase();
const normalizedLocal = normalizeId(local.name);
const matchesNameOrSlug = (
normalizedLocal === normalizeId(script.name) ||
normalizedLocal === normalizeId(script.slug)
);
const matchesInstallBasename = (script as any)?.install_basenames?.some((base: string) => normalizeId(base) === normalizedLocal) ?? false;
return matchesNameOrSlug || matchesInstallBasename;
}) ?? false;

return {
Expand Down
10 changes: 10 additions & 0 deletions src/server/api/routers/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ export const scriptsRouter = createTRPCRouter({
const firstInstallMethod = script?.install_methods?.[0];
const os = firstInstallMethod?.resources?.os;
const version = firstInstallMethod?.resources?.version;
// Extract install basenames for robust local matching (e.g., execute.sh -> execute)
const install_basenames = (script?.install_methods ?? [])
.map(m => m?.script)
.filter((p): p is string => typeof p === 'string')
.map(p => {
const parts = p.split('/');
const file = parts[parts.length - 1] ?? '';
return file.replace(/\.(sh|bash|py|js|ts)$/i, '');
});

return {
...card,
Expand All @@ -189,6 +198,7 @@ export const scriptsRouter = createTRPCRouter({
version: version,
// Add interface port
interface_port: script?.interface_port,
install_basenames,
} as ScriptCard;
});

Expand Down
2 changes: 2 additions & 0 deletions src/types/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export interface ScriptCard {
os?: string;
version?: string;
interface_port?: number | null;
// Optional: basenames of install scripts (without extension)
install_basenames?: string[];
}

export interface GitHubFile {
Expand Down