Files
eden/README.md
T

11 KiB

EVE Intelligence

A self-hosted EVE Online intelligence assistant built with Bun, SvelteKit/Svelte 5, convex-svelte, self-hosted Convex and bun:sqlite.

Milestone 1: connect multiple EVE characters, synchronize assets, and view a reference-price estimate through the same service in chat and the Assets page. JEV makes a typed intent judgment; application code owns authorization and arithmetic.

This is an initial implementation, not a production-audited release. The offline quick start downloads no reference archives; the explicit production worker imports real EVE Ref, Hoboleaks, and CCP SDE data. Manufacturing, market-depth liquidation, capital routing and general-purpose conversational answers are not implemented.

Quick start: offline fixture slice

Requires Bun 1.3.14 (the tested runtime). No API credentials or Docker required for the explicitly labeled demo.

bun install --frozen-lockfile
bun run reference:fixture
APP_MODE=demo bun run dev

Open http://localhost:5173. Use Estimate all assets, Browse assets, or /value and /assets. The two pilots and prices are synthetic. Item names come from the compiled SQLite fixture database, not runtime raw JSON. Natural-language intent routing requires a TypeSafe key; without one the app honestly supports only explicit commands.

bun test
bun run check
bun run build
APP_MODE=demo APP_ORIGIN=http://localhost:3000 ORIGIN=http://localhost:3000 bun run start

The estimate excludes unpriced/unknown items and blueprint copies. ESI average prices are not Jita buy orders, firm quotes, liquidity estimates or replacement costs. Stale/incomplete data blocks valuation rather than silently becoming zero.

This instance: Infisical + Pangolin

Use the live deployment guide for dev.evebot.app, the read-only Infisical machine identity, safe secret injection, and the persistent Docker deployment on host ports 5173/3210. Public settings live in config/dev.env; credentials are not committed.

Live local development (standalone alternative)

  1. Copy .env.example to private .env. Keep APP_MODE=live.

  2. Generate application secrets with bun run keys:generate. This creates .env.keys with mode 0600 and refuses to overwrite it. Merge those values into .env (do not commit either file). Encryption/signing/bridge keys are distinct.

  3. Start only your local backend: docker compose up -d backend.

  4. Generate the deployment admin key: docker compose exec backend ./generate_admin_key.sh. Put it in CONVEX_SELF_HOSTED_ADMIN_KEY in .env. This key is CLI-only, not a browser or web-container credential.

  5. Configure backend function environment, then deploy:

    bun run convex:configure
    bunx convex dev --once
    

    APP_AUTH_ISSUER, APP_AUTH_JWKS, CONVEX_BRIDGE_SECRET and CONVEX_SYNC_WORKER_SECRET must be set in Convex's environment, not merely the Docker process environment. The direct configure command reads the local private .env, including CONVEX_SELF_HOSTED_ADMIN_KEY; never put that admin key in a web or worker environment. Custom JWT audience is eve-intelligence; the public JWKS data URI avoids a boot dependency on the web server.

  6. Register an EVE application and exact callback at https://developers.eveonline.com/. Set EVE_CLIENT_ID, EVE_CALLBACK_URL, and EVE_CLIENT_SECRET for a confidential web client. A public PKCE client leaves the secret blank. Initial login requests esi-assets.read_assets.v1; later dataset upgrades preserve only server-allowlisted existing scopes.

  7. Set ESI_USER_AGENT with your actual operator contact. Optional TYPESAFE_API_KEY enables server-side JEV routing. Set public/internal Convex URLs as described in .env.example.

  8. Build the fixture reference database and start bun run dev. Connect a character, synchronize it, and add more characters with Connect EVE Character. Each connects explicitly to the current application user.

  9. In a second terminal, create a private .env.worker containing only CONVEX_URL, CONVEX_SYNC_WORKER_SECRET, TOKEN_ENCRYPTION_KEY, EVE_CLIENT_ID, optional EVE_CLIENT_SECRET, EVE_CALLBACK_URL, ESI_USER_AGENT, and worker tuning values, then start the worker with bun --env-file=.env.worker run sync:worker. Do not source the full web .env; the worker launcher intentionally rejects bridge/admin/JWT/JEV credentials.

Important: the fixture DB contains only a handful of types. Live assets absent from it remain explicitly unpriced/unknown. Do not describe a fixture-backed report as a complete real-character valuation. See full-import handoff before ingesting real releases.

