AGENTS.md@packages/client/src/lib/gateway · git:20260820.cd99caa · 2026-08-20 · sha256 2aa7a7dfe84195c0

AGENTS.md@packages/client/src/lib/gateway git:20260820.cd99caaA

Immutable. This exact content is served forever at /api/v1/blob/2aa7a7dfe84195c0.

# DOX — packages/client/src/lib/gateway

Files in this directory. One row per source file. See change: fold-oversized-agents-directories.

| File | Purpose |
|------|---------|
| `gateway-action.ts` | Pure config algebra for the "add gateway URL" action (D12/D13). Exports `validateGatewayDraft` (scheme drives eligibility: `http://` needs a trusted network and can be neither QR-paired nor OAuth; ≥1 auth mode mandatory), `buildGatewayAddPatch` (ONE patch carrying `publicBaseUrls` + `cors.allowedOrigins` + `auth.redirectBaseUrl` iff oauth + `trustedNetworks` iff trusted-network + the `gateways[]` provenance record — atomicity is structural), `buildGatewayRemovePatch` (reverts only recorded values STILL EQUAL in live config), `computeGatewayStatus` (read-only; trusted networks checked against the EFFECTIVE merge, top-level ∪ `auth.bypassHosts`), `buildGatewayFixPatch` (delta only, never re-runs add), plus the D9 offer layer: `buildGatewayModeOffer`/`isUnregisteredGatewayUrl` and `retainAvailableModes`/`everyModeAvailable` — the offer is recomputed each readiness tick but a checked box is not, so the availability rule lives here, not only in JSX. No I/O. See change: config-override-oauth-redirect-base. |
| `gateway-api.ts` | Client fetch helpers for the Gateway surfaces. Exports `getBlockEvents`, `runEnrollStep`, `getConfig`,… → see `gateway-api.ts.AGENTS.md` |
| `gateway-config-ops.ts` | Pure config-mutation helpers for the Gateway UI. Exports `isSecureBaseUrl`, `appendPublicBaseUrl`… → see `gateway-config-ops.ts.AGENTS.md` `suggestTrustEntries` now reads the SHARED well-known-range table; the module re-exports the reachability predicate for client callers. See change: warn-unreachable-trusted-networks. |
| `gateway-endpoints.ts` | Two-QR transport split + endpoints fetch. Exports `isPairingEligible` (scheme-authoritative, tls tag… → see `gateway-endpoints.ts.AGENTS.md` |
| `gateway-providers.ts` | Client provider matrix metadata. Exports `GatewayProviderId`, `GATEWAY_PROVIDERS` (zrok/ngrok public;… → see `gateway-providers.ts.AGENTS.md` |
| `gateway-setup.ts` | Per-provider setup-step model (D3 taxonomy). Exports `SetupStepKind`… → see `gateway-setup.ts.AGENTS.md` |
| `primary-switch.ts` | Pure D10 layer: `canMakePrimary` (connected AND not already primary — a disconnected promotion mints a redirect URI nobody can reach), `primarySwitchConsequence` (names the redirect-URI re-mint and the sign-in breakage, not just "are you sure"), `buildPrimarySwitchPatch` (writes `tunnel.provider` ONLY — a deep merge must not blank `tunnel.<id>.mode`). See change: add-zrok-custom-reserved-name. |
| `readiness-poll.ts` | Pure poll state machine for the readiness board. `shouldTick`/`onOpen`/`onClose`/`onTickStart`/`onTickResult`/`onTickError`/`secondsSinceCheck`, plus `READINESS_LABEL`/`nextAction`/`readinessSeverity`. Invariant: `onOpen` performs exactly ONE immediate tick, then one every 5s while open; `onClose` stops polling AND clears `inFlight` (otherwise the next open's first tick is suppressed forever); a result landing after close is DISCARDED; a tick starting while one is in flight is suppressed. Every state carries text, never colour alone. See change: add-zrok-custom-reserved-name. |
| `reserved-name.ts` | Pure state for Gateway Setup step 3. `reservedNameStepState` → idle/typing-valid/invalid/taken/write-failed/reserved/replace-confirm; `localValidationError` (states a FIX), `needsReplaceConfirm`, `reservedNameUrl`. `RESERVED_NAME_RE` MIRRORS the server's and is pinned against a verbatim copy — a mirror that disagrees is worse than none. Client check is a latency affordance, never the authority. See change: add-zrok-custom-reserved-name. |