From 75be4e0555e3f221eb37413cc8cdee81d15d6c41 Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 31 Jul 2026 16:42:26 +0800 Subject: [PATCH 1/2] feat(background): add jobs HTTP API, TUI badge, and failure notifications - Add GET /experimental/jobs and POST /experimental/jobs/:jobID endpoints with BackgroundJobInfo schema and regenerated SDK client methods - Add TUI background-jobs plugin: running-job badge in app_bottom slot and a cancel dialog (background.jobs palette command) - Render failed background commands as error state carrying the exit code; surface errors via notify - Gate background shell behind the experimentalBackgroundShell runtime flag --- packages/opencode/openapi.json | Bin 0 -> 2207536 bytes packages/opencode/src/effect/runtime-flags.ts | 1 + .../instance/httpapi/groups/experimental.ts | 45 +++ .../instance/httpapi/handlers/experimental.ts | 23 ++ packages/opencode/src/tool/shell.ts | 304 ++++++++++++++++-- packages/opencode/src/tool/shell/prompt.ts | 30 +- packages/opencode/test/tool/shell.test.ts | 155 +++++++++ packages/sdk/js/src/v2/gen/sdk.gen.ts | 81 +++++ packages/sdk/js/src/v2/gen/types.gen.ts | 76 +++++ packages/tui/src/feature-plugins/builtins.ts | 2 + .../system/background-jobs.tsx | 186 +++++++++++ 11 files changed, 866 insertions(+), 37 deletions(-) create mode 100644 packages/opencode/openapi.json create mode 100644 packages/tui/src/feature-plugins/system/background-jobs.tsx diff --git a/packages/opencode/openapi.json b/packages/opencode/openapi.json new file mode 100644 index 0000000000000000000000000000000000000000..1f75abcca7c56df480ee5ffe281e2e0934c43c01 GIT binary patch literal 2207536 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%0AK91Z@3dfW`!ii+yzGqZ_d9gXP^Za(5 zErNfFI2xjgb0X`ZJ>7?@E5K%{M;j(b=6(K;#zI(mYE+-v@`?>BZk&d!*cpCN#S9gwT+SZEVFvI6|jq|H%e9CLt{q5gMY`2ikr=BF}j5%zi(U~OF|DUgoq>-h9ui9#e ze*2uY5deX7xk!M#L6`N`Vl0QLaoU|5X=tfl8rFc&t$)>0D4z2x$?A3`_)pJ`8O^Z< zu>0io)JFoI)rgvmsEN-PpRYxr^RH}tea;!#!?2$?b`aY$F)XW*i5j(TBF#pvTfElI zl^iG2&Rxzujhzs^s@mLa-=Xc-WawLR6rZcTu`66*mpyp(&?pMEAc*(ZSXhwbH6E>z z`!A=?R9BNPSRd&&g!IiN^{IVHdhSfE=`@sU zG*Y~#vR*Irq4NH4VZ;%w6TFtMTZ`uEsX)dLso{9eojj#V`DdiDZt0Y@H)Ml;O+1P- zO}_fXt2LI4U`&@Wl)G`Qd!j}vVDvVN$(C1jp4)PoTyUntmljVs{EVFJ$jJ)T@pafc zI(x_MBC3_6TApROHY}dMBl%wUU#QRL?C6kpr@3Oc@j{#G=GZ*wu=a8D{ba9WoS)P- zyI@4FI?qz>_OEl!@p(*fwKr604IKu&+@Jc${k(ZdpIiGI3w$+vD$mGue;9F3F#3G) z@QCQa^y2w`q6`M?i%)V#mJ$wr7#qk`!3#R_()+z_pxI{!U=0yb>g z`Ft_+fan8zu6ZZ$_jkKnUXm|~v(g4$AXCJ<29|C%AKa7;YNI0v)0RDNfUd}#TaZY zjVRC1SVLoh%iA^97o@p?l3*aNlMttQN&j%Yp1K#GP}F9`0K=UW?Dy#GYT#UV=di#H zefpn96zPU6#?k4w6$fG7gLg-vBaMAt@~@lUlTD7^{l83>`G^?Jix_d$_HuEex(v5S zm9$sNRI#fau&_-12q#cl9*LF*KZfjOs0%QP3Wh1x<%O>)Lh(^^Nvo z&N`b)IG&$qSt*?6jXY&vnj7n5uMB_I+Q0Ub+y@KQ3tXx2tn)g#yNc_x5^WS`epwiqd$>tbZW`07A;wW!CHFIW+q}ML6 za#mQ3PmPu3Q>FPu)?nCO!|ob(m+d)&)o;%gW)gqGGO0#RND0FAcWO`Wn^Q0>CEck zXs#Guh8`PwZ0IqO;=`+o>oKV&KcPM5z zncZM=9>wU*6qgY76wFl2vZ(Fp{(K-hE6oo~5xeq+V|x`32Uok@Q|$BVv3E0S&$s`_ zr=8a<)zDMrn@<_-+PXaOOl^+B@EN>^+o_)8lJY{ZpUufM+l>$DExijn7Vc5)2fE|! ziVyM5H&k^uFB;W%#eVn%Q|*fF+xBKlGbY>kml!8&El@*QTuF(jHPaN%mU>JUQau0o zk|^qmXzD^8#nWL?%Ne;H>%(3jr_Kvq^EGXseBRw|e93V_y?@Y46&dl->84lRMND!J ztJLLC;Zv!_ILuBr%ul(HDl9w-4j|nNZydMhhp-FEyozQ@h?7Y4SSODGUC7Elt;uq$GOC@?uj{jQo1RO znyC3%&zM9X7NzJy`)c&!=VnpXM7j27Z4A3&*cGF8N+i~>E8=-&21leN6=^|+4P5#;M^tPo8Me)^ZH8?ll6BZNaoYx2^tZ#ZAsnP?4gRYl z+OCVTYyDjlJ&5fM#=f*6;f9185>7A>mvHejb;fzEz3K}NttOb~UGF7mrM96)(BtrN zZG7ZD!$LzXfqTC4yc$lEFGYUB-*r(FqXy({6yWCSj@^Ini*d&KZr15FQQvW$3W^$8 zbl&|)Qm8K0$xq?m8~b;n3cJ5VJoSpK)tTenY=@^j^7{Y855Y5b8+2-_@*Qzv6&jboL;*rj|< z){NLOuD!zA8FP{<;lnzqBW>fQcUagfsI@>0hL^UXb+)s{ZUM}Ow?`gL){w8EmLK-o zs1yLlg!bAyvfnPLQh+U#*L20%l+Wl2-E&Q~S2a>o%e&0Ky{w`>^e#Nq$4@b%!QcLk zu-Z3P>)P!aKUg5bRVRt%iJDc#Gdam@urc%#TPVg_8u0|2g{$od+=ov`Ji*Z48siC~ zpUx?t@|ym`9^x0Ip&(OncJlivo;h?B{M%Lyvn4#**lit$Wj|Kv`)Y3LK zrhFHUeLJ0*32#&@&1J0EH5^}h$lp*z8Rz*dg(Kz*)Oyrtrq~?hyKpWT9lh{*AJQ`T zGVj1%iVwu0%e;rrL|t|+<{it<1*g7Vkrab(wEPOi-nQ)ga1tzfye!2#SA?~Gqr3j; zIjs!No@_rqLiiC^u_VR&y(O9Qe5zRMg&U?H>~X@mnIGvN;IFS%w4pw0)~mJtoc-2i zb#ki?t@CGPKJ^%^drvK%bAGdLp$+eOc+YHKkKQ>f!R^`>!OUMs%Kl1H_i2T!t>IeV z$EcHz{?o7x=k$+HM|V+=$lCaX-tqHf0}h{gp3jVqJMZrFczxtVbWn)~YBgdF^%@x5 z`n-AmzZ*~TX?i#F`E{}lFX{iVxt5$yTNELT9v}`W=UKC6gB5yC|8eCc{58lqRDPp+ z&zv!VZ&A^Q+A7$?EmlqaEVdMddr$9!)V2GC*GWJ_fj-rUhd=j}IK&BIZNDeEcS*Y7 zV)JOi-Qk`a=kqGlg-`LrJ{s`BgmazaGuU&E`%g?6t6cfNjd4N0!i%Yone8uT<8l?R{LsroFAu$3mOGz!+~ze& zO!V)OeWbTj-T*lwoGduH9nY~Aj8?vx{6YB4Yl`30L`Z7vEuOd3j)yhV&{hT`Lr)Do zHT2ZbQ-XoG|0sIuIY|!Gm9Pvsq0d}BenRyV&&Y;HwtG~PUrydmtF}Rp1y}{&5k?UM zY#oR7fFEyly~r9Jgz;+i5W|4@@!azqd(We0=C!lV<@f!yW$hyv8rpbh(7$u_FCvo1p?PDG$>n_D`s^~>2dKL>{c1%1{bjN;vD=|WSGQX!$hW_u z{4rLZyVM`P<>ls(4=pG0nke8^)B4v?Oi%01NDj7RV*JOy#HfvbiLKeN3x{1OaOAzPJ6LwJmd4sx&ZghZ zOfDyEW4Gd*neYyP*YiRz~N8 z=Y)N9KA1}luEl~bq^KZASMl~*FYJf7pf#EY8%tgvzIpix){FHkRr5qof6?ys8)|0p zd4wPM?-+#)|4?xCamq-_E{eDXsKwUk*;}WLhkxiwv$gq$ZZrzj-#9S?wc(KDqx!pD zpB+o}ca0uw_d#8{tCKN!tNgd!v|D+nlWipx>8B1S)MKIMiJta@%h4R)7c0T#?Yi8| za+*)pPFJn3#Z|82!nU!Dd}b^S`#?t*BYrG&>tD4Lis$?Y@Y?MIa1Qsc8MeW&4Qg~8 zs9h)Fg`aBphWuk2N%)L$N$JfAQ&RSdoku6D#4r<61(Ctzkvh z>C;gOW$3RCbC4CGKQJfK7uzWlw<2Zd%!u~RkM_oV|9VOg&C!=4%&4i@?{4FnG3|CZ zxN5f}HSr5stNqy-S{*5nE~hKy4LX}ni?N(VW=HdkL?0GK%_(uCc1q~hziKHI&-ofa z7g>}y`cM0(Rn+A*Vitv~?{NATc27aSfL4Y@F)Rw+%T=TEK)pIyFLYkRQOs3hd+5CJ zp$mt1J^D}xw~Z<)=;bg+!#na%Xb&rPnqHFz{Fy4LaDML#`g>@@8^Xcd9%VLe=k1y| zc0GJf-!fX8zIsM9^n$Pl45C60XZJoPI^#~XK4#IC_KNZi7wR5jI(@6vv%|L%S?OOx zi+uDo8u}!zPh@BO?VUe`bH`z~LKdKp!C3`&>pi_bemh&)zKm_5b>X0Xa4~G_>>^X6 zceK*jU@-0V7;Fq*XZSk9*D*Yk%9VWHJ4Rx%A%D8Y_X5q;`d_TsUD{h;y-OI^ zMo#yd{=2Ypx~zHJU(AkFa3Z3WI2kwfET|9hOPo)rk7Nk1>*AH>ZhicNS1E0Ur0AV7 z;;!znP=sMjZr^?NylT@YSe^u-h(8Ub37|Y51v43oI9u?~4>yUMES@(+Slu;FkdgYV5 zoWWcA1~PD*=*N>cO?T&zbS{tDf9Yy==A6XwaMJMTh;wS`dvvPg91`}ATx`CY zvS>C(lzbV@sxCjfQ>swL4BT0oE;kRz!a*go?20*#S^enk^*N4NeMKvU^AHYwtsc=F zK!MMwZ}P?FSk}s&)f1Z8Yto*&aJ*G87t;%t(nau83)(-m2Nc!*Suit3x z?oV9D`tHNDlMVYL51UHkGkrw-_kw12MVkHiXL{(8CccKew-TK!4qfY&=Xal|_4UM& z$2r#r#E+0WEQgLohs4*F?e2GzWJPV~`2pJisTo3RTussyRlKkZj!}!8PHTvHJ|yae zJ~?E2F140eySJn#k9#F~mdC%2UlTuG62%@Pt^Po>f*pI@v?{YaURs5hh10EI6L7`) zaj$4N-{W0dIXMPV)VI`m=lHpmPs%a#J^r$f=s0x@uP1w-ucjC|A}NO($BWy2 z!l$Riqvunem+P#=Qb1j>W&aVF%O2XXsp*X64t5>o*o!ECn&V1pM@BKrb0hmmV+sL0HZj42o(8R ziG6;??@_3mF`kXf{PZs=x@ni!ah@y5G+Q#=Bc4PgjAhgN3DeSJ_TF@6@(sXcR}y+_c8A^hKVipv&ERu*QR>lK8+^uJg^|mQFBN` z?wY2sc0uznlISO*C&UTS8HDvO#~t3#Jmni?Wv(a63@row9KWafS2=^JeU3U!QP)Q} zT_-rF^0986V;moHo*vszXpJFX^_T`7eW+n)WlY=i`j!Qk?ej z+iqb`(|l~b(=v4q-wg@?Ud?|c3h*_hM&iimZ8oZT8XggQJ!$J%?v`tB85NftDS8zs zVvox3oVvIE(OhvM0GuI4sFFcsQo~d>X4Yp92f;ElE?I91Yi|2Mlj%WgyeB zBdQG(ZWO+aLVyY6$6E7ibup`6(Q=U>;mT<9eHbAwfB2VlTvs}AKO;*LaqqUZ)54kO zZ{$nR6C6AaI^v3|Hi&vqlgPXt5TsWCD-^3}xTQ=4;tt55v%Hf!58wy+GrRhOvroBR z>3Q7$Ok?5Xd#6^89PT; za?ft(8fI#tokE_0H;Hvde%j|It~<8*4*Y0WBQrOCn4XlqB9i$A!!X-@y_0h>oz!5|uRWIPTLf*8eF(OF0_ivv(0aZikx@JCyQuo`;MhS44&8?TV0*fG2EY3J%Djk(A3OlVzu;QbYao({ zXYM(ia7(eYdx5Xd(gE>U^l?CJma`q;aYTqd(iLOjJ&4SKtFbfT9eukdo`>D=p630_ zEROf>#x_3er!Vt*qa+P`M2tkD<=$myx(Q=5Jfp{O#)>>Kut6b+>UNVwgx8&vEOrtB($F*8Q#*pirsGp2s zU+ekKej1-cTX!xWhHqFuU-~fDQojHE^6OH=$3Ap!in%ZXL8(+)kQLn;UiU;(Kzf^1GkhMn@g#q}wX5L#e2% zMz?VzpS7zX_ixDxK{knd0UzcJVC{46?&*|0sO^FvxWIM4Yhll%ZLjK@<|6hjY}cnm zXWU2f>E`!TZTscaHK@+dk-3Fy)G7zeh{#i;Mge&n#Gw(*Zsi81qxo{dKkQ}1mt|M6#+CsjEfk%z;%xq9FW%LZXGdV!)!=Mb zxLVfw)y{ZJ9ylrlkman^1O4<d!#OZT?xBJEljIb-wWA;RxUkTuLeD`jie zDkmv?Dx51>*CH)=pCqylkQiZJ$gpY;?~w>T z(>v-|P?3hcaQqGL%)>rc`9}7{n0wyRGw86Xi^s?;an;9q`0l!VNFSddT#Z2`>!y-r zbVprBfx6hIR*P{J6-NWOP82yhNcZ`+;IbKINHEk$pojc?SX<>`Oa=mbZ>du5*(VA2 zoTMF~6^Vx$Kg3~BATRCdwX4g|_M%;#&8Nq{+j;79!hb8BFrW9#Ecl&@=EbK&N^7xAYQ7|7m>z9kkR=97@|^rVR0f=r^yer@>_n0BJ|tkHJTJ|BYVoPFwbQW0 ze@Q{w54zYJwwp(^3U8;Ax?pWyt+exmn?1^Fl8~QWi!HC=Vm3Q^lQMQ-bC;ga_uTn` z_Va)b&_CxT{r?eR{4rfoeJ-bf31?hS{382-(mWAcStBjLW#*I}jZGh7P#=S6iAsg< zb5|^9Kjr2Q9F(Ng0|z_ij3UhV75R@+U2k?^-q5$$&B>jQ;w#v`Rv(lVkF7Y%;frY> z{vWCUu0PGajb>`>g<2_>mjJx(uFT-xQP4+xo?xD)Qook5CwpskHc7aOTH7NJ31mjy z9{CUwU5DU-MLTwD|Hk67wRSWFUk7m{91q(>@#qGBrGi5ovcnm^@`!g z@F3FU31I|cvObMZTL*214Bj{ao@^G$$ zQjQ+5!oy=TRX?KjQdG6Hr}iyT+()veK!@#Cm22(Cc{Jon%nk1~6;C`4XpK+1N@FF@ zWB+%eSiiR59{HnJbS4~Tj3^gsCa~`VG0AsieaL(7(Om{BF-nh7_?CP~SpSG3+^6wS z>3~^CT&*3u8lBo|v&staPO4kt&Hp6$b(+jXA5cAkE|q)|2|63#M1_>zh+$8pEBgDO zSNKy}C-kU+d~1Vd_fefV-D75ER8e2a z=Y)f~Ib4msWbBRQV-Pj)u(dF^h6r93;#F@aOBSCsbRalk7}~hn9wQ}L?R)rLIcr`Q zIoLhS_9y4Qa8Cf9qsd*){>*YV$q7Psg$?o0b(@}63#+I(=l?r2 z8Xo*<)-%mta?djSi98qQ(Ga281#ixYTA-T#6=_OT_|-)#LWy#m)^ASAm*m5)t+!iR zN$luF6c-hHZPcgrigUAvPjy9^-d99l$VrwXHFM~xZBNMOY9Y?|x*$Q>=Y}nENqOUM zh}saf5O3ipm5nHpSZ{U96Ct(KTi-HPj*jIX``QCq*ZRuI82iomT-Iyy#F-*$B=<_D z++WAvSB?R05695VuRO11^fhE9G?z~MmFO<-&&6tSknclpH|}~OT{ztO9QRZ`?EFdN zB1g^8M?CV}S@+Qq0?m8U7B%PMw0QSAt_{~$J5%AL9RB5=R#;pam!~y(SB&Oh@1Y*> zCDn`MXi3J%^JYoTly*qozoSWT0-%!pCpeeRrVKe_Qfe9dlbSN zOjMe^CoY#!g!aC0-U0qIk#V`#{bcWwK;mY$ord`|R;GoN+4!9|~M zH|<%1`=99E&KIQhm%KBFak+=123*Bl<|*^kK4z1mEI?J7Yi(R8ueEZsj;d?!mQef6Lu->~NkBs;;Et zg`PI${Y%WqkJQ!hzQBd6$e#J9zi~{vu6u_KiF^+Etv1>(BjK8s5B6PrXW4R+XL6O| zZbY-(eMZK_wblnUQE?q-mF_xAMu`|hspoSPj#HgsJ98!hxdCkjPQ9Gd$%Oe7mYc7v zXDci%oLoycI@p*Z*C=V++)rJcP1YwqyLqxkFG2Y2Y~ypbx#ukOc_JGd^0_5qqF{M>w{{KBcH?Bw{W(MhU;=%?!Lw6__ePZ&h&%Ul{~X9 zyK2u_K8I^IIB7W>s?G!LZR_Nv$yuSss#HJmaLSlHpJHrMnE+`oof@$>3v~~nZFD=; zNqkTC5@K}nEcUVEFLVgfRYUl-6}DY^kGhg@j_MtCv_gH@EzMWn1-lEMpKtz3Z$<)gS23$$Oe(-GhYla?%>-k>VTyowq)$Mw}a!veX6NxGtwpFmlUI zFM&>PpUM-Vsc_}Jif#MK$fpGXdH zwN~CsjE#lw^71zJR8A(u?#FjI&ph-RN>V=dmRhc<(_8Y!+PNPq$Mo@#1gjyx%(L&z zxX{&ht$qD^$XK|BaL%*AW$bz$#FMqOC~t#D)z3CJqx$~ISVO^0`r5vRq0}trOww?~ zXxrCW8r#KxL;L)o<$k@>aqV0ia_n6DLuOd3Z`$X8H-_^#OvwYE1~U0_szgC2Pp)H! z2iD)}a@V?zerumg! zMzlbvLavBjBc8$Dim9E^MFm6or?)Oz;^yJ|^zt@Ml{wjfXo~6RtdWIt^5^NE+9`RL zhn@4(h>hLSf4r|~={YI+G|?wN8Z_E{b6}>J{*xIP?xSAGsJuyCCrIyZ7Cw8J)6czWS?^N zG7e*;X@!67OZnw^jgG6I5^rN)@7wABIvVxyw99ox78x_JC81>9KxdsBJ|fb(a7|ECK)NWN^+0vu&?dXZl3p7Z2z-P=~cj7!bz=` zn9D2dbJW*3?^goKE@cf*rzxdITWZ!0_i!~IPO8;ul3haw&5fOLPf0RBkHAi!hs9QY zgEi-$XxK}pK)*tM!fHegl+P1E-$qD8%>4~@V#Qy_ID2>QbyZCvU+;Q-4@r9R&LmJ7 zbR$!jcHdQq>0R0yZcG`w{?R=e*1}V|w(sTfwed1C_Blbz-Q<{;;ls_7V#~nEXVzYC zejvPJuNPWVb%aTUs4> zVdwO3z8|)0`frc3*fACKI(|6qybbjm&c0^+fO1Q`qUEUEIQ#IMV(_Hk=;yb^-hfl5 zHN9R!*{887+IAoz)~>THL#T8TIfe<)63bSOp_v_<-)z28NzrAXL4VQKQ_wYQ(cPPcaQd~OZpp8Z5LHTwISR#mF+bXomY>JnVcjkLn|`y1IBmt@0TeB#fa zh%=a5xs#$qkohl}`iFVuI|;MacoP|#qe?PD?ixEAA{HND%Pail z>8HFOR|H`1GqQoPJB{^srplwl;I7f6{`1SOgGPq?5aI896g2h(zN^Pz-Fs^BoU{6E zjyx;GUH$nkXS>Urba*M_J3medpE>-cB8w?b6CR95(Du9 zEGL86p1}&S1hnUWrqpTurJvwaGeh7UmhsK(I^bQ``1l@C3#S58^JKK(nn$wrq+TMr zWBBu`laBUSn)SEuZ;wg3qwI4AZE`;ke=B9lsQoC+jA$fJ8=aYv`mL6XSxa~F++6)3 z=$9_vK7K~16u_Ab0K2@)ghg}%k;}9XO_lgC@ z;y_Z-EqV8{4{Xzde6FPld2UN~3OcE@S(q{kt|8XiHLZ-he+gk|iY-!utuv)PDsy2R zt*e(x4b|l2sBNdE;~BOs!FP$Rd{`azHCW?5X|GLjs953%@4h|py3gx)#&n&ziXuNJl$>fkBYaU*Crv{ zbuu=GL&N1ZZ>$ZrR@-4d=5i9egx4JJ`Mzh&c0Vh~o?UYrd~x3Sq1#0sV!y_lk9q8{ z;@?s(>>2SpV+__Gppw7&ba?1LSZ>JQn4E^3{fRCj@Ox5gn_E{zmT~$#_sVO|N50agmfFfupb#FHK2msr%t~v;{OW-+IH!+}GT5`vRMMtDbnxaO z`jsF+t`QY@@07W#5OZr=Nf(~hm5e=?!e(09#zp}R!H;I?kiLUGE~)*!+3?QfG^c<| zc=vGb91-j!Q69rFzLwQ#)%)lWr|ZnK3?KN?v1L_sIyEMr1bgVvDZNK@>lI?dg`&g_ zby*jU&Dh=%$L_n*N@KC-QW#HLBqEiW(~XSezg>yN-w8MKUp_VQx9-~ROB1I03_VC% zGihFEqrO&6`J5m;r(Tk;CS8ucpD*Z)fcKPP;N8M=>~rnTy10C6p)l=i_C+V$p9-`N zf9&+m&dlrR-O>YVYJu<(Q2{s=9hhGP_Fk(rJw8oqM_IlnPI|TZj8@G2SX`+rAy;neS3>&BroZcEiM${DckFGB_^e>)3)Y{mH=}x)*q(Ln$izfOo z*>`!o?Ms4OP-lUcgnOJy@^tfW^ndh+zd!lk4~g>Nk=@WQ-`uScIwT{4cuLQ3FX0>N ziYNEwsB^b+2VEK=XL1l3i!N_Vm+Z69ThU@G=a5M@zXe8Y)YA#LLj1io5f=vGIP=RN{t+ zA*L|E5;P9aTBtd@4otf7W`beSa$u9 zRtD!zaIZbiHhxWV4P67_f6RT)gK70S_tkS;_Tz2{AF!-n(|_=qUTk{4;|XB^u@2;M zdyk8(;JdD)isg`kG)Hea8!Js+&`DTXWW`(fr!K-brzR2p5V~L960Go`H1G;9hB6rT z8SD`5_?W{h#t5~7jLg5L@r&PcR;xd!l(v`m^~+7ki1E3_v|ed0MiR3Ai+gnM8~W~MirUpeOMQ^2+z<8F>DGrO${A z{3AVYk9m*2wKY?^i$E53}`B?ECRt2OnNW*2#Ap*cLyu}`p$maZvHaa#)!klD4}eP-4cf1 zcgmu*LE!o!`#sZ0DF2qcBV_0=?kbt*%aYdBMTe`6_(l@uGQ*(<9GSKoW|ERPtS{A`aXX?ZzOM(Ybei`*x82|46+6iWmzMP zsD}oOYlIE529+jrVJqiPg)Zb;lTVdr86g+bi1DRFH$raUUu+so*@foa{u^M)u^$sV&o3SAlM!>Xo!jYECspzg zAf{Dw&Uz@@b}5&U1uAC(1ov_cVb)&g=1uZAMc z`pvNz%qWa!>_05qt@4yy!k-nQ)InY;ZL_`8^#;9qR+JWJ#aWUcyTi)F;z%#jO41vp^W@Lfo=H4>vOV=VL7 z&q=yV(UhE0yEb}&PxNl`Jlg2N&4#D2m#0ayyJ&wfn7w0dFzk{qv~hUDNq&Stw`%fy zZuR6I;dQeETpNcmBkTf7x7&nft^2{3;tsr_gyX!vGCf|{HuG0uZBhr7i|A9&RWF)V z2sM$8hI4r3>O0g1nX0a`EgC}N@_uTS^N>Iex9<^iAt*;KQ6CiZ(lz^!QHul*3HgdT z>pjFAEG>+q+dXDDv2GWcJeOMmxd&DU&I~->`Em6ZXF))9^Unug<0`_&MK#prR3$x^ zPV2nOeB7@@g*i#@^B(&fKE?X_%OF)}Mrtqd-~HJnhR}B_2p)RYt%yMgiZ^`hAyOGa2C!X2Wt8)C}&% zzMwQM9@4zNn0o7=Zsyo#7Ooh}pxBK0ml}#~wUE;M#1%rX$p&e*PAtGt4`LjekYk!`(bdAZaLa5Wq73MV+<#QrgnwUe3Z^I~1 zjElFMN95bR-8`W+bh{;|IVi-|l5vdv@76@c)g{?IX^e;l4>9A~MzM9mv$2&iW9B-4 zrB*E$Q8m=eGE``b|8nQEFIjp@ z>xvi%x^?E(Hl(iOmIJ>`-np&ByvujlxB5})Z&v#A4P33U z-(BPAgwLlNyq{!zZgmXYZSpEcAE`0tS%+zjg7?L84YKc3a!0XDa5`3$pBYYhx+dyJ z&1kC*-n~!lOBk+SLWcvEFd^me_l7q3Z-4gtmO~F{CD@)R+1{Zgq_HDfv)%@8Wy>Li z%=HH9=^yspZzKU^b)QcbBVq~pOjVxp5!=$?Iwc3Rwoo39nrf^PZc}zj9s=f`_TGdV z$}>2eXTidILbqn_#_%0kaa_?-rb`2XOU>FGs%lhGDeEu6ji(M9o zIcv16ndk0sxo#MLrfQUH>OY{XNJ-!1-? zUC}s$Mhr#}#qP~7_3~NZ!F7(TcE|Dg*tM}!cA!0m{W%`{vG1@y>+i0Sbh(I9s1ewI z*jwEy_{wCL!`%M zD`|Jx%$U4O;W|fIMyfI``7weN#q^_;7}O?Co#Wq-5;V4ao87*S=rGRaXpdTg$M%&u zM6^{-h-!_x?h}4!g8lBm;O>UJ`pm1K1yfrru|n<}gZ`MPXejNn=p{$Oc(kEahSsM5 z{?^6ozNF3LX>IfUf_E!z(B)Gb=L;dz*)1{2E7lmt2to1r9HF`2Xp)+&c^(GVMxf+A zXYa{PS7Fkg^Xb{orz>)iGUi)$gxm-cBN7W0o) zW31cqG?dHQAx1}{H^g2xtIEH)INq-=5jpV{aU^=&=QuK?{^OPrbMy8+bXttQTDWq^ zsl3N9;6#F_YJU=tGW)O9fvlDWfROmylAqBg-qx^1uKlT*i{3L$&Pjp4?>GkFdifEwo zg!sSs_8onTojZUSr>>=`N1$9T*ssRi1GQRZ24S7!pID<4H4^l zHeo%!w*6)kgLk`mFh%@cPivo#kcYInq}69IHD9{MymG8<3?s7U+bQQ^pEy2e?~%*J zZSWjJclaK7(C+g!E7@E3B5KIz(jwn4vh?+|6IuScr5Z)VHn0aVEm89nh$uLBa@lu8 z{Fb!I^GQ-+UK))SN(=q&g}5ZddTysq#>gkO#zypYMJ+W%;jDEO&(bI@7h=DpXs1U1 zgcQbl3H_o4%V&Fvao?ZzDFTWdy@ePbT1h0IdkrzAqs#z+MJt9#ezp$SIYlD5ht!vW*9#{t0b*tOmQR0V~)CVWzIg#ruNCwP; zZM;^Vbny_U53`P;x53q7*zrirfRX#UbK_$71o6nh2z9uT+D&V|C|JBtISNTjD@dx{bT{v%D_wae zI?>EwJreFa!Y!3|kIThkTJkQZ4`C-TcAgR)3x0A`ybJ}ckzO8<{VIK* zpAeQ%lZ6%I97eg$9P@c%atd-Zh6jwCq19oFQKfB@q(Py z@#7TP!ddNarcB&@qHTEhX93}4mQz~Yo2g>vhR$(B1_6;^ z^l*H!%3U2#2}0Bp<+PPZ^^gYHij%HFX*&ZW#G*)invE7`A>RpPG5(X^uopnz&9yYg zm^{Fn@(}oS{_{PQG#s&CQqbixtcEh!D>Yc;zx_Gwi|-y2zrESW$<{eK4%gProX6?+ zFf*uOSBE8OE{-|o`d_Es4Y_qOoZ4>7x>Ufs#nNZCr}%*(Hk7_EoLv&mkbT%K*1q}l z)|d<_OF6)7_6caSc)ivfzKi?zwppMW2eNIqxc}kPTic*Ud>u9hvVFf1^jhrud7;D1 zp~i5Q;_;l$v+E2(3CeoU&2M=y@_tilC{!j39@ofYTx0i~EGO9=w8mJP!Rr3FERU&HK05||;?H4UmfL?&j1X44>;*uc z^lzWO%lRUqWIlwbMml1^wi@@K;>ua^gSVT%+~K6vvq%4N^ikoQb1x0iIv0kfbuNZF z=ItI?+T&~Y?|q*5hCJMtn)9mouBu}!{%-PF}+%P zGq@Bx3bgzB`eE&dPw!2`9s4DP$D9RW`_D06V=E#?xoeTT!)_No!8Mk%@%bZ%u~y3h zbuNZVddcY+m6!R}w-DxAacMYWzqIh7u{oLJV)$H}MUT9xzoXiwf?)%J@?Zn;UcR&z zOi>JTbWASKr|JFJK=ECk^Jf#|!?L7sZPw2#0-s)goY`|h)(`6Mup18D-&$74^=jHy z2s_(95Ck8|l52xvX=@n~7f>}rS96B!e>a|}RA-m^@VTp!rUI5d9KEgEi;O4vX;%|# ztpfAB54#(|Oi`3PpOdO`&z3T%+;wO7(Bq;@XCB5z2mJU%9f6zjq~33U~c*7Q@Pxc07hwSI(YK%kAApp^SZ-hDfL+ zgv{mplFW)_4ePKrydbQSR+shTYC|Q=bBEvsp_a{b@R6NXk0uKW=liT_&!DSMOEv%Q z-99zcbKx7(w6f1iWa?Xr?6&tGy`mAH6Q;E>y8Mh%`Zy+ujjUn|iMtZ5)kf9tU6Fa= znx_x@&QN04Sefofb1Y7GBzLv-vyoB4S=Hzv8O6TFqI1ZY{6=0@jtlHDjU*^_f*%vuhT=eU1e>#CViT-jP@8^|cJYfM5SrYv3Ju+tWQ zr7iT>sPbJq*3bj-YRc{}jk_8-YUWk@R0}3@{oea`I9v=HV9$r{S8zSe;*N@GAQ-kb|kwLrZ(hB?`<(veNo0 z{!5B}YcOu>_!K7lVJ!wR>Kx*ERmrcSSNrAWKgm9obkD=Z_keqt4@plO3 z-@|$`B?rH!5xJJ)5y?T`A$L7>1?w{^db5CIml~aGE}zpZ&M7bL_E(%UgFn%T=v~W| z%Pb|_(Q~Vn*2Q`0)U!@HKl?VFWGIniVWwVb_f@a?`7zbMq!mP5J6}5`vyy8laddKC zp3kkZ+{3l;;5R3!?;aKx@i&ivGgAZB0XkazZxx541gAQ<71y`k}*Ga~}74|Tm1h(GOKZfDUl2gYp0N zWxGgJeP8dtB})Y`U`K~W_ii`sJ)(TcaO%7}y^^tCVzLM8ULz|F9kT3{wb+;Byg%73 zuwaJlJWkok@m8#GyY$?@%&M0e#!7*lL!Hud>+FoQRmL1W&$qB^`^r)lZ{)Z7FzfV= zJfD(J@;kr7wuk4ywrl?&zhXQ$#2SX*b8mw#TCSZe>lweGqikaGREh(W-Fc zcB)xOb&9QxBnBn) zP@)5-g>*JBj(OIv{(Ms!3Gd+d^xn^r=Q8&kt7WB64F4(UYV^G;KN;_-zSsP#En8A6 zvb>F8_hw8&dm`qn$7MgdutJu2+r?jqV%f-wl#gS$X{q2%oa>!tprA>T= zQ#0JP%yG}|d^nw8c}~&@Yq1`kZ*W?s^N=H5O;n=KwA^v6(-XoF&igdj`n+V1i;Wzu z2-nILG=5Fi<@c0>~T98rX8tSB&%#gcdSIAo1emt4>IDkH} z!)pF$=&JRh(^$7uONM$R$blZPNqio=j^2~b?lotoLsS`X@0=d6Vl>oGolKDSnZFtH z1z9g2hy(hJi(N8U_nxqtG5f*_in=1MhYi;s!?Dr(!jGDX8{*+!w2K|O?W4JN@cC4c z0*-B?D|a-GCZjr_b*?6=aYCH=k^XVTOpTOFYgAvlraVUfKK$KRhiK>X-zxcDo^gJh z5*~6Mw6D=qHmcyXpRFn*#^;urQ*JKCVmt&Z94E!GBsiV+dqan(E#1(nIewoXXQeQP zPDo;6Pdspx=9U!AfYRC`kNl*eE3D6Mt2j{0{_akSrl~`CNv?H-AE46&JP&BJe)!Ybo1yQ(mHK?DrbH~!69H9-h%iHogTioX(hWfkEAQ2( zZ&BONyZ3WkAUM{o;R~{MZ|H5BP8>3_Ttg}od%t!c0=#P23dlfQP7%^a)7rju%# z&qInmel6-pAMm%q)#s&6U0n3e|7*1Z{NQ)=ALO~cJA$FpdUE-C8B~DTQKx&fgY_%Y zEwHKX(OaJpKVionAi22vKE0DuB!1jhH^1gFkdv>ml^N0$wjWD4NXy5Q_K)SOYNhF) zi3)D0F7S4W$&~g$>{e>-dsp*^2{UP4i0LQc03TENsDppEHY=Bhz|@|m^@o_zsqW_%dW}oJ4qPjc}V~g_NF*(e?gi`S=5libALyOIJ zy9s@x2a}z|p7I*2qYaklTl{$`8kTSwI;dMxvFyACtI%X;J;}r4dp5uu1;PeG_>06_WF?)K- z+OtH@C9N0MeQPk)Dq(z0I)8pC+rJ+zo7G^A>Ca(bdehBr-A?`ak0Fw z&5~JQV`H?eH*5jK{ov=9s2TBq3yR%Hj=db2p3~LJU4cJset+k`#>rhUWLZ z3mvY8?l-4r?2D>h&2xXsU~<)9PL_qTYe}u|O7OfU4k2@;YFaC@R1B?H?6$h5|Bxj> z{b-JAV-mSV0-71GgD!GsKcp?Oa4nXk5@TJbArf5`LN=F5Tt3R-D@Q+R>hyO$?lMe0xdi`@efea_= zZ*@LF2*Y|k!uZ;MeK+6x{gQ_s_BJasa;V{id{7VkQW*6dd+e$2=HvjX8|U|IcCD-!Z=_{a z3)lEM-^b>@cnQ|x%@ol>y*S6o5nF&Zdq(wQ&}k#8;PY24)()NLV4)f+$@$~p8vGYp zID_LDFOLY9=CsnBf0p)TLhK%|KdZ-AE0@LmuQcxGQ+Q6hxq4yv)-lbTi`e^mHnz4g z-+GN+H?;9D^pATC87;h~Q{D}}=W|S&FIaMh5z!Qe^0CqMds@zt4rQ@c)8*iRl`B2f z=Ea#~90YtW7teBK7}g>_(|(!1m__dImHleUlNp;~8Pu5~qpIm|S6Zd^lcr#8 zn)u*%^cP}XCQfiloh48ufEWy)(wScK_)35tb`Ad{!Y#UKU(ufCLxmqSguOn8fNwjF zcbHJ$CtPzMGsJrj1@9b-kqGsV6g%gtg2S1?Db*<<9%-LQdkRv$;{5Bo*xlh!%MU~=uxAdDS_Jk(qZV{2d_!{4CcAvgOuxbSM!;|z+h(^%)6FxQ9 zupOe*31@L=QU^15M;v>3K=KA&6zY$-H@x%*JUpvDHjhK3A4EQGK3Q$(40)LtDb{NM_0OeCh=!kn2VmilibJ8o(9%N?e|==hSEO0!?1B^$Bc8ay`woQ`D2 zR#@_t@pwOH0@6|8EyYlvvk|QYm*k@5@}_XjpVQOuH=zH~8#4uG9L5+$;$68sprHiL z_W83|cTNI!5wQJ?csqyj5YymFXm;r^9m6zs-N6P!qyzsyy~`ZDruXIE#yIbl$Ec&? zG!3|OLA3yS;60<0_&$=oAQX#S6Hb@onn83PVH@Iio4?*!q#;$t-sxwR-0Fm}V-;Mv z&mF7odW35#G78tYwBcWJ64BiS*rI7PI#3`TdsYP#_O&GWVsg)ZKE3w1E5`Zu)BQ5n zGHM*26dX00&!yJ0J>}v#PGn9IA9ZiC^0>x2aMfV!EMrmSB-vZC72ZtMzsN7$Ox?sw z768L*_60)z_31F|*NwDDR@eSXNr8UcX6m2V&WvL;R&ln!x|r`N>iLdrA^iVqTK^le zGGP&w>dN$IJ(g-oeCpYyK6Kxmhg5j9q;1kXCL^S{95y)bTubw?j1i|=^J^Z8oX#*f zN$Cf9%MzL|4R?NZ!d3Zv=}5eor{v9W9TkYjYFRRyC)@qS|3{wb_tfLp z^-ohWUEY|ondEm|nHS(Gf1LJ8VPE~+o+`h$??XPsRy?HZ*t+|B)p6n+at7}R*ZEzfZL+1!SA)ll=y{o|La1DOC(p@%4s!>U zx@XiNBK~gklwgSA8Z;NfuFxV^O#`nc>eezBS9-TWVl-I`1a;U%^vv)q_FcNW4SZ?~ zX;v_p$F7{_#=G&_=)}csnNHvr#LlG2Yh=s^7Q!p~5AjPmiAcMTMetFg^Av5!^ErIV zJ-k|fQ}La7#-%Sl`OlX6eIVof6i&@UoK~~qJt54^p@i9-m6@Uo(K8nttOoz(W8f?i zw=naD^g-lTBD<|;E6IqtnQkeL{D$l-6Gzsp(VV_~-+J$RLfnP@A*r>>L*G+QFDpx2 ziP~F^kHtkU}y7Rs0f1bOLPzN4fWa~6NvtBFxA`#b(RpY0(I60;Uk zc*xEF5Ir6_U3B<75{KMw{z6h`RzCHJ>*!iDkTFXu9j~;xh&d@AJxQ;yJ<_hS1~J=lJ#*E2 zJuxd&@L7_7Ijb{93v64*Ft-nh5u15x#<`iU+rGwGVh<-BRjRc@ZsVFNv-aC{&GaX` z-F!irW!St==>IRLOvvp@d#!y#nB#f`oG&NYn{{`cio=YZ(m3trg7WN#F%NX{Kn4f3 z0k5c+_ThB;vd=k zA>mhGUN@dkY4t~6RM^NVYZ1Sd^7!r1_&EMyH?5N|ciMte*ZB zk5JC&ZTxqH-}rz1u@1>Udg?N^ckPGAdg>mUypPS{&?G*1fcNdnX%3?=a9sW@A@^m65VR_TzoSyFl$M zpL%gfbqXb@zo0q!=Vz}C`(G3F^10sJFJX;-9i-Vy`gcSBuBie9XOpkFp5pNYD8*IW`+An)~JrMQLMm1`XD z?#AuP=~-mNpGls{$)YzahxsuV=KpU=JH1^wj4|uwuxzb$bJq`KWnFIU+Nk?P z6WEV~vuM}m(J-_U^}z0d7nA;i&4n)4I0a-~b}T~-d4Rkv;$=V6=MO7|(~T?OFZhqJ zXV-?;M+DVdI{Sss8@eTH5GViOG@Lc+1BUhwWU*rHZwba5+V#R*w&seJ9H*^MInru#ZY)1717+KOQZl?Xn}$igEBxZG)(e7@9kdI#rf zuE{SqS?P42if~Pq>>+GU@k&D^l^h{t@ZaZjzRlw(q8BeX$Y&xR1aHvLh7%q5A+}wWpiBGd-c+H#h>yhF=c|OH)@;k0us;YpE zF19&*IL=NZZZii~?HS(!Ow@KDX5R3-TWKrKAa_q?7*d^+n?T@ENN^09DRklN5iwNX9gHO zQ>OS3vi|xWXMv`;yB{r?S?`N>O#i17q8dn^6QUbPTi$B|WGEHe|Dhx zWAoUOmc=d$^m#K<^n8+`IP(>`?~{qX?Cf`%&O(``;e`ZP3(=eRWN-GGGt(hwzIu&`(Gb5o znIP>me={a(5kC+%`iu(-!n*f_)r{E}R#4Ox`LXan`eQgYdSCco60ULbOD{URA}q9z z=K65wQymC6wvDdb(Qb+IpOb%xTJ*N@czxMkI;V&y!xzt-h!pa#X^raN8ME2^d*tuF zIz+1j;x@CuB-iqc^W&88kc)cx8a-uc3#|PtZW%E?x73_+b2)6k0y~yiGN2YsYE*|e zfk^uNb8y@kL|z)qvmir@(RdT_HBR$?iVMIyZGIs?>0)Eo5gF(gu3t=3w@3%Mme!;s zk#m?d@9^^(Yl9E_oss{BF9jXl4?dl>AERwpqR4c?VgOabia4LLUhsM3+Yb}u*OT4) z>eILE8SuXOG#AMF=+^KBz2EN0KMzad!N4=nTUo%(66`+Me^*q2i~ql;?{XGSP29aC{n|T5$Kd~- zDp{~&^k;%UC7*NDx?5=fo$#FBSrMBRWJkW4q8_Lee`A%TfY)*Ehi6M z*ncE_eRV+aKBVZ=bD|OH=H}8(8q={~w31Lxsd9ZCbd-XXa5+f73APk}iIjNiQ^59A=o<#S42r|-XLc`^sjt(U+zv^mDr6EUsGk|Xv@i(ezO&(gzC;u@sK{i$vovSQuxWB=UqxlpUY^uFlRjkY`_ z&4FAb`pREZj|}a2 zXq{jT=0&!;bJ!OJf4ljXGBvDojCaqu8)Vzz!9B}bL#-5Cm&;GnYU%xP-ROTCqqyy- zzPmpV#bJN*1LA1TA+O73HPn@sG{RdUzFZ5bp08~$!^f++D|6q?9SH!n!9{2K`wI8gaIJoycUp5YO|^Tf0(VL~##XUJW50wFBu1Zp z?df-SdJg#t^jQ43c}kzeYsh7%Lan!C3~ZMccG}*+E*Dsz+!Gkwfw)i(OQ0^MYNMke zt5F35T`(^;jeY`V<(|=K+Wl4G>S?>n#i+{6@`muieQ0t1#9lzFL@edQFEnSO{qkHflC|~1$$?QWKJIa zbGCsm(S@(zL1L>eRYoTvt2vfFjM2 z{Jt=v#nO*EfQwBDErqqhPBoK>gG`3DfTxRZL;FE+m7lXOZ(F52D#8GZZpS5i9@tl^ z+gF*NgTVz?;2+`~nEH{y>_K@knFe}@YqS)0bJEUmE7PfMSxL4yMq7M$Y{mE&8xLoD zl98~<&_NEB3#XIb1ZC&eWw(;j)inFAzIjcS;w$nya`iW9Nyt?_z;v&9q-j3~#VyG% z^j75_9<3ECJ+u%@`}}?bk?kSf^?*R)TCH*vH9y!91&cS0bJl@;f-Yz%$6qpEex^Ob z5L!PeYQdZ0(lY%^iyV#d^1kHW<4NWrOK*0t*X>jAeJzd0&}uKb?<&Q4+`HMEqr6vQ|x3r|H<>SE@H(zZ2g+6h`^$WTW z>vK+W2WyDuE;j!}bBOU2YpFDBdAOF9rm+6g-4!0v{23px$b@?C(X3xiv&a77%R3rQ z&ph@^jBbIaoS$RU3Ufya`h7{37~f(4FL!rJ)Aw$94kwY=(qaFchxk9L=Ov1AZ#pf- zg)v4&WzPDUW(wbz>(HmmAz=pq_AzjcxLwHwb+lTbHUOytnbFQvSQBH|^SRUn9^!~K_3$+K5GvYN9 zxd?ox-k*|z{9Z)kuBLTkzG&mpKDj8IOb=@UT)H$IF>IwUmD3iXlw+OYN(BDS=a4n& z56Q&m@E-E(k~Z7$mPA{$&}9sJOoi+4j$-okKG`t0Wc!x1Xh?@;y@4JYu(UOCr*Qmo zj4g~D#a3;5S0^jJ7N2Ha$8#<$aeF`J2fmsxp!e>$qE{gO=FSVLgLO&yfJ&@B{#;BK zl(aT_H*v-QF(qj49A<=*TPUjx3H(ExEQ~#q^KH*GHe$cTs2mV4-B-n>PPXjjte?E~ z8Lq*SR0?i|bn25|h;zH4uDlg_`Uw`C@d59^^gEPphB*J@ntuC09s#n|urm=IV!!;F z@;>+IGrAt)G!uzb*yr2ByO15@a)x+5X0cwn`hj>Gnl#5(yQL?y8e9d?!teXc+=KGC zCh0KY2ku}=aBs)U&3_VgwC*-vdL8Qc3S16v#y$HMyRLkiV>{Ac$$fb<=Il4@rMtP) z%7}-t?B(dUL|xy|x1|-^Ek|>YlomdAEy37omu&|(4z+9)IIMocTF8o>5aqdRc0!!R zv2wF&tyNEN={@kj@jh@bqJBB4Zgi@PA=rJpI~5c22Vd58w@SmVqZoNU^l9W5TvL{x z+>?u%#O9TfA7(tix(JypwgY49n(ovmBgW^KnpbWhti`-%Lrv*%`*rY4zXNcjJ0_vN?cI!;t=oWZ z)-OG4Xhv2s)cvl^%;VpT5~CsL9Go(OZ0?C?Rh>}oH%DDEa!NYM@3`uzO`hsCYp&&l z?6{#hGKJ_)g%U_~^Ml>+x4ZH4Hj9iK&QQ0XN1oTgg>&`L8yr>9EJL;RHS(SiPM7{t zR-QbsgR^E=h>RRUR$~d7QR4crEY)QMT#+xexv3V*GFCVz7uz~+H>0KKpP^0X=wt-B zYF1J11-F-T|8lo~-EP`zD^Hy@sF_`fiUFk-2RXYeMkQ>O8JwLJDpmz!{VX#XQLb@2 z)cl&K!rc6g29#Nw{UpE*WGMfVl3e_&kryRw^~X{iJ1OdD$A)hgLmS62-*1kwSzyPn z4~xrbKdNJBp?uTG?8B_j6$>?IMaA$fe5SXWLaf$kjbWn;#-YcJgwk68{!?|;Q}Xs$ zj?~o`Cln2}qt(MkXWZqu$Y59W%bax`HhR8umS9`1A!lghy*w?~Hu*14%XQf3f(iD> zhm9W3F1a$--p4U)bdjOMMrWVjw~N@5;x{{JZPythjwO z;^-j_mo21lC2I6~8?A`;^531OnbcEtv|~mo$I(&qWH@cu=#0Bzqr0A^Pk*Hdqz->3 zE>`AYL(@KFHN0#_8F6&MMf$2)MR|I}(bE-R!$$u&)ecFt+^+W+HoA+A(7riaO&tBv zUB(L8jtlCsZ%6lX^$flZq^kmJv%CCvL zwc6-UNc+8}idpQn9dUG6q1cf%YFz{aW*jaO=$U-N!md*$}1W4EjN568BDOc4a^#vXC_Q7a=-!d#7)Gi-cK3@JuKuAVrV zVs_xT5s^1^W`ELIt0N+B8E3~~?IRDM?Qdq&3O>)-eJa*Njpd%VKyB!- zHs#)5_7nE!aAoUuvdCC@i`v|!n^(@l=B$l$C$OvV&H8dA+2Cb(9H8K_bN28&j*(S} zS&I@=A3JD=$I;*882JU!*Y;IsF%OT!#+m(Dhri)*FwR1|^bl)++^EL!h}3(8H{`Q#-R<9xBGg>~qCea3!T3nQ8awY+Roy{rKV2p^tb8Tm7*Vr?C`G zH+mYpCaN4g4OrHWOj})Sw%&(hej9l;rni(77R}FEedN__eAu6L_!}M@<7{|rLOW?M zg)YKlSu8$*bl0BBx8D2f{gs;8-qP7k&!_XlQFq>UezsXLlTqNV zLC2Uy3+bceFBtsvKABraj{6Vh*E~hE`xB$1#G!PQh-b_mQ>OpTR0A^3F&{pb$P3Ou zgt3BhrA=tPe7?P%*-DX}!gijFyW^qqin(rhT1^1*5GMcI|W8cHmO0&6OdS zQ-|UkI=Q=Tj(HDLPko@ocw`hh8GImT*x)qIi|JpkYRaZ;e9n7ha<@ieGo;h4QCSC+cIw{H?>^@P&nve7k!1!owF%XJCgfY$OeT z(#RWmW_!0wV)(*>5nQzx%x5cmR?ym(ibMm3FD#glI6TJ)hA(`0zVHLe{bJ8Aci9-H z3&i~xUe{dgFDJQh5@Y^6Hj#m0KEkb@$;UR+y8415uJ1Ovo%eb8WzXo?F{#Od#Azty z3!gh2ctTNT`=ssR3o~!z=+khI=%aF#f_Y}1*Q0|gr5WeI=}LwYUFzT*zA)28D2InH zJbdA_eqGuZ7W-_8d}&E?h@?E!Y^K58+1LR&GL}@&a(G_a=>+q;soyAa{pYlfY1<*x zUYZI_NHWn`RpVP%gm@`RHMn6i3t*w67qVYK&P7-4Ho5SA} znF3orr0B9G7ix?eYqTw6Y+yc|ETHi>kv&BH{|oXx|Cu!IS+OrhjOzsla@AJ|n=-?WanS$@sbsm??s94Q#Uyhy{>~X}(8NO!x zoV{gzP1nlqv4X8$N{x5*h9VO0sJ03JuZh>B>8=%OjrXXLU4Sg_4TSt=d;vdlBHohi zIrDce=FUb9C1E|KH5g+iE?B}=Ki@*=H11ud=qXP>B4>G4hwncj^Za&X?1+A2HE^Sj za(Gbs(|+SLWJl!fZl}esfmEL0lhW1xq$yngC z$otcX#skCrHB!Y;l6}@*3(WgD*HBLp;NWYb&$o2_nX+obk7gMm-Q79c%)XM2zvW(V zJkvUVV^h-E@VAG*O&k~cCMnA37gLDIznXj{+x#P2$$5*Btu(qaM$cuPInNfKXM_9i zUh|$s@wM$-j$}W2o>w1(N>#2Cmx z^!St$!|SEpy5@xXlk;i+WsAg0&t(ornNfS}%aPIK%2|4xk}zk+X0*PPDdV>An>@SS zd?35vlH}yY%IBz!9m~vcZN*HkI)gdeoIGpe?@Sppv|+^Oevu=8WdHAYm5P6t{9TK` z9NuhQ#nDz*;`4VgxyirS(x(>B%j35OQ)`Ro*I0nCTdzn~^s=U~ga3x~3QnZc!vXq) z^#iGe4v?+VIkfIvZ=y!#=s8Pwrf^-?65n zL-qmfH91rI`TgvE!IWI{crD>GkH_HwGS{IOp|LNS3J!fA+YiLwztOBtC&_z5{~w(| z%xa5IpR0Dt@s_?5gH2iRvFdz~bk4urc_9zKU|^iprqOWmI6}$?1h0Yj#y&RDV(v9Z znR4gw0tFM{RfoUf1v2JB2|T>OQC}BwRa)2X>fE;dccRqjLXGqRcJsc+vOb(>V8-a# z@ZxASMmLf$>ye_2e*S!nTl9H6@#4nrDAw7-gA=_4`#7ZMk;N1I_}5ks&fXn0IynNX zF^Lvp8#OzBBdt@WNO^Xyovwo`r3L4}=~g6^Y$zR^!+T@8m`fExT^g**y(5Pwm>4-c zgNgVj&?iUx_V2yvYf=r=H4<7d5b|W51e9^|xh->-ZeHv0H>H-8=>jF_svQ^r|n2an9+$Sm6YBy^JM zAG&mAG1MG~<)!jI`CrK+!f84;Q~y&`61PYoS(iCgv)^vMB^cNv%RyC&0SYX6zs%gF z^&hd`f1}pU@5sWAEUfSiUq=>J`UPnP^X*_PmYuI zTpEl?Irom?^ZNL(|JLEp=;%3_;+h@P0^_`$(`J-de+~Uy>~SRGkEchsN?3EFTcyy4 zT=!Q^8)}Wi@_8knyx+{MPM>47MLy;H;TAd5zPELF>6}ThPl;hqGsPPtW6cK9n&&g~5f$ApSP*ub?>!~p3 zQ)APMu8dXllzSTa?=C;V`q@;au*L3HYw0w7oQ6^vYxL0r7oJcgTKI6}tVJKV*Ob(@ z?;1I48yoIt9sZ2AF7vpI@ADh_em~#*mHfSPis6@f&zVtrbbAIYVFpJ(7Xyti4Mxs- z`0qj;=DI)s9levUCJXK>;;|kS?&`Z(zRS$peA37jxf@ZiXVl%dtuJ{fXIdfF%uPG5 zyw?!QBI7~%-Ot3E()0r3dtDmf?+k{|Mm;rg#_&!<`#nV&Yso2x-s#9GkDRh-5x$O` z@{&2_xMw=D$}SC#UA}W|GL4nBZK`7oAsb$)P_G8-axceJd|S1@zoCn-8K_dV!pKeF z^bn1WkJ0LIq3e*kUhFJgN$q+h{qeBOs;(oKteKmZTG!^48VsKeuXK2&(XKox%2=CM z`rt0|W_Aw5GfZt3NL%j9e^(qLqdooTwi`*y>*9EhYvf78I7?ao`Ri7fJ87ep6cyxY zCiN8TL;XoZW|W!=XXA~EeF5G(*^Ew8z^BG07@1L_yzr{S-^h$I=0b@zGNU6i8gkXh zjB4bH;0;{GwLpiH%QZDiePDLua~f|L*sH^`zf*b%$n(~-thij~*>Ez7Tw$C4HdWrd zCyFY0DDqV58p`_TcT|c!pEc(m$s1}`OP<+I6$5kkvzyV@Q!y_v#p{&iSN~dz!(1#V zq?R*fd`6(^=bg)l{#Az^Emm^ah}DiQU9Vx}KEKJ9s{BnTv$Sip+}h;Vq_h_KHIRLC zf)D$Q;c?=!jg2tkkfMx!ln`56eYb!g?(_%u2H{>0$SvjcaHxe`OChdr+w`jcu6#_y zzq>9LGU8~yq~{&jAytn!T8JtBCQd`;{RXU44F8Q-8sjr2-F)1SSelO!^S2IvBbLS( z3-!l{rHxpc;U@VsVrd$=Vz9*-srS?VqxVjax4bhe(_|*xUAL?@UQ8{rpRN9m;D_T7x|9N2Gx{`Z!Pa=6uR2_4z!f|JWzW zNw83Ay3#%_H%FWyuTw*;*3^rnEuV3+cOLH|N9W<+jM7%GbL(*5h%zufOIizejVOcA zUU=2vZ$udwbD;znQHBv^2)Qb)YsapU7`EbmR5@4Sj}`K#YjPAu4Ulp*d>$Qs#K)PhkLa>CaB+Ser}A&g!H!W=umz)f|mY)ubLQ7 z4ffFy61MD>6_Kmsx3G$%zogL52)JtVTy3hfKaa{Y8ym6D^P`|#HIeHeTf-}WQO_@Y zcP)j1Z{jDdjLI`q@<0asq~5Cx$sLOqYge6pN`Ei6eoYbO)paM*LnJ$T2fN0)|Dq+@-VCe1UxS6UY})xnk0gmd6@^J^)7mU-&n9IJmG>ZB1@6nw<4Bd!?3iv8Uj>hFC9l)yFO zih_yQRfip|B+1t}#^QxiU1H>(MBng>HpYj0{pg)9%f}8@)KA-cHpdQD8yjKN;4Bd# zT}vG73E2zW?`lNAB!6MzKikb&V+4u0r0ms%9$1YRllEFh1Wadh&%?iH!@7N|$RZk^ z8<8)@qQ*Yp*umebysB`8>tY-_xJKklcp-Id%Z2!(VKqY=uqxu1rM_S}J!kk!eA1U8u$DK-%a+%TEy*HOi*aNfY znX<5Desb++am$Eu&10}cU3q_3WYp*$Wb5%5HV)7C!tP&4zh@M8fL22V^C^8o{c5?} zosAFHV47@mn-=!pmA9?^yJ5BIdn(6mXS)J|QnSAgb#p!+j&q9zm+rNs&2abd(p;R`f9dcy>Ju1eq5Rr~h0lJ^?VU#E zTtW{IvqlTrG=tCSNZ+zv8cw%GUIp=ui_O|`v2-;8B6r9q!BWfhUhr2>{toGR9!-Q= z?%A}j>J351HZpdEfoE{Ka?W}Z2<4jhY0O=^Dx18I6UK8G_81?^tU{{fU)&WMz9A$> zDmKX&GrFdPt^OW#oXS!>oL#%-_NPR!zUD)hFo(!4n1$m7`4<@c!fICkxd-C{*25LuWeMBrsRv@3fFi> z+U~!R_F2vy4jh?8#%oN%*%)W6L;jCFfIeREw+?^9Yhm0CuSIC6XLYGYa%$)lu;uNu zn!3TWVYd@DM9YQ z$U2DC6<&4t8}_@%Jhzf~^zeX9u*ou{bfU*Y zDBbGrlq|_<{q5#Cy&rox&*_A`{Xu~pFSi844dDd+nz&oZ{^0qUAV7Ww0ERaMoS+m{v z{QHo)!Et2?$HlRWfoo16<#?ubvs;pn?VeXTs0^L^zMcm6=IOAy)Iag=gt{akvlv?e z87H<9@*CD!M@Qy~_L{3S{l>Hv-k66Sx(R(P-jjxhP1a*g(vZY{Nx_%Xs4f*TC%LO& zcAdDhJ4@t)me#sl0rpqIFr>{_#FxN4KEuwuoK_)+`%v4KPdi2}Jt70>j*=T2R1%J_ zkplc=>n_plR3~TSL1%Br;dSLgjMDHN{!3Au{EkQ^`qts(n+x(@b_G=m<{Z2^ElHfuLu#ro9rP31WCjQGP$FkFC~r^XEyz|3a98^$Q(qs_a}!w>yEp zn{b<>t=&@mhhP@ko?s!IuB47z&q68b3Y8B;slO1Vweb#MfP4o9=df(x@Oh?g7NH$_ zP8hwW|5(a#JucI)`wMuJ^P7;+km-oWq@D%;$_ZqlMQZwO~P?>U6e#aD{|w{R2Ur zUhVWdmz_&!ze9$?-$fh_G%gk|?0Hz{sMfN7f$wKJ;K<$Y@4iK^Wf|kc^yKyAQ5(zO zw(R+7cm{08o@Fo=!)17XjAIa+!CO&xY|hw3E`ME_6UGMmGs7R8JGUpKf39fWIZH9* z3|CskskGHQaHHMx?eG{yl%@G@GX-%B0?J+ITQnSy#%S!97_afnfa7?_E|&(F;=>i; z@7+wuzVuc~b_jnV=T>Xu_0Dw(E;m^g87<#vNrz z^m?)@FGxz~WHiQMu4-T9N1xvGgs2tvR2#&?*JZz^2h=66s%;L~X9D{V`9vMw+u{;2 zjxbn(54NUyG@->F7)k3qrsL2Cy(L@aIa!M$EyRM1+ooK760?v5zj@s6vf?O>3!K)D z%9fHJBy-x5M*;p5Z)m&u`_1pBF>v-1EOqv-Zs}W47W_b1_4wP!;Rn_`TlojP^OnYK zqZL^DyUo$%)_^OHT+cu|v-b7S+7#&(iv5zJ`dqZYjvM;Yovkn<8TfCPd-%H)7SHxn zrE*FX>Uw&|YkQ=ro26~4KP2o{Pq6Jfq}Qdd;N`tF{K* zmwzn$emGVs^k^y0ZnUUx&FMP*<+%aXZ(Q4>)g3+*nz)OZ1MH$Vq=VtRAsft`T&5W2 zU1;F9WO3!aR(YFT!&s3HbMkx+gL2Q7W(By`3LPY#oSz0PBC4swI%c>V3}VLvTYvLl ztD#7k-nQ)InY$8;zl+HU{>A3b5}x|wCpUBO z4ez|rP;kg)HS(e@gCMI6&zUg{eyfubA>4JGmcyWd?>%WS?sBkB_z-`Fj^LWtU1Kn1 z8v}nO{N{MmrwZmce=XL?b?=IqIzwB&rf_rFDct7px}Bm>kW5lpsFMKg@ejX}@d@#9 zdsLdEhh|S+*&++2Ko2ZJCYesl8YtQ^2#m?QPHEkEk4Mg%k5NX7Dso(AM~v9obA4yg zbK;Zn->!!w--*64e+wt@H;9h9beZDbe!4P-6I2ku<3gkr@ec8yz9tEZ9Q%Fx7Ha^R zimn!jisX1Gq(6=JY}1-s@~B{&=HOXYx?B@xfR+70u(oWAyO(cSNnum&>EvI_4#}8A zU>zL$CB_%HJ0~lI^7h5GZXDR~?R~P&*4c#+)tNSAn1QZWa41vYtJGv#@Lp7FY4<** zBhUKk?+|KN6Q|$7w3mu*W3T8d+Dn$xi0QGp$D7F@^ok0n-Zxh)jO zcFmhRNY*TGdTFJUjAfhCwr`p5us0O>b(R8r7hArxBPu-&DWt79}yiw(sAy| zR0^C@OcN1JjwR<~1R-rMY0vhm+G>@?b9D=BVR#EQeK1QHj`0RKJkR|?nL4fDM;

a)l)0(sLV>@M=*}U0@TPHW=`Q>8C{+v?sKp^Soi9_hZXds`#A~7cHM#IF zNILnl=&Z4B!Hn8Q^R88q=DOG~DQxFFC|esDZWX;E>%)KBb4$@uKN^b72B$gMl{c<# zF;%ETw=Cti4BY}QsjG+ZZeBNJ7K8W7&t(jf#c{4RmJ#~v2Ri|6p zy=)^%%bAmXXd)XEYt%$Pl10IueVW&O8bxi=^G|hxhzZ0n+Zv-EJ`EztE{0?Hg#;-{ z7Rf55*ES`Gd5U-u*-?=1IoLZq6CDR*IJQ4jSC*`zD%a+O?7$`^{%YQ=APb(*Aay?~V6!+?c)pX_r(y>%0VR zT|U^gwZ?sI5r@xt{jquf|MuQ&IgTUQ7Om&~6|y=n_dYawTmJ!@qV|z(4QxT`wretU z8#r?l1R#K<#B;3w{rXCWGiHy-%&5#7++bt^RasdP9zHA|!lT47(>-p{9cP82NLM8i9x1NmCw9lX08>KQDCYku~=Y=0#aQNBA+t8 zVd*GEw|F#D^TNoL{y~~d(_*bN$XN?~R+sv9?I53!80z!2En<$p#5T%m$=?#K-d9@* z91MW{mIMA3&co4giP;U&GJGxZ4D+&OF%K(?S=LLk>fG%H z^>WxR0g2Wt%H(r$P36a`c!V~(EUj(ZoOYaQ*{}l$`n6XTcFu-@mO35LW#T>kpet<~ z@1{H(dePIy5$-ph@5`4*k$a~^qh7W?Tx<3mW6JZZAssG?`Pg3hrQFQ*dZ$N2T`hXf z!uLTW_Gi+2wFpMaHKG5L*R@kU%yqSckL+^XR+q|NdGl%C?#6!za_H8YB`Cz;!kLF5 zNvL~i@5FLSGR6B!u*1-G-kxfCPeHo!`V^W+bgDbo0rjlovp&-^>fdd?+kF49_gEXn zRPALku@dE4u(jM{zKx?qFSI33%*P~iSPY-gQ0U=WKb#ziPO;~M?g8d_O8?-6V85>3 zgKSyL$4Gb0)96r(=Tm07<&z!{T2xQCG^KK@rD_)dxu&&PkLCG=--}o8F!UVOp*(@O|Hm1%Y>pM^rUZdX~>bPr^m#_Yg^}v*P+^K2tyxw3N?MK(267QnwY+rfSd3IQJ z)?ny(#=cR>iq&kKMxDGxn! z$ojmae>c>*zP}vWxcS_sw}vx>xo#8HLr*W3kqT#A9yBi((f1LS@^H*9Ua^;afd*C2s={5Z)PtXvq+%s+0 zo%{53Ek8F8D`RMzrH|*QWSr&O=A0PVZ^k)YDkH4XL(Au-{93X#@@@V0;>r`X@w-S` zYX`OV^X}#Qb-N&U&EbO(-+&ukuSkh1pAXTkTwYRJdyGz_pNxLr<{0Owj&Y8;`1CQ( z)8X|pLKi;FM^xn9slG7k{IT0%|M5Y*hpX;a32jp3Jhpbfj5OVM+&v(TeH#}d4RJPO z-^K{Eip=|b+&6Y*HLX&!4jMX$xpfU}kegd+PTE|YSHS+YU$^T#9T#y$v>qCTUvV0y zM1y{~C^x&YHS(G!Of|_aqpiJsSY3M|7R(t!#7*EUK|5?W|0Jz3?+gRjmGRZ8j@x(~ zA%$~14IP|Yd8eBl57sr`v^93$b+|p*bUwihtb^{vKZA zTrX@siv&@2-bpk)GUxiFX`0s2Io1ap>91v1b$#IX2W`;^(<3)yI;ED^h2?JFtHj2~ z53tHQFAE6RpPfe=Jf|*K`W>}(@8?y@thI0CzPi{s z0C{cU|5R3cAR9z`@SJHQXp5fcbU^O*-5_sM>-Cn@S-_FEL(Z{>s&sS z=d|#v+`FZUBUHa~46vOe+~?&AQjOYT8>V?y z@ptL*gZS?GQ9sEXhP1huQA;X#L8Gwft^V`59Prf57ar$cS|14`%&9cQ&Ij(xbw~Z~ zd(12+&!9?o+CfjobB`J)BXe8PIZWtYm?pf7a14c^|G!{oFgLSCgA(>`VSY z{E2?5?o6~)%azek>fyAYwrOZ>OTKMe3^5&5=oi$nWWJj0<>nJn>R)7SbM&uSuW5U4 z(z%2bo;DJPr^;*VaAA1&e6Kt_@#c(B4D;X_AsRspXOsi#bz=Ps@^4Yw{EWQhL#Pu6 z6<*VbU()|viQ3w?yLHV)X%2Z$uHb{0o8KO=r>-~MXJTGL1Qs?D>yADFeMa_a zc$(}f)=;#JOs=WCjUS;lhZ@Lw?nE-F#{eqN4HQk&_PB=Lq~J>c$o z#8RF(Cr15U^nE`Ohrn+tt(89d7sJT=oW@kQMx_(v>oNy!=G`%{fS1EAih0s7HoBqD z4lB!ggsU?VyY8*)>LcJ$lxoP?T9r9PxKra8xrZ@;+yA$3bFJ6Q%S_s4>+JbFt_$&7 zNoL*Hv^#1e*EDcWnw<8Hd6?h99)ftq`5m7+7c1!J9F> zv6uWEEvi$-#3?!m(Rg0hn7;!%-^W_!couS>TYJ$5@v7-|GroJ5{*KEyo4;fJj_|90 z)%aTO+frNt-jn$|jshiX<7n1D+m+Y;_(t=0{)ade^(n~Km2@~$YEI3e`8zfGI{r6* zr)7Vz(5p=kJ9|FP-X=jbSHK>`vZv=u1m9-GNO_UGLOp+tDy-OdEd^-RY^mg})xPbjD1Ux>%%D?Iwz0?h2xdzPbs`-zDuo+wx1o)R}$Z2zKc*h zyqfRA^eEX#=AG2Gx5P}$cX>;er>%Pm(>aH`>Xa6aPNP&-rzW(CuNuG0y{A^E=G*Y4 zGB-YE?Nwd)f~4+>JTtBb=h*dpD2Ao%ukeEK}-3G*y$8=qIr$xHRkl1SV6g3wO>ksHEe1b4_URJRr@(< z4eK5DZO2dFj8|^2%N#F0%nFqyPN$INqje8@+$<~9239{+A$<22t& z=$NNp385TYMiCu3cxO7gWBfwd9p1@iUZZ)9X|#EaoyteZc#kMYMf{E!=wRvi@Qh++ zAt##GXkKGUCyOS>HT9Xs;FY*q$9iIni&x4@Xe(u2qj`aN#~enW1daTGO=~C?iVoy*07%C=)8G0 z=Gh3=G|#4ts)R;zO;J{e`pXh0Pr!A#e3(P;{pMIgRWd{KY|2$~I*m%URrB@^ac|i9 zfGV%3lJK0cB~F>O+P^zO+qOqckE!U|bzBw)C+eay`)Y$ee<2r|pJRSbNf(O-XFDFF z{5e+EGB}pO@wp2)(e>)Bb5@E?TOxq+jng{fx=-h#&h;_-pZ7Z;ZOIy9$I3I((f!UK zu)4oqdR@1~ZdFU!s@`>fIJW?{ymu{U-Pfs8VoR}8bVA^hLG?}uLOHpnG9CJx_3>$U z)NGvQcjV-K`aZ32{rEXC)z*lh<)~Mpnnta|_R^k^HpZ?wop)1SZLvSo?2es01>4%| zOjzIY?oTIn-$O&sLg7I3&U#t#oOTn-gKJ6C`S)=2*v_2tX~MMAs9U3~W=pIO;q<*4 z)`!sg5XO?~|6R_^^xc&e;@vrZ@>qYM#b3E0-}?hqwd4QOt%(cQh<%cfGUkyi+cyH) zqL;*%xLVc-w6LrZyr3nsM$CbhGqRI#ecZsm*HAs~vRywZ1=g^mWgKL+aaJ2AvVB^$ zahFsHf%DqnQ(RKS?Zf7K!Wi*Msr|f_vJ49SSz|7hMefh z9xIu0j#Yg{AyL=FUAJ_7LwT`N_AuMzjXh7FH~AHxBi68>IleCOvKG%g%-k6J0hSpv zFO+T7I$o&d#lV02S@nU4vE{{lB*$ncXE)@olKqhPH9KN?vFTXP@?w@36B)~0m&%K^ zA>uLq&z#t>P@+8h-gS(x$osw?Jn%OQXWm*oH&o;yHZU(IxQohOoOt$*?Cmv;Z{Fxy zYSx4=?rx=zMi*b_=W0y&wVb}$b)UiOy@hxa(8eX?OC-A$Eea{JW?=AHNKo1Yc zffvbnS1lL-`*%MM`v2KrO(?hOyg|#=~4`}U&N(mgG!oC#)zx!Iq|9Ce$U$u zdA~+k&6bq-f^DW`I{2@+C&C&ww2ZZ^y34A&L?W!Z>y)ayP%VE)5kK^k7-P?-XVuOJ z4-yr1h%-L<^8LTiU+?JO4MmC2^{H+XwL9kM^<8^hKF!y#139{t=%v}eL-eJ7ChkL5 zbK5O*NmKx?x7{+ih;kSsDkCRY&2c@}Kyz@Q?Uu3KGJ?6>wWNpL9pJavn;2uc<9sOM zpy0{ZgDzOp?wUU}9aUMalGQ5tIwJnPT&>f04}V+cVUE5UW0{2t<=OYHRTAsIeD!S( z)yw>ARz*YkyY_}cikUw&KYyQF?Japc{;4KEJfP5@AFj4%1AJ({&|1Eb?b!hTEpIh+ z&ldK>@=9Vw!>i?$m>xN6Bb2hdlI4{gFR-T}k^kPhuCB>2lCmdYe$ea9zlc7X9{~z# z^6u6;MD_jry}qLxm-C7vXQ3xrADMPXjjH?Op-DxcoDO?Yso}J0K&e?RpMaEG{j$e) zLpf4(b(eiHmdmnSmT2Ck{Ws>tv!R-rdt+K&%ko-|8|Am0hLiW?YI&`c0&7^;GLklb z&ipwit>(|2P8Yba@AJO-bLgG+p5mwG&%q}xcPV7wEnG`}%~5a-i<9$=ONc@9gb%YK zG4|&y7iYORwzBEIr!eMJMr!!{*t*1=FK2l<%gYJk!?mQ9{d-a`W)5Dk`ovrxk#a0i zRzh1T^W)5q6F#y1UZ=F*E5!bD^m2$qatK~H3|CDX$$daOl2uxAWZKwk9T~|(q zYiW5o$49+7A>~%TmX~`>{x?otwv%D8ixYCZ-TafN@rk5ct1rmW+N~&}JBV!bJo~*Q z_xeb}DgeEM**gB4=mq9L>(XH-!)hGuWXyJz#T2+$p|+(Q(=o5jyf!DTmVLAAn{Y$v zTEibD1SHREvm59Rh>Emjvu|ZRDWjj-J36IW*gvli)woCSC#sx!LD+U||CJDh#{K8& zv;mFg^+j`3hR^PibZh%7@lLwxHMAt( z-oGMPo~+Nl#u@t;%MrcGu^nVWTnqgYui8FFepny)TxiiBi~eX_Etb=A_9+F{u%&t3 z&-&+zFd|~R$Sa|DqGn^oo1zGjd<15>txxV6JXL*V_E)T;6U@ zK62dIJ#Erz(I1Qch>Vx6F=9cb$C#5ZS~(HV{79PV!_e2=d5Lvd6M6egevMRb$FYo( zwvk!4jS{D{ai2T<-=aC?`6(5bKEGs+21j(^XPP_WbB`k$)F=xIS+F8 zP7kx+o6~;$PFw#mzE|?3+=)P*oa1J>Kjfi{6|zIQH7n6rqwOL4+UJ9|c}^O`JZ(XN zR%7ApM`-10SP>QOA1MyZHUW{%P`jMb`&^ZFMwUZrNfYMN z618ZdCTbpl^sl^_QJb`~WpouCE!J38BDET0tg?H`9P8|!lGb^&Yex5!culRk$KT6P zvk*eZI$z_?77oRIT6`#7^@~chOUBs0!bF~|&%QQmZMOR!Y2^50s#9uf(tj=TYfz%S zM)O0CKz>7()t!S|)`!zHxmEfA@AvUwOPaOBv8)$EYo+J0(lrk8ijFg;_UJ&2!*Srn zn#2l_xiC>%z($|yu2NC4onj$dr+?0#P$M#xA7VmH>>n<6YTziaAqpl{AOx1EN zvYi|@$9J_VA9Rnqohh$YIF=bsZ@UupJJEYf59xPUQG;|d<%ZvNNi&s5iTGgt@I{-9Ri14RV?O#hy5 z-q7FgNju>0@94+&aiR0c(_t^$w7jfXj(n8Cy{k*K7Ij!7(&Ot+i{!{E%C%pNDu**l z-Fi^V4#|a7!_#_gC&CwSj&<%~TQCMaj*IHR=7hXxXK2_N8loTFHK*U)yZoEgm!%ZA zsAR7CSs+;rZKbS>k9F}8K8b6M?M%dZbrNH2v|EFvB0Q;`@4enyd>!-E^pa1HS~rqq zB0#-->cjOWOB}O?Ma%J4iJvqN{1Eg0skdlnbfgh+^Ay+c6zzl#aN>SiQmX?HRN-HD zXOFE8V0ymoJBo$+-9=#YtlNjrx4GZbsu-&S$k7R}mC&MpKVmW1)%}+Kp#~87HgrQg zoo*i`%s9m{X7+TKJsC{z6yR(m;pIoZ&%pWF$k)~zSCZ!LR~tb*Mt*x8CBzwUR?fJX2+@4_nA zH~Rhpv45!~hSBamw$nUTp|^kCodq_Jbq>BVkJT#IeK`$(U#@S)2eN6X1-+f^5A7m) z;MX567MEb}eTwfFv9KbO%n=hZsT6oXt2 zz20s}GS~;fUPSnh$RKPt<;begZg)|woTTy?5nptXVdfbbeVXOvcS6dWceTEEWz~=H zEAL3!WT&v5a4(byvl6;?8@Ep`?^#*>BY3g5_0@1c>_-jz;~w7KVttUr-pX}%cGtWr z^Qz3N5;>FWyy%~MN@<@MW7_h$c=CicooQZG&Gvwvz1DOWUX_k{Wc2%5Jqd3MXDiJ= zCoM#RwN>4nRotaF${s2Z7}vr&kJZu8Jl17BR^*wv&*g`Qt}cjASr$+{H1k!35}}6D z_4YVl6 zvr254>@<&<0&CdQGBUGXkJjtaA>Ul>)0}GFwfuvU<;P5GdP}Pb9*3sako4TlOEcDH zdZ<0{B%;YXZr+ne#CxGEwk{E6i>(VK#%QNGv30Hr3whBHv?1t{UKV?72%2-%hM?n< ze5|X0?XK~)MEHAo$BET}g_PpIc9%yS=P$6f%T?EzC$Xy-{P(mo{{_X^uQrcpfBsv_ zn3Vlpbbh?1-Vi^2Ie+cfVsEH?lwP=RTD0DMn)?UlPB7EI7f;yIEOl>4zDKUD7opBZ<1~4$ zTx;{}vjV8y!M?n*1ju;gy3Dv>wcy3`DQNBcaWTqtgkfH+PC4z4+PY7Tu*96QhW;t(u)r7NXlsC9KZItfkd$FE5PL7L!K_0w*qJ%r}&x;td4#b;A}xrYA8 z>CM!V<}~P*`e_R)drZ6vZTO7%^@{$1Z)-gnQppK*eqM6mHQ`jDai|L4bwfW_jeR20 zu|0eEJnB5KTQ^5Ha8!;`!fC*C*EI5vG@2IsosI%ECU-P~&-D2`ef;l2RTH`ww0svn zmwsQU%Sv34czZXThwxFN38 zWgz9n-D(HutGgyinKm*fms9kY`}BVKU&xtYf0yi9N-c+sT&_9ZkoV+@{oZdk|A(I1 zs=4sVbY1qROO;zSmPj|hk~BJ6T#|qL;=!hZ+Ee?w%M-N~m~Wxl`i|;j2=!In&rMgp z$0%@y4M+4_xG)_vrzI`T(vcn z`?j0kNvi@6&Xwh{W79@o8@Xn09i>^4{rO!KEUTkNe_77Wvot?#UNzLfv-M@7G~4BH z#NRi6p?)RT6z4_nspP|R= zaHq!K@}w;x9mKB?OQ~xn_o-Mzh4d})r+mI`WS?mDft&c;x_RRpM_-+`wb5$`Bj#yF z6mAVJRzOeX7#jK|`)kl9g{kx{9kC0!u{=NFM?nnZ;;Hg!T-y;(_^DWq#_=hhRpUna zzU?OFy>@x$8OCEBOJz5bUFp^QILFfz&(U>&%%z?BPR9Gvy{2p1=F&0`O|SVmo|wNsA-aXbQyjl9OoVopM*gEoKYGwzk$VuMocH%3n8X(C=B-v0<%EFBBccu}J;uejjT zbZ0o;31@Y&XLb@XVCb1?9I|Ws*u$H`E)|}kzRIO{we{x{M3CwK*ogE~DGRl{Zu9e1 zR9EEhy&*j!9l#L-L~nfg8=eUA7U<}Pv9f%zc9Zi-YIO=a6;S_x{4sdFO?Fc{^vTg8 zf6co$tp|S zO1n4pSGBtxuG8*vwq3gm_QzQ;?ao-sYxnwkIJc%H9^Q5S;VId{8;TA{g#8i4*v~g# zZ~j|FK&ifMu@loUar|9+bS}Po{+VWNRoNxkXK9XWYwNb7Hjf++)pYHaP+4oW^=`gD ztrDCGu)Uk>RtiS)m6>*4oye1^Tnh{lat>@&VmLrVTM@s`)Zlyanbp$BGt`%)ZkN)SE9p@Y3xv}T*@eG}AhwR39 zCuc$YS>pFR_Vw>-p|@s#d~RvS!u|;Q*&hF?<(X?U#@;#96Y9REe9tK%2VUD)hwc}i z_>nr5q0hq`>XLz4DqvB)t|`?7yYzNA9c#d-*6un}y4JH2!$ko?Y3`X`5l~u5$DOGuJF(?#U(lsG$Hq z((LpM+YDc7_sd@VH(80#dul5j73XU@T|#o6r}&Iz&MI*UIBu*Dky_!_m{c$Rb=2N3 z4t+vM^pkPufXLA&gFRB5&jpPBiLO&QRPtf_YQr5zj`jVP(D!b1tmA!Zt|dX(F>*~m z98csp&tpPs*xLYZLF@PwWkgl7h#GEk zE6;M|<0yYF`y^9rlT32->EE)1j4IWC7(mJtQNqfr%m#bV5ReALZpM6-goPRC#sGz{lsHYaCn z7g2v9c?hfvzgk+gwQOgedmqurp;`B>W(@Vk?N|8~Aii8}qLlAHH-z(i@ZHjFf!6HWvLYQ6c!*j8P4r(VgDej8S>Wxm2^ za!p4)#lqw~6nLQ5lr;x`y>3G6xz(0&$`#{n?`!IR>NBA)i72#nfss$kby`;#`LtZ; z_}K0l(-EOOL+56>E54@uG7TZhb6eJ2?v-n=kx$`t8G~GNoIlPo)a68k&VGI@|pPBORt(mU<$Z8(>eS( zE>?^+?X`}(vX7~Jx676A>=^ly&+I#0a{A3EgF5Y$V-C?Gv{;%}zScbdKCumvnttBA zJW;Oy&c-_2ySnDnC=hzXt#J$a=KeF*R#n$ZslRpFQ3X`Jpq2z3Ef520$pmWDcWZ8O z1!S5nt{@!IdQByCSGdVgq`!A7#RP_xfRzkILUMC)xs+oL5k=~#$k$pHSMaIPf&%>e z@w<-A;=AQ7T$iIpD&J-i%pwRc9vGhvm`7gknMGheOc7PeF^3oh zZ$YiC+E1$_uv&^-Ek%4Hh*elj-ESXKx85BpYNYaA z&y)G{!|%t)C1w$@vd3!?EY=W8@hR0;LoQ{ShhN@H4|f-Q|uKj%!iARSd$o1h~oj81x!+)-}`-X*!+{B!8fpdpVOmED+d z&Z(nwua2Hm=fa~YqbPkYI0YH;67=O=uiG*@LEh6C&@Tq3GPiXtOS$8cK7U7Rj=p_0 zdZND{y2ZAA7u%h<19!-cISCf7DQhx)eQ;LxCmQFpwK+a|aEIbc(jSoQ%ZYRebz5oO zYAfUTwQY5#_v7L9ozsFGoey;izm}8mi-L^y+ZCCcW8PYx zKgijOJv?uxm$l4s0rXRjN}{*K!v7EHAXtiC)^6HZLe46q88`ZA8e6AG%*$=kKXoKI zN|nafD!bgdIb73r*+tcA-n#Bua=#&@g8jJXWZ_|ZVZWaca``}3A2z?t5h+#(Z9r*0 zQ+iwr?tG(;Xtz8Xa+@CgN@)|~nmldX_|we)tA}-xzUJu72C0Dtxp`Qt)VGl*=CRTg zo@e}zb&$NV^k!R&gK;**d-_3k?!^W^8ppcO1Abq)_nJlroTZIO)~d!kIqikdmR1w* z;hB7n1I`rVz4v9>>~AY$j!*tyHJxL2z z;A)6uyrS=$#!vU;Sw170UD8^mWs8s z*f~)VmiWpv80o9@XFG81KIx5nS}Sn>R7}#&{bjU(bCz#NmqMqntw;GxBiNSR>(X86 zgOr-AC*rxSr6rv9zNcOh(Bq#T^f-G^Z|D_04xFNkU8440es);`7~Pbj(xA_W&A(LJ zQhv6aS+@_dvCwud?R_|W;`r`t@IPJ+|3eEh=V?BOM(Gzrr23LD0r0>yoZQ06Vp${# zGqv^;sPXkM_t%5=ec2qxaU%%VbUXOpK*ij1JE!C1v$&S1S{!QavN+U=G+zsCqQ>ej}uAkniSg?E1;p5?I_W|2%WGUFTxht^ zahv>B(y{VBuG?X!jAiM33anux%h7Mk(n-yIeSex(d7h7KK?d^gl%(fy5z0Bm65Jll z#}v;&T_z$s5-raAgK6}=r4B>SndUGd>m#cuf>sVGT%uNqN12i?Ph8Kmq-z{TN6Pw% zzbnnoALvbKEAs z<@A)iCs&K(r4(4hMwT&@#qs*Y@if#0Y2Y0(F7jX~S#*S44JA8D7)tJelD{U*j9q;e zOST%xB~UW=w{ZMsv1E%S8%jn#FRYHWJ*n?$FBoe2xo5@w=FgOqdOqxBM?We2eVltz z4J8Z4vsiNM3t22#cw^W5qQ57-1L`B!_tI)YhiVhsNyOaOzv3c1_s?RbfZJnpVcLEbl$oKNyotXU4vqjjHsE^H(5Qi)iaCj z+(o5EDC1|8ePzD0XtYJ69pA}sIn5>S$<=UnN`W=3W*Hk9&NiIgA7_i@SZe>DAfy)T zT$Tl=wSeki4abc?-miR39ev-^nHg*ERxYD@w@!@m-MrV(QaP`tWMz&eVlJF(k#ocL zqJNgf_7+1A>u%>ng00dd--XC=Hvg8^PgxAzV(1~4;7m!_gv%xrmU2|sg-J(!)B0V> zcu#BBVi+Yl+!(sf5m;Mr1xLX4ZIQtLJr-*a025OyNtoMc`PbSV9vY~8+B8EL1k3$L_kX0hzOeWbc? z)53{9+L&WALY!G2n|4QyuA1MKlYaKD${tx8he`&BaT>2Czvk2M!fL)q!go>gb^f3= z_}SvMAuojW!wx3kme(8e-)tAMpq6>w@EHFMS)z~+&&X#-=P2{!zMhG|#@dz^y9aAv z`;!I9$aQz|Q0oXky?ghm?oZBPxj7isJUNl`_*z5UxF7vwPTP}9ZM^w(j+1t0J92uU zr%zW}SM%=N>h8LmRNlM$nf$sN!qDH6XLn20q94q=BO2Ig^=yxp^X@)8@Zs4IV_;4+ z{|?nhFT3}R(ISIb_cp9z{+-j^?zi39X!GyPzZ-kvR}R;if9IrCek<4IK+D~eXVyn& zp1OaBbH}d+w7HKFOFx=CM@q&V87FDKfBBRMZ9JF#qi>x*Xc}ME6NsY}Jy)PA(&oi88-kf=JPDA3inr*{9 zR(F|F;9`Xen6h@T{tZj@Z!mAJ%!R&YS<0Ks?KA4&;#dFeY}HY&UD@<{XVmw9#mCNPV8AYlZnY=HIaH@9*D)^6qz|^CLyJ zgUoi2m9%Y$O3;)3j-tt2Up>!`+72??LFRK8JZ0-vf!zt)igzqjGcN&M_u4x?*ZmQu zDEdP5uG*`AH&(U0qV3%(>ff~8ydn*beFtqF1028U)igO2FQ3J=&Bpl1q@OQZADebZ zZRDCy!ueORnf{)z5S{t&gk3(^L-W_nGF6VRmaRJcnk45H{b<-H#qlkDlpy-zy6u_d}a+qfuZNtQJ^j#sTrbMRh#_xy8tLOp?8lW>~(XXc-2oGZF8&9lt0 zpXQ(CG_jq?Q|o%=xG_eHp^nyZ>NIQUzB|;W`-bNG*5o-$F-P9frSFa^Z$6W4)7QpP z8P!2JJr4DS?ca^h&p9{qoa!_#2`Ale-jLn@u=$28_t@V1bUN2*Nz4WXu4>f&VhiG?b7Kyb>Sq|bkU07D{3tF3sc5~~o9s2*} zY_pFE|3rG}6a7QJ_>z2iWQ{HB$JsVRiOdNx{?O4yuB${FO3d?O+2_o0z1VT=oIu>B zg{R$TV%*h|(RQDn7s)T-1H+BF2ju7mlvM>M03^8-)+@zG2A< z9d0a9st2Et4dr@9eOFW(Rcf)DRtbj4WS?`$OTJo(H^I^Isx2Kk#O^J48)x*-=QG25 zRt2W#R{>MvNvc|U`thji7wS5HzGH3jrD)*<(F)Vd_Iqc+`DDIz&#o| za6ItC?^bc{`YpQa2x$&cdhW8}$WiddZMCb?Bq&v+NgVREe zvmEhDst&XcvSKs%TGF-tU55Qq3anu(%UZy&UmxsOMp^lHO44(o~S$xIz3+r z&bq!#cX@(Ff4S$h_G9{I5-l5fEc+d9B@l18r#(!l0z!OiTt}7^H!j@`M(6qxhLic@ zn)eXGJ6b4tPm%-eJ#URqmwr=FwX9OghoS#cX}CDo?NJF8Oump3JsrWsL&0 z*|&Pd+?^`du{6|yjC69E=VFD-T#hm&inLO~X(j2nDpd@n8TRYSlpFh&c08uO8sY=M zQ@2!MfSP;DXGj#^@)<&jF(@)u)2zh^paFc|vp9jp33A#?th`*)sQw&3$!eHcMzI&# z;eYE_+N85%y4@*S;~2hUDor>8+!qHTXC;=h95-GhocR zkC9_^9v8m+ns6TCcIfzsj+PuVu&Vfc*4+B1!FP@K%#`&%Tj{hao_j_J5AqpTDHmF$ zyj9AJMRC`XMs{}?GR#q64U1aV42BFv`_)canj29Lb#3nxuyUBmm&D!S#N52r;PD&< zN;>LrQKNLn_{UIB_?&vXBRXz4(Qu-Z_L@&wwgz}cE=DMOqR*%&J18xDXUNcyq2oLG zt)zA3ede;bB7aOa&Uy3f2U)Fw)f)KR1ufRIH+oHD&g;D>+I3t;I+lU4aYKDhETf3C zAZqY|=s8C|!?D%BS-$<6GNA7tzMH#PBRd78junO#!s$vl`9@y*NPna15~uxWUEhUU zc881Is`6-kS{go{f5t}6%Ag(>a`AYGr2?r~&fLzO=#PhQ2QE7!4TNZ^<1@>cTgE)6 zm&Dr0HO&{#v95-G4gCsd@%504%{scw796nMV)5c z9S;0R`>iA83r^AXc*8i;Hxhh z_kV5vOc{e4%4puw|JQ_qky*W`SMMJxYTi>W0e^o-?^}1i|DY_d{xi>`muG9;`C4Oz zWe>uAi`a+9w7S^MJ1*iG=lkQRe|-cP3C@nkC*RW5<<|dm#U1GWF6@*-Yj}gFgp9u? zKEyd#hK&syLp#J;rWZDbzVrFa(6OOoL&t`W4IQ_l!2Wy7TM=Wa3l+yb*3G1&8q_f2 zuCnNV`_ljE?clN6$tRXi7k_paXwmf>V}7$!Pf~<1COf91`JA8YRu^68>K1~}96&aA z&bZ=OMxT+zndN0isLi29S#5vnCFRs#4|T_uTgQrSHx^gbBc=O?99hq|Ajeh>3tBR&KkAWx&q7C}$C^TN&fDxw(W`!o@p;k7VavAcNN%`)C>+ z)-tCX#EQz*JVc>Hc>TAE5^9vy?4@~#(=pJgR^H@r)tq?A7+o)NQMRCceJI!qXG?nP z%(?y|kF1vuf&Lix)U^p+!UXI6UsdzC)rg~qOP`@QU5az)^pQu2I(0z>T|?LJn4`mU z^2qyTa@@=B#A|(F-p?1`{gV9Xrz8V6gcKnQt*0{O*0AjT$X*%iI^v=ww$DJ~Mq_MZ zZl8g(Sz&ez8X@F7tFE%@s+{H$+b&n@Ly}Tp4XatkjJE$&G~2HGGv^SOc|f8m{Oi0b zVR=&7+iUlLwD?p_|7j7F950m7_Zk`_H}lerwVC?473c5qTwMpv(hU3MPjX}5ZjgO? zLI13ei`AWp-q=Om88WTlGwWv^ckJkA0dpG5t*PY_5SI{7aeO_TM%|ol^(n8}2g@Z) zk3w250aY{m7GLk1OAyO(I_gAfiZAC-&!?^Oqd|siXr8Vum-{}22$~fH` zb|3mfqdLQO81DkRUkzMl$lZ{;=vQ|w=~Q7#(ojevwD?`#X9aJBiEDj%n+H7I*K zA2k#vYa!Pf{^?^A!gX)wR9?@R_m-}rj=z7L)x;ch?az0#*w*(X=N}0DxVnNe-j)@X zYr4{*U({!%Q6-EMjz5pkM;Ku`y3<`{#MZ~}T8_CiT-`c%@hVL5wuHmviVmr;NB6`B zI9YV826oSh=QLjO@T?ZA;l2}HgRkgk{ZZE>a?IQ`1esecu3rjiaZ%X~;b;gA^@3sq zvhRQD-T`@{Ty;HKTW5_1ejcb?yOy`MOsmw!@$0G1=GQ|_S);Ax&;&J%-DjVRSp7s= z$=~l>wxX$BYSF6}wL-PsWm9ybM&Xhc)TBLrW;s#_%@W_etEd%rnfP3HQQSqS&+P^E z6ucwqJ|in76;ESl*uur4b*FK&`*bNnQI=)@V|IJ1%GO*scz2q#?6Kr{$c-Lo1Qa*#W4^DN!x-3q^O5{u-Zzg^i#}`~(f^R0 zYs;5E$oh6;JKSa8LKxxFb#!ir`-g$w&WOWMHNhN*e7VnaWlfdiVbNab>1cjOxIX50 z2zSKS)MK+9IgFTE`=$s*b(y>(DfiF0Ye7%jjb+ToX3SB2{s&p_7W&G{r7|#9duaMa z;|q*Hi*~!&TvTHE7I&T+cV^^=lM3I{4?0V|*gPQ~dP(y7kvK_@+@-wJ60w^WscWwX zNk;St%Cmej8x&evq5+Hd}j#Ix*OH(2iuT%U&EZ(j3Gcn zfP#(q3ZJrHrm${(#_uGM@ovd#`<8qh4utjpy!nw%THw$9TFm^(_sLby>&abmooAor zDRNEY3mP7kPx;q4UVldMM(i8`j@DPpe~SE`J`E>;|K90Y_nSAwi-?!@8JlRkJ9_3v ziof)lGxH&k)bno7#M4lz#d|>e%-=l|ePMnl3Fz}&a1hqL=UCk{`;HYHbwyH-cwB!9 z=bqko{I7`C=z83Xcdv*F)1MZ`G@lRE50Kbtd=)i#B$=P- zA6I9L(V1mjE;>-IE$B_|?Q26?=c8x4WNh^r>(8mtL5qUK7TsbYyUl{3?+MHQIoVp+ z1Pw){SjHkCCE4SO>#;inY7{Pgnkmg=4*WB3#g#A(pY%7rrG=G zk8tOTh9+cOa$RP8p9t^3nj!uJzhX}Gbc|(mvrKaYu&sRJr_|YgBwq!!ZrHH}-v_xv z?BPSVEoX`GDta*>h6bOjY)j?a+iZZ?R@o~wk4hLXa%+fYw0nk_*&l<)_K|4tcIapH z{V?~p={WydTz6*|&8IP+W~@&W zYSghi{Znfm>XEk0CTg|vJ8O7!tyu_Ya$u6@gm>Q#c}70ljB)gKb3VKaREs?=Uk!Z? zz9QRlL%(0s2tLs}uZNMmq*w5IOCKIhS88?#`ap}x=T^or?XKeT-xJr|4rj!m-^l&u z@sI;Y?A5wC+WCv~^jt1F|9;>%j?Od3AyXfjX4o%Yn;ZLf!wB%N#676TV5|;UBu z0iQw-hp_T3r~Un>>@Id=8F|adkIl#<6TP1pHJ6c|Bd25RkH~AiR-i8JEqEL?zpsaS zSHx>RP&{y1Y~C`)unuSgMLS(sjbXWhtJX)9%McF}URTH0xS6J-tB`zN|j#NK=86_l))d|q31xd(gruv70H z;dsQV_c8weiK_p``WVxF>kw!C{o%X&(AuHyIa+WRT=16WiOTPBo?I^~fBWUz`_MUz zzOKbPVa@@g=rcR)fgK+O>9tlrfBE)4v%&d~=z9B%_z!(=$F5eaBjK;&+$)?|QI8Zr z4?;6zH!!^NG5pV;jlX}KbmAF$jJ1A8P0wp_0Ke`mwFK!%c0!!DLlkNNsb`TC(Y-M9P`kFLcZ$zd#!_nJ=7FjtN~YsgA&ex-S7^YL-? z{$a?!QMMMIm2^*fM8ChISFG|)>b)7S^f=6E`=o-TlC8ql-D$rz*6TK*6=OpvHnfm-PiTXJ6xpPGS}EP zj*B;^alNHu-P3ajF#`RTV*cD;G>5=_KE&@W7K5#Z-sLDB#XUWndmJ%F>BZA{COVgl z$tKJ>Z!@0P&tJa3MqNGkP@{XRN0jsSIKG~fh&Ak7j!vc7x6XS1{J`@dm%#Z+XnAxd zHE&R|-*(ctRDs03FLfK2>*W+mKKeNEdE-9MnNMgwVM*8eNFa@_&%wl2OK7!(K6fD( z?6UoJ&PvgEOI^Kuy_pU0sunf3vau zDfzCwFRB09ht0o8*OWM4<9e%Bk!lsL2|lB$LDc#&&)F^&+odA5!(BCblDiC9rW9Di zT9*Aw%Qh^PZSXbfxcH@ucR@?Xv4fJm6B(QviM%BA{$i-)<{tJqQgBqG2>Si05=+eFeVo_0))Fj^DSNH12m! z-vlYb>Gm2or532A^1&j1pzWnfS+O@Y3YVlWx6-9&=DS6f?vA7RWxpR!XpQ^|z;>i&VEserPe~#Qev^G-Ql9 zyM~JPYx;RfK8Wn1;Jq#3JIFDh=eP8gdP^uPyn}aO@cTHa6Q?cS(I?7wQN}elca97k zcH*Sx6_xmlM;Wfh8agP4gi4&G`5lK5uazF1mZ68FS*#XFJI-Z}(Q7$Ey`ThkgrjuGk{TW$Gy%g;Oh!*7Qar*#?aIWiFH^&IZ;DOAEh{yp2EdR~k8`JZCy z>sF^eI_-|y*fkvIXl-b8SG#>Aax4hJY6q-#Ks3Y>c+@Hf43P@I@wH|#*k&0bjVZ8( zjkKsSb7PF4T5_nu_0w{x?$dFWeMwxpE94i?X${`a&8?)HG!(nv(MWU=x}$x}`2TSx z`d#Lx6dkm1{WNa3JwsTBEv?V9jmt*mI23xJ#HBf1wRGhGdN~NcaR;F|-%`$y=<|9( zIS=d~e^xzH!|Bd7^>(RBuq<&hZn>rsxQn;~R?MnLh30bIU6!uI7m}sp)!@Gj1EN0( zPJ2Sn$3Jh5vwF15Yx#Fddh&2l%72kghwVev1&VM&W1h&A-@?yvD(Ixjum{sycOH$IoQtfrj|GLxoe;DrglWt!al!#=LY9iXuJ7abXt|@;9J7;`_%smJudGzzmp!jqpM~Y zjz!`hc{48SO3XI5vOWt-ODp9?lW@ zf9MYMPkTeZ`_I8s@IGF{|8hFHJPUGy6P;!Ez*qDaBGP#Ee)Ip*T9;$?xpzv`&~TDJ zUU1i1(#SivL22}mKrcFp&RuQJiS~%r<5i9SQ>(p8TohW>r86UlaAD^=PMVn-VPKT< zMy07pQ%c(q5#{)?CZVY0ge*O$wS7yNNp|sTYrNa>yrFTRmn3*_+9;mUy5RgDXaqc? zOqbj{QzY2&A=_BDs{13$|3!5DU~)Y0)kn%dFmL@z*VhAOrpqw&B}cbGVc07jyX;ne zp3(P%?_mq4$&YCjL~5K&b0&X%t&-=n{n0S(7yDvLoCjUTWk}(RfR? zL9QBtSyr#0yFK(CA_Yreyk1<88~0jk{bZ0ohEBq}=XalapIL3*+5T#fDYxD!5)oZo(ttuY z^y|pwo5#+z1)Ip2^n6}EvX9T^-zm*d)A3rZ`Yq8mrOEoT56pvhP-F5AS)60(s z6b7w-Lzv8P*fHWT?$9o4eB9c#thMs*l=PUczYv|^IGXd8CC;{=e%JXBS-F4kw;m6k zH+bFlHQfarVzx#!Y3Vv=XGN$@%+|y-HowN9ysybxq4wAOn!X*{Lo7TttJ>SI;o1SW z%I4RMLH*%cnqT90q%m8QNBm-QPTSUeKX^y?U*;II4@DNH?S#rZ$PZhZY)xca+cp=3*Re?m0LMK zzZ2S~r{oVIcVzz1DfmOkXJfU^Gddm5NY-52k0)ARu5&UzqET8bP>W}Wyf*B{xbeqv z(rfC0^M2?Kgp+~y(Kfnu5?@E=Z5DDLETnmHr)43{pF5S+UYRg`vYObKZu7O4f#FnQ97r-pXlqw=ayLH^;jaW zoH>%b))`e#^U9w+>WpWB5!s1|D!uH?Siq`n!-oE6zO zl<}`73*54@Tx9`CoaeWP)o1JZ?Kx>;43OhtekZr${Ekl@Lk;_Y8eCT+Lk;i|a_27` zc0ZF)PJPtidK?*Q$mzK`R%&eAwZ*oCD`}`fqW0-E?X(u!(>k?TH$=-B~;nUJE2J`V!IreknB^N!F$OL%JYQT

B2@E$(0l!nXnZ`%;zBa@Gl~3%YeJWm)9}8u{LK`&vgO*!T32viZ3VxpR0e zL`RyP#~SXgf^G^DNY~k{{ytd!rc8RD!9XU0A0XpYC==n2pahZ#$Pt_@r0dC)cG6 zIt~4Xq=z1#O8Svr)6U_Nk?j{|%1H)CTtY75*SK?mzaoaPShm-VtN7CQh{XTk;W@dcyl2=; zXcJ!zd&LwH&B&gQVK1h@)E+&Cz2H9!$~5ei_ZgP!HJ{IE@fje%TByCXU8JW~Im73F z$m*X_O#YVe7ihqpE)07a_KH!0c1jLc_VkLNoLX;lUbMjvEH>aB8B5{SG-R) zoMXwGmDwFiG{@1#A~smNwNb-4ofC`NaCC1(uJbvKs4SVOS88#Zl4QoTTD#k;tBASJ zthwQXGS`cam214RTauu0Jq_|6ggl@1g4Nc3wb5lp=#{QVXgllFW{NMB7jrgn4$p;i zENLO3k>P{#IUG8TO3_8Fe)tei6wXH#&Ie?0Mcv@f2_NttYwMjTwR?x(J2A8}{$3nD zPaG?cy*T088(Ns7xeYCd#*MEfUF+YsrK~d7^z+`$ecN@^JDPw~Cn1Hs=UGP#b=o>KFh<4LYn3D-|v3#n$Y5OBr%u@FQ-AZt$s zZZ@2AYB&d(UgS4XA7mKEFpk(NcP(cT`esZ*t1)LK#>NR+to{wfyFO5c5&vuPVn;Xr z?YL}yxJGQ*L&}(4$GWd?*Aa2MwFt&g4**)6#_k_zKCHXNFSvg(M{%tGSZtN#@1<<} zZP~sjEg0>de3?tqeu(4VoHR~rlQ+h1 zK5z0XK1Udy+b29{QJPc4au%a894Ck^e>EJJuYK>GnR-R_g4gs92xHkOPz(M+W(txr zZ)Cg3)qbFny(7ebP2-z4x|Zt8SVkZn=!0@Q!~u}&g6}bA9E<_5_TwXfGMY3JIF8ct zoLZhw?&C3s(YbbfFHc!#)HweH7#2OFKy{occqn5>jFh|n_ZjmPj(4lqgY(_fcwO4| zlFO&!YcGzH=Z=vF`OKF3^WPC?0ZmR>CHI_o55qK>mgng;i*lD-$Ie`<0B|eIKA=yZ znhz-Bk!!!`w>&Yvw$Z7TJ{nzoouA8h@M}4J#qapqpp}lhqhAX}uxEJ9I7$oB0S>zw zZN*c~gX+#Z(%0y4Q~zFYA$n;*YXDh})g0;f1Fb<1v4zvBdqe{2oUh+e;{Z(-rc?=y ziA06yTI5GCE&m-N$(lssn zaa+=Bj9*x@{Yn~6tCr?fKcmj&{<>cjPdF_}3G3CVNOc-Fi9VgiRqoR{o!IWFq+=h4 zA2o`)F@|f{yQ)^_DL0DJUZcKML~ZtF&I*M#d+zLeN2pNgfLI55*b_bpW`qcbJy2tw|Y(++;7chM8(oc`GkF4*bQsDHvtvF=v?Wc5!qdjrd2d9!8m zW+Iopv1e_K4;NE}6f;!8(z%hzs|@-gFMJ>w~@?X>KYWtVcAQuL@?ExVN06uoO+QVHG9$Pib!eWDsk_)>R64+NlC zKDA_Qyl8sG&Uc&d=)0fN2yUp3qCA=!j~{M!t;8{gxuCoHAqs}>%)-#&B<>(9}IUAV%W*EsZlH&^Grg^u-ve`NvJz#v`(^_n5Oy<)fW!Dd9 zsc??5Er-tcrk2LXg^q(Pa>ksyc7^&4#dL9Uj&!QBY-L{OA8WP}{V~7+XXN(@4_Lm^ z@|Cq*j@aG2v{?Om&-(T76pb-RCf-Sb$WD9zpjB zach-GyWaaBt|en8M?phH`-zGypLja4vOFRRBibeHqiG)TQgi(*#@6t+?2ZskJ^g!G z7IPYLjt#PoMY1ySRpTDH*DBgW3p$4r$6}6_NR+Q9mKW3*R)S2@tK|>#(Xrn3?E8&~T+YYv5cEZ94=Trk!nNer z90d&x?GqY$OsjcCKYSW`nY+_yXN&(n&2P8<)qaFq_t?gEc9Kk)$SAM7^*1PUevAoH zNw8>8Oe6Wb=Cz9^JnjAlB8&UEgHK|~`&TjLvi`8D)Cr{Zg>GoL*~W6)`!rBk{*v4#3_?{>)P0J9;S=NIzH8aq1DMt>@*#2{?qRLCzefr z?ahZWA4)8hyITC%;>Xgf`y-*~4}`XStfg1Y2p`p~M<1UBXK5p{i>%n(6SbEkxM&caxMD1}{xo}4B zbI;Z@!W7|pn+H^1AF)vBI++I~w27}Zi-r54`##Xm%i)9)7qze9TmEdEdDz8T_;zdz zpY-wpet3{u(bAtc|Dso%Us9u#j;U&E)E`xZtIf#3pHIn33U~Fhmh!|rg-VpsC~`d2 z`KaK-nL(FBwIzF_=Om}dEkauL9Zac~G@MY9)0kFy4 zg&6aIbp*DKz$H!=9>sO38YuLeMHS{HasSJQUiD+Fbc`Uzpl+FOd9J;qr9kd-rnJ;I zw5>*;d8S^*gC%&o`6p51 z6G`;HNTy4YsN2!d8t!{!1Ky2rK-qKAXFSz{r*R!a4x!Bs^I5&SeCcsB8A;jGH{>8R z@~@h#$bIa?A6rzT&QFl|H4szF$Pn$oF4y@T48nL?$%+Us915Nbqd^=Ya;xbgMvjJt z`>@9Sa(6k+Qs2S<(|~A@ZTzs|Y!;%%hWL&j@j+rg(Lb!b{lkGYh+K7WVP5w+8EX;{T)-DJGt%_7PO z{@s8`wCC)`vbwc2ySS!Zd@@Kwt(%@%Mv*4IYBCYiYV8VpL^`BjqS?kdmLv3~T5ZQN z5deRc$IKBs!#{6+{DO>sty&9_1f8$tF1gOJgHH$k{Y2Ie{?y&((XhY$&BoVVngx?F z;HpWke;T?TC7VMTZvuK zJ+Yc)>bFlrA5UoEFxW&HHceA9!Djj*HfiYwYL7 zUGHi-bFMZl*NDb*x~RnYOta>?+u%f&E0UR)iAR`|1Am`ii)Q^3J^d5?LqzkE_#JUg zjr&q=Ymt&^(qXxodAXT3U7P0s)4pv{hg2TI=#*(+u~Tx*X)U~WY`9jkL{A9Ca^6a> zAxSyOG;2wEVp{348s8lwBt3$h>kEtu6IjYK`sc6iX=zQNf`%7F>g8Hni_(hA=XZxz z-E0h}vOZp_Lg*)wqF3|}p2YRgTg7~TIr-t3s-v;K;W{6;*I(9E`FBnQ89g0j9Xrpk zCxWAWf8YFt@`?9!j-N&Qjwjm3@r-b#&nVvT7eY?xY9_0FTDXa$^kb?6;>cv^W9s-- zkP~7sd8@*!)T?6tlqwu|oFI};zbA8QI0N>~B ztVjgk(Lza_p@C@jyfr>u`e9!jGJKrRyPQeKFfLN#gA%Ipxd0IXCnw`pd3vX*5)L{K z#!{c3c1LaYtx>m}R_DDnp$_ENfb@NeYA1ZkI#~9H?J)A+PFGLQ{*<^2-u5j;ukbAv zkz`pv{C?idJ9(rHY4lh8w9s}=bL|iI=F#=S-dJh$Yl8mR$DO%|@%5Z5xElM1#;j+5 zdo3CjBhhRz<4x_3Io3MI=gu0(T;bjk8eUj+#*l?vD(d}|c=sb!UL#BYh%7N`>dhV> zk3Dv)i&&Ri-_x?by<=UP_S~(0<(Zh41eN>wYB`JN*Rb)PBdNl~j$2?HRAgdD2YX7E zEzHMt5Br27J}pRA{){weZtagdgILpcQdcQd>fMW{_WgQ%H7DB=?O`n<{tB2C^ge~Eo(+?4zb5bX{X^^p8k>C_?2`dL1pi=9JI;}j*FMtUh&x|X-hbWm&)ur> zXnk6mm08xxJSA=OdGmO{_0T*P1v#erAFM6Ty8zO2t9xoOkZY=Yydj;pRGb=AUo#dB z9nUj1ZMudwHH?0Y82xszl&6l!oo+F03fDd@Yw@yb| zv#H}?)3l)1a!CGfU#enlzbWWm+6#EtH6yOdl~>vJn)a^0YsI}K{^AvCiA~qP3A?sX z=`MT7dsn~IN5DF)G}peh{V{JJ+HTJ2b@w^l{q2_wgJ!42CfDq>+_xP(#rq*&^_Fy` zMA4)wIUdP9*)UWhenq)0>}K!9*Lda)MefG=tbHl`^OrHyD4h4 z5FdF#|E$*X7;7yNfy3&adbQ;#*&|u=)A92}haIv%=dYUCz-4XVcN7!3H48ZGY~pho zkHYBH5&N4#d48A z@nTYML3;kAHjY1&>TG^J)RZ;a_S-+;sFmZd5OOv+Xy_+&ug$zNbT- zOX&Cg6xDT=wO)#cTePk8`WvTR?QH0IXG7-@^4ZX($7=YjhEKF%>6%J#o!Y-DKj*g~K-Lh4}F?Uh%y z`?>lJH+rFX$*MUz_r^teJXGS9W3%Dk6K~yaklBN`bWff2Tqj1o-$TmrX1{Z25S$y+ zO7EZ%-#z~X^7q3kpAEZ@c%9K@FI?%1VxNhUEbz?o-FWJnGo57%|2RD`^?P~L&{KEA zDShbAQ6H`QUWd-{sd#Nl93Y?1Ya92jZVNT-6VAx=D6exbYmt)y-xp#%`d8wq8;afW zTKqV~fUY;+P&DK%X;-UAKAwEHXw+xHil05i{jMn!j%M8s9ENchQKkPmIV0X}qp%);|pZRFrnn>b~NBchyR{4x{ z+#mGMU+2@(_t$%?>2vXjerUgLYgqe)c@4IQI7OC6*DG>`6T@E*(IZ5WKFrP@hf%t^ zXH%!f+^lBmGlpZVk3e6K_e8VTgjecw)$Yjo3iw|6(Y!b(No>b+{LAm;R-50+gm*9GrTG zEg40tD63oRl(L~7&@~ZGSBR@xLcjKmR@PtR(~6#jv>016J#TFw*DTx1#Hhk`u5+Fn z-*gMFX_NJAQ*PD80)?_rldfJ`S!kWN$0dJDi)Q)u*C7d>Wxjr+WNDYHY7V*OTgu`f zbFU$%R07TJl;kR=)zXzvq12rb+L!e;n=?imJ88zJ;wmUzV~L(ASM>5KwRn^zKErpE zG?x2*sYz|?2wBoi?s=w(QB?TiVjx$h>|*jrD5W9uo9 z_I0#=0{hZWpuMAEUE7~lKY^I5$Hm=ZgaqWfY|L-Erxj~#J9k5{fn2wne$^(|H~)zIsG?6*+IDPFYYQAKUe5q~DSA+5Jyz z(cm&ZkT?u``#y4r*V#}5sJ$*~kcv0k&n6W`sO3Jkvrr+E;YwSCe2$eFlQ9>K+9N{V zVoh`UcYo&EjvPv;9Q0hya+!@<)<&HVSpumR;<`jsGd!nEgxRR$u~8v@LEv|h zX?IWKoHd{Ppdkdoi*k*vV4TC%G$d2NV$kzo$DN^2*tJ8? z;^j1Hxa01$aA-=8ecN66J4H+05$9=omo>AlFL4iR`<9*3VlU)cvm5pA=I>AU`65Pt zO+V<4C)pUT2@T(QOZTAj7Qgp`c97f;@%{W~p&8L>7rmRy94)h(8x4`{Xu33UQW)wLA6}$V;MR=26T+-D_Lc(m5bN8>^YYt zfu$ku@s+toq%OsqE%|KsY3+OS5{=L1-zm-T*kt{`NE3p}(1>3TQI%Wz8@yqsyRkJr z{HX71Z;j7rT@gF;SJ~wJKS&RRKgS{Gk4eKrlKH%cw}X`bxOp_3H}ghCi_>)R)Lxk` zW;n%4gtc$AC~6vmz9G8c1RhXisw^OXi6`6;wOextDUHLKl;SHT+XN0~zI`>U`~5JZ z`4pWt4pg$CmhGN?TKtmTPy;9L+>*wF984Vtau3K&z{5gDp~hi2@%)aa4IdbMKVKr)fwh&zu8DrGsC`s`$LhuZEn%uf^+lQCNjt z$C`2)^}lHr`&6mvs6Su!YrLLn({~Tln5s$T^Yh1^<7P(ub>gGW&@* z+;uX0LfToXy~=tdwQ_Ap0u~wHl~#ATJU`RNA;vOwv>0_sgKkOdwx5)p&NH;;dBo(j zY$`Q5nopM;N2T&wxzRWt#NAs$jnBSxovC}`<+U4MZ$4$^+&tp%tIyqiHl{(io+Yl4 z&;PsNDa-q~ZU=3K6RBIYnS62{r@5!39QTy?9j93FnN%!Y|C{6xUKwIAh~)6Ae(?O4lxW640_+0a1@3^~{}ug{=V9br(F3XXN8XQbUJ>VV z4Y|*U;Jq4;KN+IPpe&y~2nrx$`qk!t({CS$cOKEdxAZs56MvIGi$46%QP6Z8Q~0KR zPOzfToqrm1#TDtI{xbu`_#B-SpY&TD`Ii3UN5tRf?cJ_O{B4*IuTlS*y(gZ&oh0w= z9QHj~k*7Q0D#mQmrEs@v5`I_zbqJpit9$!^dd6zAr^GEcUr;pbEIjKg;$diCaM$ad ztOnzlT}t@V&Ci?vZwF&{-lm|R@v~s83N69U*aeTkHedyjb)7!acFE=X%J3U^F)wiJ zCz=uC|0N{ZeOv$e0HrOpLg9DqVlJNtJh$65xhMSu)YyOgI5+m~j_upe)YI(S9gIEQ zU%1;4zn! z_gaNd?>~B%-|jtf_vHSgb}{tcqjpc;ZFC+vCC=CNLozja*j1b;Mo@9wsP`JxzOO&O zA=3Pc{^81boGF^@yNbRFqn(&V{H=X5D&hA$9yI1OUVJ(rH;Fa-QB~H5yh9rp6==VTI2>h~hZAYN81lND$Nv8TDJf>M literal 0 HcmV?d00001 diff --git a/packages/opencode/src/effect/runtime-flags.ts b/packages/opencode/src/effect/runtime-flags.ts index 65e02f076360..65998efa3fa3 100644 --- a/packages/opencode/src/effect/runtime-flags.ts +++ b/packages/opencode/src/effect/runtime-flags.ts @@ -41,6 +41,7 @@ export class Service extends ConfigService.Service()("@opencode/Runtime enableQuestionTool: bool("OPENCODE_ENABLE_QUESTION_TOOL"), experimentalReferences: enabledByExperimental("OPENCODE_EXPERIMENTAL_REFERENCES"), experimentalBackgroundSubagents: enabledByExperimental("OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS"), + experimentalBackgroundShell: enabledByExperimental("OPENCODE_EXPERIMENTAL_BACKGROUND_SHELL"), experimentalLspTy: bool("OPENCODE_EXPERIMENTAL_LSP_TY"), experimentalLspTool: enabledByExperimental("OPENCODE_EXPERIMENTAL_LSP_TOOL"), experimentalOxfmt: enabledByExperimental("OPENCODE_EXPERIMENTAL_OXFMT"), diff --git a/packages/opencode/src/server/routes/instance/httpapi/groups/experimental.ts b/packages/opencode/src/server/routes/instance/httpapi/groups/experimental.ts index 52c714a5ae64..a79e36ce1d71 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/groups/experimental.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/groups/experimental.ts @@ -87,6 +87,28 @@ export const SessionListQuery = Schema.Struct({ archived: Schema.optional(QueryBoolean), }) +const BackgroundJobStatus = Schema.Union([ + Schema.Literal("running"), + Schema.Literal("completed"), + Schema.Literal("error"), + Schema.Literal("cancelled"), +]) + +const BackgroundJobInfo = Schema.Struct({ + id: Schema.String, + type: Schema.String, + title: Schema.optional(Schema.String), + status: BackgroundJobStatus, + startedAt: Schema.Number, + completedAt: Schema.optional(Schema.Number), + output: Schema.optional(Schema.String), + error: Schema.optional(Schema.String), + command: Schema.optional(Schema.String), + background: Schema.optional(Schema.Boolean), +}).annotate({ identifier: "BackgroundJobInfo" }) + +const BackgroundJobList = Schema.Array(BackgroundJobInfo).annotate({ identifier: "BackgroundJobList" }) + export const ExperimentalPaths = { capabilities: "/experimental/capabilities", console: "/experimental/console", @@ -98,6 +120,8 @@ export const ExperimentalPaths = { worktreeReset: "/experimental/worktree/reset", session: "/experimental/session", sessionBackground: "/experimental/session/:sessionID/background", + jobs: "/experimental/jobs", + jobCancel: "/experimental/jobs/:jobID", resource: "/experimental/resource", } as const @@ -245,6 +269,27 @@ export const ExperimentalApi = HttpApi.make("experimental") "Detach any synchronous subagents currently blocking the session and continue them in the background.", }), ), + HttpApiEndpoint.get("jobs", ExperimentalPaths.jobs, { + query: WorkspaceRoutingQuery, + success: described(BackgroundJobList, "List of background jobs"), + }).annotateMerge( + OpenApi.annotations({ + identifier: "experimental.background.list", + summary: "List background jobs", + description: "Get all background jobs running in the current instance.", + }), + ), + HttpApiEndpoint.post("jobCancel", ExperimentalPaths.jobCancel, { + params: { jobID: Schema.String }, + query: WorkspaceRoutingQuery, + success: described(Schema.Boolean, "Cancelled background job"), + }).annotateMerge( + OpenApi.annotations({ + identifier: "experimental.background.cancel", + summary: "Cancel a background job", + description: "Cancel a running background job by id.", + }), + ), HttpApiEndpoint.get("resource", ExperimentalPaths.resource, { query: WorkspaceRoutingQuery, success: described(Schema.Record(Schema.String, MCP.Resource), "MCP resources"), diff --git a/packages/opencode/src/server/routes/instance/httpapi/handlers/experimental.ts b/packages/opencode/src/server/routes/instance/httpapi/handlers/experimental.ts index b218c6040d1e..6404abfec855 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/handlers/experimental.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/handlers/experimental.ts @@ -171,6 +171,27 @@ export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "exper return promoted.some((job) => job !== undefined) }) + const jobs = Effect.fn("ExperimentalHttpApi.jobs")(function* () { + const list = yield* background.list() + return list.map((job) => ({ + id: job.id, + type: job.type, + ...(job.title ? { title: job.title } : {}), + status: job.status, + startedAt: job.started_at, + ...(job.completed_at ? { completedAt: job.completed_at } : {}), + ...(job.output ? { output: job.output } : {}), + ...(job.error ? { error: job.error } : {}), + ...(typeof job.metadata?.command === "string" ? { command: job.metadata.command } : {}), + ...(job.metadata?.background === true ? { background: true } : {}), + })) + }) + + const jobCancel = Effect.fn("ExperimentalHttpApi.jobCancel")(function* (ctx: { params: { jobID: string } }) { + const cancelled = yield* background.cancel(ctx.params.jobID) + return cancelled !== undefined + }) + const resource = Effect.fn("ExperimentalHttpApi.resource")(function* () { return yield* mcp.resources() }) @@ -188,6 +209,8 @@ export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "exper .handle("worktreeReset", worktreeReset) .handle("session", session) .handle("sessionBackground", sessionBackground) + .handle("jobs", jobs) + .handle("jobCancel", jobCancel) .handle("resource", resource) }), ) diff --git a/packages/opencode/src/tool/shell.ts b/packages/opencode/src/tool/shell.ts index 1e4423e01774..1e020145deb5 100644 --- a/packages/opencode/src/tool/shell.ts +++ b/packages/opencode/src/tool/shell.ts @@ -1,4 +1,4 @@ -import { Effect, Stream } from "effect" +import { Effect, Scope, Stream } from "effect" import os from "os" import { createWriteStream } from "node:fs" import * as Tool from "./tool" @@ -19,11 +19,24 @@ import * as Truncate from "./truncate" import { Plugin } from "@/plugin" import { ChildProcess } from "effect/unstable/process" import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner" -import { ShellPrompt, type Parameters } from "./shell/prompt" +import { ShellPrompt, type Parameters, type SummaryMode } from "./shell/prompt" import { BashArity } from "@/permission/arity" +import { BackgroundJob } from "@/background/job" +import { Identifier } from "@/id/id" +import { Database } from "@opencode-ai/core/database/database" +import { MessageV2 } from "@/session/message-v2" +import type { TaskPromptOps } from "./task" +import type { SessionPrompt } from "@/session/prompt" +import { SessionID } from "@/session/schema" export { Parameters } from "./shell/prompt" +const BACKGROUND_STARTED = [ + "The command is running in the background. You will be notified automatically when it finishes.", + "DO NOT sleep, poll for progress, or duplicate this command's work.", + "Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.", +].join("\n") + const MAX_METADATA_LENGTH = 30_000 const CWD = new Set(["cd", "chdir", "popd", "pushd", "push-location", "set-location"]) const FILES = new Set([ @@ -254,6 +267,78 @@ function tail(text: string, maxLines: number, maxBytes: number) { } } +function head(text: string, maxLines: number, maxBytes: number) { + const lines = text.split("\n") + if (lines.length <= maxLines && Buffer.byteLength(text, "utf-8") <= maxBytes) { + return { + text, + cut: false, + } + } + + const out: string[] = [] + let bytes = 0 + for (const line of lines) { + const size = Buffer.byteLength(line, "utf-8") + (out.length > 0 ? 1 : 0) + if (out.length >= maxLines || bytes + size > maxBytes) { + if (out.length === 0) { + out.push(line.slice(0, maxBytes)) + } + break + } + out.push(line) + bytes += size + } + return { + text: out.join("\n"), + cut: true, + } +} + +const ERROR_PATTERN = /\b(error|fail(ed|ure)?|warning|exception|traceback|cannot|unable|fatal)\b/i + +function errorLines(text: string, maxLines: number, maxBytes: number) { + const lines = text.split("\n") + if (lines.length <= maxLines && Buffer.byteLength(text, "utf-8") <= maxBytes) { + return { + text, + cut: false, + } + } + + const out: string[] = [] + let bytes = 0 + for (const line of lines) { + if (!ERROR_PATTERN.test(line)) continue + const size = Buffer.byteLength(line, "utf-8") + (out.length > 0 ? 1 : 0) + if (out.length >= maxLines || bytes + size > maxBytes) break + out.push(line) + bytes += size + } + if (out.length === 0) return tail(text, maxLines, maxBytes) + return { + text: out.join("\n"), + cut: true, + } +} + +function summarize(text: string, mode: SummaryMode, maxLines: number, maxBytes: number) { + if (mode === "head") return head(text, maxLines, maxBytes) + if (mode === "error") return errorLines(text, maxLines, maxBytes) + return tail(text, maxLines, maxBytes) +} + +const NETWORK_COMMAND = /^(curl|wget|ping|tracert|tracepath|ssh|gh)\b/i +const NETWORK_GIT = /^git (fetch|pull|clone|push|ls-remote)\b/i +const BUILD_COMMAND = /^(bun |npm |yarn |pnpm |mvn |gradle |cargo |make )?(build|test|typecheck|check|lint|install|ci)\b/i + +function defaultTimeoutFor(command: string, fallback: number) { + if (NETWORK_COMMAND.test(command)) return Math.min(fallback, 15_000) + if (NETWORK_GIT.test(command)) return Math.min(fallback, 15_000) + if (BUILD_COMMAND.test(command)) return Math.max(fallback, 300_000) + return fallback +} + const parse = Effect.fn("ShellTool.parse")(function* (command: string, ps: boolean) { const tree = yield* Effect.promise(() => parser().then((p) => (ps ? p.ps : p.bash).parse(command))) if (!tree) throw new Error("Failed to parse command") @@ -344,6 +429,9 @@ export const ShellTool = Tool.define( const trunc = yield* Truncate.Service const plugin = yield* Plugin.Service const flags = yield* RuntimeFlags.Service + const background = yield* BackgroundJob.Service + const scope = yield* Scope.Scope + const database = yield* Database.Service const defaultTimeoutMs = flags.bashDefaultTimeoutMs ?? 2 * 60 * 1000 const cygpath = Effect.fn("ShellTool.cygpath")(function* (shell: string, text: string) { @@ -432,6 +520,7 @@ export const ShellTool = Tool.define( cwd: string env: NodeJS.ProcessEnv timeout: number + summaryMode: SummaryMode }, ctx: Tool.Context, ) { @@ -446,6 +535,7 @@ export const ShellTool = Tool.define( let cut = false let expired = false let aborted = false + let exited = false const closeSink = Effect.fnUntraced(function* () { const stream = sink @@ -482,6 +572,9 @@ export const ShellTool = Tool.define( Effect.gen(function* () { yield* Effect.addFinalizer(closeSink) const handle = yield* spawner.spawn(cmd(input.shell, input.command, input.cwd, input.env)) + yield* Effect.addFinalizer(() => + exited ? Effect.void : handle.kill({ forceKillAfter: "3 seconds" }).pipe(Effect.orDie), + ) yield* Effect.forkScoped( Stream.runForEach(Stream.decodeText(handle.all), (chunk) => { @@ -545,6 +638,8 @@ export const ShellTool = Tool.define( timeout.pipe(Effect.map(() => ({ kind: "timeout" as const, code: null }))), ]) + if (exit.kind === "exit") exited = true + if (exit.kind === "abort") { aborted = true yield* handle.kill({ forceKillAfter: "3 seconds" }).pipe(Effect.orDie) @@ -566,7 +661,7 @@ export const ShellTool = Tool.define( } if (aborted) meta.push("User aborted the command") const raw = list.map((item) => item.text).join("") - const end = tail(raw, limits.maxLines, limits.maxBytes) + const end = summarize(raw, input.summaryMode, limits.maxLines, limits.maxBytes) if (end.cut) cut = true if (!file && end.cut) { file = yield* trunc.write(raw) @@ -603,42 +698,183 @@ export const ShellTool = Tool.define( const prompt = ShellPrompt.render(name, process.platform, limits, defaultTimeoutMs) yield* Effect.logInfo("shell tool using shell", { shell }) - return { - description: prompt.description, - parameters: prompt.parameters, - execute: (params: Parameters, ctx: Tool.Context) => - Effect.gen(function* () { - const instanceCtx = yield* InstanceState.context - const cwd = params.workdir - ? yield* resolvePath(params.workdir, instanceCtx.directory, shell) - : instanceCtx.directory - if (params.timeout !== undefined && params.timeout < 0) { - throw new Error(`Invalid timeout value: ${params.timeout}. Timeout must be a positive number.`) - } - const timeout = params.timeout ?? defaultTimeoutMs - const ps = Shell.ps(shell) - yield* Effect.scoped( - Effect.gen(function* () { - const tree = yield* Effect.acquireRelease(parse(params.command, ps), (tree) => - Effect.sync(() => tree.delete()), - ) - const scan = yield* collect(tree.rootNode, cwd, ps, shell, instanceCtx) - if (!containsPath(cwd, instanceCtx)) scan.dirs.add(cwd) - yield* ask(ctx, scan, params) - }), - ) + const runShell = Effect.fn("ShellTool.runShell")(function* ( + params: Parameters, + ctx: Tool.Context, + shell: string, + cwd: string, + timeout: number, + ) { + return yield* run( + { + shell, + command: params.command, + cwd, + env: yield* shellEnv(ctx, cwd), + timeout, + summaryMode: (params.summary_mode ?? "tail") as SummaryMode, + }, + ctx, + ) + }) + + const renderBackgroundOutput = (jobID: string, command: string, state: "running" | "completed" | "error", exit?: number | null, text?: string) => { + const header = `` + const tag = state === "error" ? "shell_error" : "shell_result" + return [header, `<${tag}>`, text ?? "", ``, ""].join("\n") + } - return yield* run( + const injectBackgroundResult = Effect.fn("ShellTool.injectBackgroundResult")(function* ( + ctx: Tool.Context, + ops: TaskPromptOps, + jobID: string, + command: string, + state: "completed" | "error", + exit: number | null, + text: string, + ) { + const msg = yield* MessageV2.get({ sessionID: ctx.sessionID, messageID: ctx.messageID }).pipe( + Effect.provideService(Database.Service, database), + Effect.orDie, + ) + const variant = msg.info.role !== "assistant" ? undefined : msg.info.variant + yield* ops + .prompt({ + sessionID: ctx.sessionID, + agent: ctx.agent, + variant, + parts: [ { - shell, - command: params.command, - cwd, - env: yield* shellEnv(ctx, cwd), - timeout, + type: "text", + synthetic: true, + text: renderBackgroundOutput(jobID, command, state, exit, text), }, - ctx, + ], + }) + .pipe(Effect.ignore, Effect.forkIn(scope, { startImmediately: true })) + }) + + const executeShell = Effect.fn("ShellTool.execute")(function* (params: Parameters, ctx: Tool.Context) { + const instanceCtx = yield* InstanceState.context + const cwd = params.workdir + ? yield* resolvePath(params.workdir, instanceCtx.directory, shell) + : instanceCtx.directory + if (params.timeout !== undefined && params.timeout < 0) { + throw new Error(`Invalid timeout value: ${params.timeout}. Timeout must be a positive number.`) + } + const ps = Shell.ps(shell) + yield* Effect.scoped( + Effect.gen(function* () { + const tree = yield* Effect.acquireRelease(parse(params.command, ps), (tree) => + Effect.sync(() => tree.delete()), ) + const scan = yield* collect(tree.rootNode, cwd, ps, shell, instanceCtx) + if (!containsPath(cwd, instanceCtx)) scan.dirs.add(cwd) + yield* ask(ctx, scan, params) }), + ) + + const runInBackground = params.background === true + const timeout = + params.timeout ?? + (runInBackground + ? defaultTimeoutMs + : defaultTimeoutFor(params.command, defaultTimeoutMs)) + if (!runInBackground) { + return yield* runShell(params, ctx, shell, cwd, timeout) + } + + if (!flags.experimentalBackgroundShell) { + return yield* Effect.fail( + new Error("Background shell requires OPENCODE_EXPERIMENTAL_BACKGROUND_SHELL=true"), + ) + } + + const ops = ctx.extra?.promptOps as TaskPromptOps | undefined + if (!ops) { + return yield* Effect.fail(new Error("ShellTool background requires promptOps in ctx.extra")) + } + + const jobID = Identifier.ascending("job") + const metadata = { + command: params.command, + cwd, + background: true, + } + + // The background run must outlive the originating tool call: the AI SDK + // aborts the tool-call signal when the call's lifecycle ends (after the + // model consumes the "running" result), which would kill a child process + // still listening on `ctx.abort`. Give the background task its own + // signal so only explicit `background.cancel` interrupts it. + const bgAbort = new AbortController() + const bgCtx = { ...ctx, abort: bgAbort.signal } + + const runTask = Effect.fn("ShellTool.backgroundRun")(function* () { + const result = yield* runShell(params, bgCtx, shell, cwd, timeout) + const state = result.metadata.exit === 0 ? "completed" : "error" + return renderBackgroundOutput(jobID, params.command, state, result.metadata.exit, result.output) + }) + + const notify = Effect.fn("ShellTool.notifyBackgroundResult")(function* () { + yield* background.wait({ id: jobID }).pipe( + Effect.flatMap((waited) => { + const info = waited.info + if (info?.status === "completed") + return injectBackgroundResult( + ctx, + ops, + jobID, + params.command, + /state="error"/.test(info.output ?? "") ? "error" : "completed", + null, + info.output ?? "", + ) + if (info?.status === "error") + return injectBackgroundResult(ctx, ops, jobID, params.command, "error", null, info.error ?? "") + return Effect.void + }), + Effect.forkIn(scope, { startImmediately: true }), + ) + }) + + const info = yield* background.start({ + id: jobID, + type: ShellID.ToolID, + title: params.command, + metadata, + onPromote: Effect.all([ + ctx.metadata({ + title: params.command, + metadata: { ...metadata, jobId: jobID }, + }), + notify(), + ]), + run: runTask().pipe( + Effect.onInterrupt(() => background.cancel(jobID)), + ), + }) + + yield* notify() + + return { + title: params.command, + metadata: { + ...metadata, + jobId: info.id, + output: "", + exit: null, + truncated: false, + }, + output: renderBackgroundOutput(jobID, params.command, "running", null, BACKGROUND_STARTED), + } + }) + + return { + description: prompt.description, + parameters: prompt.parameters, + execute: (params: Parameters, ctx: Tool.Context) => + executeShell(params, ctx).pipe(Effect.orDie), } }) }), diff --git a/packages/opencode/src/tool/shell/prompt.ts b/packages/opencode/src/tool/shell/prompt.ts index b576b7729767..f0d2a0aa78c3 100644 --- a/packages/opencode/src/tool/shell/prompt.ts +++ b/packages/opencode/src/tool/shell/prompt.ts @@ -7,6 +7,14 @@ import { ShellID } from "./id" const PS = new Set(["powershell", "pwsh"]) const CMD = new Set(["cmd"]) +export type SummaryMode = "head" | "tail" | "error" + +const SUMMARY_MODE_NOTE = + " - Use `summary_mode` to control how large output is summarized: `\"head\"` (first lines), `\"tail\"` (last lines, good for build/test failures), `\"error\"` (only lines matching error/fail/warning patterns). Defaults to `\"tail\"`." + +const BACKGROUND_NOTE = + " - For long-running commands (builds, tests, CI polling, watchers), set `background: true` to run the command in the background and keep the conversation responsive. The result will be delivered automatically when it finishes. DO NOT sleep, poll, or check on a background command. Background commands use the full default timeout unless you pass an explicit `timeout`." + export type Limits = { maxLines: number maxBytes: number @@ -19,6 +27,16 @@ export function parameterSchema() { workdir: Schema.optional(Schema.String).annotate({ description: `The working directory to run the command in. Defaults to the current directory. Use this instead of 'cd' commands.`, }), + summary_mode: Schema.optional( + Schema.Literals(["head", "tail", "error"]).annotate({ + description: + "How to summarize the command output when it is large. 'head' keeps the first lines, 'tail' keeps the last lines (useful for test/build failures), 'error' keeps only lines containing error/fail/warning patterns. Defaults to 'tail'. The full output is always written to a file when truncated.", + }), + ), + background: Schema.optional(Schema.Boolean).annotate({ + description: + "Run the command in the background and return immediately. The result will be delivered as a follow-up message when it completes. Use this for long-running commands (builds, tests, CI polling) that would otherwise block the conversation. DO NOT sleep, poll, or check on background commands.", + }), }) } @@ -94,7 +112,9 @@ function bashCommandSection(chain: string, limits: Limits, defaultTimeoutMs: num Usage notes: - The command argument is required. - - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms. + - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms (network operations get a shorter default timeout, build/test operations a longer one). +${SUMMARY_MODE_NOTE} +${BACKGROUND_NOTE} - If the output exceeds ${limits.maxLines} lines or ${limits.maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Do NOT use \`head\`, \`tail\`, or other truncation commands to limit output; the full output will already be captured to a file for more precise searching. - Avoid using Bash with the \`find\`, \`grep\`, \`cat\`, \`head\`, \`tail\`, \`sed\`, \`awk\`, or \`echo\` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands: @@ -145,7 +165,9 @@ Before executing the command, please follow these steps: Usage notes: - The command argument is required. - - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms. + - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms (network operations get a shorter default timeout, build/test operations a longer one). +${SUMMARY_MODE_NOTE} +${BACKGROUND_NOTE} - If the output exceeds ${limits.maxLines} lines or ${limits.maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Do NOT use \`Select-Object -First\`, \`Select-Object -Last\`, or other truncation commands to limit output; the full output will already be captured to a file for more precise searching. - Avoid using Shell with PowerShell file/content cmdlets unless explicitly instructed or when these cmdlets are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands: @@ -194,7 +216,9 @@ Before executing the command, please follow these steps: Usage notes: - The command argument is required. - - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms. + - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms (network operations get a shorter default timeout, build/test operations a longer one). +${SUMMARY_MODE_NOTE} +${BACKGROUND_NOTE} - If the output exceeds ${limits.maxLines} lines or ${limits.maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Do NOT use \`more\` or other pagination commands to limit output; the full output will already be captured to a file for more precise searching. - Avoid using Shell with cmd.exe file/content commands unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands: diff --git a/packages/opencode/test/tool/shell.test.ts b/packages/opencode/test/tool/shell.test.ts index a970f85d468f..abad5ac9b8f4 100644 --- a/packages/opencode/test/tool/shell.test.ts +++ b/packages/opencode/test/tool/shell.test.ts @@ -16,9 +16,12 @@ import { Truncate } from "@/tool/truncate" import { SessionID, MessageID } from "../../src/session/schema" import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner" import { FSUtil } from "@opencode-ai/core/fs-util" +import { Database } from "@opencode-ai/core/database/database" +import { BackgroundJob } from "../../src/background/job" import { Plugin } from "../../src/plugin" import { testEffect } from "../lib/effect" import { Tool } from "@/tool/tool" +import type { TaskPromptOps } from "@/tool/task" import { RuntimeFlags } from "@/effect/runtime-flags" import { InstanceStore } from "@/project/instance-store" @@ -32,6 +35,8 @@ const shellLayer = Layer.mergeAll( Config.node, Agent.node, RuntimeFlags.node, + Database.node, + BackgroundJob.node, ]), ), testInstanceStoreLayer, @@ -1196,4 +1201,154 @@ describe("tool.shell truncation", () => { }), ), ) + + it.live( + "background task survives the tool-call abort signal and reports its real output", + () => + runIn( + projectRoot, + Effect.gen(function* () { + const controller = new AbortController() + const ops: TaskPromptOps = { + cancel: () => Effect.void, + resolvePromptParts: (template) => Effect.succeed([{ type: "text", text: template }] as any), + prompt: (input) => Effect.succeed({} as any), + } + const res = yield* run( + { + command: `echo background-survives-abort && sleep 2 && echo background-done`, + background: true, + }, + { + ...ctx, + abort: controller.signal, + extra: { promptOps: ops }, + }, + ) + expect(res.output).toContain("running in the background") + + controller.abort() + + const jobs = yield* BackgroundJob.Service + const job = yield* jobs.wait({ id: (res.metadata as unknown as { jobId: string }).jobId, timeout: 15_000 }) + expect(job.timedOut).toBe(false) + expect(job.info?.status).toBe("completed") + expect(job.info?.output).toContain("background-survives-abort") + expect(job.info?.output).toContain("background-done") + expect(job.info?.output).not.toContain("User aborted the command") + }).pipe(Effect.provide(RuntimeFlags.layer({ experimentalBackgroundShell: true }))), + ), + 25_000, + ) + + it.live( + "background network command is not force-killed by the foreground network short timeout", + () => + runIn( + projectRoot, + Effect.gen(function* () { + const ops: TaskPromptOps = { + cancel: () => Effect.void, + resolvePromptParts: (template) => Effect.succeed([{ type: "text", text: template }] as any), + prompt: (input) => Effect.succeed({} as any), + } + const res = yield* run( + { + command: `ping -n 18 127.0.0.1`, + background: true, + }, + { + ...ctx, + extra: { promptOps: ops }, + }, + ) + expect(res.output).toContain("running in the background") + + const jobs = yield* BackgroundJob.Service + const job = yield* jobs.wait({ id: (res.metadata as unknown as { jobId: string }).jobId, timeout: 30_000 }) + expect(job.timedOut).toBe(false) + expect(job.info?.status).toBe("completed") + expect(job.info?.output).not.toContain("terminated command after exceeding timeout") + expect(job.info?.output).toMatch(/TTL=/) + }).pipe(Effect.provide(RuntimeFlags.layer({ experimentalBackgroundShell: true, bashDefaultTimeoutMs: 30_000 }))), + ), + 45_000, + ) + + it.live( + "background shell jobs are not scoped to a session (session removal leaves them running)", + () => + runIn( + projectRoot, + Effect.gen(function* () { + const ops: TaskPromptOps = { + cancel: () => Effect.void, + resolvePromptParts: (template) => Effect.succeed([{ type: "text", text: template }] as any), + prompt: (input) => Effect.succeed({} as any), + } + const res = yield* run( + { + command: `echo session-independent-background && sleep 1 && echo still-running`, + background: true, + }, + { + ...ctx, + extra: { promptOps: ops }, + }, + ) + expect(res.output).toContain("running in the background") + + const jobs = yield* BackgroundJob.Service + const job = yield* jobs.wait({ id: (res.metadata as unknown as { jobId: string }).jobId, timeout: 15_000 }) + expect(job.timedOut).toBe(false) + expect(job.info?.status).toBe("completed") + expect(job.info?.output).toContain("still-running") + + // Unlike task subagents (whose metadata carries sessionId/parentSessionId), + // background shell jobs deliberately carry no session linkage, so + // Session.cancelBackgroundJobs never selects them on session removal. + expect(job.info?.metadata).toEqual({ + command: "echo session-independent-background && sleep 1 && echo still-running", + cwd: projectRoot, + background: true, + }) + }).pipe(Effect.provide(RuntimeFlags.layer({ experimentalBackgroundShell: true }))), + ), + 25_000, + ) + + it.live( + "background shell job reports a failing command as error state", + () => + runIn( + projectRoot, + Effect.gen(function* () { + const ops: TaskPromptOps = { + cancel: () => Effect.void, + resolvePromptParts: (template) => Effect.succeed([{ type: "text", text: template }] as any), + prompt: (input) => Effect.succeed({} as any), + } + const res = yield* run( + { + command: `echo before-failure; exit 3`, + background: true, + }, + { + ...ctx, + extra: { promptOps: ops }, + }, + ) + expect(res.output).toContain("running in the background") + + const jobs = yield* BackgroundJob.Service + const job = yield* jobs.wait({ id: (res.metadata as unknown as { jobId: string }).jobId, timeout: 15_000 }) + expect(job.timedOut).toBe(false) + expect(job.info?.status).toBe("completed") + expect(job.info?.output).toContain('state="error"') + expect(job.info?.output).toContain('exit="3"') + expect(job.info?.output).toContain("before-failure") + }).pipe(Effect.provide(RuntimeFlags.layer({ experimentalBackgroundShell: true }))), + ), + 25_000, + ) }) diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index 9ed0084aac84..173d321c8b97 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -29,6 +29,10 @@ import type { EventTuiPromptAppend, EventTuiSessionSelect, EventTuiToastShow, + ExperimentalBackgroundCancelErrors, + ExperimentalBackgroundCancelResponses, + ExperimentalBackgroundListErrors, + ExperimentalBackgroundListResponses, ExperimentalCapabilitiesGetErrors, ExperimentalCapabilitiesGetResponses, ExperimentalConsoleGetErrors, @@ -886,6 +890,78 @@ export class Session extends HeyApiClient { } } +export class Background extends HeyApiClient { + /** + * List background jobs + * + * Get all background jobs running in the current instance. + */ + public list( + parameters?: { + directory?: string + workspace?: string + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [ + { in: "query", key: "directory" }, + { in: "query", key: "workspace" }, + ], + }, + ], + ) + return (options?.client ?? this.client).get< + ExperimentalBackgroundListResponses, + ExperimentalBackgroundListErrors, + ThrowOnError + >({ + url: "/experimental/jobs", + ...options, + ...params, + }) + } + + /** + * Cancel a background job + * + * Cancel a running background job by id. + */ + public cancel( + parameters: { + jobID: string + directory?: string + workspace?: string + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [ + { in: "path", key: "jobID" }, + { in: "query", key: "directory" }, + { in: "query", key: "workspace" }, + ], + }, + ], + ) + return (options?.client ?? this.client).post< + ExperimentalBackgroundCancelResponses, + ExperimentalBackgroundCancelErrors, + ThrowOnError + >({ + url: "/experimental/jobs/{jobID}", + ...options, + ...params, + }) + } +} + export class Resource extends HeyApiClient { /** * Get MCP resources @@ -1261,6 +1337,11 @@ export class Experimental extends HeyApiClient { return (this._session ??= new Session({ client: this.client })) } + private _background?: Background + get background(): Background { + return (this._background ??= new Background({ client: this.client })) + } + private _resource?: Resource get resource(): Resource { return (this._resource ??= new Resource({ client: this.client })) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 90c91e9158cc..747bc186a722 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -2246,6 +2246,21 @@ export type GlobalSession = { project: ProjectSummary | null } +export type BackgroundJobInfo = { + id: string + type: string + title?: string + status: "running" | "completed" | "error" | "cancelled" + startedAt: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + completedAt?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + output?: string + error?: string + command?: string + background?: boolean +} + +export type BackgroundJobList = Array + export type McpResource = { name: string uri: string @@ -7858,6 +7873,67 @@ export type ExperimentalSessionBackgroundResponses = { export type ExperimentalSessionBackgroundResponse = ExperimentalSessionBackgroundResponses[keyof ExperimentalSessionBackgroundResponses] +export type ExperimentalBackgroundListData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/experimental/jobs" +} + +export type ExperimentalBackgroundListErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ExperimentalBackgroundListError = ExperimentalBackgroundListErrors[keyof ExperimentalBackgroundListErrors] + +export type ExperimentalBackgroundListResponses = { + /** + * List of background jobs + */ + 200: BackgroundJobList +} + +export type ExperimentalBackgroundListResponse = + ExperimentalBackgroundListResponses[keyof ExperimentalBackgroundListResponses] + +export type ExperimentalBackgroundCancelData = { + body?: never + path: { + jobID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/experimental/jobs/{jobID}" +} + +export type ExperimentalBackgroundCancelErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ExperimentalBackgroundCancelError = + ExperimentalBackgroundCancelErrors[keyof ExperimentalBackgroundCancelErrors] + +export type ExperimentalBackgroundCancelResponses = { + /** + * Cancelled background job + */ + 200: boolean +} + +export type ExperimentalBackgroundCancelResponse = + ExperimentalBackgroundCancelResponses[keyof ExperimentalBackgroundCancelResponses] + export type ExperimentalResourceListData = { body?: never path?: never diff --git a/packages/tui/src/feature-plugins/builtins.ts b/packages/tui/src/feature-plugins/builtins.ts index b67923f3c5d1..913e1f75a78f 100644 --- a/packages/tui/src/feature-plugins/builtins.ts +++ b/packages/tui/src/feature-plugins/builtins.ts @@ -9,6 +9,7 @@ import SidebarMcp from "./sidebar/mcp" import SidebarTodo from "./sidebar/todo" import DiffViewer from "./system/diff-viewer" import Notifications from "./system/notifications" +import BackgroundJobs from "./system/background-jobs" import PluginManager from "./system/plugins" import WhichKey from "./system/which-key" @@ -32,5 +33,6 @@ export function createBuiltinPlugins(options: { experimentalEventSystem: boolean PluginManager, WhichKey, DiffViewer, + BackgroundJobs, ] } diff --git a/packages/tui/src/feature-plugins/system/background-jobs.tsx b/packages/tui/src/feature-plugins/system/background-jobs.tsx new file mode 100644 index 000000000000..aa7092851f65 --- /dev/null +++ b/packages/tui/src/feature-plugins/system/background-jobs.tsx @@ -0,0 +1,186 @@ +import type { BackgroundJobInfo } from "@opencode-ai/sdk/v2" +import type { TuiPlugin, TuiPluginApi } from "@opencode-ai/plugin/tui" +import { createResource, createSignal, Show } from "solid-js" +import type { BuiltinTuiPlugin } from "../builtins" +import { DialogSelect, type DialogSelectOption } from "../../ui/dialog-select" + +const id = "internal:background-jobs" + +const POLL_MS = 5000 + +function formatTime(ms: number | string) { + const elapsed = Date.now() - Number(ms) + if (Number.isNaN(elapsed)) return "?" + if (elapsed < 60_000) return `${Math.round(elapsed / 1000)}s` + if (elapsed < 3_600_000) return `${Math.round(elapsed / 60_000)}m` + return `${Math.round(elapsed / 3_600_000)}h` +} + +function jobLabel(job: BackgroundJobInfo) { + return job.command ?? job.title ?? job.id +} + +function runningJobs(jobs: BackgroundJobInfo[] | undefined) { + return jobs?.filter((job) => job.status === "running") ?? [] +} + +function View(props: { api: TuiPluginApi }) { + const [jobs, setJobs] = createSignal([]) + const [lock, setLock] = createSignal(false) + + const refresh = async () => { + try { + const directory = props.api.state.path.directory + const result = await props.api.client.experimental.background.list( + { directory }, + { throwOnError: true }, + ) + setJobs(result.data ?? []) + } catch { + // server may be unavailable during startup; next poll retries + } + } + + createResource(async () => { + await refresh() + const timer = setInterval(refresh, POLL_MS) + return () => clearInterval(timer) + }) + + const rows = (): DialogSelectOption[] => + jobs().map((job) => ({ + title: jobLabel(job), + value: job.id, + description: `${job.status} · started ${formatTime(job.startedAt)}${job.status === "running" ? " · press enter to cancel" : ""}`, + disabled: job.status !== "running", + })) + + const cancel = async (jobID: string) => { + if (lock()) return + setLock(true) + try { + const directory = props.api.state.path.directory + const result = await props.api.client.experimental.background.cancel( + { jobID, directory }, + { throwOnError: true }, + ) + props.api.ui.toast({ + variant: result.data ? "success" : "error", + message: result.data ? `Cancelled background job ${jobLabel(jobs().find((x) => x.id === jobID)!)!}` : "Job already finished", + }) + } catch { + props.api.ui.toast({ variant: "error", message: "Failed to cancel background job" }) + } finally { + setLock(false) + await refresh() + } + } + + const close = () => props.api.ui.dialog.clear() + + return ( + { + const job = jobs().find((x) => x.id === item.value) + if (job?.status !== "running") return + void cancel(job.id) + }} + actions={[ + { + title: "cancel", + command: "background.cancel", + hidden: lock(), + onTrigger: (item) => { + const job = jobs().find((x) => x.id === item.value) + if (job?.status !== "running") return + void cancel(job.id) + }, + }, + ]} + /> + ) +} + +function show(api: TuiPluginApi) { + api.ui.dialog.replace(() => ) +} + +function RunningJobs(props: { api: TuiPluginApi }) { + const [running, setRunning] = createSignal([]) + + const refresh = async () => { + try { + const directory = props.api.state.path.directory + const result = await props.api.client.experimental.background.list( + { directory }, + { throwOnError: true }, + ) + setRunning(runningJobs(result.data)) + } catch { + setRunning([]) + } + } + + createResource(async () => { + await refresh() + const timer = setInterval(refresh, POLL_MS) + return () => clearInterval(timer) + }) + + const theme = () => props.api.theme.current + + return ( + 0}> + show(props.api)} + backgroundColor={theme().backgroundElement} + paddingTop={1} + paddingBottom={1} + paddingLeft={2} + paddingRight={2} + flexShrink={0} + > + + {running().length} bg + + + + ) +} + +const tui: TuiPlugin = async (api) => { + api.slots.register({ + order: 200, + slots: { + app_bottom() { + return + }, + }, + }) + + api.keymap.registerLayer({ + commands: [ + { + name: "background.jobs", + title: "Background jobs", + category: "System", + namespace: "palette", + run() { + show(api) + }, + }, + ], + bindings: api.tuiConfig.keybinds.gather("background.palette", ["background.jobs"]), + }) +} + +const plugin: BuiltinTuiPlugin = { + id, + tui, +} + +export default plugin From b22ed60d69290cb3c7ea46c3627d63627657418f Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 31 Jul 2026 17:11:07 +0800 Subject: [PATCH 2/2] refactor(tool): remove SummaryMode and flatten background shell closures - Drop the unrequested SummaryMode (head/error/tail) feature and its summary_mode parameter - Collapse runShell/runTask/notify into inline run() calls; keep only renderBackgroundOutput and injectBackgroundResult helpers - Inject the background result once via onPromote instead of a duplicate wait --- packages/opencode/src/tool/shell.ts | 197 +++++---------------- packages/opencode/src/tool/shell/prompt.ts | 17 +- 2 files changed, 45 insertions(+), 169 deletions(-) diff --git a/packages/opencode/src/tool/shell.ts b/packages/opencode/src/tool/shell.ts index 1e020145deb5..461f94d592e1 100644 --- a/packages/opencode/src/tool/shell.ts +++ b/packages/opencode/src/tool/shell.ts @@ -19,7 +19,7 @@ import * as Truncate from "./truncate" import { Plugin } from "@/plugin" import { ChildProcess } from "effect/unstable/process" import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner" -import { ShellPrompt, type Parameters, type SummaryMode } from "./shell/prompt" +import { ShellPrompt, type Parameters } from "./shell/prompt" import { BashArity } from "@/permission/arity" import { BackgroundJob } from "@/background/job" import { Identifier } from "@/id/id" @@ -267,67 +267,6 @@ function tail(text: string, maxLines: number, maxBytes: number) { } } -function head(text: string, maxLines: number, maxBytes: number) { - const lines = text.split("\n") - if (lines.length <= maxLines && Buffer.byteLength(text, "utf-8") <= maxBytes) { - return { - text, - cut: false, - } - } - - const out: string[] = [] - let bytes = 0 - for (const line of lines) { - const size = Buffer.byteLength(line, "utf-8") + (out.length > 0 ? 1 : 0) - if (out.length >= maxLines || bytes + size > maxBytes) { - if (out.length === 0) { - out.push(line.slice(0, maxBytes)) - } - break - } - out.push(line) - bytes += size - } - return { - text: out.join("\n"), - cut: true, - } -} - -const ERROR_PATTERN = /\b(error|fail(ed|ure)?|warning|exception|traceback|cannot|unable|fatal)\b/i - -function errorLines(text: string, maxLines: number, maxBytes: number) { - const lines = text.split("\n") - if (lines.length <= maxLines && Buffer.byteLength(text, "utf-8") <= maxBytes) { - return { - text, - cut: false, - } - } - - const out: string[] = [] - let bytes = 0 - for (const line of lines) { - if (!ERROR_PATTERN.test(line)) continue - const size = Buffer.byteLength(line, "utf-8") + (out.length > 0 ? 1 : 0) - if (out.length >= maxLines || bytes + size > maxBytes) break - out.push(line) - bytes += size - } - if (out.length === 0) return tail(text, maxLines, maxBytes) - return { - text: out.join("\n"), - cut: true, - } -} - -function summarize(text: string, mode: SummaryMode, maxLines: number, maxBytes: number) { - if (mode === "head") return head(text, maxLines, maxBytes) - if (mode === "error") return errorLines(text, maxLines, maxBytes) - return tail(text, maxLines, maxBytes) -} - const NETWORK_COMMAND = /^(curl|wget|ping|tracert|tracepath|ssh|gh)\b/i const NETWORK_GIT = /^git (fetch|pull|clone|push|ls-remote)\b/i const BUILD_COMMAND = /^(bun |npm |yarn |pnpm |mvn |gradle |cargo |make )?(build|test|typecheck|check|lint|install|ci)\b/i @@ -520,7 +459,6 @@ export const ShellTool = Tool.define( cwd: string env: NodeJS.ProcessEnv timeout: number - summaryMode: SummaryMode }, ctx: Tool.Context, ) { @@ -661,7 +599,7 @@ export const ShellTool = Tool.define( } if (aborted) meta.push("User aborted the command") const raw = list.map((item) => item.text).join("") - const end = summarize(raw, input.summaryMode, limits.maxLines, limits.maxBytes) + const end = tail(raw, limits.maxLines, limits.maxBytes) if (end.cut) cut = true if (!file && end.cut) { file = yield* trunc.write(raw) @@ -698,27 +636,12 @@ export const ShellTool = Tool.define( const prompt = ShellPrompt.render(name, process.platform, limits, defaultTimeoutMs) yield* Effect.logInfo("shell tool using shell", { shell }) - const runShell = Effect.fn("ShellTool.runShell")(function* ( - params: Parameters, - ctx: Tool.Context, - shell: string, - cwd: string, - timeout: number, - ) { - return yield* run( - { - shell, - command: params.command, - cwd, - env: yield* shellEnv(ctx, cwd), - timeout, - summaryMode: (params.summary_mode ?? "tail") as SummaryMode, - }, - ctx, - ) - }) - - const renderBackgroundOutput = (jobID: string, command: string, state: "running" | "completed" | "error", exit?: number | null, text?: string) => { + const renderBackgroundOutput = ( + jobID: string, + state: "running" | "completed" | "error", + exit?: number | null, + text?: string, + ) => { const header = `` const tag = state === "error" ? "shell_error" : "shell_result" return [header, `<${tag}>`, text ?? "", ``, ""].join("\n") @@ -728,28 +651,24 @@ export const ShellTool = Tool.define( ctx: Tool.Context, ops: TaskPromptOps, jobID: string, - command: string, - state: "completed" | "error", - exit: number | null, - text: string, + info: BackgroundJob.Info | undefined, ) { const msg = yield* MessageV2.get({ sessionID: ctx.sessionID, messageID: ctx.messageID }).pipe( Effect.provideService(Database.Service, database), Effect.orDie, ) const variant = msg.info.role !== "assistant" ? undefined : msg.info.variant + const state = + info?.status === "error" + ? "error" + : /state="error"/.test(info?.output ?? "") ? "error" : "completed" + const text = info?.status === "error" ? (info.error ?? "") : (info?.output ?? "") yield* ops .prompt({ sessionID: ctx.sessionID, agent: ctx.agent, variant, - parts: [ - { - type: "text", - synthetic: true, - text: renderBackgroundOutput(jobID, command, state, exit, text), - }, - ], + parts: [{ type: "text", synthetic: true, text: renderBackgroundOutput(jobID, state, null, text) }], }) .pipe(Effect.ignore, Effect.forkIn(scope, { startImmediately: true })) }) @@ -776,12 +695,13 @@ export const ShellTool = Tool.define( const runInBackground = params.background === true const timeout = - params.timeout ?? - (runInBackground - ? defaultTimeoutMs - : defaultTimeoutFor(params.command, defaultTimeoutMs)) + params.timeout ?? (runInBackground ? defaultTimeoutMs : defaultTimeoutFor(params.command, defaultTimeoutMs)) + if (!runInBackground) { - return yield* runShell(params, ctx, shell, cwd, timeout) + return yield* run( + { shell, command: params.command, cwd, env: yield* shellEnv(ctx, cwd), timeout }, + ctx, + ) } if (!flags.experimentalBackgroundShell) { @@ -796,77 +716,44 @@ export const ShellTool = Tool.define( } const jobID = Identifier.ascending("job") - const metadata = { - command: params.command, - cwd, - background: true, - } + const metadata = { command: params.command, cwd, background: true } // The background run must outlive the originating tool call: the AI SDK - // aborts the tool-call signal when the call's lifecycle ends (after the - // model consumes the "running" result), which would kill a child process - // still listening on `ctx.abort`. Give the background task its own - // signal so only explicit `background.cancel` interrupts it. + // aborts the tool-call signal when the call's lifecycle ends, which would + // kill a child process still listening on `ctx.abort`. Give the background + // task its own signal so only an explicit `background.cancel` interrupts it. const bgAbort = new AbortController() const bgCtx = { ...ctx, abort: bgAbort.signal } - const runTask = Effect.fn("ShellTool.backgroundRun")(function* () { - const result = yield* runShell(params, bgCtx, shell, cwd, timeout) - const state = result.metadata.exit === 0 ? "completed" : "error" - return renderBackgroundOutput(jobID, params.command, state, result.metadata.exit, result.output) - }) - - const notify = Effect.fn("ShellTool.notifyBackgroundResult")(function* () { - yield* background.wait({ id: jobID }).pipe( - Effect.flatMap((waited) => { - const info = waited.info - if (info?.status === "completed") - return injectBackgroundResult( - ctx, - ops, - jobID, - params.command, - /state="error"/.test(info.output ?? "") ? "error" : "completed", - null, - info.output ?? "", - ) - if (info?.status === "error") - return injectBackgroundResult(ctx, ops, jobID, params.command, "error", null, info.error ?? "") - return Effect.void - }), - Effect.forkIn(scope, { startImmediately: true }), - ) - }) - - const info = yield* background.start({ + yield* background.start({ id: jobID, type: ShellID.ToolID, title: params.command, metadata, onPromote: Effect.all([ - ctx.metadata({ - title: params.command, - metadata: { ...metadata, jobId: jobID }, - }), - notify(), + ctx.metadata({ title: params.command, metadata: { ...metadata, jobId: jobID } }), + background.wait({ id: jobID }).pipe( + Effect.flatMap((waited) => injectBackgroundResult(ctx, ops, jobID, waited.info)), + Effect.forkIn(scope, { startImmediately: true }), + ), ]), - run: runTask().pipe( + run: run({ shell, command: params.command, cwd, env: yield* shellEnv(ctx, cwd), timeout }, bgCtx).pipe( + Effect.map((result) => + renderBackgroundOutput( + jobID, + result.metadata.exit === 0 ? "completed" : "error", + result.metadata.exit, + result.output, + ), + ), Effect.onInterrupt(() => background.cancel(jobID)), ), }) - yield* notify() - return { title: params.command, - metadata: { - ...metadata, - jobId: info.id, - output: "", - exit: null, - truncated: false, - }, - output: renderBackgroundOutput(jobID, params.command, "running", null, BACKGROUND_STARTED), + metadata: { ...metadata, jobId: jobID, output: "", exit: null, truncated: false }, + output: renderBackgroundOutput(jobID, "running", null, BACKGROUND_STARTED), } }) diff --git a/packages/opencode/src/tool/shell/prompt.ts b/packages/opencode/src/tool/shell/prompt.ts index f0d2a0aa78c3..6f80fdb697b7 100644 --- a/packages/opencode/src/tool/shell/prompt.ts +++ b/packages/opencode/src/tool/shell/prompt.ts @@ -7,11 +7,6 @@ import { ShellID } from "./id" const PS = new Set(["powershell", "pwsh"]) const CMD = new Set(["cmd"]) -export type SummaryMode = "head" | "tail" | "error" - -const SUMMARY_MODE_NOTE = - " - Use `summary_mode` to control how large output is summarized: `\"head\"` (first lines), `\"tail\"` (last lines, good for build/test failures), `\"error\"` (only lines matching error/fail/warning patterns). Defaults to `\"tail\"`." - const BACKGROUND_NOTE = " - For long-running commands (builds, tests, CI polling, watchers), set `background: true` to run the command in the background and keep the conversation responsive. The result will be delivered automatically when it finishes. DO NOT sleep, poll, or check on a background command. Background commands use the full default timeout unless you pass an explicit `timeout`." @@ -27,12 +22,6 @@ export function parameterSchema() { workdir: Schema.optional(Schema.String).annotate({ description: `The working directory to run the command in. Defaults to the current directory. Use this instead of 'cd' commands.`, }), - summary_mode: Schema.optional( - Schema.Literals(["head", "tail", "error"]).annotate({ - description: - "How to summarize the command output when it is large. 'head' keeps the first lines, 'tail' keeps the last lines (useful for test/build failures), 'error' keeps only lines containing error/fail/warning patterns. Defaults to 'tail'. The full output is always written to a file when truncated.", - }), - ), background: Schema.optional(Schema.Boolean).annotate({ description: "Run the command in the background and return immediately. The result will be delivered as a follow-up message when it completes. Use this for long-running commands (builds, tests, CI polling) that would otherwise block the conversation. DO NOT sleep, poll, or check on background commands.", @@ -113,7 +102,7 @@ function bashCommandSection(chain: string, limits: Limits, defaultTimeoutMs: num Usage notes: - The command argument is required. - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms (network operations get a shorter default timeout, build/test operations a longer one). -${SUMMARY_MODE_NOTE} + ${BACKGROUND_NOTE} - If the output exceeds ${limits.maxLines} lines or ${limits.maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Do NOT use \`head\`, \`tail\`, or other truncation commands to limit output; the full output will already be captured to a file for more precise searching. @@ -166,7 +155,7 @@ Before executing the command, please follow these steps: Usage notes: - The command argument is required. - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms (network operations get a shorter default timeout, build/test operations a longer one). -${SUMMARY_MODE_NOTE} + ${BACKGROUND_NOTE} - If the output exceeds ${limits.maxLines} lines or ${limits.maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Do NOT use \`Select-Object -First\`, \`Select-Object -Last\`, or other truncation commands to limit output; the full output will already be captured to a file for more precise searching. @@ -217,7 +206,7 @@ Before executing the command, please follow these steps: Usage notes: - The command argument is required. - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms (network operations get a shorter default timeout, build/test operations a longer one). -${SUMMARY_MODE_NOTE} + ${BACKGROUND_NOTE} - If the output exceeds ${limits.maxLines} lines or ${limits.maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Do NOT use \`more\` or other pagination commands to limit output; the full output will already be captured to a file for more precise searching.