DSH iOS सिम्युलेटर
DeepSeek Harness बातचीत के भीतर एक लाइव, इंटरैक्टिव iOS सिम्युलेटर — साथ ही USB से आपका असली iPhone।
22 एजेंट टूल्स • लाइव MJPEG साइडबार पैनल • सिम्युलेटर & USB से असली iPhone • लिस्ट/फ़ीड पंक्ति क्रियाएँ • SwiftUI प्रीव्यू हॉट रीलोड
npm: @zseven-w/dsh-ios · वर्तमान प्लगइन रिलीज़: 0.1.0-rc.3 · DSH 0.1.1-rc.1 के साथ परीक्षित
English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Français · Español · Deutsch · Português · Русский · हिन्दी · Türkçe · ไทย · Tiếng Việt · Bahasa Indonesia
npm: @zseven-w/dsh-ios · वर्तमान प्लगइन रिलीज़: 0.1.0-rc.3 · DSH 0.1.1-rc.1 के साथ परखा गया
DSH बातचीत के भीतर से चलाया गया एक वास्तविक iPhone — बाईं ओर टूल कॉल, दाईं ओर लाइव डिवाइस पैनल
## DSH iOS सिम्युलेटर क्यों
DSH iOS सिम्युलेटर एजेंट को बातचीत के भीतर एक असली iOS सिम्युलेटर देता है — और आपको पिक्सल। एजेंट डिवाइस बूट कर सकता है, Xcode प्रोजेक्ट या Swift पैकेज बिल्ड करके चला सकता है, एक्सेसिबिलिटी पहचान या OCR टेक्स्ट से UI चला सकता है, यूनिफ़ाइड लॉग पढ़ सकता है और प्रोसेस, बैकट्रेस व लीक की जाँच कर सकता है, जबकि डिवाइस की लाइव स्ट्रीम एक स्थायी साइडबार पैनल में दिखती है जहाँ आप वीडियो पर सीधे टैप, ड्रैग, घुमा सकते हैं और Home दबा सकते हैं। वही क्रियाएँ USB से जुड़े असली iPhone पर भी काम करती हैं: प्लगइन फ़ोन पर WebDriverAgent बिल्ड करके लॉन्च करता है, उसके कंट्रोल और स्क्रीन पोर्ट को लूपबैक पर टनल करता है और डिवाइस को उसी पैनल, कार्ड और टूल्स में स्ट्रीम करता है। कोई इमेज ब्लॉक नहीं, कोई स्क्रीन-रिकॉर्डिंग फ़ाइल नहीं: विज़ुअल बाइट्स UI तक केवल DSH वेबसर्वर द्वारा जारी साइन किए हुए, समय-सीमा वाले URL से पहुँचते हैं।
| | |
| --- | --- |
| 🖥️ **बातचीत में लाइव सिम्युलेटर** | बूट किए गए डिवाइस की serve-sim MJPEG स्ट्रीम, साइन किए हुए `/_dsh/dsh-ios/*` रूट से प्रॉक्सी होकर स्थायी दाएँ पैनल में — ब्राउज़र कभी serve-sim के पोर्ट को नहीं छूता। |
| 📱 **USB से असली iPhone** | `ios_real_start_wda` जुड़े फ़ोन पर WebDriverAgent बिल्ड करके लॉन्च करता है और उसके कंट्रोल (REST) व स्क्रीन (MJPEG) पोर्ट को लूपबैक पर टनल करता है; फिर वही पैनल, टूल्स, कार्ड और स्टेटस कैप्सूल फ़ोन चलाते हैं। डिवाइस अनलॉक होना चाहिए, और असली अकाउंट पर हर टैप प्लगइन के “पहले पहचानो, फिर टैप करो” नियमों से बंधा है। |
| 🛠️ **22 एजेंट टूल्स** | डिवाइस, बूट/शटडाउन, स्क्रीनशॉट, इंटरैक्ट, बिल्ड और रन, यूनिफ़ाइड लॉग, AXe-आधारित UI ट्री और एलिमेंट-से-टैप, लिस्ट/फ़ीड पंक्ति क्रियाएँ, Vision OCR खोज/टैप, SwiftUI प्रीव्यू हॉट रीलोड, प्रोसेस, बैकट्रेस, लीक, ऐप जानकारी। |
| 👆 **इंटरैक्टिव पैनल** | लाइव वीडियो पर टैप और ड्रैग करें; होवर टूलटिप्स के साथ Home / घुमाएँ / स्क्रीनशॉट / रीफ़्रेश आइकन टूलबार; साइज़ मोड (适应 · 50–125% · S/M/L); फ़्रेम स्टाइल (无框 / 边框 / 真机框); डबल-क्लिक रीसेट के साथ 960 px तक ड्रैग-रिसाइज़; लैंडस्केप में ऑटो-चौड़ाई। |
| 🧾 **लिस्ट और फ़ीड पंक्तियाँ** | `ios_sim_ui_rows` गहरे एक्सेसिबिलिटी स्नैपशॉट को लेबल और सामान्य रूप से पार्स किए गए काउंटरों वाली अनुक्रमित पंक्तियों में बदलता है; `ios_sim_tap_row` पंक्ति के भीतर सापेक्ष निर्देशांक पर टैप करता है और काउंटर के अपेक्षित ±1 बदलाव से क्रिया की पुष्टि करता है — लिस्ट ऐप देने वाली यही एकमात्र विश्वसनीय पुष्टि है। |
| 🔐 **केवल-लूपबैक ट्रांसपोर्ट** | serve-sim समर्पित पोर्ट रेंज में 127.0.0.1 से बाइंड होता है; हर रूट को लूपबैक पीयर, लूपबैक `Host` और Fetch-Metadata/Origin जाँच चाहिए; HMAC कैपेबिलिटी 10 मिनट में समाप्त हो जाती हैं। असली डिवाइस पर WebDriverAgent कंट्रोल/MJPEG टनल उसी घेरे के भीतर लूपबैक usbmux फ़ॉरवर्ड हैं। |
| ⚡ **SwiftUI प्रीव्यू हॉट रीलोड** | `ios_sim_preview` आपके पैकेज के बाहर एक डिस्पोज़ेबल होस्ट ऐप बनाता है, आपके प्रीव्यू को dylib के रूप में बिल्ड करता है और संपादनों को बिना रीलॉन्च के चल रहे सिम्युलेटर में हॉट-स्वैप करता है (~2–5 सेकंड)। |
| 🧭 **सिमेंटिक UI ऑटोमेशन** | `ios_sim_ui_tree` एक्सेसिबिलिटी ट्री (AXe-आधारित) डंप करता है और `ios_sim_tap_element` लेबल या पहचानकर्ता से टैप करता है; ट्री खाली या विकृत होने पर `ios_sim_find_text` स्क्रीन का OCR करता है, और `ios_sim_tap_text` मिले टेक्स्ट पर टैप करता है — अनुमानित निर्देशांकों के बजाय पहचान- और टेक्स्ट-आधारित टैप। |
## टूल्स
सभी 22 टूल हर होस्ट पर पंजीकृत होते हैं और केवल सादा JSON लौटाते हैं — विज़ुअल बाइट्स UI तक केवल `presentationMeta` + साइन किए हुए रूट से पहुँचते हैं, कभी इमेज ब्लॉक के रूप में नहीं। सिम्युलेटर udid simctl/serve-sim से होकर जाते हैं; फ़िज़िकल-डिवाइस udid अपने आप WebDriverAgent से होकर जाते हैं। गैर-macOS होस्ट पर (या जब serve-sim अनुपलब्ध हो) टूल पंजीकृत रहते हैं पर व्याख्यात्मक एरर से विफल होते हैं; एकमात्र अपवाद `ios_sim_preview` का `status` है, जो किसी भी होस्ट पर सच्चाई से `{ running: false }` बताता है।
### मुख्य सिम्युलेटर टूल
| टूल | क्या करता है | मुख्य पैरामीटर |
| --- | --- | --- |
| `ios_sim_devices` | इस Mac पर उपलब्ध iOS सिम्युलेटर डिवाइस सूचीबद्ध करता है (udid, नाम, रनटाइम, स्थिति) और कौन से बूट हैं, साथ ही USB से जुड़े फ़िज़िकल iPhone `realDevices` में (udid, नाम, osVersion, model, state, developerMode)। दूसरे टूल्स को देने के लिए udid या नाम खोजने हेतु इसे पहले चलाएँ। | — |
| `ios_sim_boot` | डिवाइस बूट करता है और उसकी लाइव serve-sim स्ट्रीम शुरू करता है; स्ट्रीम बातचीत भर जीवित रहती है ताकि पैनल सिम्युलेटर लाइव दिखा सके। | `udid` (आवश्यक — udid या डिवाइस नाम) |
| `ios_sim_shutdown` | डिवाइस बंद करता है; स्ट्रीम उस डिवाइस को लक्षित कर रही हो तो उसे भी रोक देता है। | `udid` (आवश्यक) |
| `ios_sim_screenshot` | PNG लेता है और छोटा JSON सारांश लौटाता है (पथ, बाइट्स, आयाम, डिवाइस); इमेज कार्ड/पैनल में दिखती है, कभी इमेज ब्लॉक के रूप में नहीं। स्ट्रीम हो रहे सिम्युलेटर और USB से जुड़े फ़ोन (WebDriverAgent के ज़रिए) दोनों पर काम करता है। | `udid` (वैकल्पिक — स्ट्रीम हो रहा डिवाइस, वरना पहला बूटेड सिम्युलेटर) |
| `ios_sim_interact` | स्ट्रीम हो रहे डिवाइस से इंटरैक्ट करता है — सिम्युलेटर या USB फ़ोन: 0..1 सामान्यीकृत निर्देशांक पर टैप, टेक्स्ट टाइप (सिम्युलेटर पर US कीबोर्ड), हार्डवेयर बटन दबाना (`home`, `lock`, `volumeUp`…), स्क्रॉल या टच जेस्चर भेजना; क्रिया स्थिर होने (~300 ms) के बाद ताज़ा स्क्रीनशॉट प्रभाव दिखाता है। | `action` (आवश्यक — `tap`/`type`/`button`/`gesture`/`scroll`), `x`/`y`, `text`, `name`, `json` |
| `ios_sim_list_apps` | बूटेड सिम्युलेटर या जुड़े फ़ोन पर इंस्टॉल्ड ऐप्स सूचीबद्ध करता है (bundle id, डिस्प्ले नाम, संस्करण, सिस्टम फ़्लैग) — किसी थर्ड-पार्टी का bundle id अनुमान नहीं लगाया जा सकता, इसलिए सूची देखें या `ios_sim_launch_app` को `name` दें। विफल सूचीकरण खाली सूची लौटाने के बजाय एरर फेंकता है (जैसे “डिवाइस CoreDevice से पहुँच योग्य नहीं है”), इसलिए `count: 0` का मतलब हमेशा यही है कि डिवाइस पर सचमुच कोई मेल खाता ऐप नहीं है। | `udid` (वैकल्पिक), `query` (डिस्प्ले नाम और bundle id दोनों पर केस-इनसेंसिटिव सबस्ट्रिंग, CJK सहित), `include_system` (डिफ़ॉल्ट false) |
| `ios_sim_launch_app` | बूटेड सिम्युलेटर या जुड़े फ़ोन पर इंस्टॉल्ड ऐप लॉन्च करता है — `bundleId` से, या `name` से (डिस्प्ले नाम का केस-इनसेंसिटिव सबस्ट्रिंग, उसी सूचीकरण से हल होता है, CJK सहित)। दोनों में से ठीक एक; लॉन्च विफलता और अस्पष्ट नाम दोनों आगे क्या करना है यह बताकर लौटते हैं (सोर्स से बिल्ड के लिए `ios_sim_build_run` है)। | `bundleId` या `name` (ठीक एक), `udid`, `relaunch` |
| `ios_sim_build_run` | सिम्युलेटर के लिए `.xcodeproj`, `.xcworkspace` या Swift पैकेज बिल्ड करता है, बनी `.app` इंस्टॉल करके लॉन्च करता है; फ़िज़िकल-डिवाइस udid देने पर उसकी जगह फ़ोन पर बिल्ड, इंस्टॉल और लॉन्च करता है (Apple Development साइनिंग चाहिए)। विफलता पर परिणाम में फ़िल्टर किया हुआ `xcodebuild` एरर टेल होता है। पूरे बिल्ड में मिनट लगते हैं। | `projectPath` (आवश्यक), `scheme`, `udid` (स्ट्रीम हो रहा → बूटेड → नवीनतम-रनटाइम iPhone, जो बूट होता है), `configuration` (डिफ़ॉल्ट `Debug`) |
| `ios_real_start_wda` | USB से जुड़े फ़िज़िकल iPhone पर WebDriverAgent (WDA) शुरू करता है — केवल असली डिवाइस, कभी सिम्युलेटर नहीं। पहले से चल रहा WDA जवाब दे तो उसे अपना लेता है; वरना `xcodebuild` बिल्ड/लॉन्च चलाता है (कोल्ड बिल्ड में मिनट लगते हैं), फिर WDA के तैयार बताने तक इंतज़ार करके लाइव पैनल के कंट्रोल/MJPEG पोर्ट लौटाता है। जब `ios_sim_screenshot` / `ios_sim_interact` / `ios_sim_ui_tree` / `ios_sim_tap_element` बताएँ कि डिवाइस के लिए WDA नहीं चल रहा, तब पहले इसे चलाएँ। | `udid` (आवश्यक — `ios_sim_devices.realDevices` से फ़िज़िकल-डिवाइस udid) |
### UI-ट्री टूल (AXe-आधारित)
| टूल | क्या करता है | मुख्य पैरामीटर |
| --- | --- | --- |
| `ios_sim_ui_tree` | सबसे आगे वाले ऐप का एक्सेसिबिलिटी एलिमेंट ट्री (लेबल, पहचानकर्ता, मान, डिवाइस पॉइंट में फ़्रेम) और स्क्रीन साइज़ (पॉइंट में) डंप करता है — सिम्युलेटर पर AXe, USB फ़ोन पर WebDriverAgent (वहाँ डिफ़ॉल्ट रूप से गहराई सीमित: व्यस्त ऐप का असीमित स्नैपशॉट ~32 s / 751 KB, सीमित ~2 s); आउटपुट ~40 KB पर सीमित है (सबसे गहरे स्तर काटे जाते हैं, `truncated` + संकेत सेट होता है)। | `udid` (वैकल्पिक), `max_depth`, `filter` (लेबल/पहचानकर्ता/प्रकार पर केस-इनसेंसिटिव सबस्ट्रिंग) |
| `ios_sim_tap_element` | एलिमेंट को पहचान से टैप करता है — पहले सटीक मिलान, फिर `identifier`/`label` पर केस-इनसेंसिटिव सबस्ट्रिंग; नेस्टेड डुप्लिकेट एक लक्ष्य में समेटे जाते हैं, अस्पष्ट मिलान हर उम्मीदवार सूचीबद्ध करते हैं। टैप एलिमेंट के केंद्र पर पड़ता है (सिम्युलेटर पर AXe HID, फ़ोन पर WebDriverAgent), फिर ~300 ms बाद स्क्रीनशॉट प्रभाव दिखाता है; `expect_text` / `expect_gone` दें तो टैप और उसकी पुष्टि एक ही राउंड ट्रिप बन जाते हैं (`expected.matched`)। | `udid` (वैकल्पिक), `identifier`, `label`, `expect_text`, `expect_gone` |
### लिस्ट & फ़ीड पंक्तियाँ
लिस्ट/फ़ीड ऐप्स हर आइटम को एक एक्सेसिबिलिटी सेल में समेटते हैं जिसका लेबल पूरा सारांश और सारे काउंटर रखता है (“57 回复。18 喜欢。592 次查看”) — मिलाने के लिए कोई प्रति-कंट्रोल चाइल्ड बटन नहीं होते, और पंक्ति सेल केवल गहरे स्नैपशॉट में दिखते हैं। ये दो टूल उस संरचना को पंक्तियों के रूप में खोलते हैं और पंक्ति के भीतर काम करते हैं।
| टूल | क्या करता है | मुख्य पैरामीटर |
| --- | --- | --- |
| `ios_sim_ui_rows` | सबसे आगे वाले ऐप की दृश्य लिस्ट/फ़ीड पंक्तियों को कच्चे ट्री के बजाय पंक्तियों के रूप में पढ़ता है: हर पंक्ति अपना इंडेक्स, पॉइंट में फ़्रेम, समेटा लेबल और उस लेबल से पार्स किए काउंटर बताती है (संख्या + वर्गीकरण टोकन, जैसे `57 回复` → 回复=57, चीनी या अंग्रेज़ी में — कोई ऐप शब्दावली हार्डकोड नहीं)। पंक्तियाँ केवल गहरे स्नैपशॉट में दिखती हैं: फ़ोन पर डिफ़ॉल्ट `max_depth` 60 है, जिसकी लागत हर कॉल पर ~15–25 s / ~0.5 MB है (WDA अनुरोध क्रम से संभालता है) — पहले सस्ते ऑब्ज़र्वर रखें (`ios_sim_find_text` / `ios_sim_ui_tree`)। काउंटर ह्यूरिस्टिक से पार्स होते हैं और कुंजियाँ राउंड-ट्रिप करती हैं: `ios_sim_tap_row.expect_count` में कुंजी ठीक वैसे ही दें जैसी सूची में दिखी है। पंक्तियाँ न मिलने पर परिणाम कारण बताता है (गहराई बहुत कम / यह लिस्ट स्क्रीन नहीं है / गहरे पढ़ने के बाद सचमुच एक्सेसिबिलिटी जानकारी नहीं है) — उथला पढ़ना कभी “ऐप में एक्सेसिबिलिटी जानकारी नहीं” नहीं बताया जाता; स्क्रीन से बाहर की पंक्तियाँ हटाकर `omittedOffscreen` में गिनी जाती हैं। | `udid` (वैकल्पिक), `max_depth` (केवल फ़ोन; डिफ़ॉल्ट 60) |
| `ios_sim_tap_row` | एक दृश्य लिस्ट पंक्ति के भीतर सापेक्ष स्थिति पर टैप करता है (`ios_sim_ui_rows` द्वारा बताई गई पंक्ति: 0-आधारित इंडेक्स; x/y उस पंक्ति के फ़्रेम के अंश — 0 = बायाँ/ऊपरी किनारा, 1 = दायाँ/निचला, डिफ़ॉल्ट 0.5 = केंद्र) सिम्युलेटर (AXe) या USB फ़ोन (WebDriverAgent) पर। पंक्ति का फ़्रेम एक ताज़ा ट्री-पठन से आता है, इसलिए कोई निरपेक्ष स्क्रीन निर्देशांक अनुमानित नहीं होता; सीमा से बाहर इंडेक्स विफल होता है (कभी क्लैम्प नहीं)। सुरक्षा द्वार: `expect_count={key,delta}` के साथ टूल पंक्ति का लेबल फिर पढ़कर पुष्टि करता है कि काउंटर ठीक +1/−1 बदला (`countCheck.verified`); अगर कुंजी पंक्ति के पार्स किए काउंटरों में नहीं है, टैप होने से पहले ही अस्वीकृत हो जाता है — असली डिवाइस पर टैप कभी जाँच-पड़ताल नहीं होता। `expect_count` के बिना भी टैप होता है (पंक्ति-सापेक्ष स्पष्ट स्थिति ही पहचान है) पर कुछ सत्यापित नहीं होता। | `udid` (वैकल्पिक), `index` (आवश्यक), `x`, `y` (अंश 0..1), `max_depth`, `expect_count` (`{key, delta}`) |
### OCR टूल (Vision)
| टूल | क्या करता है | मुख्य पैरामीटर |
| --- | --- | --- |
| `ios_sim_find_text` | बूटेड सिम्युलेटर या USB फ़ोन की वर्तमान स्क्रीन का OCR प्लगइन-कंपाइल्ड Vision हेल्पर से करता है (सटीक पहचान, zh-Hans + en-US, पहले उपयोग पर `swiftc` से `~/Library/Caches/dsh-ios/bin/ocr` में कंपाइल)। इसे तब चलाएँ जब एक्सेसिबिलिटी ट्री खाली या विकृत हो, टेक्स्ट ग्राफ़िक के रूप में बना हो (बैज संख्याएँ, इमेज में पकी कीमतें), या स्क्रीन पर क्या है इसे स्वतंत्र रूप से जाँचना हो। ताज़ा स्क्रीनशॉट लेकर `{device, size, items:[{text, confidence, rect}]}` लौटाता है — rect डिवाइस-पॉइंट बॉक्स हैं (मूल ऊपर-बाएँ), कॉन्फ़िडेंस-क्रमित, आउटपुट ~40 KB पर सीमित (`truncated` सबसे कम कॉन्फ़िडेंस की पूँछ हटाता है; `query` से संकीर्ण करें या `min_confidence` बढ़ाएँ)। | `udid` (वैकल्पिक), `query` (केस-इनसेंसिटिव सबस्ट्रिंग), `min_confidence` (डिफ़ॉल्ट 0.3) |
| `ios_sim_tap_text` | वर्तमान स्क्रीन का OCR करके सबसे अच्छे टेक्स्ट-मिलान के केंद्र पर टैप करता है — वही सटीक → केस-इनसेंसिटिव-कन्टेन → उम्मीदवार-सूची अस्पष्टता नियम जो `ios_sim_tap_element` के हैं, उस टेक्स्ट के लिए जिसे एक्सेसिबिलिटी ट्री देख नहीं सकता (बिना-a11y ऐप्स, बैज संख्याएँ, इमेज में पका टेक्स्ट)। फ़ोन पर टैप WebDriverAgent से डिवाइस के निरपेक्ष पॉइंट पर पड़ता है; स्ट्रीम हो रहे सिम्युलेटर पर serve-sim कंट्रोल से सामान्यीकृत होकर भेजा जाता है (पहले `ios_sim_boot` चलाएँ)। ~300 ms बाद ताज़ा स्क्रीनशॉट प्रभाव दिखाता है; `expect_text` / `expect_gone` दें तो टैप और उसकी पुष्टि एक ही राउंड ट्रिप बन जाते हैं (`expected.matched`)। असली डिवाइस पर हर टैप के वास्तविक परिणाम होते हैं — यह जानने के लिए कि कोई अनजान कंट्रोल क्या करता है, उसे कभी टैप न करें। | `udid` (वैकल्पिक), `query` (आवश्यक), `min_confidence`, `expect_text`, `expect_gone` |
| `ios_sim_wait_for` | स्क्रीन पर किसी टेक्स्ट के आने या गायब होने तक प्रतीक्षा करता है — `ios_sim_find_text` वाली ही कैप्चर+OCR पाइपलाइन को तब तक पोल करता है जब तक शर्त पूरी न हो या टाइमआउट न हो जाए (डिफ़ॉल्ट 8 सेकंड, अधिकतम 60 सेकंड)। टाइमआउट एक सामान्य `matched:false` उत्तर है, कभी एरर नहीं — find_text के मैनुअल लूप (असली iPhone पर ~1.2 सेकंड प्रति चक्कर) की जगह एक ही कॉल। मेल मिलने पर `item` में OCR टेक्स्ट, कॉन्फ़िडेंस और डिवाइस पॉइंट्स में आयत होता है। | `udid` (वैकल्पिक), `text` (आवश्यक), `mode` (`appear`/`disappear`), `timeout_ms`, `min_confidence` |
### लॉग टूल
| टूल | क्या करता है | मुख्य पैरामीटर |
| --- | --- | --- |
| `ios_sim_logs` | सिम्युलेटर ऐप जो छापता है उसे डिवाइस के यूनिफ़ाइड लॉग से पढ़ता है: `snapshot` (`log show --last `, डिफ़ॉल्ट 2m) या `follow` (`duration_seconds` तक सीमित लाइव कैप्चर, डिफ़ॉल्ट 10, अधिकतम 60 — कभी लटकती स्ट्रीम नहीं)। आउटपुट ~300 पंक्तियों / 30 KB पर सीमित है और संकीर्ण करने का संकेत देता है। | `udid` (वैकल्पिक), `mode` (`snapshot`/`follow`), `duration`, `duration_seconds`, `bundle_id`, `predicate` (कच्चा NSPredicate, `bundle_id` पर प्राथमिकता), `level` (`default`/`info`/`debug`), `grep` |
### प्रीव्यू टूल
| टूल | क्या करता है | मुख्य पैरामीटर |
| --- | --- | --- |
| `ios_sim_preview` | सिम्युलेटर में लाइव SwiftUI प्रीव्यू हॉट रीलोड: `start` (डिफ़ॉल्ट) पैकेज की जाँच करता है, प्लगइन कैश में डिस्पोज़ेबल होस्ट ऐप बनाता है (आपके पैकेज के भीतर कभी नहीं), पैकेज को सिम्युलेटर के लिए dylib के रूप में बिल्ड करता है, होस्ट इंस्टॉल करके लॉन्च करता है और सोर्स पर नज़र रखता है — हर संपादन फिर बिल्ड होकर बिना रीलॉन्च के हॉट-स्वैप होता है (~2–5 s)। कंपाइलर एरर आख़िरी अच्छा प्रीव्यू बनाए रखते हैं और `status` से दिखते हैं; एक समय में एक सेशन। | `packagePath` (`start` के लिए आवश्यक), `udid`, `action` (`start`/`status`/`stop`), `previewFilter` (प्रीव्यू नामों पर केस-इनसेंसिटिव सबस्ट्रिंग) |
### डीबग टूल्स
| टूल | क्या करता है | मुख्य पैरामीटर |
| --- | --- | --- |
| `ios_sim_processes` | एक सिम्युलेटर के चल रहे ऐप प्रोसेस उसके अपने launchd से सूचीबद्ध करता है (होस्ट-दृश्य pid, नाम, bundle id) — बैकट्रेस/लीक के लिए pid स्रोत; फ़िज़िकल-डिवाइस udid पर इसके बजाय devicectl से फ़ोन के प्रोसेस सूचीबद्ध करता है। | `udid` (वैकल्पिक), `filter` (नाम/bundle id पर केस-इनसेंसिटिव सबस्ट्रिंग) |
| `ios_sim_backtrace` | वन-शॉट बैच LLDB (अटैच → थ्रेड बैकट्रेस → डिटैच, कभी इंटरैक्टिव नहीं); आउटपुट ~200 पंक्तियों पर सीमित, मुख्य थ्रेड पहले, लक्ष्य हमेशा फिर-शुरू-हुआ सत्यापित। जब macOS अटैच मना करे (डेवलपर मोड बंद), Xcode के `sample` इंजन (बिना सस्पेंड) पर डिग्रेड होकर सक्षम करने का संकेत बताता है। केवल सिम्युलेटर — फ़िज़िकल डिवाइस कारण सहित अस्वीकृत होते हैं। | `udid` (वैकल्पिक), `pid` / `bundle_id`, `all_threads` (डिफ़ॉल्ट true) |
| `ios_sim_leaks` | Xcode के `leaks` टूल से लीक विश्लेषण: `summary` (लीक संख्या, कुल लीक बाइट्स, शीर्ष ~30 प्रकार) या `memgraph` (Xcode Instruments में खोलने के लिए `.memgraph` आर्टिफ़ैक्ट, यहाँ कभी पार्स नहीं होता)। स्कैन के दौरान ऐप सस्पेंड रहता है और हमेशा फिर शुरू होता है। केवल सिम्युलेटर। | `udid` (वैकल्पिक), `pid` / `bundle_id`, `mode` (`summary`/`memgraph`) |
| `ios_sim_app_info` | इंस्टॉल्ड ऐप के तथ्य: ऐप बंडल पथ, लिखने योग्य डेटा कंटेनर और Info.plist मान — सिम्युलेटर पर `simctl appinfo` (साथ `get_app_container` फ़ॉलबैक), USB फ़ोन पर `devicectl` से; अनुपस्थित ऐप के लिए `installed: false` और `ios_sim_list_apps` बताने वाला `note`। | `udid` (वैकल्पिक), `bundle_id` (आवश्यक) |
## डिस्प्ले सतहें
- **साइडबार पैनल — “iOS 模拟器”.** लाइव दृश्य स्थायी दाएँ पैनल में रहता है (एक फ़िक्स्ड डॉक जो बातचीत को किनारे करता है, या संकीर्ण व्यूपोर्ट पर केंद्रित ओवरले)। यह लाइव MJPEG स्ट्रीम दिखाता है और वीडियो पर सीधे क्लिक-से-टैप व ड्रैग-से-जेस्चर लेता है, साथ में आइकन टूलबार (Home, स्क्रीनशॉट, घुमाएँ, रीफ़्रेश) जिसके बटनों पर होवर टूलटिप्स हैं। साइज़ कंट्रोल देते हैं **适应** (पैनल चौड़ाई में फ़िट), डिवाइस की तार्किक चौड़ाई का **50–125%** ज़ूम, और **S / M / L** प्रीसेट जो डिवाइस की छोटी भुजा तय करते हैं (पोर्ट्रेट चौड़ाई; लैंडस्केप में ऐसा स्केल कि डिवाइस अपना भौतिक आकार बनाए रखे)। फ़्रेम स्टाइल हैं **无框 / 边框 / 真机框** (फ़्रेमलेस / बेज़ल / यथार्थवादी डिवाइस शेल) और आनुपातिक कॉर्नर रेडियस। डिवाइस लैंडस्केप में घूमे तो पैनल अपने आप आरामदायक आकार तक चौड़ा होता है और वापस घूमने पर आपकी चौड़ाई बहाल करता है — बीच में किया मैनुअल ड्रैग हमेशा जीतता है। बाएँ किनारे का हैंडल पैनल को चौड़ा/संकरा खींचता है (अधिकतम 960 px; डबल-क्लिक डिफ़ॉल्ट चौड़ाई पर रीसेट)। जब USB से जुड़ा iPhone स्ट्रीम लक्ष्य हो, वही पैनल फ़ोन की WebDriverAgent MJPEG स्ट्रीम उन्हीं कंट्रोल्स से दिखाता है।
- **कॉम्पैक्ट बातचीत कार्ड.** टूल परिणाम बिना इनलाइन इमेजरी के एक-पंक्ति कार्ड के रूप में दिखते हैं: एकीकृत **“iOS 模拟器”** शीर्षक, एक क्रिया उप-लेबल (बूट / स्क्रीनशॉट / इंटरैक्ट / बिल्ड और रन / WebDriverAgent शुरू करें), डिवाइस नाम, स्टेटस बैज और “साइडबार में खोलें” संकेत। पंक्ति पर क्लिक पैनल खोलता है; बटन, लिंक या लाइव फ़्रेम पर क्लिक उसे कभी नहीं खोलते।
- **इनपुट के ऊपर स्टेटस कैप्सूल.** जब पैनल बंद हो और स्ट्रीम ऑनलाइन हो, कंपोज़र के ऊपर हरी बिंदी वाली छोटी पिल (`` · 实时) दिखती है जो क्लिक पर पैनल खोलती है। यह सेशन-गेटेड है: तभी दिखती और पोल होती है जब वर्तमान बातचीत में सिम्युलेटर परिणाम माउंट हों, और उनके बिना किसी सेशन पर जाते ही रुक जाती है।
- **स्टैंडर्ड मोड और Code मोड.** स्टैंडर्ड सेशन होस्ट-प्रोजेक्टेड `presentationMeta` उपयोग करते हैं। नेस्टेड Code Mode (PTC) डिस्पैच कभी meta नहीं ले जाते, इसलिए क्लाइंट टिकाऊ परिणाम JSON से वही meta फिर बनाता है — पैनल, कार्ड और कैप्सूल दोनों मोड में काम करते हैं।
## सुरक्षा
- ब्राउज़र कभी serve-sim के पोर्ट से बात नहीं करता। हर बाइट DSH वेबसर्वर ओरिजिन से प्लगइन-स्वामित्व वाले `/_dsh/dsh-ios/*` रूट से गुज़रता है: `/stream/` (MJPEG प्रॉक्सी), `/screenshot/` (कैश्ड PNG), `/ws?token=…` (HID कंट्रोल रिले), साथ ही `/grant`, `/capture` और `/status` एंडपॉइंट।
- टोकन HMAC-SHA256 कैपेबिलिटी हैं (`base64url(payload).base64url(mac)`) जो 10 मिनट में समाप्त होती हैं और प्रति-DSH-होम कुंजी से साइन होती हैं (`/cache/dsh-ios/stream-access.key`, 0600, एटॉमिक रूप से बनती है)।
- हर रूट किसी भी कैपेबिलिटी की जाँच से पहले लूपबैक/विश्वसनीय ट्रांसपोर्ट घेरा लागू करता है: लूपबैक पीयर पता, लूपबैक `Host` (DNS-रीबाइंडिंग अस्वीकृत) और Fetch-Metadata/Origin जाँच। स्क्रीनशॉट रूट केवल प्लगइन कैश निर्देशिका की फ़ाइलें देता है (सिम्बॉलिक लिंक अस्वीकृत, `realpath` कंटेनमेंट)।
- serve-sim केवल लूपबैक पर समर्पित पोर्ट रेंज (3181–3244) में फ़ोरग्राउंड चाइल्ड के रूप में चलता है, इसलिए पोर्ट 3100 पर उपयोगकर्ता का अपना serve-sim कभी नहीं छुआ जाता; `--host` कभी उपयोग नहीं होता।
- **असली-डिवाइस ट्रांसपोर्ट** — WebDriverAgent कंट्रोल (REST, डिवाइस पोर्ट 8100) और स्क्रीन (MJPEG, पोर्ट 9100) टनल USB लिंक पर लूपबैक usbmux फ़ॉरवर्ड हैं; वे उसी साइन-रूट घेरे के पीछे रहते हैं, और ब्राउज़र फिर भी केवल DSH वेबसर्वर ओरिजिन से बात करता है।
- **ऑर्फ़न अडॉप्शन/रीक्लेम** — अगर पिछला DSH होस्ट अशिष्टता से मारा गया और उसका serve-sim हेल्पर बच गया, तो वही डिवाइस अपना लिया जाता है (ऑर्फ़न का हैंडशेक प्रामाणिक है); किसी दूसरे डिवाइस के स्लॉट पर क़ब्ज़ा जमाए पुराना हेल्पर `serve-sim -k` से रीक्लेम होकर एक बार फिर लॉन्च होता है।
- **कीप-अलाइव + आइडल स्टॉप** — क्रैश हुई स्ट्रीम पृष्ठभूमि में फिर शुरू होती है (~5 s देरी); शून्य उपभोक्ता होने पर स्ट्रीम 5 मिनट बाद अपने आप रुकती है। जानबूझकर रोकना कभी लड़ा नहीं जाता। (असली-डिवाइस रनर जानबूझकर आइडल रीपिंग से मुक्त है: उसे फिर शुरू करने में बहु-मिनट `xcodebuild` रीबिल्ड लगता है।)
## आवश्यकताएँ
- **पूर्ण Xcode के साथ macOS** — केवल Command Line Tools नहीं। `xcodebuild`, `xcrun simctl` और सिम्युलेटर रनटाइम सब Xcode के साथ आते हैं।
- **Xcode में कम से कम एक iOS सिम्युलेटर रनटाइम** इंस्टॉल हो।
- **पैनल के लिए DSH ≥ 0.1.0-rc.6 और वेब बंडल**। हेडलेस प्रोफ़ाइल भी चलती हैं: सभी 22 टूल सामान्य रूप से काम करते हैं, बस लाइव दृश्य नहीं होता।
- **गैर-macOS होस्ट**: प्लगइन लोड होता है और सभी 22 टूल पंजीकृत होते हैं, पर हर कॉल व्याख्यात्मक एरर लौटाती है (`iOS Simulator requires macOS with Xcode …`)।
- **serve-sim** इस प्लगइन की npm निर्भरता के रूप में आता है, इसलिए असली इंस्टॉल पर स्थानीय रूप से हल होता है; `npx -y serve-sim` फ़ॉलबैक डेवलपमेंट ट्री को कवर करता है (पहले उपयोग में नेटवर्क चाहिए)।
- **AXe** (वैकल्पिक — केवल AXe-आधारित टूल्स को चाहिए: `ios_sim_ui_tree` / `ios_sim_tap_element`, साथ ही सिम्युलेटर पर `ios_sim_ui_rows` / `ios_sim_tap_row`): `brew install cameroncooke/axe/axe`, या प्लगइन को पिन किया रिलीज़ (v1.8.0, SHA-256 सत्यापित) `~/Library/Caches/dsh-ios/bin` में अपने आप डाउनलोड करने दें। `DSH_IOS_AXE_BIN` रिज़ॉल्यूशन ओवरराइड करता है; `DSH_IOS_AXE_OFFLINE=1` डाउनलोड बंद करता है।
- **Vision OCR** (वैकल्पिक — केवल `ios_sim_find_text` / `ios_sim_tap_text` को चाहिए): प्लगइन पहले उपयोग पर अपनी बंडल की गई `assets/ocr.swift` को `swiftc` से `~/Library/Caches/dsh-ios/bin/ocr` में कंपाइल करता है (zh-Hans + en-US पहचान)।
- **lldb अटैच को macOS डेवलपर मोड चाहिए**: एक बार `sudo DevToolsSecurity -enable` चलाएँ। तब तक `ios_sim_backtrace` Xcode के `sample` इंजन (बिना सस्पेंड) का उपयोग करता है और `ios_sim_leaks` सक्षम-संकेत के साथ डिग्रेड होता है।
- **असली iPhone** — अनलॉक स्क्रीन वाला USB-जुड़ा iPhone (लॉक स्क्रीन पर WebDriverAgent शुरू नहीं हो सकता; ऑटो-लॉक: कभी नहीं पर विचार करें), डेटा-सक्षम USB केबल (केवल Wi-Fi पेयरिंग पोर्ट फ़ॉरवर्ड नहीं ले जा सकती), डिवाइस पर डेवलपर मोड सक्षम, `~/Library/Caches/dsh-ios/wda/src` पर WebDriverAgent चेकआउट (प्लगइन वहाँ से `WebDriverAgentRunner` स्कीम बिल्ड करता है — वह कभी कुछ डाउनलोड या क्लोन नहीं करता), और USB टनल के लिए libimobiledevice का usbmux (`brew install libimobiledevice`)। पहला WDA बिल्ड साइन किया WebDriverAgentRunner इंस्टॉल करता है: पूछे जाने पर डिवाइस पर उसके सर्टिफ़िकेट पर भरोसा करें, और फ़्री-टीम साइनिंग प्रोफ़ाइल समाप्त होने पर (7 दिन की अवधि) `ios_real_start_wda` फिर चलाएँ।
## DSH में इंस्टॉल करें
```sh
dsh plugin --profile web add @zseven-w/dsh-ios@latest
dsh web
```
## त्वरित शुरुआत
एक सामान्य पहली बातचीत:
1. **डिवाइस खोजें** — “उपलब्ध सिम्युलेटर सूचीबद्ध करो।” → `ios_sim_devices`।
2. **बूट करें** — “iPhone 17 Pro बूट करो।” → `ios_sim_boot`। स्ट्रीम शुरू होती है और **“iOS 模拟器” पैनल** खुलता है: डिवाइस साइडबार में लाइव है। (फिर खोलने के लिए किसी सिम्युलेटर कार्ड पंक्ति या इनपुट के ऊपर की स्टेटस पिल पर क्लिक करें।)
3. **वीडियो पर टैप करें** — पैनल पर सीधे टैप या ड्रैग करें; या एजेंट को UI चलाने दें: “Settings खोलो, फिर General टैप करो।” → `ios_sim_interact` (या पहचान-आधारित टैप के लिए `ios_sim_ui_tree` + `ios_sim_tap_element`; टेक्स्ट-आधारित टैप के लिए `ios_sim_find_text` + `ios_sim_tap_text`; लिस्ट/फ़ीड ऐप्स के लिए `ios_sim_ui_rows` + `ios_sim_tap_row`)।
4. **अपना ऐप बिल्ड करके चलाएँ** — “/path/to/MyApp.xcodeproj बिल्ड करके चलाओ।” → `ios_sim_build_run`। पूरा बिल्ड मिनट लेता है; पूरा होने पर ऐप सिम्युलेटर में लॉन्च होता है और आप उसे पैनल में लाइव देखते हैं।
5. **प्रीव्यू हॉट रीलोड** — “/path/to/MyPackage के SwiftUI प्रीव्यू दिखाओ।” → `ios_sim_preview start`। सोर्स फ़ाइल संपादित करें और प्रीव्यू चल रहे सिम्युलेटर में ~2–5 s में हॉट-स्वैप हो जाता है — कोई रीलॉन्च नहीं।
6. **असली iPhone चलाएँ** — फ़ोन USB (डेटा केबल) से जोड़ें, अनलॉक करें, फिर “फ़ोन पर WebDriverAgent शुरू करो।” → `ios_real_start_wda`। पैनल फ़ोन की लाइव स्ट्रीम पर बदल जाता है और हर टूल उसके `realDevices` udid को स्वीकारता है; कॉल विफल होने पर पैनल के स्टेटस से कोडेड कारण पढ़ें (`device-locked`, `cert-untrusted`, `profile-expired`, `tunnel-failed`, `device-unplugged`)।
## समस्या निवारण
- **बैकट्रेस lldb के बजाय `sample` उपयोग करता है, या leaks प्रतिबंधित जाँच की शिकायत करता है** — macOS डेवलपर मोड बंद है। एक बार `sudo DevToolsSecurity -enable` चलाकर फिर कोशिश करें। तब तक टूल साफ़-सुथरे ढंग से डिग्रेड होते हैं: `ios_sim_backtrace` Xcode के `sample` (सिंबॉलिकेटेड, बिना सस्पेंड) पर गिरता है और `ios_sim_leaks` सक्षम-संकेत बताता है।
- **`ios_sim_ui_tree` / `ios_sim_tap_element` को AXe चाहिए** — `brew install cameroncooke/axe/axe` से इंस्टॉल करें, या प्लगइन को पहले उपयोग पर पिन किया रिलीज़ डाउनलोड करने दें (github.com तक नेटवर्क चाहिए)। एरर संदेश में हमेशा पूरा इंस्टॉल संकेत होता है; `DSH_IOS_AXE_BIN=/path/to/axe` रिज़ॉल्यूशन ओवरराइड करता है। पंक्ति टूल्स (`ios_sim_ui_rows` / `ios_sim_tap_row`) को सिम्युलेटर पर भी AXe चाहिए।
- **`ios_sim_find_text` / `ios_sim_tap_text` बताते हैं कि OCR हेल्पर गायब है** — पहला उपयोग `swiftc` (Xcode चाहिए) से बंडल की गई `assets/ocr.swift` को `~/Library/Caches/dsh-ios/bin/ocr` में कंपाइल करता है; एरर में सटीक पथ और संकेत होता है।
- **`ios_sim_ui_rows` को पंक्तियाँ नहीं मिलतीं** — परिणाम कारण बताता है: गहराई बहुत कम (`max_depth` बढ़ाएँ; फ़ोन पर हर गहरे स्नैपशॉट की लागत ~15–25 s), यह लिस्ट स्क्रीन नहीं है, या गहरे पढ़ने के बाद सचमुच एक्सेसिबिलिटी जानकारी नहीं है। उथला पढ़ना कभी ग़लती से “एक्सेसिबिलिटी गायब” नहीं बताया जाता।
- **iOS 26.2 सिम्युलेटर पर `ios_sim_leaks`** — iOS 26.2 रनटाइम पर, डेवलपर मोड सक्षम होने पर भी Xcode का `leaks` सिम्युलेटर प्रोसेस जाँचने में `Failed to get DYLD info` या minimal-corpse जैसी घातक डायग्नोस्टिक्स से विफल हो सकता है। टूल साफ़-सुथरे ढंग से डिग्रेड होता है: आपको कच्ची डायग्नोस्टिक मिलती है, लक्ष्य हमेशा फिर-शुरू-हुआ सत्यापित होता है, और कुछ हैंग नहीं होता। प्लगइन-पक्ष का कोई समाधान नहीं — ऐसा होने पर `mode: "memgraph"` या कोई दूसरा रनटाइम आज़माएँ।
- **असली-डिवाइस कॉल कोडेड स्टेटस से विफल होती हैं** — पैनल का स्टेटस अनुमान नहीं, कारण बताता है: `device-locked` (फ़ोन अनलॉक करें; अपने आप ठीक हो जाता है), `cert-untrusted` (डिवाइस पर WebDriverAgent सर्टिफ़िकेट पर भरोसा करें), `profile-expired` (फ़्री-टीम साइनिंग 7 दिन चलती है — रीबिल्ड के लिए `ios_real_start_wda` फिर चलाएँ), `tunnel-failed` (USB लिंक/usbmuxd जाँचें), `device-unplugged` (डेटा-सक्षम USB केबल उपयोग करें — केवल Wi-Fi पेयरिंग पोर्ट फ़ॉरवर्ड नहीं ले जा सकती)।
- **स्ट्रीम अपने आप रुक जाती है** — यह आइडल नीति है, क्रैश नहीं: शून्य उपभोक्ता (पैनल बंद, कोई कार्ड माउंट नहीं, कोई सक्रिय रूट नहीं) होने पर स्ट्रीम 5 मिनट बाद रुकती है और अगले टूल कॉल या पैनल खुलने पर फिर शुरू होती है। क्रैश हुई स्ट्रीम ~5 सेकंड में पृष्ठभूमि में फिर शुरू होती है।
## डेवलपमेंट
```sh
pnpm install
pnpm run build # होस्ट tsc + क्लाइंट बंडल → lib/
pnpm run typecheck
```
`scripts/` के स्मोक टेस्ट बिल्ड किए `lib/` का अभ्यास कराते हैं (जो हिस्से सिम्युलेटर बूट करते हैं या USB फ़ोन से बात करते हैं वे केवल macOS; उन हिस्सों को छोड़ने के लिए `DSH_IOS_SMOKE_SKIP_SIM=1` सेट करें):
| स्क्रिप्ट | क्या कवर करती है |
| --- | --- |
| `node scripts/dev-smoke.mjs` | सिम होस्ट: बाइनरी रिज़ॉल्यूशन, स्ट्रीम लॉन्च, कंट्रोल, कीप-अलाइव, dispose. |
| `node scripts/dev-tools-smoke.mjs [--full-build]` | असली सिम्युलेटर के विरुद्ध मुख्य टूल्स (साथ ही `--full-build` से असली बिल्ड)। |
| `node scripts/dev-routes-smoke.mjs` | साइन किए वेब रूट: grant, स्ट्रीम प्रॉक्सी, स्क्रीनशॉट, ws रिले, घेरे, समाप्ति। |
| `node scripts/dev-card-smoke.mjs` | क्लाइंट कार्ड: स्टैटिक SSR (कोई `
` नहीं), status/capture कॉन्ट्रैक्ट, लगभग-लाइव नेटवर्क हिस्सा। |
| `node scripts/dev-panel-smoke.mjs` | पैनल घटक, साइज़ मोड, फ़्रेम स्टाइल, डॉक/ट्रिगर/कैप्सूल तर्क (केवल स्टैटिक)। |
| `node scripts/dev-logs-smoke.mjs` | `ios_sim_logs` snapshot/follow, फ़िल्टर, सीमाएँ, प्रोसेस रीपिंग। |
| `node scripts/dev-uitree-smoke.mjs` | UI-ट्री टूल्स: AXe रिज़ॉल्यूशन/डाउनलोड पाइपलाइन, सेलेक्टर, असली-सिम्युलेटर ट्री और टैप। |
| `node scripts/dev-debug-smoke.mjs` | डीबग टूल्स: प्रोसेस, बैकट्रेस (lldb + sample), लीक, ऐप जानकारी। |
| `node scripts/dev-preview-smoke.mjs` | प्रीव्यू हॉट रीलोड: शुरुआत, संपादन → बिना रीलॉन्च हॉट-स्वैप, एरर रिकवरी, रोकना। |
| `node scripts/dev-orphan-smoke.mjs` | अशिष्ट होस्ट-किल के बाद ऑर्फ़न serve-sim का अडॉप्शन/रीक्लेम। |
| `node scripts/dev-ocr-smoke.mjs` | Vision-OCR टूल्स: हेल्पर रिज़ॉल्यूशन, swiftc कंपाइल कैश, पहचान पाइपलाइन, tap-text रूटिंग। |
| `node scripts/dev-wda-smoke.mjs` | WebDriverAgent होस्ट: `ServerURLHere` पार्सिंग, विफलता वर्गीकरण, टनल, कीप-अलाइव (मॉक; वैकल्पिक लाइव पास)। |
| `node scripts/dev-realdevice-smoke.mjs` | USB-जुड़े iPhone के विरुद्ध `xcrun devicectl` — टूल्स के उपयोग वाले सटीक कोड पथ। |
| `node scripts/dev-realstart-smoke.mjs` | `/real-start` रूट: घेरा, कोडेड अस्वीकृतियाँ, बिल्ड/लॉन्च गेटिंग (स्टैटिक)। |
| `node scripts/dev-realtools-smoke.mjs` | `ios_sim_screenshot` / `ios_sim_interact` / `ios_sim_ui_tree` / `ios_sim_tap_element` के असली-डिवाइस बैकएंड, साथ ही `ios_real_start_wda`। |
## इकोसिस्टम
- [DSH Android](https://github.com/ZSeven-W/dsh-android) — बातचीत के भीतर लाइव Android एमुलेटर या USB डिवाइस — पूरी तरह adb से संचालित
- [DSH Crew](https://github.com/ZSeven-W/dsh-crew) — Claude Code / Codex से DSH एजेंट को काम सौंपें
- [DSH Noema](https://github.com/ZSeven-W/dsh-noema) — DSH के लिए दीर्घकालिक स्मृति
- [DSH OpenPencil](https://github.com/ZSeven-W/dsh-openpencil) — बातचीत के भीतर `.op` डिज़ाइन दस्तावेज़ देखें और संपादित करें
## श्रेय & लाइसेंस
- [serve-sim](https://github.com/EvanBacon/serve-sim) — Evan Bacon — सिम्युलेटर स्ट्रीमिंग इंजन (Apache-2.0; बंडल की गई रनटाइम निर्भरता)।
- [AXe](https://github.com/cameroncooke/AXe) — Cameron Cooke — UI-ट्री टूल्स के पीछे की एक्सेसिबिलिटी CLI (MIT)।
- [WebDriverAgent](https://github.com/appium/WebDriverAgent) — वह WebDriver सर्वर जिसे प्लगइन असली डिवाइस पर बिल्ड करके लॉन्च करता है (BSD-लाइसेंस)।
- आर्किटेक्चर Codex के “Build iOS Apps” प्लगइन से प्रेरित; SwiftUI प्रीव्यू इंजन सार्वजनिक रूप से दस्तावेज़ित तरीक़े का क्लीन-रूम पुनःकार्यान्वयन है — कोई Codex कोड कॉपी नहीं किया गया।
- पूरी सूचनाओं के लिए [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md) देखें।
**लाइसेंस**: MIT