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
11 changes: 11 additions & 0 deletions apps/catalog/src/components/ResultList.astro
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ const initialRows = rows.slice(0, 24);
)}
<div class="catalog-result-row__heading">
<a class="catalog-result-row__title" href={row.detailHref}>{row.name}</a>
{row.trust === "official" && (
<span
class="catalog-result-row__trust catalog-result-row__trust--official catalog-result-row__trust--title"
aria-hidden="true"
>
<HugeIcon
class="catalog-result-row__trust-icon size-[14px]"
icon={catalogTrustIcons.official ?? AlertCircleIcon}
/>
</span>
)}
Comment thread
ian-pascoe marked this conversation as resolved.
</div>
</div>
<p class="catalog-result-row__description" role="cell">{row.description}</p>
Expand Down
20 changes: 10 additions & 10 deletions apps/catalog/src/data/official-catalog.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions apps/catalog/src/scripts/virtual-results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ function renderRow(item: VirtualItem, row: CatalogSearchRow | undefined): HTMLEl
${renderCapletIcon(row)}
<div class="catalog-result-row__heading">
<a class="catalog-result-row__title" href="${escapeAttribute(row.detailHref)}">${escapeHtml(row.name)}</a>
${renderTitleTrustIcon(row)}
</div>
</div>
<p class="catalog-result-row__description" role="cell">${escapeHtml(row.description)}</p>
Expand Down Expand Up @@ -395,6 +396,11 @@ function renderCapletIcon(row: CatalogSearchRow): string {
return `<img class="catalog-result-row__icon" src="${escapeAttribute(row.icon.url)}" alt="" width="32" height="32" loading="lazy" decoding="async" referrerpolicy="no-referrer">`;
}

function renderTitleTrustIcon(row: CatalogSearchRow): string {
if (row.trust !== "official") return "";
return `<span class="catalog-result-row__trust catalog-result-row__trust--official catalog-result-row__trust--title" aria-hidden="true">${renderIcon(catalogTrustIcons.official ?? AlertCircleIcon, "", "catalog-result-row__trust-icon")}</span>`;
}
Comment thread
ian-pascoe marked this conversation as resolved.

function renderIcon(icon: IconSvgObject, label: string, className = ""): string {
const classAttribute = className ? ` class="${escapeAttribute(className)}"` : "";
const accessibilityAttributes = label
Expand Down
11 changes: 11 additions & 0 deletions apps/catalog/src/styles/catalog.css
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,17 @@
color: var(--muted-foreground);
}

.catalog-result-row__trust--title {
min-width: 1.35rem;
min-height: 1.35rem;
padding-inline: 0;
}

.catalog-result-row__trust--title svg {
width: 0.875rem;
height: 0.875rem;
}