The first verified EVE character creates an application user and is the sole signed-out login character; additional linked characters are data-only until an authenticated user switches the primary. Reconnecting a character to a different application user or with a changed owner hash fails closed. Local data-only-character disconnection is implemented, but remote EVE revocation, unlink/delete, transfer recovery, and account merging/recovery remain deferred.

Single-host Docker Compose

Compose uses Convex's default SQLite backend; it introduces no other datastore.

  • backend: persistent Convex SQLite volume, API bound to loopback by default (the configured Pangolin deployment explicitly overrides this).
  • web: Bun web service with read-only reference volume.
  • sync-worker: dedicated durable asset-sync worker with a bundled runtime and worker-only secret.
  • reference-worker: dedicated one-shot heavy-ingestion process (tools profile).
  • dashboard: optional loopback-only management UI (admin profile).

For local container use, set APP_ORIGIN and APP_AUTH_ISSUER to http://localhost:3000 and the EVE callback to http://localhost:3000/auth/eve/callback. Repeat bun run convex:configure after changing issuer.

docker compose up -d backend
# Configure/deploy Convex as above before starting live web.
# Explicit production archive import (~109 MiB for the reviewed releases):
docker compose --profile tools run --rm --build reference-worker
docker compose up -d --build web
# Start the explicitly profiled durable asset worker; Compose forwards only its worker environment:
docker compose --profile worker up -d --build sync-worker
# Optional management UI:
docker compose --profile admin up -d dashboard

Invoking the tools worker explicitly imports production archives into /app/data/reference, the shared web/worker volume. --check fetches metadata only. Fixture imports require an explicit --fixture override and a separate demo output directory/volume; never use a fixture worker against the live volume.

For remote exposure use HTTPS reverse proxies for the app and Convex browser WebSocket/API endpoints. PUBLIC_CONVEX_URL must be browser-reachable, while Compose's CONVEX_URL=http://backend:3210 is internal. Configure exact origins/callbacks. Keep backend/admin ports on loopback/management networks. The backend and optional dashboard defaults are immutable digest-pinned images in compose.yaml; use only reviewed digest overrides for production. See security gates.

Structure

src/lib/domain/             framework-independent capabilities, assets, money, future domain ports
src/lib/server/             Bun-only composition, ESI/SSO, crypto, Convex and SQLite adapters
src/lib/server/assistant/   typed JEV intent routing and allowlisted deterministic dispatch
src/convex/                validated user state, secure bridge, browser-safe reactive queries
src/routes/                Svelte views and same-origin server endpoints
workers/                   reference compiler entrypoint (outside Convex actions)
fixtures/reference/        tiny documented source-shape fixtures
scripts/                   key generation and Convex configuration
tests/                     offline deterministic regression tests
docs/research/             current official-source evidence and captured ESI contracts

Operational limits

  • This checkpoint records local/disposable prototype verification only. It makes no claim of deployed/live ESI verification or production readiness; live multi-character linking, revocation and transfer scenarios remain deferred.
  • Production imports use reviewed source adapters and immutable SQLite artifacts. CCP NPC station IDs, system/type/owner/position facts are imported when npcStations.jsonl is present; station names remain optional and the production profile explicitly marks station coverage incomplete until an isolated measured replay. Twenty-one dangling blueprint references in the reviewed release are preserved explicitly rather than fabricated. See reference operations and the verification record for executed import checks and limitations.
  • Asset synchronization is enqueued by the web process and completed by the separate durable sync-worker. Convex leases/CAS protect staging and token rotation; start the worker explicitly with the worker-scoped launcher before testing live synchronization.
  • ESI page collections are not transactional snapshots. Stability checks reduce risk; cache rollover/mutation may require a later retry.
  • Location IDs are shown explicitly as unresolved. Fitted/nested assets are distinct ESI items; no contents multiplier is applied to ship prices.
  • Conversations/execution summaries persist for authenticated live users; this first UI does not yet provide a history browser. A pending guest request is kept only in tab sessionStorage and rechecked after login/sync.
  • Reference-source state is local to the worker/artifact volume for this milestone; future Convex jobs may initiate/check it without extracting archives inside Convex.
  • Add snapshot/session/execution retention, remote revocation and full unlink/delete lifecycle, key rotation and restore-tested backups before multi-user production. Preserve encryption keys with backups: losing them loses access to stored credentials.

EVE Online is a trademark of CCP Games. This project is not endorsed by CCP.