wayBetter Store

(FOSS) पुल रिक्वेस्ट ही सबमिशन है

प्रकाशित कीजिए अपनी रचना।

थीम एक JSON फ़ाइल है। प्लगइन एक JavaScript फ़ाइल है। इसे बनाइए, ऐप में आज़माइए, फिर स्टोर में जोड़िए: एक पुल रिक्वेस्ट में एक फ़ोल्डर, या अगर आप git इस्तेमाल नहीं करते तो किसी इशू में फ़ाइल। दोनों के लिए एक मुफ़्त git.crt.fyi अकाउंट चाहिए, और कुछ नहीं।

1

इसे बनाइए

एक चलती हुई फ़ाइल से शुरू कीजिए। स्कैफ़ोल्डर एक फ़ाइल लिख देता है; ऐप के अपने बनाएँ सेक्शन (wayBetter → बनाएँ) में उदाहरण और थीम के लाइव मान हैं।

एक थीम

रंग, फ़ॉन्ट, कोने, घनत्व, लेआउट, पृष्ठभूमि, इफ़ेक्ट। तीन रंग काफ़ी हैं; बाकी निकाल लिए जाते हैं और टेक्स्ट पढ़ने लायक रखा जाता है।

या इसे ऐप में बनाइए: दिखावट → थीम बिल्डर → एक्सपोर्ट करें। THEMES.md में वह सब कुछ है जो थीम सेट कर सकती है।

एक प्लगइन

start() और stop() वाली एक क्लास, और एक हेडर जो बताता है कि इसे किसने बनाया और यह क्या इस्तेमाल करता है।

TypeScript प्रोजेक्ट के लिए --ts जोड़िए। PLUGINS.md में API, अनुमतियाँ और लाइव रीलोड हैं।

hide-trends.plugin.js
/**
 * @name Hide Trends
 * @description Hides the trends box in the right column, so the timeline is the only thing moving.
 * @version 1.0.0
 * @author you
 * @permissions network:none
 */
module.exports = class HideTrends {
  start() { wayBetter.api.injectCSS('hide-trends', '[data-testid="sidebarColumn"] section { display: none }'); }
  stop()  { wayBetter.api.clearCSS('hide-trends'); }
};

स्टोर प्लगइन का नाम, लेखक, संस्करण, विवरण और अनुमतियाँ इसी हेडर से पढ़ता है, और थीम का नाम, लेखक और विवरण उसके JSON से। इंस्टॉल स्क्रीन भी वही मान दिखाती है, इसलिए दोनों में कभी अंतर नहीं हो सकता।

2

इसे आज़माइए

स्टोर वैकल्पिक है। जो फ़ाइल चलती है, वह पहले से शेयर करने लायक है।

  • फ़ाइल को wayBetter विंडो पर छोड़िए। आपको वही इंस्टॉल स्क्रीन मिलती है जो स्टोर के आइटम को मिलती है: नाम, लेखक, संस्करण, SHA-256, अनुमतियाँ, कोड।
  • काम करते समय डेवलपर मोड चालू कीजिए (सेटिंग → डेवलपर): सेव किया हुआ प्लगइन, थीम फ़ाइल या custom.css हर टैब में एक साथ रीलोड हो जाता है।
  • इसे स्टोर के बिना शेयर कीजिए। फ़ाइल भेजिए, या waybetter.fyi, cdn1.crt.fyi पर किसी https URL या git.crt.fyi की किसी रॉ फ़ाइल का waybetter://install लिंक। यह इंस्टॉल स्क्रीन के बिना कभी इंस्टॉल नहीं होता।
3

एक फ़ोल्डर जोड़िए

स्टोर का हर आइटम रिपॉज़िटरी में store/<app>/ के अंदर एक फ़ोल्डर है। फ़ोल्डर का नाम ही आइटम की id और यहाँ उसका पता है: /store/plugins/<id>/।

