Skip to content

Commit b991a21

Browse files
committed
fix(landing): match bare competitor names in descriptions; pluralize remaining actions
1 parent 1bd90a3 commit b991a21

3 files changed

Lines changed: 30 additions & 16 deletions

File tree

‎apps/sim/app/(landing)/comparisons/library-links.ts‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,34 @@ const MAX_LINKS = 3
1111
const SUBJECT_SCORE = 2
1212
const MENTION_SCORE = 1
1313

14-
/** Whole-word, case-sensitive match on any of the competitor's names. */
15-
function buildMentionPattern(competitor: CompetitorProfile): RegExp {
16-
const phrases = competitor.mentions ?? [competitor.name]
14+
interface MentionPatterns {
15+
/** Matches Title Case titles and tags, where a bare common-word name ("Make") is ambiguous. */
16+
subject: RegExp
17+
/** Matches sentence-case descriptions, where the bare name is unambiguous. */
18+
mention: RegExp
19+
}
20+
21+
/** Whole-word, case-sensitive match on any of `phrases`. */
22+
function wordPattern(phrases: string[]): RegExp {
1723
return new RegExp(`\\b(?:${phrases.map(escapeRegExp).join('|')})\\b`)
1824
}
1925

26+
function buildMentionPatterns(competitor: CompetitorProfile): MentionPatterns {
27+
const aliases = competitor.mentions ?? [competitor.name]
28+
return {
29+
subject: wordPattern(aliases),
30+
mention: wordPattern([competitor.name, ...aliases]),
31+
}
32+
}
33+
2034
const COMPETITOR_PATTERNS = ALL_COMPETITORS.map((competitor) => ({
2135
competitor,
22-
pattern: buildMentionPattern(competitor),
36+
patterns: buildMentionPatterns(competitor),
2337
}))
2438

25-
function scoreRelevance(post: ContentMeta, pattern: RegExp): number {
26-
if (pattern.test(post.title) || post.tags.some((tag) => pattern.test(tag))) return SUBJECT_SCORE
27-
return pattern.test(post.description) ? MENTION_SCORE : 0
39+
function scoreRelevance(post: ContentMeta, { subject, mention }: MentionPatterns): number {
40+
if (subject.test(post.title) || post.tags.some((tag) => subject.test(tag))) return SUBJECT_SCORE
41+
return mention.test(post.description) ? MENTION_SCORE : 0
2842
}
2943

3044
/** The highest-scoring items with a positive score, best first; ties keep input order. */
@@ -44,16 +58,16 @@ function topByScore<T>(items: T[], score: (item: T) => number): T[] {
4458
export async function getLibraryPostsForCompetitor(
4559
competitor: CompetitorProfile
4660
): Promise<ContentMeta[]> {
47-
const pattern = buildMentionPattern(competitor)
48-
return topByScore(await getAllPostMeta(), (post) => scoreRelevance(post, pattern))
61+
const patterns = buildMentionPatterns(competitor)
62+
return topByScore(await getAllPostMeta(), (post) => scoreRelevance(post, patterns))
4963
}
5064

5165
/**
5266
* Comparison pages for the competitors a library article is about or names,
5367
* subjects first, then in {@link ALL_COMPETITORS} order.
5468
*/
5569
export function getComparisonsForPost(post: ContentMeta): CompetitorProfile[] {
56-
return topByScore(COMPETITOR_PATTERNS, ({ pattern }) => scoreRelevance(post, pattern)).map(
70+
return topByScore(COMPETITOR_PATTERNS, ({ patterns }) => scoreRelevance(post, patterns)).map(
5771
({ competitor }) => competitor
5872
)
5973
}

‎apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ function buildMetaDescription(integration: Integration): string {
249249
const sample = operations.slice(0, 3).map((o) => toPhrase(o.name, name))
250250
const remaining = operations.length - sample.length
251251
sentences.push(
252-
`Sim AI agents can ${toProseList(remaining > 0 ? [...sample, `${remaining} more ${name} actions`] : sample)}.`
252+
`Sim AI agents can ${toProseList(remaining > 0 ? [...sample, pluralize(remaining, `more ${name} action`)] : sample)}.`
253253
)
254254
}
255255
if (triggers.length > 0) {

‎apps/sim/lib/compare/data/types.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,11 @@ export interface CompetitorProfile {
246246
*/
247247
isWorkflowBuilder?: boolean
248248
/**
249-
* Phrases that identify this competitor in library article titles, tags,
250-
* and descriptions, matched case-sensitively on word boundaries. Drives the
251-
* links between comparison pages and library articles. Defaults to `[name]`;
252-
* set it when articles use another name ("AgentKit") or when the bare name
253-
* is also a common word ("Make").
249+
* Phrases that identify this competitor in library article titles and tags,
250+
* matched case-sensitively on word boundaries; descriptions also match the
251+
* bare `name`. Drives the links between comparison pages and library
252+
* articles. Defaults to `[name]`; set it when articles use another name
253+
* ("AgentKit") or when the bare name is a common Title Case word ("Make").
254254
*/
255255
mentions?: string[]
256256
/** Logo icon and brand colors, when available. */

0 commit comments

Comments
 (0)