मैं लंबे एजेंट रन शुरू करता रहा और फिर टर्मिनल पर यूं मंडराता रहा जैसे वह मुझ पर पैसे उधार रखता हो। मरे हुए मिनट जुड़ते गए। तो मैंने एक छोटा टूल बनाया जो टर्मिनल पर नज़र रखता है ताकि मुझे न रखनी पड़े।

यहां शर्मिंदगी वाली बात है। मैं अपने AI एजेंट को एक असली काम देता, auth मॉड्यूल रीफ़ैक्टर करना, एक रूट माइग्रेट करना, पूरी टेस्ट सुइट चलाना, और फिर मैं बस... देखता रहता। प्रोग्रेस स्पिनर के छह मिनट, और मैं उसे यूं घूरता जैसे नज़र हटाते ही स्पिनर चला जाएगा।
दूसरा विकल्प इससे भी बुरा था। Slack पर चला जाना, किसी और चीज़ में उलझ जाना, और दस मिनट बाद वापस आना जब एजेंट पहले ही काम पूरा करके ठंडा पड़ चुका होता। तब तक मैं भूल चुका होता कि मैंने माँगा क्या था।
तो रन को लगते छह मिनट थे, पर मुझे कीमत पंद्रह की चुकानी पड़ती। हर बार। शुरू और खत्म के बीच का वह गैप, चुपचाप मेरा पूरा दिन खा रहा था।
🔔 सिग्नल पहले से ही वहां था
परेशान करने वाली बात यह है कि जिस पल के बारे में मैं जानना चाहता था, वह पहले से मौजूद है। हर एजेंट को ठीक-ठीक पता होता है कि उसने अपनी बारी कब खत्म की या आपसे कुछ पूछने के लिए कब रुका। Claude Code एक Stop हुक फ़ायर करता है। Codex में एक notify कमांड है। Gemini में AfterAgent इवेंट है। Copilot में agentStop है।
यह इवेंट हर टूल में पहले से बैठा था। कोई इसे एक सीधे "अरे, वापस आ जाओ" में नहीं बदल रहा था।
इसी नज़रिए ने मुझे शिकायत करना छोड़कर बनाना शुरू करवाया। मुझे कुछ भी पोल करने या किसी लॉग को स्क्रैप करने की ज़रूरत नहीं थी। मुझे बस एक ऐसा सिग्नल पकड़ना था जो एजेंट पहले से ही ब्रॉडकास्ट कर रहा था, और उसे आवाज़, नोटिफ़िकेशन, ध्वनि में बदलना था: एक धक्का जो मुझ तक पहुंचे चाहे मैं कहीं भी भटक गया हूं। यही turnbell करता है।