store/x/ — wayBetter for X के आइटम
store/x/plugins/hide-trends/
  hide-trends.plugin.js   the plugin, exactly as it installs
  item.json               { "category": "focus", "tags": ["trends", "sidebar"] }
  preview.svg             optional, 640×400 (.svg or .png); drawn for you without one

store/x/themes/midnight-mint/
  theme.json              the theme, as Appearance → Export writes it
  item.json               { "version": "1.0.0" }
  preview.svg             optional; drawn from the theme without one
category
प्लगइन: reading, writing, filters, focus या tools। थीम: dark या light, जो छोड़ देने पर थीम के mode से लिया जाता है।
tags
ज़्यादा से ज़्यादा 12 शब्द, जिन्हें लोग खोजेंगे।
version
सिर्फ़ थीम के लिए (प्लगइन का उसके हेडर में होता है)। फ़ाइल बदलने पर इसे बढ़ाइए।
विवरण
एक या दो वाक्य जो बताएँ कि यह क्या करता है, कम से कम 50 अक्षर। पहले 160 अक्षर इसके पेज का सर्च इंजन विवरण बनते हैं।

पूरा सबमिशन बस इतना ही है। पेज, कार्ड, खोज की प्रविष्टि, लिंक प्रीव्यू, स्ट्रक्चर्ड डेटा और साइटमैप की प्रविष्टि साइट बिल्ड होते समय हस्ताक्षरित कैटलॉग से बनते हैं। पूरे नियम store/README.md में हैं।

4

जाँचें चलाइए

कोई होस्टेड CI नहीं है। जाँचें वे कमांड हैं जिन्हें आप भेजने से पहले चलाते हैं, और मर्ज करने से पहले एक मेंटेनर दोबारा चलाता है।

अपने क्लोन में
git submodule update --init
bun install --frozen-lockfile
bun run check:store      # your folder, against the Store's rules
bun run test             # everything else, including the site's SEO test
  • Id और नामफ़ोल्डर id (a-z 0-9 -, 40 तक), name.plugin.js, एक ऐप में कोई डुप्लिकेट नहीं
  • आकारआइटम फ़ाइलें 2 MiB तक, प्रीव्यू 16:10 में 300 KB तक
  • हेडर@name, @version, एक विवरण, और एक @permissions पंक्ति जिसमें network या network:none लिखा हो
  • ईमानदार अनुमतियाँजब कोड fetch, XMLHttpRequest, WebSocket, EventSource या sendBeacon कॉल करता है तो network:none अस्वीकार कर दिया जाता है; नियंत्रित API कॉल घोषित करने ही होंगे
  • कोई रिमोट कोड नहींकोई eval, new Function या import() नहीं; प्रीव्यू में कोई स्क्रिप्ट या बाहरी फ़ाइल नहीं; थीम के CSS में कोई @import या बाहरी URL नहीं
  • कैटलॉगआइटम से ऐसा कैटलॉग बनता है जिसे ऐप स्वीकार करते हैं (फ़्रेमवर्क के अपने नियम), और प्रकाशित कैटलॉग अब भी अपने हस्ताक्षर और हैश से मेल खाता है
  • खोज और शेयरिंगपेज का शीर्षक 60 अक्षर तक, विवरण 50 से 160, दोनों अनोखे
5

इसे भेजिए

जुड़ने के दो रास्ते. दोनों के लिए मुफ़्त git.crt.fyi खाता चाहिए: कोई भी साइन अप कर सकता है, और एक मेंटेनर हर नया खाता हाथ से मंज़ूर करता है.

पुल रिक्वेस्ट

  1. git.crt.fyi पर रिपॉज़िटरी को फ़ोर्क कीजिए।
  2. किसी ब्रांच पर अपना फ़ोल्डर जोड़िए और जाँचें चलाइए।
  3. पुल रिक्वेस्ट खोलिए। टेम्पलेट पूछता है कि यह क्या करता है और क्या इस्तेमाल करता है।

git नहीं है? एक इशू खोलिए

  1. थीम या प्लगइन वाला टेम्पलेट चुनिए।
  2. फ़ाइल अटैच कीजिए (और प्रीव्यू भी, अगर आपके पास हो)।
  3. एक मेंटेनर आपके लिए फ़ोल्डर जोड़ देता है।

