Niniejsza specyfikacja definiuje oficjalny protokół komunikacyjny (v1) pomiędzy lokalnym daemonem orkiestracji koru a wtyczkami klienckimi IDE (Cursor, Windsurf, VS Code, JetBrains). Protokół ten stanowi warstwę sterowania (Control Plane) nad istniejącym środowiskiem programistycznym użytkownika.
Dokument łączy trzy poziomy opisu:
- kontrakt wire protocol
v1(stabilny, implementowany wpackages/koruide/src/koruide/protocol.py), - semantyka adapterów IDE (zależna od API host IDE i wersji pluginów),
- model operacyjny pętli autopilota (decyzje runtime, fallbacki, verify, cooldown).
W efekcie nie wszystkie ścieżki opisane poniżej są obecnie osiągalne we wszystkich adapterach IDE (szczegóły w sekcjach 1, 5 i 6).
Techniczny kontrakt wire protocol jest utrzymywany równolegle w docs/specs/kide-002-koruide-api-v1.md, a aktualna implementacja dekodera i helperów znajduje się w packages/koruide/src/koruide/protocol.py.
W dokumencie stosowane są jawne etykiety statusu:
- REQUIRED in v1 — część twardego kontraktu wire (
v1), wymagana po stronie parsera/daemona. - OPTIONAL in v1 — legalne i obsługiwane w
v1, ale niewymagane od każdego adaptera IDE. - IMPLEMENTATION-DEFINED — semantyka zależna od pluginu/IDE; nie jest jednolicie gwarantowana.
- NOT YET UNIVERSALLY AVAILABLE — typ/ścieżka obecna w spec lub daemonie, ale niepowszechnie dostępna w aktywnych bridge'ach.
Architektura opiera się na trójwarstwowym modelu sterowania, w którym koru nie zastępuje wbudowanego chatu IDE, lecz nim steruje:
flowchart TB
subgraph Koru_Core ["Warstwa Autopilota Koru (Daemon)"]
Daemon["Koru Daemon (AutopilotDaemon)"]
Queue["Kolejka Planfile (Ticket Queue)"]
Verify["Weryfikacja post-run (Shell/Pytest/Ruff)"]
Audit["Audit Log (NDJSON)"]
end
subgraph IDE_Layer ["Warstwa Adapterów IDE"]
VSCode["Plugin VS Code Bridge"]
Cursor["Plugin Cursor Bridge"]
Windsurf["Plugin Windsurf Bridge"]
Fallback["OS Injector Fallback (xdotool / wtype / ydotool)"]
end
subgraph Chat_Layer ["Wbudowany Chat IDE"]
IDE_Chat["Interfejs Chat IDE (Cascade / Copilot / AI Assistant)"]
end
%% Połączenia sterowania i przepływu
Queue -->|Pobranie zadania| Daemon
Daemon -->|1. NDJSON Socket (chat.send)| VSCode
Daemon -->|1. NDJSON Socket (chat.send)| Cursor
Daemon -->|1. NDJSON Socket (chat.send)| Windsurf
Daemon -->|2. Fallback (Keyboard Sim)| Fallback
VSCode -->|Wstrzyknięcie i Submit| IDE_Chat
Cursor -->|Wstrzyknięcie i Submit| IDE_Chat
Windsurf -->|Wstrzyknięcie i Submit| IDE_Chat
Fallback -->|Symulacja klawiszy / kliknięć| IDE_Chat
IDE_Chat -->|Hinty lifecycle (opcjonalne)| VSCode
IDE_Chat -->|Hinty lifecycle (opcjonalne)| Cursor
IDE_Chat -->|Hinty lifecycle (opcjonalne)| Windsurf
VSCode -->|session.* / message.* (best-effort)| Daemon
Cursor -->|session.* / message.* (best-effort)| Daemon
Windsurf -->|session.* / message.* (best-effort)| Daemon
Queue -->|Planowanie verify| Verify
Verify -->|Wynik verify -> status ticketu| Queue
Daemon -->|Audit / event append| Audit
- Plugin IDE (Thin Bridge): Pozostaje maksymalnie uproszczony ("thin client"). Odpowiada za:
- Połączenie się z lokalnym Unix socketem daemona przy starcie IDE.
- Wstrzykiwanie tekstu do okna chatu IDE i opcjonalne kliknięcie "Submit".
- Propagowanie zdarzeń cyklu życia chatu (
session.started/session.ended) tam, gdzie API IDE to umożliwia. - Raportowanie diagnostycznych metadanych w
ack(np. wyniki probe ladder).
- Koru Daemon (Control Plane): Zawiera całą logikę biznesową:
- Kolejkowanie zadań planfile, budowanie promptów i handoffów.
- Decyzje o wyborze drogi (plugin vs. OS injector fallback).
- Polityki runtime dla wersji pluginu (
connectedvs.expected) oraz blokadę stale-plugin drive przyKORU_STRICT_PLUGIN_VERSION=1. - Obsługa timeoutów, polityk cooldown, logowania audytowego oraz maszyn stanów sesji.
- Wywoływanie zewnętrznych narzędzi weryfikacji i jakości kodu (
pytest,ruff,redup,regix,wup).
- Wire protocol
v1i daemon: wdrożone. - VS Code / Cursor / Windsurf plugin:
hello,chat.sendimessage.sentdziałają;session.endedorazmessage.receivedpozostają ograniczone przez API i nie są emitowane jako pełny strumień lifecycle. - Instalacja i drift wersji pluginu:
koru autopilot manageraportujeconnected/version,installediexpected; daemon może raportować drift wackoraz blokować drive przez stary live plugin w trybie strict. - JetBrains plugin: aktualnie scaffold (połączenie socket +
hello), bez pełnej obsługichat.sendi stabilnych hooków lifecycle. - Post-run verify: wykonywane w pętli autonomicznej
koru(nie jako bezpośrednia akcja daemona po każdymsession.ended).
- Protokół fizyczny: Lokalny Unix domain socket (UDS).
- Ścieżka gniazda:
- Podstawowa:
$XDG_RUNTIME_DIR/koru-autopilot.sock(zazwyczaj/run/user/$UID/koru-autopilot.sock) - Instancjonowana: przy
KORU_AUTOPILOT_INSTANCE=vscodesocket ma postać$XDG_RUNTIME_DIR/koru-autopilot-vscode.sock. Zalecane, gdy jednocześnie działa kilka IDE lub kilka okien tego samego IDE. - Awaryjna (fallback):
/tmp/koru-autopilot-$UID.sock
- Podstawowa:
- Formatowanie ramki (NDJSON): Każda wiadomość jest zakodowana jako pojedyncza linia tekstu w standardzie UTF-8 zakończona znakiem nowej linii (
\n). - Limit wielkości linii: Maksymalnie 1 MiB (
1024 * 1024bajtów). Próba wysłania większej linii skutkuje natychmiastowym zamknięciem połączenia i błędemline too large. - Uwierzytelnianie i Bezpieczeństwo:
- Uprawnienia pliku socketu ustawiane są na
0600(wyłącznie właściciel procesu). - Daemon weryfikuje tożsamość każdego klienta przy nawiązywaniu połączenia poprzez wbudowany mechanizm
SO_PEERCREDna poziomie jądra Linux. Połączenia od użytkowników o UID innym niż UID daemona są natychmiast odrzucane (reject foreign peer UID).
- Uprawnienia pliku socketu ustawiane są na
Każda ramka NDJSON posiada następującą strukturę bazową:
{
"type": "NAZWA_TYPU",
"id": "OPCJONALNE_ID_KORELACJI"
}Pozostałe pola są spłaszczonym payloadem zależnym od wartości type.
| Typ | Kierunek | Status | Uwagi |
|---|---|---|---|
hello |
plugin -> daemon | REQUIRED in v1 | Podstawowy handshake adaptera |
chat.send |
daemon -> plugin | REQUIRED in v1 | Główna komenda sterująca |
drive |
CLI -> daemon | REQUIRED in v1 | Główny request operatora/autoloopu |
status |
CLI -> daemon | REQUIRED in v1 | Health i introspekcja połączeń/backendów |
ping |
CLI/daemon -> daemon/plugin | REQUIRED in v1 | Keep-alive/health check |
shutdown |
CLI/daemon -> daemon/plugin | REQUIRED in v1 | Kontrolowane zatrzymanie |
ack |
uniwersalne | REQUIRED in v1 | Potwierdzenie i nośnik metadanych wyniku |
error |
uniwersalne | REQUIRED in v1 | Ramka błędu protokołu/wykonania |
session.started |
plugin -> daemon | OPTIONAL in v1 | Zdarzenie lifecycle best-effort |
session.ended |
plugin -> daemon | OPTIONAL in v1 | Hint lifecycle, nie gwarantowany |
message.sent |
plugin -> daemon | OPTIONAL in v1 | Częsty event mostka pluginowego |
status.error |
plugin -> daemon | IMPLEMENTATION-DEFINED | Diagnostyka pluginu/specyficznego adaptera |
message.received |
plugin -> daemon | NOT YET UNIVERSALLY AVAILABLE | Przechwyt odpowiedzi LLM zależny od API IDE |
Wysyłane natychmiast po połączeniu wtyczki z socketem w celu rejestracji środowiska. Status: REQUIRED in v1.
{
"type": "hello",
"id": "vscode-hello-1a8f",
"ide": "cursor",
"version": "1.0.4",
"buildSha": "5bf6fc852b66c95a",
"protocolVersion": 2,
"pid": 28491
}- Pola:
ide(string): Identyfikator środowiska (vscode,vscodium,cursor,windsurf,jetbrains,zed).version(string): Wersja wtyczki koru-autopilot.buildSha(string, optional): Hash konkretnego builda VSIX zapisany wpackage.jsonjakokoruAutopilotBuild.sha.protocolVersion(integer, optional): Wersja kontraktu plugin/daemon.pid(integer): ID procesu wtyczki w systemie.
version jest używane przez daemon wyłącznie jako metadana runtime/policy.
Nie zmienia dekodowania ramek v1, ale może spowodować zablokowanie drive,
gdy KORU_STRICT_PLUGIN_VERSION=1 i wersja live pluginu różni się od wersji
VSIX/package oczekiwanej przez bieżącą instalację koru.
buildSha domyka przypadek, w którym wersja VSIX jest taka sama, ale edytor nadal
uruchamia starszy kod. Przy strict policy daemon odrzuca połączenie, jeśli zna
oczekiwany hash builda, a live plugin wysyła inny hash albo nie wysyła go wcale.
Informuje, że asystent LLM w IDE rozpoczął generowanie odpowiedzi. Status: OPTIONAL in v1.
{
"type": "session.started",
"id": "ev-sess-start-992",
"chat": "cascade"
}- Pola:
chat(string): Identyfikator sub-systemu chat (np.cascade,copilot,default).
- Uwaga implementacyjna: traktowane jako zdarzenie opcjonalne; nie wszystkie pluginy potrafią je emitować stabilnie.
Informuje, że asystent LLM w IDE zakończył swoją odpowiedź lub użytkownik przerwał sesję. W modelu runtime jest to hint lifecycle, który może zostać użyty do decyzji o dalszych krokach (handoff, verify scheduling), ale nie jest sygnałem gwarantowanym.
Status: OPTIONAL in v1.
{
"type": "session.ended",
"id": "ev-sess-end-993",
"chat": "cascade",
"reason": "completed"
}- Pola:
chat(string): Identyfikator sub-systemu chat.reason(string): Powód zakończenia (np.completed,user-stop,error,timeout).
- Uwaga implementacyjna: daemon obsługuje ten typ wiadomości, ale pluginy IDE mogą go nie emitować w sposób ciągły.
Potwierdzenie wysłania promptu przez użytkownika lub wstrzyknięte sterowanie. Status: OPTIONAL in v1.
{
"type": "message.sent",
"id": "ev-msg-sent-01",
"chat": "default",
"text": "Refactor database connections",
"length": 29
}Odebranie odpowiedzi od modelu asystenta w IDE (częściowe lub całkowite). Status: NOT YET UNIVERSALLY AVAILABLE.
{
"type": "message.received",
"id": "ev-msg-recv-02",
"chat": "default",
"text": "Sure, I have updated the client.py file...",
"summary": "Updated database pool configuration in client.py"
}- Uwaga implementacyjna: w aktualnym VS Code bridge tekst odpowiedzi LLM nie jest jeszcze przechwytywany.
Błędy wewnętrzne wtyczki lub integracji IDE. Status: IMPLEMENTATION-DEFINED.
{
"type": "status.error",
"id": "ev-err-409",
"message": "Cascade input field not found in DOM",
"severity": "warning",
"source": "probe-ladder"
}Żądanie wstrzyknięcia tekstu do aktywnego chatu IDE i opcjonalnego wykonania zatwierdzenia (Submit). Status: REQUIRED in v1.
{
"type": "chat.send",
"id": "drive-9a8f2c",
"text": "Napisz test jednostkowy dla modułu protocol.py w pytest.",
"submit": true
}- Pola:
text(string): Prompt/wskazówki, które mają zostać wklejone.submit(boolean): Jeślitrue, wtyczka powinna automatycznie wysłać prompt (kliknąć wyślij / nacisnąć Enter). Jeślifalse, wtyczka powinna tylko wkleić tekst do pola edycji.
Zapytanie o stan aktywności (keep-alive). Status: REQUIRED in v1.
{
"type": "ping",
"id": "ping-482"
}Nakaz natychmiastowego wygaszenia integracji lub odłączenia klienta. Status: REQUIRED in v1.
{
"type": "shutdown",
"id": "shutdown-99"
}Żądanie odpalenia autopilota. Wysyłane przez CLI koru autopilot drive.
Status: REQUIRED in v1.
{
"type": "drive",
"id": "cli-drive-11",
"text": "Refactor protocol decoding logic",
"submit": true,
"ide": "cursor",
"require_plugin": false
}- Pola:
text(string): Tekst zadania.submit(boolean): Flaga natychmiastowego wysłania chatu.ide(string): Wskazanie konkretnego IDE (auto,cursor,windsurf,vscode).require_plugin(boolean): Jeślitrue, uniemożliwi keyboard-injector fallback i wygeneruje błąd, jeśli dedykowana wtyczka nie jest połączona.
Polityka wersji pluginu: gdy daemon używa ścieżki pluginowej, do wyniku
ack może dodać plugin_version, expected_plugin_version,
plugin_version_mismatch i plugin_version_policy. Domyślnie mismatch jest
ostrzegawczy (plugin_version_policy="warn"). Przy KORU_STRICT_PLUGIN_VERSION=1
lub KORU_PLUGIN_VERSION_POLICY=strict daemon zwraca error przed wysłaniem
chat.send do stale pluginu. Tryb strict jest fail-closed: jeśli daemon nie
potrafi ustalić expected_plugin_version, blokuje plugin drive zamiast
akceptować potencjalnie stary runtime.
Zapytanie o bieżący stan daemona, podłączone wtyczki, statusy procesów i dostępne backendy wstrzykiwania. Status: REQUIRED in v1.
{
"type": "status",
"id": "cli-status-9"
}Odpowiedź status zawiera listę plugins; każdy wpis zawiera co najmniej
ide i fd, a jeśli plugin zgłosił wersję w hello, także version.
Wersje zainstalowane na dysku (installed) i wersja oczekiwana (expected)
nie są częścią wire status; raportuje je komenda warstwy operacyjnej
koru autopilot manage.
Uniwersalna ramka potwierdzenia odbioru/przetwarzania. Zawsze niesie pasujące id w celu korelacji asynchronicznej.
Status: REQUIRED in v1.
{
"type": "ack",
"id": "drive-9a8f2c",
"ok": true,
"delivered": true,
"opened": true,
"submitted": true,
"winning_focus_open": "workbench.action.chat.open",
"winning_paste": "type",
"winning_submit": "type:\n"
}- Pola dodatkowe (spłaszczone z
infopo stronie helpera):ok(boolean): Ramka została zaakceptowana/przetworzona na poziomie handlera.delivered(boolean): Czy tekst trafił do edytora chatu.opened(boolean): Czy panel chatu został otwarty/skupiony.submitted(boolean): Czy prompt został wysłany.winning_focus_open,winning_paste,winning_submit: opcjonalne pola diagnostyczne (probe-ladder).verification: poziom potwierdzenia (strict,plugin_ack,event_only,plugin_error).plugin_version,expected_plugin_version,plugin_version_mismatch,plugin_version_policy: opcjonalne metadane driftu wersji live pluginu.
Normatywna semantyka ack (v1):
ok=truenie musi oznaczać pełnego sukcesu submitu end-to-end.- Flagi
delivered,opened,submittedsą semantycznie niezależne i mogą występować w różnych kombinacjach. - Pola
winning_*oraz inne metadata są opcjonalne i implementacyjno-diagnostyczne.
Zgłoszenie błędu przetwarzania ramki lub awarii wykonania polecenia. Status: REQUIRED in v1.
{
"type": "error",
"id": "drive-9a8f2c",
"ok": false,
"message": "no connected autopilot plugin for ide=cursor; keyboard fallback disabled."
}Jeśli klient lub adapter implementuje tylko bazowy, stabilny zestaw v1,
rekomendowany profil minimalny obejmuje:
- plugin/adapter:
hello+ obsługachat.send+ odpowiedźack|error, - operator/CLI:
drive,status,ping,shutdown, - envelope:
ack,error.
Eventy lifecycle (session.*, message.*) są wartościowe, ale nie są wymagane
do bazowej interoperacyjności sterowania.
Różne wersje IDE i wbudowane w nie chaty posiadają odmienne interfejsy programistyczne (API). Ścisły kontrakt v1 dopuszcza w hello tylko pola ide, version i pid, a decoder ignoruje pola spoza allowlisty. Capabilities pozostają więc opisowym modelem adaptera/future extension, a nie dodatkowym payloadem ramki hello.
W praktyce rolę „negocjacji” pełni dziś głównie:
- probe ladder po stronie pluginu VS Code/VSCodium/Windsurf/Cursor,
- metadane zwrotne w
ack(winning_focus_open,winning_paste,winning_submit,probe_ladder).
Przykładowy JSON capabilities należy traktować jako aspiracyjny model rozszerzenia,
nie element normatywnego hello w v1.
- Nieznany
type->error. - Nieprawidłowe ramki (UTF-8/JSON/schemat) ->
error. - Nieznane pola opcjonalne są ignorowane tylko tam, gdzie dopuszcza to schemat
typu (w praktyce głównie
ack/error).
v1: stabilne sterowanie (hello,chat.send,drive,status,ack,error).v1.x(opcjonalnie): capability hints bez łamania kompatybilności.v2: dedykowane ramki negocjacji (np.capabilities.report) i pełniejszy lifecycle/reply events.
W aktualnym stanie runtime decyzje daemona opierają się głównie na:
- wyniku wykonania komendy i metadanych
ack, - polityce fallback (
require_plugin, dostępne backendy), - polityce wersji pluginu (
plugin_version_mismatch,KORU_STRICT_PLUGIN_VERSION,KORU_PLUGIN_VERSION_POLICY), - sygnałach pętli autonomicznej (kolejka, verify, diagnostyka),
- opcjonalnych hintach lifecycle (
session.*,message.*) gdy adapter je emituje.
Daemon koru utrzymuje stan sesji sterowania w pętli autopilot. Poniższy automat opisuje model docelowy, a nie gwarantowany przebieg każdego adaptera IDE:
stateDiagram-v2
[*] --> Disconnected : Start Daemona
Disconnected --> Connected : hello (Plugin podłączony)
Connected --> Idle : Rejestracja OK
Idle --> DriveRequested : drive (CLI / kolejka)
DriveRequested --> DriveDelivered : plugin chat.send accepted
DriveRequested --> Degraded : strict plugin version mismatch
DriveRequested --> DriveFallback : plugin unavailable/error + fallback
DriveDelivered --> WaitingLifecycleHint : waiting adapter events
DriveFallback --> WaitingLifecycleHint : prompt injected by OS path
WaitingLifecycleHint --> VerifyScheduled : queue/autoloop schedules verify
WaitingLifecycleHint --> Stalled : waiting_input / brak postępu / cooldown skip
Stalled --> DriveRequested : kolejne zadanie lub retry
VerifyScheduled --> Idle : verify success
VerifyScheduled --> Degraded : verify fail / diagnostics fail
Degraded --> DriveRequested : self-heal prompt
Connected --> Disconnected : socket_close / error / shutdown
Idle --> Disconnected : socket_close / error / shutdown
DriveRequested --> Disconnected : socket_close / error / shutdown
WaitingLifecycleHint --> Disconnected : socket_close / error / shutdown
- DriveRequested: daemon próbuje ścieżkę pluginową; przy błędzie/przerwie przechodzi do fallbacku (jeśli
require_plugin=false). Przedchat.sendmoże zablokować stale plugin, gdy strict version gate jest aktywny. - DriveDelivered / DriveFallback: prompt został przekazany odpowiednio przez plugin lub przez injector OS.
- WaitingLifecycleHint: system czeka na hinty adaptera (
session.*,message.*) i równolegle na sygnały postępu kolejki. - VerifyScheduled:
post_run_verifyjest planowane/uruchamiane przez pętlę autonomiczną, nie przez sam fakt nadejścia pojedynczego eventu pluginu. - Stalled: brak postępu (
waiting_input, stagnacja, cooldown safeguard) — możliwe skipy lub retry. - Degraded: ścieżka po błędach verify/diagnostics; zwykle kończy się nowym promptem self-heal.
UWAGA (Cooldown Safeguard): aby ograniczyć pętle nieskończone, session.ended
odebrane zbyt szybko po chat.send może zostać zignorowane (cooldown), bez natychmiastowego reinject.
Scenariusz: Autopilot pobiera zadanie z kolejki i wstrzykuje je do IDE przez plugin; dalej pętla autonomiczna decyduje o verify.
-
Uruchomienie Daemona i podłączenie wtyczki (Cursor):
[Plugin -> Daemon]: {"type":"hello","id":"h1","ide":"cursor","version":"0.1.0","pid":4012} [Daemon -> Plugin]: {"type":"ack","id":"h1","ok":true,"role":"plugin"} -
Wstrzyknięcie zadania autopilot (CLI / Queue Loop):
[CLI -> Daemon]: {"type":"drive","id":"drv-123","text":"Napisz funkcję add(a, b) w math.py","submit":true} [Daemon -> Plugin]: {"type":"chat.send","id":"drv-123","text":"Napisz funkcję add(a, b) w math.py","submit":true} -
Wtyczka otwiera chat, wkleja i submituje:
[Plugin -> Daemon]: {"type":"message.sent","chat":"default","text":"Napisz funkcję add(a, b) w math.py","length":35} [Plugin -> Daemon]: {"type":"ack","id":"drv-123","ok":true,"delivered":true,"opened":true,"submitted":true} [Daemon -> CLI]: {"type":"ack","id":"drv-123","ok":true,"delivered":true,"opened":true,"submitted":true,"backend":"plugin","plugin_version":"0.1.13","expected_plugin_version":"0.1.13","plugin_version_mismatch":false}Jeśli live plugin zgłosi np.
version="0.1.11", a bieżąca paczka koru oczekuje0.1.13, daemon może zwrócićackzplugin_version_mismatch=truew trybie ostrzegawczym. PrzyKORU_STRICT_PLUGIN_VERSION=1zamiastchat.sendzwracaerror. -
Asystent IDE generuje kod i kończy odpowiedź (zdarzenia lifecycle opcjonalne):
[Plugin -> Daemon]: {"type":"session.ended","chat":"default","reason":"completed"} // jeśli wspierane przez plugin/API IDE -
Weryfikacja post-run:
- Daemon odsyła
ackdla każdego odebranego eventu pluginu (w tymsession.ended, jeśli nadejdzie):[Daemon -> Plugin]: {"type":"ack","id":"session-event","ok":true,"event":"session.ended"} - Pętla autonomiczna uruchamia
pytest/ruffzgodnie z konfiguracjąpost_run_verify. - Jeśli testy przejdą pomyślnie (
Exit Code: 0):- Zapis do logu audytowego:
audit.record("cycle_completed", ticket="PLF-123", verify="success"). - Stan daemona wraca do
Idle(pobranie kolejnego zadania).
- Zapis do logu audytowego:
- Daemon odsyła
Gdy bezpośrednia komunikacja z wtyczką nie powiedzie się lub wtyczka nie jest połączona (require_plugin: false), daemon uruchamia kaskadę fallbacków:
- Plugin (Primary): Próba wstrzyknięcia przez
chat.send. - OS Injector Profile (Secondary Fallback): Wykrycie aktywnego okna za pomocą profili interfejsu (np. wyznaczenie współrzędnych pola wprowadzania chatu i symulacja kliknięcia oraz pisania).
- Keyboard Simulation (Tertiary Fallback):
- System X11: Uruchomienie narzędzia
xdotoolz matrixem czyszczenia modyfikatorów klawiatury (--clearmodifiers). - System Wayland (Hyprland / Sway): Wykorzystanie wirtualnej konsoli
wtype. - System Wayland (GNOME): Wykorzystanie daemona
ydotool(wymaga dostępu do/dev/uinput).
- System X11: Uruchomienie narzędzia
- Clipboard Injection (Last Resort): Wstrzyknięcie przez schowek (
Ctrl+V) jest wykonywane jako tryb awaryjny. Przywrócenie schowka jest implementowane w ścieżce pluginowej VS Code, natomiast fallbackos_injectornie gwarantuje obecnie pełnego restore.
Zdarzenia mogą być rejestrowane w ~/.local/state/koru/autopilot.log (lub $XDG_STATE_HOME/koru/autopilot.log), gdy audit jest włączony. W trybie uruchomienia daemona przez CLI audit jest domyślnie aktywny.
| Funkcja / Event | VS Code / Cursor / Windsurf | JetBrains |
|---|---|---|
hello |
tak | tak |
obsługa chat.send |
tak | nie (scaffold) |
emisja message.sent |
tak | nie |
emisja session.started |
częściowo / best-effort | nie |
emisja session.ended |
częściowo / best-effort | nie (planowane) |
emisja message.received |
nie (w praktyce brak stabilnego capture) | nie |
Tabela opisuje bieżący stan implementacji adapterów i nie zmienia normatywnego
kontraktu wire v1.
- Dla środowisk produkcyjnych i przebiegów CI-like zalecany jest tryb
require_plugin=true(bez fallbacku keyboard/clipboard). - Dla soak/autonomous runs, w których niedopuszczalny jest stary live plugin,
zalecane jest
KORU_STRICT_PLUGIN_VERSION=1. W tym trybie drift wersji blokujedriveprzed wysłaniemchat.send. - Ścieżki
os_injector/keyboard mają niższy poziom zaufania niż plugin bridge (ryzyko trafienia do niewłaściwego okna/pola wejścia). - Użycie fallbacku powinno być logowane audytowo wraz z informacją o backendzie.
- Clipboard fallback może modyfikować schowek użytkownika; pełne restore nie jest gwarantowane na każdej ścieżce backendowej.
- plugin-only:
require_plugin=true, brak fallbacku OS; najwyższa przewidywalność. - plugin-only strict:
require_plugin=true+KORU_STRICT_PLUGIN_VERSION=1; najwyższa przewidywalność przy wielu wersjach pluginu/IDE. - plugin-preferred with fallback: domyślny tryb roboczy desktop (
require_plugin=false). - visible typing: preferencja backendów typujących zamiast ukrytego paste.
- unattended soak mode: autoloop + diagnostyka + verify, z audit trail i kontrolą stagnacji.
- Problem:
message.receivedi pełny read-side odpowiedzi modelu nie są stabilnie dostępne we wszystkich IDE. - Wpływ:
message.sentpotwierdza wysłanie promptu, ale nie jest dowodem, że agent IDE zakończył pracę ani że kod został zmieniony. - Obejście: pętla autonomiczna używa queue state,
post_run_verify, diagnostyki i TestQL/WUP zamiast traktować pojedynczy event chatu jako pełny sukces end-to-end.