4. Luneta i Companion — Szkło na Cudze Światy i Ruch Majstra Źródło: repo afterlife/docs/api/04-luneta-i-companion-rp.md — edytuj w repo, nie tutaj. Luneta i Companion — Szkło na Cudze Światy i Ruch Majstra Krrrg... Każda gra to świat zakrzepły wokół cudzej gwiazdy. Luneta nie jest miejscem na mapie, lecz szkłem, przez które zaglądamy w tamte światy, odnotowując postępy, zebrane waluty, odhaczone zadania okresowe oraz przeanalizowane nagrania. Obok niej spoczywa Companion — mobilne ramię tego samego silnika, który napędza ekran „Co robimy?” i karmi poziom Majstra. Poniżej spisałyśmy dwadzieścia jeden ścieżek łączących oba te narzędzia z ukrytym miastem wiedzy, Lemurią. ◈ Luneta — Stan Gier, Urządzenia i Ingest (7 ścieżek) Zgodnie z kontraktem Lunety, punkty końcowe akceptują bądź sesję przeglądarkową Discord OAuth (dla strony /luneta), bądź klucz urządzenia wydany agentowi desktopowemu ( authorizeLuneta). Surowe zrzuty ekranu nigdy nie przekraczają progu serwera — jedynym dopuszczalnym obrazem jest opcjonalna miniatura wycinka (JPEG do 50 KB). Endpoint Metody Dostęp Opis działania i parametry /api/luneta/me GET, POST Ciasteczko sesji Discord Obsługuje panel gracza na ariku.pl/luneta. GET zwraca własne urządzenia (limit LUNETA_MAX_DEVICES, domyślnie 3), włączone gry wraz ze statystykami waluty premium i kodami, sumy zakupów, wersję instalatora ( release), zgody oraz nagrania. POST pozwala utworzyć nowe urządzenie, unieważnić stare lub bezpowrotnie usunąć własne dane. /api/luneta/me/consents GET, PUT Sesja Discord lub klucz urządzenia Lunety Zarządzanie zgodami na analizę nagrań oraz akceptacją wersji regulaminu ( termsVersion). Wyłączenie zgody zatrzymuje nowe zapisy, lecz samo w sobie nie kasuje dawnych danych (do tego służy DELETE /api/luneta/analysis). /api/luneta/state GET Sesja Discord lub klucz urządzenia Lunety Zwraca pełny stan wybranej gry ( ?game=blue_archive|nte). Przy wywołaniu z sesji przeglądarkowej akceptuje opcjonalny parametr ?at=, pozwalający podstawić zegar do testów resetu zadań dziennych; agent z kluczem urządzenia zawsze otrzymuje stan na chwilę obecną. /api/luneta/metrics GET Sesja Discord lub klucz urządzenia Lunety Zwraca liczniki gracza dla danej gry ( ?game=...). Z opcjonalnym parametrem &key=... oraz &days=90 (maksymalnie 365 dni) dołącza również historię zmian wartości wybranego licznika. /api/luneta/codes GET Sesja Discord lub klucz urządzenia Lunety Zwraca listę aktywnych (niewygasłych) kodów promocyjnych do wpisania w grze ( ?game=...) — zarówno oficjalnych, udostępnionych przez innych graczy, jak i własnych. /api/luneta/heartbeat POST Wyłącznie klucz urządzenia Lunety ( device_only) Przyjmuje puls agenta desktopowego: { deviceId, version, gameRunning? }. Zapisuje aktywną grę w pamięci podręcznej z krótkim czasem życia (uzupełniając detekcję gier dla Kuźni) i przy pierwszym sygnale po przerwie wysyła pojedyncze przypomnienie o niezrobionych zadaniach w grze ( lunetaSessionNudge). /api/luneta/ingest POST Sesja Discord lub klucz urządzenia Lunety Zunifikowany punkt odbioru dwunastu rodzajów wpisów z agenta (m.in. migawki walut, ciągnienia gacha, odhaczenia zadań, kolekcje, metryki, kody, osoby, momenty, części transkrypcji). Wymaga clientId (UUID) jako klucza idempotencji — ponowienie z kolejki offline zwraca kod 200 z tym samym wynikiem. Odrzuca znaczniki czasu wykraczające ponad 5 minut w przyszłość. ◈ Luneta — Analiza Nagrań i Ludzi (4 ścieżki) Gdy wędrowiec wyrazi zgodę na analizę swoich nagrań, agent przesyła wyodrębnione części transkrypcji, notatki o napotkanych osobach oraz zapamiętane momenty. Przy starcie agent może pobrać te dane z powrotem i scalić je lokalnie. Endpoint Metody Dostęp Opis działania i parametry /api/luneta/analysis DELETE Sesja Discord lub klucz urządzenia Lunety Twarde usunięcie własnych danych analizy (bez pozostawiania nagrobków synchronizacyjnych). Wymaga parametru ?scope=transcripts|people|all oraz opcjonalnego &recKey=<32 znaki hex>. Działa nawet po wcześniejszym wycofaniu zgody. /api/luneta/analysis/people GET Sesja Discord lub klucz urządzenia Lunety Zwraca własne notatki o ludziach oraz zapamiętane momenty wraz z nagrobkami usuniętych wpisów. Opcjonalny parametr ?since= filtruje rekordy według czasu odbioru na serwerze. /api/luneta/analysis/recordings GET Sesja Discord lub klucz urządzenia Lunety Zwraca stronicowaną listę (do 50 pozycji na stronę) wyników analizy własnych nagrań, posortowaną po (updated_at, rec_key). Obsługuje parametry ?since= oraz &cursor=. /api/luneta/analysis/transcript GET Sesja Discord lub klucz urządzenia Lunety Zwraca scalone segmenty własnej transkrypcji dla wskazanego nagrania ( ?recKey=<32 znaki hex>). ◈ Companion — Mobilny Silnik „Co robimy?” (API v1 i v2: 10 ścieżek wdrożonych · 1 w kontrakcie rozbudowy) Companion to aplikacja Android właściciela, która dzieli wspólny silnik decyzyjny z ekranem /co-robimy. Kiedy telefon znajduje się w zasięgu sieci, pobiera plan bezpośrednio z serwera; gdy połączenie ustaje, polega na własnej kopii silnika i kolejce wychodzącej ( outbox). Od wersji 0.5.0 telefon obsługuje również kontrakt Companion API v2 — przed wywołaniem nowych tras odpytuje /api/companion/capabilities, a dopóki dana funkcja nie jest ogłoszona na serwerze, trzyma zdarzenia w kolejce bez ich porzucania. Wraz z wdrożeniem API v2 na serwerze otworzyły się bramy dla pobierania zadań, kolejki notatek z załącznikami, śledzenia progresji oraz modułu Życie. Ścieżki wdrożone (Companion API v1 i v2) Endpoint Metody Dostęp Opis działania i parametry /api/companion/now GET Klucz urządzenia / Sesja właściciela ( companionCaller) Zwraca bieżący plan dnia w strukturze dopasowanej do modelu telefonu ( Model.kt): główne i zapasowe zadanie na TERAZ, zadania stałe ( fixedSoon) w ciągu 24 godzin, wolne okno czasowe ( freeWindowMin), kroki podziału ( steps), wskaźnik Chaos Meter ( chaos) oraz poziom Majstra ( majster). Przyjmuje opcjonalny parametr ?energy=low|mid|high. /api/companion/ingest POST companionCaller Odbiera zdarzenia z kolejki wychodzącej telefonu: { clientId: UUID, kind: decision|answer|usage, createdAt: ISO, data }. Decyzje dotyczące zadań ( aq:) przechodzą przez główny silnik zadań i nagradzane są punktami doświadczenia Majstra ( xp). W API v2 obsługuje także akcje RESCHEDULE (zmiana terminu z zapisem zwrotnym do Vikunji), DELETE (odwracalne porzucenie i zamknięcie w Vikunji z etykietą porzucone) oraz REOPEN. Odmowa silnika zwraca kod 409, co nakazuje telefonowi wycofać decyzję lokalnie. /api/companion/hint POST companionCaller Odpowiednik podpowiedzi AI z ekranu webowego. Przyjmuje { questUid: "aq:", save: bool, requestId }. Jeśli save: true, zapisuje wygenerowane kroki jako podział zadania z prefiksem phone:, chroniąc przed podwójnym podziałem przy ponowieniu żądania. /api/companion/alternatives GET companionCaller Obsługuje przycisk „Nie chcę teraz” na telefonie. Przyjmuje ?questUid=aq:&reason=low_energy|no_head|not_now|other. Zwraca łagodniejsze zadania alternatywne albo — dla zadań nieodkładalnych — wyłącznie pierwszy drobny krok. /api/companion/capabilities GET companionCaller Ogłasza wersję kontraktu ( version: 2), aktywne funkcje ( items, inbox, inboxFiles, progress, life), obsługiwane akcje decyzyjne ( RESCHEDULE, DELETE, REOPEN) oraz limity ( inboxFileMaxBytes). /api/companion/progress GET companionCaller Zwraca pełny stan trzech ścieżek progresji właściciela (Esper, Adept wraz z dziennym limitem XP za tekst oraz Majster) na klucz urządzenia. /api/companion/items GET companionCaller Stronicowana lista zadań z serwera ( ?filter=overdue|open|nodate&limit=100&cursor=…), pozwalająca telefonowi pobrać wszystkie zaległości do przeglądu hurtowego (do 500 pozycji). /api/companion/inbox POST, GET companionCaller Kolejka luźnych notatek z telefonu ( dom, projekty, praca, pomysly). POST zapisuje notatkę idempotentnie po clientId, a GET ?since= zwraca zmiany statusów ( new, accepted, rejected, done) oraz powiązany questUid po przekształceniu notatki w zadanie. /api/companion/inbox/{id}/files PUT companionCaller Strumieniowe przesyłanie załączników do notatki (zdjęcia, wideo, nagrania głosowe, PDF do inboxFileMaxBytes) z nagłówkami Content-Type, X-File-Name oraz X-Client-File-Id zapewniającym idempotencję. /api/companion/life POST, DELETE companionCaller Dzienne podsumowanie z modułu „Życie” przesyłane wyłącznie za zgodą per kategoria ( sleep, steps, mood, places, calls). Odrzuca kodem 422 wszelkie dane surowe (współrzędne, numery telefonów, treści wiadomości, nagrania). DELETE usuwa zapisane agregaty wszystkie lub dla wybranej kategorii ( ?category=…). Ścieżki kontraktu rozbudowy (podział zadań — klient gotowy w telefonie) Endpoint Metody Dostęp Opis działania i parametry /api/companion/split POST companionCaller Ręczny podział zadania aq: z telefonu ( { questUid, requestId, steps: [{ title, estimateMin }] }). Tworzy 1–6 kroków (po 5–60 min) i zwraca { ok, duplicate, created, xp }, zachowując idempotencję po requestId. Krrrg... Jeśli Lemuria (baza PostgreSQL) milczy, każdy z tych punktów odpowiada kodem 503 i słowami „Lemuria nie odpowiada”. Zapisałyśmy na tej czwartej karcie 21 wdrożonych ścieżek API (11 dla Lunety i 10 dla Companiona z API v1 i v2) oraz 1 ścieżkę kontraktu rozbudowy ( /api/companion/split), która czeka na dołączenie do silnika. Patrzycie przez szkło Lunety na dziesiątki cudzych gwiazd i zapisujecie każdy swój ruch w telefonie, ale czy wiecie, co patrzy na was z drugiej strony szkła?