openvibers/openvibe.wiki Commits
Adopt openvibe-publishing v1.3.0 and add /llms-full.txt
Changes
@@@ -2,4 +2,5 @@## Unreleased++- `openvibe-publishing` v1.2.0 → v1.3.0: `/llms-full.txt` now publishes the `llms.txt` header plus an excerpt of every indexable page (the same gate as the sitemap, never a whole article) under a 512 KiB cap, and the home page carries the site's one-line `ai-summary` meta and WebPage JSON-LD.- Every page is rendered through `openvibe-publishing/layout` (`openvibe-shared/shell` page()) instead of a local template: the same head tags, stylesheets, feed links, app icon and Frame, with robots still explicit on every page (the gate's decision on an article, a string elsewhere); `openvibe-shared` v2.5.0 → v2.6.0 and `openvibe-publishing` v1.1.0 → v1.2.0, and the JS size budgets rise by the shell's `web-runtime.js` (5 files, 245 KB raw, 59 KB brotli).@@@ -278,7 +278,7 @@ Production: `/opt/openvibe.wiki`, env `/etc/openvibe/wiki.env`, unit- PostgreSQL 18 and Valkey 9 (OpenVibe.Host `roles/data/`, ADR-035): every read and write is async through`openvibe-sdk/db`; Valkey holds the per-actor limit counters (optional: without `VALKEY_URL` they count per process).--- `openvibe-publishing` v1.2.0 (async PostgreSQL stores, ingest and publication chassis), `openvibe-contracts`++- `openvibe-publishing` v1.3.0 (async PostgreSQL stores, ingest and publication chassis), `openvibe-contracts`v0.76.0, `openvibe-shared` v2.6.0(Frame, release, metrics, readiness, SEO helpers, legal pages), `openvibe-sdk` v0.26.0 (db, auth, PostgreSQLevents outbox, per-actor limits, testing) — pinned release tarballs.@@@ -9,7 +9,7 @@"domain": "openvibe.wiki","contracts": "openvibe-contracts v0.76.0","packages": [-- "openvibe-publishing v1.2.0",++ "openvibe-publishing v1.3.0","openvibe-shared v2.6.0","openvibe-sdk v0.26.0"],@@@ -15,7 +15,7 @@"express-rate-limit": "^7.5.0","iovalkey": "^0.4.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",-- "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.2.0",++ "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.3.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.6.0","pg": "^8.23.0"@@@ -92,65 +92,6 @@"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==","license": "MIT"},-- "node_modules/base64-js": {-- "version": "1.5.1",-- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",-- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",-- "funding": [-- {-- "type": "github",-- "url": "https://github.com/sponsors/feross"-- },-- {-- "type": "patreon",-- "url": "https://www.patreon.com/feross"-- },-- {-- "type": "consulting",-- "url": "https://feross.org/support"-- }-- ],-- "license": "MIT",-- "optional": true,-- "peer": true-- },-- "node_modules/better-sqlite3": {-- "version": "11.10.0",-- "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz",-- "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==",-- "hasInstallScript": true,-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "bindings": "^1.5.0",-- "prebuild-install": "^7.1.1"-- }-- },-- "node_modules/bindings": {-- "version": "1.5.0",-- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",-- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "file-uri-to-path": "1.0.0"-- }-- },-- "node_modules/bl": {-- "version": "4.1.0",-- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",-- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "buffer": "^5.5.0",-- "inherits": "^2.0.4",-- "readable-stream": "^3.4.0"-- }-- },"node_modules/body-parser": {"version": "1.20.8","resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.8.tgz",@@@ -175,32 +116,6 @@"npm": "1.2.8000 || >= 1.4.16"}},-- "node_modules/buffer": {-- "version": "5.7.1",-- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",-- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",-- "funding": [-- {-- "type": "github",-- "url": "https://github.com/sponsors/feross"-- },-- {-- "type": "patreon",-- "url": "https://www.patreon.com/feross"-- },-- {-- "type": "consulting",-- "url": "https://feross.org/support"-- }-- ],-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "base64-js": "^1.3.1",-- "ieee754": "^1.1.13"-- }-- },"node_modules/buffer-equal-constant-time": {"version": "1.0.1","resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",@@@ -245,14 +160,6 @@"url": "https://github.com/sponsors/ljharb"}},-- "node_modules/chownr": {-- "version": "1.1.4",-- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",-- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",-- "license": "ISC",-- "optional": true,-- "peer": true-- },"node_modules/cluster-key-slot": {"version": "1.1.2","resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",@@@ -320,34 +227,6 @@"ms": "2.0.0"}},-- "node_modules/decompress-response": {-- "version": "6.0.0",-- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",-- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "mimic-response": "^3.1.0"-- },-- "engines": {-- "node": ">=10"-- },-- "funding": {-- "url": "https://github.com/sponsors/sindresorhus"-- }-- },-- "node_modules/deep-extend": {-- "version": "0.6.0",-- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",-- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "engines": {-- "node": ">=4.0.0"-- }-- },"node_modules/denque": {"version": "2.1.0","resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",@@@ -376,17 +255,6 @@"npm": "1.2.8000 || >= 1.4.16"}},-- "node_modules/detect-libc": {-- "version": "2.1.2",-- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",-- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",-- "license": "Apache-2.0",-- "optional": true,-- "peer": true,-- "engines": {-- "node": ">=8"-- }-- },"node_modules/dotenv": {"version": "16.6.1","resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",@@@ -437,17 +305,6 @@"node": ">= 0.8"}},-- "node_modules/end-of-stream": {-- "version": "1.4.5",-- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",-- "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "once": "^1.4.0"-- }-- },"node_modules/es-define-property": {"version": "1.0.1","resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",@@@ -493,17 +350,6 @@"node": ">= 0.6"}},-- "node_modules/expand-template": {-- "version": "2.0.3",-- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",-- "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",-- "license": "(MIT OR WTFPL)",-- "optional": true,-- "peer": true,-- "engines": {-- "node": ">=6"-- }-- },"node_modules/express": {"version": "4.22.3","resolved": "https://registry.npmjs.org/express/-/express-4.22.3.tgz",@@@ -587,14 +433,6 @@],"license": "BSD-3-Clause"},-- "node_modules/file-uri-to-path": {-- "version": "1.0.0",-- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",-- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",-- "license": "MIT",-- "optional": true,-- "peer": true-- },"node_modules/finalhandler": {"version": "1.3.2","resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",@@@ -631,14 +469,6 @@"node": ">= 0.6"}},-- "node_modules/fs-constants": {-- "version": "1.0.0",-- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",-- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",-- "license": "MIT",-- "optional": true,-- "peer": true-- },"node_modules/function-bind": {"version": "1.1.2","resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",@@@ -685,14 +515,6 @@"node": ">= 0.4"}},-- "node_modules/github-from-package": {-- "version": "0.0.0",-- "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",-- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",-- "license": "MIT",-- "optional": true,-- "peer": true-- },"node_modules/gopd": {"version": "1.2.0","resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",@@@ -761,42 +583,12 @@"node": ">=0.10.0"}},-- "node_modules/ieee754": {-- "version": "1.2.1",-- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",-- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",-- "funding": [-- {-- "type": "github",-- "url": "https://github.com/sponsors/feross"-- },-- {-- "type": "patreon",-- "url": "https://www.patreon.com/feross"-- },-- {-- "type": "consulting",-- "url": "https://feross.org/support"-- }-- ],-- "license": "BSD-3-Clause",-- "optional": true,-- "peer": true-- },"node_modules/inherits": {"version": "2.0.4","resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz","integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==","license": "ISC"},-- "node_modules/ini": {-- "version": "1.3.8",-- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",-- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",-- "license": "ISC",-- "optional": true,-- "peer": true-- },"node_modules/iovalkey": {"version": "0.4.0","resolved": "https://registry.npmjs.org/iovalkey/-/iovalkey-0.4.0.tgz",@@@ -1027,53 +819,12 @@"node": ">= 0.6"}},-- "node_modules/mimic-response": {-- "version": "3.1.0",-- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",-- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "engines": {-- "node": ">=10"-- },-- "funding": {-- "url": "https://github.com/sponsors/sindresorhus"-- }-- },-- "node_modules/minimist": {-- "version": "1.2.8",-- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",-- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "funding": {-- "url": "https://github.com/sponsors/ljharb"-- }-- },-- "node_modules/mkdirp-classic": {-- "version": "0.5.3",-- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",-- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",-- "license": "MIT",-- "optional": true,-- "peer": true-- },"node_modules/ms": {"version": "2.0.0","resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz","integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==","license": "MIT"},-- "node_modules/napi-build-utils": {-- "version": "2.0.0",-- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",-- "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",-- "license": "MIT",-- "optional": true,-- "peer": true-- },"node_modules/negotiator": {"version": "0.6.3","resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",@@@ -1083,20 +834,6 @@"node": ">= 0.6"}},-- "node_modules/node-abi": {-- "version": "3.96.0",-- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.96.0.tgz",-- "integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "semver": "^7.3.5"-- },-- "engines": {-- "node": ">=10"-- }-- },"node_modules/object-inspect": {"version": "1.13.4","resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",@@@ -1121,17 +858,6 @@"node": ">= 0.8"}},-- "node_modules/once": {-- "version": "1.4.0",-- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",-- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",-- "license": "ISC",-- "optional": true,-- "peer": true,-- "dependencies": {-- "wrappy": "1"-- }-- },"node_modules/openvibe-contracts": {"version": "0.76.0","resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",@@@ -1149,9 +875,9 @@}},"node_modules/openvibe-publishing": {-- "version": "1.2.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.2.0",-- "integrity": "sha512-n/20yxXo5jRs0wi7KsR+R9jDkGsoBak3gqElHV6XyU+i1t3XCzaoz+sDb10G2cbc4uEaNB/F09VtQKrQzLp6YQ==",++ "version": "1.3.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.3.0",++ "integrity": "sha512-dIXLK5JpFqUEztywlWgSupUa9NEkovVczR2qeIvpst5evOyKZlwGzQktArvWUQn1ly6CoLL5mn/FnKiqoPvZFA==","license": "MIT","engines": {"node": ">=20"@@@ -1350,35 +1076,6 @@"node": ">=0.10.0"}},-- "node_modules/prebuild-install": {-- "version": "7.1.3",-- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",-- "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",-- "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "detect-libc": "^2.0.0",-- "expand-template": "^2.0.3",-- "github-from-package": "0.0.0",-- "minimist": "^1.2.3",-- "mkdirp-classic": "^0.5.3",-- "napi-build-utils": "^2.0.0",-- "node-abi": "^3.3.0",-- "pump": "^3.0.0",-- "rc": "^1.2.7",-- "simple-get": "^4.0.0",-- "tar-fs": "^2.0.0",-- "tunnel-agent": "^0.6.0"-- },-- "bin": {-- "prebuild-install": "bin.js"-- },-- "engines": {-- "node": ">=10"-- }-- },"node_modules/proxy-addr": {"version": "2.0.8","resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz",@@@ -1396,18 +1093,6 @@"url": "https://opencollective.com/express"}},-- "node_modules/pump": {-- "version": "3.0.4",-- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",-- "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "end-of-stream": "^1.1.0",-- "once": "^1.3.1"-- }-- },"node_modules/qs": {"version": "6.16.0","resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz",@@@ -1448,39 +1133,6 @@"node": ">= 0.8"}},-- "node_modules/rc": {-- "version": "1.2.8",-- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",-- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",-- "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",-- "optional": true,-- "peer": true,-- "dependencies": {-- "deep-extend": "^0.6.0",-- "ini": "~1.3.0",-- "minimist": "^1.2.0",-- "strip-json-comments": "~2.0.1"-- },-- "bin": {-- "rc": "cli.js"-- }-- },-- "node_modules/readable-stream": {-- "version": "3.6.2",-- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",-- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "inherits": "^2.0.3",-- "string_decoder": "^1.1.1",-- "util-deprecate": "^1.0.1"-- },-- "engines": {-- "node": ">= 6"-- }-- },"node_modules/redis-errors": {"version": "1.2.0","resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",@@@ -1672,55 +1324,6 @@"url": "https://github.com/sponsors/ljharb"}},-- "node_modules/simple-concat": {-- "version": "1.0.1",-- "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",-- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",-- "funding": [-- {-- "type": "github",-- "url": "https://github.com/sponsors/feross"-- },-- {-- "type": "patreon",-- "url": "https://www.patreon.com/feross"-- },-- {-- "type": "consulting",-- "url": "https://feross.org/support"-- }-- ],-- "license": "MIT",-- "optional": true,-- "peer": true-- },-- "node_modules/simple-get": {-- "version": "4.0.1",-- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",-- "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",-- "funding": [-- {-- "type": "github",-- "url": "https://github.com/sponsors/feross"-- },-- {-- "type": "patreon",-- "url": "https://www.patreon.com/feross"-- },-- {-- "type": "consulting",-- "url": "https://feross.org/support"-- }-- ],-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "decompress-response": "^6.0.0",-- "once": "^1.3.1",-- "simple-concat": "^1.0.0"-- }-- },"node_modules/split2": {"version": "4.2.0","resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",@@@ -1745,60 +1348,6 @@"node": ">= 0.8"}},-- "node_modules/string_decoder": {-- "version": "1.3.0",-- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",-- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "safe-buffer": "~5.2.0"-- }-- },-- "node_modules/strip-json-comments": {-- "version": "2.0.1",-- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",-- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "engines": {-- "node": ">=0.10.0"-- }-- },-- "node_modules/tar-fs": {-- "version": "2.1.5",-- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz",-- "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "chownr": "^1.1.1",-- "mkdirp-classic": "^0.5.2",-- "pump": "^3.0.0",-- "tar-stream": "^2.1.4"-- }-- },-- "node_modules/tar-stream": {-- "version": "2.2.0",-- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",-- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",-- "license": "MIT",-- "optional": true,-- "peer": true,-- "dependencies": {-- "bl": "^4.0.3",-- "end-of-stream": "^1.4.1",-- "fs-constants": "^1.0.0",-- "inherits": "^2.0.3",-- "readable-stream": "^3.1.1"-- },-- "engines": {-- "node": ">=6"-- }-- },"node_modules/toidentifier": {"version": "1.0.1","resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",@@@ -1808,20 +1357,6 @@"node": ">=0.6"}},-- "node_modules/tunnel-agent": {-- "version": "0.6.0",-- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",-- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",-- "license": "Apache-2.0",-- "optional": true,-- "peer": true,-- "dependencies": {-- "safe-buffer": "^5.0.1"-- },-- "engines": {-- "node": "*"-- }-- },"node_modules/type-is": {"version": "1.6.18","resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",@@@ -1844,14 +1379,6 @@"node": ">= 0.8"}},-- "node_modules/util-deprecate": {-- "version": "1.0.2",-- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",-- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",-- "license": "MIT",-- "optional": true,-- "peer": true-- },"node_modules/utils-merge": {"version": "1.0.1","resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",@@@ -1870,14 +1397,6 @@"node": ">= 0.8"}},-- "node_modules/wrappy": {-- "version": "1.0.2",-- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",-- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",-- "license": "ISC",-- "optional": true,-- "peer": true-- },"node_modules/xtend": {"version": "4.0.2","resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",@@@ -26,7 +26,7 @@"express-rate-limit": "^7.5.0","iovalkey": "^0.4.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",-- "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.2.0",++ "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.3.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.6.0","pg": "^8.23.0"@@@ -8,14 +8,20 @@* /sitemap.xml sitemap index → /sitemaps/spaces.xml, /sitemaps/pages-<n>.xml* /feed.atom recent changes (Atom), /feed.json (JSON Feed 1.1)* /llms.txt orientation for language models++ * /llms-full.txt the same orientation plus an excerpt of every indexable page, bounded*/const express = require('express');const seo = require('openvibe-publishing/seo');const ssr = require('openvibe-publishing/ssr');const sharedSeo = require('openvibe-shared/seo');const cache = require('openvibe-shared/cache-policy');++const { AI_SUMMARY } = require('../render/layout');const PER_SITEMAP = 45000;++// /llms-full.txt is Wiki, so it can be large: the cap must hold, and a page contributes an excerpt++// (its summary, or its opening text), never the whole article.++const LLMS_MAX_BYTES = 512 * 1024;++const LLMS_EXCERPT = 500;function createMachine({ svc, config }) {const router = express.Router();@@@ -97,7 +103,7 @@ function createMachine({ svc, config }) {const spaces = (await svc.listSpaces({ kind: 'anonymous' })).filter((s) => s.visibility === 'public');setCache(res, 3600).type('text/plain').send(sharedSeo.llmsTxt({name: 'OpenVibe.Wiki',-- summary: 'Wiki spaces of the OpenVibe network: page trees, immutable revisions, citations attached to the revision that used them, infoboxes and internal links.',++ summary: AI_SUMMARY,details: 'Every public page has a JSON representation at the same address plus ".json" (same content, same visibility rules). Revision history and diffs are public for public pages. AI-generated revisions are labelled and are published only after a person approves them.',sections: [{ title: 'Spaces', links: spaces.map((s) => ({ title: s.name, url: `${origin}${svc.spacePath(s)}`, note: s.description || '' })) },@@@ -110,6 +116,24 @@ function createMachine({ svc, config }) {}));}));++ /**++ * /llms-full.txt: the llms.txt header, then one section of every indexable page. The same gate++ * as the sitemap decides who is here (a public, published page still unreviewed stays out), and++ * each entry is an excerpt — the page's summary, or its opening text — never the article. The++ * byte cap keeps a large wiki bounded: llmsFull truncates whole entries and says so.++ */++ router.get('/llms-full.txt', wrap(async (_req, res) => {++ const pages = (await svc.publishedPublic()).filter(({ decision }) => decision.indexable).map(({ space, page, rev }) => ({++ title: rev.fields.title,++ url: svc.pageUrl(space, page),++ text: rev.fields.summary || ssr.markdownToText(rev.content, LLMS_EXCERPT),++ }));++ setCache(res, 3600).type('text/plain').send(sharedSeo.llmsFull({++ site: 'OpenVibe.Wiki', summary: AI_SUMMARY, base: origin,++ sections: [{ title: 'Pages', pages }], maxBytes: LLMS_MAX_BYTES,++ }));++ }));++return router;}@@@ -31,7 +31,7 @@ const ovServe = require('openvibe-shared/serve');const cache = require('openvibe-shared/cache-policy');const seo = require('openvibe-publishing/seo');const ssr = require('openvibe-publishing/ssr');--const { renderPage } = require('../render/layout');++const { renderPage, AI_SUMMARY } = require('../render/layout');const views = require('../render/views');const frame = require('openvibe-shared/frame');const showcase = require('openvibe-shared/showcase');@@@ -123,9 +123,11 @@ function createPages({ svc, viewers, platform, config, log = console, limits })router.get('/', wrap(async (req, res) => {if (req.actor.subject) await svc.access.prepareVip(req.actor, (await svc.vipSpaces()).map((space) => ({ space }))); // VIP spaces the viewer may seeconst [spaces, recent] = await Promise.all([svc.listSpaces(req.actor), svc.recentChanges(10)]);++ // The site's one-line AI summary: the shell turns it into the ai-summary meta and the home's++ // WebPage JSON-LD (openvibe-publishing/layout v1.3.0 forwards `summary`).send(req, res, 200, views.home({ spaces, recent, actor: req.actor }) + frame.shipped({ service: 'wiki', title: 'Recently shipped on OpenVibe.Wiki' }), {robots: 'index, follow', cache: 'public', active: 'home', path: '/', styles: [showcase.STYLESHEET],-- jsonLd: seo.structuredData.webPage({ url: `${config.baseUrl}/`, name: 'OpenVibe.Wiki', description: 'Wiki spaces of the OpenVibe network.' }),++ summary: AI_SUMMARY,});}));// What shipped on OpenVibe.Wiki: the shared update log every OpenVibe site has.@@@ -16,6 +16,9 @@ const { escapeHtml: esc } = require('openvibe-publishing/ssr');const SITE_NAME = 'OpenVibe.Wiki';const NETWORK_URL = 'https://openvibe.network';const DEFAULT_DESCRIPTION = 'OpenVibe.Wiki: wiki spaces with page trees, revision history, citations and discussion, part of the OpenVibe network.';++// The one AI summary for the site: /llms.txt and /llms-full.txt publish it, and the home page carries it++// as the shell's ai-summary meta / WebPage JSON-LD (openvibe-publishing/layout forwards `summary`).++const AI_SUMMARY = 'Wiki spaces of the OpenVibe network: page trees, immutable revisions, citations attached to the revision that used them, infoboxes and internal links.';const NAV_LINKS = [{ label: 'Spaces', href: '/' },{ label: 'Recent changes', href: '/recent' },@@@ -60,7 +63,8 @@ function navConfig(o, config) {}/**-- * o: title, description, path (canonical path), robots or decision (one is required: the gate's++ * o: title, description, summary (one line an AI can read, for the shell's ai-summary meta and++ * WebPage JSON-LD), path (canonical path), robots or decision (one is required: the gate's* decision for an article, an explicit string for every other page), head (extra head HTML, added* after the shared tags), jsonLd, ogType, body, active, actor, config, feeds, styles, query*/@@@ -81,6 +85,7 @@ function renderPage(o) {lang: 'en',title: o.title ? `${o.title} · ${SITE_NAME}` : SITE_NAME,description: o.description || DEFAULT_DESCRIPTION,++ summary: o.summary,canonical: `${config.baseUrl}${o.path || '/'}`,decision: o.decision,robots: o.robots,@@@ -102,4 +107,4 @@ function renderPage(o) {});}--module.exports = { renderPage, asset, setRelease, SITE_NAME, DEFAULT_DESCRIPTION, NETWORK_URL, assetVersion };++module.exports = { renderPage, asset, setRelease, SITE_NAME, DEFAULT_DESCRIPTION, AI_SUMMARY, NETWORK_URL, assetVersion };@@@ -74,7 +74,7 @@ const { getPaths, crawl } = require('./security-crawl');const paths = getPaths(h.app, values, {// (Queries use parts of the words: a page may echo its own query back.)query: 'q=ledger&space=vault&revision=2&from=1&to=2',-- extra: ['/sitemap.xml', '/sitemaps/spaces.xml', '/sitemaps/pages-1.xml', '/feed.atom', '/feed.json', '/llms.txt', '/recent', '/updates',++ extra: ['/sitemap.xml', '/sitemaps/spaces.xml', '/sitemaps/pages-1.xml', '/feed.atom', '/feed.json', '/llms.txt', '/llms-full.txt', '/recent', '/updates','/search?q=ledger', '/search?q=private-plans', '/search?q=draft-musings', '/search?q=Hidden+Ledger', '/api/v1/search?q=members-only','/api/v1/search?q=ledger', '/api/v1/search?q=unpublished-revision', '/api/v1/search?q=proposal-secret','/api/v1/spaces', '/s/vault', '/s/open', '/w/open/open-page/history', '/w/open/open-page/diff/1/2', '/w/open/open-page?revision=2',@@@ -48,7 +48,7 @@ const INTERNAL = [const n = (await h.db.prepare('SELECT max(number) AS n FROM wiki_page_revisions WHERE entity_id = ?').get(page.id)).n;try { await h.svc.publish(page.id, { revision: n }, owner); } catch { /* the gate may refuse: fine */ }for (const p of ['/w/refs/cited-page', '/w/refs/cited-page/sources', '/w/refs/cited-page/history', `/api/v1/pages/${page.id}`, `/api/v1/pages/${page.id}/revisions/${n}/citations`,-- `/api/v1/pages/${page.id}/revisions/1/citations`, '/feed.atom', '/feed.json', '/llms.txt', '/sitemaps/pages-1.xml']) {++ `/api/v1/pages/${page.id}/revisions/1/citations`, '/feed.atom', '/feed.json', '/llms.txt', '/llms-full.txt', '/sitemaps/pages-1.xml']) {await H.req(h, 'GET', p, { cookie: H.cookieFor(tok) });await H.req(h, 'GET', p);}@@@ -21,6 +21,8 @@ async function lastIndexEvent(h, pageId) {const cite = [{ url: 'https://example.org/a', retrievedAt: '2026-09-20T00:00:00Z' }];const { page } = await h.svc.createPage(space.id, { title: 'Open page', body: H.LONG, citations: cite }, owner);const other = (await h.svc.createPage(space.id, { title: 'Second page', body: H.LONG, citations: cite }, owner)).page;++ // Public and published, but no citations: listable, not indexable (the gate's unsourced).++ const unsourced = (await h.svc.createPage(space.id, { title: 'Unsourced page', body: H.LONG }, owner)).page;// Draft: not in sitemap, feed or index; direct URL is 404 for anonymous visitors.let r = await H.req(h, 'GET', '/sitemaps/pages-1.xml');@@@ -31,9 +33,21 @@ async function lastIndexEvent(h, pageId) {// Published: sitemap, feeds, index upsert, public cache.await h.svc.publish(page.id, {}, owner);await h.svc.publish(other.id, {}, owner);++ await h.svc.publish(unsourced.id, {}, owner);r = await H.req(h, 'GET', '/sitemaps/pages-1.xml');assert.ok(r.text.includes('http://wiki.test/w/notes/open-page'));++ assert.ok(!r.text.includes('/w/notes/unsourced-page'), 'an unsourced page is noindex: not in the sitemap');assert.ok((await H.req(h, 'GET', '/feed.atom')).text.includes('http://wiki.test/w/notes/open-page'));++ // /llms-full.txt: the llms.txt header, then exactly the indexable pages — the same gate as the++ // sitemap, so a listable-but-noindex page stays out — each an excerpt, under the byte cap.++ r = await H.req(h, 'GET', '/llms-full.txt');++ assert.strictEqual(r.status, 200);++ assert.match(r.headers.get('content-type'), /^text\/plain/);++ assert.strictEqual(r.headers.get('cache-control'), 'public, max-age=3600, stale-while-revalidate=3600');++ assert.ok(r.text.startsWith('# OpenVibe.Wiki') && r.text.includes('> Wiki spaces of the OpenVibe network'), 'the llms.txt header comes first');++ assert.ok(r.text.includes('http://wiki.test/w/notes/open-page') && r.text.includes('http://wiki.test/w/notes/second-page'));++ assert.ok(!r.text.includes('unsourced-page'), 'only indexable pages, not merely listable ones');++ assert.ok(Buffer.byteLength(r.text) <= 512 * 1024, 'the page stays within maxBytes');assert.ok((await H.req(h, 'GET', '/feed.json')).json.items.some((i) => i.url === 'http://wiki.test/w/notes/open-page'));let ev = (await lastIndexEvent(h, page.id));assert.strictEqual(ev.event_type, 'wiki.index_document.upserted');@@@ -57,6 +71,7 @@ async function lastIndexEvent(h, pageId) {assert.ok(!(await H.req(h, 'GET', '/feed.atom')).text.includes('open-page'));assert.ok(!(await H.req(h, 'GET', '/feed.json')).text.includes('open-page'));assert.ok(!(await H.req(h, 'GET', '/llms.txt')).text.includes('open-page'));++ assert.ok(!(await H.req(h, 'GET', '/llms-full.txt')).text.includes('open-page'), 'a private page leaves the AI map too');r = await H.req(h, 'GET', '/w/notes/open-page');assert.strictEqual(r.status, 404);assert.strictEqual(r.headers.get('cache-control'), 'private, no-store');@@@ -134,6 +149,12 @@ async function lastIndexEvent(h, pageId) {r = await H.req(h, 'GET', '/robots.txt');assert.ok(r.text.includes('Sitemap: http://wiki.test/sitemap.xml'));assert.ok(r.text.includes('Disallow: /api/'));++++ // The home carries the site's one-line AI summary: the ai-summary meta and a WebPage JSON-LD.++ r = await H.req(h, 'GET', '/');++ assert.strictEqual(r.status, 200);++ assert.ok(/<meta name="ai-summary" content="[^"]+">/.test(r.text), 'the home has the ai-summary meta');++ assert.ok(r.text.includes('"@type":"WebPage"'), 'and the WebPage JSON-LD');console.log('visibility ok');} finally {await h.stop();
@@ -2,4 +2,5 @@
@@ -2,4 +2,5 @@
## Unreleased
## Unreleased
+- `openvibe-publishing` v1.2.0 → v1.3.0: `/llms-full.txt` now publishes the `llms.txt` header plus an excerpt of every indexable page (the same gate as the sitemap, never a whole article) under a 512 KiB cap, and the home page carries the site's one-line `ai-summary` meta and WebPage JSON-LD.
- Every page is rendered through `openvibe-publishing/layout` (`openvibe-shared/shell` page()) instead of a local template: the same head tags, stylesheets, feed links, app icon and Frame, with robots still explicit on every page (the gate's decision on an article, a string elsewhere); `openvibe-shared` v2.5.0 → v2.6.0 and `openvibe-publishing` v1.1.0 → v1.2.0, and the JS size budgets rise by the shell's `web-runtime.js` (5 files, 245 KB raw, 59 KB brotli).
- Every page is rendered through `openvibe-publishing/layout` (`openvibe-shared/shell` page()) instead of a local template: the same head tags, stylesheets, feed links, app icon and Frame, with robots still explicit on every page (the gate's decision on an article, a string elsewhere); `openvibe-shared` v2.5.0 → v2.6.0 and `openvibe-publishing` v1.1.0 → v1.2.0, and the JS size budgets rise by the shell's `web-runtime.js` (5 files, 245 KB raw, 59 KB brotli).
@@ -278,7 +278,7 @@ Production: `/opt/openvibe.wiki`, env `/etc/openvibe/wiki.env`, unit
@@ -278,7 +278,7 @@ Production: `/opt/openvibe.wiki`, env `/etc/openvibe/wiki.env`, unit
- PostgreSQL 18 and Valkey 9 (OpenVibe.Host `roles/data/`, ADR-035): every read and write is async through
- PostgreSQL 18 and Valkey 9 (OpenVibe.Host `roles/data/`, ADR-035): every read and write is async through
`openvibe-sdk/db`; Valkey holds the per-actor limit counters (optional: without `VALKEY_URL` they count per process).
`openvibe-sdk/db`; Valkey holds the per-actor limit counters (optional: without `VALKEY_URL` they count per process).
-- `openvibe-publishing` v1.2.0 (async PostgreSQL stores, ingest and publication chassis), `openvibe-contracts`
+- `openvibe-publishing` v1.3.0 (async PostgreSQL stores, ingest and publication chassis), `openvibe-contracts`
v0.76.0, `openvibe-shared` v2.6.0
v0.76.0, `openvibe-shared` v2.6.0
(Frame, release, metrics, readiness, SEO helpers, legal pages), `openvibe-sdk` v0.26.0 (db, auth, PostgreSQL
(Frame, release, metrics, readiness, SEO helpers, legal pages), `openvibe-sdk` v0.26.0 (db, auth, PostgreSQL
events outbox, per-actor limits, testing) — pinned release tarballs.
events outbox, per-actor limits, testing) — pinned release tarballs.
@@ -9,7 +9,7 @@
@@ -9,7 +9,7 @@
"domain": "openvibe.wiki",
"domain": "openvibe.wiki",
"contracts": "openvibe-contracts v0.76.0",
"contracts": "openvibe-contracts v0.76.0",
"packages": [
"packages": [
- "openvibe-publishing v1.2.0",
+ "openvibe-publishing v1.3.0",
"openvibe-shared v2.6.0",
"openvibe-shared v2.6.0",
"openvibe-sdk v0.26.0"
"openvibe-sdk v0.26.0"
],
],
@@ -15,7 +15,7 @@
@@ -15,7 +15,7 @@
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
- "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.2.0",
+ "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.3.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.6.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.6.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
@@ -92,65 +92,6 @@
@@ -92,65 +92,6 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT"
"license": "MIT"
},
},
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "optional": true,
- "peer": true
- },
- "node_modules/better-sqlite3": {
- "version": "11.10.0",
- "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz",
- "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "bindings": "^1.5.0",
- "prebuild-install": "^7.1.1"
- }
- },
- "node_modules/bindings": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "file-uri-to-path": "1.0.0"
- }
- },
- "node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
"node_modules/body-parser": {
"node_modules/body-parser": {
"version": "1.20.8",
"version": "1.20.8",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.8.tgz",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.8.tgz",
@@ -175,32 +116,6 @@
@@ -175,32 +116,6 @@
"npm": "1.2.8000 || >= 1.4.16"
"npm": "1.2.8000 || >= 1.4.16"
}
}
},
},
- "node_modules/buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
- }
- },
"node_modules/buffer-equal-constant-time": {
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
@@ -245,14 +160,6 @@
@@ -245,14 +160,6 @@
"url": "https://github.com/sponsors/ljharb"
"url": "https://github.com/sponsors/ljharb"
}
}
},
},
- "node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
- "license": "ISC",
- "optional": true,
- "peer": true
- },
"node_modules/cluster-key-slot": {
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
@@ -320,34 +227,6 @@
@@ -320,34 +227,6 @@
"ms": "2.0.0"
"ms": "2.0.0"
}
}
},
},
- "node_modules/decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "mimic-response": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/denque": {
"node_modules/denque": {
"version": "2.1.0",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
@@ -376,17 +255,6 @@
@@ -376,17 +255,6 @@
"npm": "1.2.8000 || >= 1.4.16"
"npm": "1.2.8000 || >= 1.4.16"
}
}
},
},
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "license": "Apache-2.0",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/dotenv": {
"node_modules/dotenv": {
"version": "16.6.1",
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
@@ -437,17 +305,6 @@
@@ -437,17 +305,6 @@
"node": ">= 0.8"
"node": ">= 0.8"
}
}
},
},
- "node_modules/end-of-stream": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
- "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "once": "^1.4.0"
- }
- },
"node_modules/es-define-property": {
"node_modules/es-define-property": {
"version": "1.0.1",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
@@ -493,17 +350,6 @@
@@ -493,17 +350,6 @@
"node": ">= 0.6"
"node": ">= 0.6"
}
}
},
},
- "node_modules/expand-template": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
- "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
- "license": "(MIT OR WTFPL)",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/express": {
"node_modules/express": {
"version": "4.22.3",
"version": "4.22.3",
"resolved": "https://registry.npmjs.org/express/-/express-4.22.3.tgz",
"resolved": "https://registry.npmjs.org/express/-/express-4.22.3.tgz",
@@ -587,14 +433,6 @@
@@ -587,14 +433,6 @@
],
],
"license": "BSD-3-Clause"
"license": "BSD-3-Clause"
},
},
- "node_modules/file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/finalhandler": {
"node_modules/finalhandler": {
"version": "1.3.2",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
@@ -631,14 +469,6 @@
@@ -631,14 +469,6 @@
"node": ">= 0.6"
"node": ">= 0.6"
}
}
},
},
- "node_modules/fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/function-bind": {
"node_modules/function-bind": {
"version": "1.1.2",
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -685,14 +515,6 @@
@@ -685,14 +515,6 @@
"node": ">= 0.4"
"node": ">= 0.4"
}
}
},
},
- "node_modules/github-from-package": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/gopd": {
"node_modules/gopd": {
"version": "1.2.0",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -761,42 +583,12 @@
@@ -761,42 +583,12 @@
"node": ">=0.10.0"
"node": ">=0.10.0"
}
}
},
},
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "BSD-3-Clause",
- "optional": true,
- "peer": true
- },
"node_modules/inherits": {
"node_modules/inherits": {
"version": "2.0.4",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
"license": "ISC"
},
},
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "license": "ISC",
- "optional": true,
- "peer": true
- },
"node_modules/iovalkey": {
"node_modules/iovalkey": {
"version": "0.4.0",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/iovalkey/-/iovalkey-0.4.0.tgz",
"resolved": "https://registry.npmjs.org/iovalkey/-/iovalkey-0.4.0.tgz",
@@ -1027,53 +819,12 @@
@@ -1027,53 +819,12 @@
"node": ">= 0.6"
"node": ">= 0.6"
}
}
},
},
- "node_modules/mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/mkdirp-classic": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/ms": {
"node_modules/ms": {
"version": "2.0.0",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
"license": "MIT"
},
},
- "node_modules/napi-build-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
- "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/negotiator": {
"node_modules/negotiator": {
"version": "0.6.3",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -1083,20 +834,6 @@
@@ -1083,20 +834,6 @@
"node": ">= 0.6"
"node": ">= 0.6"
}
}
},
},
- "node_modules/node-abi": {
- "version": "3.96.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.96.0.tgz",
- "integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/object-inspect": {
"node_modules/object-inspect": {
"version": "1.13.4",
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
@@ -1121,17 +858,6 @@
@@ -1121,17 +858,6 @@
"node": ">= 0.8"
"node": ">= 0.8"
}
}
},
},
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "optional": true,
- "peer": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
"version": "0.76.0",
"version": "0.76.0",
"resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
"resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
@@ -1149,9 +875,9 @@
@@ -1149,9 +875,9 @@
}
}
},
},
"node_modules/openvibe-publishing": {
"node_modules/openvibe-publishing": {
- "version": "1.2.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.2.0",
- "integrity": "sha512-n/20yxXo5jRs0wi7KsR+R9jDkGsoBak3gqElHV6XyU+i1t3XCzaoz+sDb10G2cbc4uEaNB/F09VtQKrQzLp6YQ==",
+ "version": "1.3.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.3.0",
+ "integrity": "sha512-dIXLK5JpFqUEztywlWgSupUa9NEkovVczR2qeIvpst5evOyKZlwGzQktArvWUQn1ly6CoLL5mn/FnKiqoPvZFA==",
"license": "MIT",
"license": "MIT",
"engines": {
"engines": {
"node": ">=20"
"node": ">=20"
@@ -1350,35 +1076,6 @@
@@ -1350,35 +1076,6 @@
"node": ">=0.10.0"
"node": ">=0.10.0"
}
}
},
},
- "node_modules/prebuild-install": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
- "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
- "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "detect-libc": "^2.0.0",
- "expand-template": "^2.0.3",
- "github-from-package": "0.0.0",
- "minimist": "^1.2.3",
- "mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^2.0.0",
- "node-abi": "^3.3.0",
- "pump": "^3.0.0",
- "rc": "^1.2.7",
- "simple-get": "^4.0.0",
- "tar-fs": "^2.0.0",
- "tunnel-agent": "^0.6.0"
- },
- "bin": {
- "prebuild-install": "bin.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/proxy-addr": {
"node_modules/proxy-addr": {
"version": "2.0.8",
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz",
@@ -1396,18 +1093,6 @@
@@ -1396,18 +1093,6 @@
"url": "https://opencollective.com/express"
"url": "https://opencollective.com/express"
}
}
},
},
- "node_modules/pump": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",
- "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"node_modules/qs": {
"node_modules/qs": {
"version": "6.16.0",
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz",
@@ -1448,39 +1133,6 @@
@@ -1448,39 +1133,6 @@
"node": ">= 0.8"
"node": ">= 0.8"
}
}
},
},
- "node_modules/rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
- "optional": true,
- "peer": true,
- "dependencies": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "bin": {
- "rc": "cli.js"
- }
- },
- "node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/redis-errors": {
"node_modules/redis-errors": {
"version": "1.2.0",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
@@ -1672,55 +1324,6 @@
@@ -1672,55 +1324,6 @@
"url": "https://github.com/sponsors/ljharb"
"url": "https://github.com/sponsors/ljharb"
}
}
},
},
- "node_modules/simple-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "optional": true,
- "peer": true
- },
- "node_modules/simple-get": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
- "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "decompress-response": "^6.0.0",
- "once": "^1.3.1",
- "simple-concat": "^1.0.0"
- }
- },
"node_modules/split2": {
"node_modules/split2": {
"version": "4.2.0",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
@@ -1745,60 +1348,6 @@
@@ -1745,60 +1348,6 @@
"node": ">= 0.8"
"node": ">= 0.8"
}
}
},
},
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tar-fs": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz",
- "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
- }
- },
- "node_modules/tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/toidentifier": {
"node_modules/toidentifier": {
"version": "1.0.1",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -1808,20 +1357,6 @@
@@ -1808,20 +1357,6 @@
"node": ">=0.6"
"node": ">=0.6"
}
}
},
},
- "node_modules/tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "license": "Apache-2.0",
- "optional": true,
- "peer": true,
- "dependencies": {
- "safe-buffer": "^5.0.1"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/type-is": {
"node_modules/type-is": {
"version": "1.6.18",
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -1844,14 +1379,6 @@
@@ -1844,14 +1379,6 @@
"node": ">= 0.8"
"node": ">= 0.8"
}
}
},
},
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/utils-merge": {
"node_modules/utils-merge": {
"version": "1.0.1",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -1870,14 +1397,6 @@
@@ -1870,14 +1397,6 @@
"node": ">= 0.8"
"node": ">= 0.8"
}
}
},
},
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC",
- "optional": true,
- "peer": true
- },
"node_modules/xtend": {
"node_modules/xtend": {
"version": "4.0.2",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -26,7 +26,7 @@
@@ -26,7 +26,7 @@
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"iovalkey": "^0.4.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.76.0",
- "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.2.0",
+ "openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.3.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.6.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.6.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
@@ -8,14 +8,20 @@
@@ -8,14 +8,20 @@
* /sitemap.xml sitemap index → /sitemaps/spaces.xml, /sitemaps/pages-<n>.xml
* /sitemap.xml sitemap index → /sitemaps/spaces.xml, /sitemaps/pages-<n>.xml
* /feed.atom recent changes (Atom), /feed.json (JSON Feed 1.1)
* /feed.atom recent changes (Atom), /feed.json (JSON Feed 1.1)
* /llms.txt orientation for language models
* /llms.txt orientation for language models
+ * /llms-full.txt the same orientation plus an excerpt of every indexable page, bounded
*/
*/
const express = require('express');
const express = require('express');
const seo = require('openvibe-publishing/seo');
const seo = require('openvibe-publishing/seo');
const ssr = require('openvibe-publishing/ssr');
const ssr = require('openvibe-publishing/ssr');
const sharedSeo = require('openvibe-shared/seo');
const sharedSeo = require('openvibe-shared/seo');
const cache = require('openvibe-shared/cache-policy');
const cache = require('openvibe-shared/cache-policy');
+const { AI_SUMMARY } = require('../render/layout');
const PER_SITEMAP = 45000;
const PER_SITEMAP = 45000;
+// /llms-full.txt is Wiki, so it can be large: the cap must hold, and a page contributes an excerpt
+// (its summary, or its opening text), never the whole article.
+const LLMS_MAX_BYTES = 512 * 1024;
+const LLMS_EXCERPT = 500;
function createMachine({ svc, config }) {
function createMachine({ svc, config }) {
const router = express.Router();
const router = express.Router();
@@ -97,7 +103,7 @@ function createMachine({ svc, config }) {
@@ -97,7 +103,7 @@ function createMachine({ svc, config }) {
const spaces = (await svc.listSpaces({ kind: 'anonymous' })).filter((s) => s.visibility === 'public');
const spaces = (await svc.listSpaces({ kind: 'anonymous' })).filter((s) => s.visibility === 'public');
setCache(res, 3600).type('text/plain').send(sharedSeo.llmsTxt({
setCache(res, 3600).type('text/plain').send(sharedSeo.llmsTxt({
name: 'OpenVibe.Wiki',
name: 'OpenVibe.Wiki',
- summary: 'Wiki spaces of the OpenVibe network: page trees, immutable revisions, citations attached to the revision that used them, infoboxes and internal links.',
+ summary: AI_SUMMARY,
details: 'Every public page has a JSON representation at the same address plus ".json" (same content, same visibility rules). Revision history and diffs are public for public pages. AI-generated revisions are labelled and are published only after a person approves them.',
details: 'Every public page has a JSON representation at the same address plus ".json" (same content, same visibility rules). Revision history and diffs are public for public pages. AI-generated revisions are labelled and are published only after a person approves them.',
sections: [
sections: [
{ title: 'Spaces', links: spaces.map((s) => ({ title: s.name, url: `${origin}${svc.spacePath(s)}`, note: s.description || '' })) },
{ title: 'Spaces', links: spaces.map((s) => ({ title: s.name, url: `${origin}${svc.spacePath(s)}`, note: s.description || '' })) },
@@ -110,6 +116,24 @@ function createMachine({ svc, config }) {
@@ -110,6 +116,24 @@ function createMachine({ svc, config }) {
}));
}));
}));
}));
+ /**
+ * /llms-full.txt: the llms.txt header, then one section of every indexable page. The same gate
+ * as the sitemap decides who is here (a public, published page still unreviewed stays out), and
+ * each entry is an excerpt — the page's summary, or its opening text — never the article. The
+ * byte cap keeps a large wiki bounded: llmsFull truncates whole entries and says so.
+ */
+ router.get('/llms-full.txt', wrap(async (_req, res) => {
+ const pages = (await svc.publishedPublic()).filter(({ decision }) => decision.indexable).map(({ space, page, rev }) => ({
+ title: rev.fields.title,
+ url: svc.pageUrl(space, page),
+ text: rev.fields.summary || ssr.markdownToText(rev.content, LLMS_EXCERPT),
+ }));
+ setCache(res, 3600).type('text/plain').send(sharedSeo.llmsFull({
+ site: 'OpenVibe.Wiki', summary: AI_SUMMARY, base: origin,
+ sections: [{ title: 'Pages', pages }], maxBytes: LLMS_MAX_BYTES,
+ }));
+ }));
+
return router;
return router;
}
}
@@ -31,7 +31,7 @@ const ovServe = require('openvibe-shared/serve');
@@ -31,7 +31,7 @@ const ovServe = require('openvibe-shared/serve');
const cache = require('openvibe-shared/cache-policy');
const cache = require('openvibe-shared/cache-policy');
const seo = require('openvibe-publishing/seo');
const seo = require('openvibe-publishing/seo');
const ssr = require('openvibe-publishing/ssr');
const ssr = require('openvibe-publishing/ssr');
-const { renderPage } = require('../render/layout');
+const { renderPage, AI_SUMMARY } = require('../render/layout');
const views = require('../render/views');
const views = require('../render/views');
const frame = require('openvibe-shared/frame');
const frame = require('openvibe-shared/frame');
const showcase = require('openvibe-shared/showcase');
const showcase = require('openvibe-shared/showcase');
@@ -123,9 +123,11 @@ function createPages({ svc, viewers, platform, config, log = console, limits })
@@ -123,9 +123,11 @@ function createPages({ svc, viewers, platform, config, log = console, limits })
router.get('/', wrap(async (req, res) => {
router.get('/', wrap(async (req, res) => {
if (req.actor.subject) await svc.access.prepareVip(req.actor, (await svc.vipSpaces()).map((space) => ({ space }))); // VIP spaces the viewer may see
if (req.actor.subject) await svc.access.prepareVip(req.actor, (await svc.vipSpaces()).map((space) => ({ space }))); // VIP spaces the viewer may see
const [spaces, recent] = await Promise.all([svc.listSpaces(req.actor), svc.recentChanges(10)]);
const [spaces, recent] = await Promise.all([svc.listSpaces(req.actor), svc.recentChanges(10)]);
+ // The site's one-line AI summary: the shell turns it into the ai-summary meta and the home's
+ // WebPage JSON-LD (openvibe-publishing/layout v1.3.0 forwards `summary`).
send(req, res, 200, views.home({ spaces, recent, actor: req.actor }) + frame.shipped({ service: 'wiki', title: 'Recently shipped on OpenVibe.Wiki' }), {
send(req, res, 200, views.home({ spaces, recent, actor: req.actor }) + frame.shipped({ service: 'wiki', title: 'Recently shipped on OpenVibe.Wiki' }), {
robots: 'index, follow', cache: 'public', active: 'home', path: '/', styles: [showcase.STYLESHEET],
robots: 'index, follow', cache: 'public', active: 'home', path: '/', styles: [showcase.STYLESHEET],
- jsonLd: seo.structuredData.webPage({ url: `${config.baseUrl}/`, name: 'OpenVibe.Wiki', description: 'Wiki spaces of the OpenVibe network.' }),
+ summary: AI_SUMMARY,
});
});
}));
}));
// What shipped on OpenVibe.Wiki: the shared update log every OpenVibe site has.
// What shipped on OpenVibe.Wiki: the shared update log every OpenVibe site has.
@@ -16,6 +16,9 @@ const { escapeHtml: esc } = require('openvibe-publishing/ssr');
@@ -16,6 +16,9 @@ const { escapeHtml: esc } = require('openvibe-publishing/ssr');
const SITE_NAME = 'OpenVibe.Wiki';
const SITE_NAME = 'OpenVibe.Wiki';
const NETWORK_URL = 'https://openvibe.network';
const NETWORK_URL = 'https://openvibe.network';
const DEFAULT_DESCRIPTION = 'OpenVibe.Wiki: wiki spaces with page trees, revision history, citations and discussion, part of the OpenVibe network.';
const DEFAULT_DESCRIPTION = 'OpenVibe.Wiki: wiki spaces with page trees, revision history, citations and discussion, part of the OpenVibe network.';
+// The one AI summary for the site: /llms.txt and /llms-full.txt publish it, and the home page carries it
+// as the shell's ai-summary meta / WebPage JSON-LD (openvibe-publishing/layout forwards `summary`).
+const AI_SUMMARY = 'Wiki spaces of the OpenVibe network: page trees, immutable revisions, citations attached to the revision that used them, infoboxes and internal links.';
const NAV_LINKS = [
const NAV_LINKS = [
{ label: 'Spaces', href: '/' },
{ label: 'Spaces', href: '/' },
{ label: 'Recent changes', href: '/recent' },
{ label: 'Recent changes', href: '/recent' },
@@ -60,7 +63,8 @@ function navConfig(o, config) {
@@ -60,7 +63,8 @@ function navConfig(o, config) {
}
}
/**
/**
- * o: title, description, path (canonical path), robots or decision (one is required: the gate's
+ * o: title, description, summary (one line an AI can read, for the shell's ai-summary meta and
+ * WebPage JSON-LD), path (canonical path), robots or decision (one is required: the gate's
* decision for an article, an explicit string for every other page), head (extra head HTML, added
* decision for an article, an explicit string for every other page), head (extra head HTML, added
* after the shared tags), jsonLd, ogType, body, active, actor, config, feeds, styles, query
* after the shared tags), jsonLd, ogType, body, active, actor, config, feeds, styles, query
*/
*/
@@ -81,6 +85,7 @@ function renderPage(o) {
@@ -81,6 +85,7 @@ function renderPage(o) {
lang: 'en',
lang: 'en',
title: o.title ? `${o.title} · ${SITE_NAME}` : SITE_NAME,
title: o.title ? `${o.title} · ${SITE_NAME}` : SITE_NAME,
description: o.description || DEFAULT_DESCRIPTION,
description: o.description || DEFAULT_DESCRIPTION,
+ summary: o.summary,
canonical: `${config.baseUrl}${o.path || '/'}`,
canonical: `${config.baseUrl}${o.path || '/'}`,
decision: o.decision,
decision: o.decision,
robots: o.robots,
robots: o.robots,
@@ -102,4 +107,4 @@ function renderPage(o) {
@@ -102,4 +107,4 @@ function renderPage(o) {
});
});
}
}
-module.exports = { renderPage, asset, setRelease, SITE_NAME, DEFAULT_DESCRIPTION, NETWORK_URL, assetVersion };
+module.exports = { renderPage, asset, setRelease, SITE_NAME, DEFAULT_DESCRIPTION, AI_SUMMARY, NETWORK_URL, assetVersion };
@@ -74,7 +74,7 @@ const { getPaths, crawl } = require('./security-crawl');
@@ -74,7 +74,7 @@ const { getPaths, crawl } = require('./security-crawl');
const paths = getPaths(h.app, values, {
const paths = getPaths(h.app, values, {
// (Queries use parts of the words: a page may echo its own query back.)
// (Queries use parts of the words: a page may echo its own query back.)
query: 'q=ledger&space=vault&revision=2&from=1&to=2',
query: 'q=ledger&space=vault&revision=2&from=1&to=2',
- extra: ['/sitemap.xml', '/sitemaps/spaces.xml', '/sitemaps/pages-1.xml', '/feed.atom', '/feed.json', '/llms.txt', '/recent', '/updates',
+ extra: ['/sitemap.xml', '/sitemaps/spaces.xml', '/sitemaps/pages-1.xml', '/feed.atom', '/feed.json', '/llms.txt', '/llms-full.txt', '/recent', '/updates',
'/search?q=ledger', '/search?q=private-plans', '/search?q=draft-musings', '/search?q=Hidden+Ledger', '/api/v1/search?q=members-only',
'/search?q=ledger', '/search?q=private-plans', '/search?q=draft-musings', '/search?q=Hidden+Ledger', '/api/v1/search?q=members-only',
'/api/v1/search?q=ledger', '/api/v1/search?q=unpublished-revision', '/api/v1/search?q=proposal-secret',
'/api/v1/search?q=ledger', '/api/v1/search?q=unpublished-revision', '/api/v1/search?q=proposal-secret',
'/api/v1/spaces', '/s/vault', '/s/open', '/w/open/open-page/history', '/w/open/open-page/diff/1/2', '/w/open/open-page?revision=2',
'/api/v1/spaces', '/s/vault', '/s/open', '/w/open/open-page/history', '/w/open/open-page/diff/1/2', '/w/open/open-page?revision=2',
@@ -48,7 +48,7 @@ const INTERNAL = [
@@ -48,7 +48,7 @@ const INTERNAL = [
const n = (await h.db.prepare('SELECT max(number) AS n FROM wiki_page_revisions WHERE entity_id = ?').get(page.id)).n;
const n = (await h.db.prepare('SELECT max(number) AS n FROM wiki_page_revisions WHERE entity_id = ?').get(page.id)).n;
try { await h.svc.publish(page.id, { revision: n }, owner); } catch { /* the gate may refuse: fine */ }
try { await h.svc.publish(page.id, { revision: n }, owner); } catch { /* the gate may refuse: fine */ }
for (const p of ['/w/refs/cited-page', '/w/refs/cited-page/sources', '/w/refs/cited-page/history', `/api/v1/pages/${page.id}`, `/api/v1/pages/${page.id}/revisions/${n}/citations`,
for (const p of ['/w/refs/cited-page', '/w/refs/cited-page/sources', '/w/refs/cited-page/history', `/api/v1/pages/${page.id}`, `/api/v1/pages/${page.id}/revisions/${n}/citations`,
- `/api/v1/pages/${page.id}/revisions/1/citations`, '/feed.atom', '/feed.json', '/llms.txt', '/sitemaps/pages-1.xml']) {
+ `/api/v1/pages/${page.id}/revisions/1/citations`, '/feed.atom', '/feed.json', '/llms.txt', '/llms-full.txt', '/sitemaps/pages-1.xml']) {
await H.req(h, 'GET', p, { cookie: H.cookieFor(tok) });
await H.req(h, 'GET', p, { cookie: H.cookieFor(tok) });
await H.req(h, 'GET', p);
await H.req(h, 'GET', p);
}
}
@@ -21,6 +21,8 @@ async function lastIndexEvent(h, pageId) {
@@ -21,6 +21,8 @@ async function lastIndexEvent(h, pageId) {
const cite = [{ url: 'https://example.org/a', retrievedAt: '2026-09-20T00:00:00Z' }];
const cite = [{ url: 'https://example.org/a', retrievedAt: '2026-09-20T00:00:00Z' }];
const { page } = await h.svc.createPage(space.id, { title: 'Open page', body: H.LONG, citations: cite }, owner);
const { page } = await h.svc.createPage(space.id, { title: 'Open page', body: H.LONG, citations: cite }, owner);
const other = (await h.svc.createPage(space.id, { title: 'Second page', body: H.LONG, citations: cite }, owner)).page;
const other = (await h.svc.createPage(space.id, { title: 'Second page', body: H.LONG, citations: cite }, owner)).page;
+ // Public and published, but no citations: listable, not indexable (the gate's unsourced).
+ const unsourced = (await h.svc.createPage(space.id, { title: 'Unsourced page', body: H.LONG }, owner)).page;
// Draft: not in sitemap, feed or index; direct URL is 404 for anonymous visitors.
// Draft: not in sitemap, feed or index; direct URL is 404 for anonymous visitors.
let r = await H.req(h, 'GET', '/sitemaps/pages-1.xml');
let r = await H.req(h, 'GET', '/sitemaps/pages-1.xml');
@@ -31,9 +33,21 @@ async function lastIndexEvent(h, pageId) {
@@ -31,9 +33,21 @@ async function lastIndexEvent(h, pageId) {
// Published: sitemap, feeds, index upsert, public cache.
// Published: sitemap, feeds, index upsert, public cache.
await h.svc.publish(page.id, {}, owner);
await h.svc.publish(page.id, {}, owner);
await h.svc.publish(other.id, {}, owner);
await h.svc.publish(other.id, {}, owner);
+ await h.svc.publish(unsourced.id, {}, owner);
r = await H.req(h, 'GET', '/sitemaps/pages-1.xml');
r = await H.req(h, 'GET', '/sitemaps/pages-1.xml');
assert.ok(r.text.includes('http://wiki.test/w/notes/open-page'));
assert.ok(r.text.includes('http://wiki.test/w/notes/open-page'));
+ assert.ok(!r.text.includes('/w/notes/unsourced-page'), 'an unsourced page is noindex: not in the sitemap');
assert.ok((await H.req(h, 'GET', '/feed.atom')).text.includes('http://wiki.test/w/notes/open-page'));
assert.ok((await H.req(h, 'GET', '/feed.atom')).text.includes('http://wiki.test/w/notes/open-page'));
+ // /llms-full.txt: the llms.txt header, then exactly the indexable pages — the same gate as the
+ // sitemap, so a listable-but-noindex page stays out — each an excerpt, under the byte cap.
+ r = await H.req(h, 'GET', '/llms-full.txt');
+ assert.strictEqual(r.status, 200);
+ assert.match(r.headers.get('content-type'), /^text\/plain/);
+ assert.strictEqual(r.headers.get('cache-control'), 'public, max-age=3600, stale-while-revalidate=3600');
+ assert.ok(r.text.startsWith('# OpenVibe.Wiki') && r.text.includes('> Wiki spaces of the OpenVibe network'), 'the llms.txt header comes first');
+ assert.ok(r.text.includes('http://wiki.test/w/notes/open-page') && r.text.includes('http://wiki.test/w/notes/second-page'));
+ assert.ok(!r.text.includes('unsourced-page'), 'only indexable pages, not merely listable ones');
+ assert.ok(Buffer.byteLength(r.text) <= 512 * 1024, 'the page stays within maxBytes');
assert.ok((await H.req(h, 'GET', '/feed.json')).json.items.some((i) => i.url === 'http://wiki.test/w/notes/open-page'));
assert.ok((await H.req(h, 'GET', '/feed.json')).json.items.some((i) => i.url === 'http://wiki.test/w/notes/open-page'));
let ev = (await lastIndexEvent(h, page.id));
let ev = (await lastIndexEvent(h, page.id));
assert.strictEqual(ev.event_type, 'wiki.index_document.upserted');
assert.strictEqual(ev.event_type, 'wiki.index_document.upserted');
@@ -57,6 +71,7 @@ async function lastIndexEvent(h, pageId) {
@@ -57,6 +71,7 @@ async function lastIndexEvent(h, pageId) {
assert.ok(!(await H.req(h, 'GET', '/feed.atom')).text.includes('open-page'));
assert.ok(!(await H.req(h, 'GET', '/feed.atom')).text.includes('open-page'));
assert.ok(!(await H.req(h, 'GET', '/feed.json')).text.includes('open-page'));
assert.ok(!(await H.req(h, 'GET', '/feed.json')).text.includes('open-page'));
assert.ok(!(await H.req(h, 'GET', '/llms.txt')).text.includes('open-page'));
assert.ok(!(await H.req(h, 'GET', '/llms.txt')).text.includes('open-page'));
+ assert.ok(!(await H.req(h, 'GET', '/llms-full.txt')).text.includes('open-page'), 'a private page leaves the AI map too');
r = await H.req(h, 'GET', '/w/notes/open-page');
r = await H.req(h, 'GET', '/w/notes/open-page');
assert.strictEqual(r.status, 404);
assert.strictEqual(r.status, 404);
assert.strictEqual(r.headers.get('cache-control'), 'private, no-store');
assert.strictEqual(r.headers.get('cache-control'), 'private, no-store');
@@ -134,6 +149,12 @@ async function lastIndexEvent(h, pageId) {
@@ -134,6 +149,12 @@ async function lastIndexEvent(h, pageId) {
r = await H.req(h, 'GET', '/robots.txt');
r = await H.req(h, 'GET', '/robots.txt');
assert.ok(r.text.includes('Sitemap: http://wiki.test/sitemap.xml'));
assert.ok(r.text.includes('Sitemap: http://wiki.test/sitemap.xml'));
assert.ok(r.text.includes('Disallow: /api/'));
assert.ok(r.text.includes('Disallow: /api/'));
+
+ // The home carries the site's one-line AI summary: the ai-summary meta and a WebPage JSON-LD.
+ r = await H.req(h, 'GET', '/');
+ assert.strictEqual(r.status, 200);
+ assert.ok(/<meta name="ai-summary" content="[^"]+">/.test(r.text), 'the home has the ai-summary meta');
+ assert.ok(r.text.includes('"@type":"WebPage"'), 'and the WebPage JSON-LD');
console.log('visibility ok');
console.log('visibility ok');
} finally {
} finally {
await h.stop();
await h.stop();