From 46ea8a929662faf87c90bc0e9f5b6928fc47ba4c Mon Sep 17 00:00:00 2001 From: Alex Cube Date: Wed, 26 Aug 2026 16:47:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=BA=D0=BD=D0=BE=20=D1=81=20=D0=B8?= =?UTF-8?q?=D0=BD=D0=B4=D0=B8=D0=BA=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D1=87=D1=91=D1=80=D0=BD?= =?UTF-8?q?=D0=BE=D0=B9=20=D0=BA=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Маленькое окно на C#, собирается компилятором из состава Windows: ставить нечего, зависимостей нет — как и у всего остального в проекте. Запускает node дочерним процессом, показывает его вывод, прячется в трей, красит значок по /api/state. Node теперь уходит вместе с окном: окно держит его stdin, server.mjs при DEEPSEEK_TRAY=1 слушает close на этой трубе. Job Object не подошёл бы — он забрал бы с собой и браузер, который человеку нужен. Окно смотрит на checked, а не только на ready: снимок обновляет сторож, и без этой проверки окно показывало бы «готов» через секунду после смерти браузера. Поэтому /api/state отдаёт ещё и watchdogSec. Co-Authored-By: Claude Opus 5 --- .gitignore | 3 + README.md | 60 ++++++++-- build.cmd | 15 +++ icon.png | Bin 0 -> 70067 bytes server.mjs | 10 +- tray.cs | 335 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 414 insertions(+), 9 deletions(-) create mode 100644 build.cmd create mode 100644 icon.png create mode 100644 tray.cs diff --git a/.gitignore b/.gitignore index de7dc7d..db9ce6d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ chats.json # Свой на каждой машине: пути к браузеру и профилю. config.local.json + +# Собирается из tray.cs командой build.cmd — в репозиторий не идёт. +*.exe diff --git a/README.md b/README.md index 19cee54..e951e89 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + # deepseek-api **DeepSeek, притворяющийся Ollama.** @@ -29,13 +31,14 @@ 1. [Что понадобится](#что-понадобится) 2. [Установка по шагам](#установка-по-шагам) -3. [Проверка, что всё работает](#проверка-что-всё-работает) -4. [Как подключить свою программу](#как-подключить-свою-программу) -5. [Что умеет и чего не умеет](#что-умеет-и-чего-не-умеет) -6. [Настройка](#настройка) -7. [Если не работает](#если-не-работает) -8. [Безопасность](#безопасность) -9. [Как это устроено внутри](#как-это-устроено-внутри) +3. [Окно с индикатором](#окно-с-индикатором) +4. [Проверка, что всё работает](#проверка-что-всё-работает) +5. [Как подключить свою программу](#как-подключить-свою-программу) +6. [Что умеет и чего не умеет](#что-умеет-и-чего-не-умеет) +7. [Настройка](#настройка) +8. [Если не работает](#если-не-работает) +9. [Безопасность](#безопасность) +10. [Как это устроено внутри](#как-это-устроено-внутри) --- @@ -135,6 +138,9 @@ start.cmd Это окно должно оставаться открытым — пока оно живо, работает и сервис. Останов — `Ctrl+C` или просто закрыть окно. +Чёрная консоль не обязательна: рядом лежит окно с индикатором в трее — +см. [Окно с индикатором](#окно-с-индикатором). + ### Шаг 5. Войти в DeepSeek Браузер поднимается сам, но в пустом профиле вы ещё не залогинены. Дайте @@ -160,6 +166,43 @@ curl http://localhost:11500/api/tags --- +## Окно с индикатором + +Тем, кому чёрная консоль мешает, есть маленькое окно: тот же вывод, но +сворачивается в трей, а цвет значка показывает состояние сервиса. + +```cmd +build.cmd +deepseek-api.exe +``` + +`build.cmd` собирает `deepseek-api.exe` (около 20 КБ) компилятором C# из +состава Windows — `csc.exe`, он есть на любой машине с .NET Framework 4. +Ставить ничего не нужно, прав администратора тоже. Сам `.exe` в репозиторий +не кладётся: собирается за секунду. + +Окно запускает `node server.mjs` дочерним процессом и показывает его вывод. +Крестик прячет окно в трей, выход — из меню значка. Node уходит вместе с окном +в любом случае, даже если окно снять диспетчером задач; браузер переживает — +он отдельный процесс и нужен вам. + +Цвет значка: + +| Цвет | Что значит | +|---|---| +| зелёный | готов, вопросы принимаются | +| синий | идёт запрос: в подсказке — сколько секунд и длина очереди | +| жёлтый | браузер есть, а вкладки с чатом нет; или сервер не отвечает | +| красный | браузер не отвечает; текст беды — в подсказке и всплывающей записке | +| серый | node не запущен или снимок состояния устарел (сторож молчит) | + +Второй запуск не поднимает второй сервер, а разворачивает уже открытое окно — +заодно не будет `EADDRINUSE`. + +`start.cmd` никуда не делся: он для запуска без графики. + +--- + ## Проверка, что всё работает Откройте **вторую** командную строку (первая занята сервисом): @@ -423,7 +466,8 @@ POST /api/chat | `browser.mjs` | всё про браузер: CDP, разметка DeepSeek, отправка, ожидание ответа, чаты | | `config.json` | настройки; `config.local.json` рядом перебивает их | | `chats.json` | рабочее состояние: id живых чатов (заводится сам) | -| `start.cmd` | запуск | +| `start.cmd` | запуск в консоли | +| `tray.cs`, `build.cmd` | окно с индикатором в трее; `.exe` собирается на месте | | `test.mjs` | проверка перевода формата, браузер не нужен | Зависимостей нет — только то, что есть в Node 22. diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..84e7e4e --- /dev/null +++ b/build.cmd @@ -0,0 +1,15 @@ +@echo off +rem ASCII only - cmd.exe reads .cmd in the system codepage, not UTF-8. +rem Builds deepseek-api.exe from tray.cs with the C# compiler shipped in Windows. +setlocal +set CSC=%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe +if not exist "%CSC%" set CSC=%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe +if not exist "%CSC%" ( + echo csc.exe not found. .NET Framework 4.x is required. + exit /b 1 +) +"%CSC%" /nologo /target:winexe /optimize+ /out:"%~dp0deepseek-api.exe" ^ + /r:System.dll /r:System.Drawing.dll /r:System.Windows.Forms.dll ^ + /r:System.Web.Extensions.dll "%~dp0tray.cs" +if errorlevel 1 exit /b 1 +echo Built: %~dp0deepseek-api.exe diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..31e9f3bd021a68faf4d305ecc91ceb9ee5b976e1 GIT binary patch literal 70067 zcmeFZbx_++_b*P1JH_4IU4j*NcPS7wxE6vJcb8I%Yl{?@7AP()kd^|WxCDwfxXVpH zkI(PU{N_7z@67$kvl0??wN-GjD6x=`kZ{#h74?yjo**8dAYq^( z-Yk9IIU?Q$gA7gm^nn5NUOt|V&TbC$et}*N^bTNWL?(E_U3U?8kRIpGDKT}8Y$#cQ zkn?3!sx^_MUVKpIH}qI!$#eL2p%rp;CNrP83x`cQXHGsQs){7J9G*->|8&?VW;4g} z15_UG{iV?_XpL{aiZLyhH9}%Ii`3|pHxowFVpj&=#Xid-sdYuh$C!z1KR0sTSgosI48}8X3K-}(kokJiSYI9;o%0T~EPcC|P|hy2JG_X=cN^ z3FSjTrCE0Cu>jNc?qRcf5!1_}yO@Zw_RKB7BqnoHH1Q7thVlqbmqvn8Bc@@+*b5@w zhjf@umIkW{NisF|JB66dtNzEefDT7z|EervRir4s_Im-$EB^@p>Gs|<_pZ>V;Nl3b z`t62}S3lWyCyPjBo+@`lB<&Zm!k@gB?7Pb1rO0FobjGSAJPK1@HAEWmh$wB-_FN7v zkU^5zbGb$n7e}f3n%(pJ#3MZ1^Ra06;u2X7&F4BM_N5)d?);q*_GPN239$2Y=LOn( z+B)!p-MtWohlC_03-$uqxjOjK+d4Qodq^|FyLuVvo$aL=O+>W#wY(G@K+dW`J`M&! z+J<&Pu67dkjIuIVQeXfAz}>+QNDp>*^Y8_Lr5XRi1t6aPB=a%S|0Uw*D$QuBrAx2i z>El2z%qz^x&!Yr(_7`N7!J?P)v3CUMD=PmT0`WoZg2ngT}5aRXpapDt@ zkdWZx7vvKZTzD$20{)VCG;A`jO?B(a|=|TSo6KL!C(odR^5s^>- zkM_BHX=(iv-oy9rEFk#c0|UMI1bF%R+}-*9y@aoyl0O3E?+yCjmhd%1xGA5$gRkdH zA3Fyne+LggrhkX9xBF*#ua`bMdqWV#|B3q_(*Mx?FJXj~mKH$K)9&S;=BX)4GybU` zVDD+?Y!CSBQP4q96ewXQ$|EK!WX~fkBEZihF5)Q8qMG6yO)(5fi9PZ9Uo_e zRRZ1qy;Xmp>=975h;jmAcJ_!i*bDIpOE@A>B={Y99PAt&1#QJ0>_mj^|AMl&11Nj? zxC0U0>Ff@4a^UmwaQZ9b58(hgT{US&L0`>!lRXLkn! zKj0re1;oU~#Dv8}#Y6=KM1(~||0QJX;Ny$1#XqP5{JcWqf93q?7yv>Y1hv3FmWlxQ zD;=Q?K*7fW=;!HU=;`Su&G@HL^nXhJGg}McQ1(DSpd!%E0RhS{C<@>g2MCH93WxxN zgaJZ=T>L@+{(qDAw0Cw4{Qr~w<399Kf9rHrXJ179fqy0a&8G|;y#My;Zy(*9|8gdJ z`oG))0JQs?3cf&phre-*!1`O39SG>*%f9^u-; zA|ir3Ksy0Z9#L^e0ei%Yn4pN=Uo89+-PhC6F97J{Am@bO5y2J0K>y;3p8fA##qpo= z0U(Dz{eYm12VrUdqD+*L@9)a;{TVU-p{*3(|A!B$zXbkmh(VP5TN+~MLX3ob{~QYc z&KIJs|2KdB-VgsbtDvXR3<+>BodpI`9MKOt=AUM}HstovUP(&tIZ%h&p@6MAC081cx)bsJV+?SAunHnbEg>L?K^mc`dl?TV z#z|rcY~5D@=R1ixr>zxTrkh)90UQO3^Fa+r*`NaAHJp_w7A1l@^12RoI-H0O zyh@a9=@oND6kTwG7o^OKo)#YrXL}HLI%cmkVn?;2UI`u;mmU#r+<-MnLC~0x<*Uv| z)ET*wmL58T^}jWIVms$vb^4~{I^JbY`HJvue`1c#&TJ@hm*h6y$;$72??u-sU-#11 z;~1i6-q7(YyoT(NkJMfmShd2C2(lIS| z1S(N?Nxok;h0*odmo|ppws8fv)H$UKhBsQR*U6bhd1E=zL{deBXgOKj;`a0ycpm;P zyi4lww`y(f-miRe6*tlV5Aw?8NR%Eu`8AFrfurY3ZFPi1+JI8<)XAGR`y!sby9Gqp z2MaN6rHwhodX{vKS1AQGt8=n_4IP1XD;Rd3YCq>DitS4p8g?UKGtKb2+aXD&8>J$k zhFTPKtUGD1*AL!!N!j^yvnLBM%rr`T#n$HN?nt?CIbYX)aUG_kvxtu`b5#=ewYpRo z>5-uGz9_g_m}=6l9>%^s8v*&~Uws6T&|?Iu;ATi(c?Gv(lo7{pJ*O@sCMJ}Ag8HgW zG%QkqWB4lE-Dg*!jF0=G@v0C!^eo^i9S23O8yB0Bf2Bn82u%tPjv6A2V%iNZc)2$4 z?P$vP2u~og2@TEzrAlrBlUP-E%eVFY_$uj|Ly{HD`a;n4qHcUITG{t9J?~>oTCTO>(=#F+SO`C5nS<@Kq&YAjJM~JeRK)pI z34y;q8!6n*qc64~@{~4dltV7RUvf-~-x4~n`_c>VSca92#1_d@Rmfm?Hz2$aTUa1LR!zD_a!}+ojm!E2_DEtUFRd(ZWW3+ z`gIZLdSg6(mG*m^iSA2#H5b8pzI?HO@uaHri>1cJ50beB(La#x&S4`K;mcO!0bt-V zMGR2o*|TkGM$$@QMY51Pxnk8ui8yt_Wby1{8)f$#We1C(={&BmGF@7U8Q!Z?Vqy3a7pGDbB6z2b$$*l;5dCyp`s>KmYEbtTCLfC- z<_0`jrFGyFK@qv@vtuwBVRDLN))Gbcxs3xO^YKdD<#S>7Yejwi_r%uZ#E^iOe%$b# z-#2>|D_^W7PfA#rwhW9Bh5=YQ|6Xn&=4Se+Q^mdl>t6klFd`Y{+plCy=&}#n5}g50 z9F)6y$O)?{O)buAdFqfA($LuFU|kWzxkn_Z8Gad~HR9>X1APlHu=q!!U#xcO<{Aj< zL8m#NkhwfmVH97!tuCUkxO_fbC?1Uwc_|vrVAa<(#-SU33C0Y0Vn?%L+AW^k5wCCR zsjB-fk4rT(dTEnbNv?JaBuYgN<7Xu&CL6?q!G*)N(u2No8arTZTFz(AJlvr*$RFv2?a&uQ!h&dbLnDoq)N9_B@%x)yviJRaegU zyts1CNDs}O=j|5l0t{hzyaDl(!?#}4`>awp2_HVCsVVT- zJb?j+rx{RGv*j_G5<1hdkD?WUU|nhmQKr8@Yh$M_nqPmM*Vnl2R|%z2j8y_+feaf8 z4+j8@6 zIXVsqeeS;WNO}|(c1*-6zr7eDtuhEC*lzm#dOAzl}1xiu=ebSaAklG751-* z(&}JA=d!-I7Ym&Pb{1325IY`X?+gyAJV zAum-FT`(5@Q>*)_6HS@Xm;*8Dq+?c4k9Lb0%HXcFvL$;077;^^DUm$2lUmz}L6zq1 zwLf;p!_No4z^R7u>Q-SSK5>s;c*KX&(u}lJk^E|Mc-L@*0WC{3cRRkBd%c0>QvEUT zao??>*``)P^Q~xI*N%|sWcH<-!smqf*wegsy`Py*SZ75si8j; z@)pg+^k~nHQ#gMYJr$p_hYH2oZ3%JN<>)CnrmNtXl5GU?_49K?R9zZsvE!RNsSUwU zec-GZY9q=pd->G}8a^VyqO)WP0zPq~Q#!)T2w2e*@W`H)s0Vcwd!j10V9DT1A809m zCm6Tx6jb?+Ge>9lO~}+m5@}%@e5Fg;N~R4lzh-$~GT|FRKkSDq_)gqutmipnoL}R_ z8IiJJeho}U-NtIwR``LH2l$v|*3xcs(`wav0;+F(cO(mc9)m_*iBiBMK7kd3!X$6` z9IEm(#ilOUm{f+GcJ%7QyGFgo*7HY@IUL3w_I8;WFg3qFP0nQ zV9#WBaC1wZ%6PVyB0$iuScFm)?=b1bJCa9W6`01S`8e?=OIFBp{}3X%kliT+^sfZCsj@n$%ZTSW@?WdU1Hby`!qD>+KM>F{X_!r>=kDB?ew0^BPV5cMz-& zYh1d0rwqjjS8DNvF=h-y=1ZxCSQr_!#K`7XjG{Gr?Z-Tf?+}w5huFFgT!Om5o2M)z>&MzeZwu4Dy_c zFBY*|pt10ffTyU?wc7_?`@Kf9X#ua5s$`yrGF7{g)7*n zXA`7cM)ao9$Be|=6kv-4k@?_3KlYt=L@-x`(4UEWvYCc3tfND*(`1gB-<3RDv(xDl zZ_%+`?FBbpC4?c>si>GNd#dm|&3y>n>)^sCm52(RWBuVM%H51$gy|cXspKi;( z9X5NdgRWa&qpgM8%)hvVQ0>5Fo$5SNTSyhnva#?>2~mrVUUA5AulcYBXxZK#l1@!8 zCS~bTY7ht(+SJEY(Cbms1X$4|JZFr&GUfD}x=-C|*6Lu+o>LsbeLmLMl?T){Ue_fC z!rrdUQEhv14h;}A$L4-7D3@2}|GZ*{TNkwVo?suw`svB&e0UQX$H4`sFf|3$&sc!r zRg_7jyqk6^{v8@yJYfNcyu6^xGcddR$K`tgRh|Clj}iVjA|01}c;drv7@ufurs0A%_S(1G_>Ov^g>lYwxyt3mI`WmUPPxUw z^nPL?J%qX%IT7E`e!Gz{Rb_&QKEiLa8+(HhTu1U8=AN`PeU!7vc5}a`pwjinVea2Ma!9EXsuvq z1xsf`>d={`SSM}WP!8K~Jpsg3^lF3v)_|7ji=>^y z-O5>VC7>Rl5HvfhM)!eg4L0QH3WE zhLxCKa$C;|OIR3YF&QJF$DM@aiD63wonAaS`V83#Hz;zW^kA;ArLK6a;f;hltTY3> zeOz7P2(HG zt3N|K3PTXRzCsk5CS_&T-}Lh2-Q^Jvz^l zCI-)Rjrhq^DW^J_uRA;JDeHjH`_MDov*`~1^jq4%6Xeo$aqi(KB&&6;yy7EIOlsjv%&DOC*_o+8&?3ajhwTxN&)72_suA_#9J ziwd$>@_LQNVsd^XQ~F}*dZs5}IaCWl3SLu!nB0drdl0Qj zjOlq%ON%Ett;6!olM&^;O{EA5vhkxLDYB7~5z`J2+;4SelP6pF-luk4rU9q3;UshZ zQ!BSEr>TnqcE7kCCklpJIi`1i?>x`!^JtA>(9kdNwa>{GPN3Dtp-JqH3E(y4CpL9u z#nAkDw8|cHjOR*i>+5#L|8!Ygm>)QBJ0&>vR9Z@W==mcO-dN#1-N)?X=J%vZ7Qs|H zQlCQXUrS$voN8Ri9HHMHG^Ze3V-@p5=LPHi+gnfB+bH;bI2?I%6>^Ve;VvSXU1=F1 zf_7x;^fb+yIH}{ska3F>>_zHmw6-{fXA&-cx-pg-A+wgMB|nmS+(JOj%bDHKFqQDZ zHH>{U^m%bXWuXqRu(s4nkSHE*Q_v(OZP1Qb!DCkOVAR~BmeplpF7;Qd;Di1Go^3(9 z8=Qs3#r|#Z_IH5X`(*C%F@2@7r{hf+(c#o+ZttSO+mXMX^s@u9?0(L;&=|(Z^A4)< zBYllI8sMBX?SU+axUz4At|*G5y+!evsmbBG{t{yi{5o-X_l2$JqGh!Ap<>#9!O_tQ zv4Ztp3V*cgS^a!f)=(4*9Zj1*n|>3ruR>Nry(u$lPG<+o`>{N!Ey-P0TgxT5&uzsG zc}|${NhWu{nYllK$$7jF+j)YaB>Jmo{Y?{;964(63?D~G|66&kXCzYSAQkv3L#1=Q z%E9t-x#8}`YT96$Y=lx0Y13A&@6KT%rK%S1CT%k}(|b^MqCK;ncl&cg48FQ^0wrZ` z24=63NX+qhjXHjiEqN(YN|x@xiylXja;8CX;;+~wD77(VMn^F%I%!UMPo}SavaP&4 zEtqdf1MJo}tm+~((<``b^E_Mfh850Pg8Rw*9}ic1wr0|NcjRuTd?ec0k5&YnpxmUM zUDALlc0J*I9>r*8WH`ze%GT33Yeil4a(y`y;;+@rj1^z1mL2TMmBJs9k^yF%) z*-kcI@odGGlMSAoQ5wC+4Uc0n~&k84$lvtRAcvGh}Mvrp(~Bk$5iUq+aB#0PR-4Y9vyjI_27S1xLkfoHuvKA z5UiZ_%A;iXnF{a6Z63DXEt-aqVPHo#+L|ZM`0wx?CF{puO4bj1PLPE_--hcGB@^BK z@Al3EQ0!kqz9X7LL4@_!dnSBqOz?0vq>kmTf{(u2jH31*jMC>=o+;_;y;DRFm1Pn3 zRj^(~Qb496Z;4ejB6tQpKleUuwz%FHmSqY*GsyPUyy zO62?Xm4Qx^&pdw7V}#_6NXU^L+;)zpquRVyPZ)a$@cVw!6MUW7Ble<##tM?}@H!KN zolM1nL(W;rT&)Q@Ez3X9w}zHq)khqm*cvuSk1yLnJzNsmS$8hjtBTQ z(D$8TB!9edzF~ERGuGFQf&_*qL_Gwcl>Xyimqkx%e;0|b#66tL&b$03Ej4^kyb&`> zXED5GVmW!TIGXj|AcC_33*gfF((uiU9x!PIlF`w7KS>uhj@cjyhaUpi!ac2bEMDL5 zw3%4mkDt!fd-}Od9dv^jxL#`^-xQrLScG{Cgn9;&wyua=tE~ z%`*Sd+!WvGSjuZ}NXqLcjoVM+eAgb(1wB_nnrBL1s{V4w;mlEwj8D)qB8|dch}#R7 zS*UlEnabELV9JP|%2;>e2@|b!O^Uu~7yYzYOWgiN0eP@+J9KN&T73J|`pxx2K=0w% z59BMZ;edwDn+c7E&b`*vGh8*+)Wn*`)3R&Lw|cON%kJP7co!^VH1G4UVF>n*rSE<` zR+kr-UgK%Jn4>)xPSowIpFuB5*}192+$ubmgDC4sIcGtY;Gkufu$z|R<3r!aeZHH* zfaOO}syNvC7hm2esZf+$?BKPW*w_Asb$6_H+dB|YAn-F z@yHkLB}wCj;~5I8eOHmuxm9XJzH&b@C$m3B^PEaIVpm%8@UY5=*if;NytS6UP3Sy{ zj8AHxs5*Qzd3X_Wj<8;?{z?-ozO;s*yDZrr|M^iU?p!4>+WcwU?=~XI!)|1?{G(;K z)mYo>u*<;J@SUcH?OL*sj3HOU^5-V{migaTdn0~d_*d!dBciBAk9#!eIW9dEXeR_Y zL8n_QmIbroJX}{lct&*}IFDR1@TdC*#oI10|K>?sW_Z|J zX~;HTXWm@*jd-*16SYJWJnR{Z@;bAQRNIO^fLvxYqB@VRE#rr+a(G~W@3$v>(vf1_ z>$nrv{Aq_Bt3|t6R-G|2+VbtNjZ#IIOe{tkc?{nf?6W{La`L6IL=vv6SzNK>VlvBt z8+6am{)YMel?!cBcq^B?SxiZ7$?m}p{d;CpH(g18IXk)UQtdu0#el<^ZE5HM%|&HL z0M^eExG8b$OXT~KzFK~=CM{yRu+>Emz(rd__* z==e|@7nDx;aNQVc+Ieow>@05q9f{DmD9Zu|I?@1t+E-BD}XORuBP!9ot| zd}=jj4}F6NAE!UR{dny)dK&=H?pG!T0NSRpL=c2Ht}w zo0qkEC5pH3NdF6xcXRvk=W{MGo5(9C2HvlsT%uo)(SOzT#~N{!zK?ykCK=XJ?@P2L z#CZDMJV{;Nspt~RVIrDXqG=mR_5&XE!RQs(d)s~Ir7Fp+OO8u!MkUF@qU1Znmu}%J zQp%LMBxy1bgvEUoyz`h8q1qyjjMT* z)u1rDyVSJC?G;G@Ve_MDu7=Gov-@M5?h%u_QcQz`Ztuht;@BlTxVKv#Px>9usT<+X zBt1ILbrB{d-?WZue)cOg$u~E3z?j8w4d-12YR}1 z(pfl$Rim)^dXf!RFJdQYZ_k9jt(Pd^Gpcc&HPCG~(^>T^S>H?)`+cSZ+-v62USj$G z^hU1{SSTj{xC_9&;<)mM#;4$K&c%S!*B#4`O)7B~$t0-~S+(8QTj)Pl=2P29dGZJG zR$iM4Ij-sMXsQ}$DG6UbI+DP_k8hSPvL>Axde7=LOvB*!1;LOv;b#&>fzWWD&8fJS zj{rL8=8bYXV=< zkM(6~cQi~Jd1H|XapIF~3zFd%-+qt?i~4P;5fh##cl=VHLBUB{S)kWe7giVLq%fme zjAcm{*Xb$o8yLBv*SH9J##VG^l`63ZYB%e|ZP}iv$bIHS8)rc4Ci?LfB6+nk{Q5M9 zFXSTaGudbX7)$b?k*N5lPg3+Ye;NXK{qeLKhOM$LJXtpUDdI_(*L)7KQj%gbf1nwr z!XOh)+X#Cd(@XhZYcRU7+ewYI@X7Ix0;q@~VsDoTa(58uWaTr-Q@z|PLq;iKz(!IK zbl2oJ%Q=%$&7Mykv?epL?1J4oeZ`EubfT!Ip|7lBVHr3%S#b3=%KFGx^7;_|t9a#1 z=iuY$?}~4}4i+&Eb@KznO4;X7pi`QND?Cb+&RpIA8#p>gXw8OI|5A4^q33o;=`e%d znZUxMNA;kZ&Sdo*>^d-02X^Aju8j%8ijY)Y=_>z-it>@{uZrdjdrS@nbCn0&a9W}ik_$Sj5R-NL0#SLk`8 zF7W}s6Iz3`kF1~(uue}!b>8*z@J)w}hB+j`;Xa&NVrJ$g4u=mSuYC>cBv&obEy-v(o zc$A!)3JCU#UN6l!YP7&sA|y{uV63e&bP-`~Gs>HpRZ=k_bEk1{?FjfWzoPAAB8He? zF3eNZE1xPwh)IwVK@>Rz#bkckPxs+dIT12rnBRX6PIcTO(y>V_P?U3WqIywCW5^}K zsuAS>Zcw%SOL=XPfPLQc< zo^&v29L*8ohlefqyd`^ld(T`5wgEG5w~g{#M?tm%dbfRiwQj2lMc`WD@PB3q}{A)T@9fEu1GS%tQe#> z&~*D(M-zM1;Jbv;t80<*tBX0AOA8gNz6SX9v%n&|V`Au9Qs4cz8WF^lpC=k9ILn=) z??JH-t=n=ku^Nn%J-b-Fy*nrE^4(L@;7A^jD9sQ01zAiKo^Cx+1`+YO?Z{7H|L(ec z@}c)!rpmuHs{%8Dv=u6>G6J>@l~wZS$K+cGW34U<+G9(T+^Z~R$L%Z5KknT~WLfRn zRFSd#rt!*-A z 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 iBGls%+A*@pl_g2B_(&t;ucLK6Ujh=q#) literal 0 HcmV?d00001 diff --git a/server.mjs b/server.mjs index 6ee50c7..d501aba 100644 --- a/server.mjs +++ b/server.mjs @@ -218,7 +218,7 @@ const server = createServer(async (req, res) => { ...state, seconds: state.busy && state.since ? Math.round((Date.now() - state.since) / 1000) : 0, host: cfg.host, port: cfg.port, cdpPort: cfg.cdpPort, - watchdog: !!cfg.watchdog, + watchdog: !!cfg.watchdog, watchdogSec: cfg.watchdogSec, }); } @@ -308,4 +308,12 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) } console.log('Остановить — Ctrl+C'); }); + + // Запущены из окна (tray.cs): оно держит нашу трубу stdin открытой. Труба + // закрылась — окна больше нет, и висеть дальше незачем: раньше закрытая + // консоль оставляла node в памяти. Браузер при этом переживает нас: он + // отдельный процесс и нужен человеку. + if (process.env.DEEPSEEK_TRAY) { + process.stdin.on('close', () => process.exit(0)).resume(); + } } diff --git a/tray.cs b/tray.cs new file mode 100644 index 0000000..4b0a7ee --- /dev/null +++ b/tray.cs @@ -0,0 +1,335 @@ +// Окно с индикаторами вместо чёрной консоли. +// +// Запускает `node server.mjs` дочерним процессом, показывает его вывод, +// сворачивается в трей и красит значок по снимку из GET /api/state. +// Собирается компилятором из состава Windows — см. build.cmd, ставить нечего. +// +// Важное про снимок: state обновляет сторож, раз в watchdogSec секунд. +// Поэтому смотреть надо на поле checked, а не только на ready: иначе окно +// покажет «всё хорошо» через секунду после того, как браузер убили. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Web.Script.Serialization; +using System.Windows.Forms; + +class Tray : Form +{ + const string MUTEX = "deepseek-api-tray"; + const string SHOW = "deepseek-api-tray-show"; + + static Mutex only; + static EventWaitHandle wake; + + [STAThread] + static void Main() + { + bool first; + only = new Mutex(true, MUTEX, out first); + wake = new EventWaitHandle(false, EventResetMode.AutoReset, SHOW); + // Второй экземпляр не поднимает сервер (иначе EADDRINUSE), а просто + // разворачивает окно первого и уходит. + if (!first) { wake.Set(); return; } + + Application.EnableVisualStyles(); + Application.Run(new Tray()); + } + + readonly string here = AppDomain.CurrentDomain.BaseDirectory; + readonly TextBox log = new TextBox(); + readonly NotifyIcon tray = new NotifyIcon(); + readonly System.Windows.Forms.Timer poll = new System.Windows.Forms.Timer(); + readonly JavaScriptSerializer json = new JavaScriptSerializer(); + + Process node; + int port; + string lastError; + bool quitting; + + Tray() + { + port = ReadPort(); + + Text = "deepseek-api"; + Width = 900; Height = 520; + StartPosition = FormStartPosition.CenterScreen; + + log.Multiline = true; + log.ReadOnly = true; + log.ScrollBars = ScrollBars.Vertical; + log.Dock = DockStyle.Fill; + log.BackColor = Color.FromArgb(20, 20, 20); + log.ForeColor = Color.Gainsboro; + log.Font = new Font("Consolas", 9f); + log.BorderStyle = BorderStyle.None; + Controls.Add(log); + + var menu = new ContextMenuStrip(); + menu.Items.Add("Показать окно", null, (s, e) => Restore()); + menu.Items.Add("Выход", null, (s, e) => { quitting = true; Close(); }); + tray.ContextMenuStrip = menu; + tray.Visible = true; + tray.DoubleClick += (s, e) => Restore(); + + // Значок окна — картинка проекта, если она рядом; значок в трее всё + // равно рисуется цветом состояния, там картинке места нет. + var png = Path.Combine(here, "icon.png"); + if (File.Exists(png)) + try { using (var bmp = new Bitmap(png)) Icon = Icon.FromHandle(bmp.GetHicon()); } + catch { Icon = Dot(Color.Gray); } + else + Icon = Dot(Color.Gray); + Mark(Color.Gray, "запуск…"); + + poll.Interval = 1000; + poll.Tick += Look; + poll.Start(); + + // Второй экземпляр стучится через именованное событие; ждём его + // в фоне и разворачиваемся. + var waiter = new Thread(() => + { + while (wake.WaitOne()) BeginInvoke((Action)Restore); + }); + waiter.IsBackground = true; + waiter.Start(); + + Start(); + } + + // -------------------------------------------------------------- сервер + + void Start() + { + var si = new ProcessStartInfo("node", "\"" + Path.Combine(here, "server.mjs") + "\""); + si.WorkingDirectory = here; + si.UseShellExecute = false; + si.CreateNoWindow = true; + si.RedirectStandardOutput = true; + si.RedirectStandardError = true; + si.StandardOutputEncoding = Encoding.UTF8; + si.StandardErrorEncoding = Encoding.UTF8; + // Труба stdin — поводок: закроется вместе с нами, и node уйдёт сам, + // даже если окно снимут диспетчером задач и OnFormClosed не сработает. + si.RedirectStandardInput = true; + si.EnvironmentVariables["DEEPSEEK_TRAY"] = "1"; + + node = new Process(); + node.StartInfo = si; + node.EnableRaisingEvents = true; + node.OutputDataReceived += (s, e) => Say(e.Data); + node.ErrorDataReceived += (s, e) => Say(e.Data); + node.Exited += (s, e) => Say("[процесс node завершился]"); + try + { + node.Start(); + node.BeginOutputReadLine(); + node.BeginErrorReadLine(); + } + catch (Exception e) + { + Say("Не удалось запустить node: " + e.Message); + Say("Node должен быть в PATH. Проверка: node --version"); + node = null; + } + } + + bool Alive { get { return node != null && !node.HasExited; } } + + void Say(string line) + { + if (line == null) return; + if (InvokeRequired) { BeginInvoke((Action)Say, line); return; } + // Хвоста в четверть мегабайта хватает с запасом; дальше режем, + // иначе за сутки работы окно съест память на одном логе. + if (log.TextLength > 250000) log.Text = log.Text.Substring(log.TextLength / 2); + log.AppendText(line + Environment.NewLine); + } + + // -------------------------------------------------------------- снимок + + async void Look(object sender, EventArgs e) + { + if (!Alive) { Mark(Color.Gray, "node не запущен"); return; } + + string body; + try + { + using (var web = new WebClient()) + { + web.Encoding = Encoding.UTF8; + body = await web.DownloadStringTaskAsync( + "http://127.0.0.1:" + port + "/api/state"); + } + } + catch + { + Mark(Color.Gold, "сервер не отвечает на порту " + port); + return; + } + + Dictionary s; + try { s = (Dictionary)json.DeserializeObject(body); } + catch { Mark(Color.Gold, "непонятный ответ сервера"); return; } + + bool browser = Flag(s, "browser"), ready = Flag(s, "ready"), busy = Flag(s, "busy"); + int queue = Num(s, "queue"), seconds = Num(s, "seconds"); + int watchdogSec = Num(s, "watchdogSec"); + string error = Str(s, "error"); + double stale = Age(Str(s, "checked")); + + if (error != null && error != lastError) + tray.ShowBalloonTip(10000, "deepseek-api", error, ToolTipIcon.Warning); + lastError = error; + + // Снимок обновляет сторож, поэтому он всегда чуть отстаёт. Три срока + // сторожа без проверки — уже не «чуть», верить такому нельзя. + bool fresh = watchdogSec <= 0 || (stale >= 0 && stale < watchdogSec * 3); + + if (busy) + Mark(Color.DodgerBlue, "запрос идёт " + seconds + " с" + Waiting(queue)); + else if (!fresh) + Mark(Color.Gray, "снимок устарел на " + (int)stale + " с — сторож молчит"); + else if (error != null) + Mark(Color.Firebrick, error); + else if (ready) + Mark(Color.MediumSeaGreen, "готов, порт " + port + Waiting(queue)); + else if (browser) + Mark(Color.Gold, "браузер есть, вкладка с чатом — нет"); + else + Mark(Color.Firebrick, "браузер не отвечает"); + } + + static string Waiting(int queue) + { + return queue > 1 ? "; в очереди " + (queue - 1) : ""; + } + + // Возраст отметки времени в секундах; -1, если отметки нет. + static double Age(string iso) + { + DateTime t; + if (iso == null || !DateTime.TryParse(iso, null, + System.Globalization.DateTimeStyles.AdjustToUniversal | + System.Globalization.DateTimeStyles.AssumeUniversal, out t)) return -1; + return (DateTime.UtcNow - t).TotalSeconds; + } + + static bool Flag(Dictionary d, string k) + { + object v; + return d.TryGetValue(k, out v) && v is bool && (bool)v; + } + + static int Num(Dictionary d, string k) + { + object v; + if (!d.TryGetValue(k, out v) || v == null) return 0; + try { return Convert.ToInt32(v); } catch { return 0; } + } + + static string Str(Dictionary d, string k) + { + object v; + return d.TryGetValue(k, out v) ? v as string : null; + } + + // --------------------------------------------------------------- значок + + readonly Dictionary icons = new Dictionary(); + + Icon Dot(Color c) + { + Icon icon; + if (icons.TryGetValue(c.ToArgb(), out icon)) return icon; + using (var bmp = new Bitmap(16, 16)) + { + using (var g = Graphics.FromImage(bmp)) + { + g.SmoothingMode = SmoothingMode.AntiAlias; + using (var b = new SolidBrush(c)) g.FillEllipse(b, 1, 1, 14, 14); + using (var p = new Pen(Color.FromArgb(120, 0, 0, 0))) g.DrawEllipse(p, 1, 1, 14, 14); + } + icon = Icon.FromHandle(bmp.GetHicon()); + } + icons[c.ToArgb()] = icon; + return icon; + } + + void Mark(Color c, string hint) + { + tray.Icon = Dot(c); + // Подсказка трея обрывается на 63 символах — длинную ошибку режем сами. + string text = "deepseek-api: " + hint; + tray.Text = text.Length > 62 ? text.Substring(0, 59) + "..." : text; + Text = "deepseek-api — " + hint; + } + + // ----------------------------------------------------------------- окно + + void Restore() + { + Show(); + WindowState = FormWindowState.Normal; + Activate(); + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + if (WindowState == FormWindowState.Minimized) Hide(); + } + + protected override void OnFormClosing(FormClosingEventArgs e) + { + // Крестик прячет в трей; выход — только из меню значка. Иначе легко + // закрыть окно, думая, что сервис остановлен, а он остался работать. + if (!quitting && e.CloseReason == CloseReason.UserClosing) + { + e.Cancel = true; + Hide(); + return; + } + base.OnFormClosing(e); + } + + protected override void OnFormClosed(FormClosedEventArgs e) + { + poll.Stop(); + tray.Visible = false; + // Закрытая консоль иногда оставляла node висеть — теперь убиваем явно. + // Браузер не трогаем: он живёт своей жизнью и нужен человеку. + try { if (Alive) node.Kill(); } catch { } + base.OnFormClosed(e); + } + + // ----------------------------------------------------------------- порт + + int ReadPort() + { + int p = 11500; + foreach (var name in new[] { "config.json", "config.local.json" }) + { + var path = Path.Combine(here, name); + if (!File.Exists(path)) continue; + try + { + var d = (Dictionary)json.DeserializeObject( + File.ReadAllText(path, Encoding.UTF8)); + if (d != null && d.ContainsKey("port")) p = Convert.ToInt32(d["port"]); + } + catch { } + } + var env = Environment.GetEnvironmentVariable("DEEPSEEK_API_PORT"); + int fromEnv; + if (env != null && int.TryParse(env, out fromEnv)) p = fromEnv; + return p; + } +}