# kg-droid-hook

Minimalny plugin dla `factory.ai` `droid`, ktory loguje:

- prompty uzytkownika przez `UserPromptSubmit`
- koncowa odpowiedz droida przez `Stop`

Opcjonalnie plugin moze tez odpytywac `kg graph` i wstrzykiwac do kontekstu Droida
pasujace nody znalezione na podstawie biezacego promptu i ostatnich wiadomosci
uzytkownika z transcriptu.

Plugin zapisuje logi jako JSONL w:

```text
~/.factory/kg-droid-hook/
```

Domyslne pliki:

- `prompts.jsonl`
- `responses.jsonl`

Mozesz zmienic katalog logow przez zmienna srodowiskowa `KG_DROID_HOOK_LOG_DIR`.

## Integracja z `kg`

Ustaw nazwe grafu, z ktorego chcesz pobierac kontekst:

```sh
export KG_DROID_HOOK_GRAPH=eyg
```

Domyslnie plugin probuje wykryc nasze repo `kg` na podstawie `cwd` sesji Droida i wtedy
uruchamia lokalne:

```sh
cargo run --quiet --bin kg --
```

Jezeli nie znajdzie repo, fallbackuje do komendy `kg` z `PATH`.

`KG_DROID_HOOK_KG_CMD` zostalo tylko jako opcjonalny override, jesli chcesz wymusic
konkretne binarium albo komende developerska:

```sh
export KG_DROID_HOOK_KG_CMD='kg'
```

Przyklad override do lokalnego buildu:

```sh
export KG_DROID_HOOK_KG_CMD='cargo run --quiet --bin kg --'
```

Mozesz tez zmienic limit wynikow na zapytanie:

```sh
export KG_DROID_HOOK_FIND_LIMIT=3
```

Po ustawieniu `KG_DROID_HOOK_GRAPH` hook `UserPromptSubmit`:

- bierze biezacy prompt
- bierze kilka ostatnich wiadomosci usera z `transcript_path`
- odpala `kg graph <GRAPH> node find ... --json`
- deduplikuje trafione nody
- dodaje skrocony kontekst do promptu Droida jako `additionalContext`

## Instalacja lokalna

Z katalogu repo:

```sh
droid plugin marketplace add /home/mariopr/projects/kg/kg-droid-hook
droid plugin install kg-droid-hook@kg-droid-hook --scope user
```

Ten katalog jest jednoczesnie pluginem i lokalnym marketplace, wiec `marketplace add`
powinno wskazywac bezposrednio na `kg-droid-hook/`.

Albo dla samego projektu:

```sh
droid plugin install kg-droid-hook@kg-droid-hook --scope project
```

## Co robi plugin

### `UserPromptSubmit`

Skrypt `hooks/log_prompt.py` zapisuje wpis z polami:

- `timestamp`
- `session_id`
- `cwd`
- `transcript_path`
- `prompt`
- `graph`
- `queries`
- `context_added`
- `additional_context`
- `context_error`

### `Stop`

Skrypt `hooks/log_stop.py` probuje wyciagnac ostatnia odpowiedz asystenta z pliku `transcript_path` i zapisuje:

- `timestamp`
- `session_id`
- `cwd`
- `transcript_path`
- `reply`
- `reply_found`

To jest best-effort parsing transcriptu. Jezeli aktualny format transcriptu droida rozni sie od przewidzianego schematu, wpis nadal zostanie zapisany, ale `reply_found` moze byc `false`.

## Przyklad logu promptu

```json
{"timestamp":"2026-04-04T12:00:00+00:00","hook_event_name":"UserPromptSubmit","session_id":"abc","cwd":"/repo","transcript_path":"/tmp/session.jsonl","prompt":"napraw testy checkoutu","graph":"eyg","queries":["napraw testy checkoutu","checkout"],"context_added":true,"additional_context":"Relevant kg graph context from `eyg`:\n- concept:checkout | Checkout [Concept]","context_error":null}
```

## Przyklad logu odpowiedzi

```json
{"timestamp":"2026-04-04T12:00:05+00:00","hook_event_name":"Stop","session_id":"abc","cwd":"/repo","transcript_path":"/tmp/session.jsonl","reply":"Naprawilem testy.","reply_found":true,"stop_hook_active":false}
```

## Szybki test z `kg`

```sh
export KG_DROID_HOOK_LOG_DIR=/tmp/kg-droid-hook-test
export KG_DROID_HOOK_GRAPH=eyg
rm -rf /tmp/kg-droid-hook-test
mkdir -p /tmp/kg-droid-hook-test
droid --debug
```

Wyslij prompt zawierajacy fraze, ktora istnieje w grafie. Po odpowiedzi sprawdz:

```sh
cat /tmp/kg-droid-hook-test/prompts.jsonl
cat /tmp/kg-droid-hook-test/responses.jsonl
```

Jesli `context_added` ma wartosc `true`, to hook znalazl nody w grafie i dodal je
do kontekstu przed odpowiedzia Droida.

Hook filtruje tez techniczne wpisy Droida z transcriptu, takie jak `system-reminder`,
anulowane requesty i komunikaty o `TodoWrite`, zeby nie trafialy do query dla `kg`.
