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
7 changes: 4 additions & 3 deletions COPY.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,17 @@ Every ranked section says what orders it. ADR-0004 and ADR-0010 set the rules.

| Surface | String |
| --- | --- |
| Trending header | `Ranked by how many separate devs talked about each one.` |
| Trending header, with star rows | `Ranked by how many separate devs talked about each one. GitHub stars rank the rest of the board.` |
| Trending header | `Ranked by how many separate devs talked about each one. Skills from the 20 most-starred repositories rank lower, so lesser-known skills lead.` |
| Trending header, with star rows | `Ranked by how many separate devs talked about each one. GitHub stars rank the rest of the board. Skills from the 20 most-starred repositories rank lower, so lesser-known skills lead.` |
| Trending star row label | `Ranked by GitHub stars` |
| Track talked heading | `{Noun} skills devs talked about this week`, or `this month` on the month board |
| Track talked line | The trending header string, unchanged |
| Track talked line | `Ranked by how many separate devs talked about each one.` Track pages skip the demotion (ADR-0010), so the line never states it |
| Track pinned heading | `Hand-picked {noun} skills` |
| Track stars heading | `More {noun} skills, ranked by GitHub stars`, or `{Noun} skills, ranked by GitHub stars` when no section comes before it |
| Track quiet line | `Devs talked about {n} of these skills this week. A list ranked by devs starts at 5.` |

`{noun}` is the track's `noun` field in `clusters.ts`, such as `design` or `SEO`.
The 20 in the trending header is `DEMOTED_STARRED_REPOSITORIES` in `shared/trending-range.ts`. The page and the ranking read that one constant.
Never call a ranked section top, popular, hot, best, or a leaderboard.

