@kahinmcp/kahin 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.md +28 -13
- package/bin/setup.mjs +1 -1
- package/docs/juggler-ai-native.md +449 -0
- package/lib/kahin-0.3.5-py3-none-any.whl +0 -0
- package/package.json +4 -3
- package/lib/kahin-0.3.3-py3-none-any.whl +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.5] — 2026-08-06
|
|
4
|
+
|
|
5
|
+
### Düzeltilen
|
|
6
|
+
- `kahin_browser_start()` artık varsayılan olarak gerçek Camoufox/Mirage
|
|
7
|
+
başlatıyor; screenshot, mobile viewport, screencast, upload ve accessibility
|
|
8
|
+
çağrıları Shadow seçilmiş olsa bile Kahin içinde görsel backend'e yükseltiliyor.
|
|
9
|
+
- Yeni capability sözleşmesi `kahin_engine_health` yanıtında motorun gerçek
|
|
10
|
+
görsel/mobile/DOM-stream/a11y/screencast sınırlarını raporluyor; generic
|
|
11
|
+
`kahin_screenshot` ve `Page.captureScreenshot` yolu dış otomasyon fallback'i
|
|
12
|
+
kullanmadan Camoufox'a geçiyor.
|
|
13
|
+
- Shadow/Obscura artık bağımsız MCP/OpenCode süreçleri arasında sabit `9241`
|
|
14
|
+
portunu paylaşmıyor; varsayılan başlatma her child için geçici loopback portu
|
|
15
|
+
kullanıyor ve gerçek portu raporluyor.
|
|
16
|
+
- Port çakışmasında ikinci child'ın yabancı browser WebSocket'ine bağlanıp
|
|
17
|
+
yanlışlıkla `started` dönmesi engellendi; child kararlılığı doğrulanmadan
|
|
18
|
+
engine state'e yayınlanmıyor ve başarısız child temizleniyor.
|
|
19
|
+
- Mirage/Zig sidecar shutdown cancellation path'i child ve IPC kaynaklarını
|
|
20
|
+
güvenle temizliyor.
|
|
21
|
+
|
|
22
|
+
### Testler
|
|
23
|
+
- İki bağımsız Shadow instance'ı ve explicit port çakışması gerçek Obscura
|
|
24
|
+
binary'siyle regresyon testine alındı.
|
|
25
|
+
- Shadow -> Camoufox screenshot handoff ve varsayılan motor gerçek browser ile
|
|
26
|
+
doğrulandı.
|
|
27
|
+
- Python runtime suite: 115 passed; Zig sidecar tests/build: passed.
|
|
28
|
+
|
|
29
|
+
## [0.3.4] — 2026-08-05
|
|
30
|
+
|
|
31
|
+
### Eklenen
|
|
32
|
+
- Mirage/Juggler için gerçek-zamanlı DOM stream: bounded semantic snapshot,
|
|
33
|
+
cursor tabanlı MutationObserver + input/focus/click/change event delta'ları,
|
|
34
|
+
reset/dropped sinyalleri ve canlı nodeId action yüzeyi.
|
|
35
|
+
- `kahin_mirage_dom_start`, `kahin_mirage_dom_snapshot`,
|
|
36
|
+
`kahin_mirage_dom_events`, `kahin_mirage_dom_action`,
|
|
37
|
+
`kahin_mirage_dom_stop` olmak üzere 5 yeni tool.
|
|
38
|
+
- Ajanların source okumadan kullanacağı [AI-native Juggler kılavuzu](docs/juggler-ai-native.md).
|
|
39
|
+
|
|
40
|
+
### Değişen
|
|
41
|
+
- MCP server instructions artık adaptive Mirage DOM akışını, cursor/reset ve
|
|
42
|
+
canlı nodeId kurallarını doğrudan ajana bildiriyor.
|
|
43
|
+
|
|
44
|
+
### Testler
|
|
45
|
+
- Gerçek Camoufox e2e: DOM snapshot + delta + canlı type/click action ve
|
|
46
|
+
navigation sonrası stream reset regresyonları.
|
|
47
|
+
|
|
3
48
|
Tüm önemli değişiklikler bu dosyada tutulur. Format: [Keep a Changelog](https://keepachangelog.com/tr/1.1.0/) — [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
49
|
|
|
5
50
|
## [0.3.3] — 2026-08-05
|
|
@@ -103,6 +148,8 @@ Tüm önemli değişiklikler bu dosyada tutulur. Format: [Keep a Changelog](http
|
|
|
103
148
|
- Zig Juggler harness: pipe transport, Browser/Page/Runtime/Network/Input/Emulation adapters, interception, process manager, perf + crash-recovery
|
|
104
149
|
- CDP ansiklopedisi: 56 domain, 667 komut, 237 event, 609 type (Chrome 148)
|
|
105
150
|
|
|
151
|
+
[0.3.4]: https://gitlab.com/void0x14/kahin-mcp/-/compare/v0.3.3...v0.3.4
|
|
152
|
+
[0.3.5]: https://gitlab.com/void0x14/kahin-mcp/-/compare/v0.3.4...v0.3.5
|
|
106
153
|
[0.3.3]: https://gitlab.com/void0x14/kahin-mcp/-/compare/v0.3.2...v0.3.3
|
|
107
154
|
[0.3.2]: https://gitlab.com/void0x14/kahin-mcp/-/compare/v0.3.1...v0.3.2
|
|
108
155
|
[0.2.0]: https://gitlab.com/void0x14/kahin-mcp/-/compare/v0.1.8...v0.2.0
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ AI modeller Chrome'un içine girip sayfa gezip kod çalıştırabilir ama CDP'yi
|
|
|
16
16
|
|
|
17
17
|
56 domain, 667 komut, 237 event, 609 type — Chrome 148 protokolü gömülü.
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## 109 Tool · 4 Kategori Ailesi · 2 Engine
|
|
20
20
|
|
|
21
21
|
Tool'lar engine-ayrımlı kategori dosyalarında (`kahin/tools/`): paylaşılan çekirdek + Obscura + Camoufox aileleri.
|
|
22
22
|
|
|
@@ -29,10 +29,10 @@ Tool'lar engine-ayrımlı kategori dosyalarında (`kahin/tools/`): paylaşılan
|
|
|
29
29
|
| DEJA_VU — Debug | CDP event geçmişi, network istekleri, console mesajları | 4 |
|
|
30
30
|
| PROPHECY — Pattern DB | Kullanım desenlerini öğren, sorgula, öner | 5 |
|
|
31
31
|
| HEALER | Hata istatistikleri | 1 |
|
|
32
|
-
| MIRAGE — Camoufox Native (
|
|
32
|
+
| MIRAGE — Camoufox Native (77) | Juggler protokolü üstünde gerçek-zamanlı DOM stream, DOM, Input, PageEx, Tab, Network, Storage, Emulation, Dialog/Download/Worker/WS, Upload, Screencast, Accessibility, Engine sağlığı | 77 |
|
|
33
33
|
| OBSCURA — Ayrı kategori | Obscura'ya özel tool'lar (hazırlanıyor) | 0 |
|
|
34
34
|
|
|
35
|
-
**Toplam:
|
|
35
|
+
**Toplam: 109 tool.**
|
|
36
36
|
|
|
37
37
|
## Bir satırda özet
|
|
38
38
|
|
|
@@ -87,7 +87,13 @@ Gerisini AI halleder. Ama dilersen tool'ları direkt de çağırabilirsin:
|
|
|
87
87
|
→ kahin_error_decode(error_code=-32601) → hatayı çözümler
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
`kahin_browser_start` varsayılan olarak Camoufox/Mirage başlatır. Shadow
|
|
91
|
+
yalnızca hızlı, görsel olmayan CDP işleri için açıkça seçilir; screenshot,
|
|
92
|
+
mobile viewport, screencast, upload veya accessibility isteyen bir tool,
|
|
93
|
+
Shadow'ı Kahin içinde Camoufox'a yükseltir. Ajanın başka bir otomasyon
|
|
94
|
+
kütüphanesine geçmesi gerekmez.
|
|
95
|
+
|
|
96
|
+
Camoufox (Juggler native) ile:
|
|
91
97
|
|
|
92
98
|
```
|
|
93
99
|
→ kahin_browser_start(engine="mirage")
|
|
@@ -99,6 +105,8 @@ Camoufox (Juggler native) ile, engine `mirage` seçilince:
|
|
|
99
105
|
→ kahin_mirage_set_file_chooser_intercept(true) → kahin_mirage_upload_files(["/abs/path"])
|
|
100
106
|
→ kahin_mirage_screencast_start → kahin_mirage_screencast_frame (base64 JPEG)
|
|
101
107
|
→ kahin_mirage_accessibility_tree → kahin_engine_health
|
|
108
|
+
→ kahin_mirage_dom_start → kahin_mirage_dom_snapshot → kahin_mirage_dom_events
|
|
109
|
+
→ kahin_mirage_dom_action (snapshot'tan alınan canlı nodeId ile)
|
|
102
110
|
```
|
|
103
111
|
|
|
104
112
|
`kahin_browser_start` tek bir Camoufox/sidecar süreci açar. İlk sayfa işlemi
|
|
@@ -108,7 +116,8 @@ yerine `kahin_mirage_tab_new` ve `kahin_mirage_tab_switch` kullanın. Camoufox
|
|
|
108
116
|
aktifken `kahin_execute_cdp` ve diğer CDP araçları, eşdeğer Juggler/Mirage
|
|
109
117
|
çağrısına otomatik yönlendirilir ve CDP biçimli sonuç döndürür.
|
|
110
118
|
|
|
111
|
-
Tam liste için: [AGENTS.md](AGENTS.md)
|
|
119
|
+
Tam liste için: [AGENTS.md](AGENTS.md). Juggler'ın ajan sözleşmesi ve gerçek-zamanlı
|
|
120
|
+
DOM akışı için [AI-native Juggler kılavuzuna](docs/juggler-ai-native.md) bakın.
|
|
112
121
|
|
|
113
122
|
## Proje Felsefesi
|
|
114
123
|
|
|
@@ -127,8 +136,13 @@ mcp · orjson · Levenshtein · websockets · httpx · camoufox · Pillow · pyd
|
|
|
127
136
|
|------|-------|----------|
|
|
128
137
|
| 9222 | Chrome DevTools | RESERVED |
|
|
129
138
|
| 9240 | Kusatma Engine | RESERVED |
|
|
130
|
-
| 9241 | Obscura
|
|
131
|
-
|
|
|
139
|
+
| 9241 | Eski Shadow/Obscura sabit portu | Varsayılan olarak kullanılmaz |
|
|
140
|
+
| — | Mirage/Camoufox | TCP portu yok; Juggler stdio pipe kullanır |
|
|
141
|
+
|
|
142
|
+
Shadow/Obscura için `kahin_browser_start` port verilmeden çağrıldığında Kahin,
|
|
143
|
+
her child için loopback üzerinde kernel'den geçici bir port alır. Böylece aynı
|
|
144
|
+
makinedeki bağımsız MCP/OpenCode süreçleri birbirlerinin WebSocket'ine bağlanmaz.
|
|
145
|
+
Sabit port yalnızca özellikle `port=...` verildiğinde kullanılır.
|
|
132
146
|
|
|
133
147
|
## Kendi Kendini Onarma
|
|
134
148
|
|
|
@@ -142,8 +156,9 @@ Kahin'de hata loglama ve kendini onarma sistemi gömülüdür:
|
|
|
142
156
|
|
|
143
157
|
```
|
|
144
158
|
oracle.py → MCP server (bootstrap: mcp instance + engine lifecycle + main)
|
|
145
|
-
tools/ →
|
|
146
|
-
_common.py → _safe_cdp, _require_engine, _auto_learn
|
|
159
|
+
tools/ → 109 tool, engine-ayrımlı kategori dosyaları
|
|
160
|
+
_common.py → capability routing, _safe_cdp, _require_engine, _auto_learn
|
|
161
|
+
the_twins/capabilities → motor-yetenek sözleşmesi ve Mirage yükseltme matrisi
|
|
147
162
|
grimoire/seraph/prophecy/healer → CDP bilgi + doğrulama + pattern (paylaşılan)
|
|
148
163
|
pilot/trainman/dejavu → browser/session/debug (paylaşılan)
|
|
149
164
|
pilot_mirage/trainman_mirage/dejavu_mirage → Camoufox DOM+Input+PageEx / Tab / Network+Console
|
|
@@ -163,14 +178,14 @@ camoufox-harness/ → Zig sidecar (Juggler protocol, vendor binary gömül
|
|
|
163
178
|
|
|
164
179
|
## 🗺️ Yol Haritası
|
|
165
180
|
|
|
166
|
-
- [
|
|
167
|
-
- [x] **Camoufox entegrasyonu tamamlandı** — gerçek Camoufox (Zig sidecar + Juggler pipe)
|
|
181
|
+
- [x] **Juggler protokolü** için AI-native uçtan uca dokümantasyon, kullanım ve pratik örnekleri
|
|
182
|
+
- [x] **Camoufox entegrasyonu tamamlandı** — gerçek Camoufox (Zig sidecar + Juggler pipe) varsayılandır; görsel capability isteyen Shadow çağrıları Kahin içinde Mirage'a yükseltilir
|
|
168
183
|
- [x] **Obscura entegrasyonu tamamlandı** — gerçek Obscura binary'si (WebSocket CDP) ile çalışıyor, startup problemleri giderildi
|
|
169
184
|
- [ ] **SKILLS** destekleri ve konfigre edilebilir kişsiel hazır skills oluşturma özelliği
|
|
170
185
|
- [x] **Tek tık kurulum** — `pnpm add -g @kahinmcp/kahin`, sonra `kahin` (ilk çalıştırmada Python ortamını otomatik kurar)
|
|
171
186
|
- [ ] **Zero-dependency** hedefi (Go/Rust portu)
|
|
172
187
|
- [ ] **LSP modu** — kod içinde hata yakalama, AI'a yanlışını yüzüne vurma
|
|
173
|
-
- [x] **Tool sayısı
|
|
188
|
+
- [x] **Tool sayısı 109** — Camoufox Juggler-native 77 tool (gerçek-zamanlı DOM stream, DOM, Input, Network, Storage, Emulation, Dialog, Tab, Worker/WS, Upload, Screencast, Accessibility) + paylaşılan 32 çekirdek
|
|
174
189
|
- [ ] **Obscura ayrı tool'ları** — CDP-yeteneklerine özel pilot_obscura/trainman_obscura/dejavu_obscura kategorilerini doldur
|
|
175
190
|
|
|
176
191
|
- [ ] **Gerçek zamanlı izleme** — AI'ın Kahin'i nasıl kullandığını canlı gör
|
|
@@ -192,7 +207,7 @@ camoufox-harness/ → Zig sidecar (Juggler protocol, vendor binary gömül
|
|
|
192
207
|
## Geliştirme
|
|
193
208
|
|
|
194
209
|
```bash
|
|
195
|
-
uv run pytest tests/ #
|
|
210
|
+
uv run pytest tests/ # 109 tests (all pass when Camoufox is available)
|
|
196
211
|
uv run ruff check kahin/ # lint
|
|
197
212
|
uv run python -m kahin.oracle # manuel başlatma
|
|
198
213
|
```
|
package/bin/setup.mjs
CHANGED
|
@@ -324,7 +324,7 @@ export function setup() {
|
|
|
324
324
|
const KAHIN_HOME = process.env.KAHIN_HOME || join(homedir(), ".local", "share", "kahin");
|
|
325
325
|
const KAHIN_VENV = join(KAHIN_HOME, "venv");
|
|
326
326
|
const KAHIN_PY = process.platform === "win32" ? join(KAHIN_VENV, "Scripts", "python.exe") : join(KAHIN_VENV, "bin", "python");
|
|
327
|
-
const KAHIN_WHEEL = join(dirname(fileURLToPath(import.meta.url)), "..", "lib", "kahin-0.3.
|
|
327
|
+
const KAHIN_WHEEL = join(dirname(fileURLToPath(import.meta.url)), "..", "lib", "kahin-0.3.5-py3-none-any.whl");
|
|
328
328
|
|
|
329
329
|
// Gömülü wheel'i venv'e kurar. Postinstall'da ve `kahin setup`'ta çalışır.
|
|
330
330
|
// PyPI'a bağımlı DEĞİL — wheel paketle birlikte gelir.
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
# Kahin Juggler: AI-native kullanım kılavuzu
|
|
2
|
+
|
|
3
|
+
Bu belge, bir ajanın Camoufox/Mirage tarayıcısını kaynak kodu okumadan
|
|
4
|
+
kullanabilmesi için sözleşmeyi anlatır. Mirage, Chrome CDP'si değildir:
|
|
5
|
+
Kahin'in Zig sidecar'ı gerçek Juggler mesajlarını JSONL olarak taşır ve MCP
|
|
6
|
+
tool'ları bu yüzeyi ajana güvenli, yapılandırılmış bir biçimde sunar.
|
|
7
|
+
|
|
8
|
+
## 1. Zihinsel model
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
MCP tool
|
|
12
|
+
-> Kahin Mirage adapter
|
|
13
|
+
-> Zig sidecar (Juggler JSONL)
|
|
14
|
+
-> Camoufox Page/Browser
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- `kahin_browser_start` varsayılan olarak bir Camoufox süreci ve tek bir
|
|
18
|
+
sidecar başlatır. `engine="shadow"` yalnızca hızlı, görsel olmayan CDP
|
|
19
|
+
işleri için açıkça seçilir.
|
|
20
|
+
- Shadow aktifken screenshot, mobile emulation, accessibility, upload veya
|
|
21
|
+
screencast isteyen bir tool çağrısı, aktif URL'i koruyarak Kahin içinde
|
|
22
|
+
Shadow -> Mirage yükseltmesi yapar. Ajanın Playwright ya da başka bir
|
|
23
|
+
otomasyon kütüphanesine geçmesi sözleşme dışıdır.
|
|
24
|
+
- İlk sayfa ilk sayfa tool'u çağrıldığında tembel olarak oluşturulur.
|
|
25
|
+
- Aynı browser'ı ve aktif sekmeyi yeniden kullan. Başka sayfa gerektiğinde
|
|
26
|
+
yeni browser açmak yerine `kahin_mirage_tab_new` ve
|
|
27
|
+
`kahin_mirage_tab_switch` kullan.
|
|
28
|
+
- Juggler'da `Browser.*` browser köküne, `Page.*` ise aktif target/session'a
|
|
29
|
+
aittir. MCP araçları session routing'i ajandan saklar.
|
|
30
|
+
- `kahin_execute_cdp`, Mirage aktifken desteklenen CDP çağrılarını Juggler
|
|
31
|
+
eşdeğerine yönlendirir; görsel capability isteyen bilinen çağrılar Shadow
|
|
32
|
+
aktifse önce Mirage'a yükseltilir. Juggler'da bulunmayan her CDP domain'i
|
|
33
|
+
varmış gibi tahmin etme.
|
|
34
|
+
|
|
35
|
+
## 2. Ajanın temel protokolü
|
|
36
|
+
|
|
37
|
+
Dinamik bir sayfada güvenilir akış şöyledir:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
browser_start(mirage)
|
|
41
|
+
-> navigate
|
|
42
|
+
-> dom_start
|
|
43
|
+
-> dom_snapshot
|
|
44
|
+
-> [dom_events(after_seq, stream_id, wait_ms)]*
|
|
45
|
+
-> dom_action(live_node_id)
|
|
46
|
+
-> dom_snapshot veya evaluate ile doğrulama
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Zorunlu kurallar:
|
|
50
|
+
|
|
51
|
+
1. Bilmediğin bir CDP methodunu göndermeden önce
|
|
52
|
+
`kahin_validate_command` kullan. Hata sonrası
|
|
53
|
+
`kahin_error_decode` ile düzeltmeyi öğren.
|
|
54
|
+
2. CSS selector'ı eylem kimliği olarak uzun süre saklama. Snapshot'taki
|
|
55
|
+
`nodeId`, o document/frame içindeki canlı node'a bağlıdır.
|
|
56
|
+
3. `reset`, `dropped` veya `requiresSnapshot` görüldüğünde eski node/cursor
|
|
57
|
+
bilgisine güvenme; yeni snapshot al.
|
|
58
|
+
4. `truncated=true` tam sayfa anlamına gelmez. Selector, `max_nodes` veya
|
|
59
|
+
`max_depth` ile alanı daralt.
|
|
60
|
+
5. Bir input'a yazdıktan, tıkladıktan veya navigation yaptıktan sonra sonucu
|
|
61
|
+
gözlemle. Eylem yanıtı tek başına uygulama başarısı değildir.
|
|
62
|
+
|
|
63
|
+
## 3. Gerçek zamanlı DOM vericisi
|
|
64
|
+
|
|
65
|
+
DOM stream sayfanın kendi `MutationObserver`'ını ve DOM event listener'larını
|
|
66
|
+
kullanır. Sayfa tarafında bounded bir ring buffer tutulur; sidecar yalnızca
|
|
67
|
+
değişiklik sinyali taşır. Böylece hızlı bir sayfa, sidecar reader'ını büyük
|
|
68
|
+
DOM payload'ları ile bloke etmez.
|
|
69
|
+
|
|
70
|
+
### 3.1 Tool sözleşmesi
|
|
71
|
+
|
|
72
|
+
| Tool | Amaç | Önemli parametreler |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `kahin_mirage_dom_start` | Observer'ı mevcut ve sonraki document'lara kurar | `max_events`, `frame_id` |
|
|
75
|
+
| `kahin_mirage_dom_snapshot` | Sınırlandırılmış, anlamsal canlı ağaç döndürür | `selector`, `max_nodes`, `max_depth`, `include_hidden`, `text_limit`, `frame_id` |
|
|
76
|
+
| `kahin_mirage_dom_events` | Cursor sonrasındaki delta/event'leri okur | `after_seq`, `stream_id`, `limit`, `wait_ms`, `frame_id` |
|
|
77
|
+
| `kahin_mirage_dom_action` | Snapshot nodeId'si üzerinde allow-list eylemi yapar | `node_id`, `action`, `text`, `frame_id` |
|
|
78
|
+
| `kahin_mirage_dom_stop` | Mevcut frame observer'ını ve ring'i kapatır | `frame_id` |
|
|
79
|
+
|
|
80
|
+
`dom_start` sonucu ajanın saklaması gereken kimlik:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"status": "started",
|
|
85
|
+
"stream": {
|
|
86
|
+
"streamId": "mdd1-abc123",
|
|
87
|
+
"cursor": 0,
|
|
88
|
+
"revision": 0,
|
|
89
|
+
"pending": 0,
|
|
90
|
+
"active": true,
|
|
91
|
+
"url": "https://example.test/app",
|
|
92
|
+
"readyState": "complete"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Snapshot sonucu, action için gereken `nodeId` ile birlikte anlamsal bilgi
|
|
98
|
+
verir:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"streamId": "mdd1-abc123",
|
|
103
|
+
"cursor": 4,
|
|
104
|
+
"revision": 4,
|
|
105
|
+
"url": "https://example.test/app",
|
|
106
|
+
"readyState": "complete",
|
|
107
|
+
"nodeCount": 8,
|
|
108
|
+
"truncated": false,
|
|
109
|
+
"focused": null,
|
|
110
|
+
"root": {
|
|
111
|
+
"nodeId": "n1",
|
|
112
|
+
"tag": "main",
|
|
113
|
+
"role": "main",
|
|
114
|
+
"name": "Account",
|
|
115
|
+
"text": "Name Save",
|
|
116
|
+
"visible": true,
|
|
117
|
+
"rect": {"x": 0, "y": 0, "width": 800, "height": 180},
|
|
118
|
+
"attributes": {"id": "account"},
|
|
119
|
+
"actions": [],
|
|
120
|
+
"children": [
|
|
121
|
+
{
|
|
122
|
+
"nodeId": "n4",
|
|
123
|
+
"tag": "input",
|
|
124
|
+
"role": "textbox",
|
|
125
|
+
"name": "Name",
|
|
126
|
+
"value": "",
|
|
127
|
+
"actions": ["focus", "type"]
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Snapshot alanlarının anlamı:
|
|
135
|
+
|
|
136
|
+
- `role`, `name`, `text`: ajanın selector tahmini yerine kullanıcıya görünen
|
|
137
|
+
hedefi anlamasına yardım eder.
|
|
138
|
+
- `visible`, `rect`: görünürlük ve gerçek viewport geometrisidir.
|
|
139
|
+
- `attributes`: yalnızca güvenli tanımlayıcı/erişilebilirlik özniteliklerinin
|
|
140
|
+
bounded alt kümesidir.
|
|
141
|
+
- `value`: input/textarea/select/contenteditable için gelir; password input
|
|
142
|
+
değeri `[redacted]` olur.
|
|
143
|
+
- `actions`: node'un doğrudan desteklediği `click`, `focus`, `type`, `select`
|
|
144
|
+
ipuçlarını gösterir. `select` bu ilk action yüzeyinde uygulanmaz; select
|
|
145
|
+
için mevcut DOM/evaluate veya daha özel tool sözleşmesini kullan.
|
|
146
|
+
- `cursor`: o snapshot anındaki son sequence numarasıdır. Delta okumaya bu
|
|
147
|
+
cursor'dan devam edilir.
|
|
148
|
+
|
|
149
|
+
### 3.2 Delta ve event akışı
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"streamId": "mdd1-abc123",
|
|
154
|
+
"cursor": 7,
|
|
155
|
+
"revision": 7,
|
|
156
|
+
"reset": false,
|
|
157
|
+
"dropped": false,
|
|
158
|
+
"pending": 2,
|
|
159
|
+
"url": "https://example.test/app",
|
|
160
|
+
"events": [
|
|
161
|
+
{
|
|
162
|
+
"seq": 6,
|
|
163
|
+
"timestamp": 1780000000000,
|
|
164
|
+
"type": "childList",
|
|
165
|
+
"target": {"nodeId": "n1", "tag": "main"},
|
|
166
|
+
"added": [{"nodeId": "n8", "tag": "button", "role": "button", "name": "Save"}],
|
|
167
|
+
"removed": [],
|
|
168
|
+
"addedCount": 1,
|
|
169
|
+
"removedCount": 0
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"seq": 7,
|
|
173
|
+
"timestamp": 1780000000010,
|
|
174
|
+
"type": "event",
|
|
175
|
+
"event": "input",
|
|
176
|
+
"target": {"nodeId": "n4", "tag": "input", "role": "textbox", "value": "Ada"}
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`MutationObserver` kaynaklı `attributes`, `characterData` ve `childList`
|
|
183
|
+
event'lerine ek olarak `input`, `change`, `focusin`, `focusout` ve `click`
|
|
184
|
+
sayfa event'leri verilir. Bu event'ler neden-sonuç sinyalidir; tam güncel
|
|
185
|
+
durum için snapshot yetkilidir.
|
|
186
|
+
|
|
187
|
+
`dom_events` için önerilen çağrı:
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"after_seq": 4,
|
|
192
|
+
"stream_id": "mdd1-abc123",
|
|
193
|
+
"limit": 100,
|
|
194
|
+
"wait_ms": 30000
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
`wait_ms` en fazla 30 saniyeye clamp edilir. Yeni event gelirse veya timeout
|
|
199
|
+
olursa tool döner; ajan bunu kendi gözlem döngüsünde tekrar çağırabilir.
|
|
200
|
+
|
|
201
|
+
### 3.3 Cursor güvenliği
|
|
202
|
+
|
|
203
|
+
| Durum | Anlam | Ajanın yapacağı |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `reset=false`, `dropped=false` | Cursor hâlâ geçerli | Event'leri işle, cursor'u ilerlet |
|
|
206
|
+
| `reset=true` | Farklı document/streamId ile okuma yapıldı | Snapshot al, yeni `streamId`/cursor sakla |
|
|
207
|
+
| `dropped=true` | Eski delta ring buffer'dan düştü veya stream değişti | Snapshot al; eski event'leri birleştirmeye çalışma |
|
|
208
|
+
| `truncated=true` | Snapshot cap'i ağacın tamamını içermedi | Selector/cap ile daha dar snapshot al |
|
|
209
|
+
| `requiresSnapshot=true` | Node silindi, navigation oldu veya action stale | Yeni snapshot al, yeni nodeId seç |
|
|
210
|
+
|
|
211
|
+
Navigation document'ı yeniler ve nodeId'leri geçersiz kılar. Her frame'in
|
|
212
|
+
document'ı kendi `streamId`'sine sahiptir; `frame_id` verilirse snapshot,
|
|
213
|
+
event ve action aynı frame context'inde çalışır.
|
|
214
|
+
|
|
215
|
+
### 3.4 Live action sözleşmesi
|
|
216
|
+
|
|
217
|
+
İzin verilen action'lar: `click`, `hover`, `focus`, `type`, `scroll`.
|
|
218
|
+
|
|
219
|
+
- `click` ve `hover`, node'un gerçek viewport koordinatını ölçer ve
|
|
220
|
+
`Page.dispatchMouseEvent` gönderir.
|
|
221
|
+
- `type`, canlı node'u focus eder ve gerçek `Page.insertText` çağrısı yapar.
|
|
222
|
+
`text` zorunludur.
|
|
223
|
+
- `focus`, canlı node'u focus eder.
|
|
224
|
+
- `scroll`, node'u görünür alana `scrollIntoView` ile getirir.
|
|
225
|
+
- Node bağlı değilse hiçbir replacement node'a fallback yapılmaz; yapılandırılmış
|
|
226
|
+
`stale_node`/`requiresSnapshot` döner.
|
|
227
|
+
|
|
228
|
+
Örnek:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"node_id": "n4",
|
|
233
|
+
"action": "type",
|
|
234
|
+
"text": "Ada"
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Başarılı action sonrası en az bir doğrulama yap:
|
|
239
|
+
|
|
240
|
+
```text
|
|
241
|
+
dom_snapshot(selector="#name")
|
|
242
|
+
veya
|
|
243
|
+
kahin_evaluate("document.querySelector('#name').value")
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## 4. Frame ve sekme kullanımı
|
|
247
|
+
|
|
248
|
+
1. `kahin_mirage_tab_list` ile target'ları gör.
|
|
249
|
+
2. `kahin_mirage_tab_new` ile sayfa aç veya
|
|
250
|
+
`kahin_mirage_tab_switch(target_id)` ile geç.
|
|
251
|
+
3. `kahin_mirage_frame_tree` ile frame hiyerarşisini al.
|
|
252
|
+
4. Frame içindeki DOM tool'larına `frame_id` ver.
|
|
253
|
+
|
|
254
|
+
Frame tool'ları `frame_id` için aynı aktif target'ın main-world execution
|
|
255
|
+
context'ini kullanır. Frame ayrıldığında context ve nodeId artık geçersizdir;
|
|
256
|
+
yeniden frame tree + snapshot gerekir.
|
|
257
|
+
|
|
258
|
+
## 5. Juggler gerçeği: hangi primitive ne yapıyor?
|
|
259
|
+
|
|
260
|
+
DOM stream sahte CDP `DOM.*` event'leri üretmez. Camoufox Juggler'da mevcut
|
|
261
|
+
olmayan bir domain'i taklit etmek yerine gerçek browser primitives birleştirilir:
|
|
262
|
+
|
|
263
|
+
| Primitive | Rol |
|
|
264
|
+
|---|---|
|
|
265
|
+
| `Browser.addBinding` | Sayfa ile sidecar arasında düşük hacimli notify köprüsü |
|
|
266
|
+
| `Browser.setInitScripts` | Yeni document/frame'lerde stream init script'ini çalıştırır |
|
|
267
|
+
| `Page.bindingCalled` | Python tarafını uyandıran sinyal; DOM payload'ı taşımaz |
|
|
268
|
+
| `Runtime.evaluate` | Snapshot, delta drain ve action state'i sayfadan ister |
|
|
269
|
+
| `MutationObserver` | Gerçek DOM mutation kayıtlarını üretir |
|
|
270
|
+
| `Page.dispatchMouseEvent` | Click/hover için gerçek Juggler input |
|
|
271
|
+
| `Page.insertText` | Focus edilmiş input'a gerçek text insertion |
|
|
272
|
+
|
|
273
|
+
Init script gelecekteki document'ları kapsar; mevcut document için Kahin
|
|
274
|
+
script'i ayrıca evaluate eder. Observer sayfa tarafında bounded olduğu için
|
|
275
|
+
`dom_events` cursor olmadan geçmişi sınırsız saklamaz.
|
|
276
|
+
|
|
277
|
+
## 6. Juggler tool kataloğu (A-Z)
|
|
278
|
+
|
|
279
|
+
Aşağıdaki liste Mirage'ın 77 Juggler-native tool'unun tamamıdır. `MIRAGE`
|
|
280
|
+
tool'ları `engine="mirage"` aktifken kullanılır.
|
|
281
|
+
|
|
282
|
+
### DOM gözlem ve adaptif action (5)
|
|
283
|
+
|
|
284
|
+
- `kahin_mirage_dom_start`
|
|
285
|
+
- `kahin_mirage_dom_snapshot`
|
|
286
|
+
- `kahin_mirage_dom_events`
|
|
287
|
+
- `kahin_mirage_dom_action`
|
|
288
|
+
- `kahin_mirage_dom_stop`
|
|
289
|
+
|
|
290
|
+
### DOM query/action (12)
|
|
291
|
+
|
|
292
|
+
- `kahin_mirage_query`, `kahin_mirage_query_all`
|
|
293
|
+
- `kahin_mirage_click`, `kahin_mirage_type`
|
|
294
|
+
- `kahin_mirage_get_text`, `kahin_mirage_get_attribute`
|
|
295
|
+
- `kahin_mirage_set_attribute`, `kahin_mirage_focus`
|
|
296
|
+
- `kahin_mirage_hover`, `kahin_mirage_get_html`
|
|
297
|
+
- `kahin_mirage_wait_selector`, `kahin_mirage_get_value`
|
|
298
|
+
|
|
299
|
+
### Input (7)
|
|
300
|
+
|
|
301
|
+
- `kahin_mirage_mouse_click`, `kahin_mirage_mouse_move`
|
|
302
|
+
- `kahin_mirage_mouse_down`, `kahin_mirage_mouse_up`
|
|
303
|
+
- `kahin_mirage_key_press`, `kahin_mirage_key_text`
|
|
304
|
+
- `kahin_mirage_scroll`
|
|
305
|
+
|
|
306
|
+
### PageEx (6)
|
|
307
|
+
|
|
308
|
+
- `kahin_mirage_reload`, `kahin_mirage_go_back`, `kahin_mirage_go_forward`
|
|
309
|
+
- `kahin_mirage_stop`, `kahin_mirage_frame_tree`, `kahin_mirage_page_content`
|
|
310
|
+
|
|
311
|
+
### Tab/session (6)
|
|
312
|
+
|
|
313
|
+
- `kahin_mirage_tab_new`, `kahin_mirage_tab_switch`, `kahin_mirage_tab_close`
|
|
314
|
+
- `kahin_mirage_tab_list`, `kahin_mirage_tab_bring_front`
|
|
315
|
+
- `kahin_mirage_context_new`
|
|
316
|
+
|
|
317
|
+
### Network/console (10)
|
|
318
|
+
|
|
319
|
+
- `kahin_mirage_network_requests`, `kahin_mirage_get_response_body`
|
|
320
|
+
- `kahin_mirage_intercept_requests`, `kahin_mirage_unintercept_requests`
|
|
321
|
+
- `kahin_mirage_network_continue`, `kahin_mirage_network_abort`
|
|
322
|
+
- `kahin_mirage_cache_disable`, `kahin_mirage_clear_cache`
|
|
323
|
+
- `kahin_mirage_console_log`, `kahin_mirage_errors_list`
|
|
324
|
+
|
|
325
|
+
### Storage (6)
|
|
326
|
+
|
|
327
|
+
- `kahin_mirage_cookie_get`, `kahin_mirage_cookie_set`, `kahin_mirage_cookie_clear`
|
|
328
|
+
- `kahin_mirage_storage_local_get`, `kahin_mirage_storage_local_set`
|
|
329
|
+
- `kahin_mirage_storage_session_get`
|
|
330
|
+
|
|
331
|
+
### Emulation (10)
|
|
332
|
+
|
|
333
|
+
- `kahin_mirage_set_user_agent`, `kahin_mirage_set_viewport`
|
|
334
|
+
- `kahin_mirage_set_device_scale_factor`, `kahin_mirage_set_media`
|
|
335
|
+
- `kahin_mirage_set_touch`, `kahin_mirage_set_color_scheme`
|
|
336
|
+
- `kahin_mirage_set_reduced_motion`, `kahin_mirage_set_locale`
|
|
337
|
+
- `kahin_mirage_set_timezone`, `kahin_mirage_set_geolocation`
|
|
338
|
+
|
|
339
|
+
### Dialog/download/worker/WebSocket (7)
|
|
340
|
+
|
|
341
|
+
- `kahin_mirage_dialog_list`, `kahin_mirage_dialog_accept`,
|
|
342
|
+
`kahin_mirage_dialog_dismiss`
|
|
343
|
+
- `kahin_mirage_download_list`, `kahin_mirage_download_save`
|
|
344
|
+
- `kahin_mirage_worker_list`, `kahin_mirage_websocket_list`
|
|
345
|
+
|
|
346
|
+
### Upload (2)
|
|
347
|
+
|
|
348
|
+
- `kahin_mirage_set_file_chooser_intercept`
|
|
349
|
+
- `kahin_mirage_upload_files`
|
|
350
|
+
|
|
351
|
+
### Screencast (4)
|
|
352
|
+
|
|
353
|
+
- `kahin_mirage_screencast_start`, `kahin_mirage_screencast_frame`
|
|
354
|
+
- `kahin_mirage_screencast_stop`, `kahin_mirage_screencast_pending`
|
|
355
|
+
|
|
356
|
+
`kahin_mirage_screencast_frame(fresh=true)`, önceki çağrıların ACK edilmiş
|
|
357
|
+
ama henüz kuyrukta kalan frame'lerini temizler ve çağrıdan sonra gelen ilk
|
|
358
|
+
frame'i bekler. Sayfa mutation'ı veya viewport değişiminden sonra görsel
|
|
359
|
+
doğrulama için bu yol kullanılmalıdır; varsayılan `fresh=false` ise kuyruktaki
|
|
360
|
+
en eski frame FIFO olarak döner.
|
|
361
|
+
|
|
362
|
+
### Accessibility ve health (2)
|
|
363
|
+
|
|
364
|
+
- `kahin_mirage_accessibility_tree`
|
|
365
|
+
- `kahin_engine_health`
|
|
366
|
+
|
|
367
|
+
## 7. Hazır akışlar
|
|
368
|
+
|
|
369
|
+
### 7.1 Dinamik form doldurma
|
|
370
|
+
|
|
371
|
+
```text
|
|
372
|
+
1. kahin_browser_start(engine="mirage", headless=true)
|
|
373
|
+
2. kahin_navigate(url="https://example.test/account")
|
|
374
|
+
3. kahin_mirage_dom_start(max_events=512)
|
|
375
|
+
4. kahin_mirage_dom_snapshot()
|
|
376
|
+
5. textbox nodeId'si ile kahin_mirage_dom_action(action="type", text="Ada")
|
|
377
|
+
6. kahin_mirage_dom_snapshot(selector="#name") ile value doğrula
|
|
378
|
+
7. Save button nodeId'si ile dom_action(action="click")
|
|
379
|
+
8. kahin_mirage_dom_events(after_seq=..., stream_id=..., wait_ms=5000)
|
|
380
|
+
9. Sonuç panelini snapshot/evaluate ile doğrula
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### 7.2 SPA navigation veya hydration bekleme
|
|
384
|
+
|
|
385
|
+
```text
|
|
386
|
+
dom_start
|
|
387
|
+
snapshot -> (streamId=S, cursor=C)
|
|
388
|
+
dom_events(after_seq=C, stream_id=S, wait_ms=30000)
|
|
389
|
+
event geldiyse: ilgili subtree'yi yeniden snapshot et
|
|
390
|
+
reset/dropped geldiyse: full snapshot al, S/C'yi yenile
|
|
391
|
+
timeout olduysa: küçük bir snapshot veya uygulama-ready kontrolü yap
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### 7.3 Iframe
|
|
395
|
+
|
|
396
|
+
```text
|
|
397
|
+
frame_tree -> frame_id=F
|
|
398
|
+
dom_snapshot(frame_id=F)
|
|
399
|
+
dom_action(node_id=N, action="click", frame_id=F)
|
|
400
|
+
dom_events(after_seq=C, stream_id=S, frame_id=F, wait_ms=5000)
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## 8. Hata kurtarma matrisi
|
|
404
|
+
|
|
405
|
+
| Hata/sinyal | Sebep | Kurtarma |
|
|
406
|
+
|---|---|---|
|
|
407
|
+
| `Browser engine is not running` | Start yok | `kahin_browser_start()` |
|
|
408
|
+
| `Browser engine is dead` | Sidecar/Camoufox öldü | `kahin_browser_stop`, sonra yeni `start` |
|
|
409
|
+
| `stale_node` | Node silindi veya document değişti | Snapshot + yeni nodeId |
|
|
410
|
+
| `reset`/`dropped` | Stream değişti veya ring overflow | Snapshot; eski cursor'u bırak |
|
|
411
|
+
| `not_found` | Selector artık yok | Event/snapshot ile yeni hedef bul |
|
|
412
|
+
| `truncated` | Snapshot cap'i küçük | Selector veya cap daralt/genişlet |
|
|
413
|
+
| `unsupported_action` | Action allow-list dışında | Yalnızca desteklenen action kullan |
|
|
414
|
+
| `not_text_input` | Hedef textbox değil | Role/name/action ipuçlarını tekrar değerlendir |
|
|
415
|
+
| `Method not found` | Juggler'da CDP methodu yok/yanlış | Validate + get command/dependency; native Mirage tool seç |
|
|
416
|
+
|
|
417
|
+
Hata alınca aynı hatayı körlemesine tekrarlama. Önce state'i yeniden oku,
|
|
418
|
+
gerekirse `kahin_error_decode` ve `kahin_get_dependencies` kullan.
|
|
419
|
+
|
|
420
|
+
## 9. Güvenlik ve sınırlar
|
|
421
|
+
|
|
422
|
+
- DOM snapshot ve event payload'ları cap'lidir; bounded sonuçlar ajana açıkça
|
|
423
|
+
`truncated`, `pending`, `reset` ve `dropped` durumlarını verir.
|
|
424
|
+
- Password input değerleri snapshot/event descriptor'larında redacted olur.
|
|
425
|
+
- `attributes` tam HTML değildir; güvenli kimlik ve erişilebilirlik alanlarıyla
|
|
426
|
+
sınırlıdır. Tam HTML gerekiyorsa bunun maliyetini bilerek
|
|
427
|
+
`kahin_mirage_get_html` veya `kahin_mirage_page_content` kullan.
|
|
428
|
+
- `kahin_mirage_dom_action` allow-list dışı JavaScript çalıştırmaz.
|
|
429
|
+
`kahin_evaluate` genel amaçlıdır; sayfa verisi ve yan etkiler bakımından
|
|
430
|
+
ayrıca değerlendirilmelidir.
|
|
431
|
+
- DOM event'i uygulamanın başarılı olduğunu kanıtlamaz. Her write/click
|
|
432
|
+
sonrasında görünür sonucu veya state'i doğrula.
|
|
433
|
+
|
|
434
|
+
## 10. Kaynak ve tasarım kararları
|
|
435
|
+
|
|
436
|
+
Bu tasarımda browser gözlemi için gerçek web platformu `MutationObserver`,
|
|
437
|
+
Juggler binding/init-script surface'i ve bounded cursor modeli kullanılır.
|
|
438
|
+
CDP DOM domain'indeki node-id/document reset fikriyle aynı güvenlik kuralı
|
|
439
|
+
uygulanır: document değişince eski node truth değildir.
|
|
440
|
+
|
|
441
|
+
- [MDN MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe)
|
|
442
|
+
- [Chrome DevTools Protocol DOM domain](https://chromedevtools.github.io/devtools-protocol/tot/DOM/)
|
|
443
|
+
- [Playwright Page API: init scripts and page lifecycle](https://playwright.dev/docs/api/class-page)
|
|
444
|
+
- [Model Context Protocol server concepts](https://modelcontextprotocol.io/docs/learn/server-concepts)
|
|
445
|
+
|
|
446
|
+
MCP resource subscription her istemci/SDK sürümünde aynı şekilde mevcut
|
|
447
|
+
olmadığından, taşınabilir ilk sözleşme tool + bounded long-poll'dur. İleride
|
|
448
|
+
resource subscription eklense bile `streamId`, `cursor`, `reset` ve
|
|
449
|
+
`dropped` kuralları değişmemelidir.
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kahinmcp/kahin",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Kahin — CDP ansiklopedisi + anti-detect browser otomasyon MCP sunucusu. Kurulumda 22 AI CLI aracını otomatik tespit edip kendini kaydeder.
|
|
3
|
+
"version": "0.3.5",
|
|
4
|
+
"description": "Kahin — CDP ansiklopedisi + anti-detect browser otomasyon MCP sunucusu. Kurulumda 22 AI CLI aracını otomatik tespit edip kendini kaydeder. Camoufox görsel varsayılandır; Obscura hızlı CDP işleri için opt-in'dir.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"kahin": "bin/kahin.mjs"
|
|
7
7
|
},
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"lib",
|
|
15
15
|
"LICENSE",
|
|
16
16
|
"CHANGELOG.md",
|
|
17
|
-
"README.md"
|
|
17
|
+
"README.md",
|
|
18
|
+
"docs/juggler-ai-native.md"
|
|
18
19
|
],
|
|
19
20
|
"engines": {
|
|
20
21
|
"node": ">=18"
|
|
Binary file
|