テーマ
色、フォント、角、密度、レイアウト、背景、エフェクト。3色あれば十分で、残りは自動で導かれ、文字は読みやすく保たれます。
アプリ内で作ることもできます: 外観 → テーマビルダー → エクスポート。テーマで設定できる項目はTHEMES.mdにすべて載っています。
(FOSS) プルリクエストが、そのまま申請
テーマはJSONファイル1つ。プラグインはJavaScriptファイル1つ。作って、アプリで試して、ストアに追加しましょう。プルリクエスト1つにフォルダー1つ、gitを使わないならイシューにファイルを添付。どちらも無料のgit.crt.fyiアカウントだけで足ります。
動くファイルから始めましょう。スキャフォールダーが1つ書き出します。アプリ内の「作成」セクション(wayBetter → 作成)には、サンプルと現在のテーマの値があります。
色、フォント、角、密度、レイアウト、背景、エフェクト。3色あれば十分で、残りは自動で導かれ、文字は読みやすく保たれます。
アプリ内で作ることもできます: 外観 → テーマビルダー → エクスポート。テーマで設定できる項目はTHEMES.mdにすべて載っています。
start()とstop()を持つクラスと、誰が作り何を使うかを示すヘッダー。
TypeScriptプロジェクトなら--tsを付けます。API、権限、ライブリロードはPLUGINS.mdにあります。
/**
* @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から読み取ります。インストール画面にも同じ値が表示されるので、両者が食い違うことはありません。
ストアは必須ではありません。動くファイルは、それだけで共有できます。
custom.cssが、すべてのタブで同時に再読み込みされます。waybetter://installリンクを送ります。インストール画面を経ずにインストールされることはありません。ストアのアイテムはすべて、リポジトリのstore/<app>/以下のフォルダーです。フォルダー名がアイテムのIDになり、ここでのアドレスにもなります: /store/plugins/<id>/。
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
categoryreading、writing、filters、focus、toolsのいずれか。テーマ: darkまたはlight。省略するとテーマのmodeから決まります。tagsversion申請はこれで全部です。ページ、カード、検索エントリ、リンクプレビュー、構造化データ、サイトマップのエントリは、サイトのビルド時に署名付きカタログから生成されます。詳しいルールはstore/README.mdにあります。
ホストされた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
a-z 0-9 -、40文字まで)、name.plugin.js、同じアプリ内で重複なし@name、@version、説明、そしてnetworkかnetwork:noneを明記した@permissions行fetch、XMLHttpRequest、WebSocket、EventSource、sendBeaconを呼ぶ場合、network:noneは拒否されます。制限付きAPIの呼び出しは宣言が必要ですeval、new Function、import()は不可。プレビューにスクリプトや外部ファイルは不可。テーマのCSSに@importや外部URLは不可参加の方法は 2 つ。どちらも無料の git.crt.fyi アカウントが必要です。誰でも登録でき、新しいアカウントはメンテナーが一つずつ手作業で承認します。
ストアの署名鍵は意図的にオフラインで保管しているため、マージしただけでは公開されません。マージ後、メンテナーがコードを読み、鍵のあるマシンでwaybetter store buildとwaybetter store signを実行してプッシュします。サイトが再ビルドされ、あなたのアイテムのページができ、どのアプリも次に署名付きカタログを読んだときにそれを表示します。
署名付きカタログに入っているものはすべてその鍵が保証します。だからこそ、どのプラグインも署名の前に人が読みます。
すべてのwayBetterアプリで共通のファイルが1つ。手で編集することはなく、フォルダーからビルドされます。
{ "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"] }
] }
appsを明記します。アプリはファイル全体を検証し、自分のアイテムだけを残します。ストアのアイテムではありません。51言語すべてがアプリに組み込まれ、必要なときに読み込まれます。
apps/desktop/locales/<tag>.jsonで翻訳を直す、または仕上げる。プルリクエストか、変更したファイルを添付したイシューで。bun run i18n:checkでチェック: キー、プレースホルダー、複数形、マークアップなし。0 error(s)と表示される必要があります。