@singi-labs/sifa-sdk 0.11.9 → 0.11.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -379,6 +379,7 @@ declare const APP_CATEGORY_MAP: {
379
379
  readonly aetherdocs: "Slides";
380
380
  readonly kich: "Recipes";
381
381
  readonly margin: "Research";
382
+ readonly recipe: "Recipes";
382
383
  readonly linkat: "Links";
383
384
  readonly kipclip: "Links";
384
385
  readonly statusphere: "Social";
@@ -761,16 +762,36 @@ interface ActivityItemForUrl {
761
762
  */
762
763
  declare function getAppIdForCollection(collection: string): string;
763
764
  /**
764
- * Resolve the canonical clickable URL for an activity item the same URL
765
- * the activity-card UI in sifa-web renders.
766
- *
767
- * Returns `null` when no link is appropriate (the card would render
768
- * non-clickable, or hide itself entirely).
765
+ * How the activity-card health scanner should verify a card is still live.
766
+ *
767
+ * - `record`: the URL is a first-party permalink that renders THIS record
768
+ * (e.g. a Bluesky post at bsky.app, a tangled repo, a smokesignal event).
769
+ * The authoritative liveness check is "does the record still exist on its
770
+ * PDS" — `com.atproto.repo.getRecord` on the item's own at-uri — NOT an
771
+ * HTTP probe of the rendering app. Rendering apps (bsky.app, tangled.sh)
772
+ * frequently answer HEAD with 404/405 while serving GET fine, which
773
+ * false-positives every permalink as broken.
774
+ * - `url`: the URL is a foreign or derived target — a bookmarked page, an
775
+ * external publisher, a *different* record's page, or a profile page.
776
+ * Its reachability is independent of this record, so probe the URL.
777
+ * - `none`: the card has no clickable URL; nothing to check.
778
+ */
779
+ type CardHealthStrategy = 'record' | 'url' | 'none';
780
+ interface CardHealth {
781
+ /** The clickable URL the card renders. Null when non-clickable. */
782
+ url: string | null;
783
+ /** How the scanner should verify liveness. See {@link CardHealthStrategy}. */
784
+ strategy: CardHealthStrategy;
785
+ }
786
+ /**
787
+ * Resolve the canonical clickable URL for an activity item **and** how its
788
+ * liveness should be checked — the single source of truth shared by:
789
+ * - sifa-web activity cards (which render `.url`), and
790
+ * - the sifa-api link-health scanner (which switches on `.strategy`: probe the
791
+ * record's PDS for `record`-strategy cards, probe the URL for `url`).
769
792
  *
770
- * Used by:
771
- * - sifa-web activity cards (single source of truth for href)
772
- * - sifa-api external-URL health scanner (must match what the UI links to,
773
- * so broken-link detection lines up with what users actually click)
793
+ * See {@link CardHealthStrategy} for why self-permalinks (bsky posts, etc.)
794
+ * must be verified by record existence rather than an HTTP probe of the app.
774
795
  *
775
796
  * Resolution order:
776
797
  * 1. Per-collection bespoke logic (tangled, kipclip, margin, smokesignal
@@ -779,6 +800,12 @@ declare function getAppIdForCollection(collection: string): string;
779
800
  * 2. Generic `record.url` field (used by hyperboards and similar).
780
801
  * 3. Pattern-based per-item / profile URL from the registry.
781
802
  */
803
+ declare function resolveCardHealth(item: ActivityItemForUrl): CardHealth;
804
+ /**
805
+ * Resolve the canonical clickable URL for an activity item — the same URL
806
+ * the activity-card UI in sifa-web renders. Thin wrapper over
807
+ * {@link resolveCardHealth}; returns `null` when no link is appropriate.
808
+ */
782
809
  declare function resolveCardUrl(item: ActivityItemForUrl): string | null;
783
810
 
784
811
  /**
@@ -992,4 +1019,4 @@ declare function pickPrimaryPosition<T extends PrimaryPositionCandidate>(positio
992
1019
  */
993
1020
  declare const SIFA_SDK_VERSION: string;
994
1021
 
995
- export { ACTIVITY_TIERS, ACTIVITY_VISIBILITY_RULES, APP_CATEGORIES, APP_CATEGORY_IDS, APP_CATEGORY_MAP, APP_URL_PATTERNS, type ActivityItemForUrl, type ActivityTaxonomy, type ActivityTier, type AppCategoryId, type AppUrlPatterns, CALENDAR_EVENT_MODE_LABELS, CALENDAR_EVENT_STATUS_LABELS, CATEGORY_LABELS, CATEGORY_ORDER, COLLECTION_TO_APP, COMPANY_OPTIONAL_EMPLOYMENT_TYPES, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type ContinentCode, type CsvRow, DIMENSIONS_MAX_SCORE, type DimensionKey, type DimensionMap, EMPLOYMENT_TYPE_GROUPS, EMPLOYMENT_TYPE_LABELS, type EmploymentTypeGroup, type EmploymentTypeOption, INDUSTRY_OPTIONS, type IndustryOption, type KnownAppId, type LexiconEntry, LocationValue, MIN_SKILLS, type MergedProfileSkill, OPEN_TO_OPTIONS, OPEN_TO_TOKENS, OPEN_TO_TOKEN_TO_VALUE, OPEN_TO_VALUE_TO_TOKEN, type OpenToGroup, type OpenToOption, PLATFORM_LABELS, PLATFORM_OPTIONS, PRESENTATION_LINK_TYPE_LABELS, PRESENTATION_LINK_TYPE_OPTIONS, PRESENTATION_ROLE_LABELS, PRESENTATION_ROLE_OPTIONS, PUBLISHERS, type ParsedDelivery, type ParsedPresentation, type PdsProvider, PdsProviderInfo, type PlatformId, type PresentationDeliverySummary, PresentationDuration, type PresentationLinkTypeOption, type PresentationRoleOption, type PrimaryPositionCandidate, Profile, type ProfileCompletion, type ProfileDimensionInputs, ProfilePresentationDelivery, ProfilePresentationDeliveryRecord, ProfilePresentationRecord, ProfileSkill, type Publisher, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, STANDARD_PUBLISHER_ID, type SkillCategory, type TierMeta, WORKPLACE_TYPE_LABELS, WORKPLACE_TYPE_OPTIONS, type WorkplaceTypeOption, categoryForApp, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, dimensionsFromInputs, durationFromMinutes, findIndustry, formatDistanceToNow, formatLocation, formatPresentationDuration, formatRelativeTime, getActivityTaxonomyVersion, getActivityTier, getAppCategoryIcon, getAppIdForCollection, getCalendarEventModeLabel, getCalendarEventStatusLabel, getContinent, getDisplayLabel, getEmploymentTypeLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getLexiconEntry, getOpenToLabelKey, getPdsDisplayName, getPlatformLabel, getPresentationLinkTypeLabel, getPresentationRoleLabel, getPublisherByHost, getPublisherById, getPublisherFromSiteUrl, getTierMeta, getWorkplaceTypeLabel, groupSkillsByCategory, isAppCategory, isCompanyRequired, isKnownAppId, isKnownPlatform, isValidRgbColor, isVisibleActivityItem, lexiconDateExtractor, limitCombiningMarks, meetsContrastAA, normalizeOpenTo, normalizePlatformId, normalizePresentationMode, normalizePresentationRole, normalizeWorkplaceTypes, openToTokenToValue, openToValueToToken, parseIntendedAudiences, parseLocationString, parsePresentationDuration, pdsProviderFromApi, pickPrimaryPosition, presentationCsvRowToRecord, presentationDeliveryCsvRowToRecord, profileToDimensionInputs, relativeLuminance, resolveCardUrl, rgbToString, sanitizeDisplayText, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, stripHtmlToText, summarizePresentationDeliveries, truncateGraphemes };
1022
+ export { ACTIVITY_TIERS, ACTIVITY_VISIBILITY_RULES, APP_CATEGORIES, APP_CATEGORY_IDS, APP_CATEGORY_MAP, APP_URL_PATTERNS, type ActivityItemForUrl, type ActivityTaxonomy, type ActivityTier, type AppCategoryId, type AppUrlPatterns, CALENDAR_EVENT_MODE_LABELS, CALENDAR_EVENT_STATUS_LABELS, CATEGORY_LABELS, CATEGORY_ORDER, COLLECTION_TO_APP, COMPANY_OPTIONAL_EMPLOYMENT_TYPES, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type CardHealth, type CardHealthStrategy, type ContinentCode, type CsvRow, DIMENSIONS_MAX_SCORE, type DimensionKey, type DimensionMap, EMPLOYMENT_TYPE_GROUPS, EMPLOYMENT_TYPE_LABELS, type EmploymentTypeGroup, type EmploymentTypeOption, INDUSTRY_OPTIONS, type IndustryOption, type KnownAppId, type LexiconEntry, LocationValue, MIN_SKILLS, type MergedProfileSkill, OPEN_TO_OPTIONS, OPEN_TO_TOKENS, OPEN_TO_TOKEN_TO_VALUE, OPEN_TO_VALUE_TO_TOKEN, type OpenToGroup, type OpenToOption, PLATFORM_LABELS, PLATFORM_OPTIONS, PRESENTATION_LINK_TYPE_LABELS, PRESENTATION_LINK_TYPE_OPTIONS, PRESENTATION_ROLE_LABELS, PRESENTATION_ROLE_OPTIONS, PUBLISHERS, type ParsedDelivery, type ParsedPresentation, type PdsProvider, PdsProviderInfo, type PlatformId, type PresentationDeliverySummary, PresentationDuration, type PresentationLinkTypeOption, type PresentationRoleOption, type PrimaryPositionCandidate, Profile, type ProfileCompletion, type ProfileDimensionInputs, ProfilePresentationDelivery, ProfilePresentationDeliveryRecord, ProfilePresentationRecord, ProfileSkill, type Publisher, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, STANDARD_PUBLISHER_ID, type SkillCategory, type TierMeta, WORKPLACE_TYPE_LABELS, WORKPLACE_TYPE_OPTIONS, type WorkplaceTypeOption, categoryForApp, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, dimensionsFromInputs, durationFromMinutes, findIndustry, formatDistanceToNow, formatLocation, formatPresentationDuration, formatRelativeTime, getActivityTaxonomyVersion, getActivityTier, getAppCategoryIcon, getAppIdForCollection, getCalendarEventModeLabel, getCalendarEventStatusLabel, getContinent, getDisplayLabel, getEmploymentTypeLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getLexiconEntry, getOpenToLabelKey, getPdsDisplayName, getPlatformLabel, getPresentationLinkTypeLabel, getPresentationRoleLabel, getPublisherByHost, getPublisherById, getPublisherFromSiteUrl, getTierMeta, getWorkplaceTypeLabel, groupSkillsByCategory, isAppCategory, isCompanyRequired, isKnownAppId, isKnownPlatform, isValidRgbColor, isVisibleActivityItem, lexiconDateExtractor, limitCombiningMarks, meetsContrastAA, normalizeOpenTo, normalizePlatformId, normalizePresentationMode, normalizePresentationRole, normalizeWorkplaceTypes, openToTokenToValue, openToValueToToken, parseIntendedAudiences, parseLocationString, parsePresentationDuration, pdsProviderFromApi, pickPrimaryPosition, presentationCsvRowToRecord, presentationDeliveryCsvRowToRecord, profileToDimensionInputs, relativeLuminance, resolveCardHealth, resolveCardUrl, rgbToString, sanitizeDisplayText, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, stripHtmlToText, summarizePresentationDeliveries, truncateGraphemes };
package/dist/index.d.ts CHANGED
@@ -379,6 +379,7 @@ declare const APP_CATEGORY_MAP: {
379
379
  readonly aetherdocs: "Slides";
380
380
  readonly kich: "Recipes";
381
381
  readonly margin: "Research";
382
+ readonly recipe: "Recipes";
382
383
  readonly linkat: "Links";
383
384
  readonly kipclip: "Links";
384
385
  readonly statusphere: "Social";
@@ -761,16 +762,36 @@ interface ActivityItemForUrl {
761
762
  */
762
763
  declare function getAppIdForCollection(collection: string): string;
763
764
  /**
764
- * Resolve the canonical clickable URL for an activity item the same URL
765
- * the activity-card UI in sifa-web renders.
766
- *
767
- * Returns `null` when no link is appropriate (the card would render
768
- * non-clickable, or hide itself entirely).
765
+ * How the activity-card health scanner should verify a card is still live.
766
+ *
767
+ * - `record`: the URL is a first-party permalink that renders THIS record
768
+ * (e.g. a Bluesky post at bsky.app, a tangled repo, a smokesignal event).
769
+ * The authoritative liveness check is "does the record still exist on its
770
+ * PDS" — `com.atproto.repo.getRecord` on the item's own at-uri — NOT an
771
+ * HTTP probe of the rendering app. Rendering apps (bsky.app, tangled.sh)
772
+ * frequently answer HEAD with 404/405 while serving GET fine, which
773
+ * false-positives every permalink as broken.
774
+ * - `url`: the URL is a foreign or derived target — a bookmarked page, an
775
+ * external publisher, a *different* record's page, or a profile page.
776
+ * Its reachability is independent of this record, so probe the URL.
777
+ * - `none`: the card has no clickable URL; nothing to check.
778
+ */
779
+ type CardHealthStrategy = 'record' | 'url' | 'none';
780
+ interface CardHealth {
781
+ /** The clickable URL the card renders. Null when non-clickable. */
782
+ url: string | null;
783
+ /** How the scanner should verify liveness. See {@link CardHealthStrategy}. */
784
+ strategy: CardHealthStrategy;
785
+ }
786
+ /**
787
+ * Resolve the canonical clickable URL for an activity item **and** how its
788
+ * liveness should be checked — the single source of truth shared by:
789
+ * - sifa-web activity cards (which render `.url`), and
790
+ * - the sifa-api link-health scanner (which switches on `.strategy`: probe the
791
+ * record's PDS for `record`-strategy cards, probe the URL for `url`).
769
792
  *
770
- * Used by:
771
- * - sifa-web activity cards (single source of truth for href)
772
- * - sifa-api external-URL health scanner (must match what the UI links to,
773
- * so broken-link detection lines up with what users actually click)
793
+ * See {@link CardHealthStrategy} for why self-permalinks (bsky posts, etc.)
794
+ * must be verified by record existence rather than an HTTP probe of the app.
774
795
  *
775
796
  * Resolution order:
776
797
  * 1. Per-collection bespoke logic (tangled, kipclip, margin, smokesignal
@@ -779,6 +800,12 @@ declare function getAppIdForCollection(collection: string): string;
779
800
  * 2. Generic `record.url` field (used by hyperboards and similar).
780
801
  * 3. Pattern-based per-item / profile URL from the registry.
781
802
  */
803
+ declare function resolveCardHealth(item: ActivityItemForUrl): CardHealth;
804
+ /**
805
+ * Resolve the canonical clickable URL for an activity item — the same URL
806
+ * the activity-card UI in sifa-web renders. Thin wrapper over
807
+ * {@link resolveCardHealth}; returns `null` when no link is appropriate.
808
+ */
782
809
  declare function resolveCardUrl(item: ActivityItemForUrl): string | null;
783
810
 
784
811
  /**
@@ -992,4 +1019,4 @@ declare function pickPrimaryPosition<T extends PrimaryPositionCandidate>(positio
992
1019
  */
993
1020
  declare const SIFA_SDK_VERSION: string;
994
1021
 
995
- export { ACTIVITY_TIERS, ACTIVITY_VISIBILITY_RULES, APP_CATEGORIES, APP_CATEGORY_IDS, APP_CATEGORY_MAP, APP_URL_PATTERNS, type ActivityItemForUrl, type ActivityTaxonomy, type ActivityTier, type AppCategoryId, type AppUrlPatterns, CALENDAR_EVENT_MODE_LABELS, CALENDAR_EVENT_STATUS_LABELS, CATEGORY_LABELS, CATEGORY_ORDER, COLLECTION_TO_APP, COMPANY_OPTIONAL_EMPLOYMENT_TYPES, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type ContinentCode, type CsvRow, DIMENSIONS_MAX_SCORE, type DimensionKey, type DimensionMap, EMPLOYMENT_TYPE_GROUPS, EMPLOYMENT_TYPE_LABELS, type EmploymentTypeGroup, type EmploymentTypeOption, INDUSTRY_OPTIONS, type IndustryOption, type KnownAppId, type LexiconEntry, LocationValue, MIN_SKILLS, type MergedProfileSkill, OPEN_TO_OPTIONS, OPEN_TO_TOKENS, OPEN_TO_TOKEN_TO_VALUE, OPEN_TO_VALUE_TO_TOKEN, type OpenToGroup, type OpenToOption, PLATFORM_LABELS, PLATFORM_OPTIONS, PRESENTATION_LINK_TYPE_LABELS, PRESENTATION_LINK_TYPE_OPTIONS, PRESENTATION_ROLE_LABELS, PRESENTATION_ROLE_OPTIONS, PUBLISHERS, type ParsedDelivery, type ParsedPresentation, type PdsProvider, PdsProviderInfo, type PlatformId, type PresentationDeliverySummary, PresentationDuration, type PresentationLinkTypeOption, type PresentationRoleOption, type PrimaryPositionCandidate, Profile, type ProfileCompletion, type ProfileDimensionInputs, ProfilePresentationDelivery, ProfilePresentationDeliveryRecord, ProfilePresentationRecord, ProfileSkill, type Publisher, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, STANDARD_PUBLISHER_ID, type SkillCategory, type TierMeta, WORKPLACE_TYPE_LABELS, WORKPLACE_TYPE_OPTIONS, type WorkplaceTypeOption, categoryForApp, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, dimensionsFromInputs, durationFromMinutes, findIndustry, formatDistanceToNow, formatLocation, formatPresentationDuration, formatRelativeTime, getActivityTaxonomyVersion, getActivityTier, getAppCategoryIcon, getAppIdForCollection, getCalendarEventModeLabel, getCalendarEventStatusLabel, getContinent, getDisplayLabel, getEmploymentTypeLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getLexiconEntry, getOpenToLabelKey, getPdsDisplayName, getPlatformLabel, getPresentationLinkTypeLabel, getPresentationRoleLabel, getPublisherByHost, getPublisherById, getPublisherFromSiteUrl, getTierMeta, getWorkplaceTypeLabel, groupSkillsByCategory, isAppCategory, isCompanyRequired, isKnownAppId, isKnownPlatform, isValidRgbColor, isVisibleActivityItem, lexiconDateExtractor, limitCombiningMarks, meetsContrastAA, normalizeOpenTo, normalizePlatformId, normalizePresentationMode, normalizePresentationRole, normalizeWorkplaceTypes, openToTokenToValue, openToValueToToken, parseIntendedAudiences, parseLocationString, parsePresentationDuration, pdsProviderFromApi, pickPrimaryPosition, presentationCsvRowToRecord, presentationDeliveryCsvRowToRecord, profileToDimensionInputs, relativeLuminance, resolveCardUrl, rgbToString, sanitizeDisplayText, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, stripHtmlToText, summarizePresentationDeliveries, truncateGraphemes };
1022
+ export { ACTIVITY_TIERS, ACTIVITY_VISIBILITY_RULES, APP_CATEGORIES, APP_CATEGORY_IDS, APP_CATEGORY_MAP, APP_URL_PATTERNS, type ActivityItemForUrl, type ActivityTaxonomy, type ActivityTier, type AppCategoryId, type AppUrlPatterns, CALENDAR_EVENT_MODE_LABELS, CALENDAR_EVENT_STATUS_LABELS, CATEGORY_LABELS, CATEGORY_ORDER, COLLECTION_TO_APP, COMPANY_OPTIONAL_EMPLOYMENT_TYPES, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type CardHealth, type CardHealthStrategy, type ContinentCode, type CsvRow, DIMENSIONS_MAX_SCORE, type DimensionKey, type DimensionMap, EMPLOYMENT_TYPE_GROUPS, EMPLOYMENT_TYPE_LABELS, type EmploymentTypeGroup, type EmploymentTypeOption, INDUSTRY_OPTIONS, type IndustryOption, type KnownAppId, type LexiconEntry, LocationValue, MIN_SKILLS, type MergedProfileSkill, OPEN_TO_OPTIONS, OPEN_TO_TOKENS, OPEN_TO_TOKEN_TO_VALUE, OPEN_TO_VALUE_TO_TOKEN, type OpenToGroup, type OpenToOption, PLATFORM_LABELS, PLATFORM_OPTIONS, PRESENTATION_LINK_TYPE_LABELS, PRESENTATION_LINK_TYPE_OPTIONS, PRESENTATION_ROLE_LABELS, PRESENTATION_ROLE_OPTIONS, PUBLISHERS, type ParsedDelivery, type ParsedPresentation, type PdsProvider, PdsProviderInfo, type PlatformId, type PresentationDeliverySummary, PresentationDuration, type PresentationLinkTypeOption, type PresentationRoleOption, type PrimaryPositionCandidate, Profile, type ProfileCompletion, type ProfileDimensionInputs, ProfilePresentationDelivery, ProfilePresentationDeliveryRecord, ProfilePresentationRecord, ProfileSkill, type Publisher, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, STANDARD_PUBLISHER_ID, type SkillCategory, type TierMeta, WORKPLACE_TYPE_LABELS, WORKPLACE_TYPE_OPTIONS, type WorkplaceTypeOption, categoryForApp, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, dimensionsFromInputs, durationFromMinutes, findIndustry, formatDistanceToNow, formatLocation, formatPresentationDuration, formatRelativeTime, getActivityTaxonomyVersion, getActivityTier, getAppCategoryIcon, getAppIdForCollection, getCalendarEventModeLabel, getCalendarEventStatusLabel, getContinent, getDisplayLabel, getEmploymentTypeLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getLexiconEntry, getOpenToLabelKey, getPdsDisplayName, getPlatformLabel, getPresentationLinkTypeLabel, getPresentationRoleLabel, getPublisherByHost, getPublisherById, getPublisherFromSiteUrl, getTierMeta, getWorkplaceTypeLabel, groupSkillsByCategory, isAppCategory, isCompanyRequired, isKnownAppId, isKnownPlatform, isValidRgbColor, isVisibleActivityItem, lexiconDateExtractor, limitCombiningMarks, meetsContrastAA, normalizeOpenTo, normalizePlatformId, normalizePresentationMode, normalizePresentationRole, normalizeWorkplaceTypes, openToTokenToValue, openToValueToToken, parseIntendedAudiences, parseLocationString, parsePresentationDuration, pdsProviderFromApi, pickPrimaryPosition, presentationCsvRowToRecord, presentationDeliveryCsvRowToRecord, profileToDimensionInputs, relativeLuminance, resolveCardHealth, resolveCardUrl, rgbToString, sanitizeDisplayText, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, stripHtmlToText, summarizePresentationDeliveries, truncateGraphemes };
package/dist/index.js CHANGED
@@ -1011,6 +1011,9 @@ var APP_CATEGORY_MAP = {
1011
1011
  // io.kich.recipe.recipe — authored recipes
1012
1012
  margin: "Research",
1013
1013
  // at.margin.{note,annotation} — web-annotation notes with a body
1014
+ // Onboard from moll.dev profile audit.
1015
+ recipe: "Recipes",
1016
+ // exchange.recipe.recipe — authored recipes on recipe.exchange
1014
1017
  // Web-only (rendered in pills/cards via sifa-web atproto-apps.ts;
1015
1018
  // no backend scan collection yet)
1016
1019
  linkat: "Links",
@@ -1961,6 +1964,13 @@ var APP_URL_PATTERNS = Object.freeze({
1961
1964
  urlPattern: "https://kich.io/recipes/{rkey}",
1962
1965
  profileUrlPattern: "https://kich.io"
1963
1966
  },
1967
+ recipe: {
1968
+ // recipe.exchange viewer. Verified: GET /recipes/{rkey} returns 200 (rkey
1969
+ // alone; no did needed) and /profiles/{handle} returns 200 for the author
1970
+ // page. /recipe/{rkey} 404s.
1971
+ urlPattern: "https://recipe.exchange/recipes/{rkey}",
1972
+ profileUrlPattern: "https://recipe.exchange/profiles/{handle}"
1973
+ },
1964
1974
  aetherdocs: {
1965
1975
  // Aether OS is a browser OS — presentations open inside it and there's no
1966
1976
  // public per-record viewer. The card embeds the deck from the record; the
@@ -2031,7 +2041,9 @@ var COLLECTION_TO_APP = [
2031
2041
  ["wiki.lichen.", "lichen"],
2032
2042
  // Onboard from aramzs.xyz profile audit.
2033
2043
  ["os.aether.", "aetherdocs"],
2034
- ["io.kich.recipe.recipe", "kich"]
2044
+ ["io.kich.recipe.recipe", "kich"],
2045
+ // Onboard from moll.dev profile audit.
2046
+ ["exchange.recipe.recipe", "recipe"]
2035
2047
  ];
2036
2048
 
2037
2049
  // src/cards/resolve-card-url.ts
@@ -2043,6 +2055,12 @@ function getAppIdForCollection(collection) {
2043
2055
  if (parts.length >= 2) return `${parts[0]}.${parts[1]}`;
2044
2056
  return collection;
2045
2057
  }
2058
+ function urlHealth(url) {
2059
+ return url ? { url, strategy: "url" } : { url: null, strategy: "none" };
2060
+ }
2061
+ function recordHealth(url) {
2062
+ return url ? { url, strategy: "record" } : { url: null, strategy: "none" };
2063
+ }
2046
2064
  function interpolate(pattern, vars) {
2047
2065
  let result = pattern;
2048
2066
  for (const [key, value] of Object.entries(vars)) {
@@ -2059,18 +2077,18 @@ function shouldUseItemPattern(appId, collection) {
2059
2077
  }
2060
2078
  return true;
2061
2079
  }
2062
- function patternUrl(appId, vars, collection) {
2080
+ function patternHealth(appId, vars, collection) {
2063
2081
  const patterns = APP_URL_PATTERNS[appId];
2064
- if (!patterns) return null;
2082
+ if (!patterns) return { url: null, strategy: "none" };
2065
2083
  if (patterns.urlPattern && shouldUseItemPattern(appId, collection)) {
2066
2084
  const url = interpolate(patterns.urlPattern, vars);
2067
- if (url) return url;
2085
+ if (url) return recordHealth(url);
2068
2086
  }
2069
2087
  if (patterns.profileUrlPattern) {
2070
2088
  const url = interpolate(patterns.profileUrlPattern, vars);
2071
- if (url) return url;
2089
+ if (url) return urlHealth(url);
2072
2090
  }
2073
- return null;
2091
+ return { url: null, strategy: "none" };
2074
2092
  }
2075
2093
  var TANGLED_REPO_SLUG = /^[a-zA-Z0-9._-]+$/;
2076
2094
  function stringOrNull(value) {
@@ -2083,33 +2101,31 @@ function parseAtUri(atUri) {
2083
2101
  if (!match || !match[1] || !match[2]) return null;
2084
2102
  return { did: match[1], rkey: match[2] };
2085
2103
  }
2086
- function resolveCardUrl(item) {
2104
+ function resolveCardHealth(item) {
2087
2105
  const { collection, record, uri, rkey, authorDid, authorHandle } = item;
2088
2106
  const appId = getAppIdForCollection(collection);
2089
2107
  if (collection.startsWith("sh.tangled.")) {
2090
2108
  const repoName = stringOrNull(record.name) ?? (collection === "sh.tangled.repo" ? rkey : null);
2091
2109
  if (repoName && authorHandle && TANGLED_REPO_SLUG.test(repoName)) {
2092
- return `https://tangled.sh/${authorHandle}/${repoName}`;
2110
+ return recordHealth(`https://tangled.sh/${authorHandle}/${repoName}`);
2093
2111
  }
2094
- return patternUrl("tangled", { handle: authorHandle, did: authorDid, rkey }, collection);
2112
+ return patternHealth("tangled", { handle: authorHandle, did: authorDid, rkey }, collection);
2095
2113
  }
2096
2114
  if (collection.startsWith("com.kipclip.") || collection.startsWith("community.lexicon.bookmarks.")) {
2097
2115
  const subject = stringOrNull(record.subject);
2098
- if (subject) return subject;
2099
- return patternUrl("kipclip", { handle: authorHandle, did: authorDid, rkey });
2116
+ if (subject) return urlHealth(subject);
2117
+ return patternHealth("kipclip", { handle: authorHandle, did: authorDid, rkey });
2100
2118
  }
2101
2119
  if (collection === "at.margin.bookmark") {
2102
- const source = stringOrNull(record.source);
2103
- if (source) return source;
2104
- return null;
2120
+ return urlHealth(stringOrNull(record.source));
2105
2121
  }
2106
2122
  if (collection === "at.margin.annotation" || collection === "at.margin.note") {
2107
2123
  const target = record.target;
2108
2124
  if (target != null && typeof target === "object") {
2109
2125
  const source = stringOrNull(target.source);
2110
- if (source) return source;
2126
+ if (source) return urlHealth(source);
2111
2127
  }
2112
- return APP_URL_PATTERNS.margin?.profileUrlPattern ?? null;
2128
+ return urlHealth(APP_URL_PATTERNS.margin?.profileUrlPattern ?? null);
2113
2129
  }
2114
2130
  if (collection === "community.lexicon.calendar.rsvp") {
2115
2131
  const subject = record.subject;
@@ -2118,62 +2134,68 @@ function resolveCardUrl(item) {
2118
2134
  if (subjectUri) {
2119
2135
  const parsed2 = parseAtUri(subjectUri);
2120
2136
  if (parsed2) {
2121
- return `https://smokesignal.events/${parsed2.did}/${parsed2.rkey}`;
2137
+ return urlHealth(`https://smokesignal.events/${parsed2.did}/${parsed2.rkey}`);
2122
2138
  }
2123
2139
  }
2124
2140
  }
2125
- return null;
2141
+ return { url: null, strategy: "none" };
2126
2142
  }
2127
2143
  if (collection === "community.lexicon.calendar.event") {
2128
2144
  const parsed2 = parseAtUri(uri);
2129
2145
  if (parsed2) {
2130
- return `https://smokesignal.events/${parsed2.did}/${parsed2.rkey}`;
2146
+ return recordHealth(`https://smokesignal.events/${parsed2.did}/${parsed2.rkey}`);
2131
2147
  }
2132
- return null;
2148
+ return { url: null, strategy: "none" };
2133
2149
  }
2134
2150
  if (collection === "quest.atmo.event") {
2135
2151
  const parsed2 = parseAtUri(uri);
2136
2152
  if (parsed2) {
2137
- return `https://atmo.rsvp/p/${parsed2.did}/e/${parsed2.rkey}`;
2153
+ return recordHealth(`https://atmo.rsvp/p/${parsed2.did}/e/${parsed2.rkey}`);
2138
2154
  }
2139
- return null;
2155
+ return { url: null, strategy: "none" };
2140
2156
  }
2141
2157
  if (collection === "quest.atmo.checkin") {
2142
2158
  const eventUri = stringOrNull(record.event);
2143
2159
  if (eventUri) {
2144
2160
  const parsed2 = parseAtUri(eventUri);
2145
2161
  if (parsed2) {
2146
- return `https://atmo.rsvp/p/${parsed2.did}/e/${parsed2.rkey}`;
2162
+ return urlHealth(`https://atmo.rsvp/p/${parsed2.did}/e/${parsed2.rkey}`);
2147
2163
  }
2148
2164
  }
2149
- return null;
2165
+ return { url: null, strategy: "none" };
2150
2166
  }
2151
2167
  if (collection === "fyi.atstore.listing.review") {
2152
2168
  const listingMeta = record.listingMeta;
2153
2169
  if (listingMeta != null && typeof listingMeta === "object") {
2154
2170
  const slug = stringOrNull(listingMeta.slug);
2155
- if (slug) return `https://atstore.fyi/products/${encodeURIComponent(slug)}`;
2171
+ if (slug) return urlHealth(`https://atstore.fyi/products/${encodeURIComponent(slug)}`);
2156
2172
  }
2157
- return APP_URL_PATTERNS.atstore?.profileUrlPattern ?? null;
2173
+ return urlHealth(APP_URL_PATTERNS.atstore?.profileUrlPattern ?? null);
2158
2174
  }
2159
2175
  if (collection === "social.crate.content") {
2160
- return stringOrNull(record.canonicalUrl);
2176
+ return urlHealth(stringOrNull(record.canonicalUrl));
2161
2177
  }
2162
2178
  if (collection === "social.crate.note") {
2163
- return null;
2179
+ return { url: null, strategy: "none" };
2164
2180
  }
2165
2181
  if (collection.startsWith("site.standard.")) {
2166
2182
  const siteUrl = stringOrNull(record.siteUrl);
2167
2183
  const path = stringOrNull(record.path);
2168
- if (siteUrl && path) return `${siteUrl}${path}`;
2169
- if (siteUrl) return siteUrl;
2184
+ if (siteUrl && path) return urlHealth(`${siteUrl}${path}`);
2185
+ if (siteUrl) return urlHealth(siteUrl);
2170
2186
  }
2171
2187
  if (collection === "io.kich.recipe.recipe") {
2172
- return patternUrl("kich", { handle: authorHandle, did: authorDid, rkey }, collection);
2188
+ return patternHealth("kich", { handle: authorHandle, did: authorDid, rkey }, collection);
2189
+ }
2190
+ if (collection === "exchange.recipe.recipe") {
2191
+ return patternHealth("recipe", { handle: authorHandle, did: authorDid, rkey }, collection);
2173
2192
  }
2174
2193
  const recordUrl = stringOrNull(record.url);
2175
- if (recordUrl) return recordUrl;
2176
- return patternUrl(appId, { handle: authorHandle, did: authorDid, rkey }, collection);
2194
+ if (recordUrl) return urlHealth(recordUrl);
2195
+ return patternHealth(appId, { handle: authorHandle, did: authorDid, rkey }, collection);
2196
+ }
2197
+ function resolveCardUrl(item) {
2198
+ return resolveCardHealth(item).url;
2177
2199
  }
2178
2200
 
2179
2201
  // src/cards/visibility.ts
@@ -2669,8 +2691,8 @@ var ProfileVolunteeringRecordSchema = z.object({
2669
2691
  });
2670
2692
 
2671
2693
  // src/index.ts
2672
- var SIFA_SDK_VERSION = "0.11.9";
2694
+ var SIFA_SDK_VERSION = "0.11.11";
2673
2695
 
2674
- export { ACTIVITY_TIERS, ACTIVITY_VISIBILITY_RULES, ADULT_CONTENT_LABELS, APP_CATEGORIES, APP_CATEGORY_IDS, APP_CATEGORY_MAP, APP_URL_PATTERNS, AtmosphereFeedItemSchema, CALENDAR_EVENT_MODE_LABELS, CALENDAR_EVENT_STATUS_LABELS, CATEGORY_LABELS, CATEGORY_ORDER, COLLECTION_TO_APP, COMPANY_OPTIONAL_EMPLOYMENT_TYPES, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, DIMENSIONS_MAX_SCORE, EMPLOYMENT_TYPE_GROUPS, EMPLOYMENT_TYPE_LABELS, EndorsementConfirmationRecordSchema, EndorsementRecordSchema, FEATURE_FLAGS, FeatureAllowlistEntrySchema, FeedActorSchema, FollowFeedItemSchema, FollowFeedPageSchema, FollowProfilePageSchema, FollowProfileSchema, GraphFollowRecordSchema, INDUSTRY_OPTIONS, MIN_SKILLS, OPEN_TO_OPTIONS, OPEN_TO_TOKENS, OPEN_TO_TOKEN_TO_VALUE, OPEN_TO_VALUE_TO_TOKEN, PLATFORM_LABELS, PLATFORM_OPTIONS, PRESENTATION_LINK_TYPE_LABELS, PRESENTATION_LINK_TYPE_OPTIONS, PRESENTATION_ROLE_LABELS, PRESENTATION_ROLE_OPTIONS, PUBLISHERS, PresentationDurationSchema, PresentationLinkSchema, ProfileCertificationRecordSchema, ProfileCourseRecordSchema, ProfileEducationRecordSchema, ProfileExternalAccountRecordSchema, ProfileHonorRecordSchema, ProfileLanguageRecordSchema, ProfilePositionRecordSchema, ProfilePresentationDeliveryRecordSchema, ProfilePresentationRecordSchema, ProfileProjectRecordSchema, ProfilePublicationRecordSchema, ProfileSelfRecordSchema, ProfileSkillRecordSchema, ProfileVolunteeringRecordSchema, PublicationAuthorSchema, SIFA_SDK_VERSION, SKILL_CATEGORIES, STANDARD_PUBLISHER_ID, SifaFeedItemSchema, WORKPLACE_TYPE_LABELS, WORKPLACE_TYPE_OPTIONS, atUriSchema, categoryForApp, certDateExtractor, cidSchema, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, datetimeSchema, decodeFeedCursor, dedupeSkills, detectPdsProvider, didSchema, dimensionsFromInputs, durationFromMinutes, encodeFeedCursor, externalRecordRefSchema, findIndustry, formatDistanceToNow, formatLocation, formatPresentationDuration, formatRelativeTime, getActivityTaxonomyVersion, getActivityTier, getAppCategoryIcon, getAppIdForCollection, getCalendarEventModeLabel, getCalendarEventStatusLabel, getContinent, getDisplayLabel, getEmploymentTypeLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getLexiconEntry, getOpenToLabelKey, getPdsDisplayName, getPlatformLabel, getPresentationLinkTypeLabel, getPresentationRoleLabel, getPublisherByHost, getPublisherById, getPublisherFromSiteUrl, getTierMeta, getWorkplaceTypeLabel, groupSkillsByCategory, hasAdultContent, isAppCategory, isCompanyRequired, isKnownAppId, isKnownPlatform, isValidRgbColor, isVisibleActivityItem, languageTagSchema, lexiconDateExtractor, limitCombiningMarks, makeGraphFollowRecordSchema, maxGraphemes, meetsContrastAA, normalizeOpenTo, normalizePlatformId, normalizePresentationMode, normalizePresentationRole, normalizeWorkplaceTypes, openToTokenToValue, openToValueToToken, parseIntendedAudiences, parseLocationString, parsePresentationDuration, pdsProviderFromApi, pickPrimaryPosition, presentationCsvRowToRecord, presentationDeliveryCsvRowToRecord, profileToDimensionInputs, relativeLuminance, resolveCardUrl, rgbToString, sanitizeDisplayText, sanitizeHandleInput, selfLabelsSchema, singleDateExtractor, sortByDateDesc, stripHtmlToText, strongRefSchema, summarizePresentationDeliveries, truncateGraphemes, uriSchema };
2696
+ export { ACTIVITY_TIERS, ACTIVITY_VISIBILITY_RULES, ADULT_CONTENT_LABELS, APP_CATEGORIES, APP_CATEGORY_IDS, APP_CATEGORY_MAP, APP_URL_PATTERNS, AtmosphereFeedItemSchema, CALENDAR_EVENT_MODE_LABELS, CALENDAR_EVENT_STATUS_LABELS, CATEGORY_LABELS, CATEGORY_ORDER, COLLECTION_TO_APP, COMPANY_OPTIONAL_EMPLOYMENT_TYPES, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, DIMENSIONS_MAX_SCORE, EMPLOYMENT_TYPE_GROUPS, EMPLOYMENT_TYPE_LABELS, EndorsementConfirmationRecordSchema, EndorsementRecordSchema, FEATURE_FLAGS, FeatureAllowlistEntrySchema, FeedActorSchema, FollowFeedItemSchema, FollowFeedPageSchema, FollowProfilePageSchema, FollowProfileSchema, GraphFollowRecordSchema, INDUSTRY_OPTIONS, MIN_SKILLS, OPEN_TO_OPTIONS, OPEN_TO_TOKENS, OPEN_TO_TOKEN_TO_VALUE, OPEN_TO_VALUE_TO_TOKEN, PLATFORM_LABELS, PLATFORM_OPTIONS, PRESENTATION_LINK_TYPE_LABELS, PRESENTATION_LINK_TYPE_OPTIONS, PRESENTATION_ROLE_LABELS, PRESENTATION_ROLE_OPTIONS, PUBLISHERS, PresentationDurationSchema, PresentationLinkSchema, ProfileCertificationRecordSchema, ProfileCourseRecordSchema, ProfileEducationRecordSchema, ProfileExternalAccountRecordSchema, ProfileHonorRecordSchema, ProfileLanguageRecordSchema, ProfilePositionRecordSchema, ProfilePresentationDeliveryRecordSchema, ProfilePresentationRecordSchema, ProfileProjectRecordSchema, ProfilePublicationRecordSchema, ProfileSelfRecordSchema, ProfileSkillRecordSchema, ProfileVolunteeringRecordSchema, PublicationAuthorSchema, SIFA_SDK_VERSION, SKILL_CATEGORIES, STANDARD_PUBLISHER_ID, SifaFeedItemSchema, WORKPLACE_TYPE_LABELS, WORKPLACE_TYPE_OPTIONS, atUriSchema, categoryForApp, certDateExtractor, cidSchema, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, datetimeSchema, decodeFeedCursor, dedupeSkills, detectPdsProvider, didSchema, dimensionsFromInputs, durationFromMinutes, encodeFeedCursor, externalRecordRefSchema, findIndustry, formatDistanceToNow, formatLocation, formatPresentationDuration, formatRelativeTime, getActivityTaxonomyVersion, getActivityTier, getAppCategoryIcon, getAppIdForCollection, getCalendarEventModeLabel, getCalendarEventStatusLabel, getContinent, getDisplayLabel, getEmploymentTypeLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getLexiconEntry, getOpenToLabelKey, getPdsDisplayName, getPlatformLabel, getPresentationLinkTypeLabel, getPresentationRoleLabel, getPublisherByHost, getPublisherById, getPublisherFromSiteUrl, getTierMeta, getWorkplaceTypeLabel, groupSkillsByCategory, hasAdultContent, isAppCategory, isCompanyRequired, isKnownAppId, isKnownPlatform, isValidRgbColor, isVisibleActivityItem, languageTagSchema, lexiconDateExtractor, limitCombiningMarks, makeGraphFollowRecordSchema, maxGraphemes, meetsContrastAA, normalizeOpenTo, normalizePlatformId, normalizePresentationMode, normalizePresentationRole, normalizeWorkplaceTypes, openToTokenToValue, openToValueToToken, parseIntendedAudiences, parseLocationString, parsePresentationDuration, pdsProviderFromApi, pickPrimaryPosition, presentationCsvRowToRecord, presentationDeliveryCsvRowToRecord, profileToDimensionInputs, relativeLuminance, resolveCardHealth, resolveCardUrl, rgbToString, sanitizeDisplayText, sanitizeHandleInput, selfLabelsSchema, singleDateExtractor, sortByDateDesc, stripHtmlToText, strongRefSchema, summarizePresentationDeliveries, truncateGraphemes, uriSchema };
2675
2697
  //# sourceMappingURL=index.js.map
2676
2698
  //# sourceMappingURL=index.js.map