इसे छोड़कर कंटेंट पर जाएं

TUI रनटाइम इंटर्नल्स

यह दस्तावेज़ इंटरैक्टिव मोड में टर्मिनल इनपुट से रेंडर किए गए आउटपुट तक के नॉन-थीम रनटाइम पाथ का मानचित्रण करता है। यह packages/tui में व्यवहार और packages/coding-agent कंट्रोलर्स से इसके इंटीग्रेशन पर केंद्रित है।

रनटाइम परतें और स्वामित्व

Section titled “रनटाइम परतें और स्वामित्व”
  • packages/tui इंजन: टर्मिनल लाइफसाइकिल, stdin नॉर्मलाइज़ेशन, फोकस रूटिंग, रेंडर शेड्यूलिंग, डिफरेंशियल पेंटिंग, ओवरले कंपोज़िशन, हार्डवेयर कर्सर प्लेसमेंट।
  • packages/coding-agent इंटरैक्टिव मोड: कम्पोनेंट ट्री बनाता है, एडिटर कॉलबैक और कीमैप बाइंड करता है, एजेंट/सेशन इवेंट्स पर प्रतिक्रिया देता है, और डोमेन स्टेट (स्ट्रीमिंग, टूल एक्जीक्यूशन, रिट्रीज़, प्लान मोड) को UI घटकों में अनुवादित करता है।

बाउंड्री नियम: TUI इंजन मैसेज-अज्ञेय है। यह केवल Component.render(width), handleInput(data), फोकस और ओवरले जानता है। एजेंट सेमांटिक्स इंटरैक्टिव कंट्रोलर्स में रहते हैं।

इम्प्लीमेंटेशन फ़ाइलें

Section titled “इम्प्लीमेंटेशन फ़ाइलें”

बूट और कम्पोनेंट ट्री असेंबली

Section titled “बूट और कम्पोनेंट ट्री असेंबली”

InteractiveMode TUI(new ProcessTerminal(), showHardwareCursor) का निर्माण करता है और परसिस्टेंट कंटेनर बनाता है:

  • chatContainer
  • pendingMessagesContainer
  • statusContainer
  • todoContainer
  • statusLine
  • editorContainer (CustomEditor रखता है)

init() उस क्रम में ट्री को वायर करता है, एडिटर पर फोकस करता है, InputController के माध्यम से इनपुट हैंडलर रजिस्टर करता है, TUI शुरू करता है, और एक फोर्स्ड रेंडर का अनुरोध करता है।

एक फोर्स्ड रेंडर (requestRender(true)) रिपेंटिंग से पहले पिछली-लाइन कैश और कर्सर बुककीपिंग को रीसेट करता है।

टर्मिनल लाइफसाइकिल और stdin नॉर्मलाइज़ेशन

Section titled “टर्मिनल लाइफसाइकिल और stdin नॉर्मलाइज़ेशन”

ProcessTerminal.start():

  1. रॉ मोड और ब्रैकेटेड पेस्ट सक्षम करता है।
  2. रिसाइज़ हैंडलर अटैच करता है।
  3. आंशिक एस्केप चंक्स को पूर्ण सीक्वेंस में विभाजित करने के लिए StdinBuffer बनाता है।
  4. Kitty कीबोर्ड प्रोटोकॉल सपोर्ट (CSI ? u) क्वेरी करता है, फिर सपोर्टेड होने पर प्रोटोकॉल फ्लैग सक्षम करता है।
  5. Windows पर, kernel32 मोड फ्लैग के माध्यम से VT इनपुट एनेबलमेंट का प्रयास करता है।

StdinBuffer व्यवहार:

  • खंडित एस्केप सीक्वेंस (CSI/OSC/DCS/APC/SS3) बफर करता है।
  • data केवल तभी एमिट करता है जब कोई सीक्वेंस पूर्ण हो या टाइमआउट-फ्लश हो।
  • ब्रैकेटेड पेस्ट डिटेक्ट करता है और रॉ पेस्ट किए गए टेक्स्ट के साथ paste इवेंट एमिट करता है।

यह आंशिक एस्केप चंक्स को सामान्य कीप्रेस के रूप में गलत व्याख्यायित होने से रोकता है।

इनपुट रूटिंग और फोकस मॉडल

Section titled “इनपुट रूटिंग और फोकस मॉडल”

इनपुट पाथ:

stdin -> ProcessTerminal -> StdinBuffer -> TUI.#handleInput -> focusedComponent.handleInput

