openvibers/openvibe.examples AGENTS.md
AGENTS.md
| 1 | # AGENTS.md — OpenVibe.Examples |
| 2 | |
| 3 | ## Project overview |
| 4 | |
| 5 | Executable, copyable public integration examples for the OpenVibe platform: the SDK, scoped developer-app |
| 6 | credentials and public APIs, **nothing else**. Each example is small, runs on its own and proves one thing |
| 7 | with a smoke test. **MIT**, so any example can be copied into a developer's own project (the services |
| 8 | themselves are AGPL-3.0). |
| 9 | |
| 10 | - There is **no service here**: no unit, port, env file or package publish, and nothing is deployed from |
| 11 | this repository. CI runs `npm test` and the developer-path check against the SDK's mock platform. |
| 12 | - Pin at this release: `openvibe-sdk` v0.150.0 (a dev dependency; `openvibe-contracts` v0.410.0 for the |
| 13 | mod manifest), Node 22.22.1 in CI. |
| 14 | |
| 15 | ## What it owns |
| 16 | |
| 17 | - Eighteen examples, each with `README.md`, `.env.example`, `package.json`, code and |
| 18 | `test/smoke.test.js`: |
| 19 | - the nine charter ones: `browser-app`, `node-server-app`, `webhook-consumer`, `event-subscriber`, |
| 20 | `media-uploader`, `chat-bot`, `tool-job`, `mod-manifest`, `oauth-app`; |
| 21 | - and `ai-chat`, `go-live`, `zone-s3`, `space-deploy`, `inventory-wear`, `game-scores`, |
| 22 | `developer-path`-style walkthroughs and the newer app examples listed in the README table. |
| 23 | - The on-demand end-to-end run (`npm run e2e`: Media, Events pull, a Tools job against the real platform |
| 24 | with the developer's own sandbox app) and the sandbox-app setup (`npm run new-app`). |
| 25 | - The Wave 20 exit check: `npm run developer-path` against the real platform and |
| 26 | `npm run developer-path:mock` against the mock (CI). |
| 27 | - The repository checks: `test/public-surface.test.js`, `test/structure.test.js`, |
| 28 | `test/create-app.test.js`, `test/developer-path.test.js`, `test/tools-job-proof.test.js`. |
| 29 | |
| 30 | Not owned: any platform service, the SDK (OpenVibe.SDK), the contracts (OpenVibe.Contracts) or the |
| 31 | developer console (OpenVibe.Services). |
| 32 | |
| 33 | ## What each example proves (short) |
| 34 | |
| 35 | | Example | Proves | |
| 36 | |---|---| |
| 37 | | `browser-app` | a no-build page imports the SDK browser bundle, reads the registry cross-origin and signs in with PKCE (a public app needs no secret) | |
| 38 | | `node-server-app` | client-credentials app token per audience, registry discovery, contracts version, trace propagation | |
| 39 | | `media-uploader` | upload/read/delete in the project's Media tenant; sandbox files get signed URLs | |
| 40 | | `event-subscriber` | publish to `app.<project_key>.*`, pull with a durable cursor, gaps; anonymous realtime for public events | |
| 41 | | `webhook-consumer` | an app subscription, `X-OpenVibe-Signature-V2` (±300 s), exactly-once inbox, secret rotation | |
| 42 | | `tool-job` | a Tools job submitted once (idempotency key), reattached after restart, SSE resumed | |
| 43 | | `oauth-app` | authorization code + PKCE for a confidential app, server exchange, offline token checks | |
| 44 | | `chat-bot` | Chat's `/ws/chat` protocol, one configured room, always a bot (no app principal yet) | |
| 45 | | `mod-manifest` | a `mods.mod-manifest@1` validated against schema, catalog and compatibility | |
| 46 | | `go-live` | a Live API token finds/creates a WHIP slot; FFmpeg 8+ publishes; the stream key is never printed | |
| 47 | | `game-scores` | Play achievements/leaderboard from a sandbox app, idempotent round | |
| 48 | | `inventory-wear` | public catalog + who wears what, 100 per call, no token | |
| 49 | | `space-deploy` | Space deploy+rollback from CI with an app token | |
| 50 | | `zone-s3` | Zone's S3 surface with AWS SDK v3, scoped access key, presigned share ≤7 days | |
| 51 | |
| 52 | ## Repository map |
| 53 | |
| 54 | - [examples/](examples/) — one directory per example; each has `README.md`, `.env.example`, |
| 55 | `package.json`, source and `test/smoke.test.js`. |
| 56 | - [scripts/e2e.js](scripts/e2e.js) — on demand only, real platform. |
| 57 | - [scripts/developer-path.js](scripts/developer-path.js) — the real exit check; |
| 58 | [scripts/developer-path-mock.js](scripts/developer-path-mock.js) — the same against the mock (CI). |
| 59 | - [scripts/new-sandbox-app.js](scripts/new-sandbox-app.js) — project + sandbox app + grants. |
| 60 | - [scripts/tools-job-proof.js](scripts/tools-job-proof.js) — the Tools job proof. |
| 61 | - [test/run.js](test/run.js) — runs every example's smoke test plus the repository checks. |
| 62 | - [test/public-surface.test.js](test/public-surface.test.js), [test/structure.test.js](test/structure.test.js). |
| 63 | - [.github/workflows/ci.yml](.github/workflows/ci.yml) — Node 22.22.1, `npm test`, the mock developer path. |
| 64 | |
| 65 | ## Commands |
| 66 | |
| 67 | ```bash |
| 68 | fnm use 22.22.1 # or any Node 22 |
| 69 | npm ci # one install for all examples (npm workspaces) |
| 70 | npm test # every smoke test + repository checks, no network |
| 71 | npm test -- chat oauth # only names containing a word; --strict makes a skip fail |
| 72 | npm run e2e # three examples against the real platform (needs .env/sandbox app) |
| 73 | npm run new-app # create a project + sandbox app + grants |
| 74 | npm run developer-path # the Wave 20 exit check against the real platform |
| 75 | npm run developer-path:mock # the same against the mock (what CI runs) |
| 76 | ov test # the harness's sharded run of what the change reaches |
| 77 | ``` |
| 78 | |
| 79 | ## How the tests stay offline |
| 80 | |
| 81 | `npm test` runs each example's smoke test against `openvibe-sdk/testing`'s `createMockPlatform()`: an |
| 82 | in-process fake at the real public origins with real RS256 tokens, developer apps/projects, sandbox |
| 83 | handling per service, `/oauth/authorize` with auto-consent, retention gaps (`pruneEvents()`), a delivery |
| 84 | worker and Tools jobs with SSE. The mock plays the developer-app rules as production does (own-project |
| 85 | events topics, Media project tenants, sandbox URLs). Chat is the one service the SDK does not mock, so |
| 86 | `chat-bot` ships `test/mock-chat-server.js`. Every smoke test replaces the global `fetch` with one that |
| 87 | throws, so an accidental network call fails the test. |
| 88 | |
| 89 | ## Conventions |
| 90 | |
| 91 | - The public surface only: `openvibe-sdk`, scoped developer-app credentials and public APIs. **Never** a |
| 92 | first-party loopback key, a first-party database, an internal header or a service token. |
| 93 | - One example proves one thing; its smoke test asserts the observable result, including the refusal cases. |
| 94 | - No build step: the browser example loads the SDK bundle directly; Node examples run as written. |
| 95 | - No secret in the repository or the tests; `.env.example` names variables only, and a test never prints a |
| 96 | token or a key. |
| 97 | - MIT header stays; a copy of an example into another project must keep working. |
| 98 | |
| 99 | ## Pitfalls |
| 100 | |
| 101 | - **A first-party shortcut invalidates the example.** If it needs an internal first-party key header, a |
| 102 | loopback URL, a database or a service token, it is not an example of the public platform. |
| 103 | - **Production apps need staff in some cases:** switching a project to `sandbox+production` and setting |
| 104 | its allowance is an operator step; a sandbox app cannot do it. |
| 105 | - **Chat has no app principal yet.** `chat.message.send` is first-party, so `chat-bot` uses a dedicated |
| 106 | bot's Live `hbt_` token, not a developer app. Do not present it as an app-token flow. |
| 107 | - **No refresh tokens and no profile:** a Network app token lasts 5 minutes and the app learns only the |
| 108 | person's `usr_…` id; `identity.subject.resolve` is first-party. Design the example around that. |
| 109 | - **`/oauth/token` is not CORS-open**, so a browser exchanges the code on its own server (`browser-app` |
| 110 | does). |
| 111 | - **Publishing a mod into Games is not public** (`games.mod.manage` is first-party); the manifest example |
| 112 | validates, it does not publish. |
| 113 | - **`npm test` must stay offline.** The mock's `fetch`-throws guard is the enforcement; do not add a test |
| 114 | that reaches the network. |
| 115 | - **`npm run e2e` is not part of CI** and needs real sandbox credentials; do not make it a required check. |
| 116 | - **Version drift is real:** the README's "Built on" lines can lag `package.json` (SDK v0.150.0 now). Trust |
| 117 | `package.json`/the lockfile for what runs. |
| 118 | |
| 119 | ## Documentation |
| 120 | |
| 121 | - [README.md](README.md) — the example table, starting a new app, the end-to-end walkthrough, how the |
| 122 | platform works for a sandbox app, the developer path, what still does not work, running tests, layout. |
| 123 | - Each [examples/<name>/README.md](examples/) — the example's own setup and claims. |
| 124 | - [SECURITY.md](SECURITY.md), [STATUS.json](STATUS.json). |
| 125 | - The SDK is OpenVibe.SDK; the platform docs are at https://openvibe.services. |
| 126 |