Featured recommendations
- Complete proposed Featured set: {lineup.proposed.length} of {lineup.targetSize}{" "}
- {searchReport.artifactKind === "plugin" ? "plugins" : "skills"}. Review usefulness, quality,
- security and category coverage before approving a selection. This report does not publish
- Featured changes.
+ {lineup.proposed.length} ready of {lineup.targetSize} {catalog} · {lineup.pendingCount}{" "}
+ pending reservations · {lineup.telemetryShortfall} open telemetry places.
-
- Evidence groups appear in this order: both signals, search demand, adoption. Within each
- group, search counts and then the existing Trending rank determine order. No blended score
- is used; plugins and skills are ranked separately.
+
+ Telemetry ranks eligible entries by recorded installs over 30 completed UTC days, then
+ final-seven-day installs, then stable identity. Downloads, search-result associations,
+ publisher status and current Featured membership add no ranking bonus.
+
+
+ Review usefulness, quality, security and category coverage before approving publication.
+ This report does not publish Featured changes. Recorded installs are events, not unique
+ users or proof of successful runtime installation.
+ {lineup.staleEditorial ? (
+
+ Editorial choices changed from revision {lineup.editorialRevision} to{" "}
+ {lineup.currentEditorialRevision}. Refresh this report before approving a selection.
+
+ ) : null}
- Adoption: {adoption.status}. Snapshot generated {date(adoption.generatedAt)}; observed
- period {date(adoption.periodStart)} to {date(adoption.periodEnd)}. Inspected{" "}
- {adoption.inspectedItems} of {adoption.totalItems} entries in the existing Trending
- snapshot.
- {adoption.truncated ? " Additional adoption entries were not inspected." : ""}
+ Adoption: {adoption.status}. {date(adoption.periodStart)} inclusive to{" "}
+ {date(adoption.periodEnd)} exclusive. Read {date(adoption.generatedAt)}. Inspected{" "}
+ {adoption.inspectedItems} of {adoption.totalItems} identities across {adoption.scannedRows}{" "}
+ daily rows
+ {adoption.truncated ? "; additional candidates remain outside the inspected metadata" : ""}.
+ Current eligibility checked {date(report.metadataCheckedAt)}.
- Search evidence covers the top {searchReport.rows.length} of {searchReport.totalQueries}{" "}
- matching queries. Current eligibility checked {date(report.metadataCheckedAt)}.
- {searchReport.currentMetadataStatus === "unavailable"
- ? " Current search-result metadata is unavailable; adoption candidates may still be available."
- : ""}
+ Aggregate scan started {date(adoption.collectionStartedAt)}. Search intelligence remains
+ separate demand and gap evidence; current search-result associations do not establish demand
+ for an individual artifact.
- {lineup.proposed.filter((entry) => entry.change === "retain").length} retained ·{" "}
- {lineup.proposed.filter((entry) => entry.change === "add").length} additions ·{" "}
+ {lineup.proposed.filter((candidate) => candidate.change === "retain").length} retained ·{" "}
+ {lineup.proposed.filter((candidate) => candidate.change === "add").length} additions ·{" "}
{lineup.removals.length} removals proposed.
- {lineup.shortfall > 0 ? (
-
- {lineup.shortfall} open Featured {lineup.shortfall === 1 ? "place" : "places"}. We do not
- fill the set with entries that fail the quality checks.
-
- ) : null}
-
- Emerging means recently published (within 14 days) with observed adoption, or an entry in
- the existing Rising feed with adoption. It does not imply accelerating growth.
-
- {lineup.proposed.length ? (
-
- {lineup.proposed.map((candidate) => (
-
-
-
-
- {candidate.change === "retain" ? "Retain" : "Add"}
- {candidate.emerging ? " · Emerging" : ""} · {supportLabels[candidate.support]}
-
-
-
- {candidate.summary ??
- "No catalog summary is available. Review the artifact details."}
-
- Category: {candidate.category ?? "Uncategorized — review coverage"}
- {candidate.search ? (
-
-
- {searchReport.window.days === 7
- ? candidate.search.matchedSearches7d
- : candidate.search.searches30d}{" "}
- searches matched current catalog results · {searchReport.window.days} days
-
-
- {date(candidate.search.periodStart)} to {date(candidate.search.periodEnd)}.
- Aggregated through {date(candidate.search.dataThrough)}. These are matching
- query counts, not unique people or installs of this artifact.
-
-
- {candidate.search.queries.map((query) => (
- -
- “{query.query}” · {query.searches7d} in 7 days · {query.previous7d} previous
- 7 days · {query.searches30d} in 30 days · {query.scope} scope
-
- ))}
-
- {candidate.search.omittedQueries ? (
- {candidate.search.omittedQueries} more matching queries omitted.
- ) : null}
-
+ {lineup.reservedSlots > 0 ? (
+ <>
+ Editorial slots · {lineup.reservedSlots} reserved
+
+ Manual choices remain in order when recommendations are recomputed. Pending reservations
+ stay visible here and are omitted from public cards.
+
+
+ {lineup.reservations.map((reservation) => {
+ const candidate = selectedBySlot.get(reservation.slot);
+ return candidate ? (
+
) : (
-
No search evidence in the inspected queries.
- )}
- {candidate.adoption ? (
-
-
- Trending #{candidate.adoption.rank} · {candidate.adoption.source}
-
+
+ Slot {reservation.slot + 1} · Editorial · Pending
+ {reservation.displayName ?? "Unassigned editorial slot"}
+ {reservation.name ? {reservation.name} : null}
+ {reservation.reason ?? "Reserved for an editorial choice."}
- {candidate.adoption.downloads ?? "Unknown"} downloads ·{" "}
- {candidate.adoption.installs ?? "Unknown"} installs ·{" "}
- {candidate.adoption.bookmarks ?? "Unknown"} bookmarks
+ {reasons(reservation.pendingReasons) || "No eligible public artifact selected"}
-
- {date(candidate.adoption.periodStart)} to {date(candidate.adoption.periodEnd)}
-
-
- Snapshot {candidate.adoption.snapshotId} · generated{" "}
- {date(candidate.adoption.generatedAt)} · ranking{" "}
- {candidate.adoption.rankingVersion}
-
- {candidate.adoption.sourceObservedAt !== null ? (
- Source last observed {date(candidate.adoption.sourceObservedAt)}
- ) : null}
- {candidate.adoption.lifetimeInstalls !== null ? (
-
- {candidate.adoption.lifetimeInstalls} lifetime installs (separate from the
- observed period)
-
- ) : null}
-
- ) : (
-
No adoption evidence in the inspected Trending snapshot.
- )}
-
- ))}
-
- ) : (
+ No public card. Telemetry will not replace this reservation.
+
+ );
+ })}
+
+ >
+ ) : null}
+
+ Install-ranked selection · {telemetry.length} of {lineup.telemetryTarget}
+
+
+ {telemetry.map((candidate) => (
+
+ ))}
+
+ {lineup.telemetryShortfall > 0 ? (
- No eligible Featured candidates in the available evidence. Review coverage and exclusions
- below.
+ {lineup.telemetryShortfall} open telemetry places. We do not pad the selection with
+ ineligible entries or missing install evidence.
- )}
- {lineup.removals.length ? (
-
- Proposed removals
+ ) : null}
+ {lineup.removals.length > 0 ? (
+
+ Proposed removals ({lineup.removals.length})
- {lineup.removals.map((entry) => (
- -
- {entry.displayName}:{" "}
- {entry.reasons.map((reason) => reasonLabels[reason] ?? reason).join("; ")}
+ {lineup.removals.map((item) => (
+
-
+ {item.displayName}: {reasons(item.reasons)}
))}
-
+
) : null}
Current Featured baseline ({lineup.baseline.length})
-
- {lineup.baseline.map((entry) => (
- -
- {entry.id} · version {entry.version ?? "unavailable"} · Featured{" "}
- {date(entry.featuredAt)}
+
+ {lineup.baseline.map((item) => (
+ -
+ {item.id} · version {item.version ?? "unavailable"} · Featured {date(item.featuredAt)}
))}
-
+
- {recommendations.totalCandidates > lineup.proposed.length ? (
-
- Proposed {lineup.proposed.length} of {recommendations.totalCandidates} eligible
- candidates. Evidence-ranked candidates are reassessed each iteration; current entries with
- unknown evidence can fill remaining places.
-
- ) : null}
- {recommendations.excluded.length ? (
+
+ {recommendations.totalCandidates} eligible candidates; {recommendations.omittedCandidates}{" "}
+ outside the displayed candidate detail.
+
+ {recommendations.excluded.length > 0 ? (
- {recommendations.excluded.length} entries excluded from the shortlist
+ {recommendations.excluded.length} excluded from the shortlist
- {recommendations.excluded.map((entry) => (
- -
- {entry.displayName}:{" "}
- {entry.reasons.map((reason) => reasonLabels[reason] ?? reason).join("; ")}
+ {recommendations.excluded.map((item) => (
+
-
+ {item.displayName}: {reasons(item.reasons)}
))}
diff --git a/src/routes/-management/SearchInsightsPage.test.tsx b/src/routes/-management/SearchInsightsPage.test.tsx
index ad9f6afa67..886ab25733 100644
--- a/src/routes/-management/SearchInsightsPage.test.tsx
+++ b/src/routes/-management/SearchInsightsPage.test.tsx
@@ -16,8 +16,18 @@ const { getReport, getRecommendations, startReport, getResult, requests, statuse
vi.mock("convex/react", () => ({
useAction: () => getResult,
useMutation: () => startReport,
- useQuery: (_ref: unknown, args: { reportId: string } | "skip") =>
- args === "skip" ? undefined : statuses.get(args.reportId),
+ useQuery: (_ref: unknown, args: { reportId?: string; artifactKind?: string } | "skip") =>
+ args === "skip"
+ ? undefined
+ : args.artifactKind
+ ? {
+ artifactKind: args.artifactKind,
+ revision: 0,
+ editorial: [],
+ reservations: [],
+ published: null,
+ }
+ : statuses.get(args.reportId!),
}));
beforeEach(() => {
vi.resetAllMocks();
@@ -74,6 +84,8 @@ describe("SearchInsightsPage", () => {
metadataCheckedAt: report.generatedAt,
adoption: {
status: "available",
+ collectionStartedAt: report.generatedAt - 30 * 86_400_000,
+ scannedRows: 1,
generatedAt: report.generatedAt,
periodStart: report.generatedAt - 86_400_000,
periodEnd: report.generatedAt,
@@ -87,10 +99,18 @@ describe("SearchInsightsPage", () => {
excluded: [],
candidates: [],
lineup: {
- targetSize: 8,
+ targetSize: 16,
+ reservedSlots: 8,
+ telemetryTarget: 8,
+ editorialRevision: 0,
+ currentEditorialRevision: 0,
+ staleEditorial: false,
+ pendingCount: 8,
+ telemetryShortfall: 7,
+ reservations: [],
baseline: [],
removals: [],
- shortfall: 7,
+ shortfall: 15,
proposed: [
{
id: "plugin:calendar",
@@ -99,14 +119,20 @@ describe("SearchInsightsPage", () => {
url: "/plugins/calendar",
category: "productivity",
change: "add",
+ selectionBasis: "telemetry",
+ slot: 8,
+ reason: "Highest recorded installs among eligible remaining plugins.",
emerging: true,
support: "adoption-only",
search: null,
adoption: {
- source: "package-trending",
+ source: "package-daily-installs",
rank: 1,
- downloads: 40,
- installs: 3,
+ installs30d: 40,
+ installs7d: 3,
+ importedRows: 0,
+ importDatasetVersions: [],
+ periodStart7d: report.generatedAt - 7 * 86_400_000,
bookmarks: null,
snapshotId: "observed",
rankingVersion: "unversioned",
@@ -128,11 +154,11 @@ describe("SearchInsightsPage", () => {
target: { value: "featured" },
});
await screen.findByRole("link", { name: "Calendar connector" });
- expect(screen.getByText(/40 downloads/)).toBeTruthy();
- expect(screen.getByText(/1 of 8 plugins/)).toBeTruthy();
- expect(screen.getByText(/7 open Featured places/)).toBeTruthy();
- expect(screen.getByText(/Add · Emerging · Adoption/)).toBeTruthy();
- expect(screen.getByText(/No search evidence in the inspected queries/)).toBeTruthy();
+ expect(screen.getByText(/recorded installs \/ 30 days/)).toBeTruthy();
+ expect(screen.getByText(/1 ready of 16 plugins/)).toBeTruthy();
+ expect(screen.getByText(/7 open telemetry places. We do not pad/)).toBeTruthy();
+ expect(screen.getByText(/Slot 9 · Recorded installs/)).toBeTruthy();
+ expect(screen.getByText(/do not establish demand for an individual artifact/)).toBeTruthy();
expect(screen.queryByRole("table")).toBeNull();
fireEvent.change(screen.getByRole("combobox", { name: "Catalog" }), {
target: { value: "skill" },
diff --git a/src/routes/-management/SearchInsightsPage.tsx b/src/routes/-management/SearchInsightsPage.tsx
index 67556719ac..792fdc0266 100644
--- a/src/routes/-management/SearchInsightsPage.tsx
+++ b/src/routes/-management/SearchInsightsPage.tsx
@@ -1,16 +1,19 @@
import { useAction, useMutation, useQuery } from "convex/react";
import { useEffect, useMemo, useRef, useState } from "react";
import { api } from "../../../convex/_generated/api";
-import type { FeaturedIntelligenceReport } from "../../../convex/featuredIntelligence";
import type { SearchInsightArgs, SearchInsightReport } from "../../../convex/lib/searchInsights";
+import type { FeaturedIntelligenceReportSchema } from "../../../packages/clawhub/src/schema/searchInsights";
import type {
SearchReportRequest,
SearchReportStatus,
} from "../../../packages/clawhub/src/schema/searchReports";
import { Button } from "../../components/ui/button";
+import { FeaturedEditorial } from "./FeaturedEditorial";
import { FeaturedRecommendations } from "./FeaturedRecommendations";
import { insightTime as date } from "./insightTime";
+type FeaturedIntelligenceReport = typeof FeaturedIntelligenceReportSchema.infer;
+
export function SearchInsightsPage({ endDay }: { endDay?: number }) {
const startReport = useMutation(api.searchReports.start);
const getReport = useAction(api.searchReports.get);
@@ -34,7 +37,7 @@ export function SearchInsightsPage({ endDay }: { endDay?: number }) {
artifactKind,
scope,
source,
- window,
+ window: view === "featured" ? 30 : window,
...(view === "featured"
? {}
: {
@@ -199,10 +202,11 @@ export function SearchInsightsPage({ endDay }: { endDay?: number }) {
+ {view === "featured" ? (
+
+ ) : null}
{failure ? {failure}
: null}
{loading ? (
@@ -227,7 +238,7 @@ export function SearchInsightsPage({ endDay }: { endDay?: number }) {
? "Checking current eligibility…"
: phase === "running"
? view === "featured"
- ? "Analyzing search demand and adoption…"
+ ? "Analyzing recorded installs and search context…"
: "Analyzing search demand…"
: "Waiting to generate the report…"}
diff --git a/src/styles.css b/src/styles.css
index 0372d4ed25..a7f1547d02 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -34259,3 +34259,80 @@ a[class*="rounded-full"] {
width: 100%;
}
}
+
+.featured-editorial {
+ display: grid;
+ gap: 16px;
+ padding: 20px;
+ border: 1px solid var(--line);
+ border-radius: 10px;
+ background: var(--surface);
+}
+.featured-editorial h2 {
+ margin: 0 0 8px;
+}
+.featured-editorial details li {
+ margin-block: 12px;
+ overflow-wrap: anywhere;
+}
+.featured-editorial-list {
+ list-style: none;
+ padding: 0;
+ display: grid;
+ gap: 16px;
+}
+.featured-editorial-row {
+ border: 1px solid var(--line);
+ border-radius: 8px;
+ padding: 16px;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 12px;
+}
+.featured-editorial-row label {
+ display: grid;
+ gap: 6px;
+ min-width: 0;
+ font-size: 0.85rem;
+}
+.featured-editorial-row input,
+.featured-editorial-row textarea {
+ width: 100%;
+ min-width: 0;
+ padding: 8px 10px;
+ border: 1px solid var(--line);
+ border-radius: 6px;
+ background: var(--surface);
+ color: var(--ink);
+}
+.featured-editorial-row textarea {
+ min-height: 80px;
+ resize: vertical;
+}
+.featured-editorial-reason,
+.featured-editorial-row .featured-editorial-actions {
+ grid-column: 1 / -1;
+}
+.featured-editorial-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 12px;
+}
+.featured-recommendation-card.is-pending {
+ border-style: dashed;
+ background: var(--surface-muted);
+}
+.featured-install-evidence > strong {
+ display: block;
+ font-size: 1.3rem;
+ font-variant-numeric: tabular-nums;
+}
+@media (max-width: 700px) {
+ .featured-editorial-row {
+ grid-template-columns: minmax(0, 1fr);
+ }
+ .featured-editorial .search-insights-header {
+ flex-wrap: wrap;
+ }
+}