रूटिंग विवरण:

  1. TUI पहले रजिस्टर्ड इनपुट लिसनर चलाता है (addInputListener), जो consume/transform व्यवहार की अनुमति देता है।
  2. TUI कम्पोनेंट डिस्पैच से पहले ग्लोबल डीबग शॉर्टकट (shift+ctrl+d) हैंडल करता है।
  3. यदि फोकस्ड कम्पोनेंट किसी ओवरले से संबंधित है जो अब hidden/invisible है, तो TUI अगले visible ओवरले या सेव किए गए pre-overlay फोकस को फोकस रीअसाइन करता है।
  4. कीमुक्ति इवेंट्स फ़िल्टर किए जाते हैं जब तक फोकस्ड कम्पोनेंट wantsKeyRelease = true सेट नहीं करता।
  5. डिस्पैच के बाद, TUI रेंडर शेड्यूल करता है।

setFocus() Focusable.focused को भी टॉगल करता है, जो नियंत्रित करता है कि घटक हार्डवेयर कर्सर प्लेसमेंट के लिए CURSOR_MARKER एमिट करते हैं या नहीं।

की हैंडलिंग विभाजन: एडिटर बनाम कंट्रोलर

Section titled “की हैंडलिंग विभाजन: एडिटर बनाम कंट्रोलर”

CustomEditor पहले उच्च-प्राथमिकता कॉम्बो इंटरसेप्ट करता है (escape, ctrl-c/d/z, ctrl-v, ctrl-p वेरिएंट, ctrl-t, alt-up, एक्सटेंशन कस्टम कीज़) और बाकी को बेस Editor व्यवहार (टेक्स्ट एडिटिंग, हिस्ट्री, ऑटोकम्पलीट, कर्सर मूवमेंट) को डेलीगेट करता है।

InputController.setupKeyHandlers() फिर एडिटर कॉलबैक को मोड एक्शन से बाइंड करता है:

  • Escape पर कैंसेलेशन / मोड एग्जिट
  • डबल Ctrl+C या खाली-एडिटर Ctrl+D पर शटडाउन
  • Ctrl+Z पर सस्पेंड/रिज्यूम
  • स्लैश-कमांड और सेलेक्टर हॉटकीज़
  • फॉलो-अप/डीक्यू टॉगल और एक्सपेंशन टॉगल

यह की पार्सिंग/एडिटर मेकैनिक्स को packages/tui में और मोड सेमांटिक्स को coding-agent कंट्रोलर्स में रखता है।

रेंडर लूप और डिफिंग रणनीति

Section titled “रेंडर लूप और डिफिंग रणनीति”

TUI.requestRender() को process.nextTick का उपयोग करके प्रति टिक एक रेंडर तक डिबाउंस किया जाता है। एक ही टर्न में कई स्टेट परिवर्तन कोलेस होते हैं।

#doRender() पाइपलाइन:

  1. रूट कम्पोनेंट ट्री को newLines में रेंडर करें।
  2. दृश्यमान ओवरले कम्पोज़िट करें (यदि कोई हो)।
  3. दृश्यमान व्यूपोर्ट लाइनों से CURSOR_MARKER एक्सट्रैक्ट और स्ट्रिप करें।
  4. नॉन-इमेज लाइनों के लिए सेगमेंट रीसेट सफिक्स अपेंड करें।
  5. फुल रिपेंट बनाम डिफरेंशियल पैच चुनें:
    • पहला फ्रेम
    • चौड़ाई परिवर्तन
    • clearOnShrink सक्षम और कोई ओवरले नहीं के साथ श्रिंक
    • पिछले व्यूपोर्ट के ऊपर एडिट
  6. डिफरेंशियल अपडेट के लिए, केवल बदली हुई लाइन रेंज पैच करें और आवश्यक होने पर पुरानी ट्रेलिंग लाइनें क्लियर करें।
  7. IME सपोर्ट के लिए हार्डवेयर कर्सर रिपोज़िशन करें।

रेंडर राइट्स फ्लिकर/टियरिंग को कम करने के लिए सिंक्रोनाइज़्ड आउटपुट मोड (CSI ? 2026 h/l) का उपयोग करते हैं।

रेंडर सेफ्टी कॉन्स्ट्रेंट्स

Section titled “रेंडर सेफ्टी कॉन्स्ट्रेंट्स”