.catalog-result-row__description {
display: -webkit-box;
overflow: hidden;
Expand Down
25 changes: 25 additions & 0 deletions apps/catalog/test/catalog-icon-metadata.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import type { CatalogEntryRecord } from "../src/lib/catalog-store";

const catalogPath = join(import.meta.dirname, "../src/data/official-catalog.json");

const stableIconUrls = new Map([
["Neon", "https://neon.com/apple-touch-icon.png"],
["Notion", "https://www.notion.so/images/favicon.ico"],
["Sourcegraph", "https://sourcegraph.com/.assets/img/sourcegraph-mark.svg"],
["Supabase", "https://supabase.com/favicon/favicon-32x32.png"],
["Terraform", "https://developer.hashicorp.com/favicon.ico"],
]);

describe("catalog icon metadata", () => {
it("uses stable renderable icon urls for providers with broken favicons", () => {
const entries = JSON.parse(readFileSync(catalogPath, "utf8")) as CatalogEntryRecord[];

for (const [name, expectedUrl] of stableIconUrls) {
const entry = entries.find((candidate) => candidate.name === name);
expect(entry?.icon?.url, name).toBe(expectedUrl);
}
});
});
21 changes: 21 additions & 0 deletions apps/catalog/test/virtual-results.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,27 @@ describe("virtual catalog results", () => {
expect(icon.getAttribute("loading")).toBe("lazy");
});

it("shows the official trust icon next to the caplet title without repeating the status label", async () => {
mountSearchShell([
catalogSearchRowFixture({
id: "ast-grep",
name: "ast-grep",
trust: "official",
}),
]);

const { initVirtualCatalogSearch } = await import("../src/scripts/virtual-results");
trackSearch(initVirtualCatalogSearch());

const titleTrustIcon = document.querySelector(
".catalog-result-row__heading .catalog-result-row__trust--official",
);

expect(titleTrustIcon).toBeTruthy();
expect(titleTrustIcon?.getAttribute("aria-hidden")).toBe("true");
expect(titleTrustIcon?.getAttribute("aria-label")).toBeNull();
});

it("reuses row nodes that remain visible while scrolling", async () => {
mountSearchShell(manyCatalogSearchRows(200));

Expand Down
2 changes: 1 addition & 1 deletion apps/landing/src/components/landing/Activation.astro
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { exampleCaplets } from "../../data/landing";
<p class="mt-5 text-lg leading-8 text-pretty text-muted-foreground">
<code class="rounded bg-muted px-1.5 py-0.5 font-mono text-sm text-foreground">caplets setup</code> wires the agent integrations you choose. Add OSV first because it needs no auth; bring in GitHub or Sourcegraph after the discovery path feels right.
</p>
<Button class="mt-8" href="https://github.com/spiritledsoftware/caplets/tree/main/caplets" variant="outline">
<Button class="mt-8" href="https://catalog.caplets.dev" variant="outline">
Explore more Caplets
<ArrowUpRight class="size-4" aria-hidden="true" />
</Button>
Expand Down
19 changes: 19 additions & 0 deletions apps/landing/test/activation-links.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";

const repoRoot = join(import.meta.dirname, "../../..");

describe("activation links", () => {
it("sends the browse-more Caplets action to the public catalog", () => {
const source = readFileSync(
join(repoRoot, "apps/landing/src/components/landing/Activation.astro"),
"utf8",
);

expect(source).toContain('href="https://catalog.caplets.dev"');
expect(source).not.toContain(
'href="https://github.com/spiritledsoftware/caplets/tree/main/caplets"',
);
});
});
2 changes: 1 addition & 1 deletion caplets/neon/CAPLET.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ tags:
- branches
- sql
catalog:
icon: https://neon.com/favicon.ico
icon: https://neon.com/apple-touch-icon.png
mcpServer:
url: https://mcp.neon.tech/mcp
auth:
Expand Down
2 changes: 1 addition & 1 deletion caplets/notion/CAPLET.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ tags:
- tasks
- workspace
catalog:
icon: https://www.notion.com/images/notion-logo-block-main.svg
icon: https://www.notion.so/images/favicon.ico
mcpServer:
url: https://mcp.notion.com/mcp
auth:
Expand Down
2 changes: 1 addition & 1 deletion caplets/sourcegraph/CAPLET.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tags:
- code-search
- mcp
catalog:
icon: https://sourcegraph.com/favicon.ico
icon: https://sourcegraph.com/.assets/img/sourcegraph-mark.svg
mcpServer:
url: https://sourcegraph.com/.api/mcp
auth:
Expand Down
2 changes: 1 addition & 1 deletion caplets/supabase/CAPLET.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ tags:
- backend
- storage
catalog:
icon: https://supabase.com/favicon.ico
icon: https://supabase.com/favicon/favicon-32x32.png
mcpServer:
url: https://mcp.supabase.com/mcp
auth:
Expand Down
2 changes: 1 addition & 1 deletion caplets/terraform/CAPLET.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ tags:
- registry
- hcp
catalog:
icon: https://www.terraform.io/favicon.ico
icon: https://developer.hashicorp.com/favicon.ico
setup:
verify:
- label: Check Docker is available
Expand Down