1import{_ as d,c as h,a as l,b as i,e as a,d as t,w as e,r as p,o as r}from"./app-X5ZAzaQf.js";const k={};function c(o,s){const n=p("RouteLink");return r(),h("div",null,[s[12]||(s[12]=l(`<blockquote><p>ä»é¶æå»º NcatBot å¼åç¯å¢ç宿´æåã</p></blockquote><hr><h2 id="quick-reference" tabindex="-1"><a class="header-anchor" href="#quick-reference"><span>Quick Reference</span></a></h2><p>以䏿¥éª¤å¯å¨ 5 åéå 宿 NcatBot å¼åç¯å¢æå»ºã</p><h3 id="_1-fork-clone" tabindex="-1"><a class="header-anchor" href="#_1-fork-clone"><span>1. Fork & Clone</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 1. å¨ GitHub ä¸ Fork https://github.com/ncatbot/ncatbot</span></span> 2<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 2. Clone å°æ¬å°</span></span> 3<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> clone</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> https://github.com/</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"><</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">ä½ çç¨æ·</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">å</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">></span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">/ncatbot.git</span></span> 4<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">cd</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ncatbot</span></span> 5<span class="line"></span> 6<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 3. æ·»å 䏿¸¸è¿ç¨ä»åº</span></span> 7<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> remote</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> add</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> upstream</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">
7 https://github.com/ncatbot/ncatbot.git</span></span> 8<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> fetch</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> upstream</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_2-å®è£ ä¾èµ" tabindex="-1"><a class="header-anchor" href="#_2-å®è£ ä¾èµ"><span>2. å®è£ ä¾èµ</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> sync</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --extra</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> dev</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p>该å½ä»¤ä¼èªå¨å®æï¼</p><ol><li>å建 <code>.venv/</code> èæç¯å¢</li><li>å®è£ <code>pyproject.toml</code> ä¸çè¿è¡ä¾èµ</li><li>å®è£ å¼åå·¥å ·ï¼pytestãruffãmypyãtoxãpre-commit çï¼</li></ol><h3 id="_3-æ¿æ´»èæç¯å¢" tabindex="-1"><a class="header-anchor" href="#_3-æ¿æ´»èæç¯å¢"><span>3. æ¿æ´»èæç¯å¢</span></a></h3><div class="language-powershell line-numbers-mode" data-ext="powershell" data-title="powershell"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># Windows PowerShell</span></span> 9<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">.venv\\Scripts\\activate.ps1</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># Linux / macOS</span></span> 10<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">source</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .venv/bin/activate</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div><p>æ¿æ´»åç»ç«¯æç¤ºç¬¦åç¼æ¾ç¤º <code>(.venv)</code>ã</p><h3 id="_4-éªè¯å®è£ " tabindex="-1"><a class="header-anchor" href="#_4-éªè¯å®è£ "><span>4. éªè¯å®è£ </span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">python</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -c</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">import ncatbot; print('ncatbot å¯ç¨')</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span> 11<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pytest</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --version</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_5-å®è£ -pre-commit-é©å" tabindex="-1"><a class="header-anchor" href="#_5-å®è£ -pre-commit-é©å"><span>5. å®è£ pre-commit é©å</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pre-commit</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> install</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><h3 id="_6-å建åè½åæ¯å¹¶å¼å§å¼å" tabindex="-1"><a class="header-anchor" href="#_6-å建åè½åæ¯å¹¶å¼å§å¼å"><span>6. å建åè½åæ¯å¹¶å¼å§å¼å</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> fetch</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> upstream</span></span> 12<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> checkout</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -b</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> feat/ä½ çåè½æè¿°</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> upstream/main</span></span> 13<span class="line"></span> 14<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># ç¼å代ç ...</span></span> 15<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pytest</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> # è¿è¡æµè¯</span></span> 16<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> add</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .</span></span> 17<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> commit</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -m</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">feat: ä½ çåè½æè¿°</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span> 18<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> push</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> origin</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> feat/ä½ çåè½æè¿°</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>ç¶åå¨ GitHub ä¸å建 Pull Requestï¼ç®æ åæ¯ä¸ºä¸æ¸¸ <code>main</code>ã</p><hr><h2 id="å·¥å ·é¾éæ¥" tabindex="-1"><a class="header-anchor" href="#å·¥å ·é¾éæ¥"><span>å·¥å ·é¾éæ¥</span></a></h2><h3 id="å¿ éå·¥å ·" tabindex="-1"><a class="header-anchor" href="#å¿ éå·¥å ·"><span>å¿ éå·¥å ·</span></a></h3><table><thead><tr><th>
18å·¥å ·</th><th>æä½çæ¬</th><th>说æ</th></tr></thead><tbody><tr><td><strong>Python</strong></td><td>⥠3.12</td><td>æ¨è 3.12 æ 3.13</td></tr><tr><td><strong>uv</strong></td><td>ææ°ç¨³å®ç</td><td>Python å 管çå¨ + èæç¯å¢ç®¡ç</td></tr><tr><td><strong>Git</strong></td><td>⥠2.30</td><td>çæ¬æ§å¶</td></tr></tbody></table><h3 id="å®è£ å½ä»¤" tabindex="-1"><a class="header-anchor" href="#å®è£ å½ä»¤"><span>å®è£ å½ä»¤</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># å®è£ uv â Windows (PowerShell)</span></span> 19<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">powershell</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -ExecutionPolicy</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ByPass</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -c</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">irm https://astral.sh/uv/install.ps1 | iex</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span> 20<span class="line"></span> 21<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># å®è£ uv â Linux / macOS</span></span> 22<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">curl</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -LsSf</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> https://astral.sh/uv/install.sh</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"> |</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665;"> sh</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="çæ¬éªè¯" tabindex="-1"><a class="header-anchor" href="#çæ¬éªè¯"><span>çæ¬éªè¯</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --version</span></span> 23<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">python</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --version</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> # 确认 ⥠3.12</span></span> 24<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --version</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="å¼åå·¥å ·é¾-ç±-uv-sync-extra-dev-èªå¨å®è£ " tabindex="-1"><a class="header-anchor" href="#å¼åå·¥å ·é¾-ç±-uv-sync-extra-dev-èªå¨å®è£ "><span>å¼åå·¥å ·é¾ï¼ç± <code>uv sync --extra dev</code> èªå¨å®è£ ï¼</span></a></h3><table><thead><tr><th>å·¥å ·</th><th>ç¨é</th></tr></thead><tbody><tr><td><strong>pytest</strong></td><td>æµè¯æ¡æ¶</td></tr><tr><td><strong>ruff</strong></td><td>代ç lint + æ ¼å¼å</td></tr><tr><td><strong>mypy</strong></td><td>éæç±»åæ£æ¥</td></tr><tr><td><strong>tox</strong></td><td>å¤çæ¬æµè¯</td></tr><tr><td><strong>pre-commit</strong></td><td>Git æäº¤åèªå¨æ£æ¥</td></tr><tr><td><strong>codespell</strong></td><td>æ¼åæ£æ¥</td></tr></tbody></table><hr><h2 id="常ç¨å¼åå½ä»¤" tabindex="-1"><a class="header-anchor" href="#常ç¨å¼åå½ä»¤"><span>常ç¨å¼åå½ä»¤</span></a></h2><h3 id="ä»£ç æ ¼å¼å䏿£æ¥" tabindex="-1">
24<a class="header-anchor" href="#ä»£ç æ ¼å¼å䏿£æ¥"><span>ä»£ç æ ¼å¼å䏿£æ¥</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># Ruff lintï¼èªå¨ä¿®å¤ï¼</span></span> 25<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ruff</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> check</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --fix</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .</span></span> 26<span class="line"></span> 27<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># Ruff æ ¼å¼å</span></span> 28<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ruff</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> format</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .</span></span> 29<span class="line"></span> 30<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># ç±»åæ£æ¥</span></span> 31<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> mypy</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ncatbot/</span></span> 32<span class="line"></span> 33<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># æ¼åæ£æ¥</span></span> 34<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> codespell</span></span> 35<span class="line"></span> 36<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># pre-commit å ¨éè¿è¡</span></span> 37<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pre-commit</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --all-files</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="æµè¯" tabindex="-1"><a class="header-anchor" href="#æµè¯"><span>æµè¯</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># è¿è¡å ¨é¨æµè¯ï¼å«è¦ççï¼</span></span> 38<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pytest</span></span> 39<span class="line"></span> 40<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># è¦çç详æ </span></span> 41<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pytest</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --cov=ncatbot</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --cov-report=term-missing</span></span> 42<span class="line"></span> 43<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># å¤çæ¬æµè¯ï¼toxï¼</span></span> 44<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> tox</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> # å ¨é¨çæ¬</span></span> 45<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> tox</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -e</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> py312</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> # ä» Python 3.12</span></span> 46<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> tox</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -e</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> py313</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> # ä» Python 3.13</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>è¦çç HTML æ¥åè¾åºå° <code>htmlcov/</code>ï¼æµè§å¨æå¼ <code>htmlcov/index.html</code> æ¥çã</p></blockquote><h3 id="ä¾èµç®¡ç" tabindex="-1"><a class="header-anchor" href="#ä¾èµç®¡ç"><span>ä¾èµç®¡ç</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># æ·»å ä¾èµåéæ°éå® + 忥</span></span> 47<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> lock</span></span> 48<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> sync</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --extra</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> dev</span></span> 49<span class="line"></span> 50<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># å级ææä¾èµ</span></span> 51<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> lock</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --upgrade</span></span> 52<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> sync</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --extra</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> dev</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><table><thead><tr><th>
52æä»¶</th><th>ä½ç¨</th></tr></thead><tbody><tr><td><code>pyproject.toml</code></td><td>å®ä¹é¡¶å±ä¾èµï¼å®½æ³çæ¬èå´ï¼</td></tr><tr><td><code>uv.lock</code></td><td>èªå¨çæç精确éå®çæ¬ï¼çº³å ¥çæ¬æ§å¶ï¼</td></tr></tbody></table><h3 id="项ç®ç»æéè§" tabindex="-1"><a class="header-anchor" href="#项ç®ç»æéè§"><span>项ç®ç»æéè§</span></a></h3><div class="language-text line-numbers-mode" data-ext="text" data-title="text"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>ncatbot/</span></span> 53<span class="line"><span>âââ adapter/ åè®®éé å¨ï¼NapCatãMockï¼</span></span> 54<span class="line"><span>âââ api/ Bot API å°è£ ï¼IAPIClient / BotAPIClientï¼</span></span> 55<span class="line"><span>âââ app/ åºç¨ç¼æå±ï¼BotClient çå½å¨æç®¡çï¼</span></span> 56<span class="line"><span>âââ cli/ å½ä»¤è¡å·¥å ·ï¼ncatbot run / dev / config / pluginï¼</span></span> 57<span class="line"><span>âââ core/ æ ¸å¿å¼æï¼Dispatcher äºä»¶åå / Registry å¤ç卿³¨åï¼</span></span> 58<span class="line"><span>âââ event/ äºä»¶å®ä½ï¼MessageEvent / NoticeEvent / RequestEventï¼</span></span> 59<span class="line"><span>âââ plugin/ æä»¶æ¡æ¶ï¼NcatBotPlugin / Mixin / Loaderï¼</span></span> 60<span class="line"><span>âââ service/ æå¡å±ï¼RBAC / Schedule / FileWatcherï¼</span></span> 61<span class="line"><span>âââ testing/ æµè¯å·¥å ·ï¼TestHarness / æ°æ®å·¥åï¼</span></span> 62<span class="line"><span>âââ types/ Pydantic æ°æ®æ¨¡åï¼æ¶æ¯æ®µ / äºä»¶æ°æ® / æä¸¾ï¼</span></span> 63<span class="line"><span>âââ utils/ å ¬å ±å·¥å ·ï¼æ¥å¿ / é ç½® / ç½ç» / é误å®ä¹ï¼</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div>`,43)),i("p",null,[s[1]||(s[1]=a("忍¡å详ç»èè´£ä¸æ°æ®æµåé ")),t(n,{to:"/notes/guide/11.%20%E6%9E%B6%E6%9E%84%E4%B8%8E%E6%A6%82%E5%BF%B5/1.%20%E6%9E%B6%E6%9E%84%E6%80%BB%E8%A7%88.html"},{default:e(()=>s[0]||(s[0]=[a("æ¶æææ¡£")])),_:1}),s[2]||(s[2]=a("ã"))]),s[13]||(s[13]=l(`<h3 id="代ç è§è鿥" tabindex="-1"><a class="header-anchor" href="#代ç è§è鿥"><span>代ç è§è鿥</span></a></h3><ul><li>éµå¾ª <strong>PEP 8</strong>ï¼Ruff èªå¨æ ¼å¼åï¼</li><li><strong>尽鿷»å ç±»åæ³¨è§£</strong>ï¼å°¤å ¶æ¯å½æ°ç¾ååè¿åå¼</li><li>è¡å°¾ç»ä¸ <strong>LF</strong>ï¼pre-commit èªå¨è½¬æ¢ï¼</li><li>æäº¤ä¿¡æ¯éµå¾ª <a href="https://www.conventionalcommits.org/zh-hans/v1.0.0/" target="_blank" rel="noopener noreferrer">Conventional Commits</a>ï¼<code><type>(<scope>): <description></code></li></ul><table><thead><tr><th>ç±»å</th><th>说æ</th><th>示ä¾</th></tr></thead><tbody><tr><td><code>feat</code></td><td>æ°åè½</td><td><code>feat: æ·»å æ¶æ¯æ¤ååè½</code></td></tr><tr><td><code>fix</code></td><td>Bug ä¿®å¤</td><td><code>fix(api): ä¿®å¤æ¶æ¯éåæº¢åº #123</code></td></tr><tr><td><code>docs</code></td><td>ææ¡£åæ´</td><td><code>docs: æ´æ°å®è£ æå</code></td></tr><tr><td><code>refactor</code></td><td>éæ</td><td><code>refactor(core): ç®åäºä»¶ååé»è¾</code></td></tr><tr><td><code>test</code></td><td>æµè¯</td><td><code>test: è¡¥å Registry åå æµè¯</code></td></tr><tr><td><code>chore</code></td><td>æå»º/å·¥å ·</td><td><code>chore: å级 ruff çæ¬</code></td></tr></tbody></table><h3 id="忝å½å" tabindex="-1"><a class="header-anchor" href="#忝å½å"><span>忝å½å</span></a></h3><table><thead><tr><th>
63åç¼</th><th>ç¨é</th><th>示ä¾</th></tr></thead><tbody><tr><td><code>feat/</code></td><td>æ°åè½</td><td><code>feat/message-recall</code></td></tr><tr><td><code>fix/</code></td><td>Bug ä¿®å¤</td><td><code>fix/queue-overflow</code></td></tr><tr><td><code>docs/</code></td><td>ææ¡£</td><td><code>docs/plugin-guide</code></td></tr><tr><td><code>refactor/</code></td><td>éæ</td><td><code>refactor/dispatcher</code></td></tr><tr><td><code>test/</code></td><td>æµè¯</td><td><code>test/registry-unit</code></td></tr></tbody></table><h3 id="pr-æè¿°æ¨¡æ¿" tabindex="-1"><a class="header-anchor" href="#pr-æè¿°æ¨¡æ¿"><span>PR æè¿°æ¨¡æ¿</span></a></h3><div class="language-markdown line-numbers-mode" data-ext="markdown" data-title="markdown"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#999999;--shiki-light-font-weight:bold;--shiki-dark:#666666;--shiki-dark-font-weight:bold;">##</span><span style="--shiki-light:#1C6B48;--shiki-light-font-weight:bold;--shiki-dark:#4D9375;--shiki-dark-font-weight:bold;"> åæ´è¯´æ</span></span> 64<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"><!-- ç®è¦æè¿°æ¬æ¬¡åæ´çå 容å卿º --></span></span> 65<span class="line"></span> 66<span class="line"><span style="--shiki-light:#999999;--shiki-light-font-weight:bold;--shiki-dark:#666666;--shiki-dark-font-weight:bold;">##</span><span style="--shiki-light:#1C6B48;--shiki-light-font-weight:bold;--shiki-dark:#4D9375;--shiki-dark-font-weight:bold;"> åæ´ç±»å</span></span> 67<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] æ°åè½ (feat)</span></span> 68<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] Bug ä¿®å¤ (fix)</span></span> 69<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] ææ¡£æ´æ° (docs)</span></span> 70<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] éæ (refactor)</span></span> 71<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] æµè¯ (test)</span></span> 72<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] å ¶ä» (chore / style / perf)</span></span> 73<span class="line"></span> 74<span class="line"><span style="--shiki-light:#999999;--shiki-light-font-weight:bold;--shiki-dark:#666666;--shiki-dark-font-weight:bold;">##</span><span style="--shiki-light:#1C6B48;--shiki-light-font-weight:bold;--shiki-dark:#4D9375;--shiki-dark-font-weight:bold;"> å ³è Issue</span></span> 75<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"><!-- Closes #xxx æ Refs #xxx --></span></span> 76<span class="line"></span> 77<span class="line"><span style="--shiki-light:#999999;--shiki-light-font-weight:bold;--shiki-dark:#666666;--shiki-dark-font-weight:bold;">##</span><span style="--shiki-light:#1C6B48;--shiki-light-font-weight:bold;--shiki-dark:#4D9375;--shiki-dark-font-weight:bold;"> æ£æ¥æ¸ å</span></span> 78<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] 代ç éè¿ </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">\`</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">uv run pytest</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">\`</span></span> 79<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] 代ç éè¿ </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">\`</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">uv run ruff check .</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">\`</span></span> 80<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] 已添å / æ´æ°ç¸å ³æµè¯ï¼å¦éç¨ï¼</span></span> 81<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#D4976C;">-</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> [ ] å·²æ´æ°ç¸å ³ææ¡£ï¼å¦éç¨ï¼</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="pr-æäº¤å" tabindex="-1"><a class="header-anchor" href="#pr-æäº¤å"><span>PR æäº¤å</span></a></h3><ul><li><strong>CI æ£æ¥</strong>ï¼GitHub Actions èªå¨è¿è¡ lintãæµè¯åå¤çæ¬éªè¯</li><li><strong>Code Review</strong>ï¼ç»´æ¤è 审é 代ç ï¼å¯è½è¦æ±ä¿®æ¹</li><li><strong>忥䏿¸¸</strong>ï¼å¦æ PR åå¨å²çªï¼</li></ul><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> fetch</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> upstream</span></span> 82<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> merge</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> upstream/main</span></span> 83<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># è§£å³å²çªå</span></span> 84<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> add</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .</span></span> 85<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> commit</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -m</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">chore: å并䏿¸¸åæ´</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><hr><h2 id="æ·±å ¥é 读" tabindex="-1"><a class="header-anchor" href="#æ·±å ¥é 读"><span>æ·±å ¥é 读</span></a></h2>`,12)),i("table",null,[s[11]||(s[11]=i("thead",null,[i("tr",null,[i("th",null,"ææ¡£"),i("th",null,"å 容")])],-1)),i("tbody",null,[i("tr",null,[i("td",null,[t(n,{to:"/notes/contributing/1.%20%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/1.%20%E9%AB%98%E7%BA%A7%E8%AE%BE%E7%BD%AE.html"},{default:e(()=>s[3]||(s[3]=[a("é«çº§å¼åç¯å¢")])),_:1})]),s[4]||(s[4]=i("td",null,"IDE é ç½®ï¼VSCode settings.jsonï¼ãè°è¯é ç½®ï¼launch.jsonï¼ãCI/CD æ¬å°æ¨¡æãNapCat æ¬å°é¨ç½²ã常è§é®é¢ææ¥",-1))]),i("tr",null,[i("td",null,[t(n,{to:"/notes/guide/11.%20%E6%9E%B6%E6%9E%84%E4%B8%8E%E6%A6%82%E5%BF%B5/1.%20%E6%9E%B6%E6%9E%84%E6%80%BB%E8%A7%88.html"},{default:e(()=>s[5]||(s[5]=[a("æ¶ææ»è§")])),_:1})]),s[6]||(s[6]=i("td",null,"é¡¹ç®æ´ä½æ¶æã模åèè´£ãæ°æ®æµä¸çå½å¨æ",-1))]),i("tr",null,[i("td",null,[t(n,{to:"/notes/contributing/2.%20%E8%AE%BE%E8%AE%A1%E5%86%B3%E7%AD%96/"},{default:e(()=>s[7]||(s[7]=[a("设计å³ç")])),_:1})]),s[8]||(s[8]=i("td",null,"å ³é®è®¾è®¡å³çä¸åè",-1))]),i("tr",null,[i("td",null,[t(n,{to:"/notes/contributing/3.%20%E6%A8%A1%E5%9D%97%E5%86%85%E9%83%A8%E5%AE%9E%E7%8E%B0/"},{default:e(()=>s[9]||(s[9]=[a("模åå é¨å®ç°")])),_:1})]),s[10]||(s[10]=i("td",null,"忍¡åå é¨å®ç°ç»è",-1))])])])])}const g=d(k,[["render",c],["__file","index.html.vue"]]),v=JSON.parse('{"path":"/contributing/afd9taf5/","title":"å¼åç¯å¢æå»º","lang":"zh-CN","frontmatter":{"title":"å¼åç¯å¢æå»º","createTime":"2026/03/19 17:26:45","permalink":"/contributing/afd9taf5/","de
85scription":"ä»é¶æå»º NcatBot å¼åç¯å¢ç宿´æåã Quick Reference 以䏿¥éª¤å¯å¨ 5 åéå
宿 NcatBot å¼åç¯å¢æå»ºã 1. Fork & Clone 2. å®è£
ä¾èµ 该å½ä»¤ä¼èªå¨å®æï¼ å建 .venv/ èæç¯å¢ å®è£
pyproject.toml ä¸çè¿è¡ä¾èµ å®è£
å¼åå·¥å
·ï¼pytestãruffãmypyãtoxãpre-...","head":[["meta",{"property":"og:url","content":"http://docs.ncatbot.xyz/contributing/afd9taf5/"}],["meta",{"property":"og:site_name","content":"NcatBot ææ¡£"}],["meta",{"property":"og:title","content":"å¼åç¯å¢æå»º"}],["meta",{"property":"og:description","content":"ä»é¶æå»º NcatBot å¼åç¯å¢ç宿´æåã Quick Reference 以䏿¥éª¤å¯å¨ 5 åéå
宿 NcatBot å¼åç¯å¢æå»ºã 1. Fork & Clone 2. å®è£
ä¾èµ 该å½ä»¤ä¼èªå¨å®æï¼ å建 .venv/ èæç¯å¢ å®è£
pyproject.toml ä¸çè¿è¡ä¾èµ å®è£
å¼åå·¥å
·ï¼pytestãruffãmypyãtoxãpre-..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2026-04-17T14:13:00.000Z"}],["meta",{"property":"article:modified_time","content":"2026-04-17T14:13:00.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"å¼åç¯å¢æå»º\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2026-04-17T14:13:00.000Z\\",\\"author\\":[]}"]]},"headers":[],"readingTime":{"minutes":4.32,"words":1296},"git":{"updatedTime":1776435180000,"contributors":[{"name":"GEYUANwuqi","username":"GEYUANwuqi","email":"[email protected]","commits":1,"avatar":"https://gravatar.com/avatar/1cf26d82e91dff657f3fa4d4911cdabcf7b76396339e886e69f99b15d4c8c808?d=retro"}]},"autoDesc":true,"filePathRelative":"notes/contributing/1. å¼åç¯å¢/README.md"}');export{g as comp,v as data};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.