openvibers/openvibe.meme Commits
openvibe-shared v4.108.0 (was v4.107.4) (#80)
Changes
@@@ -128,7 +128,7 @@ Environment variable names are in [.env.example](.env.example); no value is comm- **PostgreSQL** — `DATABASE_URL` (through PgBouncer) and `DATABASE_DIRECT_URL` (migrations); embedded PGlite in`MEME_PGLITE_DIR` for development.- **Valkey** — optional `VALKEY_URL`, `VALKEY_PREFIX` (readiness lists it; the limits in v1 count in-process).--- **Packages** — `openvibe-contracts` v0.229.0, `openvibe-sdk` v0.74.0, `openvibe-shared` v4.107.4, the same++- **Packages** — `openvibe-contracts` v0.229.0, `openvibe-sdk` v0.74.0, `openvibe-shared` v4.108.0, the sametags OpenVibe.Today pins.## API@@@ -378,6 +378,6 @@ AGPL-3.0-only. See [LICENSE](LICENSE).<!-- versions:start -->- openvibe-contracts: v0.234.0- openvibe-sdk: v0.82.0--- openvibe-shared: v4.107.4++- openvibe-shared: v4.108.0- openvibe-publishing: v1.5.0<!-- versions:end -->@@@ -10,11 +10,11 @@"domain": "openvibe.meme","contracts": "openvibe-contracts v0.234.0","sdk": "openvibe-sdk v0.82.0",-- "shared": "openvibe-shared v4.107.4",++ "shared": "openvibe-shared v4.108.0","packages": ["openvibe-contracts v0.234.0","openvibe-sdk v0.82.0",-- "openvibe-shared v4.107.4"++ "openvibe-shared v4.108.0"],"summary": "OpenVibe.Meme is the open meme encyclopedia, rebuilt with AI. Internet entries carry an origin citation, spread points, variations, Media examples, meaning, L1 labels, related memes and a moderated revision history; OpenVibe's own running jokes keep the original importer. The importer reads only public Chat and Live APIs and proposes a candidate when a recurring phrase appears in at least two uses on two different days; the candidate is born hidden with a verbatim citation for every use and stays hidden until a staff person publishes it. Every citation is re-verified daily, a 404 marks it gone and an entry whose origin is gone is hidden. People vote once a week for meme of the week, and a caption is plain text over a template, never a rendered image. Trends come from Reddit's official API (no scraping), measured by score samples and perceptual hashes. Every public entry is one Search Fabric document queued in the service's outbox. Deep dives gather sources and fail unless every claim is cited. The generator renders real PNGs from the template's own layout and stores them in Media.","works": [@@@ -19,7 +19,7 @@"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.234.0","openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.5.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.82.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.107.4",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.108.0","pg": "^8.23.0","sharp": "^0.33.5"},@@@ -1694,9 +1694,9 @@}},"node_modules/openvibe-shared": {-- "version": "4.107.4",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.107.4",-- "integrity": "sha512-tThN0m3KMncEHVcBOvE+ysHjsZTlVIDLG1P+/i2Mulmxfc/AUpebAXhpWWrut50OChZ8o+HeePxsSrPI8mUQOQ==",++ "version": "4.108.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.108.0",++ "integrity": "sha512-NPzwjxpzGIpFpIm4uw3+VwHfsxbJ2+cD9yuhRzSwolSwqv2kCmwaVtHJ0DA9gKO3K8PCBfIP3UpKzpuSbYEJ+g==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0",@@@ -30,7 +30,7 @@"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.234.0","openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.5.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.82.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.107.4",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.108.0","pg": "^8.23.0","sharp": "^0.33.5"},@@@ -59,6 +59,10 @@ function createDiscoveryRoutes(ctx) {r.get('/llms.txt', (_req, res) => {res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsTxt({name: SITE_NAME,++ // AGT-5: each of Meme's own pages is linked at its Markdown twin (openvibe-shared 4.108.0 leaves files,++ // /api/ paths and other sites' links as they are). What an agent may skip is in `optional`, written last.++ markdown: true,++ base: site,summary: 'OpenVibe.Meme is the open meme database, rebuilt with AI. Every public entry cites the moment a running joke happened (a chat line, a VOD second, a Rundown segment), follows its later uses on a timeline, has a status (rising, peaked, classic, dead), and people vote for meme of the week. A caption generator puts plain text lines over a template image.',details: 'GET /api/v1/entries lists public entries; GET /api/v1/entries/:slug adds every citation and the use timeline; GET /api/v1/entries/:slug/series?days=30 is uses per UTC day. GET /api/v1/week lists this ISO week’s candidates and vote counts. The importer reads only public APIs and never publishes: a candidate stays hidden until a staff person publishes it.',sections: [@@@ -70,16 +74,17 @@ function createDiscoveryRoutes(ctx) {] },{ title: 'Machine-readable', links: [{ title: 'Public entries (JSON)', url: abs('/api/v1/entries') },-- { title: 'Sitemap', url: abs('/sitemap.xml') },-- { title: 'Full text for language models', url: abs('/llms-full.txt') },{ title: 'Release metadata (JSON)', url: abs('/release.json') },] },-- { title: 'Elsewhere', links: [-- { title: 'OpenVibe.Chat', url: 'https://openvibe.chat', note: 'where a running joke is often typed first' },-- { title: 'OpenVibe.Live', url: 'https://openvibe.live', note: 'the Rundown and the VOD transcripts' },-- { title: 'OpenVibe.Video', url: 'https://openvibe.video', note: 'the canonical ?t= moment' },-- { title: 'OpenVibe.Network', url: 'https://openvibe.network', note: 'accounts and staff roles' },-- ] },++ ],++ // llmstxt.org's "## Optional": what an agent may skip when it needs a shorter context.++ optional: [++ { title: 'Sitemap', url: abs('/sitemap.xml') },++ { title: 'Full text for language models', url: abs('/llms-full.txt') },++ { title: 'OpenVibe.Chat', url: 'https://openvibe.chat', note: 'where a running joke is often typed first' },++ { title: 'OpenVibe.Live', url: 'https://openvibe.live', note: 'the Rundown and the VOD transcripts' },++ { title: 'OpenVibe.Video', url: 'https://openvibe.video', note: 'the canonical ?t= moment' },++ { title: 'OpenVibe.Network', url: 'https://openvibe.network', note: 'accounts and staff roles' },],}));});@@@ -190,6 +190,10 @@ function jsonLd(html) {const llms = await t.get('/llms.txt');assert.strictEqual(llms.status, 200);assert.ok(llms.text.includes('OpenVibe.Meme'));++ // AGT-5: each of Meme's own pages is linked at its Markdown twin, and the secondary links are Optional.++ assert.ok(llms.text.includes('](https://openvibe.meme/index.md)'), 'the home link is not its twin');++ assert.ok(llms.text.includes('](https://openvibe.meme/week.md)'), 'the ballot is not its twin');++ assert.ok(llms.text.includes('\n## Optional\n'), 'no ## Optional section');});} finally {await t.close();
@@ -128,7 +128,7 @@ Environment variable names are in [.env.example](.env.example); no value is comm
@@ -128,7 +128,7 @@ Environment variable names are in [.env.example](.env.example); no value is comm
- **PostgreSQL** — `DATABASE_URL` (through PgBouncer) and `DATABASE_DIRECT_URL` (migrations); embedded PGlite in
- **PostgreSQL** — `DATABASE_URL` (through PgBouncer) and `DATABASE_DIRECT_URL` (migrations); embedded PGlite in
`MEME_PGLITE_DIR` for development.
`MEME_PGLITE_DIR` for development.
- **Valkey** — optional `VALKEY_URL`, `VALKEY_PREFIX` (readiness lists it; the limits in v1 count in-process).
- **Valkey** — optional `VALKEY_URL`, `VALKEY_PREFIX` (readiness lists it; the limits in v1 count in-process).
-- **Packages** — `openvibe-contracts` v0.229.0, `openvibe-sdk` v0.74.0, `openvibe-shared` v4.107.4, the same
+- **Packages** — `openvibe-contracts` v0.229.0, `openvibe-sdk` v0.74.0, `openvibe-shared` v4.108.0, the same
tags OpenVibe.Today pins.
tags OpenVibe.Today pins.
## API
## API
@@ -378,6 +378,6 @@ AGPL-3.0-only. See [LICENSE](LICENSE).
@@ -378,6 +378,6 @@ AGPL-3.0-only. See [LICENSE](LICENSE).
<!-- versions:start -->
<!-- versions:start -->
- openvibe-contracts: v0.234.0
- openvibe-contracts: v0.234.0
- openvibe-sdk: v0.82.0
- openvibe-sdk: v0.82.0
-- openvibe-shared: v4.107.4
+- openvibe-shared: v4.108.0
- openvibe-publishing: v1.5.0
- openvibe-publishing: v1.5.0
<!-- versions:end -->
<!-- versions:end -->
@@ -10,11 +10,11 @@
@@ -10,11 +10,11 @@
"domain": "openvibe.meme",
"domain": "openvibe.meme",
"contracts": "openvibe-contracts v0.234.0",
"contracts": "openvibe-contracts v0.234.0",
"sdk": "openvibe-sdk v0.82.0",
"sdk": "openvibe-sdk v0.82.0",
- "shared": "openvibe-shared v4.107.4",
+ "shared": "openvibe-shared v4.108.0",
"packages": [
"packages": [
"openvibe-contracts v0.234.0",
"openvibe-contracts v0.234.0",
"openvibe-sdk v0.82.0",
"openvibe-sdk v0.82.0",
- "openvibe-shared v4.107.4"
+ "openvibe-shared v4.108.0"
],
],
"summary": "OpenVibe.Meme is the open meme encyclopedia, rebuilt with AI. Internet entries carry an origin citation, spread points, variations, Media examples, meaning, L1 labels, related memes and a moderated revision history; OpenVibe's own running jokes keep the original importer. The importer reads only public Chat and Live APIs and proposes a candidate when a recurring phrase appears in at least two uses on two different days; the candidate is born hidden with a verbatim citation for every use and stays hidden until a staff person publishes it. Every citation is re-verified daily, a 404 marks it gone and an entry whose origin is gone is hidden. People vote once a week for meme of the week, and a caption is plain text over a template, never a rendered image. Trends come from Reddit's official API (no scraping), measured by score samples and perceptual hashes. Every public entry is one Search Fabric document queued in the service's outbox. Deep dives gather sources and fail unless every claim is cited. The generator renders real PNGs from the template's own layout and stores them in Media.",
"summary": "OpenVibe.Meme is the open meme encyclopedia, rebuilt with AI. Internet entries carry an origin citation, spread points, variations, Media examples, meaning, L1 labels, related memes and a moderated revision history; OpenVibe's own running jokes keep the original importer. The importer reads only public Chat and Live APIs and proposes a candidate when a recurring phrase appears in at least two uses on two different days; the candidate is born hidden with a verbatim citation for every use and stays hidden until a staff person publishes it. Every citation is re-verified daily, a 404 marks it gone and an entry whose origin is gone is hidden. People vote once a week for meme of the week, and a caption is plain text over a template, never a rendered image. Trends come from Reddit's official API (no scraping), measured by score samples and perceptual hashes. Every public entry is one Search Fabric document queued in the service's outbox. Deep dives gather sources and fail unless every claim is cited. The generator renders real PNGs from the template's own layout and stores them in Media.",
"works": [
"works": [
@@ -19,7 +19,7 @@
@@ -19,7 +19,7 @@
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.234.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.234.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.5.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.5.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.82.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.82.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.107.4",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.108.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
"sharp": "^0.33.5"
"sharp": "^0.33.5"
},
},
@@ -1694,9 +1694,9 @@
@@ -1694,9 +1694,9 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "4.107.4",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.107.4",
- "integrity": "sha512-tThN0m3KMncEHVcBOvE+ysHjsZTlVIDLG1P+/i2Mulmxfc/AUpebAXhpWWrut50OChZ8o+HeePxsSrPI8mUQOQ==",
+ "version": "4.108.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.108.0",
+ "integrity": "sha512-NPzwjxpzGIpFpIm4uw3+VwHfsxbJ2+cD9yuhRzSwolSwqv2kCmwaVtHJ0DA9gKO3K8PCBfIP3UpKzpuSbYEJ+g==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0",
"jsonwebtoken": "^9.0.0",
@@ -30,7 +30,7 @@
@@ -30,7 +30,7 @@
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.234.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.234.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.5.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.5.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.82.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.82.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.107.4",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.108.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
"sharp": "^0.33.5"
"sharp": "^0.33.5"
},
},
@@ -59,6 +59,10 @@ function createDiscoveryRoutes(ctx) {
@@ -59,6 +59,10 @@ function createDiscoveryRoutes(ctx) {
r.get('/llms.txt', (_req, res) => {
r.get('/llms.txt', (_req, res) => {
res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsTxt({
res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsTxt({
name: SITE_NAME,
name: SITE_NAME,
+ // AGT-5: each of Meme's own pages is linked at its Markdown twin (openvibe-shared 4.108.0 leaves files,
+ // /api/ paths and other sites' links as they are). What an agent may skip is in `optional`, written last.
+ markdown: true,
+ base: site,
summary: 'OpenVibe.Meme is the open meme database, rebuilt with AI. Every public entry cites the moment a running joke happened (a chat line, a VOD second, a Rundown segment), follows its later uses on a timeline, has a status (rising, peaked, classic, dead), and people vote for meme of the week. A caption generator puts plain text lines over a template image.',
summary: 'OpenVibe.Meme is the open meme database, rebuilt with AI. Every public entry cites the moment a running joke happened (a chat line, a VOD second, a Rundown segment), follows its later uses on a timeline, has a status (rising, peaked, classic, dead), and people vote for meme of the week. A caption generator puts plain text lines over a template image.',
details: 'GET /api/v1/entries lists public entries; GET /api/v1/entries/:slug adds every citation and the use timeline; GET /api/v1/entries/:slug/series?days=30 is uses per UTC day. GET /api/v1/week lists this ISO week’s candidates and vote counts. The importer reads only public APIs and never publishes: a candidate stays hidden until a staff person publishes it.',
details: 'GET /api/v1/entries lists public entries; GET /api/v1/entries/:slug adds every citation and the use timeline; GET /api/v1/entries/:slug/series?days=30 is uses per UTC day. GET /api/v1/week lists this ISO week’s candidates and vote counts. The importer reads only public APIs and never publishes: a candidate stays hidden until a staff person publishes it.',
sections: [
sections: [
@@ -70,16 +74,17 @@ function createDiscoveryRoutes(ctx) {
@@ -70,16 +74,17 @@ function createDiscoveryRoutes(ctx) {
] },
] },
{ title: 'Machine-readable', links: [
{ title: 'Machine-readable', links: [
{ title: 'Public entries (JSON)', url: abs('/api/v1/entries') },
{ title: 'Public entries (JSON)', url: abs('/api/v1/entries') },
- { title: 'Sitemap', url: abs('/sitemap.xml') },
- { title: 'Full text for language models', url: abs('/llms-full.txt') },
{ title: 'Release metadata (JSON)', url: abs('/release.json') },
{ title: 'Release metadata (JSON)', url: abs('/release.json') },
] },
] },
- { title: 'Elsewhere', links: [
- { title: 'OpenVibe.Chat', url: 'https://openvibe.chat', note: 'where a running joke is often typed first' },
- { title: 'OpenVibe.Live', url: 'https://openvibe.live', note: 'the Rundown and the VOD transcripts' },
- { title: 'OpenVibe.Video', url: 'https://openvibe.video', note: 'the canonical ?t= moment' },
- { title: 'OpenVibe.Network', url: 'https://openvibe.network', note: 'accounts and staff roles' },
- ] },
+ ],
+ // llmstxt.org's "## Optional": what an agent may skip when it needs a shorter context.
+ optional: [
+ { title: 'Sitemap', url: abs('/sitemap.xml') },
+ { title: 'Full text for language models', url: abs('/llms-full.txt') },
+ { title: 'OpenVibe.Chat', url: 'https://openvibe.chat', note: 'where a running joke is often typed first' },
+ { title: 'OpenVibe.Live', url: 'https://openvibe.live', note: 'the Rundown and the VOD transcripts' },
+ { title: 'OpenVibe.Video', url: 'https://openvibe.video', note: 'the canonical ?t= moment' },
+ { title: 'OpenVibe.Network', url: 'https://openvibe.network', note: 'accounts and staff roles' },
],
],
}));
}));
});
});
@@ -190,6 +190,10 @@ function jsonLd(html) {
@@ -190,6 +190,10 @@ function jsonLd(html) {
const llms = await t.get('/llms.txt');
const llms = await t.get('/llms.txt');
assert.strictEqual(llms.status, 200);
assert.strictEqual(llms.status, 200);
assert.ok(llms.text.includes('OpenVibe.Meme'));
assert.ok(llms.text.includes('OpenVibe.Meme'));
+ // AGT-5: each of Meme's own pages is linked at its Markdown twin, and the secondary links are Optional.
+ assert.ok(llms.text.includes('](https://openvibe.meme/index.md)'), 'the home link is not its twin');
+ assert.ok(llms.text.includes('](https://openvibe.meme/week.md)'), 'the ballot is not its twin');
+ assert.ok(llms.text.includes('\n## Optional\n'), 'no ## Optional section');
});
});
} finally {
} finally {
await t.close();
await t.close();