simple list of pds servers with open registration

Fix version display: backward compat fallback and semver extraction

Read legacy latest_pds_version key until cron populates new per-software
keys. Extract clean semver from version strings like "millipds v0.0.5.dev17+..."
for both software detection and trust score comparison.

+35 -4
+6
backend/routes/api.ts
··· 24 getServerCount(), 25 ]); 26 27 c.header( 28 "Cache-Control", 29 "public, max-age=3600, stale-while-revalidate=3600",
··· 24 getServerCount(), 25 ]); 26 27 + // Backward compat: fall back to legacy key until cron populates new keys 28 + if (!latestVersions["bluesky-pds"]) { 29 + const legacy = await getMetadata("latest_pds_version"); 30 + if (legacy) latestVersions["bluesky-pds"] = legacy; 31 + } 32 + 33 c.header( 34 "Cache-Control", 35 "public, max-age=3600, stale-while-revalidate=3600",
+18 -2
backend/routes/pages.ts
··· 27 getServerCount(), 28 ]); 29 30 const servers = await getOpenServers(latestVersions); 31 32 c.header( ··· 66 check(s.user_count != null && s.user_count > 5, "Active users (>5)"); 67 68 // Version check: compare against the server's own software latest version 69 const softwareId = s.pds_software ?? "bluesky-pds"; 70 const expectedVersion = latestVersions[softwareId]; 71 if (!expectedVersion) { 72 // Link-only software with no tracked version: benefit of the doubt 73 check(true, "Latest version"); 74 } else { 75 - check(s.version === expectedVersion, "Latest version"); 76 } 77 78 return { score, breakdown: signals.join("\n") }; ··· 304 const softwareId = s.pds_software ?? "bluesky-pds"; 305 const expectedVersion = latestVersions[softwareId]; 306 const versionText = s.version || "unknown"; 307 let versionClass = "version-outdated"; 308 - if (!expectedVersion || s.version === expectedVersion) { 309 versionClass = "version-current"; 310 } 311 ··· 353 esc(hostname) 354 }" target="_blank" rel="noopener">Moove here</a></td> 355 </tr>`; 356 } 357 358 function esc(str: string): string {
··· 27 getServerCount(), 28 ]); 29 30 + // Backward compat: fall back to legacy key until cron populates new keys 31 + if (!latestVersions["bluesky-pds"]) { 32 + const legacy = await getMetadata("latest_pds_version"); 33 + if (legacy) latestVersions["bluesky-pds"] = legacy; 34 + } 35 + 36 const servers = await getOpenServers(latestVersions); 37 38 c.header( ··· 72 check(s.user_count != null && s.user_count > 5, "Active users (>5)"); 73 74 // Version check: compare against the server's own software latest version 75 + // Extract clean semver from strings like "millipds v0.0.5.dev17+..." 76 const softwareId = s.pds_software ?? "bluesky-pds"; 77 const expectedVersion = latestVersions[softwareId]; 78 if (!expectedVersion) { 79 // Link-only software with no tracked version: benefit of the doubt 80 check(true, "Latest version"); 81 } else { 82 + const cleanVersion = extractSemver(s.version); 83 + check(cleanVersion === expectedVersion, "Latest version"); 84 } 85 86 return { score, breakdown: signals.join("\n") }; ··· 312 const softwareId = s.pds_software ?? "bluesky-pds"; 313 const expectedVersion = latestVersions[softwareId]; 314 const versionText = s.version || "unknown"; 315 + const cleanVersion = extractSemver(s.version); 316 let versionClass = "version-outdated"; 317 + if (!expectedVersion || cleanVersion === expectedVersion) { 318 versionClass = "version-current"; 319 } 320 ··· 362 esc(hostname) 363 }" target="_blank" rel="noopener">Moove here</a></td> 364 </tr>`; 365 + } 366 + 367 + /** Extract a clean semver from a version string (e.g. "millipds v0.0.5.dev17+..." → "0.0.5") */ 368 + function extractSemver(version: string | null): string | null { 369 + if (!version) return null; 370 + const m = version.match(/(\d+\.\d+\.\d+)/); 371 + return m ? m[1] : version; 372 } 373 374 function esc(str: string): string {
+11 -2
cron/refresh.cron.ts
··· 148 149 for (const data of enriched) { 150 // Detect software by matching version against known version map 151 - if (data.version && versionToSoftware[data.version]) { 152 - data.pdsSoftware = versionToSoftware[data.version]; 153 } 154 155 await updateEnrichment(data.url, {
··· 148 149 for (const data of enriched) { 150 // Detect software by matching version against known version map 151 + if (data.version) { 152 + if (versionToSoftware[data.version]) { 153 + // Exact match (e.g. "0.4.74" → bluesky-pds) 154 + data.pdsSoftware = versionToSoftware[data.version]; 155 + } else { 156 + // Extract semver from strings like "millipds v0.0.5.dev17+..." 157 + const m = data.version.match(/(\d+\.\d+\.\d+)/); 158 + if (m && m[1] !== data.version && versionToSoftware[m[1]]) { 159 + data.pdsSoftware = versionToSoftware[m[1]]; 160 + } 161 + } 162 } 163 164 await updateEnrichment(data.url, {