6.8 KiB
API aplikacji kart
Wspólna aplikacja Fastify wystawia stan dowolnej karty, nawigację UML,
checkpointy oraz Neovim wybrany przez MCP. Domyślny adres lokalnej instancji
to http://127.0.0.1:8080. Kontrakt nie zależy od serii ani konkretnej karty;
dane i recepty pochodzą z jej card_source.json.
API nie zarządza cyklem życia kontenera i nie podpina pane tmuxa. Za operacje
start/reset/refresh/attach/detach odpowiada stemctl session. API korzysta z
kontenera wskazanego przez bieżący wybór MCP i steruje zawartością jego sesji:
Neovimem, Termdebugiem/GDB i checkpointami maszyny.
Tożsamość i stan
| Metoda i endpoint | Znaczenie |
|---|---|
GET /api/identity |
id, UUID, wersja i SHA-256 źródłowego JSON-a karty. |
GET /api/card-revision |
Rewizja plików używana do automatycznego odświeżania strony. |
GET /api/state |
Złożony stan nawigacji, widoku, checkpointu i dostępności Neovima. |
GET /api/control/state |
Lekki stan synchronizacji strony z klientem sterującym. |
Serwer jest przeznaczony do pracy lokalnej. Nie ma warstwy uwierzytelnienia, dlatego nie należy wystawiać go bezpośrednio poza zaufany host.
Nawigacja UML
Hierarchia nawigacji jest stała:
card → task → block → phase → step → snapshot
Ruch kursora przez move lub PUT current nie uruchamia symulatora.
Jawna aktywacja odbywa się przez Enter w WWW albo F2 w WWW/Neovimie,
które wywołują POST /api/navigation/sync. Dla poziomu BLOCK backend wybiera
pierwszy STEP tego bloku. CARD i TASK są odrzucane, ponieważ nie wskazują
konkretnego checkpointu diagramu.
| Metoda i endpoint | Znaczenie |
|---|---|
GET /api/keyboard |
Skróty i obsługiwane poziomy nawigacji. |
GET /api/navigation/catalog |
Wszystkie prawidłowe pozycje i ich indeksy. |
GET /api/navigation/current |
Bieżąca pozycja oraz status checkpointu. |
PUT /api/navigation/current |
Ustawia dokładną pozycję i poziom fokusu. |
POST /api/navigation/move |
Przesuwa kursor o delta na wybranym poziomie. |
POST /api/navigation/sync |
Odtwarza checkpoint przypisany do bieżącej, zapisanej pozycji. |
Przykład ustawienia kroku — identyfikatory są danymi konkretnej karty:
{
"task_id": "<task-id>",
"block_id": "<block-id>",
"phase_id": "<phase-id>",
"step_id": "<step-id>",
"snapshot_ref": "<snapshot-ref>",
"focus_level": "step",
"sync_requested": true,
"actor": "stemctl"
}
Checkpointy
| Metoda i endpoint | Znaczenie |
|---|---|
GET /api/checkpoint/status |
Aktywna operacja, ostatni wynik i generacja. |
POST /api/checkpoint/activate |
Odtwarza stan GDB przypisany do snapshotu. |
Wywołanie orkiestratora przypina zarówno kontener, jak i rewizję karty:
{
"snapshot_ref": "<snapshot-ref>",
"generation": 1784280000000,
"expected_binding": {
"container_id": "<container-id>",
"instance": "<instance-id>",
"profile": "hazard3-sim",
"target": "hazard3-baremetal"
},
"expected_identity": {
"id": "<card-id>",
"uuid": "<card-uuid>",
"version": "<card-version>",
"source_sha256": "<sha256>"
}
}
Backend przechowuje bieżącą nawigację i stan viewera w SQLite. Domyślna baza
to .stem/card-state.sqlite3; ścieżkę można zmienić przez
CARD_STATE_DATABASE. Ta sama aplikacja wystawia HTTP również przez lokalny
socket .stem/card-api.sock (CARD_API_SOCKET). Repozytorium jest montowane w
kontenerze jako /workspace, dlatego Neovim wywołuje API przez
/workspace/.stem/card-api.sock bez otwierania dodatkowego portu sieciowego.
Replay kończy się powodzeniem wyłącznie ze statusem ready. Zmiana kontenera,
socketu MCP albo źródłowego JSON-a podczas operacji powoduje odrzucenie
wyniku; pozycja strony i SYNC ON nie są wtedy publikowane.
Widok i Neovim
| Metoda i endpoint | Znaczenie |
|---|---|
GET/PUT /api/viewer/state |
Skala, scroll oraz visible/sync/control/expanded/fit. |
GET /api/nvim/state |
Bieżący bufor, okno, kursor i tryb Neovima. |
PUT /api/nvim/cursor |
Ustawia row, column i opcjonalnie window. |
POST /api/nvim/input |
Przekazuje do 256 znaków przez nvim_input. |
POST /api/nvim/reset |
Resetuje cel i odświeża debugger (F1). |
POST /api/nvim/redraw |
Dopasowuje host pane i grid UI, a następnie wykonuje pełny redraw (`Ctrl+``). |
WS /api/nvim-ui |
Strumień zewnętrznego UI Neovima do panelu WWW. |
Pole viewer.scroll zapisuje położenie dokumentu (x, y), numer strony
page_index oraz sheet_scroll_top dla jej wewnętrznego obszaru. Dzięki temu
sterowanie API odtwarza ten sam fragment diagramu także wtedy, gdy przy dużym
powiększeniu przewija się najpierw zawartość strony, a dopiero potem dokument.
Wyłączenie viewer.nvim.sync automatycznie wyłącza również
viewer.nvim.control. Samo ponowne włączenie synchronizacji nie uzbraja
sterowania klawiaturą bez jawnego control: true.
viewer.allocator.visible przechowuje stan przypiętego modelu alokatora.
Model jest przełączany przez Alt+6 i pokazuje fazę/krok, allocp, zajętość
areny oraz wartości związane z bieżącym checkpointem.
Podział odpowiedzialności widoków
Interaktywny diagram UML pokazuje przepływ i służy do wyboru kroku. Nie
renderuje pod SVG osobnych paneli kodu, terminala, rejestrów, pamięci ani ramki
stosu. Te dane prezentuje Nvim view, ustawiany przez snapshot wybranego
kroku. Snapshoty pozostają w JSON/API, mimo że nie są powielane wizualnie pod
diagramem.
Postęp zajęć i raport
| Metoda i endpoint | Znaczenie |
|---|---|
GET /api/progress |
Katalog, statusy i podsumowanie wykonania. |
PUT /api/progress/:itemId |
Ustawia pending albo approved, notatkę i aktora. |
GET /api/report/teams.md |
Generuje bieżący raport Markdown do Teams. |
GET/POST /api/events |
Odczytuje lub dopisuje chronologiczne zdarzenia z timestampem backendu. |
POST /api/evidence |
Zapisuje PNG/JPEG i przypina go do zdarzenia. |
GET /api/evidence/:name |
Udostępnia zapisany dowód. |
GET /api/report/lesson.html |
Renderuje chronologiczny raport HTML z dowodami. |
Zdarzenia są dopisywane do SQLite i obejmują nawigację, aktywacje checkpointów, reset/redraw Neovima, zmiany viewera oraz postęp. Dzięki temu raport pokazuje rzeczywistą kolejność pracy, a nie wyłącznie końcowy stan.
Planowane strategie i adnotacje
Strategie debugowania będą przypinane do pełnego klucza
task/block/phase/step/snapshot. Adnotacja pozostanie osobnym rekordem:
strategy: id, label, commands, expected_observations
annotation: id, strategy_id, target, geometry, style, text, visible
Planowane operacje show/hide/toggle zmienią wyłącznie visible.
add/remove będą osobnymi, audytowalnymi operacjami. Dzięki temu ukrycie
warstwy objaśnień nie usuwa przygotowanych oznaczeń.