diff --git a/public/registry/index.json b/public/registry/index.json index a0081f1..3247e6a 100644 --- a/public/registry/index.json +++ b/public/registry/index.json @@ -1,24 +1,24 @@ { "version": 1, - "updatedAt": "2026-11-04T00:27:05.105Z", + "updatedAt": "2026-11-04T11:57:10.395Z", "plugins": { "count": 44, - "updatedAt": "2026-11-04T00:27:05.105Z" + "updatedAt": "2026-11-04T11:57:10.395Z" }, "themes": { "count": 77, - "updatedAt": "2026-11-04T00:27:05.105Z" + "updatedAt": "2026-11-04T11:57:10.395Z" }, "widgets": { "count": 70, - "updatedAt": "2026-11-04T00:27:05.105Z" + "updatedAt": "2026-11-04T11:57:10.395Z" }, "skills": { "count": 44, - "updatedAt": "2026-11-04T00:27:05.105Z" + "updatedAt": "2026-11-04T11:57:10.395Z" }, "queries": { "count": 35, - "updatedAt": "2026-11-04T00:27:05.105Z" + "updatedAt": "2026-11-04T11:57:10.395Z" } } diff --git a/public/registry/plugins.json b/public/registry/plugins.json index dd67187..13fdf9e 100644 --- a/public/registry/plugins.json +++ b/public/registry/plugins.json @@ -1,6 +1,6 @@ { "version": 1, - "updatedAt": "2026-11-04T00:27:05.105Z", + "updatedAt": "2026-11-04T11:57:10.395Z", "plugins": [ { "id": "ai-actions", @@ -84,7 +84,7 @@ "apiUrl": "https://store.notedeck.io/registry/plugins/etherscan-autolink/api.json", "sha512": "7381f997888a25ed41678eb25ffb6832e5a577d7a7d93d54f93fdcdd8a9a4ab20d62daa414a2f65711430bbba82f60f76416ae64ee317af915970d58fa7894f1", "createdAt": "2026-10-29T04:34:22+09:00", - "updatedAt": "2026-10-29T04:35:41+09:00", + "updatedAt": "2026-11-04T09:27:13+09:00", "authorUrl": "https://github.com/hitalin", "license": "MIT", "locales": { @@ -116,7 +116,7 @@ { "id": "mfm-search-engine", "name": "MFM 検索の検索エンジン変更", - "version": "1.0.0", + "version": "1.0.1", "author": "hitalin", "description": "MFM の検索ブロック (foo 検索) の遷移先を DuckDuckGo などの好きな検索エンジンにする。表示時に検索行をリンクへ書き換えるだけで、投稿そのものは変更しない。プリセット名か https の URL だけを受け付け、リンクに遷移先ホストを表示", "category": "utility", @@ -129,7 +129,7 @@ ], "sourceUrl": "https://store.notedeck.io/registry/plugins/mfm-search-engine/plugin.is", "apiUrl": "https://store.notedeck.io/registry/plugins/mfm-search-engine/api.json", - "sha512": "7d1e5ca3fc6f99c231f6fd4de7cb146c8284dd0210662069fd88a1c4b833f47a6fb9bd2c6f70182f48f68481840984559d955c3be9033855eb5e7f02fbd3f90d", + "sha512": "595eb52a1034bbcdf014258f6cb09033b31dfed342d86ab8f9ef6f39f86839c009a419ede60e6056c4b6124ed899002a212d16eee7974943d4e5599691c60b15", "createdAt": "2026-11-04T09:14:01+09:00", "updatedAt": "2026-11-04T09:14:01+09:00", "authorUrl": "https://github.com/hitalin", @@ -555,7 +555,7 @@ "apiUrl": "https://store.notedeck.io/registry/plugins/web-search/api.json", "sha512": "12dc49a10c1fd871dfaf45ab3b25ff55336cf3ae98659b67e17d41cb893674279ff620e5e189c437b4fa084e9cd7cfa13ff7058676a20398343ba2e1a294fc93", "createdAt": "2026-07-15T06:44:02+09:00", - "updatedAt": "2026-09-25T18:20:03+09:00", + "updatedAt": "2026-11-04T09:27:13+09:00", "authorUrl": "https://github.com/hitalin", "license": "MIT", "locales": { diff --git a/public/registry/plugins/mfm-search-engine/api.json b/public/registry/plugins/mfm-search-engine/api.json index 864cc48..4855ccb 100644 --- a/public/registry/plugins/mfm-search-engine/api.json +++ b/public/registry/plugins/mfm-search-engine/api.json @@ -1 +1 @@ -{"type":"plugin","data":"/// @ 1.2.1\n\n// MFM 検索の検索エンジン変更 — 「foo 検索」の遷移先を好きな検索エンジンにする\n//\n// Misskey Web も NoteDeck も MFM の検索ブロック (「foo 検索」「foo [search]」など)\n// の遷移先は Google 固定で、設定もプラグインのフックも無い。そこで\n// Plugin:register_note_view_interruptor で表示時に検索行だけをサイレントリンク\n// `?[foo 検索 (duckduckgo.com)](https://duckduckgo.com/?q=foo)` に書き換える。\n// 投稿そのものは変更しない (表示専用)。見た目は検索ボックスではなく通常の\n// リンクになる。\n//\n// 遷移先はプリセット名か https:// の URL だけを受け付け、それ以外 (http /\n// javascript / 未知の名前) は書き換えを止めて起動時に警告する。リンクのラベルに\n// 遷移先ホストを出すので、押す前にどこへ飛ぶか分かる。\n//\n// 書き換えない行: コードブロック内、引用 (> で始まる行)、検索語に [ ] を含む行\n// (リンクのラベルが壊れる)。\n//\n// interruptor は同期実行なので、この中では Mk:api / Nd:call / ダイアログを使わない。\n// 本家 Misskey Web にも同じフックがあるので NoteDeck 専用ではない。\n\n### {\n\tname: \"MFM 検索の検索エンジン変更\"\n\tversion: \"1.0.0\"\n\tauthor: \"@hitalin\"\n\tdescription: \"MFM の検索ブロック (foo 検索) の遷移先を DuckDuckGo などの好きな検索エンジンにします。表示時に検索行をリンクへ書き換えるだけで、投稿そのものは変更しません\"\n\tconfig: {\n\t\tengine: {\n\t\t\ttype: \"string\"\n\t\t\tlabel: \"検索エンジン\"\n\t\t\tdescription: \"プリセット名 (duckduckgo / brave / startpage / searx / google / bing) か、https:// で始まる URL。URL は末尾に検索語が付きます。{query} を書くとその位置に入ります\"\n\t\t\tdefault: \"duckduckgo\"\n\t\t}\n\t}\n}\n\nlet PRESETS = {\n\tduckduckgo: \"https://duckduckgo.com/?q={query}\"\n\tbrave: \"https://search.brave.com/search?q={query}\"\n\tstartpage: \"https://www.startpage.com/do/search?q={query}\"\n\tsearx: \"https://search.disroot.org/search?q={query}\"\n\tgoogle: \"https://www.google.com/search?q={query}\"\n\tbing: \"https://www.bing.com/search?q={query}\"\n}\n\n// 設定値を URL テンプレートに。プリセット名でも https URL でもなければ null\n@resolveTemplate(raw) {\n\tlet s = raw.trim()\n\tlet key = s.lower()\n\tif (Obj:has(PRESETS, key)) return Obj:get(PRESETS, key)\n\tif (!s.starts_with(\"https://\")) return null\n\tif (s.index_of(\"{query}\") != -1) return s\n\t[s, \"{query}\"].join(\"\")\n}\n\n// テンプレートのホスト部 (https:// の後から / ? # の手前まで)\n@hostOf(template) {\n\tlet rest = template.slice(8, template.len)\n\tvar end = rest.len\n\teach (let c, [\"/\", \"?\", \"#\"]) {\n\t\tlet i = rest.index_of(c)\n\t\tif (i != -1 && i < end) end = i\n\t}\n\trest.slice(0, end)\n}\n\nlet TEMPLATE = resolveTemplate(Plugin:config.engine)\nlet HOST = if (TEMPLATE != null) hostOf(TEMPLATE) else \"\"\n\nif (TEMPLATE == null) {\n\tMk:dialog(\"warning\", \"MFM 検索の検索エンジン変更: 設定「検索エンジン」はプリセット名 (duckduckgo / brave / startpage / searx / google / bing) か https:// で始まる URL にしてください。それまで検索行は書き換えません\")\n}\n\n// mfm-js の検索ブロック: 行頭から「検索語 + 空白 1 文字 + ボタン」で行末。大小無視\nlet BUTTONS = [\"[検索]\", \"[search]\", \"検索\", \"search\"]\n// AiScript の \"\\n\" はエスケープにならないので制御文字はコードポイントから作る\nlet LF = Str:lf\nlet CRLF = [Str:from_codepoint(13), LF].join(\"\")\nlet SPACES = [\" \", \" \", Str:from_codepoint(9)]\n\n// 行末のボタン部分の長さ。無ければ 0\n@trailingButton(line) {\n\tlet lower = line.lower()\n\teach (let b, BUTTONS) {\n\t\tif (lower.ends_with(b)) return b.len\n\t}\n\t0\n}\n\n// 検索行なら { query, button } を返す。違う行や、リンクにできない行は null。\n// button は行末の「検索」「search」(角括弧は外す。ラベルに入れると壊れる)\n@parseSearchLine(line) {\n\tlet bl = trailingButton(line)\n\tif (bl == 0) return null\n\tlet head = line.slice(0, line.len - bl)\n\tif (head.len < 2) return null\n\tif (!SPACES.incl(head.slice(head.len - 1, head.len))) return null\n\tlet query = head.slice(0, head.len - 1)\n\tif (query.index_of(\"[\") != -1) return null\n\tif (query.index_of(\"]\") != -1) return null\n\tlet button = line.slice(line.len - bl, line.len).replace(\"[\", \"\").replace(\"]\", \"\")\n\t{ query: query, button: button }\n}\n\n@buildUrl(query) {\n\t// encodeURIComponent は ( ) を残すが、リンク構文の括弧と衝突するので潰す\n\tlet q = Uri:encode_component(query).replace(\"(\", \"%28\").replace(\")\", \"%29\")\n\tTEMPLATE.replace(\"{query}\", q)\n}\n\n@rewrite(text) {\n\tlet lines = text.replace(CRLF, LF).split(LF)\n\tvar changed = false\n\tvar inCode = false\n\tvar parts = []\n\teach (let line, lines) {\n\t\tvar line2 = line\n\t\tif (line.starts_with(\"```\")) {\n\t\t\tinCode = !inCode\n\t\t} elif (!inCode && !line.starts_with(\">\")) {\n\t\t\tlet hit = parseSearchLine(line)\n\t\t\tif (hit != null) {\n\t\t\t\tline2 = `?[{hit.query} {hit.button} ({HOST})]({buildUrl(hit.query)})`\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t}\n\t\tparts.push(line2)\n\t}\n\tif (changed) parts.join(LF) else text\n}\n\nPlugin:register_note_view_interruptor(@(note) {\n\tif (TEMPLATE != null) {\n\t\tif (Core:type(note.text) == \"str\") note.text = rewrite(note.text)\n\t\tif (Core:type(note.renote) == \"obj\" && Core:type(note.renote.text) == \"str\") note.renote.text = rewrite(note.renote.text)\n\t}\n\tnote\n})\n"} +{"type":"plugin","data":"/// @ 1.2.1\n\n// MFM 検索の検索エンジン変更 — 「foo 検索」の遷移先を好きな検索エンジンにする\n//\n// Misskey Web も NoteDeck も MFM の検索ブロック (「foo 検索」「foo [search]」など)\n// の遷移先は Google 固定で、設定もプラグインのフックも無い。そこで\n// Plugin:register_note_view_interruptor で表示時に検索行だけをサイレントリンク\n// `?[foo 検索 (duckduckgo.com)](https://duckduckgo.com/?q=foo)` に書き換える。\n// 投稿そのものは変更しない (表示専用)。見た目は検索ボックスではなく通常の\n// リンクになる。\n//\n// 遷移先はプリセット名か https の URL だけを受け付け、それ以外 (http /\n// javascript / 未知の名前) は書き換えを止めて起動時に警告する。スキームの無い\n// 値 (search.example.com/?q=) には https:// を足す (### の文字列に // を書くと\n// NoteDeck 1.103 までのメタデータ解析がコメントとして落とし、設定が丸ごと消える\n// ため、設定の説明にも書かない。notedeck#1340)。リンクのラベルに遷移先ホストを\n// 出すので、押す前にどこへ飛ぶか分かる。\n//\n// 書き換えない行: コードブロック内、引用 (> で始まる行)、検索語に [ ] を含む行\n// (リンクのラベルが壊れる)。\n//\n// interruptor は同期実行なので、この中では Mk:api / Nd:call / ダイアログを使わない。\n// 本家 Misskey Web にも同じフックがあるので NoteDeck 専用ではない。\n\n### {\n\tname: \"MFM 検索の検索エンジン変更\"\n\tversion: \"1.0.1\"\n\tauthor: \"@hitalin\"\n\tdescription: \"MFM の検索ブロック (foo 検索) の遷移先を DuckDuckGo などの好きな検索エンジンにします。表示時に検索行をリンクへ書き換えるだけで、投稿そのものは変更しません\"\n\tconfig: {\n\t\tengine: {\n\t\t\ttype: \"string\"\n\t\t\tlabel: \"検索エンジン\"\n\t\t\tdescription: \"プリセット名 (duckduckgo / brave / startpage / searx / google / bing) か、検索エンジンの URL (例: search.example.com/?q=)。URL は末尾に検索語が付きます。{query} を書くとその位置に入ります\"\n\t\t\tdefault: \"duckduckgo\"\n\t\t}\n\t}\n}\n\nlet PRESETS = {\n\tduckduckgo: \"https://duckduckgo.com/?q={query}\"\n\tbrave: \"https://search.brave.com/search?q={query}\"\n\tstartpage: \"https://www.startpage.com/do/search?q={query}\"\n\tsearx: \"https://search.disroot.org/search?q={query}\"\n\tgoogle: \"https://www.google.com/search?q={query}\"\n\tbing: \"https://www.bing.com/search?q={query}\"\n}\n\n// 設定値を URL テンプレートに。プリセット名でも https URL でもなければ null\n@resolveTemplate(raw) {\n\tif (Core:type(raw) != \"str\") return null\n\tvar s = raw.trim()\n\tlet key = s.lower()\n\tif (Obj:has(PRESETS, key)) return Obj:get(PRESETS, key)\n\tif (s == \"\") return null\n\tif (s.index_of(\"://\") == -1) s = [\"https://\", s].join(\"\")\n\tif (!s.starts_with(\"https://\")) return null\n\tif (s.index_of(\"{query}\") != -1) return s\n\t[s, \"{query}\"].join(\"\")\n}\n\n// テンプレートのホスト部 (https:// の後から / ? # の手前まで)\n@hostOf(template) {\n\tlet rest = template.slice(8, template.len)\n\tvar end = rest.len\n\teach (let c, [\"/\", \"?\", \"#\"]) {\n\t\tlet i = rest.index_of(c)\n\t\tif (i != -1 && i < end) end = i\n\t}\n\trest.slice(0, end)\n}\n\nlet TEMPLATE = resolveTemplate(Plugin:config.engine)\nlet HOST = if (TEMPLATE != null) hostOf(TEMPLATE) else \"\"\n\nif (TEMPLATE == null) {\n\tMk:dialog(\"warning\", \"MFM 検索の検索エンジン変更: 設定「検索エンジン」はプリセット名 (duckduckgo / brave / startpage / searx / google / bing) か https の URL にしてください。それまで検索行は書き換えません\")\n}\n\n// mfm-js の検索ブロック: 行頭から「検索語 + 空白 1 文字 + ボタン」で行末。大小無視\nlet BUTTONS = [\"[検索]\", \"[search]\", \"検索\", \"search\"]\n// AiScript の \"\\n\" はエスケープにならないので制御文字はコードポイントから作る\nlet LF = Str:lf\nlet CRLF = [Str:from_codepoint(13), LF].join(\"\")\nlet SPACES = [\" \", \" \", Str:from_codepoint(9)]\n\n// 行末のボタン部分の長さ。無ければ 0\n@trailingButton(line) {\n\tlet lower = line.lower()\n\teach (let b, BUTTONS) {\n\t\tif (lower.ends_with(b)) return b.len\n\t}\n\t0\n}\n\n// 検索行なら { query, button } を返す。違う行や、リンクにできない行は null。\n// button は行末の「検索」「search」(角括弧は外す。ラベルに入れると壊れる)\n@parseSearchLine(line) {\n\tlet bl = trailingButton(line)\n\tif (bl == 0) return null\n\tlet head = line.slice(0, line.len - bl)\n\tif (head.len < 2) return null\n\tif (!SPACES.incl(head.slice(head.len - 1, head.len))) return null\n\tlet query = head.slice(0, head.len - 1)\n\tif (query.index_of(\"[\") != -1) return null\n\tif (query.index_of(\"]\") != -1) return null\n\tlet button = line.slice(line.len - bl, line.len).replace(\"[\", \"\").replace(\"]\", \"\")\n\t{ query: query, button: button }\n}\n\n@buildUrl(query) {\n\t// encodeURIComponent は ( ) を残すが、リンク構文の括弧と衝突するので潰す\n\tlet q = Uri:encode_component(query).replace(\"(\", \"%28\").replace(\")\", \"%29\")\n\tTEMPLATE.replace(\"{query}\", q)\n}\n\n@rewrite(text) {\n\tlet lines = text.replace(CRLF, LF).split(LF)\n\tvar changed = false\n\tvar inCode = false\n\tvar parts = []\n\teach (let line, lines) {\n\t\tvar line2 = line\n\t\tif (line.starts_with(\"```\")) {\n\t\t\tinCode = !inCode\n\t\t} elif (!inCode && !line.starts_with(\">\")) {\n\t\t\tlet hit = parseSearchLine(line)\n\t\t\tif (hit != null) {\n\t\t\t\tline2 = `?[{hit.query} {hit.button} ({HOST})]({buildUrl(hit.query)})`\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t}\n\t\tparts.push(line2)\n\t}\n\tif (changed) parts.join(LF) else text\n}\n\nPlugin:register_note_view_interruptor(@(note) {\n\tif (TEMPLATE != null) {\n\t\tif (Core:type(note.text) == \"str\") note.text = rewrite(note.text)\n\t\tif (Core:type(note.renote) == \"obj\" && Core:type(note.renote.text) == \"str\") note.renote.text = rewrite(note.renote.text)\n\t}\n\tnote\n})\n"} diff --git a/public/registry/plugins/mfm-search-engine/meta.json b/public/registry/plugins/mfm-search-engine/meta.json index 9451f2b..4b87ae1 100644 --- a/public/registry/plugins/mfm-search-engine/meta.json +++ b/public/registry/plugins/mfm-search-engine/meta.json @@ -1,7 +1,7 @@ { "id": "mfm-search-engine", "name": "MFM 検索の検索エンジン変更", - "version": "1.0.0", + "version": "1.0.1", "author": "hitalin", "authorUrl": "https://github.com/hitalin", "description": "MFM の検索ブロック (foo 検索) の遷移先を DuckDuckGo などの好きな検索エンジンにする。表示時に検索行をリンクへ書き換えるだけで、投稿そのものは変更しない。プリセット名か https の URL だけを受け付け、リンクに遷移先ホストを表示", diff --git a/public/registry/plugins/mfm-search-engine/plugin.is b/public/registry/plugins/mfm-search-engine/plugin.is index 43a7faf..a83f8b5 100644 --- a/public/registry/plugins/mfm-search-engine/plugin.is +++ b/public/registry/plugins/mfm-search-engine/plugin.is @@ -9,9 +9,12 @@ // 投稿そのものは変更しない (表示専用)。見た目は検索ボックスではなく通常の // リンクになる。 // -// 遷移先はプリセット名か https:// の URL だけを受け付け、それ以外 (http / -// javascript / 未知の名前) は書き換えを止めて起動時に警告する。リンクのラベルに -// 遷移先ホストを出すので、押す前にどこへ飛ぶか分かる。 +// 遷移先はプリセット名か https の URL だけを受け付け、それ以外 (http / +// javascript / 未知の名前) は書き換えを止めて起動時に警告する。スキームの無い +// 値 (search.example.com/?q=) には https:// を足す (### の文字列に // を書くと +// NoteDeck 1.103 までのメタデータ解析がコメントとして落とし、設定が丸ごと消える +// ため、設定の説明にも書かない。notedeck#1340)。リンクのラベルに遷移先ホストを +// 出すので、押す前にどこへ飛ぶか分かる。 // // 書き換えない行: コードブロック内、引用 (> で始まる行)、検索語に [ ] を含む行 // (リンクのラベルが壊れる)。 @@ -21,14 +24,14 @@ ### { name: "MFM 検索の検索エンジン変更" - version: "1.0.0" + version: "1.0.1" author: "@hitalin" description: "MFM の検索ブロック (foo 検索) の遷移先を DuckDuckGo などの好きな検索エンジンにします。表示時に検索行をリンクへ書き換えるだけで、投稿そのものは変更しません" config: { engine: { type: "string" label: "検索エンジン" - description: "プリセット名 (duckduckgo / brave / startpage / searx / google / bing) か、https:// で始まる URL。URL は末尾に検索語が付きます。{query} を書くとその位置に入ります" + description: "プリセット名 (duckduckgo / brave / startpage / searx / google / bing) か、検索エンジンの URL (例: search.example.com/?q=)。URL は末尾に検索語が付きます。{query} を書くとその位置に入ります" default: "duckduckgo" } } @@ -45,9 +48,12 @@ let PRESETS = { // 設定値を URL テンプレートに。プリセット名でも https URL でもなければ null @resolveTemplate(raw) { - let s = raw.trim() + if (Core:type(raw) != "str") return null + var s = raw.trim() let key = s.lower() if (Obj:has(PRESETS, key)) return Obj:get(PRESETS, key) + if (s == "") return null + if (s.index_of("://") == -1) s = ["https://", s].join("") if (!s.starts_with("https://")) return null if (s.index_of("{query}") != -1) return s [s, "{query}"].join("") @@ -68,7 +74,7 @@ let TEMPLATE = resolveTemplate(Plugin:config.engine) let HOST = if (TEMPLATE != null) hostOf(TEMPLATE) else "" if (TEMPLATE == null) { - Mk:dialog("warning", "MFM 検索の検索エンジン変更: 設定「検索エンジン」はプリセット名 (duckduckgo / brave / startpage / searx / google / bing) か https:// で始まる URL にしてください。それまで検索行は書き換えません") + Mk:dialog("warning", "MFM 検索の検索エンジン変更: 設定「検索エンジン」はプリセット名 (duckduckgo / brave / startpage / searx / google / bing) か https の URL にしてください。それまで検索行は書き換えません") } // mfm-js の検索ブロック: 行頭から「検索語 + 空白 1 文字 + ボタン」で行末。大小無視 diff --git a/public/registry/queries.json b/public/registry/queries.json index 59949ff..d48ce2d 100644 --- a/public/registry/queries.json +++ b/public/registry/queries.json @@ -1,6 +1,6 @@ { "version": 1, - "updatedAt": "2026-11-04T00:27:05.105Z", + "updatedAt": "2026-11-04T11:57:10.395Z", "queries": [ { "id": "bot-only", diff --git a/public/registry/skills.json b/public/registry/skills.json index b2dfbb3..d99c5fc 100644 --- a/public/registry/skills.json +++ b/public/registry/skills.json @@ -1,6 +1,6 @@ { "version": 1, - "updatedAt": "2026-11-04T00:27:05.105Z", + "updatedAt": "2026-11-04T11:57:10.395Z", "skills": [ { "id": "aiscript-surgeon", diff --git a/public/registry/themes.json b/public/registry/themes.json index b50102a..fd74b94 100644 --- a/public/registry/themes.json +++ b/public/registry/themes.json @@ -1,6 +1,6 @@ { "version": 1, - "updatedAt": "2026-11-04T00:27:05.105Z", + "updatedAt": "2026-11-04T11:57:10.395Z", "themes": [ { "id": "adwaita-dark", diff --git a/public/registry/widgets.json b/public/registry/widgets.json index ac6b6d6..1e2b2b2 100644 --- a/public/registry/widgets.json +++ b/public/registry/widgets.json @@ -1,6 +1,6 @@ { "version": 1, - "updatedAt": "2026-11-04T00:27:05.105Z", + "updatedAt": "2026-11-04T11:57:10.395Z", "widgets": [ { "id": "aiscript-health",