diff --git a/src/components/SkillFilesPanel.tsx b/src/components/SkillFilesPanel.tsx index 06a9553c..5b37095d 100644 --- a/src/components/SkillFilesPanel.tsx +++ b/src/components/SkillFilesPanel.tsx @@ -280,7 +280,9 @@ export function SkillFilesPanel({ versionId, latestFiles }: SkillFilesPanelProps ) : null} -
+
{isViewerLoading ? ( ) : fileError ? ( diff --git a/src/components/SkillHeader.tsx b/src/components/SkillHeader.tsx index 8c08e6a1..a71af49d 100644 --- a/src/components/SkillHeader.tsx +++ b/src/components/SkillHeader.tsx @@ -7,7 +7,12 @@ import type { Doc, Id } from "../../convex/_generated/dataModel"; import type { ActivityTrend } from "../lib/activityTrend"; import { getSkillBadges, isSkillOfficial } from "../lib/badges"; import { BrowseCategoryIcon } from "../lib/browseCategoryIcons"; -import { buildSkillCategoryBrowseHref, buildSkillTopicBrowseHref, formatCatalogTopicLabel, type SkillCategory } from "../lib/categories"; +import { + buildSkillCategoryBrowseHref, + buildSkillTopicBrowseHref, + formatCatalogTopicLabel, + type SkillCategory, +} from "../lib/categories"; import { formatSkillStatsTriplet } from "../lib/numberFormat"; import { buildPublisherProfileHref } from "../lib/ownerRoute"; import type { PublicPublisher, PublicSkill } from "../lib/publicUser"; @@ -15,10 +20,10 @@ import { timeAgo } from "../lib/timeAgo"; import { useHeroCreatorPublisher } from "../lib/useHeroCreatorPublisher"; import { useMediaQuery } from "../lib/useMediaQuery"; import { ActivityMetricLabel } from "./ActivityMetricLabel"; -import { InlineCodeSummary } from "./InlineCodeSummary"; import { DetailHero, DETAIL_HERO_TOPIC_LIMIT } from "./DetailPageShell"; import { DetailSecuritySummaryLabel } from "./DetailSecuritySummary"; import { useDownloadsSidebarMetricBlock } from "./DownloadsMetricCard"; +import { InlineCodeSummary } from "./InlineCodeSummary"; import { SidebarMetadata } from "./SidebarMetadata"; import { buildSkillHref } from "./skillDetailUtils"; import { SkillCommandLineCard } from "./SkillInstallSurface"; diff --git a/src/lib/browseTopicSearch.test.ts b/src/lib/browseTopicSearch.test.ts index 27d45776..8e598da0 100644 --- a/src/lib/browseTopicSearch.test.ts +++ b/src/lib/browseTopicSearch.test.ts @@ -21,7 +21,9 @@ describe("browseTopicSearch", () => { }); it("removes malformed topic keys when sanitizing search state", () => { - expect(sanitizeBrowseTopicSearch({ "topic=github": "", category: "development" }, "github")).toEqual({ + expect( + sanitizeBrowseTopicSearch({ "topic=github": "", category: "development" }, "github"), + ).toEqual({ category: "development", topic: "github", }); diff --git a/src/lib/browseTopicSearch.ts b/src/lib/browseTopicSearch.ts index 7722f0b0..f61f6dcb 100644 --- a/src/lib/browseTopicSearch.ts +++ b/src/lib/browseTopicSearch.ts @@ -55,10 +55,7 @@ export function parseBrowseTopicFromSearchString(searchStr: string | undefined) return parseTopicFromSearchParams(new URLSearchParams(normalized)); } -export function hasMalformedBrowseTopicSearch( - search: Record, - searchStr?: string, -) { +export function hasMalformedBrowseTopicSearch(search: Record, searchStr?: string) { if (Object.keys(search).some((key) => key.startsWith("topic="))) { return true; } diff --git a/src/lib/formatInlineCodeSummary.ts b/src/lib/formatInlineCodeSummary.ts index d48fa1be..5ee158c5 100644 --- a/src/lib/formatInlineCodeSummary.ts +++ b/src/lib/formatInlineCodeSummary.ts @@ -1,6 +1,4 @@ -export type InlineCodeSummarySegment = - | { type: "text"; value: string } - | { type: "code"; value: string }; +type InlineCodeSummarySegment = { type: "text"; value: string } | { type: "code"; value: string }; const INLINE_CODE_PATTERN = /`([^`\n]+)`/g; diff --git a/src/lib/monacoLoader.ts b/src/lib/monacoLoader.ts index 71101242..3f633b89 100644 --- a/src/lib/monacoLoader.ts +++ b/src/lib/monacoLoader.ts @@ -2,11 +2,12 @@ import { loader } from "@monaco-editor/react"; import * as monaco from "monaco-editor"; import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker"; -type MonacoWindow = Window & typeof globalThis & { - MonacoEnvironment?: { - getWorker: () => Worker; +type MonacoWindow = Window & + typeof globalThis & { + MonacoEnvironment?: { + getWorker: () => Worker; + }; }; -}; const browserWindow = typeof window !== "undefined" ? (window as MonacoWindow) : undefined; diff --git a/src/lib/useBrowseTopicSearch.test.ts b/src/lib/useBrowseTopicSearch.test.ts index 8bcb7df1..456d71b4 100644 --- a/src/lib/useBrowseTopicSearch.test.ts +++ b/src/lib/useBrowseTopicSearch.test.ts @@ -4,7 +4,6 @@ import { describe, expect, it, vi } from "vitest"; import { useBrowseTopicSearch } from "./useBrowseTopicSearch"; const useRouterStateMock = vi.fn(); -const navigateMock = vi.fn(); vi.mock("@tanstack/react-router", () => ({ useRouterState: (options: { select: (state: unknown) => unknown }) => @@ -23,7 +22,9 @@ describe("useBrowseTopicSearch", () => { it("falls back to malformed topic%3Dgithub query strings", () => { useRouterStateMock.mockReturnValue("?topic%3Dgithub"); - const { result } = renderHook(() => useBrowseTopicSearch({ "topic=github": "" })); + const { result } = renderHook(() => + useBrowseTopicSearch<{ topic?: string; "topic=github"?: string }>({ "topic=github": "" }), + ); expect(result.current.activeTopic).toBe("github"); expect(result.current.search.topic).toBe("github"); }); diff --git a/src/routes/plugins/index.tsx b/src/routes/plugins/index.tsx index c294a942..9c5c05e9 100644 --- a/src/routes/plugins/index.tsx +++ b/src/routes/plugins/index.tsx @@ -1,5 +1,5 @@ import { createFileRoute, Link, redirect } from "@tanstack/react-router"; -import { isPluginCategorySlug, normalizeCatalogTopic } from "clawhub-schema"; +import { isPluginCategorySlug } from "clawhub-schema"; import { useQuery } from "convex/react"; import { BadgeCheck, PackageSearch, Plus } from "lucide-react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; @@ -21,14 +21,17 @@ import { PluginListItem } from "../../components/PluginListItem"; import { BrowseResultsSkeleton } from "../../components/skeletons/BrowseResultsSkeleton"; import { Button } from "../../components/ui/button"; import { formatBrowseCount } from "../../lib/browseCount"; +import { + parseBrowseTopicFromSearchInput, + sanitizeBrowseTopicSearch, +} from "../../lib/browseTopicSearch"; import { PLUGIN_CATEGORIES, resolvePluginBrowseCategorySlug } from "../../lib/categories"; -import { parseBrowseTopicFromSearchInput, sanitizeBrowseTopicSearch } from "../../lib/browseTopicSearch"; -import { useBrowseTopicSearch } from "../../lib/useBrowseTopicSearch"; import { fetchPluginCatalog, isRateLimitedPackageApiError, type PackageListItem, } from "../../lib/packageApi"; +import { useBrowseTopicSearch } from "../../lib/useBrowseTopicSearch"; import { useMediaQuery } from "../../lib/useMediaQuery"; type VisiblePluginSort = "recommended" | "updated" | "downloads" | "trending"; diff --git a/src/routes/skills/index.tsx b/src/routes/skills/index.tsx index fe329517..9293234f 100644 --- a/src/routes/skills/index.tsx +++ b/src/routes/skills/index.tsx @@ -18,11 +18,11 @@ import { useBrowseSearchDisclosure, } from "../../components/BrowseControls"; import { formatBrowseCount } from "../../lib/browseCount"; -import { parseBrowseTopicFromSearchInput, sanitizeBrowseTopicSearch } from "../../lib/browseTopicSearch"; import { - resolveSkillBrowseCategorySlug, - SKILL_CATEGORIES, -} from "../../lib/categories"; + parseBrowseTopicFromSearchInput, + sanitizeBrowseTopicSearch, +} from "../../lib/browseTopicSearch"; +import { resolveSkillBrowseCategorySlug, SKILL_CATEGORIES } from "../../lib/categories"; import { useBrowseTopicSearch } from "../../lib/useBrowseTopicSearch"; import { parseDir, parseSort } from "./-params"; import { SkillsResults } from "./-SkillsResults"; @@ -101,10 +101,7 @@ export function SkillsIndex() { : "all"; const activeSort = ["updated", "newest", "name"].includes(model.sort) ? model.sort : undefined; const hasActiveFilters = - model.hasQuery || - Boolean(model.activeCategory) || - Boolean(activeTopic) || - model.featuredOnly; + model.hasQuery || Boolean(model.activeCategory) || Boolean(activeTopic) || model.featuredOnly; const totalSkillsCount = useQuery(api.skills.countPublicSkills, {}); const categoryTopics = useQuery( api.catalogTopics.listTopByCategory,