TUI में महत्वपूर्ण सेफ्टी चेक:

  • नॉन-इमेज रेंडर की गई लाइनें टर्मिनल चौड़ाई से अधिक नहीं होनी चाहिए; ओवरफ्लो थ्रो करता है और क्रैश डायग्नोस्टिक्स लिखता है।
  • ओवरले कम्पोज़िटिंग में डिफेंसिव ट्रंकेशन और पोस्ट-कम्पोज़िट चौड़ाई वेरिफिकेशन शामिल है।
  • चौड़ाई परिवर्तन फुल रीड्रॉ को बाध्य करता है क्योंकि रैपिंग सेमांटिक्स बदलती हैं।
  • मूवमेंट से पहले कर्सर पोज़िशन क्लैम्प की जाती है।

ये कॉन्स्ट्रेंट्स रनटाइम एनफोर्समेंट हैं, केवल कन्वेंशन नहीं।

रिसाइज़ हैंडलिंग

Section titled “रिसाइज़ हैंडलिंग”

रिसाइज़ इवेंट्स ProcessTerminal से TUI.requestRender() तक इवेंट-ड्रिवन हैं।

प्रभाव:

  • किसी भी चौड़ाई परिवर्तन से फुल रीड्रॉ ट्रिगर होता है।
  • व्यूपोर्ट/टॉप ट्रैकिंग (#previousViewportTop, #maxLinesRendered) कंटेंट या टर्मिनल साइज़ बदलने पर अमान्य रिलेटिव कर्सर मैथ से बचती है।
  • ओवरले विज़िबिलिटी टर्मिनल डायमेंशन पर निर्भर हो सकती है (OverlayOptions.visible); रिसाइज़ के बाद ओवरले non-visible हो जाने पर फोकस करेक्ट किया जाता है।

स्ट्रीमिंग और इंक्रीमेंटल UI अपडेट

Section titled “स्ट्रीमिंग और इंक्रीमेंटल UI अपडेट”

EventController AgentSessionEvent को सब्सक्राइब करता है और UI को इंक्रीमेंटली अपडेट करता है:

  • agent_start: statusContainer में लोडर शुरू करता है।
  • message_start असिस्टेंट: streamingComponent बनाता है और माउंट करता है।
  • message_update: स्ट्रीमिंग असिस्टेंट कंटेंट अपडेट करता है; टूल कॉल्स आने पर टूल एक्जीक्यूशन घटक बनाता/अपडेट करता है।
  • tool_execution_update/end: टूल रिज़ल्ट घटक और कम्पलीशन स्टेट अपडेट करता है।
  • message_end: असिस्टेंट स्ट्रीम को फाइनलाइज़ करता है, aborted/error एनोटेशन हैंडल करता है, नॉर्मल स्टॉप पर पेंडिंग टूल args को कम्पलीट मार्क करता है।
  • agent_end: लोडर्स बंद करता है, ट्रांजिएंट स्ट्रीम स्टेट क्लियर करता है, डिफर्ड मॉडल स्विच फ्लश करता है, बैकग्राउंड होने पर कम्पलीशन नोटिफिकेशन जारी करता है।

Read-tool ग्रुपिंग जानबूझकर स्टेटफुल है (#lastReadGroup) ताकि नॉन-रीड ब्रेक होने तक लगातार रीड टूल कॉल्स को एक विज़ुअल ब्लॉक में कोलेस किया जा सके।

स्टेटस और लोडर ऑर्केस्ट्रेशन

Section titled “स्टेटस और लोडर ऑर्केस्ट्रेशन”

स्टेटस लेन स्वामित्व:

  • statusContainer ट्रांजिएंट लोडर रखता है (loadingAnimation, autoCompactionLoader, retryLoader)।
  • statusLine परसिस्टेंट स्टेटस/हुक्स/प्लान इंडिकेटर रेंडर करता है और एडिटर टॉप बॉर्डर अपडेट ड्राइव करता है।

लोडर व्यवहार:

  • Loader इंटरवल के माध्यम से हर 80ms अपडेट होता है और प्रत्येक फ्रेम रेंडर का अनुरोध करता है।
  • ऑटो-कॉम्पेक्शन और ऑटो-रिट्री के दौरान उन ऑपरेशन को कैंसल करने के लिए एस्केप हैंडलर अस्थायी रूप से ओवरराइड किए जाते हैं।
  • end/cancel पाथ पर, कंट्रोलर्स पिछले एस्केप हैंडलर रिस्टोर करते हैं और लोडर घटक बंद/क्लियर करते हैं।

मोड ट्रांजिशन और बैकग्राउंडिंग

Section titled “मोड ट्रांजिशन और बैकग्राउंडिंग”

इनपुट टेक्स्ट प्रीफिक्स एडिटर बॉर्डर मोड फ्लैग टॉगल करते हैं:

  • ! -> bash मोड
  • $ (नॉन-टेम्पलेट लिटरल प्रीफिक्स) -> python मोड

Escape इनएक्टिव मोड से एडिटर टेक्स्ट क्लियर करके और बॉर्डर कलर रिस्टोर करके बाहर निकलता है; जब एक्जीक्यूशन एक्टिव हो, escape चल रहे टास्क को एबॉर्ट करता है।

InteractiveMode प्लान मोड फ्लैग, स्टेटस-लाइन स्टेट, एक्टिव टूल्स और मॉडल स्विचिंग ट्रैक करता है। Enter/exit सेशन मोड एंट्री और स्टेटस/UI स्टेट अपडेट करता है, जिसमें स्ट्रीमिंग एक्टिव होने पर डिफर्ड मॉडल स्विच शामिल है।

सस्पेंड/रिज्यूम (Ctrl+Z)

Section titled “सस्पेंड/रिज्यूम (Ctrl+Z)”

InputController.handleCtrlZ():

  1. TUI रिस्टार्ट करने और फोर्स रेंडर के लिए वन-शॉट SIGCONT हैंडलर रजिस्टर करता है।
  2. सस्पेंड से पहले TUI बंद करता है।
  3. प्रोसेस ग्रुप को SIGTSTP भेजता है।

बैकग्राउंड मोड (/background या /bg)

Section titled “बैकग्राउंड मोड (/background या /bg)”

handleBackgroundCommand():

  • आइडल होने पर रिजेक्ट करता है।
  • टूल UI कंटेक्स्ट को नॉन-इंटरैक्टिव (hasUI=false) पर स्विच करता है ताकि इंटरैक्टिव UI टूल्स जल्दी फेल हों।
  • लोडर/स्टेटस लाइन बंद करता है और फोरग्राउंड इवेंट हैंडलर अनसब्सक्राइब करता है।
  • बैकग्राउंड इवेंट हैंडलर सब्सक्राइब करता है (मुख्यतः agent_end की प्रतीक्षा करता है)।
  • TUI बंद करता है और SIGTSTP भेजता है (POSIX जॉब कंट्रोल पाथ)।

बैकग्राउंड में agent_end पर बिना क्यूड वर्क के, कंट्रोलर कम्पलीशन नोटिफिकेशन भेजता है और शटडाउन करता है।

प्राथमिक कैंसेलेशन इनपुट:

  • एक्टिव स्ट्रीम लोडर के दौरान Escape: क्यूड मैसेज एडिटर में रिस्टोर करता है और एजेंट एबॉर्ट करता है।
  • bash/python एक्जीक्यूशन के दौरान Escape: चल रहे कमांड को एबॉर्ट करता है।
  • ऑटो-कॉम्पेक्शन/रिट्री के दौरान Escape: अस्थायी एस्केप हैंडलर के माध्यम से डेडिकेटेड एबॉर्ट मेथड इनवोक करता है।
  • Ctrl+C सिंगल प्रेस: एडिटर क्लियर; 500ms के भीतर डबल प्रेस: शटडाउन।

कैंसेलेशन स्टेट-कंडिशनल है; एक ही की रनटाइम स्टेट के आधार पर abort, mode-exit, selector trigger, या no-op का अर्थ दे सकती है।

इवेंट-ड्रिवन बनाम थ्रॉटल्ड व्यवहार

Section titled “इवेंट-ड्रिवन बनाम थ्रॉटल्ड व्यवहार”

इवेंट-ड्रिवन अपडेट:

  • एजेंट सेशन इवेंट्स (EventController)
  • की इनपुट कॉलबैक (InputController)
  • टर्मिनल रिसाइज़ कॉलबैक
  • InteractiveMode में थीम/ब्रांच वॉचर

थ्रॉटल्ड/डिबाउंस्ड पाथ:

  • TUI रेंडरिंग टिक-डिबाउंस्ड है (requestRender कोलेसिंग)।
  • लोडर एनिमेशन फिक्स्ड-इंटरवल (80ms) है, प्रत्येक फ्रेम रेंडर का अनुरोध करता है।
  • एडिटर ऑटोकम्पलीट अपडेट (Editor के अंदर) डिबाउंस टाइमर का उपयोग करते हैं, टाइपिंग के दौरान रिकम्प्यूट चर्न कम करते हैं।

रनटाइम इसलिए बाउंडेड रेंडर कैडेंस के साथ इवेंट-ड्रिवन स्टेट ट्रांजिशन को मिलाता है ताकि रिपेंट स्टॉर्म के बिना इंटरैक्टिविटी रिस्पॉन्सिव बनी रहे।