diff --git a/README.md b/README.md index 6ecc9c053..d1c179368 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![npm version](https://img.shields.io/npm/v/gsd-pi?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/gsd-pi) [![npm downloads](https://img.shields.io/npm/dm/gsd-pi?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/gsd-pi) [![GitHub stars](https://img.shields.io/github/stars/gsd-build/GSD-2?style=for-the-badge&logo=github&color=181717)](https://github.com/gsd-build/GSD-2) -[![Discord](https://img.shields.io/badge/Discord-Join%20us-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/gsd) +[![Discord](https://img.shields.io/badge/Discord-Join%20us-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.com/invite/nKXTsAcmbT) [![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE) [![$GSD Token](https://img.shields.io/badge/$GSD-Dexscreener-1C1C1C?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIgZmlsbD0iIzAwRkYwMCIvPjwvc3ZnPg==&logoColor=00FF00)](https://dexscreener.com/solana/dwudwjvan7bzkw9zwlbyv6kspdlvhwzrqy6ebk8xzxkv) diff --git a/docs/what-is-pi/15-pi-packages-the-ecosystem.md b/docs/what-is-pi/15-pi-packages-the-ecosystem.md index 4e19de60a..7116cca99 100644 --- a/docs/what-is-pi/15-pi-packages-the-ecosystem.md +++ b/docs/what-is-pi/15-pi-packages-the-ecosystem.md @@ -38,6 +38,6 @@ Or just use conventional directory names (`extensions/`, `skills/`, `prompts/`, - [Package gallery](https://shittycodingagent.ai/packages) - [npm search](https://www.npmjs.com/search?q=keywords%3Api-package) -- [Discord community](https://discord.com/invite/3cU7Bz4UPx) +- [Discord community](https://discord.com/invite/nKXTsAcmbT) --- diff --git a/src/resources/extensions/gsd/tests/discord-invite-links.test.ts b/src/resources/extensions/gsd/tests/discord-invite-links.test.ts new file mode 100644 index 000000000..8b82d4749 --- /dev/null +++ b/src/resources/extensions/gsd/tests/discord-invite-links.test.ts @@ -0,0 +1,47 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +/** + * Validates that all Discord invite links in user-facing files point to valid, + * consistent invite URLs — not expired vanity links. + * + * Regression test for https://github.com/gsd-build/gsd-2/issues/2699 + */ + +const ROOT = process.cwd(); + +/** Canonical Discord invite for the GSD community. */ +const VALID_INVITE = "https://discord.com/invite/nKXTsAcmbT"; + +/** Files that contain user-facing Discord invite links. */ +const FILES_WITH_INVITE_LINKS: string[] = [ + "README.md", + "docs/what-is-pi/15-pi-packages-the-ecosystem.md", +]; + +describe("Discord invite links (#2699)", () => { + for (const relPath of FILES_WITH_INVITE_LINKS) { + it(`${relPath} contains only the canonical Discord invite`, () => { + const content = readFileSync(join(ROOT, relPath), "utf8"); + + // Extract all Discord invite URLs (discord.gg/X or discord.com/invite/X) + const invitePattern = /https?:\/\/(?:discord\.gg|discord\.com\/invite)\/[A-Za-z0-9]+/g; + const matches = content.match(invitePattern); + + assert.ok( + matches && matches.length > 0, + `Expected at least one Discord invite link in ${relPath}`, + ); + + for (const link of matches) { + assert.equal( + link, + VALID_INVITE, + `Invalid Discord invite in ${relPath}: found "${link}", expected "${VALID_INVITE}"`, + ); + } + }); + } +});