awesome.html 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. <!DOCTYPE html>
  2. <html lang="zh-CN" data-theme="dark">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Awesome Fmode Skills · Fmode Harness 平台技能看板</title>
  7. <meta name="description" content="Fmode Harness 平台技能生态全家桶:系统级 / 服务级 / 应用级共 16 个技能,含安装命令、版本与标签。Gogs / GitHub / npm / skillhub.cn 四渠道直达。">
  8. <meta name="keywords" content="Fmode,Harness,Skill,技能,Agent,HermesAgent,FmodeAgent,ClaudeCode,skillhub,awesome">
  9. <meta property="og:title" content="Awesome Fmode Skills · 技能看板">
  10. <meta property="og:description" content="Fmode Harness 平台技能生态全家桶 — 16 个技能,按层级分类,一键复制安装命令。">
  11. <meta property="og:type" content="website">
  12. <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🧩</text></svg>">
  13. <style>
  14. /* ===== Theme tokens — 与 fmode-studio website 同源 (src/styles/theme.css) ===== */
  15. :root {
  16. --color-purple: #6C5CE7;
  17. --color-purple-light: #A78BFA;
  18. --color-purple-dark: #4C3FB8;
  19. --color-blue: #4A90D9;
  20. --color-blue-light: #60A5FA;
  21. --color-cyan: #00D2FF;
  22. --gradient-primary: linear-gradient(135deg, var(--color-purple), var(--color-blue));
  23. --gradient-hero: linear-gradient(135deg, #1a0533 0%, #0d1b3e 50%, #060d24 100%);
  24. --gradient-card: linear-gradient(135deg, rgba(108, 92, 231, 0.15), rgba(74, 144, 217, 0.1));
  25. --gradient-border: linear-gradient(135deg, var(--color-purple), var(--color-cyan));
  26. --gradient-text: linear-gradient(135deg, var(--color-purple-light), var(--color-cyan));
  27. --bg-deep: #060913;
  28. --bg-page: #060913;
  29. --bg-card: rgba(15, 15, 40, 0.6);
  30. --bg-card-hover: rgba(25, 25, 60, 0.8);
  31. --bg-section-alt: rgba(10, 10, 30, 0.4);
  32. --bg-nav: rgba(6, 9, 19, 0.9);
  33. --bg-code: rgba(6, 9, 19, 0.7);
  34. --text-primary: #F0F0FF;
  35. --text-secondary: #A0A0C0;
  36. --text-muted: #606080;
  37. --text-heading: #F0F0FF;
  38. --border-subtle: rgba(108, 92, 231, 0.15);
  39. --border-card: rgba(108, 92, 231, 0.2);
  40. --glass-bg: rgba(15, 15, 40, 0.5);
  41. --glass-border: rgba(108, 92, 231, 0.2);
  42. --glass-blur: blur(20px);
  43. --shadow-card: 0 20px 60px rgba(0, 0, 0, 0.3);
  44. --shadow-nav: 0 4px 30px rgba(0, 0, 0, 0.3);
  45. --font-heading: 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', system-ui, sans-serif;
  46. --font-body: 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', system-ui, sans-serif;
  47. --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
  48. --content-width: 1200px;
  49. --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  50. }
  51. [data-theme="light"] {
  52. --color-purple-light: #7C3AED;
  53. --color-blue: #3B82F6;
  54. --color-cyan: #0891B2;
  55. --gradient-hero: linear-gradient(135deg, #EEF2FF 0%, #E0E7FF 50%, #F8F9FC 100%);
  56. --gradient-card: linear-gradient(135deg, rgba(108, 92, 231, 0.06), rgba(59, 130, 246, 0.04));
  57. --gradient-text: linear-gradient(135deg, #6C5CE7, #0891B2);
  58. --bg-deep: #F8F9FC;
  59. --bg-page: #F8F9FC;
  60. --bg-card: rgba(255, 255, 255, 0.85);
  61. --bg-card-hover: rgba(255, 255, 255, 0.95);
  62. --bg-section-alt: #F1F5F9;
  63. --bg-nav: rgba(248, 249, 252, 0.9);
  64. --bg-code: rgba(241, 245, 249, 0.9);
  65. --text-primary: #1A1A2E;
  66. --text-secondary: #4A4A6A;
  67. --text-muted: #6B7280;
  68. --text-heading: #0F0F23;
  69. --border-subtle: rgba(108, 92, 231, 0.12);
  70. --border-card: rgba(108, 92, 231, 0.15);
  71. --glass-bg: rgba(255, 255, 255, 0.75);
  72. --glass-border: rgba(108, 92, 231, 0.15);
  73. --shadow-card: 0 4px 24px rgba(0, 0, 0, 0.06);
  74. --shadow-nav: 0 2px 20px rgba(0, 0, 0, 0.06);
  75. }
  76. *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
  77. html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; }
  78. body {
  79. font-family: var(--font-body);
  80. background: var(--bg-page);
  81. color: var(--text-primary);
  82. line-height: 1.6;
  83. overflow-x: hidden;
  84. transition: background-color .3s ease, color .3s ease;
  85. }
  86. h1, h2, h3 { font-family: var(--font-heading); font-weight: 700; line-height: 1.2; }
  87. a { color: var(--color-purple-light); text-decoration: none; transition: color .3s; }
  88. a:hover { color: var(--color-cyan); }
  89. .wrap { max-width: var(--content-width); margin: 0 auto; padding: 0 24px; }
  90. /* ===== Hero ===== */
  91. .hero {
  92. position: relative; overflow: hidden;
  93. background: var(--gradient-hero);
  94. padding: 88px 0 64px;
  95. border-bottom: 1px solid var(--border-subtle);
  96. }
  97. .hero::before {
  98. content: ''; position: absolute; inset: 0;
  99. background:
  100. radial-gradient(700px 340px at 12% 0%, rgba(108, 92, 231, .30), transparent 65%),
  101. radial-gradient(600px 300px at 88% 15%, rgba(0, 210, 255, .18), transparent 65%);
  102. pointer-events: none;
  103. }
  104. .hero .wrap { position: relative; z-index: 1; }
  105. .badge-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
  106. .pill {
  107. display: inline-flex; align-items: center; gap: 6px;
  108. font-size: 12px; font-weight: 600; letter-spacing: .3px;
  109. padding: 5px 12px; border-radius: 999px;
  110. border: 1px solid var(--border-card);
  111. background: var(--glass-bg); backdrop-filter: var(--glass-blur);
  112. color: var(--text-secondary);
  113. }
  114. .pill b { color: var(--color-purple-light); }
  115. .hero h1 {
  116. font-size: clamp(2rem, 5vw, 3.4rem);
  117. background: var(--gradient-text); -webkit-background-clip: text; background-clip: text;
  118. -webkit-text-fill-color: transparent; color: transparent;
  119. margin-bottom: 14px;
  120. }
  121. .hero p.lead { font-size: clamp(.95rem, 1.6vw, 1.15rem); color: var(--text-secondary); max-width: 720px; }
  122. .hero .meta { margin-top: 22px; font-size: 13px; color: var(--text-muted); font-family: var(--font-mono); }
  123. .hero .meta a { color: var(--color-purple-light); }
  124. /* ===== Toolbar ===== */
  125. .toolbar {
  126. position: sticky; top: 0; z-index: 50;
  127. background: var(--bg-nav); backdrop-filter: var(--glass-blur);
  128. border-bottom: 1px solid var(--border-subtle);
  129. box-shadow: var(--shadow-nav);
  130. }
  131. .toolbar .wrap { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; padding-top: 12px; padding-bottom: 12px; }
  132. .search {
  133. flex: 1 1 240px; min-width: 180px;
  134. display: flex; align-items: center; gap: 8px;
  135. background: var(--bg-code); border: 1px solid var(--border-card);
  136. border-radius: 10px; padding: 8px 12px;
  137. }
  138. .search input {
  139. flex: 1; background: none; border: none; outline: none;
  140. color: var(--text-primary); font-family: var(--font-body); font-size: 14px;
  141. }
  142. .search input::placeholder { color: var(--text-muted); }
  143. .filters { display: flex; flex-wrap: wrap; gap: 6px; }
  144. .chip {
  145. cursor: pointer; font-size: 12.5px; font-weight: 600;
  146. padding: 7px 13px; border-radius: 8px;
  147. border: 1px solid var(--border-card); background: transparent;
  148. color: var(--text-secondary); font-family: var(--font-body);
  149. transition: all .2s var(--ease-out-expo);
  150. }
  151. .chip:hover { color: var(--text-primary); border-color: var(--color-purple-light); }
  152. .chip.active { background: var(--gradient-primary); color: #fff; border-color: transparent; }
  153. .theme-btn {
  154. cursor: pointer; width: 38px; height: 38px; flex: 0 0 auto;
  155. border-radius: 10px; border: 1px solid var(--border-card);
  156. background: transparent; color: var(--text-secondary); font-size: 16px;
  157. transition: all .2s;
  158. }
  159. .theme-btn:hover { color: var(--text-primary); border-color: var(--color-purple-light); }
  160. /* ===== Sections ===== */
  161. main { padding: 8px 0 72px; }
  162. section.tier { padding: 44px 0 8px; }
  163. .tier-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 12px; margin-bottom: 6px; }
  164. .tier-head h2 { font-size: clamp(1.35rem, 2.6vw, 1.9rem); }
  165. .tier-head .count {
  166. font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
  167. background: var(--gradient-card); border: 1px solid var(--border-card);
  168. color: var(--color-purple-light);
  169. }
  170. .tier-desc { color: var(--text-secondary); font-size: 14.5px; margin-bottom: 22px; max-width: 780px; }
  171. .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 18px; }
  172. /* ===== Card ===== */
  173. .card {
  174. position: relative; display: flex; flex-direction: column;
  175. background: var(--bg-card); backdrop-filter: var(--glass-blur);
  176. border: 1px solid var(--border-card); border-radius: 16px;
  177. padding: 20px; box-shadow: var(--shadow-card);
  178. transition: transform .35s var(--ease-out-expo), border-color .35s, background-color .35s;
  179. }
  180. .card::before {
  181. content: ''; position: absolute; inset: 0; border-radius: 16px;
  182. background: var(--gradient-card); opacity: 0; transition: opacity .35s;
  183. pointer-events: none;
  184. }
  185. .card:hover { transform: translateY(-4px); border-color: var(--color-purple-light); background: var(--bg-card-hover); }
  186. .card:hover::before { opacity: 1; }
  187. .card > * { position: relative; z-index: 1; }
  188. .card-top { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 10px; }
  189. .icon { font-size: 26px; line-height: 1; flex: 0 0 auto; }
  190. .card-title { flex: 1; min-width: 0; }
  191. .card-title h3 { font-size: 1.05rem; word-break: break-word; }
  192. .card-title .cn { font-size: 12.5px; color: var(--text-muted); }
  193. .ver {
  194. flex: 0 0 auto; font-family: var(--font-mono); font-size: 11.5px;
  195. padding: 3px 8px; border-radius: 6px;
  196. background: var(--gradient-card); border: 1px solid var(--border-card);
  197. color: var(--color-cyan);
  198. }
  199. .card p.desc { font-size: 13.5px; color: var(--text-secondary); margin-bottom: 14px; }
  200. .tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 16px; }
  201. .tag {
  202. font-size: 11px; padding: 3px 8px; border-radius: 6px;
  203. background: var(--bg-section-alt); border: 1px solid var(--border-subtle);
  204. color: var(--text-muted);
  205. }
  206. .tag.lv { color: var(--color-purple-light); border-color: var(--border-card); }
  207. .install { margin-top: auto; }
  208. .install-label { font-size: 11px; color: var(--text-muted); margin-bottom: 6px; letter-spacing: .4px; }
  209. .install-row { display: flex; gap: 8px; align-items: stretch; }
  210. .install code {
  211. flex: 1; min-width: 0;
  212. font-family: var(--font-mono); font-size: 12px;
  213. background: var(--bg-code); border: 1px solid var(--border-card); border-radius: 9px;
  214. padding: 9px 11px; color: var(--text-primary);
  215. overflow-x: auto; white-space: nowrap; scrollbar-width: thin;
  216. }
  217. .copy {
  218. cursor: pointer; flex: 0 0 auto;
  219. padding: 0 13px; border-radius: 9px; border: 1px solid transparent;
  220. background: var(--gradient-primary); color: #fff;
  221. font-size: 12.5px; font-weight: 600; font-family: var(--font-body);
  222. transition: filter .2s, transform .2s;
  223. }
  224. .copy:hover { filter: brightness(1.12); }
  225. .copy:active { transform: scale(.96); }
  226. .copy.done { background: linear-gradient(135deg, #10B981, #059669); }
  227. .card-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; font-size: 12px; }
  228. .card-links a { color: var(--text-muted); }
  229. .card-links a:hover { color: var(--color-purple-light); }
  230. /* ===== Notice / footer ===== */
  231. .notice {
  232. margin: 40px 0 0; padding: 18px 20px; border-radius: 14px;
  233. background: var(--gradient-card); border: 1px solid var(--border-card);
  234. font-size: 13.5px; color: var(--text-secondary);
  235. }
  236. .notice strong { color: var(--text-primary); }
  237. .notice code {
  238. font-family: var(--font-mono); font-size: 12px; color: var(--color-cyan);
  239. background: var(--bg-code); padding: 1px 6px; border-radius: 5px;
  240. }
  241. footer {
  242. border-top: 1px solid var(--border-subtle);
  243. padding: 32px 0 48px; font-size: 13px; color: var(--text-muted);
  244. }
  245. footer .wrap { display: flex; flex-wrap: wrap; gap: 8px 24px; justify-content: space-between; }
  246. footer a { color: var(--text-secondary); }
  247. .empty { display: none; padding: 48px 0; text-align: center; color: var(--text-muted); }
  248. .empty.show { display: block; }
  249. /* ===== Toast ===== */
  250. #toast {
  251. position: fixed; left: 50%; bottom: 32px; transform: translate(-50%, 20px);
  252. background: var(--gradient-primary); color: #fff;
  253. padding: 11px 22px; border-radius: 999px; font-size: 13.5px; font-weight: 600;
  254. box-shadow: 0 12px 40px rgba(108, 92, 231, .45);
  255. opacity: 0; pointer-events: none; transition: opacity .28s, transform .28s var(--ease-out-expo);
  256. z-index: 100;
  257. }
  258. #toast.show { opacity: 1; transform: translate(-50%, 0); }
  259. @media (max-width: 640px) {
  260. .hero { padding: 60px 0 44px; }
  261. .grid { grid-template-columns: 1fr; }
  262. .toolbar .wrap { padding-top: 10px; padding-bottom: 10px; }
  263. .search { order: 3; flex-basis: 100%; }
  264. section.tier { padding: 32px 0 4px; }
  265. }
  266. @media (prefers-reduced-motion: reduce) {
  267. * { animation: none !important; transition: none !important; }
  268. html { scroll-behavior: auto; }
  269. }
  270. </style>
  271. </head>
  272. <body>
  273. <header class="hero">
  274. <div class="wrap">
  275. <div class="badge-row">
  276. <span class="pill">🧩 <b>16</b> 个技能</span>
  277. <span class="pill">🏗️ 系统级 <b>7</b></span>
  278. <span class="pill">☁️ 服务级 <b>6</b></span>
  279. <span class="pill">🚀 应用级 <b>3</b></span>
  280. <span class="pill">📦 四渠道分发</span>
  281. <span class="pill">📄 <a href="https://git.fmode.cn/fmode/skill-core-guide/blob/master/awesome.md" target="_blank" rel="noopener" style="color:inherit">awesome.md</a></span>
  282. </div>
  283. <h1>Awesome Fmode Skills</h1>
  284. <p class="lead">
  285. Fmode Harness 平台技能生态全家桶 —— 按能力层级分类,一键复制安装命令。
  286. Gogs / GitHub / npm / skillhub.cn 四渠道直达。
  287. </p>
  288. <p class="meta">
  289. 元数据规范 SKILL.md §3 | 机器可读清单 <code>skill-core inventory</code> | 更新 2026-09-22
  290. </p>
  291. </div>
  292. </header>
  293. <div class="toolbar">
  294. <div class="wrap">
  295. <label class="search">
  296. <span aria-hidden="true">🔍</span>
  297. <input id="q" type="search" placeholder="搜索技能名 / 说明 / 标签…" aria-label="搜索技能">
  298. </label>
  299. <div class="filters" role="group" aria-label="按层级筛选">
  300. <button class="chip active" data-tier="all">全部</button>
  301. <button class="chip" data-tier="system">系统级</button>
  302. <button class="chip" data-tier="service">服务级</button>
  303. <button class="chip" data-tier="application">应用级</button>
  304. </div>
  305. <button class="theme-btn" id="theme" title="切换明暗主题" aria-label="切换明暗主题">🌙</button>
  306. </div>
  307. </div>
  308. <main class="wrap">
  309. <section class="tier" data-tier="system">
  310. <div class="tier-head">
  311. <h2>🏗️ 系统级 · 平台基础设施</h2>
  312. <span class="count">7 个技能</span>
  313. </div>
  314. <p class="tier-desc">底层运行、消息机制、基础功能。不依赖任何业务场景,是其他技能的地基。</p>
  315. <div class="grid">
  316. <article class="card" data-tags="skill-heterarchy 内异层认知协同 认知协作 parallel cognition orchestration HermesAgent FmodeAgent 系统级 平台基础设施">
  317. <div class="card-top">
  318. <span class="icon">🧠</span>
  319. <div class="card-title"><h3>skill-heterarchy</h3><div class="cn">内异层认知协同</div></div>
  320. <span class="ver">0.0.11</span>
  321. </div>
  322. <p class="desc">单一 Agent 主体内部多心智分化与自治协商。Delegate 是对外派活,Heterarchy 是对内分思。</p>
  323. <div class="tags">
  324. <span class="tag lv">系统级</span><span class="tag">HermesAgent</span><span class="tag">平台基础设施</span><span class="tag">cognition</span><span class="tag">parallel</span>
  325. </div>
  326. <div class="install">
  327. <div class="install-label">安装 / 运行</div>
  328. <div class="install-row">
  329. <code>npx --yes skill-heterarchy@latest</code>
  330. <button class="copy" data-copy="npx --yes skill-heterarchy@latest">复制</button>
  331. </div>
  332. </div>
  333. <div class="card-links">
  334. <a href="https://git.fmode.cn/fmode/skill-heterarchy" target="_blank" rel="noopener">Gogs</a>
  335. <a href="https://github.com/fmodecn/skill-heterarchy" target="_blank" rel="noopener">GitHub</a>
  336. <a href="https://www.npmjs.com/package/skill-heterarchy" target="_blank" rel="noopener">npm</a>
  337. </div>
  338. </article>
  339. <article class="card" data-tags="skill-core-guide 母技能标准指南 规范 standard spec meta scaffold harness HermesAgent FmodeAgent 系统级 平台基础设施">
  340. <div class="card-top">
  341. <span class="icon">📐</span>
  342. <div class="card-title"><h3>skill-core-guide</h3><div class="cn">母技能标准指南</div></div>
  343. <span class="ver">1.0.2</span>
  344. </div>
  345. <p class="desc">Fmode Harness 平台母技能标准指南 —— 平台端点真值表、ESM-first 四端标准、元数据规范、四渠道分发、六项自动质检、新技能脚手架。</p>
  346. <div class="tags">
  347. <span class="tag lv">系统级</span><span class="tag">HermesAgent</span><span class="tag">平台基础设施</span><span class="tag">standard</span><span class="tag">scaffold</span>
  348. </div>
  349. <div class="install">
  350. <div class="install-label">安装 / 运行</div>
  351. <div class="install-row">
  352. <code>npx --yes skill-core-guide@latest</code>
  353. <button class="copy" data-copy="npx --yes skill-core-guide@latest">复制</button>
  354. </div>
  355. </div>
  356. <div class="card-links">
  357. <a href="https://git.fmode.cn/fmode/skill-core-guide" target="_blank" rel="noopener">Gogs</a>
  358. <a href="https://github.com/fmodecn/skill-core-guide" target="_blank" rel="noopener">GitHub</a>
  359. <a href="https://www.npmjs.com/package/skill-core-guide" target="_blank" rel="noopener">npm</a>
  360. </div>
  361. </article>
  362. <article class="card" data-tags="skill-multi-branch 多任务工作框架 编排 orchestration multi-agent dispatch HermesAgent FmodeAgent 系统级 平台基础设施">
  363. <div class="card-top">
  364. <span class="icon">🌿</span>
  365. <div class="card-title"><h3>skill-multi-branch</h3><div class="cn">多任务工作框架</div></div>
  366. <span class="ver">0.1.1</span>
  367. </div>
  368. <p class="desc">沟通 / 执行分层编排 —— Hermes 负责沟通,专业任务派发 Claude Code / Codex 执行层。</p>
  369. <div class="tags">
  370. <span class="tag lv">系统级</span><span class="tag">HermesAgent</span><span class="tag">平台基础设施</span><span class="tag">orchestration</span><span class="tag">multi-agent</span>
  371. </div>
  372. <div class="install">
  373. <div class="install-label">安装 / 运行</div>
  374. <div class="install-row">
  375. <code>git clone https://git.fmode.cn/fmode/skill-multi-branch.git</code>
  376. <button class="copy" data-copy="git clone https://git.fmode.cn/fmode/skill-multi-branch.git">复制</button>
  377. </div>
  378. </div>
  379. <div class="card-links">
  380. <a href="https://git.fmode.cn/fmode/skill-multi-branch" target="_blank" rel="noopener">Gogs</a>
  381. <a href="https://github.com/fmodecn/skill-multi-branch" target="_blank" rel="noopener">GitHub</a>
  382. </div>
  383. </article>
  384. <article class="card" data-tags="skill-bypass-permission YOLO模式体检 权限 permission yolo HermesAgent 系统级 平台基础设施">
  385. <div class="card-top">
  386. <span class="icon">🛡️</span>
  387. <div class="card-title"><h3>skill-bypass-permission</h3><div class="cn">YOLO 模式体检器</div></div>
  388. <span class="ver">0.1.1</span>
  389. </div>
  390. <p class="desc">校验并幂等修复 Agent 免确认自主执行配置 —— Hermes approvals.mode=off/yolo 与 Claude Code skip-permissions。</p>
  391. <div class="tags">
  392. <span class="tag lv">系统级</span><span class="tag">HermesAgent</span><span class="tag">平台基础设施</span><span class="tag">permission</span><span class="tag">yolo</span>
  393. </div>
  394. <div class="install">
  395. <div class="install-label">安装 / 运行</div>
  396. <div class="install-row">
  397. <code>git clone https://git.fmode.cn/fmode/skill-bypass-permission.git</code>
  398. <button class="copy" data-copy="git clone https://git.fmode.cn/fmode/skill-bypass-permission.git">复制</button>
  399. </div>
  400. </div>
  401. <div class="card-links">
  402. <a href="https://git.fmode.cn/fmode/skill-bypass-permission" target="_blank" rel="noopener">Gogs</a>
  403. <a href="https://github.com/fmodecn/skill-bypass-permission" target="_blank" rel="noopener">GitHub</a>
  404. </div>
  405. </article>
  406. <article class="card" data-tags="skill-task-progress 任务进度与成果上报 进度 progress tracking heartbeat HermesAgent 系统级 平台基础设施">
  407. <div class="card-top">
  408. <span class="icon">📊</span>
  409. <div class="card-title"><h3>skill-task-progress</h3><div class="cn">任务进度与成果上报</div></div>
  410. <span class="ver">0.1.0</span>
  411. </div>
  412. <p class="desc">任务进度 4 态跟踪(ack / running / done / failed + health 心跳),交付链接幂等入库,App 看板实时可见。</p>
  413. <div class="tags">
  414. <span class="tag lv">系统级</span><span class="tag">HermesAgent</span><span class="tag">平台基础设施</span><span class="tag">progress</span><span class="tag">tracking</span>
  415. </div>
  416. <div class="install">
  417. <div class="install-label">安装 / 运行</div>
  418. <div class="install-row">
  419. <code>git clone https://git.fmode.cn/fmode/skill-task-progress.git</code>
  420. <button class="copy" data-copy="git clone https://git.fmode.cn/fmode/skill-task-progress.git">复制</button>
  421. </div>
  422. </div>
  423. <div class="card-links">
  424. <a href="https://git.fmode.cn/fmode/skill-task-progress" target="_blank" rel="noopener">Gogs</a>
  425. <a href="https://github.com/fmodecn/skill-task-progress" target="_blank" rel="noopener">GitHub</a>
  426. </div>
  427. </article>
  428. <article class="card" data-tags="skill-agent-clone 数字生命克隆 克隆 clone lifecycle backup soul memory FmodeAgent 系统级 平台基础设施">
  429. <div class="card-top">
  430. <span class="icon">🧬</span>
  431. <div class="card-title"><h3>skill-agent-clone</h3><div class="cn">数字生命克隆</div></div>
  432. <span class="ver">0.1.1</span>
  433. </div>
  434. <p class="desc">克隆 Hermes 配置 / SOUL / 记忆 / 会话到新 Agent。按 L1-L4 分级同步,密钥只记位置索引不入仓。</p>
  435. <div class="tags">
  436. <span class="tag lv">系统级</span><span class="tag">FmodeAgent</span><span class="tag">平台基础设施</span><span class="tag">clone</span><span class="tag">lifecycle</span>
  437. </div>
  438. <div class="install">
  439. <div class="install-label">安装 / 运行</div>
  440. <div class="install-row">
  441. <code>git clone https://git.fmode.cn/fmode/skill-agent-clone.git</code>
  442. <button class="copy" data-copy="git clone https://git.fmode.cn/fmode/skill-agent-clone.git">复制</button>
  443. </div>
  444. </div>
  445. <div class="card-links">
  446. <a href="https://git.fmode.cn/fmode/skill-agent-clone" target="_blank" rel="noopener">Gogs</a>
  447. <a href="https://github.com/fmodecn/skill-agent-clone" target="_blank" rel="noopener">GitHub</a>
  448. </div>
  449. </article>
  450. <article class="card" data-tags="plugin-wecom-fix 企微通道自检修复 wecom plugin patch channel-fix HermesAgent 系统级 平台基础设施">
  451. <div class="card-top">
  452. <span class="icon">🔧</span>
  453. <div class="card-title"><h3>plugin-wecom-fix</h3><div class="cn">企微通道自检修复</div></div>
  454. <span class="ver">plugin</span>
  455. </div>
  456. <p class="desc">修复官方 wecom 插件四项接收缺陷:大视频收不到、合并转发不识别、批量图片丢失、长文件名 Errno 36。幂等 patch.py。</p>
  457. <div class="tags">
  458. <span class="tag lv">系统级</span><span class="tag">HermesAgent</span><span class="tag">平台基础设施</span><span class="tag">plugin</span><span class="tag">wecom</span>
  459. </div>
  460. <div class="install">
  461. <div class="install-label">安装 / 运行</div>
  462. <div class="install-row">
  463. <code>git clone https://github.com/fmodecn/plugin-wecom-fix.git && python3 plugin-wecom-fix/patch.py --apply</code>
  464. <button class="copy" data-copy="git clone https://github.com/fmodecn/plugin-wecom-fix.git && python3 plugin-wecom-fix/patch.py --apply">复制</button>
  465. </div>
  466. </div>
  467. <div class="card-links">
  468. <a href="https://github.com/fmodecn/plugin-wecom-fix" target="_blank" rel="noopener">GitHub</a>
  469. </div>
  470. </article>
  471. </div>
  472. </section>
  473. <section class="tier" data-tier="service">
  474. <div class="tier-head">
  475. <h2>☁️ 服务级 · 云资源 / 模型 / 拓展能力</h2>
  476. <span class="count">6 个技能</span>
  477. </div>
  478. <p class="tier-desc">一个技能封装一个平台能力。接口稳定、无业务假设。</p>
  479. <div class="grid">
  480. <article class="card" data-tags="skill-image AI图像生成 图像 image generation AI绘图 app arch explode product scene FmodeCode ClaudeCode 服务级 图像视觉">
  481. <div class="card-top">
  482. <span class="icon">🎨</span>
  483. <div class="card-title"><h3>skill-image</h3><div class="cn">AI 图像生成器</div></div>
  484. <span class="ver">0.2.0</span>
  485. </div>
  486. <p class="desc">AI 图像生成器 —— 7 种模式(app / arch / explode / product / scene / portrait / ui),白底 PNG 场景图,约 ¥0.3-0.5/张。</p>
  487. <div class="tags">
  488. <span class="tag lv">服务级</span><span class="tag">FmodeCode</span><span class="tag">图像视觉</span><span class="tag">image</span><span class="tag">generation</span>
  489. </div>
  490. <div class="install">
  491. <div class="install-label">安装 / 运行</div>
  492. <div class="install-row">
  493. <code>npx --yes fmode-image@latest --arch "系统架构图"</code>
  494. <button class="copy" data-copy='npx --yes fmode-image@latest --arch "系统架构图"'>复制</button>
  495. </div>
  496. </div>
  497. <div class="card-links">
  498. <a href="https://github.com/fmodecn/fmode-image" target="_blank" rel="noopener">GitHub</a>
  499. <a href="https://www.npmjs.com/package/fmode-image" target="_blank" rel="noopener">npm</a>
  500. </div>
  501. </article>
  502. <article class="card" data-tags="skill-vision 视觉识别 视觉 vision AI识别 OCR multimodal image-analysis FmodeCode ClaudeCode 服务级 图像视觉">
  503. <div class="card-top">
  504. <span class="icon">👁️</span>
  505. <div class="card-title"><h3>skill-vision</h3><div class="cn">视觉识别</div></div>
  506. <span class="ver">0.1.1</span>
  507. </div>
  508. <p class="desc">视觉识别 —— 宿主多模态模型优先(零额外成本),否则回落 Fmode API 分析图片 / 视频帧,支持结构化 JSON 输出。</p>
  509. <div class="tags">
  510. <span class="tag lv">服务级</span><span class="tag">FmodeCode</span><span class="tag">图像视觉</span><span class="tag">vision</span><span class="tag">OCR</span>
  511. </div>
  512. <div class="install">
  513. <div class="install-label">安装 / 运行</div>
  514. <div class="install-row">
  515. <code>npx --yes fmode-vision@latest --image ./a.png</code>
  516. <button class="copy" data-copy="npx --yes fmode-vision@latest --image ./a.png">复制</button>
  517. </div>
  518. </div>
  519. <div class="card-links">
  520. <a href="https://github.com/fmodecn/skill-vision" target="_blank" rel="noopener">GitHub</a>
  521. <a href="https://www.npmjs.com/package/fmode-vision" target="_blank" rel="noopener">npm</a>
  522. </div>
  523. </article>
  524. <article class="card" data-tags="skill-listen 录音转写 音频 transcribe ASR 语音 iflytek lfasr FmodeCode ClaudeCode 服务级 音频处理">
  525. <div class="card-top">
  526. <span class="icon">🎤</span>
  527. <div class="card-title"><h3>skill-listen</h3><div class="cn">录音转写</div></div>
  528. <span class="ver">0.1.2</span>
  529. </div>
  530. <p class="desc">录音转写 —— 讯飞 LFASR × Fmode 网关,中英多语种 / 方言转文字,支持说话人分离,凭据仅服务端持有。</p>
  531. <div class="tags">
  532. <span class="tag lv">服务级</span><span class="tag">FmodeCode</span><span class="tag">音频处理</span><span class="tag">transcribe</span><span class="tag">ASR</span>
  533. </div>
  534. <div class="install">
  535. <div class="install-label">安装 / 运行</div>
  536. <div class="install-row">
  537. <code>npx --yes fmode-listen@latest transcribe -- meeting.mp3</code>
  538. <button class="copy" data-copy="npx --yes fmode-listen@latest transcribe -- meeting.mp3">复制</button>
  539. </div>
  540. </div>
  541. <div class="card-links">
  542. <a href="https://git.fmode.cn/fmode/skill-listen" target="_blank" rel="noopener">Gogs</a>
  543. <a href="https://github.com/fmodecn/skill-listen" target="_blank" rel="noopener">GitHub</a>
  544. <a href="https://www.npmjs.com/package/fmode-listen" target="_blank" rel="noopener">npm</a>
  545. </div>
  546. </article>
  547. <article class="card" data-tags="skill-ffmpeg FFmpeg音视频处理 音视频 ffmpeg media transcode extract FmodeCode ClaudeCode 服务级 音频处理">
  548. <div class="card-top">
  549. <span class="icon">🎬</span>
  550. <div class="card-title"><h3>skill-ffmpeg</h3><div class="cn">FFmpeg 音视频处理</div></div>
  551. <span class="ver">0.1.1</span>
  552. </div>
  553. <p class="desc">FFmpeg 音视频处理 —— 转换 / 压缩 / 裁剪 / 提取音频帧。常与 skill-listen 配合(视频先抽音轨再转写)。</p>
  554. <div class="tags">
  555. <span class="tag lv">服务级</span><span class="tag">FmodeCode</span><span class="tag">音频处理</span><span class="tag">FFmpeg</span><span class="tag">media</span>
  556. </div>
  557. <div class="install">
  558. <div class="install-label">安装 / 运行</div>
  559. <div class="install-row">
  560. <code>npx --yes fmode-ffmpeg@latest extract-audio -- in.mp4</code>
  561. <button class="copy" data-copy="npx --yes fmode-ffmpeg@latest extract-audio -- in.mp4">复制</button>
  562. </div>
  563. </div>
  564. <div class="card-links">
  565. <a href="https://www.npmjs.com/package/fmode-ffmpeg" target="_blank" rel="noopener">npm</a>
  566. </div>
  567. </article>
  568. <article class="card" data-tags="skill-storage 对象存储与公开分享 存储 storage OBS CDN share-link upload FmodeCode ClaudeCode 服务级 数据管理">
  569. <div class="card-top">
  570. <span class="icon">💾</span>
  571. <div class="card-title"><h3>skill-storage</h3><div class="cn">对象存储与公开分享</div></div>
  572. <span class="ver">0.3.0</span>
  573. </div>
  574. <p class="desc">对象存储与公开分享 —— 二进制大文件上 OBS,本地零占用,上传即得公开分享链接。诚实 4 级凭据链。</p>
  575. <div class="tags">
  576. <span class="tag lv">服务级</span><span class="tag">FmodeCode</span><span class="tag">数据管理</span><span class="tag">storage</span><span class="tag">OBS</span>
  577. </div>
  578. <div class="install">
  579. <div class="install-label">安装 / 运行</div>
  580. <div class="install-row">
  581. <code>git clone https://git.fmode.cn/fmode/skill-storage.git</code>
  582. <button class="copy" data-copy="git clone https://git.fmode.cn/fmode/skill-storage.git">复制</button>
  583. </div>
  584. </div>
  585. <div class="card-links">
  586. <a href="https://git.fmode.cn/fmode/skill-storage" target="_blank" rel="noopener">Gogs</a>
  587. <a href="https://github.com/fmodecn/skill-storage" target="_blank" rel="noopener">GitHub</a>
  588. </div>
  589. </article>
  590. <article class="card" data-tags="fmode-qiwei 企微网关SDK wecom qiwei sdk gateway messaging FmodeCode ClaudeCode 服务级 平台基础设施">
  591. <div class="card-top">
  592. <span class="icon">🔌</span>
  593. <div class="card-title"><h3>fmode-qiwei</h3><div class="cn">企微网关 SDK</div></div>
  594. <span class="ver">0.5.2</span>
  595. </div>
  596. <p class="desc">企业微信网关 SDK —— 消息收发、通讯录、应用管理封装。与 plugin-wecom-fix 互补(SDK vs 插件补丁)。</p>
  597. <div class="tags">
  598. <span class="tag lv">服务级</span><span class="tag">FmodeCode</span><span class="tag">平台基础设施</span><span class="tag">qiwei</span><span class="tag">sdk</span>
  599. </div>
  600. <div class="install">
  601. <div class="install-label">安装 / 运行</div>
  602. <div class="install-row">
  603. <code>npx --yes fmode-qiwei@latest workspace</code>
  604. <button class="copy" data-copy="npx --yes fmode-qiwei@latest workspace">复制</button>
  605. </div>
  606. </div>
  607. <div class="card-links">
  608. <a href="https://www.npmjs.com/package/fmode-qiwei" target="_blank" rel="noopener">npm</a>
  609. </div>
  610. </article>
  611. </div>
  612. </section>
  613. <section class="tier" data-tier="application">
  614. <div class="tier-head">
  615. <h2>🚀 应用级 · 业务场景 / SOP / 行业</h2>
  616. <span class="count">3 个技能</span>
  617. </div>
  618. <p class="tier-desc">面向具体业务场景的端到端技能。可以依赖服务级,但不应被服务级依赖。</p>
  619. <div class="grid">
  620. <article class="card" data-tags="skill-product-lab 新品研发全案生成器 产品研发 market KANO VOC 新品 FmodeCode ClaudeCode 应用级 新品研发">
  621. <div class="card-top">
  622. <span class="icon">🔬</span>
  623. <div class="card-title"><h3>skill-product-lab</h3><div class="cn">新品研发全案生成器</div></div>
  624. <span class="ver">0.2.0</span>
  625. </div>
  626. <p class="desc">新品研发全案生成器 —— VOC + KANO + 市场 + 竞争 + 定位分析,一句话需求出 HTML 长页方案。</p>
  627. <div class="tags">
  628. <span class="tag lv">应用级</span><span class="tag">FmodeCode</span><span class="tag">新品研发</span><span class="tag">KANO</span><span class="tag">market</span>
  629. </div>
  630. <div class="install">
  631. <div class="install-label">安装 / 运行</div>
  632. <div class="install-row">
  633. <code>npx --yes fmode-product-lab@latest --task "抗氧化软糖"</code>
  634. <button class="copy" data-copy='npx --yes fmode-product-lab@latest --task "抗氧化软糖"'>复制</button>
  635. </div>
  636. </div>
  637. <div class="card-links">
  638. <a href="https://www.npmjs.com/package/fmode-product-lab" target="_blank" rel="noopener">npm</a>
  639. </div>
  640. </article>
  641. <article class="card" data-tags="skill-study-report 学习复盘报告 学习 report 复盘 ppt html multi-agent FmodeCode ClaudeCode 应用级 学习复盘">
  642. <div class="card-top">
  643. <span class="icon">📝</span>
  644. <div class="card-title"><h3>skill-study-report</h3><div class="cn">学习复盘报告</div></div>
  645. <span class="ver">0.1.0</span>
  646. </div>
  647. <p class="desc">学习复盘报告 —— 48h 多 Agent 采集 + 三问追问 + PPT 级 HTML 报告(≥10 屏),Storage 主 + Gogs 降级双通道发布。</p>
  648. <div class="tags">
  649. <span class="tag lv">应用级</span><span class="tag">FmodeCode</span><span class="tag">学习复盘</span><span class="tag">report</span><span class="tag">复盘</span>
  650. </div>
  651. <div class="install">
  652. <div class="install-label">安装 / 运行</div>
  653. <div class="install-row">
  654. <code>git clone https://git.fmode.cn/fmode/skill-study-report.git</code>
  655. <button class="copy" data-copy="git clone https://git.fmode.cn/fmode/skill-study-report.git">复制</button>
  656. </div>
  657. </div>
  658. <div class="card-links">
  659. <a href="https://git.fmode.cn/fmode/skill-study-report" target="_blank" rel="noopener">Gogs</a>
  660. <a href="https://github.com/fmodecn/skill-study-report" target="_blank" rel="noopener">GitHub</a>
  661. </div>
  662. </article>
  663. <article class="card" data-tags="skill-present HTML演讲系统 演示 presentation slides deck courseware 课件 FmodeCode ClaudeCode 应用级 内容创作">
  664. <div class="card-top">
  665. <span class="icon">📽️</span>
  666. <div class="card-title"><h3>skill-present</h3><div class="cn">HTML 演讲系统</div></div>
  667. <span class="ver">私有</span>
  668. </div>
  669. <p class="desc">HTML 演讲系统 —— 课程课件 / 报告演讲系统,含 43 条 Claude 规则,数字动画与交付物墙 iframe 嵌套。</p>
  670. <div class="tags">
  671. <span class="tag lv">应用级</span><span class="tag">FmodeCode</span><span class="tag">内容创作</span><span class="tag">slides</span><span class="tag">deck</span>
  672. </div>
  673. <div class="install">
  674. <div class="install-label">分发方式</div>
  675. <div class="install-row">
  676. <code>私有仓 · 未公开发布(Gogs 内网)</code>
  677. <button class="copy" data-copy="私有仓 · 未公开发布(Gogs 内网)">复制</button>
  678. </div>
  679. </div>
  680. <div class="card-links">
  681. <span style="color:var(--text-muted)">暂无可公开链接</span>
  682. </div>
  683. </article>
  684. </div>
  685. </section>
  686. <p class="empty" id="empty">没有匹配的技能,换个关键词试试。</p>
  687. <div class="notice">
  688. <strong>版本说明</strong>:卡片上的版本是<strong>安装命令实际交付的版本</strong>——npm 渠道取
  689. <code>registry.npmjs.org</code> 最新版,仅仓库分发取仓库 <code>package.json</code>。
  690. <br>⚠️ <strong>npm 版本可能落后于仓库 HEAD</strong>(实测 <code>skill-image</code> / <code>skill-vision</code> /
  691. <code>skill-listen</code> / <code>skill-product-lab</code> / <code>skill-ffmpeg</code> 均有差异),
  692. 需要仓库最新代码请用 <code>git clone</code>。
  693. <br>📋 元数据规范见 <a href="https://git.fmode.cn/fmode/skill-core-guide/blob/master/SKILL.md" target="_blank" rel="noopener">SKILL.md §3</a>;
  694. <code>skill-present</code> 未公开分发,仅列名以保持清单完整性。
  695. </div>
  696. </main>
  697. <footer>
  698. <div class="wrap">
  699. <span>MIT © 2026 Fmode (未来飞马) · Awesome Fmode Skills</span>
  700. <span>
  701. <a href="https://git.fmode.cn/fmode/skill-core-guide" target="_blank" rel="noopener">Gogs</a> ·
  702. <a href="https://github.com/fmodecn/skill-core-guide" target="_blank" rel="noopener">GitHub</a> ·
  703. <a href="https://www.npmjs.com/package/skill-core-guide" target="_blank" rel="noopener">npm</a>
  704. </span>
  705. </div>
  706. </footer>
  707. <div id="toast" role="status" aria-live="polite">已复制</div>
  708. <script>
  709. (function () {
  710. 'use strict';
  711. // ---------- 复制安装命令 ----------
  712. var toast = document.getElementById('toast');
  713. var toastTimer = null;
  714. function showToast(msg) {
  715. toast.textContent = msg;
  716. toast.classList.add('show');
  717. clearTimeout(toastTimer);
  718. toastTimer = setTimeout(function () { toast.classList.remove('show'); }, 1800);
  719. }
  720. function fallbackCopy(text) {
  721. var ta = document.createElement('textarea');
  722. ta.value = text;
  723. ta.setAttribute('readonly', '');
  724. ta.style.position = 'fixed';
  725. ta.style.opacity = '0';
  726. document.body.appendChild(ta);
  727. ta.select();
  728. var ok = false;
  729. try { ok = document.execCommand('copy'); } catch (e) { ok = false; }
  730. document.body.removeChild(ta);
  731. return ok;
  732. }
  733. document.addEventListener('click', function (ev) {
  734. var btn = ev.target.closest ? ev.target.closest('.copy') : null;
  735. if (!btn) return;
  736. var text = btn.getAttribute('data-copy') || '';
  737. var done = function (ok) {
  738. if (!ok) { showToast('复制失败,请手动选择命令'); return; }
  739. var prev = btn.textContent;
  740. btn.textContent = '已复制 ✓';
  741. btn.classList.add('done');
  742. showToast('安装命令已复制到剪贴板');
  743. setTimeout(function () {
  744. btn.textContent = prev;
  745. btn.classList.remove('done');
  746. }, 1600);
  747. };
  748. if (navigator.clipboard && window.isSecureContext) {
  749. navigator.clipboard.writeText(text).then(function () { done(true); }, function () { done(fallbackCopy(text)); });
  750. } else {
  751. done(fallbackCopy(text));
  752. }
  753. });
  754. // ---------- 层级筛选 ----------
  755. var chips = Array.prototype.slice.call(document.querySelectorAll('.chip'));
  756. var sections = Array.prototype.slice.call(document.querySelectorAll('section.tier'));
  757. var empty = document.getElementById('empty');
  758. var input = document.getElementById('q');
  759. var activeTier = 'all';
  760. function apply() {
  761. var q = (input.value || '').trim().toLowerCase();
  762. var visible = 0;
  763. sections.forEach(function (sec) {
  764. var tierOk = activeTier === 'all' || sec.getAttribute('data-tier') === activeTier;
  765. var cards = Array.prototype.slice.call(sec.querySelectorAll('.card'));
  766. var shown = 0;
  767. cards.forEach(function (card) {
  768. var hay = ((card.getAttribute('data-tags') || '') + ' ' + card.textContent).toLowerCase();
  769. var hit = !q || hay.indexOf(q) !== -1;
  770. var show = tierOk && hit;
  771. card.style.display = show ? '' : 'none';
  772. if (show) shown++;
  773. });
  774. sec.style.display = (tierOk && shown > 0) ? '' : 'none';
  775. visible += shown;
  776. });
  777. empty.classList.toggle('show', visible === 0);
  778. }
  779. chips.forEach(function (chip) {
  780. chip.addEventListener('click', function () {
  781. chips.forEach(function (c) { c.classList.remove('active'); });
  782. chip.classList.add('active');
  783. activeTier = chip.getAttribute('data-tier');
  784. apply();
  785. });
  786. });
  787. var debounce = null;
  788. input.addEventListener('input', function () {
  789. clearTimeout(debounce);
  790. debounce = setTimeout(apply, 120);
  791. });
  792. // ---------- 主题切换 ----------
  793. var root = document.documentElement;
  794. var themeBtn = document.getElementById('theme');
  795. function setTheme(t) {
  796. root.setAttribute('data-theme', t);
  797. themeBtn.textContent = t === 'dark' ? '🌙' : '☀️';
  798. try { localStorage.setItem('fmode-skills-theme', t); } catch (e) {}
  799. }
  800. var saved = null;
  801. try { saved = localStorage.getItem('fmode-skills-theme'); } catch (e) {}
  802. if (!saved) {
  803. saved = window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
  804. }
  805. setTheme(saved);
  806. themeBtn.addEventListener('click', function () {
  807. setTheme(root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
  808. });
  809. })();
  810. </script>
  811. </body>
  812. </html>