## Discord digest
Expand Down
5 changes: 4 additions & 1 deletion app/components/CliInstallChip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import CommandChip from './_CommandChip.vue'
* beside `SkilldInstallChip` on the `/cli` page, which teaches the Agent to
* drive what this one installs.
*/
const { surface } = defineProps<{
const { surface, quiet = false } = defineProps<{
/** The analytics surface, such as `cli-hero`. */
surface: string
/** Ink the dot instead of rose, where another element already spends the band's rose. */
quiet?: boolean
}>()

const command = cliGlobalInstallCmd()
Expand All @@ -25,6 +27,7 @@ const consequenceId = useId()
:command="command"
mode="install"
size="sm"
:quiet="quiet"
:surface="surface"
:target="target"
copy-label="Copy CLI install command"
Expand Down
7 changes: 5 additions & 2 deletions app/components/TrendingMark.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ const bars = SPARK_BARS.slice(1)
</template>

<style scoped>
/* IBM Plex Mono has no braille, so the bars fall through to a face that does. */
/* IBM Plex Mono has no braille, so the bars fall through to a face that does.
Muted, not dimmed: `--ui-text-dimmed` is stone 400 in light and stone 500
in dark, and both fail text contrast on the page surface. Muted is the
lightest stone token that passes AA in both modes. */
.trending-mark {
display: inline-block;
flex: none;
font-family: 'IBM Plex Mono', 'DejaVu Sans Mono', 'Apple Braille', 'Segoe UI Symbol', ui-monospace, monospace;
font-size: 0.875rem;
line-height: 1;
letter-spacing: 0.04em;
color: var(--ui-text-dimmed);
color: var(--ui-text-muted);
}

.trending-mark__today {
Expand Down
8 changes: 6 additions & 2 deletions layers/marketing/app/pages/cli/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ const codeClass = 'font-mono text-xs text-default'
<template>
<div class="cli-page">
<section class="editorial-band cli-hero" aria-labelledby="cli-heading">
<!-- The band's one texture. The mask keeps the names clear of the copy. -->
<!-- The band's one texture, in stone only: the "Teach your agent skilld"
chip's dot is the band's one rose element (DESIGN.md "Brand
System"). The mask keeps the names clear of the copy. -->
<div class="cli-hero__texture" aria-hidden="true">
<TextureBrailleNames />
</div>
Expand Down Expand Up @@ -164,7 +166,7 @@ const codeClass = 'font-mono text-xs text-default'
</div>
<div class="cli-hero__action">
<span class="cli-hero__label">Install the CLI</span>
<CliInstallChip surface="cli-hero" />
<CliInstallChip surface="cli-hero" quiet />
</div>
</div>
</div>
Expand Down Expand Up @@ -418,7 +420,9 @@ const codeClass = 'font-mono text-xs text-default'

/* Below 64rem the names run as a strip under the chips. The band's bottom
padding keeps that strip clear of text. */
/* Stone only, as on the home hero: the pick draws in muted ink, not rose. */
.cli-hero__texture {
--brand-dot: var(--ui-text-muted);
position: absolute;
inset-inline: 0;
bottom: 0;
Expand Down
10 changes: 7 additions & 3 deletions layers/marketing/app/pages/skills/trending.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { githubAvatarProxyUrl } from '#shared/image-proxy'
import { relativeDay } from '#shared/trending-post'
import {
boardPost,
DEMOTED_STARRED_REPOSITORIES,
isEvidenced,
leaderboardBoardRows,
MIN_INDEXABLE_ROWS,
Expand Down Expand Up @@ -314,10 +315,13 @@ const headerDescription = computed(() => {
return 'Repositories from individual creators publishing reusable agent skills, reviewed for eligibility and ranked by GitHub stars.'
// Neither the noun nor the period, both of which the heading above now
// states. Repeating them cost the line its only job, which is the ranking
// rule, and "say it once" is the brand's own instruction.
// rule, and "say it once" is the brand's own instruction. The demotion is
// part of that rule: it reorders rows, so a line that leaves it out
// overclaims (ADR-0004).
const demoted = `Skills from the ${DEMOTED_STARRED_REPOSITORIES} most-starred repositories rank lower, so lesser-known skills lead.`
return fillerTotal.value
? 'Ranked by how many separate devs talked about each one. GitHub stars rank the rest of the board.'
: 'Ranked by how many separate devs talked about each one.'
? `Ranked by how many separate devs talked about each one. GitHub stars rank the rest of the board. ${demoted}`
: `Ranked by how many separate devs talked about each one. ${demoted}`
})

const heading = computed(() => trendingRangeHeading(range.value, clock.value))
Expand Down
9 changes: 5 additions & 4 deletions layers/registry/server/api/clusters/[slug].get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getDB } from '#server/utils/db'
import { canonicalRepoSkillPath } from '#shared/skill-routes'
import { CLUSTER_BY_SLUG } from '../../data/clusters'
import { clusterPageSql } from '../../utils/cluster-membership'
import { curateClusterSkills, parseClusterSkillKeys } from '../../utils/cluster-skill-curation'
import { clusterSkillKey, curateClusterSkills, parseClusterSkillKeys } from '../../utils/cluster-skill-curation'

function clusterMeta(cluster: Cluster) {
return {
Expand Down Expand Up @@ -95,7 +95,7 @@ export default defineCachedEventHandler(async (event) => {
/** Skills in the repository. The board prints a run command only at 1. */
repoSkillCount: s.repo_skill_count,
/** A person pinned it to this track, so the board lists it under the hand-picked heading. */
pinned: pinnedKeys.has(`${s.owner}/${s.name}`),
pinned: pinnedKeys.has(clusterSkillKey(s)),
}))
const items = page === 1
? curateClusterSkills(rankedItems, cluster.pinnedExamples)
Expand All @@ -115,6 +115,7 @@ export default defineCachedEventHandler(async (event) => {
maxAge: 60 * 10,
staleMaxAge: 60 * 60,
swr: true,
// v5: items carry `repoSkillCount` and `pinned` for the track board.
name: 'clusters-detail-origin-v5',
// v6: a pin matches `owner/repo/name`, so a namesake in another repository
// is no longer listed as pinned.
name: 'clusters-detail-origin-v6',
})
7 changes: 4 additions & 3 deletions layers/registry/server/api/clusters/index.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { getDB } from '#server/utils/db'
import { CLUSTERS } from '../../data/clusters'
import { findClusterIndexRows } from '../../utils/cluster-index-rows'
import { clusterMembersSql } from '../../utils/cluster-membership'
import { curateClusterSkills, parseClusterSkillKeys } from '../../utils/cluster-skill-curation'
import { clusterSkillKey, curateClusterSkills, parseClusterSkillKeys } from '../../utils/cluster-skill-curation'

interface SkillRow {
owner: string
Expand Down Expand Up @@ -70,7 +70,7 @@ export default defineCachedEventHandler(async (event) => {
const items: ClusterCard[] = CLUSTERS.map((c: Cluster) => {
const pinned = new Set(c.pinnedExamples)
const inCluster = rows
.filter(r => (r.category !== null && c.categories.includes(r.category)) || pinned.has(`${r.owner}/${r.name}`))
.filter(r => (r.category !== null && c.categories.includes(r.category)) || pinned.has(clusterSkillKey(r)))
// Abstract skills lead the card: they are the classified curation signal,
// and the backfill exists so the track has depth under them.
.sort((a, b) => b.is_abstract - a.is_abstract || b.stars - a.stars || a.name.localeCompare(b.name))
Expand Down Expand Up @@ -120,5 +120,6 @@ export default defineCachedEventHandler(async (event) => {
maxAge: 60 * 10,
staleMaxAge: 60 * 60,
swr: true,
name: 'clusters-index-origin-v5',
// v6: a pin matches `owner/repo/name`.
name: 'clusters-index-origin-v6',
})
Loading