🧱 पहला फ़ैसला एक कॉन्स्ट्रेंट था, फ़ीचर नहीं
एक लाइन लिखने से पहले, मैंने तय किया कि यह टूल क्या नहीं कर सकता।
मेरी प्रोसेस लिस्ट में गुनगुनाता कोई बैकग्राउंड डेमन नहीं। हर प्रोजेक्ट में इम्पोर्ट करने के लिए कोई SDK नहीं। ऐसा कुछ भी नहीं जो मुझे इस बात से घबराए कि यह क्या छू रहा है। यह हर एजेंट के अपने हुक कॉन्फ़िग को एक कमांड कॉल करने के लिए वायर करता है, और बस यही इसका पूरा फ़ुटप्रिंट है।
इससे दो नियम निकले:
- हर बदलाव बाइट-फ़ॉर-बाइट रिवर्सिबल है। turnbell (जो npm पर भी है) एक कॉन्फ़िग एडिट एटॉमिकली लगाता है, फिर आपको दिखाता है कि उसने ठीक-ठीक क्या लिखा, और आपको उसी वक़्त उसे रखने या पलटने देता है। जो फ़ाइल छुई नहीं गई थी वह ठीक उन्हीं बाइट्स पर लौट आती है जो पहले थीं; जिस फ़ाइल में इसने सिर्फ़ एक ब्लॉक इंजेक्ट किया था (मसलन, एजेंट की इंस्ट्रक्शन फ़ाइल), उसमें से बस वह ब्लॉक निकाल दिया जाता है, तो बाद में आपने जो कुछ उसके इर्द-गिर्द एडिट किया वह बचा रहता है।
- अनइंस्टॉल को ईमानदार होना ही है। यह ठीक वही पलटता है जो इसने जोड़ा था, और कुछ नहीं, ऊपर वाले दोनों नियमों का इस्तेमाल करके, तो यह कभी यह दावा नहीं करता कि यह रिवर्सिबल है और चुपचाप ऐसा हो न सके।
ज़्यादातर असली इंजीनियरिंग यहीं गई, इस बेरौनक़ वादे में कि यह चीज़ आपकी मशीन को ठीक वैसा ही छोड़ेगी जैसा उसे मिला था। जो टूल आपका ग्लोबल कॉन्फ़िग एडिट करता है, उसे यह भरोसा कमाना ही पड़ता है।
🔒 इकलौती चीज़ जो आपकी मशीन छोड़ती है
मुझे फ़ोन अलर्ट्स चाहिए थे, यानी कुछ तो नेटवर्क पर जाना ही था। इससे मैं कम नहीं, ज़्यादा सतर्क हो गया।
आवाज़, डेस्कटॉप नोटिफ़िकेशन, और ध्वनि कभी मशीन नहीं छोड़तीं, वे परिभाषा से ही लोकल हैं। इकलौता आउटबाउंड रास्ता एक वैकल्पिक वेबहुक है, और इसका एक ही सीरियलाइज़र है जो ठीक छह फ़ील्ड्स भेजता है: एक वर्ज़न, एक टाइमस्टैम्प, एजेंट का नाम, इवेंट, प्रोजेक्ट के फ़ोल्डर का नाम, और एक छोटी स्टेटस लाइन।
कोई कोड नहीं। कोई वर्किंग डायरेक्टरी नहीं। एजेंट का कोई जवाब नहीं। और भरोसा करने से पहले ही आप ठीक-ठीक बाइट्स प्रिंट करवा सकते हैं: एक फ़्लैग आपको पेलोड दिखाता है और कुछ नहीं भेजता।
प्राइवेसी कोई मार्केटिंग लाइन नहीं थी जो मैंने आख़िर में चिपका दी। यह एक स्ट्रक्चरल फ़ैसला था: नेटवर्क को ठीक एक ही दरवाज़ा दो, और उस दरवाज़े को छोटा रखो।
🧩 आठ एजेंट, एक कॉन्ट्रैक्ट
फिर आया वह गड़बड़ बीच का हिस्सा, जहां आम तौर पर दिलचस्प काम छिपा होता है।
हर एजेंट अलग सेट के हुक अलग-अलग ताक़तों के साथ एक्सपोज़ करता है। Claude Code सब कुछ कर सकता है: फ़िनिश्ड, ब्लॉक्ड, रीड-अलाउड, एक स्लैश कमांड। Cursor सिर्फ़ यह बता सकता है कि उसने काम पूरा कर लिया। opencode अपना ट्रांसक्रिप्ट एक्सपोज़ नहीं कर सकता, तो जवाब ज़ोर से पढ़ना इसके लिए मुमकिन ही नहीं है।
लालच यह है कि इस फ़र्क़ पर पर्दा डाल दो और यूनिफ़ॉर्म सपोर्ट का दावा कर दो। मैंने उल्टा किया। मैंने एक ही wire/unwire कॉन्ट्रैक्ट के पीछे हर एजेंट के लिए एक एडाप्टर बनाया, और कैपेबिलिटी टेबल आपको सीधी सच्चाई बताती है कि हर एक असल में क्या दे सकता है।
क्योंकि किसी का भरोसा खोने का सबसे तेज़ तरीक़ा यह वादा करना है जो उसका सेटअप निभा ही नहीं सकता। ईमानदार सीमाएं एक ख़ूबसूरत लेकिन झूठी ग्रिड से बेहतर हैं।
🎯 मैंने असल में क्या सीखा
मज़ेदार हिस्सा कभी बोलता हुआ टर्मिनल नहीं था। वह हर वो चीज़ थी जो उसके इर्द-गिर्द थी।
असली समस्या कुछ ऐसा बनाना थी जो आपके ग्लोबल कॉन्फ़िग में, आपके एजेंट्स में, आपकी मशीन में घुसता है, और वहां रहने लायक़ हो। इसे एटॉमिकली लगाओ, इसे रिवर्सिबल बनाओ, नेटवर्क को एक छोटा दरवाज़ा दो, जो नहीं कर सकते वह ज़ोर से बोल दो।
मैं बार-बार एक ही टेस्ट पर लौटता रहा: इसे यूं बनाओ जैसे इसे अनइंस्टॉल करने वाला बंदा देख रहा हो। इसी एक नज़रिए ने किसी भी फ़ीचर रिक्वेस्ट से ज़्यादा डिज़ाइन फ़ैसले तय किए।
आजकल मैं एक लंबा रन शुरू करता हूं और सचमुच वहां से हट जाता हूं। कुछ मिनट बाद मेरा लैपटॉप जवाब ज़ोर से बोल देता है, या मेरा फ़ोन बज़ करता है क्योंकि एजेंट अटक गया है और उसे कोई फ़ैसला चाहिए। मरे हुए मिनट ख़त्म हो गए हैं। मुझे बस ठीक उसी पल वापस बुलाया जाता है जब मायने रखता है, न एक मिनट पहले, न दस मिनट बाद।
अगर रिवर्सिबल कॉन्फ़िग एडिट्स और एक-दरवाज़े वाली नेटवर्क पॉलिसी आपको पसंद आई: turnbell ओपन सोर्स है: GitHub · npm।
आपके पास वह कौन-सा कॉन्फ़िग-एडिट करने वाला टूल है जिस पर आप तुरंत भरोसा करना बंद कर देंगे अगर पता चले कि वह रिवर्सिबल नहीं है?
मुझे जिज्ञासा है कि क्या यह आपके साथ पहले ही हो चुका है, कोई CLI जिसने कोई dotfile दोबारा लिख दिया और वापस लौटने का कोई रास्ता नहीं छोड़ा, और क्या इसने बदल दिया कि आप किसी इंस्टॉलर के वादों को कितनी बारीक़ी से पढ़ते हैं।


