अंतिम CLI: पुनर्निर्माण Base 51 के खिलाफ मेरे उपकरण बनाए गए
हर मॉडल ने अलग-अलग लाइब्रेरीज़ के सेट को चुना, इसलिए मैंने एक बेस बनाया और हर प्रोजेक्ट को उसमें अपस्ट्रीम किया. फिर मैंने Claude Fable से पूछा कि CLI मानवता अभी भी एक दशक में उपयोग कर सकती है, और Opus 5 और मैंने जो वापस आया उसे बनाया — 46 क्लॉज़, 92 टेस्ट, शून्य डिपेंडेंसीज़।
Developed by Robert E. Beckner III (Merlin) | rbeckner.com
मेरे पास इस मशीन पर 51 कमांड-लाइन टूल्स हैं. मैंने उस संख्या की योजना नहीं बनाई थी. यह इसलिए हुआ क्योंकि एक CLI एक विचार और कुछ ऐसा चलाने के बीच सबसे छोटा दूरी है जिसे मैं वास्तव में चला सकता हूँ, और क्योंकि पिछले कई वर्षों से मेरे पास उन्हें अकेले से तेज़ लिखने में मदद मिली है।
वह मदद एक आदत के साथ आई जिसे मैंने जल्दी ही नोटिस किया, जब GPT-3.5 और पहले Claude मॉडल्स वे थे जिनके साथ मैं काम करता था. 3 अलग-अलग मॉडलों से CLI के लिए स्कैफ़ोल्डिंग पूछें और आपको CLI क्या है, इस पर 3 अलग-अलग राय मिलेंगी। एक Commander की ओर बढ़ता है. एक व्यक्ति Inquirer के लिए पहुँचता है प्रेरणा के लिए. एक Chalk की ओर बढ़ता है क्योंकि आउटपुट रंगीन होना चाहिए. प्रत्येक उत्तर बचाव योग्य है. साथ में वे एक टैक्स हैं, क्योंकि अब मेरे पास 3 कोडबेस हैं जो आर्गुमेंट पार्सिंग, विफलता कैसी दिखती है, और कौन सी लाइब्रेरीज़ मैं अब देखभाल के लिए जिम्मेदार हूँ, इन सब पर असहमत हैं.
हर मॉडल ने अलग-अलग लाइब्रेरीज़ के सेट को चुना, और मैं वही था जिसे सभी के साथ रहना पड़ा#
टैक्स लाइब्रेरीज़ नहीं है. यह है कि सुधार यात्रा करना बंद कर देते हैं.
जब 3 CLIs इस बात पर असहमत होते हैं कि एक कमांड विफलता को कैसे रिपोर्ट करता है, एक में सुधार एक में सुधार है. इसे अपस्ट्रीम करने के लिए कुछ भी नहीं है. काम संयोजित नहीं होता, और दसवें टूल के बाद आप लीवरेज नहीं बना रहे हैं, आप निकट‑मिसेज़ के पोर्टफोलियो को बनाए रख रहे हैं.
मैंने पहले ही इसके विपरीत चाहने के बारे में लिखा था. पूरे तर्क में How to Turn AI Gains Into Compounding Infrastructure यह है कि एक लाभ तब स्थायी बनता है जब हर निर्भर प्रोजेक्ट इसे विरासत में लेता है। एक साझा क्षमता सतह. एक प्रमोशन नियम. एक जगह जहाँ एक सुधार उतरता है और फैलता है.
मैंने वह परत AI क्षमता, वर्कफ़्लो, संचालन के लिए बनाई थी. मैंने इसे उस चीज़ के लिए नहीं बनाया जिसे मैं वास्तव में सबसे अधिक बनाता हूँ.
इसलिए मैंने एक बेस बनाया और हर CLI प्रोजेक्ट को उसके सुधारों को उसमें ऊपर भेजा#
नियम सरल था और इसे लागू करना मेरा था: जब मेरे एस्टेट में एक CLI को कुछ बेहतर चाहिए — सेवाओं को पंजीकृत करने का एक साफ़ तरीका, बेहतर त्रुटि पथ, एक परीक्षण सहायक जो सूट को पठनीय बनाता है — वह सुधार प्रोजेक्ट में नहीं रहता। यह बेस में गया, और बेस दूसरों तक गया.
यही पूरा डिज़ाइन है. बेस जानबूझकर छोटा है. इसका आपके टूल के बारे में कोई राय नहीं है. इसका एक मजबूत राय है कि एक कमांड क्या है: कुछ जो तर्क लेता है, काम करता है, क्या हुआ रिपोर्ट करता है, और छोड़ देता है.
फ़ोल्डर 6 जुलाई 2025 को बनाया गया था, और मेरे टूल्स के 2 संस्करण 1.0 पर निर्भर थे।0 उसी दिन इसका वही संस्करण. यह संकेत है: इसे अनुमानित रूप से नहीं बनाया गया था और फिर अपनाया गया. यह पहले से मौजूद काम से निकाला गया था, उस बिंदु पर जहां प्रोजेक्ट्स के बीच वही स्कैफ़ोल्डिंग कॉपी करना तर्कसंगत नहीं रहा.
यह जल्दी फैल गया, क्योंकि फैलाव ही पूरी अवधारणा थी. 8 रिपॉज़िटरीज़ इसे 25 दिनों में कर रही थीं. 10 11 हफ्तों में.
Repositories Adopting the Base in 2025Chart data
repositories
Jul 6
2
Jul 8
4
Jul 17
5
Jul 23
7
Jul 30
8
Sep 20
10
Git उससे बाद में आया। रिपॉज़िटरी 12 नवंबर 2025 को प्रारंभ की गई, 4 महीनों में, और अगले दिन प्रकाशित हुई — यही कारण है कि संस्करण इतिहास और वास्तविक इतिहास असहमत हैं, और क्यों मैंने फ़ाइल सिस्टम की जाँच की बजाय कमिट लॉग पर भरोसा नहीं किया जब मैं यह लिखने बैठा.
वे 10 टूल्स Cloudflare प्रशासन करते हैं. स्थानीय DNS और nginx प्रबंधन। Coolify के खिलाफ तैनाती।. ब्राउज़र ऑटोमेशन. मॉडल प्रदाताओं के बीच लागत रिपोर्टिंग. अधिकांश निजी हैं, इसलिए मैं उन्हें उनके कार्य के आधार पर वर्णित कर रहा हूँ न कि नाम के आधार पर. सार्वजनिक वाले aia, जो कई मॉडलों को समानांतर में परामर्श करते हैं, और स्वयं आधार। vssh, मेरा संरक्षित रिमोट-एक्ज़ीक्यूशन टूल, भी सार्वजनिक है और उसी प्रवृत्ति से निकला — ऑपरेटर सतह को एक बार, सही ढंग से बनाना, और उसे पुनः बनाने से रोकना।
लाभांश वास्तविक थे और वे उबाऊ थे, जो अवसंरचना लाभांश के लिए सही आकार है. एक टूल में हार्डनिंग सभी में दिखाई दी. जब मैंने पाया कि एक कमांड लाल त्रुटि संदेश प्रिंट कर सकता है और फिर भी 0 पर बाहर निकल सकता है — मानव को बताता है कि यह विफल हुआ और शेल को बताता है कि यह काम किया — तो सुधार उस एक टूल में 16 स्थानों में नहीं गया जहाँ यह हुआ था। यह आधार में गया, और हर टूल ने इसे विरासत में लिया.
13 महीनों के बाद मैं इसे पुनर्निर्मित करना चाहता था, पैच नहीं#
अगस्त 2026 तक बेस काम कर रहा था और मैं अभी भी इसे हटाना चाहता था.
क्योंकि यह टूटा हुआ नहीं था. क्योंकि यह जमा हो गया था. क्योंकि वह exit-code नियम जिसे मैं सबसे गर्वित था, उसे पुनः फिट किया गया था बजाय इसके कि डिज़ाइन किया गया हो. क्योंकि वह दुनिया जिसके लिए यह लिखा गया था, उसके नीचे शिफ्ट हो गई: मेरी CLIs के अधिकांश कॉल अब मेरे द्वारा टाइप नहीं किए जाते. वे एजेंटों द्वारा जारी किए जाते हैं, stdout, stderr, और $? को अपनी एकमात्र इंद्रियों के रूप में पढ़ते हुए।
इसलिए पैच करने के बजाय, मैंने शर्तों को अलग ढंग से सेट किया. मैंने Claude Fable को एक ही निर्देश दिया, और इसे जानबूझकर बड़ा बनाया:
यदि यह अंतिम CLI फ्रेमवर्क है जिसे मानवता ने बनाया — वह जो अभी भी सेवा में है
एक दशक में — तो अब आपके पास इसे बनाने का मौका है.
वहीं से इसे डिज़ाइन करें. मैं दस्तावेज़ वापस आने की उम्मीद नहीं कर रहा था. मैं एक योजना की उम्मीद कर रहा था.
फेबल एक संधि के साथ वापस आया, और प्रतिबंध यह था कि वादे कम होने चाहिए#
जो आया वह फीचर सूची नहीं थी. यह एक संधि के रूप में संरचित था, एक कठोर दीवार द्वारा बीच में विभाजित.
एक आधा एक अनुबंध था: जो भी CLI इस आधार पर निर्मित करता है, वह हर पर्यवेक्षक को गारंटी देता है, जिसे RFC-2119 भाषा में क्रमांकित खंडों के रूप में लिखा गया है — करना अनिवार्य है, करना अनिवार्य नहीं है, करना चाहिए, हो सकता है. बारह परिवार हैं। निकास कोड. स्ट्रीम अनुशासन. मशीन आउटपुट. Self-description. Grammar. Environment. Cancellation. Determinism. प्रदर्शन बजट. Compatibility.
दूसरा आधा लेखन सतह था, जिसे बढ़ने की अनुमति थी, और जो केवल अनुबंध को संतुष्ट करने के लिए सबसे कम प्रतिरोध का मार्ग बनाने के लिए मौजूद था.
नीचे दिया गया तर्क वह भाग था जिसे मैंने विश्वसनीय पाया. एक ऐसा डिज़ाइन जो दशक तक चलने के लिए बनाया गया है, फैशन पर दांव नहीं लगा सकता, क्योंकि फैशन वही है जो समाप्त हो जाता है. यह चतुराई पर दांव नहीं लगा सकता, क्योंकि चतुराई वही है जिसे आप वर्ष 8 में पूर्वानुमान नहीं कर सकते. यह केवल उन इंटरफेस पर दांव लगा सकता है जो 1970s के बाद से नहीं बदले हैं: आर्गुमेंट वेक्टर, 3 स्ट्रीम, एक 8-बिट एग्ज़िट कोड, एनवायरनमेंट वेरिएबल्स. और इसने एक वास्तव में नया तथ्य नोट किया — कि उन इंटरफेस का अधिकांश पाठक अब एक ऐसी मशीन है जो फॉलो‑अप प्रश्न नहीं पूछ सकती.
वह क्लॉज़ जिसने सब कुछ व्यवस्थित किया, वह था जिसे उसने इस तरह खोला:
एक परिणाम, कई रेंडरिंग्स. एक कमांड एकल परिणाम की गणना करता है. एग्ज़िट
कोड, मानव पाठ, JSON दस्तावेज़ और स्ट्रीमिंग लाइन्स सभी
उस एक मान के प्रक्षेपण हैं. वे एक-दूसरे का विरोध नहीं कर सकते, क्योंकि
केवल एक स्रोत है.
यही वह वाक्य है जिस पर पूरा पुनर्निर्माण निर्भर करता है.
Diagram source
graph LR
A["execute() returns
एक मान"] --> B["एग्ज़िट कोड"]
A --> C["रेंडर्ड टेक्स्ट
stdout"]
A --> D["JSON एनवेलप
--json"]
A --> E["NDJSON स्ट्रीम
--ndjson"]
F["logger.error()
ctx.emit()"] -.-> B
F -.-> G["इवेंट्स
stderr"]
ओपस 5 और मैंने पाया कि विनिर्देश थीसिस के बारे में सही था और 3 चीजों के बारे में गलत था#
यह वह जगह है जहां काम हमारा बन गया बजाय मेरा.
मैंने विनिर्देश को ओपस 5 तक पहुँचाया और हमने इसे एक दिन में बनाया. साफ दिन नहीं था. उपयोगी भाग वे स्थान हैं जहां दस्तावेज़ ने एस्टेट से मुलाकात की और खो गया.
स्पेक ने ctx.args को नामित तर्कों के रिकॉर्ड में बदलने की इच्छा की। यह है
यह हर कमांड को भी तोड़ देता, हर एक. यह भी हर एक में हर कमांड को तोड़ देता
10 उपकरणों में से, क्योंकि वे सभी ctx.args को एक ऐरे के रूप में पढ़ते हैं। और टाइप किए गए तर्कों को ctx.namedArgs के बगल में रखा।
वह नियम जिसने निर्णय लिया. वह नियम जिसने तय किया
यह पहले ही अनुबंध में लिखा हुआ था, एक उपधारा ऊपर: कभी न तोड़ें एक
उपभोक्ता अन्य सभी मूल्यों से ऊपर है रिपॉज़िटरी में, अनुबंध के
अपनी पूर्णता.
स्पेक ने एक कमांड समूह बिना क्रिया के उपयोग त्रुटि के रूप में चाहा। चलाना एक
पैरेंट कमांड बिना सबकमांड के 2 पर बाहर निकलता। रक्षनीय, और यह करेगा
प्रत्येक स्क्रिप्ट के व्यवहार को बदलता जो एक साधारण समूह कमांड चलाता है देखने के लिए
उसकी मदद. हमने मदद प्रिंट करना जारी रखा और 0 पर बाहर निकलते रहे।
स्पेक ने मान लिया कि स्ट्रीमिंग और एकल JSON दस्तावेज़ समान थे
विशेषता। वे नहीं हैं. एक मिलियन आइटम को स्थिर मेमोरी में स्ट्रीम करना है
एक का बिंदु और दूसरे में असंभव, क्योंकि एक कॉलर जिसने एक के लिए पूछा
एकल दस्तावेज़ ने इसे एकल होने के लिए कहा. हमने व्यवहार को विभाजित किया और लिखा
कौन सी उपधारा किसे नियंत्रित करती है.
हमने उन चीजों को भी पाया जिन्हें स्पेक नहीं जान सकता था, क्योंकि वे केवल कलाकृति से दिखाई देती थीं. एक परीक्षण फ़ाइल जिसने 0 परीक्षण चलाए और सफलता रिपोर्ट की, रनर को बीच में मारते हुए. सिग्नल हैंडलिंग जिसने Ctrl-C पर 0 पर बाहर निकला — एक बाधित कमांड जिसने रिपोर्ट किया कि यह सफल रहा। दो आउटपुट हेल्पर जिन्होंने अपनी पंक्तियों को शाब्दिक बैकस्लैश-n से जोड़ा, ताकि हर तालिका एक पंक्ति पर वापस आई. एक रंग हेल्पर जिसने, जब हमने उस निर्भरता को बदल दिया जिसे उसने लपेटा था, शांतिपूर्वक अपनी टाइप सिग्नेचर को संकुचित कर दिया और कोड को तोड़ दिया जिसने कोई अक्षर नहीं बदला.
वह आखिरी एक साथ बैठने लायक है. यह किसी भी परीक्षण द्वारा नहीं पकड़ा गया जिसे हमने लिखा. यह माइग्रेशन के दौरान एक consumer's टाइपचेक में उभरा, जो एकमात्र स्थान है जहाँ यह हो सकता था.
कॉन्ट्रैक्ट केवल गिना जाता है क्योंकि बिल्ड तब विफल होता है जब किसी क्लॉज़ में कोई परीक्षण नहीं होता।#
एक वादा जिसे कुछ भी जांचता नहीं है, वह एक टिप्पणी है.
इसलिए कॉन्फ़ॉर्म. आप इस परियोजना में बिना उस चीज़ को जो इसे प्रमाणित करती है, वादा नहीं जोड़ सकते, उसी कमिट में.
Conformance Tests by Contract FamilyChart data
Value
Grammar
20
Exit codes (truth)
12
Machine output
11
Self-description
10
Environment
8
Prompt safety
6
Streams
5
Cancellation
5
Determinism
5
46 मानक क्लॉज़. 92 परीक्षण उनके साथ मैप किए गए. 184 कुल परीक्षण.
और उन सभी अनुपालन परीक्षणों में से कोई भी स्रोत पर नहीं चलता. वे पैकेज को अपनी स्वयं की बिल्ड स्क्रिप्ट के साथ बनाते हैं, npm pack चलाते हैं, टारबॉल को अनपैक करते हैं, फ़िक्स्चर CLI लिखते हैं जो अनपैक्ड एंट्री पॉइंट को इम्पोर्ट करते हैं, और उन्हें Node, Bun और Deno के तहत स्पॉन करते हैं — एग्ज़िट स्टेटस और बाइट्स पर उसी तरह दावा करते हैं जैसे एक शेल उन्हें देखेगा।
वह आकार सौंदर्यपूर्ण विकल्प नहीं था. इस पैकेज ने एक बार एक 65 KB स्टब शिप किया था. एक एकल "sideEffects": false फ़्लैग ने बंडलर को राउटर और एग्ज़िट-कोड मॉड्यूल को आर्टिफैक्ट से ट्री-शेक करने दिया जबकि उनके नाम निर्यात सूची में बने रहे। बिल्ड ने 0 के साथ बाहर निकला। स्रोत सूट पूरे समय हरा रहा. केवल कलाकृति साक्ष्य थी, और कोई भी कलाकृति को नहीं देख रहा था.
माइग्रेटिंग 7 टूल्स ने 3 गेट्स खोजे जिन्हें किसी ने नहीं जाना था#
हमने उसी दिन 7 के 10 CLI को माइग्रेट किया, और माइग्रेशन वह जगह है जहां डिजाइन ने अपनी वास्तविक ग्रेड प्राप्त की.
डिविडेंड तुरंत ही पहुंचा और कुछ भी लागत नहीं: क्योंकि पुराने संस्करण में कमांड पहले से ही मान लौटाते थे — फ्रेमवर्क ने उन्हें केवल एक एग्जिट कोड निकालने के लिए उपयोग किया, फिर उन्हें त्याग दिया — उन सभी रिटर्न मानों में से हर एक JSON पेलोड बन गया उन्नयन दिन पर। 7 टूल्स ने मशीन-पढ़ने योग्य आउटपुट प्राप्त किया बिना किसी एक कमांड को फिर से लिखे.
जो हमने अपेक्षा नहीं की थी वह वही दोष था 3 अलग-अलग टूल्स में, जिनमें से किसी को भी एक-दूसरे के बारे में पता नहीं था. हर एक के पास राउटर के सामने एक गेट था: वैध कमांड नामों की एक हाथ से रखी गई सूची, या एक स्टार्टअप चरण जो किसी भी चीज़ के चलने से पहले क्रेडेंशियल मांगता था. हर मामले में नया manifest कमांड — वह जो टूल की पूरी सतह को एक ही कॉल में वर्णित करता है, ताकि एक एजेंट इसे स्रोत पढ़े बिना सीख सके — ने "अज्ञात कमांड" या "टोकन गायब" के साथ उत्तर दिया।
उनमें से एक ने अपनी कमांड सूची की दूसरी प्रति और एक हाथ से लिखी मदद स्क्रीन रखी, दोनों ही टूल के वास्तविक कार्य से भटक गई थीं. दोनों को हटाने से उसकी सूट 52 पास से 3 फेल से 57 पास में बदल गई 0. सेट में सबसे बड़ा टूल 364 परीक्षण रखता है, और वे उन्नयन से पहले और बाद में बिना किसी स्रोत परिवर्तन के पास हो गए.
यह पैटर्न इतना अच्छा सामान्यीकृत हुआ कि यह एक लिखित प्रक्रिया बन गया, जिसे पैकेज के भीतर ही शिप किया गया. यह 9 चरण हैं, और 2 चरण जो समय लेते हैं, वे 2 हैं जिन्हें कोई भी अनुमान नहीं लगाता.
शून्य निर्भरताएँ वह एकमात्र संख्या है जिसे मॉनिटरिंग की आवश्यकता नहीं है#
बेस में 2 रनटाइम निर्भरताएँ थीं. अब इसमें कोई नहीं है.
वह आंशिक रूप से सौंदर्यात्मक और अधिकांशतः अंकगणितीय था. 8 सितंबर 2025 को, एक अटैकर ने जॉश जूनन के npm खाते को फ़िश किया, जो JavaScript में सबसे अधिक निर्भर पैकेजों के मेंटेनर हैं, एक नकली डोमेन और एक लाइव वन-टाइम कोड का उपयोग करके। 18 पैकेजों को दुर्भावनापूर्ण संस्करणों के साथ प्रकाशित किया गया, जिसमें chalk और debug शामिल हैं — पैकेजों ने मिलकर लगभग 2.6 बिलियन डाउनलोड प्रति सप्ताह का भार उठाया। पेलोड एक क्रिप्टो-क्लिपर था. मेंटेनर्स ने इसे पकड़ लिया और लगभग 2 घंटों में वापस कर दिया, और समझौता किए गए संस्करण अभी भी उस विंडो में लगभग 2.6 मिलियन बार डाउनलोड किए गए थे.
चॉक उन 3 लाइब्रेरीज़ में से एक है जिन्हें मॉडल्स ने तब तक बार-बार चुना जब मैंने उनसे एक CLI मांगा।
बेस प्रभावित नहीं हुआ — उसने कभी चॉक पर निर्भर नहीं किया — और मैं इसे नाटकीय बनाने के बजाय सटीक होना चाहता हूँ, क्योंकि यह घटना के बाद 2 महीनों में बनाया गया था. प्रासंगिकता यह नहीं है कि हमने कुछ टाला. यह है कि घटना जोखिम के वर्ग का सटीक वर्णन करती है: हर निर्भरता किसी और के रिलीज़ निर्णयों का एक दशक है, और आप एक खाते पर भरोसा कर रहे हैं जिसे आप नियंत्रित नहीं करते. वह रंग हैंडलिंग जो एक निर्भरता को बदलती है, लगभग 60 लाइनों के बारे में है. वह प्रॉम्प्टिंग जो दूसरी को बदलती है, लगभग 120. शून्य वह एकमात्र संख्या है जिसे मॉनिटरिंग की आवश्यकता नहीं है.
शिप की गई संस्करण 85 KB है, अनमिनिफाइड, बिना रनटाइम निर्भरताओं के, Node, Bun और Deno पर चल रही है। उस पर निर्मित हर कमांड को, बिना प्रति-आदेश कोड के, मिलता है:
गारंटी
इसका व्यावहारिक अर्थ क्या है
ईमानदार एग्जिट कोड्स
एक त्रुटि जिसे मानव को रिपोर्ट किया जाता है, शेल को रिपोर्ट की जाती है
--json और --ndjson
वह मान जो आपका कमांड लौटाता है, एक ऐसी आकृति में जिसे मशीन पार्स कर सकती है
manifest
पूरा उपकरण 1 निर्धारक कॉल में वर्णित है, कुछ भी लोड नहीं करता
स्ट्रीम अनुशासन
stdout पेलोड है; हर लॉग लाइन stderr पर है
उपयोग त्रुटियाँ
"आपने मुझे गलत बुलाया" के लिए एग्जिट 2, "मैंने कोशिश की और विफल रहा" के लिए 1 से अलग
प्रॉम्प्ट सुरक्षा
बिना टर्मिनल वाला प्रॉम्प्ट मिलीसेकंड में विफल हो जाता है बजाय हमेशा के लिए लटकने के
रद्दीकरण
Ctrl-C कमांड के सिग्नल को रोकता है, फिर 130 से बाहर निकलता है
वह चीज़ जिस पर मैं बार-बार लौटता हूँ, वह उस सूची पर कोई एकल आइटम नहीं है. यह है कि सूची अब checkable है. README का अपना उदाहरण प्रकाशित tarball के खिलाफ एक परीक्षण के रूप में चलता है, और उसके प्रोस में उद्धृत संख्याएँ उन संख्याओं से मेल खाती हैं जो सूट उत्पन्न करती है — एक नियम जिसने उसके पहले त्रुटि को लिखे जाने के एक मिनट के भीतर पकड़ लिया, जहाँ पृष्ठ ने 87 KB कहा और कलाकृति 85 थी.
चार साल पहले समस्या यह थी कि हर मॉडल का CLI के बारे में अलग मत था। उत्तर कभी भी मतों पर बहस करना नहीं था. यह था कि वे सभी जिस आधार पर बनाते हैं, उसे अपने पास रखें, और वादों को कहीं लिखें जहाँ बिल विफल हो सकता है.