wayBetter Store

(FOSS) プルリクエストが、そのまま申請

自分の作品を 公開しよう。

テーマはJSONファイル1つ。プラグインはJavaScriptファイル1つ。作って、アプリで試して、ストアに追加しましょう。プルリクエスト1つにフォルダー1つ、gitを使わないならイシューにファイルを添付。どちらも無料のgit.crt.fyiアカウントだけで足ります。

1

作る

動くファイルから始めましょう。スキャフォールダーが1つ書き出します。アプリ内の「作成」セクション(wayBetter → 作成)には、サンプルと現在のテーマの値があります。

テーマ

色、フォント、角、密度、レイアウト、背景、エフェクト。3色あれば十分で、残りは自動で導かれ、文字は読みやすく保たれます。

アプリ内で作ることもできます: 外観 → テーマビルダー → エクスポート。テーマで設定できる項目はTHEMES.mdにすべて載っています。

プラグイン

start()とstop()を持つクラスと、誰が作り何を使うかを示すヘッダー。

TypeScriptプロジェクトなら--tsを付けます。API、権限、ライブリロードはPLUGINS.mdにあります。

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上のrawファイルを指すwaybetter://installリンクを送ります。インストール画面を経ずにインストールされることはありません。
3

フォルダーを1つ追加

ストアのアイテムはすべて、リポジトリの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
テーマのみ(プラグインのバージョンはヘッダーにあります)。ファイルを変更したら上げてください。
説明
何をするものかを1〜2文、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、説明、そしてnetworkかnetwork:noneを明記した@permissions行
  • 正直な権限コードがfetch、XMLHttpRequest、WebSocket、EventSource、sendBeaconを呼ぶ場合、network:noneは拒否されます。制限付きAPIの呼び出しは宣言が必要です
  • リモートコードなしeval、new Function、import()は不可。プレビューにスクリプトや外部ファイルは不可。テーマのCSSに@importや外部URLは不可
  • カタログアイテムから、アプリが受け付けるカタログがビルドできること(フレームワーク自身のルール)。公開済みカタログが署名とハッシュに一致し続けること
  • 検索と共有ページタイトルは60文字まで、説明は50〜160文字、どちらも重複なし
5

送る

参加の方法は 2 つ。どちらも無料の git.crt.fyi アカウントが必要です。誰でも登録でき、新しいアカウントはメンテナーが一つずつ手作業で承認します。

プルリクエスト

  1. git.crt.fyiでリポジトリをフォークします。
  2. ブランチにフォルダーを追加し、チェックを実行します。
  3. プルリクエストを開きます。テンプレートが、何をするものか、何を使うかを尋ねます。

gitを使わない?イシューを開く

  1. テーマまたはプラグインのテンプレートを選びます。
  2. ファイルを添付します(プレビューがあればそれも)。
  3. メンテナーが代わりにフォルダーを追加します。

そのあと、メンテナーが署名

ストアの署名鍵は意図的にオフラインで保管しているため、マージしただけでは公開されません。マージ後、メンテナーがコードを読み、鍵のあるマシンでwaybetter store buildとwaybetter store signを実行してプッシュします。サイトが再ビルドされ、あなたのアイテムのページができ、どのアプリも次に署名付きカタログを読んだときにそれを表示します。

署名付きカタログに入っているものはすべてその鍵が保証します。だからこそ、どのプラグインも署名の前に人が読みます。

{ }

カタログの形式

すべてのwayBetterアプリで共通のファイルが1つ。手で編集することはなく、フォルダーからビルドされます。

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を超えるファイルがあると、カタログ全体が拒否されます。JSON Schemaはstore-catalog.schema.json、すべてのルールはフレームワークのSTORE.mdにあります。
  • 共有。 各アイテムは自分のappsを明記します。アプリはファイル全体を検証し、自分のアイテムだけを残します。
Aa

言語

ストアのアイテムではありません。51言語すべてがアプリに組み込まれ、必要なときに読み込まれます。

  • apps/desktop/locales/<tag>.jsonで翻訳を直す、または仕上げる。プルリクエストか、変更したファイルを添付したイシューで。
  • bun run i18n:checkでチェック: キー、プレースホルダー、複数形、マークアップなし。0 error(s)と表示される必要があります。
  • 次のアプリのアップデートで届きます。ストア経由ではありません。メッセージの構文と、自分の訳をアプリで確認する方法はTRANSLATING.mdにあります。

すでにあるものを見てみよう。

ストアのアイテムはすべてコードを公開しています。同梱プラグインは、APIの上手な使い方のいちばんの手本です。