Skip to content

Latest commit

 

History

History
63 lines (43 loc) · 5.82 KB

File metadata and controls

63 lines (43 loc) · 5.82 KB

AGENTS.md

Core Priorities

  1. Performance first.
  2. Reliability first.
  3. Keep behavior predictable under load and during failures (session restarts, reconnects, partial streams).

If a tradeoff is required, choose correctness and robustness over short-term convenience.

Repository Layout

  • opennow-stable/ is the Electron app. Main-process code lives in src/main, preload bridges in src/preload, renderer UI in src/renderer, and cross-process TypeScript contracts in src/shared.
  • native/ contains the native streamer implementation and build outputs used by the Electron app. Keep native build changes isolated from Electron refactors unless the task explicitly spans both.
  • locales/ contains localization sources and generated Crowdin output. See Localization before editing.
  • OpenNOW-Site/ is a separate repository when present; do not modify it from OpenNOW tasks unless explicitly requested.

Module Boundaries

  • Shared GFN main-process protocol details belong under opennow-stable/src/main/gfn. Prefer focused modules with one owner per concern (clientHeaders.ts for client identity/header constants, proxyFetch.ts for proxy-aware fetches, proxyUrl.ts for proxy URL normalization, request.ts for common response handling).
  • Do not duplicate NVIDIA/GFN constants, request headers, platform/device ID mapping, auth header construction, proxy behavior, or error parsing across feature files. Add to or extract a focused shared module first, then consume it from features.
  • Keep feature files (auth.ts, games.ts, cloudmatch.ts, subscription.ts, etc.) responsible for product flow and payload shape, not for re-declaring shared client identity or transport details.
  • Preserve provider/alliance behavior, stable device IDs, session refresh semantics, and SessionError.fromResponse() handling when refactoring GFN code.

Electron Process Boundaries

  • Main process owns filesystem, native process management, GFN network/session orchestration, Electron APIs, and security-sensitive logic.
  • Preload exposes the minimal typed bridge needed by the renderer. Do not pass raw Electron or Node primitives into renderer code.
  • Renderer code should stay UI-focused. Do not duplicate main-process GFN networking or native orchestration in React components.

Shared Contracts

  • opennow-stable/src/shared is the contract boundary between main, preload, and renderer. Keep public IPC/shared interfaces stable unless the task explicitly requires a contract change.
  • When changing shared types, update every caller across main, preload, and renderer in the same change and run type checks.
  • Avoid using any or renderer-only types in shared contracts. Prefer serializable DTOs and explicit unions.

Maintainability

Long term maintainability is a core priority. If you add new functionality, first check if there is shared logic that can be extracted to a separate module. Duplicate logic across multiple files is a code smell and should be avoided. Don't be afraid to change existing code. Don't take shortcuts by just adding local logic to solve a problem.

  • Refactors should reduce ownership ambiguity: name the new owner module, move duplicated logic there, and keep behavior equivalent unless a behavior change is requested.
  • Prefer small, typed helpers over broad utils modules. If a helper needs knowledge of one protocol or product area, keep it beside that area.
  • Keep compatibility with existing persisted auth/session state unless a migration is explicitly part of the task.

Localization

Crowdin owns generated translations. When changing localized copy, edit only locales/en.json as the source language file. Do not manually edit other locales/*.json files; they are generated by Crowdin and should only change through Crowdin sync pull requests.

Checks

  • For TypeScript/Electron changes, run the narrowest relevant smoke check first, then npm --prefix opennow-stable run typecheck before finishing when practical.
  • For main-process GFN/session changes, also run npm --prefix opennow-stable test -- --test-name-pattern gfn or the closest targeted test command available; if scripts do not support filtering, run npm --prefix opennow-stable test.
  • For localization changes, run npm --prefix opennow-stable run locales:check.
  • Do not claim completion if the relevant acceptance check fails. Report the failing command and failure point.

Cursor Cloud specific instructions

  • All commands run from opennow-stable/ (or use the root npm run <script> wrappers). Dependencies are managed with npm (package-lock.json); the bun.lock is secondary — do not use bun. Node 22 is required.
  • Standard scripts are defined in opennow-stable/package.json: dev, build, lint, typecheck, test, locales:check. Don't duplicate them; use those.
  • Running the app: npm run dev (root) launches electron-vite dev and opens the Electron window on the desktop DISPLAY (:1). It is a long-running process — start it in a background/tmux session, not a blocking foreground call.
  • Benign startup noise: in this container Electron logs Failed to connect to the bus (dbus) and vkCreateInstance() failed: -9 / Failed to create and initialize Vulkan (GPU). These are expected with no real GPU/dbus and do not indicate failure — the UI still renders and networks fine.
  • OpenNOW is a bring-your-own-account GeForce NOW client: there is no local backend. Full end-to-end gameplay/login requires a real NVIDIA/GFN account. Clicking "Sign in" opens NVIDIA's OAuth page (login.nvgs.nvidia.com); the auth/networking path can be exercised up to that external login without credentials.
  • The native Rust streamer in native/opennow-streamer is optional and Windows-focused (npm run native:check / native:build need the Cargo toolchain). It is not required to run or develop the Electron client; the default stream path uses embedded Chromium WebRTC.