4 Commits

Author SHA1 Message Date
Mavis 68bc7015fd Phase 1c: real kRPC bridge (full protocol + mock mode for development)
CI / Lint, typecheck, test, build (pull_request) Failing after 9s
- packages/krpc-client: TypeScript kRPC protocol client
  - connection.ts: varint encoding/decoding, length-prefix framing,
    per-socket read queue (avoids race when multiple read promises
    in flight). Uses multiplication not '<<' for varint shift
    because JS truncates << to 32 bits.
  - schema.ts: hand-written protobufjs schema for kRPC meta-protocol
    (ConnectionRequest, Request, Response, StreamUpdate, Status, etc.)
    - enough to do connection handshake, single procedure calls, and
      stream subscription. Service-specific types (SpaceCenter.Vessel,
    Orbit, CelestialBody) need to be loaded from the kRPC mod's
    .proto files at runtime.
  - client.ts: KRPCClient with connect/invoke/addStream/removeStream/
    onStreamUpdate/close. Tested with hand-rolled mock server.
  - 10 tests (varint round-trips incl. uint64, wire format with raw
    sockets).

- apps/tools/ksp-bridge: bridge that connects KSP to our API
  - convert.ts: pure kRPC -> UniverseSnapshot conversion
    (situation enum mapping, body id normalization, etc.)
  - bridge.ts: main poll loop with retry + backoff
  - krpc-adapter.ts: KRPCAdapter class that owns the KRPCClient
  - index.ts: entrypoint with MOCK MODE for development (emits
    synthetic state when no KSP is available, so you can verify the
    HTTP pipeline end-to-end)
  - 9 tests (7 conversion + 2 end-to-end bridge)

- ksp/README.md: full setup guide
  - CKAN install, KSP server start, env vars
  - Hand-rolled KSP calls list (what SpaceCenter methods we need)
  - Roadmap for the remaining .proto-loading work
  - Protocol deep-dive (for the next dev)

- Bug fixes along the way: protobufjs default import (not namespace),
  varint 32-bit truncation, JavaScript bitwise 32-bit limit,
  handshake status enum comparison (number vs string).

End-to-end verified: API + bridge in mock mode, 2 bodies + 1 vessel
arriving at /api/v1/state, 500ms polling cadence, automatic recovery
on HTTP failures.
2026-06-02 20:42:54 +00:00
Mavis 9e76ec9328 Phase 2: 3D live map driven by API WebSocket
CI / Lint, typecheck, test, build (pull_request) Failing after 9s
- apps/live-map/src/hooks/useLiveState.ts: WebSocket subscription
  with exponential-backoff reconnect, polling fallback, status tracking
- apps/live-map/src/scene/Scene.tsx: refactored Three.js scene with
  per-frame orbit propagation, vessel marker color-coding by owner,
  orbit-line visibility tied to focus filters, smooth camera follow
  on selected vessel/body
- apps/live-map/src/scene/layout.ts: bodyPositionAt / vesselPositionAt
  helpers (heliocentric frame, walk up the parent chain), logScale
  helpers for the system view
- apps/live-map/src/scene/color.ts: per-body and per-owner color maps
- apps/live-map/src/panels/TimeControls.tsx: play/pause/reverse/reset
  buttons, ×1/×10/×100/×1k/×10k/×100k speeds, UT scrub slider,
  live-edge indicator (LIVE / Nh behind / Nh ahead)
- apps/live-map/src/panels/VesselList.tsx: vessel sidebar with click-
  to-track; color-coded by owner (KASA=blue, SPES=orange)
- apps/live-map/src/panels/FocusPanel.tsx: planet/moon/vessel orbit
  visibility toggles
- apps/live-map/src/panels/StatusPill.tsx: WS status (LIVE/POLLING/
  OFFLINE/STALE), body + vessel + message counts
- tests/scene.test.ts: 10 tests for layout helpers (periodicity,
  vessel-centered positioning, logScale round-trips)

End-to-end verified: mock publisher → API → live-map WebSocket →
scene re-renders with the new vessel positions and orbits.
2026-06-02 19:18:22 +00:00
Mavis a457b9d96f Phase 1: data pipeline (Postgres+Redis with in-memory fallback, mock telemetry publisher, WebSocket fan-out, hub /debug page)
CI / Lint, typecheck, test, build (pull_request) Failing after 10s
- packages/db: postgres.js + ioredis wrapper, StateStore interface with
  InMemory + Postgres implementations, schema migration runner
- apps/api: refactored to use @kerbal-rt/db; live WebSocket hub subscribes
  to store changes and broadcasts to all clients
- apps/tools/mock-telemetry: Node script that generates realistic KSP
  state and POSTs to /api/v1/ingest at 1Hz (uses same keplerian math
  as the live-map renderer)
- apps/hub: new /debug page that connects to /api/v1/live and shows
  the live state
- ksp/README.md: documents Phase 1c (real kRPC bridge) and the two
  implementation options
- Tests: 17 total (5 kepler math, 5 db store, 5 API health/state,
  2 API WebSocket fan-out)

End-to-end verified: mock publisher → API → hub /debug page,
11 snapshots/5s over WebSocket, vessels advancing in mean anomaly.
2026-06-02 18:54:46 +00:00
Mavis 938ba042b3 Phase 0: fix typecheck, format, build; remove stray emit; pin port via env
CI / Lint, typecheck, test, build (push) Failing after 22s
2026-06-02 16:07:09 +00:00