फिर एक मेंटेनर हस्ताक्षर करता है

स्टोर की हस्ताक्षर कुंजी जान-बूझकर ऑफ़लाइन रखी गई है, इसलिए मर्ज करना प्रकाशित करना नहीं है। मर्ज के बाद एक मेंटेनर कोड पढ़ता है, जिस मशीन पर कुंजी है उस पर waybetter store build और waybetter store sign चलाता है, और पुश करता है। साइट दोबारा बिल्ड होती है, आपके आइटम को उसका पेज मिलता है, और हर ऐप अगली बार हस्ताक्षरित कैटलॉग पढ़ते ही उसे देख लेता है।

हस्ताक्षरित कैटलॉग की हर चीज़ की ज़िम्मेदारी वही कुंजी लेती है, इसीलिए हस्ताक्षर से पहले हर प्लगइन को एक इंसान पढ़ता है।

{ }

कैटलॉग का फ़ॉर्मैट

हर wayBetter ऐप के लिए एक ही फ़ाइल। आप इसे कभी हाथ से नहीं बदलते: यह फ़ोल्डरों से बनती है।

catalog.json (फ़ॉर्मैट 2)खुला
{ "format": 2, "name": "wayBetter Store", "generatedAt": "2026-09-30T…Z", "items": [
  { "apps": ["x"], "kind": "plugin", "id": "thread-reader", "name": "Thread Reader",
    "author": "wayBetter", "version": "1.2.0", "description": "…",
    "category": "reading", "tags": ["threads"],
    "url": "https://waybetter.fyi/store/plugins/bt-thread-reader.plugin.js",
    "file": "bt-thread-reader.plugin.js", "sha256": "<64 hex>", "size": 10961,
    "preview": "https://waybetter.fyi/store/previews/plugin-thread-reader.svg",
    "permissions": ["ui", "clipboard", "commands", "network:none"] }
] }
  • हस्ताक्षरित। catalog.json.sig, catalog.json के ठीक-ठीक बाइट पर किया गया Ed25519 हस्ताक्षर है। ऐप इसे अपने अंदर कंपाइल की गई सार्वजनिक कुंजी से सत्यापित करते हैं, फिर हर डाउनलोड का आकार और SHA-256 जाँचते हैं।
  • सख़्त। अनजान फ़ील्ड, 500 से ज़्यादा आइटम या 1 MiB से बड़ी फ़ाइल होने पर पूरा कैटलॉग अस्वीकार हो जाता है। store-catalog.schema.json इसका JSON Schema है; फ़्रेमवर्क के STORE.md में हर नियम है।
  • साझा। हर आइटम अपना apps बताता है। ऐप पूरी फ़ाइल सत्यापित करता है और सिर्फ़ अपने आइटम रखता है।
Aa

भाषाएँ

ये स्टोर के आइटम नहीं हैं: सभी 51 भाषाएँ ऐप में ही शामिल हैं और ज़रूरत पड़ने पर लोड होती हैं।

  • apps/desktop/locales/<tag>.json में कोई अनुवाद ठीक या पूरा कीजिए, पुल रिक्वेस्ट से या बदली हुई फ़ाइल अटैच करके किसी इशू से।
  • bun run i18n:check से इसे जाँचिए: कुंजियाँ, प्लेसहोल्डर, बहुवचन रूप, कोई मार्कअप नहीं। इसे 0 error(s) प्रिंट करना चाहिए।
  • यह ऐप के अगले अपडेट के साथ आता है, स्टोर के ज़रिए नहीं। TRANSLATING.md में संदेशों का सिंटैक्स और ऐप में अपने शब्द देखने का तरीका है।

देखिए कि पहले से क्या मौजूद है।

स्टोर का हर आइटम अपना कोड दिखाता है। साथ आने वाले प्लगइन इस बात के सबसे अच्छे उदाहरण हैं कि API का अच्छा इस्तेमाल कैसे हो।