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,