diff --git a/.claude/rules/relay-client.md b/.claude/rules/relay-client.md new file mode 120000 index 0000000..91129a2 --- /dev/null +++ b/.claude/rules/relay-client.md @@ -0,0 +1 @@ +../../docs/guides/relay-client.md \ No newline at end of file diff --git a/.gitignore b/.gitignore index 487a5b5..679e1f6 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,7 @@ ytdlp-cache/ # Local dev secrets .env -# Claude Code state (worktrees, plans, etc.) -.claude/ +# Claude Code state (worktrees, plans, etc.) — but DO track the portable +# rules symlinks so scoped guides lazy-load in any clone. +.claude/* +!.claude/rules/ diff --git a/AGENTS.md b/AGENTS.md index aef0731..92cf5e9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,8 +24,8 @@ Run from repo root unless noted. | Build `.s9pk` (x86) | `make x86` | | Bump version (interactive) | `make bump` | | Install to local StartOS | `make install` *(see Always/Never — bump first; the binary is `start-cli` under the hood)* | -| Lint | TODO — no `lint` script in `server/package.json`. Add one if you want it. | -| Type-check | TODO — there's a top-level `tsconfig.json` but the server is all `.js`. Confirm intent before assuming. | +| Type-check (StartOS TS) | `npm run check` *(repo root; runs `tsc --noEmit` over `startos/**/*.ts`. The `server/` is plain JS and is not type-checked.)* | +| Format (StartOS TS) | `npm run prettier` *(repo root; `prettier --write startos`. There is **no** ESLint/linter — `server/` JS is untooled. Many `startos/versions/*.ts` are currently unformatted.)* | Mode is selected at boot via the `RECAP_MODE` env var: `single` (default) or `multi`. @@ -83,12 +83,7 @@ vendor/keysat-licensing-client/ local-link Keysat SDK ### Client-side contract with the relay -Endpoint shapes + auth model are documented canonically in `../recap-relay/AGENTS.md`. The client side is: - -- **Env vars** — `RECAP_RELAY_BASE_URL` (default `https://relay.recaps.cc`) + `RECAP_RELAY_OPERATOR_KEY` (matches the relay's `relay_cloud_operator_key`). Both gitignored; reference names, never values. Resolved in `server/relay-default.js` and `server/config.js`. -- **Auth direction (what the client SENDS)** — cloud calls send `X-Recap-Operator-Key` + `X-Recap-User-Id`; self-hosted calls send `X-Recap-Install-Id` (+ optional `Authorization: `). Set the same `X-Recap-Job-Id` on transcribe + analyze in one summary so the relay bills one credit, not two. -- **Endpoints called** — `/relay/{transcribe, transcribe-url, jobs/:id, summarize-url, summarize-url/:jobId/events, analyze, tts, balance, capabilities, policy, credits/packages, credits/buy, credits/invoice/:id, user-tier, user-tier/:id, tier-invoice, tier-zaprite-order, tier-plans, expiring-subscriptions}`. Settle webhooks land on the relay side, never here. -- **Files** — `server/providers/relay.js` (transcribe/summarize/analyze/tts + balance + tier reads/writes), `server/relay-capabilities.js` (capabilities poll), `server/billing-routes.js` (tier purchase orchestration), `server/credits-purchase.js` (credit-pack purchase proxy), `server/subscription-reminders.js` (polls `/relay/expiring-subscriptions`). (`/relay/policy` is a small inline proxy in `index.js`.) +The full client-side relay contract — env vars, the `/relay/*` endpoint list, `X-Recap-*` header directions, and the file map — lives in **`docs/guides/relay-client.md`**. Read it before editing `server/providers/relay.js`, `relay-capabilities.js`, `relay-default.js`, `billing-routes.js`, `credits-purchase.js`, `subscription-reminders.js`, or the relay env-var resolution in `config.js`. Canonical endpoint shapes are in `../recap-relay/AGENTS.md`. ### Cross-repo changes (sibling: `../recap-relay`) diff --git a/docs/guides/relay-client.md b/docs/guides/relay-client.md new file mode 100644 index 0000000..5a5aefb --- /dev/null +++ b/docs/guides/relay-client.md @@ -0,0 +1,19 @@ +--- +paths: + - server/providers/relay.js + - server/relay-capabilities.js + - server/relay-default.js + - server/billing-routes.js + - server/credits-purchase.js + - server/subscription-reminders.js + - server/config.js +--- + +# Client-side contract with the relay + +Endpoint shapes + auth model are documented canonically in `../recap-relay/AGENTS.md`. The client side is: + +- **Env vars** — `RECAP_RELAY_BASE_URL` (default `https://relay.recaps.cc`) + `RECAP_RELAY_OPERATOR_KEY` (matches the relay's `relay_cloud_operator_key`). Both gitignored; reference names, never values. Resolved in `server/relay-default.js` and `server/config.js`. +- **Auth direction (what the client SENDS)** — cloud calls send `X-Recap-Operator-Key` + `X-Recap-User-Id`; self-hosted calls send `X-Recap-Install-Id` (+ optional `Authorization: `). Set the same `X-Recap-Job-Id` on transcribe + analyze in one summary so the relay bills one credit, not two. +- **Endpoints called** — `/relay/{transcribe, transcribe-url, jobs/:id, summarize-url, summarize-url/:jobId/events, analyze, tts, balance, capabilities, policy, credits/packages, credits/buy, credits/invoice/:id, user-tier, user-tier/:id, tier-invoice, tier-zaprite-order, tier-plans, expiring-subscriptions}`. Settle webhooks land on the relay side, never here. +- **Files** — `server/providers/relay.js` (transcribe/summarize/analyze/tts + balance + tier reads/writes), `server/relay-capabilities.js` (capabilities poll), `server/billing-routes.js` (tier purchase orchestration), `server/credits-purchase.js` (credit-pack purchase proxy), `server/subscription-reminders.js` (polls `/relay/expiring-subscriptions`). (`/relay/policy` is a small inline proxy in `index.js`.)