
कोड डिफ़्स को संदर्भ के साथ स्कैन करके एक प्रभाव ग्राफ़ बनाता है और कमज़ोरियों का पता लगाने के लिए LLM का उपयोग करता है, जो मल्टी-रेपो स्कैन और SARIF आउटपुट के साथ CI गेटिंग का समर्थन करता है।
Diff सुरक्षा स्कैनर परिवर्तनों के प्रभावों को अनदेखा कर देते हैं, Zairo उन प्रभावों को ढूंढता है और कमजोरियों की तलाश करता है। Zairo आपके कोड में हुए परिवर्तनों को संदर्भ के साथ स्कैन करता है, आपके देखने के लिए एक सबग्राफ बनाता है और आपकी पसंद के LLMs का उपयोग करके कमजोरियों का पता लगाता है।

pipx install zairo
# जो कुछ भी आपने अभी तक commit नहीं किया है उसे स्कैन करें
zairo .
# किसी PR/ब्रांच diff को स्कैन करें
zairo . --base main --target HEAD
# यदि कोई उच्च-गंभीरता वाली चीज़ सामने आती है तो build को विफल करें
zairo . --base main --target HEAD --fail-on high
इसे एक से अधिक रिपॉजिटरी दें, अतिरिक्त तर्कों के रूप में या --repos-file में प्रति पंक्ति एक (या दोनों, एक सूची में विलय करके), और यह अपने आप मल्टी-रेपो मोड में स्विच हो जाता है: हर रिपॉजिटरी को अपनी अलग रिपोर्ट मिलती है, साथ ही एक संयुक्त सारांश भी।
zairo backend frontend infra --base main --fail-on high -o zairo_multi_out
--base/--target (और हर अन्य विकल्प) सूची में हर रिपॉजिटरी पर उसी तरह लागू होते हैं, इसलिए मल्टी-रेपो मोड सबसे अच्छा तब काम करता है जब वे सभी एक ही चीज़ के विरुद्ध diff करते हैं (जैसे सभी का main)। अलग-अलग परंपराओं वाली रिपॉजिटरीज़ को अलग-अलग रन की आवश्यकता होती है।
क्या स्कैन करना है
--base, -b (कोई नहीं): वह ref जिससे diff करना है, जैसे main या HEAD~3। छोड़ देने पर, zairo असंबद्ध (uncommitted) परिवर्तनों को स्कैन करता है।--target, -t (कोई नहीं): वह ref जिस तक diff करना है। --base की आवश्यकता है; छोड़ देने पर (--base सेट होने पर), यह आपके working tree के विरुद्ध diff करता है।--depth, -d (1): प्रत्येक परिवर्तन के आसपास impact graph में कितने hops के callers/callees को खींचना है।--language, -l (auto): Trailmark को स्वतः पहचानने देने के बजाय किसी भाषा को बलपूर्वक निर्धारित करें।LLM स्कैनिंग
--graph-only (बंद): कमजोरी स्कैन को छोड़ें और केवल impact graph बनाएं -- कोई findings नहीं, कोई report.sarif नहीं।--model (gemini/gemini-2.5-pro): कोई भी LiteLLM model string।--concurrency, -c (5): एक रिपॉजिटरी के स्कैन के भीतर समानांतर LLM अनुरोध।--batch-size (1): इस संख्या में नोड्स को एक ही LLM अनुरोध में समूहित करें, प्रति नोड एक कॉल के बजाय -- कम अनुरोध (provider rate limits में मदद करता है), लेकिन साझा fault isolation की कीमत पर: एक खराब/गलत प्रारूप वाला प्रतिक्रिया उस batch के हर नोड को विफल कर देता है, सिर्फ एक को नहीं। Caching किसी भी तरह प्रति-नोड बनी रहती है।--max-tokens (4096): प्रति अनुरोध आउटपुट बजट। Reasoning मॉडल इसे आंतरिक सोच पर भी खर्च करते हैं, इसलिए यदि आप खाली प्रतिक्रियाएँ देखते हैं तो इसे बढ़ाएँ।--cache / --no-cache (cache चालू): उस कोड को फिर से स्कैन करना छोड़ें जो पिछले रन के बाद से अपरिवर्तित है (<output>/.llm_cache.json में content hash द्वारा cached)।--tokens (बंद): प्रिंट करें कि स्कैन ने वास्तव में कितने tokens उपयोग किए (cache hits गिनती नहीं करते, क्योंकि उन्होंने कोई कॉल नहीं की)।आउटपुट और गेटिंग
--output, -o (zairo_out): रिपोर्ट कहाँ जाती हैं। मल्टी-रेपो मोड: हर रिपॉजिटरी को अपना <output>/<repo-slug>/ मिलता है, साथ ही यहाँ एक संयुक्त rollup.* भी।--fail-on (कोई नहीं): यदि इस या उससे ऊपर की गंभीरता वाली कोई finding सामने आती है तो गैर-शून्य exit code दें (low/medium/high/critical)। --graph-only के साथ संयुक्त होने पर त्रुटि देता है (गेट करने के लिए कुछ नहीं होगा)। मल्टी-रेपो मोड: सभी रिपॉजिटरीज़ को मिलाकर जाँच की जाती है। देखें CI / PR गेटिंग।--verbose, -v (बंद): चरण दर चरण क्या हो रहा है प्रिंट करें (git कमांड, worktree सेटअप, प्रति-नोड स्कैन प्रगति)।--debug, -vv (बंद): वह सब कुछ जो --verbose प्रिंट करता है, साथ ही LLM को भेजा गया सटीक prompt और हर नोड के लिए उसका कच्चा प्रतिक्रिया -- <output>/debug.log में लिखा जाता है (मल्टी-रेपो मोड में प्रति-रेपो), क्योंकि कंसोल पर प्रिंट करने के लिए यह बहुत अधिक है।केवल मल्टी-रेपो मोड
--repos-file (कोई नहीं): प्रति पंक्ति एक रिपॉजिटरी पथ (# टिप्पणियाँ अनुमत), सीधे दिए गए किसी भी रिपॉजिटरी के साथ विलय।--repo-concurrency (1): एक साथ कितनी रिपॉजिटरीज़ को स्कैन करना है। कुल in-flight LLM अनुरोध --concurrency × --repo-concurrency तक पहुँच सकते हैं, इसलिए अपने provider की rate limits का ध्यान रखें। 1 से ऊपर, प्रगति पूरा होने पर प्रति रिपॉजिटरी एक सारांश पंक्ति प्रिंट करती है, लाइव चरण-दर-चरण विवरण के बजाय।--continue-on-error / --stop-on-error (continue): जब एक रिपॉजिटरी विफल हो जाती है तो सूची के बाकी हिस्से को स्कैन करना जारी रखें, या रोक दें। किसी भी तरह, कोई भी विफल रिपॉजिटरी समग्र exit code को विफल कर देती है।इसी सूची के लिए CLI से किसी भी समय zairo --help चलाएँ।
report.json (हमेशा): कच्चा impact graph (nodes, edges, और कोई भी संलग्न findings), डेटा के रूप में।report.html (हमेशा): एक स्व-निहित, इंटरैक्टिव dependency-graph व्यूअर (Cytoscape.js)। इसकी findings देखने के लिए किसी नोड पर क्लिक करें।report.sarif (जब तक --graph-only उपयोग न किया जाए): findings SARIF 2.1.0 में, GitHub code scanning या किसी अन्य SARIF उपभोक्ता के लिए। हमेशा लिखा जाता है, यहाँ तक कि एक स्वच्छ स्कैन के लिए भी (एक खाली-लेकिन-मान्य लॉग), ताकि एक स्कैनिंग UI पहले से रिपोर्ट किए गए अलर्ट को हल किए हुए चिह्नित कर सके। Findings को मॉडल द्वारा टैग किए जाने पर CWE द्वारा rules में समूहित किया जाता है, ताकि एक ही तरह की बार-बार आने वाली समस्याएँ प्रति शब्दांकन भिन्नता एक नए rule के बजाय एक rule में समाहित हो जाएँ।मल्टी-रेपो मोड प्रति रिपॉजिटरी समान तीन फ़ाइलें बनाता है, साथ ही rollup.json / rollup.html / rollup.sarif: प्रति-रेपो स्थिति और गंभीरता गणना, एक डैशबोर्ड तालिका जो प्रत्येक रिपॉजिटरी की रिपोर्ट से जुड़ती है, और हर रिपॉजिटरी के SARIF परिणाम एक बहु-रन लॉग में विलय।
एक फ़ंक्शन/क्लास/मॉड्यूल जो पूरी तरह से हटा दिया गया है (सिर्फ संपादित नहीं), फिर भी report.html में दिखाई देता है, स्थिति deleted के साथ: एक धराशायी, फीका नोड जो चिह्नित करता है कि यह पहले कहाँ रहता था। Trailmark का ग्राफ इसे अपने आप प्रस्तुत नहीं कर सकता (यह केवल उस पेड़ को दर्शाता है जो अभी मौजूद है), इसलिए zairo विलोपन का अलग से पता लगाता है: यह बदली हुई फ़ाइलों को उस रूप में भी पार्स करता है जैसे वे --base पर मौजूद थीं (या HEAD, यदि --base नहीं दिया गया था) और दोनों प्रतीक सेटों का diff करता है। एक हटाया गया फ़ंक्शन कभी भी LLM स्कैनर को नहीं भेजा जाता (स्कैन करने के लिए कोई लाइव कोड नहीं बचा है), इसलिए यह केवल अपना नाम, प्रकार और पूर्व स्थान रखता है, कभी findings नहीं।
--fail-on <low|medium|high|critical> गैर-शून्य exit code देता है यदि उस या उससे ऊपर की गंभीरता वाली कोई finding मिलती है (मल्टी-रेपो मोड में सभी रिपॉजिटरीज़ को मिलाकर), ताकि एक CI चरण उस पर merge को रोक सके। कुछ बातें जानने योग्य हैं:
--graph-only के साथ संयुक्त होने पर त्रुटि देता है (गेट करने के लिए कुछ नहीं होगा)।zairo . --base "$BASE_REF" --target HEAD --fail-on high -o zairo_out
पूर्ण PR-स्कैन वर्कफ़्लो के लिए examples/github-actions/zairo-pr-scan.yml देखें: यह PR diff पर zairo चलाता है, report.sarif को GitHub के code scanning पर अपलोड करता है, और यदि गेट विफल होता है तो job को विफल कर देता है।