From d91ca630d68dcf851f3af048256ff05990dc5b2f Mon Sep 17 00:00:00 2001 From: Younes Abouelnagah Date: Thu, 5 Nov 2026 11:15:28 -0500 Subject: [PATCH 1/5] feat(mcp)!: serve the card at its compatibility line on the SAGA 1.0 candidate The card's address now names its compatibility line, ui://views/answer-card.v1.html, instead of a hash of its bytes. Every compatible release, including a release stamp or a card change, is served at the same address, so a host that still holds a tool descriptor from before a deploy reads a card that is served (#335 Q1). SAGA moves to the 1.0 release candidate, packed from the SDK's source at 8b4d987 and committed under candidates/ until 1.0.0-rc.1 is on the npm registry. The manifest pins the exact candidate version, and the root pnpm-workspace.yaml overrides the five siblings to the tarballs. The MCP packages, hono and @hono/node-server align with the SDK, with its documented dompurify and @hono/node-server overrides. - The packaging test checks a candidate against the committed tarball bytes, and a registry release against its npm integrity. - The card's SDK identity names a candidate by its source commit and tarball digests. - The Dev release gate accepts the candidate under apps/mcp/candidates; Beta and Production still refuse it. Co-Authored-By: Claude Opus 5.5 --- apps/mcp/Dockerfile | 2 + apps/mcp/README.md | 18 +- ...mponents-0.0.0-candidate.g8b4d987dd233.tgz | Bin 0 -> 29828 bytes ...2ui-core-0.0.0-candidate.g8b4d987dd233.tgz | Bin 0 -> 58813 bytes ...a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz | Bin 0 -> 53607 bytes ...ui-react-0.0.0-candidate.g8b4d987dd233.tgz | Bin 0 -> 28918 bytes ...cp-stack-0.0.0-candidate.g8b4d987dd233.tgz | Bin 0 -> 18511 bytes apps/mcp/package.json | 10 +- apps/mcp/scripts/check-release.mjs | 5 +- apps/mcp/scripts/sdk-identity.mjs | 21 +- apps/mcp/src/server/view-artifact.ts | 16 +- apps/mcp/src/view/saga-credit.tsx | 2 +- apps/mcp/test/browser.ts | 9 +- apps/mcp/test/diagnostics.test.ts | 6 +- apps/mcp/test/packaging.test.ts | 90 ++-- apps/mcp/test/parity-cases.ts | 5 +- apps/mcp/test/runtime-boundary.test.ts | 13 +- apps/mcp/test/transport.test.ts | 9 +- pnpm-lock.yaml | 389 +++++++++--------- pnpm-workspace.yaml | 12 + 20 files changed, 327 insertions(+), 280 deletions(-) create mode 100644 apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz create mode 100644 apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz create mode 100644 apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz create mode 100644 apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz create mode 100644 apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz diff --git a/apps/mcp/Dockerfile b/apps/mcp/Dockerfile index e5227bee..a6ff0511 100644 --- a/apps/mcp/Dockerfile +++ b/apps/mcp/Dockerfile @@ -5,6 +5,8 @@ RUN corepack enable && corepack prepare pnpm@10.33.0 --activate COPY package.json pnpm-lock.yaml pnpm-workspace.yaml LICENSE ./ COPY packages packages COPY apps/mcp/package.json apps/mcp/ +# Until SAGA 1.0.0-rc.1 is on the registry, the install resolves it from these private tarballs. +COPY apps/mcp/candidates apps/mcp/candidates RUN pnpm install --strict-peer-dependencies --frozen-lockfile --filter ansari-mcp... COPY apps/mcp apps/mcp RUN pnpm mcp build diff --git a/apps/mcp/README.md b/apps/mcp/README.md index 6f027629..841e9901 100644 --- a/apps/mcp/README.md +++ b/apps/mcp/README.md @@ -1,6 +1,6 @@ # Ansari MCP -A standalone MCP application. `answer_islamic_question` calls the Ansari API and returns its complete answer and attribution unchanged. SAGA links each result to one content-addressed, self-contained React card. The application owns Ansari branding, floral artwork, theme mapping and Hono HTTP hosting; SAGA owns content interpretation, FaithfulCard rendering, content policy, consent and MCP view linkage. +A standalone MCP application. `answer_islamic_question` calls the Ansari API and returns its complete answer and attribution unchanged. SAGA links each result to one self-contained React card at a stable, versioned address. The application owns Ansari branding, floral artwork, theme mapping and Hono HTTP hosting; SAGA owns content interpretation, FaithfulCard rendering, content policy, consent and MCP view linkage. ## How it works @@ -32,11 +32,15 @@ User-provided capture of the Dev answer card in Claude, showing Arabic text, RTL ## Dependencies -SAGA is installed from the public npm registry at one exact release, `0.7.6` (stable), from the [0.7.6 release branch](https://github.com/MachineWisdomAI/saga-a2ui/tree/codex/release-0.7.6): the stack `@saga-a2ui/react-mcp-stack` -plus its exact-version siblings `@saga-a2ui/core`, `@saga-a2ui/components`, `@saga-a2ui/mcp` and `@saga-a2ui/react`. No private registry, -credential, SDK tarball, SDK workspace link or SDK-package override is involved, and the manifest pins an exact version rather than a tag or range. -`pnpm check:release --target beta` checks the pinned release against the registry and the lockfile; `--target production` additionally refuses a -prerelease. The Beta and Production deploy scripts run the corresponding gate before any build or deployment. +SAGA is the 1.0 release candidate, `0.0.0-candidate.g8b4d987dd233`: the stack `@saga-a2ui/react-mcp-stack` plus its exact-version +siblings `@saga-a2ui/core`, `@saga-a2ui/components`, `@saga-a2ui/mcp` and `@saga-a2ui/react`, packed from the SDK's source at commit +`8b4d987` and committed under `candidates/` until `1.0.0-rc.1` is on the npm registry. The manifest pins that exact version; the root +`pnpm-workspace.yaml` overrides the five siblings to those tarballs, and the lockfile records their integrity. No private registry or +credential is involved. Moving to the registry release replaces the pin and the overrides and deletes `candidates/`. +The card's address names its compatibility line, `ui://views/answer-card.v1.html` (`VIEW_MAJOR` in `src/server/view-artifact.ts`), not its +bytes: every compatible release is served at the same address, and only a change an already-loaded card cannot handle increases it. +`pnpm check:release --target beta` checks the pinned release against the registry and the lockfile, and refuses the candidate; `--target production` additionally refuses a +prerelease. The Beta and Production deploy scripts run the corresponding gate before any build or deployment, so neither deploys until the release is published. Dev accepts the candidate. The application depends on one SAGA package, the stack `@saga-a2ui/react-mcp-stack`, plus React and React DOM, and imports only its subpaths: `/faithful-card` (`FaithfulCardApp`, `startFaithfulCardApp`, and the definition's one `.result(...)` reader that reads the whole delivered result, @@ -100,7 +104,7 @@ The Worker takes the variables in the table below as Wrangler `vars` or secrets, | `MCP_VIEW_DIAGNOSTICS_ORIGIN` | Set only on a deployment being diagnosed: its own public origin, such as `https://ansari-mcp-development.up.railway.app`. The card may then connect to that one origin and reports its start-up milestones to `POST /diag/view`; this changes the card's bytes, address and permissions. Unset, the card, its address and its closed permissions are unchanged and the route does not exist. A value that is not a bare `https` origin (`http` only for localhost) stops startup. Implies `MCP_LOG_LEVEL=debug`. See [First-load diagnosis](#first-load-diagnosis). | | `MCP_LOG_LEVEL` | `info` (default) or `debug`. `debug` also writes the first-load measurement records; set it only on a deployment being measured. Any other value, or `info` together with `MCP_VIEW_DIAGNOSTICS_ORIGIN`, stops startup. | -`POST /mcp` serves stateless MCP requests through Hono and the official MCP request handler. Modern requests need no initialization; older hosts can use the handler’s stateless compatibility path. No MCP session IDs, session map, expiry timer or replay store are retained. `GET /mcp` and `DELETE /mcp` return 405. `/health` exposes the release. The HTML is supplied by the hosting target (read from `dist/` at Node start, bundled into the Worker), revision-stamped and fingerprinted once before the first request is served: the release is stamped first, so equal final bytes have equal identities and a release change legitimately changes the hash. Each request creates its own lightweight MCP server using that prepared view; resource bytes and identity stay fixed until restart. No demo, font server, alternative renderer or historical resource is served. Tool calls have a fresh 60-second budget; timeout yields a safe error and leaves subsequent calls usable. The same lifetime signal aborts the upstream fetch and response-body read when the request ends or the budget expires. +`POST /mcp` serves stateless MCP requests through Hono and the official MCP request handler. Modern requests need no initialization; older hosts can use the handler’s stateless compatibility path. No MCP session IDs, session map, expiry timer or replay store are retained. `GET /mcp` and `DELETE /mcp` return 405. `/health` exposes the release. The HTML is supplied by the hosting target (read from `dist/` at Node start, bundled into the Worker), revision-stamped once before the first request is served. The release stamp changes the card's bytes, not its address, which is `ui://views/answer-card.v1.html` for every compatible release. Each request creates its own lightweight MCP server using that prepared view; resource bytes and identity stay fixed until restart. No demo, font server, alternative renderer or historical resource is served. Tool calls have a fresh 60-second budget; timeout yields a safe error and leaves subsequent calls usable. The same lifetime signal aborts the upstream fetch and response-body read when the request ends or the budget expires. Closing a request server releases its budget even if it was never connected to a transport. On SIGINT or SIGTERM the listener stops accepting requests, closes MCP handlers and HTTP connections, and exits; unfinished calls are interrupted, including older-host SSE calls. Fetch cancellation does not guarantee that the remote backend has stopped processing. Caller-disconnect propagation depends on the host transport; the local Workers runtime does not establish immediate upstream cancellation from a client disconnect. Actual fetch cancellation at the request deadline is covered on both hosting targets. diff --git a/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz b/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz new file mode 100644 index 0000000000000000000000000000000000000000..0a01a17abb94d8e1b1c8b076ed3ddbc18b719db4 GIT binary patch literal 29828 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 literal 0 HcmV?d00001 diff --git a/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz b/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz new file mode 100644 index 0000000000000000000000000000000000000000..33512d445fd3b43acd2a5ba2258f600a266781e7 GIT binary patch literal 58813 zcmV)9K*hfwiwFP!00002|Lnc_ciTpmDBM5muc+wt7m*$clGk)7FQeGbw5Aiw$5N6v zlj9c@iK2)W2yjrKWJb~d{++wk0)Vm{r#(IIIcLta1p>9)x^?$usi)`q%P zj<%JZ>!MH#qf6DyjcQE2uu7MinpR~-U#VGDtCck)Rhwm9WveMX9`R7{ZkF4o&L=B) zuC!GdOldMTS*sH>r9tkhW?omTv$^_ORWsGhbE~pyx>}gBX|JoQI}4ju%XOWf%^Ou+ zmZnx!txVbE&06VIGq39WSDcT>>HDIY>qg~Poz=Q*^70H{VmJf~FlV|@FLCJ3B331A z5La)Mp5iF7iZWBWD0rBvnHyeUZY)hbt;(jZijmT_kv|Gt^ayqXPgiATYBjAEi>l<2 z_(gS@H**??CQQ_~RgLRduIgoFjrCA<2QFu{&7*ANR;(K2L;AG3H1$Yjd2OZ*EFv%I z-y_vjYN}V(z8jc=;ANmyV;fy&a0Yg+Yhz`^e5fX-G_!n~ z>mnXKSf@Yo|EN~mYEaequX=kJp1Lj(CKq|Og0X59;s+04-kExuTUf}_)Qj9&M0mtA zx&(ME9aKB1R`t|u!}VIUF>P6!nW<}&(XTUv_&H3msIq*PPc_~uIpDmU7ApkBWYws$ zYE+Rga+tlTl&xmXC7_qZ3Dva9%*fq69EgXZ7e;dbXZhKx#^2Q}FHAr_jwgRN)26$0 zU9Ra_ZS1PR`!TDlg<6>DT$lM&%LQp_U0Qfk3qs+Og8!T;tq43g+$i24kI~xZv|224 zxKI@?j<giiCE9REy{1)pLDbvAICOUxCd;*I*2{3)KUMX4hbUZD^*OE>=@4L= zzXEwF+i(|vK*!r!=*%d6q4Ppd3c3FQT^a#31q7UGMkVd&f>5`zYVxUZ2nMq7iMDWfC0@l0<^b%ks|C?2mz?!x6fpUwkfV6wcaYPjyT zxybP-0gKD3;d`P?p(j->e^s>{b9kG0FyL~=nzBLYYjruV3cM7ms`InF)J4ykcj>Xv zsabUWN2(1zh8|!upB)a*T%$G%oxA&Kmbykv0l45c7N$1ES`~SDj)0rwCE`h`7iK7j zo|lcOXL^cEVifR52h`4@06M0c`BQ%mq?~zt?}@kXfV;B6d=7wo;e?mEb--ZJnIH~l zEQ!cS6~P9-s_Ko49|f190jgh>x+sKf+tp-|H%vT4?m+CqmE-dGD&Ry&$2($$oHDYz z8@WX&r~p;Q=>gv-X0D5ws%D#om)miBwe9w_&0`V2cVxMmDN~qfQ&(j^9ltNiB3y8#@YFmJ@~S z+BRlkLlT}_yE4E+rpP1t4LW|{d?c+nSt|tkC?F#d76i}+xMjJWt}JqSoN{ncQx7WUg4H}?Y1p9@Vz2W2tc5Zi`JxSuC1CFQ>xlb4N~&SI-18{LTmnOWy+?2 zX{S}atcYEMz#CjYB1HER^=}|n!L-la_C>N%Co5vEjH|uMOmNLYs%-Rht^xolAR&`A zNpUC_{71D?8YH}>X;!)r^t-I;BD>5%)+noT7f;^i7x?Gybgt_&P@Jl@E}Hf3tTtw( z^13z`)f5PMhnuth2NR06Wkw(lE&-1_l+Kg$gBQk zb+amqH9;9@7cXsE=zL-M-C%Q*H4PF%*U`<=OpUd=&hd86>byJ?jmG4{`@)MqutTMb zsx-_Ir`2MTmrkn3&)OfzhDgI@ZrfBWQ2#eLuzmXodP%GzB77;Ix&tw4UFzw=UQRp?8*${W~fVa|vN=*BJH%LFZ| zcoTs`oj_1W1@&mqKxuQ5kD8Z>0dhID&n+i>OefRk=q-FU_& z5`253G0?Ih5G{B9toXrEZ@)S|J$n9fTQ%lggYbrH$8&(l9n2Hnu7Cve+>{Pv@w|ee zMD^6FHabHc(<7bf1uGCG4R+pO7$#~+8E7N8h0$%`8Vu79;a<2Rvgt+@Mq5y)LMuIg z;&1D+03~=V%ha+)4{Hyh2&?RkYd8prd4y!)y^ak~DxY~e11$5*bHMKSRXyrLS&OU} zSh-j?=z-F#byHA)xG*&xRx{7*Y!^1Uc4t$9eXc0hAXpe(C+c)gS{Tr;E|`P!M&W@} zX=miqMWDQbgc2`@?-o+5b!3}&Y(r-m{JREyC&b8L6j?e$=r%WDM9{Z+7NHL6Q()f6 zGE-)&g@~;Y#t2~{{ZEdwP16v-V#Lrz|7AjJm6{lm1L{>9{|GRf{1&|+@>&Iot!S(# z0ib303XTE>;eCWl29sP4QfnmT_DJyFwAbS@qG1AGQ8nvX&B$My87hnG4XQ|JopV~$6FO~VJCHiEg3~=z@x}4<203)CJ-ISLsWLy6F|DEmjZ2~ekcoLEgqVA zw=D8$4(czC7&u6rePi90A_HSqV8+^Ly7H1f%-A;Mkf=8at3 z6YnE^|Eg->Bj>$A{xYdZDT8Z!hUy)#5nP&GElq7rX2=l)*C03&o`|FiGLSaLt3+qD zA;e$v4MB~}yff2)#3SK#0IAKHuF0>|);-u4@F-EIB7j&Ri-8=SRY*A-61fA95CEPX zY9zjh8$&O^ZssH!uzH#L0&M#HXH_f4VR~7RR#rUnRwq_dYx7^LoV`cD&}~&BOUEN! z*``{6dm2`gmtbU?*7<~w!YLhKsqNTjWK9YzYTlq?c`|^fh{}t%f{pxv@!hw6sRLLm7!BGgYWOyoFQda9f?Z3OYWwg+ z9i42eZw^n6P6W6=9i9I5_=i*V)8U&php$eLUY@AqH=$ep_*-@O>Oa)qj$XYODU*{2 z_#IeBt=~zGbR`SSr2Yn>om2~*TB}O}6)Hq^m&8^xb$WFA-OG`Bb^L1g=+(Dxj$ZxS z%kN*lIvuI+U%q+%*TYw*hu<81cXaw6h(g~UoxXZ`Lg534JjUz8H>XF>fB5e3je7mV zo7cxDFNxcdx3B=uLT&7_Ds7Hl2lUL4Rv4p;UM}luS?3_03j@GU+OSt!!M1AK#3Lkx!>q%aq^ZW=nuQC^a zyRZ%#qpVbc#?EGLs(KxmTEvspRCN=Y3`%oWk2+E`I4(8x5%Vezshao?lFn_ zYjp{l5UG+5U987@5CcZAK%!6q{^Q)cwVyehID)48q}NQp$ac2M-!c~#fmTgH}SZLO){`mhmo z)U_K=)+}uJ4XptJ9;Qy1zYMT35F6cE2!UU|dI5a3FANTUKYacA<*OG*|9cEah}MGT zvRHHYLKwOSzu{6Yoi7Q(>u&kMh{GsiYl4W?RbH5SSpc;rZEoZ>`B`p?%qmk(i^>ww zpMaOrG*)f@{C3+bDPWmkZnqX>LaNGIU!X}RYVe{ecU-(ca7ShEFNO-WbyQRByjm3* zi1=fhmvxSYYoNi~z$;?UCkMa4GL5#m^T#vf#P90NGv3Id>**Xk z)`Se+nfUX1y5Tyj{qSc_QmFN z5##fc)lejj4x^li6KMU_1g&K{GT8|t>qgN1eIchD2fceQ*~d?ABcX4SJvioUE3{HZ z@RH?02t)9~CJFo_#cvV35o{;ML`x7PN3mv>PgSAIvz0zG>a4mjb=i*WV{3_**KK!S z$=07f|MyS+-;(41`G1qY+p7Ge@&Ehx?mpOW$N%4b_~8EM`2SDw-_w}_rsA| zfb$$RDvF3#c12-$B%jr*5~IjbwggEI0xsE_0)kQvf7Yhn9&Iy?-X3ogp8*=ZJ=%u& z)a~*1qRLhUEZe*T;n{AFueOst9(sGco$T3qDu3_6Oz)D$Zjby+{J*=CRnt`EuAR=! zLU+FGdr1c3C|b=hq7TD|@**g=7p6AZE~$I&<@OKq!Mw7~E(AFGt@uas(z33aYFZU` z50CL;|Cg`b+daROmBASI z?j`s3lZT9WwEpe!_Wya9e2qh2ezBi?O~nsj$m* zjVppk5u+UGrb(FEM=EN$ zT&T1(@0wIK`Yche*=mB83G)t4D9B?#SEZ8-g`I$IkD4%r-wtI^3;Pu7)X!kYTrEt!TUS+smI2*}@fV|Y&2&|xDfGhBH8{B54nBk>?oEnn zvIof~ds#KLdlWsq3zj}z6v-m{U;NMAsx-T{(bMzYWwElmvsy0aT5QOn}=Hnn!69(_CwSOaT~l1wPOL&9tJ^u)av%Nb zUQBv5$mH*K=U{7V@6Meqb%)#}=r3^Ql8z&^Jg^ z4wt!lqOP_m@Mo-c!XJ0Q)=jGzt6$MwEy5U{r@EYF=;-` zf=JC(+0-kbH$)Nga=B{83R7$iP`%Z(S=A8eGFe0DaNd{&2gZ@Iu}e{$=o_*yy33`) zs|30Lkui{5m%6r0gmI#f#!(=oDXhzi$thGxUO}2;XyNC^Ea3$T(RP>IGDjoTDld?Z zp#VJ+#S%U9@J6lIMDt2x(Nz!eo_EM$pZ{u*^r45jT0v-m#%z*_QPrxpiF%33;lF zAA@|r!-^hGX1ja>L(bWk9A8;gq7K!WX&S0nqk(a~L#~A}GkB1+$5QHUz`}rW8HYTO z?6xr4u8=2N|AtE^1|5^w4u~5R^@eK!7^dW&ND+vMdI@n10B42vREXjM5BnJ;nR~wF zDh8+{fH{u{JP0QEp8XnFW1=*etc_nQ+zm#mEc82hZLG@GVq)q8{``m2Z+HKK7YO67 z5cDWfaBj8Z?kF25&@$<~OnC;mT{Eb100FEB1=}<8H!ya4+8^<41@$4|eh-MT!ufmT zU)Hcwhzr1Yz7So?E&kMLx?Rkzc>s`W#N<(9}hysqfs4@e^GG;4_$C#OS269|%qwWF?@0sxs z#=;r=wAXEfy9A7cnIp>d;aK;E$!QDm_z349&S07my$xHU06i3f1c7pltDc($OLGg; zXn6Iu$JWAAH2ol!+Af+}r56>^mBsrJ@_H*45MR9f_V9=APJcOi_4hAtM`5*p~H+OG;Klp+X=#jh>9`9X#@%muHI^VoJ zJv@5#@`YP!>%81*dFqGJ)V$cckJ_ufCVff$gd`Lh>7~if=5{RQx19dO__Y(5`SesS zY(Gvh5U#_Bb=!gRr-K2^V=MHLIejkbpJ4W0lY zRpD?(B}pQKkKhlt%WF6mh|?L+H$M|=KzjTZaDwu869d7B#tvxA;ZTv4@zR`}Yz)@v@-K5x|1Cu;v) z_Lu#A_2rl0^T+snGMoA5gWg4|e}OH1srKK^rZDT1C-~)be;+@S-73GF2L~>OR$xL; zu4#$x#rrL+z#kAPJiP+3IF!8JCtBSo0Nu#!ZWJtTDFYn3d|)Wg1(BUd<|vh<$)TD6 z>I*3DqTMVdZ%zt#rBZ1Ff#FSx7>rc*TW~BOiT%w%+AW5@9jjG&URIao&u9shiN^I}M>+qjZ9W?I$RW4e7KS=iIttgFL`=h_}$mg)(UEtz|y&doZw z;FGE?hy~oCECM7)vF(AZ3mOWD22z@gXXls4fc;@FVyR$q68u5a)m> zUBC|3y9+?|To+iR4$3A87BVE+=s{=61|CVP{&#($*-g(b3^_k=7{i{z6;w0Ka3Baa zoRxEjKGF4>Ax7p6GE&hsh2#-3$=7C4T>u~s)pR|@6dP3SEt>_vl$RG|MKLJj3oKE} z#bTJcI2YTM5R$;A=g|Yt7d`aFnlB1?0$}j2b%#^=?Hp24coswsPg%t60%>sMPUxpE zV1aHxsDUf$SQ*IMbQ#8>kO0y(@h8tpD!`0-We)r!rcyjs@B^6n#*vnE-8bA!7d9Nv zurf6EYSFcmC{YO#iLxVN!h@dA1C8OpkxmRVuw#-6etxT-DB$R(HTUwQ3<4c@q9EjQKDIa+v(w*9+O%8=I(7|j)0%=S1XR$jJIzb$6 zjf}FXgY9WZmaCacYkip>C<`e}shnPl%o=V9!W!QRYFZ#3W2vqH+IU+5(6zqwxE)JB zBMEl;4#?ya+T+l@?GFRMMP}v@P$F%ElK9;Tva;Z!J8 z_fJKZfZI%khrV7yRjXQGBG2AoJI}q*rn(()EY|aGnEjpC==-R`@*c01`J{X6-fW@%H(vP0MX983NzgaeSW(KtUaC6Q%7 zL(lQ$XBH(BUydL61dQ>-xdTo197-M{1P=9pMMA)?CX6>kiCOV=H06aUs-@YnDiz~rdJqH9kBhPssB5E8 z#ULvtMN+Uho&=x?ss5K=svaIF7LZNo;jFT^#}JsfXC`m-*fdvY*1i37bSND&1xq%Z zON&xZvRv8uz|SrA2Dob4`cHk0FdEhWjoi-v$(BZ0(6EJG^mQA-zKFHm7{fk>pu~XK zU?l+NcPPh=j&MB@!KNlhQ$z+%Ab%pG5~BJsr?a3&GT;#z7M!69o7+GL`=F3tEwW`2|HNl$?l~JITL2=!Vnb9-&$hrvIG*q^ict6FjuF6JCu|$(6#<2A-fwQSbI zab&N~t&}iA`yIu1M7C=IUQh^Cvc9oVeNqM|iWr3{*pn0|W}pO09y?AV);A|Xbs zTUR&utv36+)HOPqLrYd*Qo5yWifBDrzx#x$ z*>Bj|;8nEFFM8Zt!}qQ-66E+SuEI*wfzTB=8@tk$ynJrfAAy9M5Rn|5VddcX!hY0o zMF97KB{zzM!D_A}In`@m8x011D+#2Ww!Gq;_CL+nK0Z_|(a6g&jZj!+!VX|CA&)4! z2x{n2@#)@>6Rs(0#HJ4vzia6aNqrD?gw&f2>wr1-GH<4HFV#9q2YH-c5+28@X6ggD z(IK@U2bM0?pRc-Rgli`lCFwyhI_VKN44qq50H3bAW8>jm6VT&P$s+u_7L2%eEupW` zsASTfop7rBn)z5ac8tI9R`S>xG48$xTgo%U?+ zk=Mv`6$kr{B$9I^vHc`Ez#Sp8FPOepSU)q9aAUF>L+m{}B!|fk-86Tds8DDSx(kG0 zZNvKTq|uQGIzVAC-Amy$%y*U$;9>8zf)Rhhq41yv@V8u*Q73w*6@mcl!vz?JL0(&A z67tLiV~+8UUpTgZbPUA=-SZQp7o#mdQSRQ0Cz51G z=9Ba>hY0$wnaIXpLjO8lXUD5%T0!V+Zcpcis)GA38-B#Ot4w}ymT%}{yq*Jjexi2r ztS}hET(3%~kca=arfCZK1LOlJHYt(KZ=}d2=4OJPN}Xjm>j>nH#R{wHqhg6A4p0W5 zVvbk{8-gmVE6D89q_{;*f7~~(`~;05Q6S|KHZzX4=0v08(geK~qduzOxu??65XDmV zWz6<2gfl&9HkZ?Iywv~2VIiwBhkpjl0?J;BijS6_Szcn?5bk>nQ8o*MIK74(o z7J7+HILGB`B}A>2myl<|JEAyGv>J^guyIBNQ0zMxifmO{U{zgHr%)?&I+yj3Z6G0n)Fy5kYR1tER#`qhK~DR+|cjr?gXA{oWR}HN>3_ zWPxKf7(%qdMU`j6@Q(jFNsol_2 zmkx2qLbMglA?e)G>7mr&ana8}OKfmk)cRH`NLw-yD>A;=yptkh~7kM;z9x(wHo00;My(#QNiG zB@%Q_KM{4)+;Iy0dWzO$ID&eY!2s+zJHA&bY^;vrLcmk<=B}Fn&-J{6|}8H zrTJM|)rKon@#zg!R#zDCjSOyHRp)R5K(MQD&*mL82~JeX<+Cxsh-fCv!Qj|LGo|Ks zN|~3We^H&RONr%$`*+ZSG@~+kTL{KMfV#j7JC)}pl$7Ggbk}?)3-`ub38Jy1P3L3vg-F%OlzYX!*u@fOJI_c|Hg|QceDk54O8NbUW`LF zfp)D(0A(^Tjzz;r8WUiR)d1P_Sm6u-k-iQS3<`))Wrb$o7m6DE-W~*vQ?ZmVAct7v zWu@{32;fxQdu?hvj!}OHu(+C@yKZG7*?~lGsp||wcv?w)k;XEBg(VWm4*=pn)U#*m zihQ*4Js~0t0r%v@G><)JdP?35v}kmtRi9h|9esZ_gDa8rS!=m=UlRufGT7nRmp<~yYGC;K;VOC zy$pn*SXFz<64{c}8yCd@W2cOOyMMm=mwyRa;B^{A$Uu?(*_sCj@cXdaz~b*nM>SJF zCrRQ?@U6H1W5_hzzX?zY*N!Vt1u_yGvSgVR zcO-@Q)S+KHCl#PXL4LL~;9Am`3{06}nA#U^laNd0g#8|822_Y_N9GXu0fV>;XLc(Y zw4!jlx;~K4hQpRp?|<=bohj583}(g?2&g>XW72>^1*qeIxDI@xrV%T^pu`yY5aBu~ zf)+lHffPmyvFN;i=j^=c;=%_mhJ)~tAQY@Cw=V=y2vviKeSgn?`;EpNP)bx}rEnv~ zW}0!^ZXH@l1 z4>#`+zm{1T<)0B?h=Od_q^vFnLmvm{q!gSdbFqE=_Z#f3G*&w>yZaIT@CyMN1Wyvd z!s}r>;8i3_*heH%_EGN5r^t5!l+-75+r38zpMKF76HDt&YASc{&kJQ!DYOKf*0t(H z2A?-#)x%CSp>ZL(70!7lx+h*fBnap#NT#$KxMBqIFdzmW(ATXC)Qx2hP>uw+4yH)p zC?bR_8qo0$$fX!Le3yb7F5**U2{x`rXCXw`k1PSv^!Bqv{v{{jFPq~n2SK)*P$>#f z?39&+B0F+$eNr38E=>%k4OInLu4ME!!ACipt(jS2b;=N$2`-6lQ4n7xueNRg6%pYd69Y9w{M~e+8s26m_w@RYaCUzF?^ga_NR>XT z>h&Mx0KU2Y@5B30>$m0q#hQ?x{lA}}{^K47KxtQo7p^8o16wuIwRD>^&@LE^oM)A> z6m%WoK*Cvlm;T8xb(gX4-VI73CszG}~OV-tGX9^it z^9H7n%*(JZ0QgBMKM1Xz+*2B?UZ6-ZF`b?xea#E3$GG-A=HfE-&ZXk4{f#xn46`|n z1$$9$=VS>F7y|GCu(SG(mSt7$n#Hn_T7RKi1zpU4105JkD?JzZQuUV|Fuqr-W{3VF zE3e7;PrU;Ba>EnvO1nD#)i-Y2%}klQ=c`g*=o~#^{KS`el!5(r+()RV2X&o~mj-Ge zN;|_bHsRy??^qU!>Kwyk*;C&5CgCs~on`6~Sr#?4vEj&NS6FmZqz zuNo|)snvu1yDp6p_JxmO_nZW9S?i^PJ~ctt1;47TN^#&cauDa`%wWG%w4-VteXmi^ zTT#^y(rT#^GrA|h6rZ1!Jodt%k)L3LwN*igLIW(l5GPrylypx#n^X;WOVEWBx^(Vf zG6-7V>E@8Td;&*}!`UJF2RzPkX=}AAXL^wrx%PdIo!=IU9F$x#1pP$O#dCs9RR0>2 zB7(I#S1J7!S;OUqjAKmnstcssR`r0x1bbg5(U_0Gg~pLEjP^kA{auA~uB>_HEpVvw zxp=kJ($oWYo;*M|kltPGFM?Qlur#?JP^SpA313eRx|>irxt+r@f)x3!bwD?raI!ND z#aGaVl9I9vcY+Z({SANiD{-TQp^L6Oy1W)KzPwbaAxz__ObW6{g*>IMV!Qkft2R`X z23a3f6Bd+e0-q{#6UX36H9)`9JH1#IT-}F#Oz7s}>=-z~AyG<=89r{c?EFF>89Jz# zkIP~=ID2U4`LCFrg1e0huE^KpHktHX0sTAiuW;U&kcTH4W+M1waz-3{DG85<)3W`w zraKMfitn)+AWcmV;clPgXQeI@zVqxAoS9}iPdVrXdHhgOXI4l6JpTSAwwuLj3?cwn zX>Wr(0}SL8Py5nSBBoaooa3T4QurjL2!*{pJS<)=A5Rkcs&H4K`Fn6yR1;mCf_|^9 zx{4MUUQ;eFAO3u>6}b7-!pdGWP+;u!!v3s(~4_uv(T*-q&M z=oY&3bz)54CwPGE51gdaihvbl{Hz%MQTku2Q{^Y>|MqAfbiS7UclZA1_}@>Z|3TaM zTQ^rzy2g+ssk85TiD0+`H;%*NcVN!qj%vHyc5S4J{G2!+v{Zv6$#XXX%6YLl4Rr_# z%n91F4WQ}O;c{tVil)l+dKh(Efi~Bujs}I;|Z4?i}I31G?yq>kiiWXqQh0A z5N*%t4Iut&&`2eMWfzi(K*vhQ{u7s0)KHMm($p3+gr)`Mo@)tmnm}*?zBwF;kS;ri z;guT;ax2zF1x5ER*trXt*;3$*<6NvEL!yKUQ&1v9l118jRZcMis;XrQr*ktZ9CX42 zNmgNX2DEL63*!P<2?HX~FGFbP>;fv2Tf?C!OU*spe0n#6+yMY_6HK9K2nWO?aYwns zxpeUeWh1kbC4(oH7rp$1jpa>a&_z-jl7NZ|rez*AOk6gLU;C6gwA1vILCtKit4zM3 zN!c|`6}M3RZY$sLH!XLk6?8`(3Nc~`&@$s(tu#P4`XNR*S1z#e6>Ttf+G*WfnvYEy zQ1<{N0WzZJfRcg?R0Rl>*E~y9%6;ZgLAQnz-8rXx0u6r6Y{n&8(ar)VW6$%Y(=J&F zUh^>>I@^eZjZq|{==pftc!!Bf(YTb#Ae5C&Ckxr_OXK2MO__BM{n5 zqwNEy-RV@P<;^`Cw~qM63b}6JzHj2#b5PrMcoIYoKEfSe2{%9zIs&~GDo*7wZHIP` zfxZXiopk~tMiNYNCgD4%-8!_u0%fZjBSm-;3`Vmqs>E3yq@Ehap7uozKM(my6e)ao z3;uKCqWe}%Lq~|4mmuk~$}ZwO#lgvqh$fA0O`^V8yJ7+eC>USXjMt*%dy&s%EO!^= zW*(>%uFFfjEmUD6MIwsEo!Xq~I)hsGy!=;e48^E@ID`&m;QDS9?7wV$%>GF1C2ZkE z6NV29j_3;66~d~I9lL=zEAIrz=g19aAsz%L1kDMs(uEklu=NcZBpbn3;2uk(&y|)w zCeeL>@1Kp;&dQqlrmJ`rRGpHl)4@g#x<5k}#k2R;q^7-|m@=ZKm@wdjH|2;U{oEZv z0##-ZUs8;)OM`uep^y$Cp1H`KzHo!#SiPojQIdm7eQ`If4&;x+OSd(0iUiymhn zL6|FtDB755lkDWpe8^tm*g4FV@ZFa-4rL`AmZMU^7rM|H8$%dYuA2jKQP{j9=F!tW z?$z-x&yQdI`0~xk;px%wt8q+3S}{|P!ylhw(Xa^1$7=8ktw79K-r+CR?dUk4ILuG@ zQB+NfPa$FG#i!wlm3fX5@_gsoMsgp9#o^2y=RE(AcqGAhfN%sk_s=}v2%e5T2ZBbXvPZ+gWL4$4@=0QaV-mcI*JCDY#T?Y!`NdwK_&)Ar#im zRb9F-flrCVIOuv(x^ilP+UM)(u!V`7*07?9<~1BBGRcwKDyY~72aiir&KiV}&V&9W z;zJui_Y>;1g<-IExIyJ)Fu&lnUg3p;e-F5G1`GYeadfSqeWvJDovyQ<3Tw9Z(Zu0jP zRcw>gSjgA2q{X*-xhCp$jX{Cf*Mh6>Evjr)kbYsQ(Q5|CO6lBgTABw>^rXA|Epd%4C?9&%U@OmdclHP-VIvl&6bF4wyV+>C-8h6nLJYeRlvfB+$? zD^wQ~QwpP>h74;QoJ=1l8;-j)xuw+1>grbm%91DegLeIHo?{qS4ZdOxf2;;r@)aDm zkcLM8PNIblXqq8utf;T9TAVc8%LXp{-?^RkayRbC2>{&PlcHN@-VY8x*|Kqcu_`bpK3ys5E8Gf7cm9F1fm;wC5=VS^A5da#v~9ky|g z@{p9#nLN7qxAb&lCoZ}OG>K<)`rU)JMUbKJeb(4p-`=Hhc zS5%e;IwJ=G$%yBe9+F}Du3TW9Zr__twG(f3D>z+_MY5<9iN~ECY}_pSa(zzSdUyQA z=?aNSUQUZuW-Rvl5E!?vlo$$c&{xD-=rA_@!M~-j8lc07KVP+xC7k;@Q77`@SfPx{ zIDIX5jzg}fJ`|+JP{)`?pHYeFytGSJ;eLpTr}Vn4^Qkm?3dt^wZQeDtR#5j@Q_NLW zle}b6u(v_8dC*84EoLb1MB)ZE4ZyxD5lB6$mb>5jOaOYb)dNS=m-5fHpcYF$Ey{&! zZOan3UvB41S;Tv7E$>@&d*sdQb}~bI*_a9C3p^4SEV5awn@Lr^xkx+ZHAAgUu5u`K zzUSJu%Rwe#^ITj5_iAY^$cK+f;+WiGdU5C*+cMpv=LxPitoQ6+{Gwf2GWcZF>8M3O zi?c{O3`cQYP!FojRZY3>s8oWKTj`SA-iIpwuwqQvY;?OFqPXw-@FWt*ZjapYXR?5s zZH(_*Z8T5aEeH)(&T`ZJ*2F}D6 zv=Qu)jamjS3cuLH7Mj#U0X&tK-MLhs3OSm14{hw8a zUF+rB;+Fq5X%=*TUk(wYd2G&ENgho%+WR>4N=f-^#96Zo*P z7Z*pzf!Iy8sEG4$a=1vWPq_K0gROwnOMI@YV|7046X|>}6iLb#3$DkmPN8r&s8suQ z^9}<^ZEsI~3qm%wfd)~D%Z&L>mAu=7mZ(jL%6T+gQIHI79tO3(w8VMcy?3kf{R?`o z9eg;9K@m2DaofiUwCx(QWd+`9-eWB9YeAte74`eGaR@uzk_@d8p)!HZvV!wujs`+F z5*Yq&c=JAFbdJw(71Xipy$sQ*Mem#HINN*FA?G;@RN9%>VW%YK?RkRS=YR67t_&_Vm_|(=rvNQQB<+(M|iG{!Za0pXG=?Sgp=yN_cpA}9AKY#==`bIe&Powp_IO+EGi530^` zX#-Xd@x*GhIbnU`pi7c7qT_d51d=v2gv>?cK|1hDkPir!i}R#!V2_;mhxQi6;V45; zL4B1*D(01qIos4@n)H{$d#n7%{a?OjFVVnR7oLsPYw|KZ4z9=3u)|L1S&~M|U52IXQzR_}NN1&$NJ~N-R+l>QVLCp$&bd6O&_{N5O# zoAZC}-hK2{JO1a;Apm9U-g#+=nG8@t7SmnB2Sr<)gNeG7_7OaCnj)pbsFY zvaYH`Ki&84smG^J#U+0_9IMmNX=1q4S>)x%m){1>QTerv-N>e^x;9u?S>9}QB#X^e z@_N|2TK)E$bm5f2#LMq~;Q&!UuD?Lo+rpso2%l=jB&j|`QV^k+;Te43oQN2 z@6+kH_lJI8Ao}9lZNZm3AfFR9|GDe`1XbVvkSx#}>HovKj~;dE|2(*N@8M_q{|Vzi zU63T@g>ORHEz+e}7vWJ1>p3)b3@uYFL+tzopa4mQt^SY9_%O zZ>YkWd*Z_gIcmPs{6%LU-1&uL7Q-b3AB1&Q`aU~!MdMGV)zXZDLU#Bd7|O!moxV6I zg`d{CwD2fscmp8DP9m*m&?RQwdKP>i%!fbqE&3#=l)kaIjjL*u>c;Ofb-7(5#VuH{ zxEp(EF|UJK`)%y-LIXXgLLMqTl=Eaib+IJwM!EJlbVjHErEJ}hR=VzV$ll{JMp74sFm+Y`;S(OE4V)#ebj&M0 zh~{nM2Gv)-<$QV5p2~wUJdCjBIE#H4q7&Rr3#JZ)o5Rbh&M1&ztuEo%T~C$P?)ba0 zgS~m7pI17JRoAW{C4DXFz!!mMS0dz)KaQkj$92+L?*i;!!&o* z7~&dm6IJ<~i-7obKuxM*oraafAo{biv^PtgF{r}>DR+QZfa^~Mq^YXTnJ#T0GdE*0Ak-cZ>v}C^ z$S5{S%_`_Y;mW3SbCqRnX8Ai;87K8Wagi+=1*_+QrU`|1iZ#}Apn&gcRU`~IC`FuS-faasn zgVxND=7$G#bu(eU1tEP8;q#fbxQ?+3g5ASJ2fpjFIo?^gFTX1u1M0ztdx6jjQf#Bt z21#*8X0+3n-w;ZYY%Kh(FT+UxknJ~dA$qw)(e}V@6DSxu2^ad-?Y|P zI)3cZeE;a>z87U=Ps3J6M4`(ch$CC7gC)utKz@s?(YHQn)hcK=4mFqF*ERv|1Hg8D zyES*u`oCqhw>suqZ;A`3{Lk6f4U{k5dYHQcjE)+nQ1%A7vP!JEN$KpqV-UCrb-nft zu%L@uUF4=_nS^x;s^z{ch?N zt|@kdB`7Dju>j>HDu_yol<_XpV)RK&p)|=K%x1p6jxy7Tf}Mj1d#QX(omeSZVGF#bM5< z-)~c?6qg8fY)P6lSQvv#a(1;=9O>B&Ey$vpJXjPTU`)AWE zDmS5v;ixT;20wLAG9}DSN7QE!n&PF2O3}EKx{v~VOzsh}Zj7DXgx%=XRAUo6!aEA{ z;=0+cAD)&cu2a$tC{gPf3dRU8GAKgt++Nd1@W~8iGP%}@u9`uWlXH`>Ce@572Zg+Z({mfbYeRu>cz?gWTQ zFx=ipOer)x_vjt@ma`F|k|>vMS!l6WtxD^w`XD~BIL3`OFzg=c>~%5ND=kVTNfK;+ z99j}(JSstR<6(&)NGBDN#9jmm1_)8buj_V5^L(!Jvb}@=Z(L+#9|HXZh8|M3OKc&{ zRn)Cycy2!Zk+LgrJX-KzV!1tq)*L=J8b1tCLOTG&DD~nS8w{8zcq?pqk=Iq}0(htu zG%kQ<2wVGd?IG(|t#U4gC>7nreH+GV2{t(gF!4Rj-F8Dw9u{xO28FC9tuBGOsHQrX zqDWG?UF!XFGu|?D9WKR`JEHNWYPn|Xm}NSScHRxw$Tzn($Zu^Bl44D8q2wBS16*X9 z*roE$2ebi87A{&h7#=8Y%$cD%(Iv;)NqE@O#8+ssEX>!k(-SO19!RrP`Y5{6uCEJK z=L&ehWB*US(oAQ@=%S@!SDVc5c+X>##Lag-n5=W(d+%AO^R+J8d+$FD*njokZ#(ZL z4{>3+2*%^6lI5kl_ej5~W35o!_MLz{aIg_d0aWG<^{V8or(zu&r`aSuBEibHPhZyN zA_oTt7hIq~Un#1(Smp)BPy1Hw7-J4YQa@jbb%>Ei>ZMbxh2WhiMQUvtk6N_D#|%*G z=qUvo2!=&q3vDOv!%)L#1~K|@jB)4srSby{_OyC%;}rqY38%pZI@xnb5)LH7kPW&7 zN$I9OsW2f8ZY-ZLQvjmM;{IuIVm1V0CCfR|87zpAH&hLloCqLc(jpJJA$%w=`6dss zEC!twiXxRT7AXd3gR*MWO&ckl_ydCm->XuTB|1EwW$a8Vj!LwARW}{TQ}v~CPD40&FVKPfc9N}?)0?o*+WVdPxu(eaF<*~l1H05g(g#PG{x?h=0bXd;nKF0A{vAG z7O0l5xD|l&V4%X~)L{NglwkRhRMwpX8s}8!g^WX9Wqc1rMo{VKBl48Pzh&Bkt-$gQ zV|bY%>l_IG++8j?(l%gb5EVlmDp4J@GrAYOz8IH=N!ZZb_x4MGne{ zm%5~qIG39swZce83%J2ZKvpGZhsO+=kIm6}=6n@Iv3J;B%UyRXZ$-fNur+AR^sp2A zCk3-(XnjZ_{Ov|4{2ssFKOGc=k@rGD`1*}t_+7rMe>ylg5vCsLjTWn z#w?HZY>leG_@%TB&v9HAX>FjZPdE`W6B`RzO1Z?xLb|$2m0q+GcAE5U-hNBIi1 z-HzqoKo&1HXPnvi54z{nP8}Z{#4|DR z?atIhikKWpCtc z#|!3TYMp_s*t=&1x)VLkG z9xnvSk7920H{kN7B@4#89!~Z~&vK_DX8$c2#lJzn`EmD}glqj%b#0B5DBVj3N z(mL|+zQOG7RwX&^R_Y@Qkr^a?X=yO>@r;)>!1|0b_(p*Tlac#L2PBsTxEu8R3m`xA zX~b?LunyREU#Ct4(+*x7-;q^ITAhalOhIYn$Qfy}1no_OBuR!zy(;M+EYeYtlwoYn z`iX_V<-DLRvi`23Jy&mf~31BLgOu9EJKq!#)dj~74!k)d(4?F$*`>SpSUQribo=a4dg!1wvm8uYDjT+&Io{ zsp9XUUweD%xHMAY!PBe&RithWpc&Z?4e1)qyh1yoLpvm`9BfR9Fxc7Lp;Z%Bg-|5~ zP7Orbb#Ga4GG3Tr!qM8Usx;L~4OReZ5KJImV8Z4Mlp2oFb_LvYk!wrk9VfLeq3M?9 zwrFtal{M1}EstlpZMcX8{vYlDw@!{N5sc7wYH1w^rKYNQQnFFPRwrw0Uuy%$?%?0` zg+7_q`I7QobO{rrx?F>G&o*H_k}>XJX^=OEOB+e}IlK5!1%!uCo1BZ#(TSpl*UxB{ zRD$|OhSPaRj(Y4!#I1PFmLCdEeLz-WUz0)xdkV#!+>%|=EgUO8#xWCI=ty0G^A{g@ zStdymt{!sTof<6U-(s}?n^if0Qws`^p}oMD;)=#i#M$*EY-uy>bb%(m!faCQ{Q1f+ z_j(7aTEd*y7;3;$3#J~_t1?ObaxrFN;D~Kd*FAuY^tN?(5Bl4}be(K$w+SAx)tASm zUAy;$Qor}bh$IJD<2|nm0HYz<5OuWyjzIy!4FIKr8XP3(AVFbK8cV-mODYOHYC;Qv zi$=-_`n^@nf;Pk-Ovtf8F` zrn<~fBm4-Ax%pT>m~`@)ILgUh$bfYERWW-2cMGh`ZwE?6UtJHe0XQ!J-}QaKU2ncs z*?xGvsmuiqL5DB(SRHcHZ&<4}c*-Bb0%M%ni0vPOIt(g7nm95G6d29R;)oLPN^L@{ z>j1D&ysN8{M9@aiMgqCi5G1*r{|d~(!Jqio(@hA?@3ypncrj2OuAlOZaP@D8QR}!Z z3OE@!WuPC~H%kK_htdGCK7!=%IUq6Nj33EC1J`OrA;3uRb{4gdX?1~pHsUNI3 zM=X(v_dMKx1bF)WBjL`2+z9%;J@uS}BTA?gDq#&$#7=2U>US05Ta_u3O~4e8_!p4Qw+IgM9(MU9dSJrQTHWGNS@n~ewk31e8=GJ5gu zNEjo7E;Uq7m!;THz7LE+p}&Q;G!UauD0vG_-`gW!d$oiFI#Xkjuo0K&M#m|p$b@~^ z$l3?DF6)>kBd52Y!r3G-VT3a+I8}>MgeAHWi-Gz8ZSFP>&KPvHQz=0|aBZll3r0e6 zX+p6>65K83Re7g{FUl+Laj>YBN)-}~seBc3%f&~?P{{%4loAr=UUlqAjwGYkhK?gJ zOUNO3jkIe<=pVu>siS`Je}k|uq^d`9?U}`iu=1SGCd*|X3~Gl~gfi}3M}BrL=d z*0X0$1Q|K?NcdcbBm(`udo}Nv6{+)wS^6&QXAlIZuxQcGRo; zMq2N1YZGtUIdtAOVM9=^2Hnjx1otKC7=fd!9@t6Ua$|IB{cy7iDLP`H6h>crr6zjZ z&lZK_5gN2U2?fRIhv-K3E?v z&#Bp*NbJ&V(O;o!sHZfQCObQ}lbOeUa~w;2y%CPZfp(!sx1T7FRf=z>H@l*UEVms} zj!et&019ht&{m*iwgn6_lC*kI}k6)O};9%Ypo?!LD zdDfts0w>T&0#=x}r6rp)!^mSATdH~`Ds^b%iZ9(N_Tj))KB`LQeToY4aW+F)sqde^ zR$OK?DEE$^bFhglH1{PPW~PQLfsC|d$T3J-No*>2Q~2^wIsgvA3woSd`Mtpky%_I7 zc;PdPJh(9Lh;tcVgBvWxdW0$L9|{7*=|{W;PzBeBT0W_ORv@8P5>y})E{H$rt;Lb5ja=H0Uakin+P^m?ckI;bilLzmLZncHMS zWI;rN!R&|ZlhQ>viybCe7!4D?3M+sjKU>xY#Erbcq9asxocf6Y7s#-w)=YE`Ac`Pc zv3ZIUy>J31>ER|vQauGrue><^K5_LwAS7g&n<-YElW1O`lQmUa!JwJ4p+uJyXeRZ} zEG~gmgM}0`-66nZQdF2eZ!2Gm1q=GXujv6QE|h9UZ(>M7S_j}O8nzU4m7 zLsJ<|-C$WGSCt6I+_B2eHRt$a7nQtWuOG*xxT1)K(HDjj=doa3Z+z=>+Wt4V;3z~2 zK+zl73cG#Q`^(SRI8uIkJ8lQ%N<9|pak3GOG5m|EA1oU_+f`|9xyMKz1Cf~?p$pW? znesSf-o`)~Dh8DB^^%uq1u(oKw3U(!)L)LfQIU}4J0@eRnUSo5&TEHC9a=8H0?TE@ zO1aJgv3N#|Felw@bp$O^C{VTJ1A}pbR?RYE4*ZH!9usvqu^^o|K^o3L4bq*?htv@e z_ne}@atC{f6xKlN8>w8WQmA2{a)Q0|e8HZH8guY#1BI_{iHJ2QbefO#SDm|30s5vs>il zx&5O!|84mH{YUrixB36Qhj$-+=Kr6F|Nj;0BM7%YC&mn@0P=pdgluL7NI|YT!d~&< zU>8iTk>Ud3rG`a`rUhi5)-lUnytG0`cT2NsYRKUsKVY4?7p)q6m!sOCr_B&G^3}p1 z(*j9CMu6d+bxxOF^VQyx$K42_Aqf?@U|I+dxl*2;>zX9{Hp@L~ZYIbLO z3UY?)^%hqPoa^P%loZgZ!`i|OOrJ3TU=6rUg`cHkF3=2Jjj-yNVPhnXBt$whWgfpR zjo6@<+sc|6OWl$lIU+UyR26%vF?6_I1r%H6QCFqQeG7-KfR1tl)AD>5R!W5smwJ*H zd9#kXEJ7JxUM;ax7#Wgx-FgKoQS&G+C}}dxzbUy?M^Ql!M=--yt7a(RqUcts%~$zo zRDq%hBQP7HZ(f?ZL4Cb86td2rv1(uHi~Ouz;Er1il;_7wQ*uEN8zIk~wU$9UsT!Q)VHie!tvbIYrFNEh9e91$tpm9aMO zK<3UjbIiY1wgHGx7!a&yu&P6w6(@~8Zh_6GWPVFETBvxlZlo3zVLZr=g#_EZwI^*GJ3zG_H zQkd+Q;~!3+AAkSym+xPmoE-k!%M;hbw>8p;;q{cwi-b^PwS#7D!l^OjSMbqG(g>bE zs!2#Z@aUE5`sE{~u3){F#>%H<^@O8)f z8l;E9H*|v}K^8+T!PlhG;i|DgUt=S*rtn_u5lZbDVg5~RoTz~+!kA_U9oy@RieRr=?v-nV|{Vc%Y>7k;zgQeM@?b^6JL z!M^@Kd6}7af1n6>v;6n);k^eP`_J949(5Qra|vS zX=)x7T*VMcm+7X<41_1$G*n=aie%|--Px$JReHovf6UEg%EtC)wRB7iD2s@RI6ga8 z-~#$it0?DzKp?{b7f9PyA~x)3u;7gR($J{${qxt5I}TGEiCF2 ze13X&cmUe(;q%i6oDil3zmpO_YYV=oHdb4Ml2X+LG0eia&QtZ^78VxB8Y8-r@iu zGE=V6E(RVUut6c{)2VLESyitY1Nhk33|APcgBX@?#H!Skg_&Z!$myys$)L(rv}}=2 zjSwSFR&`+jB1~L~yVrNi3es4yUsk9S_+Du~K4|2hVHREdr!R5a`TLDXLO~6gv2458`xZyNdYSND82i*oJXq zcfR(5!<313r@;WP!^ghd&}*I;*FVD^haWQc2e(V)zfT&o>~v3jRsD#OWWAjfX^PAh z7?KCC=M4Totk+_Ub+p58geUMnXjb{_1WB+TjyXu{#9b`R-|{jWaX;=*I15G){Hq!Ue#ig+@a|XlKkI-0&HCTry&sO$#eVX&62x%2;0rUYh#q)jHe16X51(5ava~Kg zSc9#)l~~%R)tvl!ZsvoyiDyeW13?-+sHCAKEkcD9Q(D8m;nD>iF~fHZkBAc_{oY&U zKkonXHSUdQIgzNt?hiO6{TON*GU{5 zfg`)r+>{I~YG^?vD;nAMy70sIMv;-&7F81ioT3iN!+6MO05LpbY@@a`yS}YZr#G2PX|m+P<7Lb+8Q_L4WNfTz zbx(&vpETn^t3pwKQKF%`x(@oVIPclCZx5YJgv~n*GEAOt9?EB8oVtcYfHCcMMN%$P zjx|x~D~wuCefS$)<_JSD^1Rny9qECOX)IqMw^dxz!Qv=uH=4udix84V?SHs8G2~4B^V;xbrNB)*SeYa#x<6>&atBPMjcSzK>gczeg=hK9$@e# z_A$|=y);rB*LOAKj!@8Y53V(*L%6U&D#cZmOIrrb<8TFvrc0iAy)GlLVymtWxTb z>GIzsFT zNda^f6`HxME7zg1t}Zu3<^&e8R!?`@z%z+*X%{X&6d?fCpLrVG@zW;iMQ-7$W9dxk z66)f=Yt!VQw>RRFyqO}CA+EzUr2`g;T1PJ=f?Zez_2ISHfeS*3vfN^$+ckw2`u?~h zDNE`u%(>~*;?1*O`rAjGgBs518o+|wQYmV%!5qD+<`BK2D$k&iPJUsq;-ilS0Nl)mBWl(Q zJx>K75^990@Z45#?Sc}5{%3iaaTYw5(H9oNRc1*}`%>bxxQ8ZHZk6^+%B3UrSLL-o z!<%opYXmuVL2PT;u3gd^t6Kf-@;A4usz6ed7QvIZZ6ulcd<9+cZ>=eKF|0w?p3r{E$VI<*F#0$ib>5$wW|nb~?vW?jSUe ziLoQO%CRb~2_u#`s*%F}p0(ME{SM`KI+GxOgnA*pUxIJ%7ydC;F@NY*vgiJ9EY2p} z4lYlI3)L@e=w$D_^i8zgm z)+inc=+cWBSk^!}l7?6-#jyqe+-a#a9PQmq=jbvA5zHS(cxCY)x4Xf#%C_7@+j=2- z^bIlrn|}gH0ObRNrYuSe47(9SJ$pQ2ZkD+!(Rh;*GZFa61cf`cl$m+z1&SMaJq;f) zd{Dq3+Zu+zT)BAJ9GI1PQRN^IN~KyhhO|+SxIE~UDFrS*g7wELx+tX~%O8%RvIp*f z^8*la_;23*PN%u4Y@md+9J1bJHw$?qkZ;6xHIC#?#9>z^z;&PIVI@6=Xdg4Z%s#ML_+ahVn~jGcizq{Bc~L-Pm6Q~mF_t0 zoBG^E@ zJh)}Zkzo_kWl4r3YO;#@dQgDB#hYn-XY|E8#0`cM^^zs8cmxuUF)yQ~V)p@yCRpe! zj^-8^I9r3S025~CZFXdlr)QiGyl-Q3sjm?t-hIQ zuzNWe`Ar>YiC*3fMjx|vGw#IIufd3!|D#oyj^go# zADo!xF|&q)TWJ6vBGUJWkkEGJRwCr)4lH1sv19eUUh>LEh&oSOZCaRkL%E&iu^*RT zLoywt#z)8W6D+rtOy3XdTOZo{)ncki7mLt-NpHgIcqJmB=}+!Qa2wt_ZsutpHuDP+ zN;{&!e_Nu7tnmb-)D=5q)uJp-y`a23{-MyeX!Qb zBjJ@RU7`!BuCmp%aq}lWT8ipW!_9TQ&ajC&vz2g-uJPL_Xy}IY5@jb+EsXeY0*989 ziHKZ}yfTaP#=5QuVBCfpL~Rn8FdqXFV%cBPqfJsU#53PMuFt3239cQm^>N&X2g7k! zCZVL(LYip>MYng3qU;gr+Aa1?uJ|}~Ug;p9;R(8l0cT@E{&Wz$9x~4Glkf)f2L;sF zD^P2BLUlzBwt{g0C?2Pwok0t!xpU1EDF+5M0;LG5Y$v=H^u1KMR#QjjxRw|wa2B)8 zNsKcTXTVA5P}K<2Z_)UOnYXTRD=ijnPn7ecOkqhy!CJT12U||qD2mu4()2kcd;|`F2$Uwjl&~&X;n_mpvGewxA4mL(VjAyYwMJQ;ZVHW=D^hm^+&JVf(AqR zy?xs5yuESB?Sfq<0@WQ0vrSE1$_lUjxo(Bd|Nw~^mjDV~ zRS-o}n9sf^o*9{y1yZuCp4nsn(M=Vq@);Q!&tD8)4ak`$_7m2V`h%b&`lhQBdvJ6} z2E+eDi1bAcMi$jf6Q!W9ax1W&bQ zT&EQCAM4@dmyK;HzimiNLMU7vq0^@r^5rksH3@0N-iSak#C1#XGPgCyMh?54fp zn;zES17RUm&B~PD@W-1uz=U>mLP$*6lssYMAe;_yXf6PT2CU^Pw5x{_#iE?%bCI~c zd65JiN{=4}YnWmUKxem8Ue`Kytsz@_x2>H-9gN*?jyf2*iTffLgmXQhJ`?4|BT}0e zjtxz)6yN0SKfPOb(8@Dpen4Rc|9tPI@}V_dE9EsVFqxZ3kltrE_{XMq2eLEr30-*~ zKIFJ};OSk1*GQDCj)GK@yT*oJAZICHCvIpoFyFp8M#W+K7eM-K4x$&>gm&oqEv2LV z8pvzGNP~qu&l_IIqfyxJ;bAb41JeeTm7~T7VS9X?Qj_+Z7jk z8VRizgJ6#2_TJKZIE6?xv3qk6is@J#xaQ}dyNGGpZ~0QOkE{uizx0p%iyO0&0h!c7cHv9{ zyRvyMD-%rGT6#k+K)O7?0qbrRmiUY?PaQ|$z8ceg7&YxelW(^$r6avfsFMF^D)Cb< zBDDs>+}uxe(0bt(mZ-c7dl}pgM-#XmO@)nU;O4KY;P0(9%?Mz6=lML zGRb-}7Uw4xPue|jwMNXbKx7w*K7ve&NkBN0T0%e|28XuPr0$k%I!&Uh^x$2ve zgrQo$AVb65qcr7uxr2JoKBZ8f7dGC$$#;V5*4#@Z(zRbft_Hv1AMvju5bP*t4`&X} z@gFcxY>Szv6>i+JOK^yAznBhj9QLy7vPyy}dY|1CAl!pcPa4={ z5DVBdbRLnZPYs-}MzdlLaRI^rtO3L+3CIkFyn;rQ8iZy6>_tj(!v^dR?ySoER3?z` zE;zd($as+XO5id)zyM}0_|~a@wTAf6-G3i#>$4mC^`<@EnoI=mKjM_~^-G=msA*qb z2mgn>CW|{LU`&;2r3=Vh+iD+g!>+>az_(XfsC=OAs)vr_}Z45Q> zg)mcmVFWCd{t6gt$nskDkI>uwA>5bx{Ovs0a^X$-d`7%16Z7QIrEEuSS9sc|z>Np7 z_mOu9e7uKU=GOR*qql>az1oMw`rB{NI~*CoLVGKHD>(z^o-zJ04$+1PEgThavQGPO z%L>;Hl)h~(Z@Ze3PINe=+CgHD?Q1vD2w%F%b~eeyp&^To97IzLB2FV*o&##P+{tAbb>B%6g3(s|&VJ`6ZMjsGNZY99v#ejEPN{rzuK_)lMceg6;qr%#Cg z6akt-iRU|l3g3$F^wF?Ve>((f2jHp4z#>54;@7+rC0O4@9(__Q5T-*xtL%g4gw{RX zie?pnU>&0+pFg)V*oud%O?Y@-=z3j&ww?sxl`l|D!KBKkd6NzOKToLIj>q{6VUNwT zTQQ7vbYMKqs;SmLDe4o3F78A#20SPzrf85pH0>6E92>;YP%w0;dDN@La9@hozTwb> zAR!ge&U2|C)$q1~li?JGTNmfcY+n2F$f5&5`}5+wpsGg)7BJl)s4I;AwFSal0iA-U z8M9|QD-lRQ#yHF?b*rq>($xSk58i>vi#%IQ81?EOl3FK@5&`WG;L@R3*0n->sBb(4 z)B%laKFRNtK8;e+du30bw9=y(A4Vc9wgBaD>B43VQ63D3cAn33`^mzw`D?qP#%jx5z|l& za?fZQw@kdIP|~95!l98DpIt4bP<4cgz+HriLPgDCBh&t1oFY%D9dwn|T(5RI4p;@j zNHis8!8H&MJ^{g#U7EUa$WdTU$T~b495mSX?~Tn=cov#HMT0`%e=ZLW9+aZKh=-&k zSGq}oh#QFk(Me7Yi>d3qhIP_H#Id1Q;rI%T(~<~eb+{Exck(4f75E{24>(Wm(Cr^E zqSy->HHO=~<7=3l(3fOCJMfRteXF?xsIs;`A!n$`77OwXKu*VQ|4~+#FB$;wJ#@XG zpZqZhME`*fARIyPeUBb-1rz>Px#Xe_`fnDA^xq=r@dK{A;$J79 z8&|U9iv~mfz@oRz^C{BJCFZQ30%(>EwMm~olHTzC4^CVFJQ!wxvFJFCM9DONz$^*R zS1VVSi<~c9uF!~BFYQDKiPxd}&q$YazfozEQK|%4z9^b!9#R5qLaTYU9GhtlcU+sD zz(ZE|kKtBY15zYBC?LR5R00rb6BF4bS)rA z3C4%qZ07pxZFcG2cLv6kf&#V zh*{JQ2&N$9HbNLRvZKOT((4QWb6S>{Q0W`KI?XQ%2s{Zu@vxdXMpv)$YLP9mxG`t= zFH0;e2_x~)TYhlN_v@hm1k_v&3cASOt_UkY@U-kyC==YwhOjjLythLzsKAkM6={C+ z+!#qvwjLYxC?Phvzd^MiC=ulSi$#SCLX!9aRkflws90+V_tz7EAd7>#BUWycX)4Tf z82(7zjNLJa|1a<#^v0^9us+X)u9p1T_k_?l52r+*!KA(?P!$i!(7mLm`59=zF@_;L z24&^6F2NGUQw&lzpYd-howh_K3`qd&SBtL~(ZtjQj>!l?c%l2AM+w!N=Cy~HxX7j& zZVS^{sqCyt>R}v&7};sghbUc)gk(6@#6Ajxi|{AR3PCdRp)6=n4g4cP%*=e?%mdkz^k@NnO!N=v*@@Ryun`{*OZo3ma zWJe>a=NmMJzqrHj$ZaCrfF@r7u74_>Ue1e0(YlbcI*#}kF%tz5qPq4Os^Zg9P5^-$ zW0lZY(W38<##W|U)N(0Wp$d7GRT;>rn>ZFnG1!B7hbjh)U7tnQu}Fhq3OP~jvi!xs zmV{y4W^F@w=$8B&r^LHM1S#d0c0arM;)_UFg_@u{2{xn`qdPP==0WP!GtZ|eE-d0+ z;b*k7$k8K4EpJTo6$HP45S{343h+AU;IjdWZ_LEgrz9FTKtNRL!f{8$8_*)7E?=RQ$ z`2ZAE{s0fC4LIX3cbt0|4vuIvG42}lhw(O5!oID=a9I-a!O|VO?8(QNW$STZrPWxn6QajbRvv;fX#-&`TKI ziWf??&dp635orYIz&NQ~W8GR}AisItpiSl)gWgf0@1$C;+m%`;C}>|S&q;k7TZ4M{ zwqkTdz+_`3HT*XCn81vGm}kl1h@jH-J2Tqw=akUaB0^H8ymx~6X}639WRo`VbbJFQ z)iIhpy#yyFd@iVm&kim(VcU89xpY+jyWqCXma3}S>zbFHC}gJ2wa z5Lk}$SG)2nX6p&2b-N}epaqz&14wCcePQH+jM$xr2VB>C*loy|*)j={7zANML^V}DE8c3VA?pWxVvzYA z*!J*h@X_b=EV@lX0ZU(7=5HJ8rt9yUAoh-4+X3wD*&97!WA&M1V~i){+Zqj}aNN|{ zBk9Cwi(7Ji0?yKv<5sQb2m{LajWDFCN7%(q`t3}A9H?dC@80n#Hf%o(njqPksEPGG zOv1%0s&9-p{0byfFUw{ZX4M<0I+Rxm2kzR|+?H67PMd^WSis2jKdUt!ss5P|v{jjf?)^!qMD2K53P zOJqYZ%Sa=P?LC%vTZV|^l(4)smJ+|-%?T4VLApzM90%@DO37nbQPx2+<(n571LHTP zlsAba^LP#8Y5R?fG@U_WT8TBfrnYdI5H*-6 zB2)v=vsADkmc%wyFt)Sr7Y`izoFhFO6##U%XF8GZW%WQF^ZlM%PzQ}3&)yFQMN*7JeW^L?jIL9qfkSzLLJ*&C@RRe z9x*)8qP%{aaGh~*gcL?&$&a>;m0{ljrGjT5Ay(Bj?ByggW+JYc2s)$ageYoyHJp4E zl(*0N_)@UbTuL=QIyxjFyPHBezMTz)!miE(cZ6Dmt@l9`6rvVj*Y+TBgCMt?K!t%F zDy?cCLnfPbJ$5}=zuu5WJ*06B)!HfMjrF`y7q5!^rb~&F_^|%Mra$Q0;1C2$lt|4^ z9^G4x-BEZTL}5a??m}8QM83=Hh^}DLNDxV2ca2I z$COAexdlXRa-u|{+!~O~$>P=f>_%5XQjyh}gqLu+C?JF_&Q9(fvIV=X^nq zgKQmg4)=lri$SV(E>ZkGigOxJ3-715{g6$)uVV%dEP#7{Mmh0EOIPL;Fl+qvA}>%;&F~Q0TzHE9|!g(s|`K~%fRV;=5LF-sfEF}*2qYJ zR(5AWV?xD4CFm4nx`Il;*|`kDN)@31iawn@d(+;zQlod^2N?)XSyA{{Q5c3jh@^-r z1JPHl_FTkRX33Z#a+L<>&H-P@0&Vcj`3PNyO;e!4r+_?AfM;hJ+aR^@= zy88!hH-dGWro9Pz4IKJ~xpACkT2uCO=w~yH8}8J+_bF{o@AARV@eLS#>>1U$rK%vGbk{LL6ID{lFX6vcpe!(W0A20&htiE0)4yOO(pC+_&8~ zBQRzF)*!#z#@-~IR218di2Qby{OH`UVx~vN>S^ZV$h8@73n|Jl%6nUk6TkE2?iWEk zqw)PdrllO+?XoxTZoA|+q>m-tV+eGi!9bw_<~ZcKbZhymF|ba`9foxwr07=Ob#o|c zd3>+&odfm=bBT!XZ!Z&yC9lP??7?=~kvWzw{M|Pf>xYlB)Aor* z{`vw5+aE9U#uiIi%l*u;MDEaZ(KpctYEAAg5^?NnKv4M6in(e!;QYXt-6bM-RUpc4AjOp4% z{Kj*#C6Y`^H;x3OeNqE@E4H9mPV=`C4BKTt=W}y!3qdDb9`EzL9IznLFeM_g>z~oC z55o^$;%r_S|G&JKzV46@*#&V3zU1+Q=u;SH-`?RqM3sYL=$|i^ z*{Z%Mn-DEnB5{o|CIA!WHDrY4RS04r+=n)pl2uB zBBbt#EV4P|%)=!V&xQ9!JL}fK11ylLm zHYh`XZL#(VKHLBxt`~U)W}z0+V^uWt9BmdBd~i7{&ev7q$B>lM;jMT(x-Z=Q_9fhw zFS>JM0x)4-h*_2AzvlgLb+Q^H3{MQ(Q)=RVhLMj+mUSoC<@QuU@vt2&DL!=dJ|Em& zT9mx}TLr}svbXzk_b2bJSG3j4A*b*W3oc=c9EBm{RWSwPVmTWfacf2xl#GBTDd~hw z8MTSP5NLaw<*GG217V1a;vf#x9CC|gJ`sw9Y&LYtO=WvuRF|TzgtacP*#*Kt`>mwZ5eg8)TS`Dgg#_BmxM^<>274U3K=x=+ zte(996(c?>s0qqqv~<8w4`gHvOBb6vs9oOJ&HaSR*LHo%CL~7Y&EbctaQ_u_G(>0U z`=x0F94rwGDgPZoX1aYaMj*DiOr=)nG3;&V63q`(J4|berd+XQX@HfWpyPz9g}7zb z^*Z#0Jn6e3)d^zk27*tb#C=P@`rlHRh=o5cJ`uWgJUr!fz$BVZV$`2{21M zyQ(U{&6(A15^$r5TQBDn+|Sccg}JO^ue4a_XGK*vZ8xSN35}DYK;j|WC3&plHb@=n z?gq~8We*mu_bM_Uqhy(~YDwe=1O&ML5-JzEtU9l?`f+f3@9kkElNOEUs@pg(43PyL zUo`|FC*<_rB?x2+)ex4~NI9b@;)kgTlHiachHjBJ*_eRdihK&temE1U0PT+8%%SAu zd6u?v6nSW|OhVpd?dJhvGgn1~1)-9NB#reTiWeWEGSnN~+39$!enpn@$5^(Tp;_j0 zMjgr^24jw01d2^y@N3=u0%5br3b<;Y)~4K=%^?&TeOkL+*AIYc+IeC@c$7952BBMQ z=QO9L(8~}v+79%=q1#Usx7#WL_O`c1}6kDR<_NQE)%zxl(g+VwD^`OyS6reFL%a!A3uVd>F&l-1;&&j<8 z?(u92#&GHpy=)lHkFIbEXG3z4$TBUK3O6JY55tUl5Xx*`mz?{G4p2z1hr59qrvYTO zSl|P@JM{u;>rm^n@nC4~oZ_4b3@3az#}j7tQe=;T#AKzDmZE-_19|wN2NK%5h1T7} z!;XUzxalo9x2W0vcnc|a1+%=51EDKTVN1qA%%-B$HULX2>Y5|2Sp*w%h=i{cU#*v6 ztfvH!OgJNAGTNFFaeE#G8wYlb&QFsGeHc4NKiavw6@l_7cG6}8F%$5`f*B2J-j;`< zF7H*d@xOK)!+${r-E-Iu;6^ps2#~`f{vK^&EkAtfjAdiBNCb6Y^ys0rP?Y5*oNxZf zA0>M84gqFrO-QAgS!Y5L&^xwPxHz^XAJTT!81S=NX2N1v33_(9rl3tZ9WZ9 zw8!d?-frq;bFPfdN8A0LHd$+uy))@XhDun9|3cPWUcg--;@@b}jY;qKG4-0C0))Pu zyR7IP?vu{d>|D##O6sk%bC)$r+)U8|1lLp?vGZv!tP|rd83y5}$mv0%of#nTPkL?f zrgy^7{lLBe9%$N;T8J_(`O z#N(q8_J|*VtDWB*1Xx2pxP2@yjJjgo$z8&o>@u(JdB?My%y8BQkGa2PJ**rnBl!O|R#LH)i(gEmqIyj#WG&P`x0uw4qj zWe1qow;?1nX^awQIA1x&zA-rp3N3wy@V@}%>n1X=m(^6(|Asv>rp~}n1Fd?}Os}2Q z*)`qGHuXTe*y*OXSx~g9i`;H@K7`c#6x)<`Cpwb`1~w?fzbia+rIN{XvJ*=W+sSvIK5#~8V;|I7In3Zwq|o$Q%EAWZ5 zndjeSGzJBM^E$~0+F*ccV_-rc7389vg9#VF?7($MhEu?=!W19$ZDU9v0@4|aTTn|1mJHMQFl?EYgRQzncD^j@rZ_W&qDYS{XL1Uu zJHx)fyo?SfUIGgE0c>Yl6)ah^Ua~`(8J!S%!12m*tlBP?+G4g@w{5qoq>R>L~{~hQ% zYA+!~MB3Bly<*}zm__#-TIzW?qn0ula+aO<)w&amwqp^tL>nQ!$#+OnBjf=?<2^+8 zGN0*W?a_3oX`9SP6#@W{qz?&!R_c2X! zzX$IjbhpJOBXMs#dNl6%;Kfn}S3LTtM#s|Er&Rkw2(JE88VR1i3K}tx0g+Vpn{A7? zpQ<|nCY$w39fWWLwpor6VX(h%|DB?Zd~+)(Zo)PZqMkxoNw`N#~XVZ>n>LYIMMEnL*lG0SVbDAo9^_U0?KVg38@D93PJu zr~8wd+^}%b8R-?D)(;f08O71OxwWj(LHI@#;c1E)Zo)wQ8sIh$Im$1rRQw>$_)Fvf26xqI<}s^7mL4U-lJm&MzO=y^%^4Ga zFCj5RHlQ20MWE-Qn7o58hu+j3na{+o*U?$%TyA9|c{VHE$0>H` z2=G0ro{<+*op0?`@gYAN!JkR7^1D*^dpLrjIsk2|YwC=LaC%tn2VS-dk zQ+)B0-oAmxKqr#o_5l2=af=cZdaR-3ONY-m@gq?> z^#V&zwqnx9IA!>lG4R%qvlHl`I-s%#tom?G;{em2&ch{M~C zUD9EQ<#3^)5f??=2C~{&lFx@jB0Mm>XU`0_Z;uOh8+DY9E_Y*iIZ6&w9>Ps~@@}hy zJS6x(kK{+$KhqE^jbR4xC&)tSasn7_9~0@RtvKGtcj5JDi}ufzN5j+zRU?5Ic0Dol zS`c}0`hwT+alVH%uB@( zH@;H(Fo7f2M*O~)MnDXj!wh&S(XKNMnz{+gJ{95!g#GfaZL?s0$wpuRwMjL7!o~oq z?HWdKC%6`@Nb6I(Ai=jjsitF(+}4It5C$>)nlG$UEr|D1Ks+JDL1aA_MS^7mv$3h3 zEB+$F*$*=xgPerOQmi|`dXftnZ^}8Cs^?)M!wtXffK3!NW}$)usxRit16%i_Y3G8# zm$7Z~w!w9kT=-xPBW6>WgC5^neTO3)PJgv3~4+&Z?%!=Aw-KT%27#khdQb#BYzxEvRsr$Ta-7u`c(>!wP}{=NHOuMF-k!V2R;!!o0eBtHx-KmEs7cfLJ;x{uZ_Bx=SxU6yeOvA zdMOIe@YkOThjjY)5yFAW|sdE}?^8 z^Qr{+wxGcLih;RIQ9&NwV6+4Gc>b0!F_ukU&9bwcDwPwkf@*1gkB$Ud^1%L1t7v}P zAWcw}i7O@FGoE}4mGSU-8JMbBW?}&QF(?L^Z7JBbtDk2 zalhPYev!Q?pza5psYRaE7=8kh(DLlsrz%ru2}u~zPFxh*9YzRZFbzBUul8T>?_>Rt9XV=K4CUq_-1rv8sF3YNhLa+ED*`4Y5&p?OB$hw6G6EdF5 z8Oe2K0^9>C5r8-0zI=WE>%YAI`rp5L{q5I(;h`K095_mmzT^a8WT`>S7Z}NJ0ti(j|i}DJO9?V9pjBw~M zmz>uIP82K4S<`lI*DaGRvF$D^=e);R6GS%C_h_cp)-6Dv@>8CRlb`cGKz@P zXdTpoYk%etNC40w?h7a6EMLJ2q7-Ae@CCqXfGSTH9yCP2J7`FuSE^!pNl{UdRZct; z&6j{_17bWBZWo|#hAoif@_-@C*2^!!WdB9LCo_-(3W+C`cs7Y;gJKj{c06QHlP7F7F82S`(D+QjRSoUcjLP}>@ zp2kV|UIP9Rs?qvJOWUQaZyau{E`U48q9`$JH*OyZEh&&C7&pb4UgxB+N!`YJfz{RB zRk5r`X|NbOVc42ovo%BNW*2)1G#~%@1Js{{0K9&LDq2=8{Hvk{4SjQHeS?>@kLy}~Z=oKAh*Dj%Ev_a0Iv=7(C3%Zp+YeP*4qDK&>afbj` z#sG3z&iLMhr)#D2^s+LJxndHbo zl|*g*kRsiA@g`qd+-D;h0r}wX9kdn+A*7TWnxk)#=4if1bG}6YGleI|Rh3i) zdK|nT(UJD2@F-wdhamrT*<9zlwHK8ovUG1%htizEBa@JVjo{ zRRTy469XlqQ48!AkyHs$2}ZwAwoZr94oWh0$d0G!y*`ENjR$Dk_2l2NoI8j(`e5 z>2;D?!G1uw8R(x)iBlYx!UvdUeIzF}JhHs4=Dhdl|9e9|B)XXHX9fyY1!^tW57tW2 zwovF22diRUP^&|d6QL%^qH&qW zLvxn3F=hw0A^%7l@kuB|!hibXzyA{dS^Mv*Dx31GoY#BVm+NBh&Hn4Z?k)1V&d&4S zWDMSF|K0!c%WuDl?Z4lAbN~Jy_TNwOU$H=*1X2nzlJ8L@eL)QQDQ!NS+DAFWfwZ6h zvVsff`*N`=mylD}`sq>DWKYX!KG$D1WNPgF52UiI{Pgu%S>;G>y#u}52!Ndpig3jc zD(3N*zdUho_D6qpOquR1gYc%uXafUlUBt*tyqeGuAcf!O#VLH6 z&#$4fC%V~p5rjCKB7AFx{gBWMRp!;wLMX0if+IU6gOcU$4Om~xiqTxJSCm#wm~kna z&GDD(f*0xU^yvc%At4?4%Q@rac%!D_rLgm zCB*w!SMU1zK{1eAZ&B`^ESIN(y!NB>HoO^VU?(K2KE;40FDeyO0RbMcGq8E|`C#*#|EG#GW9hVD;81&bXmK zw|^sFEzh8aPf z&6$^ZzN)>^6RD4{^vuhf6HLRI3`XuJzQ6INS4pJ=kJJ_2#QqBYUSasAp+nZ=&;@7I zib0%DQoHH8l6bpY9QZ%+dcx@ur#%^I!g^UHT5IGKz|unDZ8x!1!6)t0vC1p1Y#^(W zV{uz_u@Ra{(EvclC5g^b2p!Q)yql9*K~ab0?n5yK&%zTBhJNtX2X~x%XXB+AN26Gx zD6~r{miE$|=+dGU$S zVl{N362Hl$f`Hc!f+{P(e`+?^igyMW0Vaw}(cMik-DuIRa)^wFGnmctkpzwHP!^7& zYvRJzE~|2Xm5qZX)5~sBak`Kx|5XXF?FI7$uG`5NB$=WIGv{t|fajF)$y=rhbT=;u zYi7MaFEAvujl2_Ju6Lr`;7n0c*>eM#+%>8s;^{$GTU)pkM8FF8k_8kssJ^b3P0Ll& zqYDmeZp^qyi?0b_WSoXmIogtp54y#AEO*V3gntQ;5ByET(U2OCKLv2_>qY|6ph_u= zeCiX$(79rPA}wn{9izl+7>AkI^cHYfCxc{wq4(ipzoD}hTGKlN4(Ah;G&YFkZj`d? zR-Iium6~IXhu)lJUm%LlEbtbo9S8zC8(8?){B2P;^(X-KM~Y(Hujq5SGy|R?fYZo_ zn2{n6VT2S@#720?3P2J$C`9(V#Zn|wUwKJ<<`M|g+m2etCWbH;2Z)9rVP^gNA5A0{_V;R!}@m;Sd0h$JZ~sam^6(cL5W4vG>kF> zdkh{L;?5zfxB(p<^k)Fx$Qz7h6+MmnlJWz!F^Ln91s)vS06vBPCG6^8~^U#F6gOAgX%UvM^yim$g`alR}o0`Pu^sZy{R{I7u9 zX@OPxEiSuCPh)g(dK#j7(X%*3o1QAl*}+bm7J|I4&}@Q5;;gC&B=KyO{S&fu`Lyqz zL+zgoojU7f@y~URp;8>!wgPKSonz^s12@en{Tx?xS(5jKof_JyCVRylAD_Z`z~iIq zJLKdOY|L9uSsDr(wkcvqty$rXXq#@8`D?@zBxme&U0=6Gzpk&Jbamv1LVY|($?^zA z%lf((ypqb%3tq_Q*{aT`9XSScX&nV(m89zNpTTt&O9hb2mma%G?mLPE=S^@`$#sD4 zV6=!@_D11&Skta)GJe4qPW72Kq&<`R!+0D+C_9i?L$r`Ox_I0Y3^eow{duSG#K5z18*q|^~d5ee*ljj9{k~W`~P?R4<~Dk zrXMf&^Y-|k`(N#U75o3b{QBE3|M35P!u(Io(>b4)ryx*5NDdgD=`Vu6y!weyX zF0UM)gWC5^X{qEWgwSFe;5h(wgV`;{QfoYXEkNct&|-NuU&FvaZV>;;(ddHqYuhMi>ge@4yMA@`aUL z@*(0;(1)Ln&+p+I(B?R4Rof$zTBJsPHgdci^;RQNx{YU7`^>HJ|p(c(<0-P3{fgOl7 z6~qmq+{-mqwZO85VrcNrq_r^Iq5=0a^q{39_$4u9V5ZQzxd8VDlV#?$E%6T@u{B3?tGqJ?k@uYRVEQnUaH1w`cN>duOMgL31LP4+0N`rewBZ zGM5-iptl57)DwR^$v5sR&?Itsc+tQDDWek(`tYFZZJmIgH?jmi?C-e5ievImYwn$` z_k9bT0SE|2rU~v$^BXx;Q9f&BE9wuDuy}{W#GWpUYcNvY=Og;AykXQ7R_~=#VWSkM zm}rN7ls;F^Jr-OPd+f+uGh5eiV%uSWaJP&gN&yHJBW%R%ts!P*dD)TJ1+>@?X&fV% z@q|R{O|Q{v)2ob+omy5tN`5)zbNX`B+mg{3okpqRV;AbVUdGEQ-G*~u{wqX3lcgKE z3EEXB9K7!R>kyb}09xvN4t8w?{77R}*u$=5J*0a96U`ac967ds@bDH(uV*!DfK(IM z0=VqPx8HyW^aWbWR#p@m$+o@vP?z|J;w@k0$m+bGz&onMxdebCt9e!|-QF- znaCM}jD&v@A`FJKb?_#$z&p-$a2e8C9_I@ER`owq2D)ehKc& z-Ye#7x4$2s9PBwbIKZapDdN9xJ4lfvy2R;bZV5qsi&euE#RtkB*EOG2S>G+4Ozf;& z@3R|hbJNq_q>a&J+qtz{KL|Zr)@!-Qrie@!db@fx!#s}#xv-(wE#kIhfNpucj`5Rr ztV1j#q$C6;r>@wf+l7IS4;R^-!byALQ^sr|I!x=OfO%1DZ{+e*AXoPb2XxgJ8Q7oL z=oBv*;~8||2hi&DL#T?uSXS+(6K}%YrXIP1u2QXqkesc8v+%yiEG6~+lDr*3ypZfj z{5-bjXfnRmKBiu%Brlh5p#7He#ym5AFAxlLj{Iu;&OM&-jxT#0PrZGak6X=bL@q$E z=y<$LWA5|MqoMMZci6gY<1s{+F;a zqKk9|Vk+VQO3Z0SAs#X7pi`o(simoYN)3ofg!1FwNlcP23tb%kY zh5wQEIn=184$6vCY-`ugxre z%RnPaokPdzw2XsfQgumAl9(8vI>MV|Xb}lbg?V!t&BC3Pb%Ug|pzzjA3^O1QGvZD* zpO;sHFGpJoZ8%9X=UgZzn;wU$aR4$QIB_`1vCsZe(la!5jI@fP z{u$;*LN7evS;3#{X7=wt=F9WuLi^+V;1|WOxjuW&oJBxVy!qKPm4wy0oo+mACqetR z1Pg^202cklo0@4tI_fA_Di{-5ce2cPYY!2Kzo3`~O*4F~PD!=3eaU?n#p&6mEKL6a^3$d{Xo=wLC*UzErXTiD*-D&XeL9}WQ9fIWW z%4H+`!+qgS=`Wx!UdwERf8cNUmjMt}MJ%`x6ql9G#}Fe^fkrSA6q0ood6Oa0kjq&x z7m`{Bp9vxK2Pdk$+e3-^ICofkEQP1pO1Hos*9RvL(a=E*Y}`6V(Q&LEjTxrD@BBbVelw^?8n;%hYmM6ZX3WU#Q=s+Kb4D00@;dcvICx_W-P?07 z@P=7sESK;l#CHRxU!LZ*M?sBMV@hl({f8{33h% z6CMyb9{%}vcuZi7k)>jSi#Xw{lxrzuUThe;)BL&=r`fy&M8IY47=_W?XKaD@K>}dE zTQ<*T{RDdCoryaJmt-O)<|-@m5}SWz@WXTo@y*Xa_e%v2n4#>t`?^y2n0U!X7wDIh zA9nxU&GDim3l3RQ{g4=f4UtR@%r44^*Gz_;_1xI?{<9bGHIC*A77m0vT)Nt?Jj#n) zJ&nTeB>+{tFFG}0r!saJ!Ryy(DtP@G3|Xlc3}{Z*E7$^XMJjO^RRoRDWo6vNbiFJR zc!uO98^w#92WE&4yv9vn6DNp{gX$ExCctQ9SPuyv@J*91hgxyYD{Nztm;7P&G;Mk#LChG%%3=r^-O?lB#v;o8xq}!jeX6OeHECn$<(6*U* z35I>qAszs5gD?nTKUTim_T%`(y+a7l&~1Oa|^5MjS?_b1pu%?dfsf>a!8sZTl* zybg^LMgoPq>)Hu{7R}&5VBl8m$NYTj3j}X!vv{1YQHPRi- z0(sE75>*mu5?=ZREDGPjmoZ<7#Uen|CSHH&_G3YaS7SR1;kUN35f)Dmy)>_9VMi)g zDmFF28S4wfmRj+JyAN36_jjbq<^AYD@l~c*mtpEKk%76u@SFjuP(_ECD*BjZBe)J^ ze(|W>4LdQl6x1j}!yo{wz|RLNY_R^JuaCkfS}$lpO$>JBtj`IwHPLg0P#_Rt0{cPZ z%~u#s1hh1tU1itf*wVq*7xGXpddUpHWWt7=xG)O7SZuVg2-ir-YKSDEdX;ra_dYdG z=7NhH%^)a3N$M8{F;R2AwxxHW3zes77f@Nk#+6vEfKwuG0m%@Jc34v+Vytq!1JenC z&jQrDmnfCh0RP|!B50m{SC{$q&{_bCrATKIY~;21fsgfKz1Qr7J7#DFVO%szS_>ix zvcY7?ZTZ3wK2GIz-{jRUo7;$21>z5F58TtRq=D$`#T%1VLvqgWePv~)g0vjPx1~EY z!Z=?VMpDKydHiY`q#f8OtT?p9FUn&9eE~1^v!5OxkPEGdwIyP_kGat1WeJAa z^~x1XD^@F_2NDg61k?&OPgc(%S%B!`Vq3A&9Tu1X93LE|KKH;8hs5I9T!PBgppEoR zkB@K?F z@liN;Ew)N~8qP$QU;ye+`=*L($7PMJsBouSOKUU&FEFMrY9)Ky-ycG=U%2~j*KY|= zcM#ggcqlMycL-lSXno<1{G*py^D5pSD9ov~N_C_CI>a+3k>=3oXFT2Dw8-l6+qYLZ z@EvgCtvh5ZYu_l@R(LjRD4!e=OCS4171g!9SpFNoJW7~dYjoo)cYK%6A%V^uCOwIK zi;g|34TMam3r1BlB&KZisn(fSty2!e8set-s|!i=eZ;e2(2S6-ed=qK-)Y<8eZl_~ zuA5D#C-Ml#V7L<0eKTv6zSkxIBR8cRo!R;{9q!}T`` ze$?7KzE{fmmhE!(`Y7kqs3dMknVuXEJ=?~<6MUPWAMxsrQ>(j)>$H%RMa#TnMmN@B z(qjn`<5KM-&ka)4t}S5C^d>$2#Ohh#N9eu+H`Pw&#v!2ruX6B+zh;o=5u0> z(45gT;aV!;W4x5YBJ`GDV;7MbBOKsHV8OiOhdEae{L(f?yl4RMK)r3DRiX$_kv<0l zXZjcK_(}gRt{)qwXKd((&58+E>JcudL%MUX5et_L1WXr3>+R(tzZ`fIFw{82DsyNwM$-)DB$K%nR&d0nm_u`j zgs4O|kibgI#<3{1Nr8W8>lSdmm28bBydd=Yp)I%0=QG5RL@!ykHHL(OR5+NF6WJD} z4RIp0Ao68H9`KtysFJ$`$sK_s-Ks2>O-NfDp7Re$#S#bbgumV%twlz5!TJTuaYgXZ zBWw{DLd_{Q`Um6^tVl-Wo(|iRP^)sOp=+r38{0XB|G<6{GazHstf<)3krSu~&#Fgm zeQ(Aw-2%uG{(7L%{bV4AdYWYF(<4E->d+EeyRl$0;t@AqV3NV(C}`4k-cSi$%zTq| zN%$t(aYcen87x$c(8l(uoNdCieh`*LL~HEh zRX(Tm&;~#Rt`6K}m1ma|dq%}R#juF>AdcK)f|LQ4dYV%`Ka3D75OJNW07{$~yoCiy zgkZ#y#ltpIAUuVUm`73?Qv!h^`|yx#>W6G57NNLRP1N@l={o#_#^pfks`_vzN!3R_ zl%O5_P&6U=&}u^JKRs5cQ!xKC0qZky9TXfMNm;#}{sOwXc+sM{sj*7MUU)B@jSE+x zW`R;M+gq=^#_a0J-)Y>G_A5(lNyuCVrCrwAnqSsLVDK_X)a4@lt8K>6zDo{ zfOkPM&M&98+YFs}XW4c0zu!qaYsuhD}ln9@i}loD3=>rPVbv>oVf8WjiOJ%|j;M5F=M400Mm{~_4Z4ek3MK-FSJChj=M9;&44dsmy zX;ktr39L19s8R9K84l^GzQcP#9J95~-mpMl`S1dw8GNdlI%mv~;xx z-e+|g+^rc@^OU@95vpyTzbXHnV{lyR0NhPY{*Y5(Y5$HSt&41T+UU&uDhcy;`=Tv= zsdNfeYm>(fLPKA^8hBCQ#&$&JW%%#apv{xK`Q?gqIsnC(-jyHCFw-x&6@}$XvC-!D z;YxDS)M*{9(-Ho=u)D;cXuJGx{{r6}A=~d7hTJ9TLvqxLXEwv3U7>k^vfHt$H7;ap zK|dC4`vG~SWfYh1%*G_liMUsj3;x#A+Sf42k(#dAH;4viwZMPvzM!v0Vf>s7Sbk+Q{a_Fcvu%xR zTTtS>z2($6$v7PBA`5)3dMY88hEHW{%?H*E%RC59OJZ|W;54pSBP}Gp2<4y~GxJ!6 zXphUkDTnyhS2v-D0RZ0*yx%jfKzbAYJ4y0;dy*+D7A)Bpa$u5~Rn3(hi~lj!UbNHp z+TURX{{?H^sy%ztdX!voE6*+)sx&C0Fl^f_oC#VtNCot93ZH=fqu))snfdKrkfGSe zSG}`xVBSpe9$|SmF5vYD_MXklbJ$MLbw(q@^xcM|$Ltupl>y%)-pSg27%9OEQcOd{ zp(xbY2sdxBkOJsjAa$jvv9Kf~3UE?hFlI0u&vY1V)mS#n%ZC=L0b`Bihp~?BD9W#L zE|pj1be+dOutOd}42LGbs8`d8`*&<+IJlLTgdi>|R zcaQ)RiWHHN%71}Bgzstw(qTG-D87-?2{oiJQjKQstm3+4h6K3fL3?>rwUdaOL*v)< zQe+D)CYlW!o5V=7g-uh?2N>Z~5h{V4g{@k~y0@qGBAb#gIdOK4edsO4??L%#PW$JA zl8`w+3W!){om?2N8KB5@OK7nKWKg8Ke)Re0;{AsJ0)9G7<#r6bEMh`O;@}z1$_Uov zM1!ORuD@ZE8@u7pkT9B2_qq2oBa{{TxIMjSL6mAVX!FCCNJnDgFLbTid}0$V)J?l_ z8JS_dM{&57ovP1E;{lrw$2Q76{ZV?d8%xbJv^0nGVm!R!pOVEV#s1pnlrG*!x}=d} zjO|+-mIE51^h3qb`=q>esQmm4yfnWJXefpMOpv`FuLQtW{GTts-T$gx|NH)5{_+R@ z&nLuxzM*nU0JUBj#0yUHwa^(iP~GY*tEOBQZ|I8pgey7@84<)3N%3uI*+<2KexBFm zx&jZ{6(mz#6e~O^VG(hNTBzhj3>^_T)@2ez7oFn((p)ZbXbJJ7p=6e$qGBgnV7L@S zUP`ITYD$;~6wsW*8ag3)p@#^S_aK1=T?I2_Z*i5^t8!Tv0JAwmh+)(y321teXG@GX zp;=70^FIDMn7E7zD0|o)oOoSueV?40!K_HGbxk2R#WY{6N@V$*bz1J0E3CARk@fT) zS`Ton=rzQUfqK2ls~YO>m^!TB=3ZebZV!-aKBh$dT9yi*vJIulvuX-|_~P%uRzhax zMOigxfP`bK@OY%0nsb+-=_?2W-lc98ID5?I50E<;FdOr{%4MFy!+uVS%s`+DbI zyyqA%gYTiEzgN2n0Kh)2CxT}Mh_MhAeJ50CA0ze@D3tcKYg-|R3^!;3`?ze1Ss|q= zkiJiI*-#G}t=otJN6}8QGX$EnM}ii&Xvn7x0b0rw(Zl zK)BQAK1M{~L|k93sh+3@2xCXPbf&|X6&6b$?%e?u=&nm%sbFUM1;uCPnuYGC%b;_P zL+famdh6(9M()W>n?tl&0?aO!^$IG2LHTax_eucr8pa(`2Y^xw){*QS^ORxJ{QXNe z6no@&DA=zyTAK>ardh1zb4H+VSid|Ux``~O4A*6DqTslb;Vu0RCFvJBpuiDdU5&!p z*xW5e%`h!w5>yqOP@@={#cMZm|Dfs;9%z~Rh$>IYCR3qGQ$N_=W|Mq5)yr9UvA=75 zCbq1_gXg?A4;g9|#x!<)%U6&A%6nu%8I4Bf_>ZlOMopuFGoAU1Ii;8Pdj3B_j z2_lb{S#Z#3nmHb8Wl^g3aT8?N13U6HR~yr_IpJ`p&nYUrRZ-jl4jT_=k~O}!$&k9B zkE3$-*rl0-)*q*B1RjDl9FVyc&GisBSF6zu5=ryK2hEDwX<`mkg56tDiedePu#n*l zV?O>QUL5Mc)sr_^mQ|$#$4tvthIkAO(ed;1Ew7e*)df^&bpP-^ zAB^qwXzNUP5{V1KNYw6D(mAFwhS}1JKSKgML1`U}91<@)wn9l(L0L{)r#=+U@h}H> zM0?q+#6^6D8B%)r4k86a>eq&>g!rakN?aP4^>JISsO2m%FDD|pvLXf8Ga-(@oRRc9ngke2pb3mnn>cj6 z)I=x%uZ7ai(gy{GmhKWWC{7_gB2}f8$vw?~@#y>wLcwn@c8lzo7^bOmZ@4XMD@Bb* zGY@Jgn-IdhF6VDNcCUxc)mU#TJ}eTi)!?xMQkMDyTkI8E&*$^#9&Z?p7_ns5jk5HR zECItk|K~b~Lrg_sK^m$XysT9RgQe?3ONi->L&fl3ymx!HlwDe_V4kg_iI*`mFA{Za z)ZZX^CZ#^4GQL`8*8BA~J3FXXJq8cp3pV%nz~}7eLgf!!&&aU!Z^$nI`;CqYThZgD zW8}OW-$%d_aNu=hoMELaNHW6;-wVuMKy_a*+d3G47=Z}LepSKkkeeF8l;+CAGWcvt z+X~^qc7mSK)2|?)X@)sQ!lf{Q3zDz0%bbZsI>pz2;7Zfr?j$3zIR!)#*)kGKysS~> zXF1$Nh6pfLZKRmVfu4}+uOqmkz^Huj6Wb-zIZ@gRA~o6D;uwW6O}&g~c19ma(=xE0`U z84uKWH`wN$1ygW7%2BiVH?}`>SbnemjC2sl3?Cpj+#);RHJFwkpmkng?6J@P?>E6N z&SuBTeb4g+8c)dD%2o}%oXG@*nNL8@%VvJj;Bv zNd_;<`l%UJ4?(7coq+Tpd8~}L>D9aJGXF8F8z6h+sBtP7JAuFf%gOn)T+HBXdOpAK z5TNAv@7+T{0|_1D9MTdrLy!TltRoj+I~tLb7(+hr-e?DW;EN-1ChNUnPL_-n5bVzK zKEo5-k6mEckd6Juk7MrY9c3v87ZQlDp5LaR1pMg+IS~Zb;HZ4Otrp{=y-rp5*;?o< zkUx>zsSrv+Fi?$@{gGaL`JX6|e{at{f&02#0TvttvH+__-5htFV*SJ>4Ch8X1ryhl z=a}`PGA`Rk@j88zSJD9)djrF^N;#}$lDQYWC(DtIcdi&pMZUwBq*!S2@CqUC_jHVO z!EGEj&z5JoFmCE$NY{o)j)Q~NHl*b5zF+-8gcBgAhQ$elO=u!glCD`CVkv85Sh^eo z1S6$ruz--$T)q*zH~xc#w6TlrLGNJ`dLO$GbM98Ul17V}Ru1AT2xl!rrWp@uknyc# zxVs$Q3|juz=(Hv#U8(?4m%s6N<9ejdxHQk_T-}o02c1Kjr9FE}ZlUsM5P?WV$M?`> zU{H}k^gVBRrUL0{eqJnVZzHEKDMB@2nqq?ncqy+g3h?+&%B$tX`bedZ(7u9&U|R;3 z(N0Wd9l~2cQEE!H#AMI)aJyyI;QN>(;c3NQg#Nm0__zE5UQ0LyrFWjqPXcpyILMR zr0eFJP}|}ICGl`_LjOeSn!v%I;C&@I!f=~~h;ZJM<--JVn0?be0pcVb+uUYEEC+T> z>SSTq4sx()r3A5WeI@?w1M}_{!n>99z14 zC(1bh_yZY5c4^$Lk;G|svIt{2VjB%R5m6B%t0Lx8Fi)a%KLV{UW?{ zWj?3eK;#J!?m^DW&?>(I&N5XX9qtD&G=wR(-D>whUV$K1{RAlG`z6bW}TLXH9{D-kC#AH zP*f3@C7Sc`RrCrFe}qDN|GjLE1?cH;Ml3^j3j{=Kw>VPA#`flfiW3f_dnY6pgo9-3Iv zKCP#mhyZnw+X*{xruiU9+sr?M#qJLd?mFL1pc_HtBG{+NWu)?dE0g(yMu{shqPT>9 zkhe(t`u)$2No%~rnl0)x5 z1`js0Z)?gR-Y5n8KOu=Gf180$V>?Wb2!?&U0?YdGY9%q7Lk=^qb2kBn_XRH0Nm=P(k1dTq=>-D^uq|yl}d>+uK z{<+TP#f<%67I1P^EJ2XqwWqkuQ3ywB)-S6s1^bo)F96VVjM88^r;vFHo(Adbe9h@r zem1Dr@+7JHEG5v6+~hUJ2AW9M@K-&vkcK3}U^Y_-hP5FMM>=EldTljM4Ie4DB>$`$rr^ z#pL$1K8ivb#kLa8l}ANpN!+?2)wj7S-}kC=$5X9*>A4`MlQA}{6=qpt!TY=Q<835Zzu%G6?SFx9hk`;?uFo$b z$+H#nB){}(<{s-M?adSySEAUd%`>=6I1MIDq4amEGDcfLw0#C7!k0P-P6TCN(R%d= zfW9iG`H;IMDGN4WR-CV^OgJuT$xv(}U(fYK4i}K2c#KASkme;bn$|^}X z3$kU(%EZvodEmA82NcFlmr77Snw;y^d3}c?o4$9zQIjZ#ItNUMfiC%mFoDBf4iIL z_C5;1a}k9qf@V=nwkcRy ziMJ~1KMrAt3qAXpWp%v#VWDxn|7*=Z^E@vSp;-}GW>r;Q;gv^H6Qz$b${qzrEb~#i zOaXpzLZ?4TKUKcS3P4H^{R^xxO+%{UQtUT&+vUx$Zkk|~NxVt$R*%{-MY!)#y`)i5 zlQ7kn_Xnm>w>0qp9Bdy>04gDwEcF?Qa6G?r4Ao$V>92WJcI~+iDMUs(va9M$c|G%Z zs2_)A=wo5jNVoDqLX>)cns}NwS&|^qJAW%rZG{#SzF=y7(%>n8le5IteyKsXzmU zNUbG^kMN@# z_b5Lrr}+aLeg?<8+Hyd86(6o42ET`jeEnoKF zVeb`WERqVxQExC*L|=6X4&&-`SaNor%dXaPU2HGQCW1cZV*&MAcZMzi#-zLR)99C zGg5s3+D?N*xCkAm?bGr=;l#5L#L1{lR49 z9^v2FJOtE&YrZBHYfGK6rlojz9vrrlEDOt zP=E^PT>0}e=`cDAL!{|;)l^ffD;-oC#A=13};6$ywfhicc=NR)MAyS#EH#~?Z(Pi4m^;m$Jx*3SAa-Vug}iF zYB6$;$dD<-3fb)oz($9PtNDCdYo;llhRJiV*b-6*qr%Xo=UnPEywIvZ zP&pdApNVTe2qhS@nUQ9v64LX>Km79I_(#0wdM8+61s8hz@|rF3)k*E01dBmFI9~&; zVr-KPl`YX4K-Qo!{qocE$H$M3zx(lV=cw*dx70_N^O(=FCA`7%kU%yn*Jo$ksORrw zvMFl)SxcQ>$IahnXAS!Mp#mn-Oy=rkwyH0vl$IY7)i4EQjB8}flo>o3h9MrNJ3vna zqZL;ql2*|$zOI{cp~Ha_g+sc=D@hBe*AV$|o;M9x#4+RIEhOYgwRAia`P-(-DA+=w z&<7;Eu!VV{)^*%(XdTZiM3d-GSe#U9fG<#Q8#tmA2>)+Bf^%pFGW0lOgy3V4Ek8vIboB8ADrW)Cpp<`EtF2oZ^|+NIc~J zmzA%MM;-$#k_(p{m{X}x9xyZnwVwKTs2W0b^gac*A}$I#4QcmIbM{<>n!;odcmZu$ zPzHQveA1;YoC}R(i9ZrB)Z(>(Mv81+{F$6h|KMfCn-cpq6qq}sIu+Y9BJl3?1k~XNozuy(=t-~8?s+A zzljaC$<9MB3)}-3d^2`^7Rr;=d^Cogjg({Z8^_s>V8~^xjDD3}byp}OLmIDK9Qw>a zA5*^m4(U&5aA=Z`7TMdUT9B8~5~3oei|j3$44=U1+w#(*dwK?9gz?J z9uyzlgtdiaQls+HCT2-KLRh>a7COR06GZtzo}0D~u{?;vigs2|0#GT+r@i2P08MY- zo6#%d)^(q(SP^dFrd>Hf_7TR%IH9)|8WHq+Ru=&#laPlgNKVjr4+6eUW>#=qV`>+K zHu$pSJBb=DY@DV+r954j!ycA{H^11=UpCqKtL<&jE7FjJ&8LZ>O#+_fB?O*ZwPKoqPF9>D=TNggEnrs@qQ#0UINW>i2?&y`k&B8M*~&GNZ6+ z*kUk9SNoBs;^$Fots+5DgQi@FZBHL3oAXsiw6&lcu%J39Ih zvd|bS3PfyObk>MlG05d(VnbDlFUg%@RNgWL?P6HV$EjX%PMsr6rEVAQ_=R%mmK6*;&05$mJfk9rFE{QmHQV3+=@y2vpM*NqEJpH(~uYB9dAU}TV_N0Eq z#^YoD(VDhpH*t%O=W|HZTc{YR3PCK&zkC(h`MfA=^XP6X!xB|s!9m2}RyW2;5GK?0 z5pa4CW$jtXL3{{aLQ@yQ`wEs0J5yz|oH1R{fE7VXCV$mk(hz^AO0i)G07_<@g6n#f&1*%h!qU+;d>-A|< zWoJ#z%Bt2PBDn|cYg`eLnm5JXQD4ia1_PCP1>GLvMcHQi0H|EI7Y%Wb2ONN-aMXRT#1J%BeUZ4pW#FUYBRic2KLjG*e z0F$3cZKu}DWnL5N2$+y)^|;2PSZ#e3x^hWQ!HjBpN&G5UP=Ge7S}eAEd-TzeHhEq& z%^Y`y&Hp}S0qqpj+Esxuqjlqv_~>6?uo+194Yh6zzIgsQoH=6z6|D17mE~f@*Qu;X zQM2Z*mY~>{NA33~#&R(k9Nc1s6pjBh4|mfHv+*}3RglZiikiVtAoiM~ZXu^kMpDbw z4jwS9CLne$77F|YMrC=Rh?n(u_q#mgB07yiTe6BKc%Z`?#-QA=HD+Jy*X|RikP6&5 zg8mw#FRhE6Opn2{0C|kAD6oHF5AF;4fdBR2kf%2i&0gY&@RL)npi7_7zk*Lt+4sY2 z$|jq?&p3lsc<5L$;P=wKPkreM0+j`w`*lef$%HMwoDnTrU zfTgWQp;c)i-GLILE~;XA=~)Of+!-j<#^$adU*slPfGrCTpn?g=G)BnU`&LYd?^)4d z2Dg-1C%%0c#X4wDQ2{s@1by-O=SZ!6r1K#)V^Ii^wH^|wgfB&Re>5r!D~NbChjCm+ z--|*h0!t0K`f0X`hHEQ!Yt>gB|1DDaC05l zx?Wl6*U@S+(liM^T7CjNM%lc$1hlxax~wI^L@&BgNo*6rdcfp(8Uqf9{ zHiM`gj+(i>ohZCUtPv75lfDTeL%T7;*;>Q#<*ALfUxl4G|E9&?ooClj z+3p$YZKVkeg$0q;k1BXX@zn0Ul;?l1GHHfJXL9BDW z+NFdDA6^U*0xu+%YTaCvm85eXfBDN3_hx_e*KwT6SCdUx-5kA|v~7VP(E!vPEC_c^ zx&8w7$N`_6-imPkXjCR!O;xbD*+P-107OU$BlnM@!q^6KVv0n=QM6#!$SX4CToXPG zMpXRU&)g!%F-Z=o*bvAj{%>3*1)8T=NN8s{g@De1grk1Pp+pdjwXT5Cj46ekJo6WPvl%^lL)qKrZ5wNHQ7z!}?4Vs>fl zzy2!+BKn}|M6f!Do{;YAFejZh#njupf}O)%Aoq?$Gux6#7}cVQVpQ0um{RsQ5gue` z2b(gKJbn|ex}4@!4u!2&2zKqgcF&(ZJ9+)&5rA?+E4>4L{`bevUp#sC6Fi3#BBA=v zmUd~)D5TFT#27ED1;mrBaw_6_z~RR<%K#*#V2F@(T8$1d z`RhxjglqZrl|e*Q2k5n%koRJuLKg!HF_oa{9djOp1CwoPMF2|M_U=a{ z{0ArC-HIZdTjACRiTLO6S2^MgL*z;->#ihK>Y34;Shq5=t=;@<(1ny&XBHWOmZJ|NW;z&* z?Lkck?=xMzSmkFAUdU`H+TqvH|1PJLTlxV1ex6;u0HnBwACJZ(aRFTa|GS*JuM{@{ z-4PVcu4y=-C>EauS^%0$Sj(;~8*yrGzaMCP&*3hW3xa^>b{}f|0B>+XF_!g^ptI18 z#L@{5%yf2&j9incS&@qZ+8)0}x8j4#{JNaEUq{6f%1Y3D9u9ew56NTkFg@Brm=~-V z-Af#!ZLz?4n00%c(9E6T-8ObV%SfIZ#sZxLv1hgT`0$_=l`Ez`C4Y+EzOz=MVE|% zc;snL$yHCFgF37sIwXhqn9d%0&j<1wpE;^#h5mFLA|ZE-7TK!b#|I|p0slRMkx419 zhi-qz2Xam%+kEudjd}O~l*O{&8}$a8v6CN|w{9joKFCu)PrSyVy)-y#@WAy3Q32@Y zLSQh+B`U$)pvO#BSykuL35W7C@aF_UaVB9!H8NP`06-b8HMaUaY7pSa!fylYZR#U> z1cALuI(=UKcYK2lz|rM5C53yy`S?ZMX9OSWWv~tT0H=KD!u9t*pO(!9#wCM)GsHH) zJ^5OzKB7BedrR zqo>L6{B)(!Z=fr1ndACFaM_Ez>A#dJ=DcC>GmQY)6ODf`OufXD3Ez5!BQs|0%N)VI z;ES*zB`1O%I^SCtM#Ia?{Q8yk#*yRW(3vsZ;af2JE)^h^xtMl7QG%Q>ELm>wPZ1Cf zIGc}_Ak-@F(&YI>5HK><5d9-8@yDn{q~t>!qB*hD?2wunItYV=^D%@KePuj|^7XwW z%n1J)VYiqg=#e46htP%EO^|I*LN5!+MgkaERC2|_Hc$;$4EjK9R=wh=N*#za&^&C= zs#XaRsj-~7WnMQvOmV2$M^nx2gHG2=miaKf2_<%{#Zp#_8tQ&yq8Bn#keE0Qi172g zdrC6qE-*V5_^JNJDZzAIqa;sgnBD=vMkv7oZ$9hiD0WnigAx zxM2#X2Dc~#skt$lCkcVkZI2*UH&(rj6lb@wk-5yvcr+tW=6{A~eY({>vNG7uV*!^EGp8e#0E>RnD7=qQ5D?!F3{q6Y=-@9-Bx_{s0^%;O<4~)fZMPHtj zSh@k;*PLplD3rw}d!OCV0b#8aTy?$w>q^0d7-Ku zrXL{R$w`oZw)4A9tq>pzd|%{2;LZCnED=Kz5xq!)!Dlzx@@4=6AB{GK(#vl=?M2jO8 z%kJU^|M%tGuel>B4xypjg8kAumS#pXqdRx*oO@0Z+Y$nF7$ayAf_#*Ui~g=!rvByJ z%1m5(QKMnTfiOc77bK>E<>B;GNYin_iYytcw9`ZByfVU};BB22Mah^JMJFdT#6YW} zwa`O}$PqY7HmwMOBc$4=H z5#xf}hq&Q=u7Uns-d+vF4mjT-j*4}Ruupz?2(vW_ae{=S*pS0TJ^W^e**~#+CW*h_ z{yXd4VMR}(YWCcL7Nj-~6K+!K0_*->MpS-Wuc}+9Z^6n4iC}NmEps>+(WyGJG^-^` zNQ&mrc?x8CPQ}73My;`ReihM6lKe{bk-N7?21u_{ihY2{_>#h z*txtv9*83`!@DCrd$Gl(YZbUF2c=OhBvf%8d;8pmhM>}sYwZ!H1(_U1*umC_htB4v z)0o{TU`r@>A0EPdQel!$!qi=KhRNz~K9NW5=Rg>qq_^Xt2VMAK(`v)GY1y+E?2)!y zYwShOm+HcSoi)wp(cY;Fx95{h(%b1=j=OrBHrCxkm>MsHGsW-TjpxzxS4ErN<*jJZ zRnMESe%Zi7Ya#s5yn?WUL~BUv77@8a9$*hp$ zg>gj>$k*WR${z>^*z*~ph>%=pF(GGDjH}=gE$I*JGjPO760KDNJ<@Z2hEdMWLjK6f{7NxVz+H5}D==QMM&vxY1ecl=7vejmx;ik5Ho{&zh< zxjHLP59-|dvsZsN?QPg`81DjB%qfWvKFn~!n+LIl8X^Ej?4I2qMgXZm3j1rdH zU>#lnAs8KbyB)OFq9=Ys5W&GzH%|TSqByVo-0V$DKR{YBJ@{fa>!z#y?9jU(R{t%? zn!bzz++O_OtJfE&ef_tK1OMxH(|`L-M7&!@sKF0}hOUS!3v7+KZ&+L?7lkYm9%15s zJpvVFqk0ROA9freZU$0i$QH=9T2s1RzTC3e6wB=!!uge7%6h%YmyYqTYK5D-U;?l_ z67oS6D%K*{I|Rn`j!=x3A?a<>o%(5S-8Px`A%S3jS~!ik*aItx;~N?Ge>AdvJB|r# zCj&=6Q=|KMAU;K}9WW!2&`z#fa33}qCnKEysL= zo39eA*k3vFfN~o(=q;$mv%T3etuSo_LE#_TNGV`PaM2*;{v!g|PYZj8e5ofyy+drD zc6w3D$F~W1|1W~Od+`5+|9%MGsoMd2aftzr5z&-0TpJ0p_snp(hVbRk$S z7}P96EqsiNR6~^Cd>WsnuYXN1FVgXQ(RmWXO{oWTB*H<*V@*Lg1_6Q|34{<{Ylj-N zIKqIUhN6ULQ}8)1(OyVD7}<=_YO4lr_BG>+nFrwHWF$QeiCIY9TA~7-PY}nqz;h@h znXk52CQ1A8!=FjernQWRNLZ0ncA=i5UDzTKojUP+Jk2bHBcynIZHft0tC+?ahtZ*% za-y}kQYl{)j0)t}is!>Q(Q496aNOY0C1;GY)Z=X<>p_@N2ebLN2JLNdgCv)ZP*$aTi< aZ1U!?^F4eHpTp-HKK}uY$UUC`fCB&p2?I(1 literal 0 HcmV?d00001 diff --git a/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz b/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz new file mode 100644 index 0000000000000000000000000000000000000000..66bcad02a1ff3d3c28e452e190fcf581608d288f GIT binary patch literal 53607 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 U{`>Ubztw;LA9Fh{!2kdQ0N@l_IRF3v literal 0 HcmV?d00001 diff --git a/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz b/apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz new file mode 100644 index 0000000000000000000000000000000000000000..038cb5a1d5f45f041249b8863a8f56a20dfe7249 GIT binary patch literal 28918 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 O_x}L&KDQeHGywqgA2odd literal 0 HcmV?d00001 diff --git a/apps/mcp/package.json b/apps/mcp/package.json index e5752e5e..b1e9726a 100644 --- a/apps/mcp/package.json +++ b/apps/mcp/package.json @@ -28,17 +28,17 @@ "lint": "eslint ." }, "dependencies": { - "@hono/node-server": "1.19.17", + "@hono/node-server": "2.1.5", "@modelcontextprotocol/hono": "2.0.2", - "@modelcontextprotocol/server": "2.3.1", - "@saga-a2ui/react-mcp-stack": "0.7.6", - "hono": "4.13.13", + "@modelcontextprotocol/server": "2.4.0", + "@saga-a2ui/react-mcp-stack": "0.0.0-candidate.g8b4d987dd233", + "hono": "4.13.16", "react": "19.3.1", "react-dom": "19.3.1", "zod": "4.6.7" }, "devDependencies": { - "@modelcontextprotocol/client": "2.3.1", + "@modelcontextprotocol/client": "2.4.0", "@modelcontextprotocol/ext-apps": "2.0.3", "@playwright/test": "1.64.0", "@types/node": "22.20.5", diff --git a/apps/mcp/scripts/check-release.mjs b/apps/mcp/scripts/check-release.mjs index f7d4be2e..8af0b630 100644 --- a/apps/mcp/scripts/check-release.mjs +++ b/apps/mcp/scripts/check-release.mjs @@ -52,11 +52,12 @@ const RELEASE_CONTENT = { const EXACT = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/; const CANDIDATE = /^0\.0\.0-candidate\.g[0-9a-f]{12}$/; /** - * A managed local SAGA tarball as the lockfile records it: `file:candidates/saga-/saga-a2ui--.tgz`, + * A managed local SAGA tarball as the lockfile records it: `file:candidates/saga-/saga-a2ui--.tgz` + * (`file:apps/mcp/candidates/...` in this monorepo, whose lockfile and overrides are at the repository root), * the directory and file naming one version. That is a snapshot candidate (0.0.0-candidate.g...) or the SDK's unpublished * local release artifacts (a real version such as 0.7.6-rc.1). Neither is a registry release. */ -const LOCAL_FILE = /^file:candidates\/saga-([^/]+)\/saga-a2ui-(?:core|components|mcp|react|lit|lit-mcp-stack|react-mcp-stack)-\1\.tgz$/; +const LOCAL_FILE = /^file:(?:apps\/mcp\/)?candidates\/saga-([^/]+)\/saga-a2ui-(?:core|components|mcp|react|lit|lit-mcp-stack|react-mcp-stack)-\1\.tgz$/; const localVersion = ref => LOCAL_FILE.exec(ref)?.[1]; const defaultRoot = fileURLToPath(new URL('../', import.meta.url)); const isPrerelease = version => version.includes('-'); diff --git a/apps/mcp/scripts/sdk-identity.mjs b/apps/mcp/scripts/sdk-identity.mjs index 41ed40ca..00477dd2 100644 --- a/apps/mcp/scripts/sdk-identity.mjs +++ b/apps/mcp/scripts/sdk-identity.mjs @@ -1,13 +1,26 @@ // Prints the SDK identity the build stamps into the card document (`data-sdk-*` on the body), as JSON. -// The application installs one exact public SAGA release from the npm registry, so the identity is that pinned stack -// version; the registry integrity of every SAGA package is recorded in the lockfile and is not repeated here. -import {readFileSync} from 'node:fs'; +// A public release is identified by its pinned stack version; the registry integrity of every SAGA package is recorded +// in the lockfile and is not repeated here. A private candidate (`0.0.0-candidate.g`, installed from +// candidates/ until the release is on the registry) is identified by its source commit and the bytes of its tarballs. +import {createHash} from 'node:crypto'; +import {readFileSync, readdirSync} from 'node:fs'; import {fileURLToPath} from 'node:url'; +const STACK = '@saga-a2ui/react-mcp-stack'; +const CANDIDATE = /^0\.0\.0-candidate\.g([0-9a-f]{12})$/; const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')); +const sha256 = bytes => createHash('sha256').update(bytes).digest('hex'); export function sdkIdentity() { - return {kind: 'registry', version: manifest.dependencies['@saga-a2ui/react-mcp-stack'], source: 'none', stackSha256: 'none', setSha256: 'none'}; + const version = manifest.dependencies[STACK]; + const candidate = CANDIDATE.exec(version); + if (!candidate) return {kind: 'registry', version, source: 'none', stackSha256: 'none', setSha256: 'none'}; + const directory = new URL(`../candidates/saga-${version}/`, import.meta.url); + const tarballs = readdirSync(directory).filter(name => name.endsWith('.tgz')).sort(); + const digests = tarballs.map(name => `${name} ${sha256(readFileSync(new URL(name, directory)))}\n`); + const stack = `saga-a2ui-react-mcp-stack-${version}.tgz`; + if (!tarballs.includes(stack)) throw new Error(`candidates/saga-${version}/ has no ${stack}.`); + return {kind: 'candidate', version, source: candidate[1], stackSha256: sha256(readFileSync(new URL(stack, directory))), setSha256: sha256(digests.join(''))}; } if (process.argv[1] === fileURLToPath(import.meta.url)) console.log(JSON.stringify(sdkIdentity())); diff --git a/apps/mcp/src/server/view-artifact.ts b/apps/mcp/src/server/view-artifact.ts index 74221e24..a4329b2d 100644 --- a/apps/mcp/src/server/view-artifact.ts +++ b/apps/mcp/src/server/view-artifact.ts @@ -1,8 +1,14 @@ import {operationViewFromHtml, type OperationView} from '@saga-a2ui/react-mcp-stack/server'; import {stampHtmlRevision} from './operation-log.js'; -/** The file name the view's content identity keeps: `ui://views/answer-card..html`. */ +/** The file name in the view's address, `ui://views/answer-card.v.html`. */ export const VIEW_FILENAME = 'answer-card.html'; +/** + * The card's compatibility line. The address names it, not the card's bytes, so every compatible release keeps one address + * and a host holding an earlier tool descriptor still reads a card that is served. Increase it only for a change an + * already-loaded card cannot handle: a result shape or action it would misread. + */ +export const VIEW_MAJOR = 1; /** Where a diagnostic card sends its milestone reports (#335). Served only when a diagnostics origin is configured. */ export const VIEW_DIAGNOSTICS_PATH = '/diag/view'; /** The head element that switches a card's diagnostics on; the card's early script reads it before the bundle runs. */ @@ -12,7 +18,7 @@ const CLOSED_CONNECT = "connect-src 'none'"; /** * Prepare immutable deployment bytes once from the built card the host supplies: no file is read here. * With a diagnostics origin (a deployment under diagnosis), the card may connect to that one origin and is told - * where to report. That changes its bytes, its address and its permissions, so a diagnostic run is compared with + * where to report. That changes its bytes and its permissions, not its address, so a diagnostic run is compared with * the closed card, not assumed equal to it. Without one, the card and its permissions are exactly the built card's. */ export function prepareAnswerView(html: string, release?: string, diagnosticsOrigin?: string): OperationView { @@ -23,8 +29,8 @@ export function prepareAnswerView(html: string, release?: string, diagnosticsOri currentHtml = currentHtml .replace(CLOSED_CONNECT, `connect-src ${diagnosticsOrigin}`) .replace(/]*>/, head => `${head}`); - return Object.freeze(operationViewFromHtml({html: currentHtml, filename: VIEW_FILENAME, title: 'Ansari answer card', csp: {connectDomains: [diagnosticsOrigin]}})); + return Object.freeze(operationViewFromHtml({html: currentHtml, filename: VIEW_FILENAME, major: VIEW_MAJOR, title: 'Ansari answer card', csp: {connectDomains: [diagnosticsOrigin]}})); } - // The identity is taken from the final bytes, after revision stamping. Declared permissions stay closed. - return Object.freeze(operationViewFromHtml({html: currentHtml, filename: VIEW_FILENAME, title: 'Ansari answer card'})); + // The release stamp is in the bytes, not the address. Declared permissions stay closed. + return Object.freeze(operationViewFromHtml({html: currentHtml, filename: VIEW_FILENAME, major: VIEW_MAJOR, title: 'Ansari answer card'})); } diff --git a/apps/mcp/src/view/saga-credit.tsx b/apps/mcp/src/view/saga-credit.tsx index 6b3e48de..6e4fe343 100644 --- a/apps/mcp/src/view/saga-credit.tsx +++ b/apps/mcp/src/view/saga-credit.tsx @@ -1,6 +1,6 @@ import {useHostLink} from '@saga-a2ui/react-mcp-stack/faithful-card'; -const REPOSITORY = 'https://github.com/MachineWisdomAI/saga-a2ui/tree/codex/release-0.7.6'; +const REPOSITORY = 'https://github.com/MachineWisdomAI/saga-a2ui'; /** * Optional application credit, separate from the unchanged upstream answer. It follows the card's diff --git a/apps/mcp/test/browser.ts b/apps/mcp/test/browser.ts index a5d38a23..de564701 100644 --- a/apps/mcp/test/browser.ts +++ b/apps/mcp/test/browser.ts @@ -5,7 +5,6 @@ import fs from 'node:fs'; import http from 'node:http'; import {Client, StreamableHTTPClientTransport} from '@modelcontextprotocol/client'; import {createContentPolicy} from '@saga-a2ui/react-mcp-stack/content-policy'; -import {viewUriForHtml} from '@saga-a2ui/react-mcp-stack/server'; import {chromium, type Frame, type Page} from '@playwright/test'; import {build, preview} from 'vite'; import {createHttpServer as createBaseHttpServer} from '../src/node/http-server.ts'; @@ -74,11 +73,11 @@ async function main() { await client.connect(transport); // ---- The served resource: exact bytes, identity, resource rules --------------------------------- - const viewUri = viewUriForHtml(stampHtmlRevision(html), VIEW_FILENAME); + const viewUri = 'ui://views/answer-card.v1.html'; const resource = await client.readResource({uri: viewUri}); const bytes = String((resource.contents[0] as {text: string}).text); check('resource:exact-served-bytes', () => assert.equal(bytes, stampHtmlRevision(html))); - check('resource:uri-is-sha256-fingerprint-of-served-bytes', () => assert.equal(viewUri, `ui://views/${VIEW_FILENAME.replace(/\.html$/, '')}.${sha(bytes).slice(0, 32)}.html`)); + check('resource:uri-names-the-compatibility-line', () => assert.equal(viewUri, `ui://views/${VIEW_FILENAME.replace(/\.html$/, '')}.v1.html`)); const meta = (resource.contents[0] as any)._meta; check('resource:closed-csp-no-origins', () => assert.deepEqual(meta.ui.csp, {connectDomains: [], resourceDomains: [], frameDomains: [], baseUriDomains: []})); const callTool = (question: string) => client.callTool({name: 'answer_islamic_question', arguments: {question}}); @@ -329,7 +328,7 @@ async function main() { check('links:successful-credit-is-silent', () => assert.equal(creditNotice, '')); const creditOpened = await page.evaluate(id => (window as any).hostProbe.state(id).openLinks, first.id); check('links:saga-credit-follows-unchanged-answer-and-uses-host', () => { - assert.deepEqual(creditOpened, ['https://ansari.chat/', 'https://github.com/MachineWisdomAI/saga-a2ui/tree/codex/release-0.7.6']); + assert.deepEqual(creditOpened, ['https://ansari.chat/', 'https://github.com/MachineWisdomAI/saga-a2ui']); assert.ok(!shownA.cardText.includes('Built with')); }); @@ -338,7 +337,7 @@ async function main() { await deliver(unavailable.id, resultA); for (const [button, status, destination] of [ ['.saga-card-link', '.saga-card-link-status', 'https://ansari.chat/'], - ['.saga-credit button', '.saga-credit [role="status"]', 'https://github.com/MachineWisdomAI/saga-a2ui/tree/codex/release-0.7.6'], + ['.saga-credit button', '.saga-credit [role="status"]', 'https://github.com/MachineWisdomAI/saga-a2ui'], ] as const) { await unavailable.frame.locator(button).click(); await unavailable.frame.locator(status).filter({hasText: 'This host cannot open links.'}).waitFor(); diff --git a/apps/mcp/test/diagnostics.test.ts b/apps/mcp/test/diagnostics.test.ts index 6dd8dcbc..26be381c 100644 --- a/apps/mcp/test/diagnostics.test.ts +++ b/apps/mcp/test/diagnostics.test.ts @@ -182,7 +182,11 @@ test('a diagnostics origin opens exactly one connect origin and stamps the beaco assert.ok(view.html.includes(`connect-src ${ORIGIN};`)); assert.ok(!view.html.includes("connect-src 'none'")); assert.deepEqual(view.csp.connectDomains, [ORIGIN]); - assert.notEqual(view.uri, prepareAnswerView(html, 'r1').uri, 'a diagnostic card has its own address'); + // Same compatibility line, so the same address; the bytes and permissions are what differ from the closed card. + const closed = prepareAnswerView(html, 'r1'); + assert.equal(view.uri, closed.uri); + assert.notEqual(view.html, closed.html); + assert.deepEqual(closed.csp.connectDomains, []); for (const bad of ['http://dev.example', 'https://dev.example/path', 'https://user@dev.example', 'not a url', 'https://dev.example?x=1']) { assert.throws(() => settingsFromEnv({MCP_VIEW_DIAGNOSTICS_ORIGIN: bad}), /MCP_VIEW_DIAGNOSTICS_ORIGIN/, bad); } diff --git a/apps/mcp/test/packaging.test.ts b/apps/mcp/test/packaging.test.ts index 6aa9cb12..bfa0e0b3 100644 --- a/apps/mcp/test/packaging.test.ts +++ b/apps/mcp/test/packaging.test.ts @@ -1,6 +1,7 @@ import assert from 'node:assert/strict'; import {test} from 'node:test'; import {execFileSync} from 'node:child_process'; +import {createHash} from 'node:crypto'; import {existsSync, readFileSync, readdirSync, realpathSync} from 'node:fs'; import {dirname, join} from 'node:path'; import {fileURLToPath} from 'node:url'; @@ -25,33 +26,45 @@ test('packaged HTML is self-contained and assets contain bytes',()=>{ } }); -// ---- The SAGA packages: one exact public npm release, never a tag, range, tarball or local file. -// The expected values below were read from the public npm registry (`npm view @saga-a2ui/@0.7.6 dist.integrity`), -// not from the files they are compared with. -const SDK_VERSION='0.7.6'; -const SDK_INTEGRITY:Record={ - core:'sha512-m+ynUS2+f36exYwqimAnnjxtVKJ1+Xm2Zscja+kWI9iFoDxVtT6C2lYxO6exSSXyi4LreJMgFhQsKh0hsaMVDg==', - components:'sha512-Gpm2uc2VbXNrxfWNy2uHfdJYdzNf5ewZKTpsaO5nsLSF0ymDjwzJ45h0BiVD77zyO4KXmDb2QipuCraTbqFApQ==', - mcp:'sha512-LBBOUhhagKZszb+Y6ooZSNDvJs3GZ6EE+Ysk8gsSVkxWrGRdcg5j3GgY/jcYF8K1NzEFQw75rm1KhM+C210ZAA==', - react:'sha512-6oz4GAWZzLjsysHSPKw6zOqYFF5D+bAcp9CtGJ5Exc/9Z+x2OM4Sn7oHMdul47iDMEJi9WNbrI5+DSGvii1a3g==', - 'react-mcp-stack':'sha512-ZYv9uL9FAjVRrfboabT6YRu6zHO8JOQKXc9D2pYskpacCRpezsVrQpNtjbh2TUDOdaY+SYEDIAl8+Js1U0oJqQ==', +// ---- The SAGA packages: one exact version from one source, never a tag, range or machine path. +// A public release resolves from the npm registry with the integrity below, read from the registry +// (`npm view @saga-a2ui/@ dist.integrity`), not from the files compared with it. Until a release is on the +// registry, a private candidate (`0.0.0-candidate.g`) resolves from the tarballs committed under candidates/, +// and the lockfile must record exactly their bytes. +const REGISTRY_INTEGRITY:Record>={ + '0.7.6':{ + core:'sha512-m+ynUS2+f36exYwqimAnnjxtVKJ1+Xm2Zscja+kWI9iFoDxVtT6C2lYxO6exSSXyi4LreJMgFhQsKh0hsaMVDg==', + components:'sha512-Gpm2uc2VbXNrxfWNy2uHfdJYdzNf5ewZKTpsaO5nsLSF0ymDjwzJ45h0BiVD77zyO4KXmDb2QipuCraTbqFApQ==', + mcp:'sha512-LBBOUhhagKZszb+Y6ooZSNDvJs3GZ6EE+Ysk8gsSVkxWrGRdcg5j3GgY/jcYF8K1NzEFQw75rm1KhM+C210ZAA==', + react:'sha512-6oz4GAWZzLjsysHSPKw6zOqYFF5D+bAcp9CtGJ5Exc/9Z+x2OM4Sn7oHMdul47iDMEJi9WNbrI5+DSGvii1a3g==', + 'react-mcp-stack':'sha512-ZYv9uL9FAjVRrfboabT6YRu6zHO8JOQKXc9D2pYskpacCRpezsVrQpNtjbh2TUDOdaY+SYEDIAl8+Js1U0oJqQ==', + }, }; -const SIBLINGS=Object.keys(SDK_INTEGRITY); +const SIBLINGS=['core','components','mcp','react','react-mcp-stack']; const pinned:string=JSON.parse(readFileSync(join(root,'package.json'),'utf8')).dependencies['@saga-a2ui/react-mcp-stack']; +const SDK_VERSION=pinned; +const CANDIDATE=/^0\.0\.0-candidate\.g([0-9a-f]{12})$/.exec(pinned); +const CANDIDATE_DIR=`candidates/saga-${pinned}`; +const candidateFile=(sibling:string)=>`${CANDIDATE_DIR}/saga-a2ui-${sibling}-${pinned}.tgz`; +const digest=(algorithm:string,file:string,encoding:'hex'|'base64')=>createHash(algorithm).update(readFileSync(join(root,file))).digest(encoding); +/** The integrity each sibling must resolve with: the registry's for a release, the committed tarball's for a candidate. */ +function expectedIntegrity(sibling:string):string{ + if(CANDIDATE) return `sha512-${digest('sha512',candidateFile(sibling),'base64')}`; + const known=REGISTRY_INTEGRITY[SDK_VERSION]; + assert.ok(known,`record the registry integrity of every SAGA package at ${SDK_VERSION} (npm view @saga-a2ui/@${SDK_VERSION} dist.integrity)`); + return known[sibling]; +} const node=(...args:string[])=>execFileSync(process.execPath,args,{cwd:root,encoding:'utf8'}); -test('the manifest pins one exact public version for every SAGA package it imports',()=>{ +test('the manifest pins one exact version for every SAGA package it imports',()=>{ const manifest=JSON.parse(readFileSync(join(root,'package.json'),'utf8')); const saga=Object.entries({...manifest.dependencies,...manifest.devDependencies}).filter(([name])=>name.startsWith('@saga-a2ui/')); assert.deepEqual(saga.map(([name])=>name).sort(),['@saga-a2ui/react-mcp-stack']); - for(const [name,version] of saga) { - assert.match(version,/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/,`${name} is an exact version, never a tag or range`); - assert.equal(version,SDK_VERSION,name); - } + for(const [name,version] of saga) assert.match(version,/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/,`${name} is an exact version, never a tag or range`); assert.equal(manifest.devDependencies.typescript, 'catalog:'); assert.equal(manifest.devDependencies.eslint, 'catalog:'); assert.equal(manifest.devDependencies['@ansari/eslint-config'], 'workspace:*'); - assert.ok(!/"(?:file|link|workspace|git\+?[a-z]*|https?):/.test(JSON.stringify({...manifest.dependencies,overrides:manifest.overrides,pnpm:manifest.pnpm})),'no local, tarball or workspace dependency source'); + assert.ok(!/"(?:file|link|workspace|git\+?[a-z]*|https?):/.test(JSON.stringify({...manifest.dependencies,overrides:manifest.overrides,pnpm:manifest.pnpm})),'no local, tarball or workspace dependency source in the manifest'); }); // The lockfile that installs this application: the workspace root's. The application has none of its own (asserted below). @@ -61,31 +74,37 @@ assert.equal(existsSync(join(root,'pnpm-workspace.yaml')), false, 'only the root const workspaceLock=join(root,'../../pnpm-lock.yaml'); if(existsSync(workspaceLock)&&existsSync(join(root,'../../pnpm-workspace.yaml'))) lockfiles.push({label:'workspace root',text:readFileSync(workspaceLock,'utf8'),prefix:'apps/mcp'}); -test('every lockfile resolves the five SAGA packages to the public registry with the registry integrity',()=>{ +test('every lockfile resolves the five SAGA packages from one source with that source\'s integrity',()=>{ assert.ok(lockfiles.length>0,'at least one lockfile installs this application'); - for(const {label,text} of lockfiles) { + for(const {label,text,prefix} of lockfiles) { + const ref=(sibling:string)=>CANDIDATE?`file:${prefix}/${candidateFile(sibling)}`:SDK_VERSION; for(const sibling of SIBLINGS) { - const key=`'@saga-a2ui/${sibling}@${SDK_VERSION}':\n resolution: {integrity: ${SDK_INTEGRITY[sibling]}}`; - assert.ok(text.includes(key),`${label} lockfile locks ${sibling} to the registry release with its integrity`); + const resolution=CANDIDATE?`{integrity: ${expectedIntegrity(sibling)}, tarball: ${ref(sibling)}}`:`{integrity: ${expectedIntegrity(sibling)}}`; + assert.ok(text.includes(`'@saga-a2ui/${sibling}@${ref(sibling)}':\n resolution: ${resolution}`),`${label} lockfile locks ${sibling} to ${CANDIDATE?'the committed candidate tarball':'the registry release'} with its integrity`); } - // Nothing else from @saga-a2ui, no second SAGA version, and no local source of any kind for it. - const resolved=[...new Set([...text.matchAll(/^ {2}'(@saga-a2ui\/[a-z-]+)@([^':(]+)':$/gm)].map(match=>`${match[1]}@${match[2]}`))].sort(); - assert.deepEqual(resolved,SIBLINGS.map(sibling=>`@saga-a2ui/${sibling}@${SDK_VERSION}`).sort(),`${label} lockfile: exactly the five packages at one version`); - assert.doesNotMatch(text,/@saga-a2ui\/[a-z-]+@file:|tarball: file:|@saga-a2ui\/lit/,`${label} lockfile: no local file or Lit package`); + // Nothing else from @saga-a2ui, no second SAGA version, and no other local source for it. + const resolved=[...new Set([...text.matchAll(/^ {2}'(@saga-a2ui\/[a-z-]+)@([^'(]+)':$/gm)].map(match=>`${match[1]}@${match[2]}`))].sort(); + assert.deepEqual(resolved,SIBLINGS.map(sibling=>`@saga-a2ui/${sibling}@${ref(sibling)}`).sort(),`${label} lockfile: exactly the five packages from one source`); + if(!CANDIDATE) assert.doesNotMatch(text,/@saga-a2ui\/[a-z-]+@file:|tarball: file:/,`${label} lockfile: no local file`); + assert.doesNotMatch(text,/@saga-a2ui\/lit/,`${label} lockfile: no Lit package`); assert.doesNotMatch(text,/(?:\/tmp\/|\/opt\/|\/Users\/|\/home\/|[A-Za-z]:\\)/,`${label} lockfile records no machine path`); } }); -test('no workspace file overrides a SAGA package',()=>{ +test('workspace overrides name a SAGA package only to install a committed candidate',()=>{ const files=[join(root,'pnpm-workspace.yaml'),join(root,'../../pnpm-workspace.yaml')].filter(file=>existsSync(file)); assert.ok(files.length>0); for(const file of files) { const workspace=readFileSync(file,'utf8'); - assert.doesNotMatch(workspace,/@saga-a2ui/,`${file} does not override or mention a SAGA package`); - assert.doesNotMatch(workspace,/file:|link:/,`${file} has no local-file dependency source`); + const overrides=[...workspace.matchAll(/^ {2}['"]?(@saga-a2ui\/[^'":]+)['"]?\s*:\s*['"]?([^'"\n]+)['"]?$/gm)].map(([,name,value])=>`${name}=${value}`).sort(); + assert.deepEqual(overrides,CANDIDATE?SIBLINGS.map(sibling=>`@saga-a2ui/${sibling}=file:apps/mcp/${candidateFile(sibling)}`).sort():[],`${file}: ${CANDIDATE?'every sibling, and only the siblings, from the candidate set':'no SAGA override'}`); + if(!CANDIDATE) assert.doesNotMatch(workspace,/file:|link:/,`${file} has no local-file dependency source`); + assert.doesNotMatch(workspace,/link:/,`${file} links no local package`); assert.match(workspace,/['"]@a2ui\/react@0\.13\.0>@a2ui\/markdown-it['"]\s*:\s*['"]0\.2\.1['"]/,`${file} pins the A2UI Markdown adapter`); } - assert.equal(existsSync(join(root,'candidates')),false,'no local SAGA inputs are committed'); + if(!CANDIDATE) assert.equal(existsSync(join(root,'candidates')),false,'no local SAGA inputs are committed'); + else assert.deepEqual(readdirSync(join(root,'candidates')),[`saga-${pinned}`],'one candidate set, the pinned one'); + if(CANDIDATE) assert.deepEqual(readdirSync(join(root,CANDIDATE_DIR)).sort(),SIBLINGS.map(sibling=>`saga-a2ui-${sibling}-${pinned}.tgz`).sort(),'the candidate set holds exactly the five tarballs'); }); test('the installed tree has strict same-version siblings and one framework runtime',()=>{ @@ -124,15 +143,20 @@ test('production code imports SAGA only through the one stack, and the browser b assert.ok(!html.includes('The MCP server already ends a different request lifetime.'),'the view bundle holds no server lifetime module'); }); -// ---- The card document names the SDK release it was built from, beside the application release. -test('the emitted card document carries the registry SDK identity beside the application release',()=>{ +// ---- The card document names the SDK it was built from, beside the application release. +test('the emitted card document carries the SDK identity beside the application release',()=>{ const html=readFileSync(join(root,'dist/view.html'),'utf8'); - const expected={kind:'registry',version:SDK_VERSION,source:'none','stack-sha256':'none','set-sha256':'none'}; + // A candidate is named by its source commit and the bytes of its tarballs, recomputed here from the committed files. + const set=CANDIDATE?createHash('sha256').update(SIBLINGS.map(sibling=>`saga-a2ui-${sibling}-${pinned}.tgz`).sort().map(name=>`${name} ${digest('sha256',`${CANDIDATE_DIR}/${name}`,'hex')}\n`).join('')).digest('hex'):'none'; + const identity=CANDIDATE + ?{kind:'candidate',version:SDK_VERSION,source:CANDIDATE[1],stackSha256:digest('sha256',candidateFile('react-mcp-stack'),'hex'),setSha256:set} + :{kind:'registry',version:SDK_VERSION,source:'none',stackSha256:'none',setSha256:'none'}; + const expected={kind:identity.kind,version:identity.version,source:identity.source,'stack-sha256':identity.stackSha256,'set-sha256':identity.setSha256}; const body=/]*>/.exec(html)?.[0]??''; for(const [name,value] of Object.entries(expected)) assert.equal(body.match(new RegExp(`\\sdata-sdk-${name}="([^"]*)"`))?.[1],value,`data-sdk-${name}`); assert.equal(body.match(/\sdata-release="([^"]*)"/)?.[1],JSON.parse(readFileSync(join(root,'package.json'),'utf8')).version,'the application release stays beside the SDK identity'); assert.ok(html.includes(` { diff --git a/apps/mcp/test/parity-cases.ts b/apps/mcp/test/parity-cases.ts index 6f4fbd42..1550f0e5 100644 --- a/apps/mcp/test/parity-cases.ts +++ b/apps/mcp/test/parity-cases.ts @@ -1,5 +1,4 @@ import assert from 'node:assert/strict'; -import {createHash} from 'node:crypto'; import {readFileSync} from 'node:fs'; import {request as httpRequest} from 'node:http'; import {after, before, describe, it} from 'node:test'; @@ -130,9 +129,9 @@ export function defineParityCases(kind: RuntimeKind): void { assert.ok(uri); assert.deepEqual((await client.listResources()).resources.map(resource => resource.uri), [uri]); const text = ((await client.readResource({uri})).contents[0] as {text: string}).text; - // Release stamping precedes hashing: the served bytes are the built card with the release stamped, and the identity is theirs. + // The served bytes are the built card with the release stamped; the address names the card's compatibility line. assert.equal(text, stampHtmlRevision(builtCard, RELEASE)); - assert.equal(uri, `ui://views/answer-card.${createHash('sha256').update(text).digest('hex').slice(0, 32)}.html`); + assert.equal(uri, 'ui://views/answer-card.v1.html'); await assert.rejects(client.readResource({uri: 'ui://obsolete.html'})); }); }); diff --git a/apps/mcp/test/runtime-boundary.test.ts b/apps/mcp/test/runtime-boundary.test.ts index 1d4b8a6b..9d6a2daf 100644 --- a/apps/mcp/test/runtime-boundary.test.ts +++ b/apps/mcp/test/runtime-boundary.test.ts @@ -1,5 +1,4 @@ import assert from 'node:assert/strict'; -import {createHash} from 'node:crypto'; import {existsSync, readdirSync, readFileSync} from 'node:fs'; import {test} from 'node:test'; import {DEFAULT_RELEASE} from '../src/server/operation-log.ts'; @@ -33,17 +32,19 @@ test('the Workers bundle holds the shared application and none of the Node hosti assert.doesNotMatch(bundle, /createAdaptorServer|SIGTERM/, 'no Node listener or signal lifecycle'); }); -test('release stamping precedes hashing: equal final bytes share an identity and a release change moves it', () => { +test('the address names the compatibility line: a release changes the card bytes, never its address', () => { const unstamped = 'one'; const stamped = 'one'; const a = prepareAnswerView(unstamped, 'r1'); const b = prepareAnswerView(stamped, 'r1'); assert.equal(a.html, b.html, 'both end as the same final bytes'); - assert.equal(a.uri, b.uri); - assert.equal(a.uri, `ui://views/answer-card.${createHash('sha256').update(a.html).digest('hex').slice(0, 32)}.html`); + assert.equal(a.uri, 'ui://views/answer-card.v1.html'); assert.match(a.html, /data-revision="r1"/); - assert.notEqual(prepareAnswerView(unstamped, 'r2').uri, a.uri, 'a legitimate release change moves the hash'); - assert.equal(prepareAnswerView(unstamped, 'r1').uri, a.uri, 'preparing again changes nothing'); + // A host holding a tool descriptor from before a deploy still names an address that is served (#335). + const next = prepareAnswerView(unstamped, 'r2'); + assert.notEqual(next.html, a.html, 'a release change reaches the bytes'); + assert.equal(next.uri, a.uri, 'and keeps the address'); + assert.equal(prepareAnswerView('two', 'r1').uri, a.uri, 'so does a compatible card change'); }); test('settings come from the supplied bindings, with the same rules under both hosts', () => { diff --git a/apps/mcp/test/transport.test.ts b/apps/mcp/test/transport.test.ts index 3c5994bb..916760c3 100644 --- a/apps/mcp/test/transport.test.ts +++ b/apps/mcp/test/transport.test.ts @@ -1,6 +1,5 @@ import assert from 'node:assert/strict'; import {test} from 'node:test'; -import {createHash} from 'node:crypto'; import {request as httpRequest} from 'node:http'; import {Client, StreamableHTTPClientTransport} from '@modelcontextprotocol/client'; import {listen} from '../src/node/http-server.js'; @@ -24,16 +23,18 @@ async function resource(html: string) { assert.deepEqual(listed.resources.map(r=>r.uri),[uri]); const read = await client.readResource({uri}); const text = (read.contents[0] as {text:string}).text; - assert.equal(uri,`ui://views/answer-card.${createHash('sha256').update(text).digest('hex').slice(0,32)}.html`); + assert.equal(uri,'ui://views/answer-card.v1.html'); + assert.match(text,/]*data-revision=/,'the read returns the release-stamped card'); await assert.rejects(client.readResource({uri:'ui://obsolete.html'})); for(const path of ['/demo','/demo/answer','/fonts/amiri.ttf']) assert.equal((await fetch(`http://127.0.0.1:${service.port}${path}`)).status,404); return uri; } finally {await client.close();await service.close();} } -test('one current resource, unchanged answer, MCP linkage and HTML identity', async()=>{ +test('one current resource, unchanged answer, MCP linkage, and one address across compatible cards', async()=>{ const a=await resource('one'); const b=await resource('two'); - assert.notEqual(a,b); + // Different card bytes on the same compatibility line keep the address, so a stale descriptor still reads a served card. + assert.equal(a,b); }); test('API client sends the question and preserves the complete response',async()=>{ const client=createAnsariHttpCompleter({baseUrl:'https://synthetic.invalid/',fetchImpl:async(url,init)=>{ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8db1d01..cb62f909 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,6 +18,13 @@ catalogs: overrides: '@a2ui/react@0.13.0>@a2ui/markdown-it': 0.2.1 + '@saga-a2ui/core': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz + '@saga-a2ui/components': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz + '@saga-a2ui/mcp': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz + '@saga-a2ui/react': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz + '@saga-a2ui/react-mcp-stack': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz + dompurify: 3.4.17 + '@hono/node-server': 2.1.5 sharp: ^0.35.0 postcss: ^8.5.23 esbuild: ^0.28.1 @@ -34,79 +41,6 @@ importers: specifier: 2.10.11 version: 2.10.11 - apps/mcp: - dependencies: - '@hono/node-server': - specifier: 1.19.17 - version: 1.19.17(hono@4.13.13) - '@modelcontextprotocol/hono': - specifier: 2.0.2 - version: 2.0.2(@modelcontextprotocol/server@2.3.1)(hono@4.13.13) - '@modelcontextprotocol/server': - specifier: 2.3.1 - version: 2.3.1 - '@saga-a2ui/react-mcp-stack': - specifier: 0.7.6 - version: 0.7.6(@modelcontextprotocol/client@2.3.1)(@modelcontextprotocol/core@2.3.1)(@modelcontextprotocol/server@2.3.1)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) - hono: - specifier: 4.13.13 - version: 4.13.13 - react: - specifier: 19.3.1 - version: 19.3.1 - react-dom: - specifier: 19.3.1 - version: 19.3.1(react@19.3.1) - zod: - specifier: 4.6.7 - version: 4.6.7 - devDependencies: - typescript-eslint: - specifier: 'catalog:' - version: 8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3) - eslint: - specifier: 'catalog:' - version: 9.39.5(jiti@2.7.0) - '@ansari/eslint-config': - specifier: workspace:* - version: link:../../packages/eslint-config - '@modelcontextprotocol/client': - specifier: 2.3.1 - version: 2.3.1 - '@modelcontextprotocol/ext-apps': - specifier: 2.0.3 - version: 2.0.3(@modelcontextprotocol/client@2.3.1)(@modelcontextprotocol/core@2.3.1)(@modelcontextprotocol/server@2.3.1)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7) - '@playwright/test': - specifier: 1.64.0 - version: 1.64.0 - '@types/node': - specifier: 22.20.5 - version: 22.20.5 - '@types/react': - specifier: 19.3.0 - version: 19.3.0 - '@types/react-dom': - specifier: 19.3.0 - version: 19.3.0(@types/react@19.3.0) - esbuild: - specifier: ^0.28.1 - version: 0.28.2 - tsx: - specifier: 4.22.0 - version: 4.22.0 - typescript: - specifier: 'catalog:' - version: 6.0.3 - vite: - specifier: 6.4.1 - version: 6.4.1(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(tsx@4.22.0)(yaml@2.9.1) - vite-plugin-singlefile: - specifier: 2.3.0 - version: 2.3.0(rollup@4.62.4)(vite@6.4.1(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(tsx@4.22.0)(yaml@2.9.1)) - wrangler: - specifier: 4.151.3 - version: 4.151.3(@types/node@22.20.5) - apps/api: dependencies: '@ansari/types': @@ -449,6 +383,79 @@ importers: specifier: ^3.2.7 version: 3.2.7(@types/node@25.9.8)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.33.0)(terser@5.51.2)(tsx@4.23.11)(yaml@2.9.1) + apps/mcp: + dependencies: + '@hono/node-server': + specifier: 2.1.5 + version: 2.1.5(hono@4.13.16) + '@modelcontextprotocol/hono': + specifier: 2.0.2 + version: 2.0.2(@modelcontextprotocol/server@2.4.0)(hono@4.13.16) + '@modelcontextprotocol/server': + specifier: 2.4.0 + version: 2.4.0 + '@saga-a2ui/react-mcp-stack': + specifier: file:candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz + version: file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz(@modelcontextprotocol/client@2.4.0)(@modelcontextprotocol/core@2.4.0)(@modelcontextprotocol/server@2.4.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + hono: + specifier: 4.13.16 + version: 4.13.16 + react: + specifier: 19.3.1 + version: 19.3.1 + react-dom: + specifier: 19.3.1 + version: 19.3.1(react@19.3.1) + zod: + specifier: 4.6.7 + version: 4.6.7 + devDependencies: + '@ansari/eslint-config': + specifier: workspace:* + version: link:../../packages/eslint-config + '@modelcontextprotocol/client': + specifier: 2.4.0 + version: 2.4.0 + '@modelcontextprotocol/ext-apps': + specifier: 2.0.3 + version: 2.0.3(@modelcontextprotocol/client@2.4.0)(@modelcontextprotocol/core@2.4.0)(@modelcontextprotocol/server@2.4.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7) + '@playwright/test': + specifier: 1.64.0 + version: 1.64.0 + '@types/node': + specifier: 22.20.5 + version: 22.20.5 + '@types/react': + specifier: 19.3.0 + version: 19.3.0 + '@types/react-dom': + specifier: 19.3.0 + version: 19.3.0(@types/react@19.3.0) + esbuild: + specifier: ^0.28.1 + version: 0.28.2 + eslint: + specifier: 'catalog:' + version: 9.39.5(jiti@2.7.0) + tsx: + specifier: 4.22.0 + version: 4.22.0 + typescript: + specifier: 'catalog:' + version: 6.0.3 + typescript-eslint: + specifier: 'catalog:' + version: 8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3) + vite: + specifier: 6.4.1 + version: 6.4.1(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(tsx@4.22.0)(yaml@2.9.1) + vite-plugin-singlefile: + specifier: 2.3.0 + version: 2.3.0(rollup@4.62.4)(vite@6.4.1(@types/node@22.20.5)(jiti@2.7.0)(lightningcss@1.33.0)(terser@5.51.2)(tsx@4.22.0)(yaml@2.9.1)) + wrangler: + specifier: 4.151.3 + version: 4.151.3(@types/node@22.20.5) + packages/auth: dependencies: '@ansari/types': @@ -456,7 +463,7 @@ importers: version: link:../types '@better-auth/expo': specifier: 1.7.7 - version: 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(better-auth@1.7.7(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))(next@15.5.25(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.0)(@types/node@25.9.5)(babel-plugin-react-compiler@1.0.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.22.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@4.1.11))(expo-constants@57.0.21)(expo-linking@57.0.12)(expo-secure-store@57.0.4(expo@57.0.27))(expo-web-browser@57.0.3(expo@57.0.27)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.1))) + version: 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(better-auth@1.7.7(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))(next@15.5.25(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.0)(@types/node@25.9.5)(babel-plugin-react-compiler@1.0.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.22.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@4.1.11))(expo-constants@57.0.21)(expo-linking@57.0.12)(expo-secure-store@57.0.4(expo@57.0.27))(expo-web-browser@57.0.3(expo@57.0.27)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.1))) bcrypt: specifier: ^6.0.0 version: 6.0.0 @@ -1601,11 +1608,11 @@ packages: '@modelcontextprotocol/sdk': optional: true - '@hono/node-server@1.19.17': - resolution: {integrity: sha512-dSneS5qhiauZWGDCeK4o695Xd9nUNjviSZCMQrj10eetr8Uln1ucn6bbphOM6UynAMMtNIzZNSpL9vnASJwrPQ==} - engines: {node: '>=18.14.1'} + '@hono/node-server@2.1.5': + resolution: {integrity: sha512-MgP/I06GdvsilDspMk/qmRzpk8LOUStP6jFAbSRi40W09DhoyUn+Mj7eyKICPqeYKybOjVFLVIAQzvu1bfIa7Q==} + engines: {node: '>=20'} peerDependencies: - hono: ^4 + hono: ^4 || ^5.0.0-0 '@humanfs/core@0.19.2': resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} @@ -1990,12 +1997,12 @@ packages: '@lit/reactive-element@2.1.2': resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} - '@modelcontextprotocol/client@2.3.1': - resolution: {integrity: sha512-mIGZXpHsjnZ6lD+gD/WCMpR5k8yVQQ8nNFH1N0Srf7AvnwTUMYD6pvTY8ng2+He5FfV7YMZLmrjL7cLa/cc3dQ==} + '@modelcontextprotocol/client@2.4.0': + resolution: {integrity: sha512-LgrD2OphHuG12vfKFKz6SOnq7bKHQmhGJIAYdD+MZBn2npHEyry6uD8zvktodtl5CQM85MO0anUyD9JwmUmxww==} engines: {node: '>=20'} - '@modelcontextprotocol/core@2.3.1': - resolution: {integrity: sha512-laVmIhPGpWi7rG9q+0UigblRN0Hws/Yjlb6qLFtVqryXVLkc4h+yN8z731POD2LnAGQlFe7/tXhUm7Bi0YB91g==} + '@modelcontextprotocol/core@2.4.0': + resolution: {integrity: sha512-z8QBKqdfXLPzkLQuG4xp8hrVEMm1PZ1IgxMN2sMbJiFiAKOWXnAzogXn2W4aqIBlP1ea6U5yiqVquvUNM1Cj6Q==} engines: {node: '>=20'} '@modelcontextprotocol/ext-apps@2.0.3': @@ -2023,8 +2030,8 @@ packages: '@modelcontextprotocol/server': ^2.3.0 hono: ^4.11.4 - '@modelcontextprotocol/server@2.3.1': - resolution: {integrity: sha512-e59MfWuSssj6DoQ96JCTqdW1AXT5/XtnTl0WWd6MU1Ka434fFUGGosCLJbGNySDhHGvxQWoRWK137FXYFkYNWw==} + '@modelcontextprotocol/server@2.4.0': + resolution: {integrity: sha512-rgR9yxSaAJ+bcsi/XroT/S2AfPiIWloXAnrdfYSCms9ivVju0ishu/wW0J21Ho6+ZOR1r7RyeRbjiRuF87ix5Q==} engines: {node: '>=20'} '@napi-rs/lzma-linux-x64-gnu@1.5.1': @@ -2934,32 +2941,37 @@ packages: '@rushstack/eslint-patch@1.16.1': resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} - '@saga-a2ui/components@0.7.6': - resolution: {integrity: sha512-Gpm2uc2VbXNrxfWNy2uHfdJYdzNf5ewZKTpsaO5nsLSF0ymDjwzJ45h0BiVD77zyO4KXmDb2QipuCraTbqFApQ==} + '@saga-a2ui/components@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz': + resolution: {integrity: sha512-ir7z/7V2B+aOov0w8YpaDfS+9DKntBboZMM3p0RiHEbGIsmMdrAG3F25TICfyx6fhnVdrEJj2k/e1qiDWtM+9g==, tarball: file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz} + version: 0.0.0-candidate.g8b4d987dd233 engines: {node: '>=22.12.0'} - '@saga-a2ui/core@0.7.6': - resolution: {integrity: sha512-m+ynUS2+f36exYwqimAnnjxtVKJ1+Xm2Zscja+kWI9iFoDxVtT6C2lYxO6exSSXyi4LreJMgFhQsKh0hsaMVDg==} + '@saga-a2ui/core@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz': + resolution: {integrity: sha512-nQO7PqLPWrebCkN7qwv7CbBFZRg0hIRQ6/WmPxpZJIL1bTAX5JkjjB3ZFVEhRQwRa0QhFcQOJpE7HW4RHtfwQQ==, tarball: file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz} + version: 0.0.0-candidate.g8b4d987dd233 engines: {node: '>=22.12.0'} - '@saga-a2ui/mcp@0.7.6': - resolution: {integrity: sha512-LBBOUhhagKZszb+Y6ooZSNDvJs3GZ6EE+Ysk8gsSVkxWrGRdcg5j3GgY/jcYF8K1NzEFQw75rm1KhM+C210ZAA==} + '@saga-a2ui/mcp@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz': + resolution: {integrity: sha512-bRR7ySzT0IPZr9Lx3pqfb3gEWeq0HkoFjDVPB3Fw7HGZzYXB/Dw6QvpsfiiZ3kPNs1fqGQcOVXS0pLruU392BA==, tarball: file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz} + version: 0.0.0-candidate.g8b4d987dd233 engines: {node: '>=22.12.0'} - '@saga-a2ui/react-mcp-stack@0.7.6': - resolution: {integrity: sha512-ZYv9uL9FAjVRrfboabT6YRu6zHO8JOQKXc9D2pYskpacCRpezsVrQpNtjbh2TUDOdaY+SYEDIAl8+Js1U0oJqQ==} + '@saga-a2ui/react-mcp-stack@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz': + resolution: {integrity: sha512-laKjVCJG1HBKd61WxwNHv1bdzA/KRa21OkG25O9k8QKaziEtewWO8RMNmTZYVjjJ9FXhKAchr5bJfPZW9lhNAw==, tarball: file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz} + version: 0.0.0-candidate.g8b4d987dd233 engines: {node: '>=22.12.0'} peerDependencies: - react: 19.3.1 - react-dom: 19.3.1 + react: ^19.3.1 + react-dom: ^19.3.1 - '@saga-a2ui/react@0.7.6': - resolution: {integrity: sha512-6oz4GAWZzLjsysHSPKw6zOqYFF5D+bAcp9CtGJ5Exc/9Z+x2OM4Sn7oHMdul47iDMEJi9WNbrI5+DSGvii1a3g==} + '@saga-a2ui/react@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz': + resolution: {integrity: sha512-BancJ8w7DTiv1Rhn2Sr7sC/YhH+Xd3chfVuKU2vzYA7xBYenyHGgT7IYjnEk7TH+ZQ796WhbYGikiG73hAW8vw==, tarball: file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz} + version: 0.0.0-candidate.g8b4d987dd233 engines: {node: '>=22.12.0'} peerDependencies: - '@saga-a2ui/components': 0.7.6 - react: 19.3.1 - react-dom: 19.3.1 + '@saga-a2ui/components': 0.0.0-candidate.g8b4d987dd233 + react: ^19.3.1 + react-dom: ^19.3.1 peerDependenciesMeta: '@saga-a2ui/components': optional: true @@ -4717,8 +4729,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@3.4.11: - resolution: {integrity: sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==} + dompurify@3.4.17: + resolution: {integrity: sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==} domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -5740,8 +5752,8 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hono@4.13.13: - resolution: {integrity: sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA==} + hono@4.13.16: + resolution: {integrity: sha512-AOLOEhvrV+iH92xXCnFr/5+3KjPKcI3xP63XJtX5spAnkznPdHijlIsUTpi7/9EhWqrTCekw5c5zh1K+YsVw7A==} engines: {node: '>=16.9.0'} hookable@6.1.1: @@ -8608,7 +8620,7 @@ snapshots: '@a2ui/markdown-it@0.2.1(@a2ui/web_core@0.13.0)': dependencies: '@a2ui/web_core': 0.13.0 - dompurify: 3.4.11 + dompurify: 3.4.17 markdown-it: 14.3.3 '@a2ui/react@0.13.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@3.25.76)': @@ -9164,27 +9176,13 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2)': - dependencies: - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.2 - '@opentelemetry/semantic-conventions': 1.43.0 - '@standard-schema/spec': 1.1.0 - better-call: 1.4.0(zod@4.4.3) - jose: 6.2.9 - kysely: 0.29.5 - nanostores: 1.5.2 - zod: 4.6.7 - optionalDependencies: - '@opentelemetry/api': 1.9.1 - '@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2)': dependencies: '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.2 '@opentelemetry/semantic-conventions': 1.43.0 '@standard-schema/spec': 1.1.0 - better-call: 1.4.0(zod@4.6.5) + better-call: 1.4.0(zod@4.4.3) jose: 6.2.9 kysely: 0.29.5 nanostores: 1.5.2 @@ -9192,13 +9190,6 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.1 - '@better-auth/drizzle-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))': - dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) - '@better-auth/utils': 0.4.2 - optionalDependencies: - drizzle-orm: 0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0) - '@better-auth/drizzle-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))': dependencies: '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) @@ -9206,9 +9197,9 @@ snapshots: optionalDependencies: drizzle-orm: 0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0) - '@better-auth/expo@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(better-auth@1.7.7(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))(next@15.5.25(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.0)(@types/node@25.9.5)(babel-plugin-react-compiler@1.0.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.22.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@4.1.11))(expo-constants@57.0.21)(expo-linking@57.0.12)(expo-secure-store@57.0.4(expo@57.0.27))(expo-web-browser@57.0.3(expo@57.0.27)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.1)))': + '@better-auth/expo@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(better-auth@1.7.7(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))(next@15.5.25(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.0)(@types/node@25.9.5)(babel-plugin-react-compiler@1.0.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.22.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@4.1.11))(expo-constants@57.0.21)(expo-linking@57.0.12)(expo-secure-store@57.0.4(expo@57.0.27))(expo-web-browser@57.0.3(expo@57.0.27)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.1)))': dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) '@better-fetch/fetch': 1.3.2 better-auth: 1.7.7(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))(next@15.5.25(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.0)(@types/node@25.9.5)(babel-plugin-react-compiler@1.0.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.22.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@4.1.11) better-call: 1.4.0(zod@4.6.5) @@ -9219,13 +9210,6 @@ snapshots: expo-secure-store: 57.0.4(expo@57.0.27) expo-web-browser: 57.0.3(expo@57.0.27)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.3.0)(react@19.3.1)) - '@better-auth/kysely-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(kysely@0.29.5)': - dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) - '@better-auth/utils': 0.4.2 - optionalDependencies: - kysely: 0.29.5 - '@better-auth/kysely-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(kysely@0.29.5)': dependencies: '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) @@ -9233,42 +9217,21 @@ snapshots: optionalDependencies: kysely: 0.29.5 - '@better-auth/memory-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)': - dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) - '@better-auth/utils': 0.4.2 - '@better-auth/memory-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)': dependencies: '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) '@better-auth/utils': 0.4.2 - '@better-auth/mongo-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)': - dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) - '@better-auth/utils': 0.4.2 - '@better-auth/mongo-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)': dependencies: '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) '@better-auth/utils': 0.4.2 - '@better-auth/prisma-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)': - dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) - '@better-auth/utils': 0.4.2 - '@better-auth/prisma-adapter@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)': dependencies: '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) '@better-auth/utils': 0.4.2 - '@better-auth/telemetry@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)': - dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.2 - '@better-auth/telemetry@1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)': dependencies: '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) @@ -10077,9 +10040,9 @@ snapshots: - supports-color - utf-8-validate - '@hono/node-server@1.19.17(hono@4.13.13)': + '@hono/node-server@2.1.5(hono@4.13.16)': dependencies: - hono: 4.13.13 + hono: 4.13.16 '@humanfs/core@0.19.2': dependencies: @@ -10361,9 +10324,9 @@ snapshots: dependencies: '@lit-labs/ssr-dom-shim': 1.6.0 - '@modelcontextprotocol/client@2.3.1': + '@modelcontextprotocol/client@2.4.0': dependencies: - '@modelcontextprotocol/core': 2.3.1 + '@modelcontextprotocol/core': 2.4.0 cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.1.1 @@ -10371,29 +10334,29 @@ snapshots: pkce-challenge: 5.0.1 zod: 4.6.7 - '@modelcontextprotocol/core@2.3.1': + '@modelcontextprotocol/core@2.4.0': dependencies: zod: 4.6.7 - '@modelcontextprotocol/ext-apps@2.0.3(@modelcontextprotocol/client@2.3.1)(@modelcontextprotocol/core@2.3.1)(@modelcontextprotocol/server@2.3.1)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7)': + '@modelcontextprotocol/ext-apps@2.0.3(@modelcontextprotocol/client@2.4.0)(@modelcontextprotocol/core@2.4.0)(@modelcontextprotocol/server@2.4.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7)': dependencies: - '@modelcontextprotocol/client': 2.3.1 - '@modelcontextprotocol/core': 2.3.1 + '@modelcontextprotocol/client': 2.4.0 + '@modelcontextprotocol/core': 2.4.0 '@standard-schema/spec': 1.1.0 zod: 4.6.7 optionalDependencies: - '@modelcontextprotocol/server': 2.3.1 + '@modelcontextprotocol/server': 2.4.0 react: 19.3.1 react-dom: 19.3.1(react@19.3.1) - '@modelcontextprotocol/hono@2.0.2(@modelcontextprotocol/server@2.3.1)(hono@4.13.13)': + '@modelcontextprotocol/hono@2.0.2(@modelcontextprotocol/server@2.4.0)(hono@4.13.16)': dependencies: - '@modelcontextprotocol/server': 2.3.1 - hono: 4.13.13 + '@modelcontextprotocol/server': 2.4.0 + hono: 4.13.16 - '@modelcontextprotocol/server@2.3.1': + '@modelcontextprotocol/server@2.4.0': dependencies: - '@modelcontextprotocol/core': 2.3.1 + '@modelcontextprotocol/core': 2.4.0 zod: 4.6.7 '@napi-rs/lzma-linux-x64-gnu@1.5.1': @@ -11298,37 +11261,40 @@ snapshots: '@rushstack/eslint-patch@1.16.1': {} - '@saga-a2ui/components@0.7.6': + '@saga-a2ui/components@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz': dependencies: '@a2ui/web_core': 0.13.0 - '@saga-a2ui/core': 0.7.6 + '@saga-a2ui/core': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz markdown-it: 15.0.3 zod: 4.6.7 - '@saga-a2ui/core@0.7.6': + '@saga-a2ui/core@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz': dependencies: '@a2ui/web_core': 0.13.0 zod3: zod@3.25.76 - '@saga-a2ui/mcp@0.7.6(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + '@saga-a2ui/mcp@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': dependencies: - '@modelcontextprotocol/client': 2.3.1 - '@modelcontextprotocol/core': 2.3.1 - '@modelcontextprotocol/ext-apps': 2.0.3(@modelcontextprotocol/client@2.3.1)(@modelcontextprotocol/core@2.3.1)(@modelcontextprotocol/server@2.3.1)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7) - '@modelcontextprotocol/server': 2.3.1 - '@saga-a2ui/core': 0.7.6 + '@hono/node-server': 2.1.5(hono@4.13.16) + '@modelcontextprotocol/client': 2.4.0 + '@modelcontextprotocol/core': 2.4.0 + '@modelcontextprotocol/ext-apps': 2.0.3(@modelcontextprotocol/client@2.4.0)(@modelcontextprotocol/core@2.4.0)(@modelcontextprotocol/server@2.4.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7) + '@modelcontextprotocol/hono': 2.0.2(@modelcontextprotocol/server@2.4.0)(hono@4.13.16) + '@modelcontextprotocol/server': 2.4.0 + '@saga-a2ui/core': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz + hono: 4.13.16 zod: 4.6.7 transitivePeerDependencies: - react - react-dom - '@saga-a2ui/react-mcp-stack@0.7.6(@modelcontextprotocol/client@2.3.1)(@modelcontextprotocol/core@2.3.1)(@modelcontextprotocol/server@2.3.1)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + '@saga-a2ui/react-mcp-stack@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz(@modelcontextprotocol/client@2.4.0)(@modelcontextprotocol/core@2.4.0)(@modelcontextprotocol/server@2.4.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': dependencies: - '@modelcontextprotocol/ext-apps': 2.0.3(@modelcontextprotocol/client@2.3.1)(@modelcontextprotocol/core@2.3.1)(@modelcontextprotocol/server@2.3.1)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7) - '@saga-a2ui/components': 0.7.6 - '@saga-a2ui/core': 0.7.6 - '@saga-a2ui/mcp': 0.7.6(react-dom@19.3.1(react@19.3.1))(react@19.3.1) - '@saga-a2ui/react': 0.7.6(@saga-a2ui/components@0.7.6)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@modelcontextprotocol/ext-apps': 2.0.3(@modelcontextprotocol/client@2.4.0)(@modelcontextprotocol/core@2.4.0)(@modelcontextprotocol/server@2.4.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@4.6.7) + '@saga-a2ui/components': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz + '@saga-a2ui/core': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz + '@saga-a2ui/mcp': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@saga-a2ui/react': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz(@saga-a2ui/components@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) react: 19.3.1 react-dom: 19.3.1(react@19.3.1) zod: 4.6.7 @@ -11337,16 +11303,16 @@ snapshots: - '@modelcontextprotocol/core' - '@modelcontextprotocol/server' - '@saga-a2ui/react@0.7.6(@saga-a2ui/components@0.7.6)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + '@saga-a2ui/react@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz(@saga-a2ui/components@file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': dependencies: '@a2ui/react': 0.13.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(zod@3.25.76) '@a2ui/web_core': 0.13.0 - '@saga-a2ui/core': 0.7.6 + '@saga-a2ui/core': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz react: 19.3.1 react-dom: 19.3.1(react@19.3.1) zod: 3.25.76 optionalDependencies: - '@saga-a2ui/components': 0.7.6 + '@saga-a2ui/components': file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz '@selderee/plugin-htmlparser2@0.11.0': dependencies: @@ -12648,18 +12614,18 @@ snapshots: better-auth@1.7.7(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0))(next@15.5.25(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.0)(@types/node@25.9.5)(babel-plugin-react-compiler@1.0.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(pg@8.22.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@4.1.11): dependencies: - '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) - '@better-auth/drizzle-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0)) - '@better-auth/kysely-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(kysely@0.29.5) - '@better-auth/memory-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2) - '@better-auth/mongo-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2) - '@better-auth/prisma-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2) - '@better-auth/telemetry': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2) + '@better-auth/core': 1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2) + '@better-auth/drizzle-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.5.4)(@opentelemetry/api@1.9.1)(@types/pg@8.21.0)(kysely@0.29.5)(pg@8.22.0)) + '@better-auth/kysely-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(kysely@0.29.5) + '@better-auth/memory-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2) + '@better-auth/mongo-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2) + '@better-auth/prisma-adapter': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2) + '@better-auth/telemetry': 1.7.7(@better-auth/core@1.7.7(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.2) '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.2 '@noble/ciphers': 2.3.0 '@noble/hashes': 2.3.0 - better-call: 1.4.0(zod@4.6.5) + better-call: 1.4.0(zod@4.4.3) defu: 6.1.7 jose: 6.2.9 kysely: 0.29.5 @@ -13153,7 +13119,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.4.11: + dompurify@3.4.17: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -13388,9 +13354,9 @@ snapshots: '@typescript-eslint/eslint-plugin': 8.70.1(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/parser': 8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.5(jiti@2.7.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)) eslint-plugin-expo: 1.1.0(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)) eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0)) eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(jiti@2.7.0)) globals: 16.5.0 @@ -13428,6 +13394,21 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.5(jiti@2.7.0) + get-tsconfig: 4.14.1 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.17 + unrs-resolver: 1.12.2 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)) + transitivePeerDependencies: + - supports-color + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)): dependencies: '@nolyfill/is-core-module': 1.0.39 @@ -13454,14 +13435,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.5(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)) transitivePeerDependencies: - supports-color @@ -13503,7 +13484,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13514,7 +13495,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.5(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.70.1(eslint@9.39.5(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -14507,7 +14488,7 @@ snapshots: dependencies: react-is: 16.13.1 - hono@4.13.13: {} + hono@4.13.16: {} hookable@6.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 8a8364a0..e41f11f0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -52,6 +52,18 @@ overrides: # Compatibility: A2UI React 0.13 needs adapter 0.2.1 (0.2.2 requires web_core 0.14). "@a2ui/react@0.13.0>@a2ui/markdown-it": "0.2.1" + # SAGA 1.0 release candidate (apps/mcp), from private tarballs packed from the SDK's source at commit 8b4d987 until + # 1.0.0-rc.1 is on the npm registry. Every sibling resolves from the same set. Replace these with the registry + # version and delete apps/mcp/candidates/ once it is published. + "@saga-a2ui/core": "file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-core-0.0.0-candidate.g8b4d987dd233.tgz" + "@saga-a2ui/components": "file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-components-0.0.0-candidate.g8b4d987dd233.tgz" + "@saga-a2ui/mcp": "file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-mcp-0.0.0-candidate.g8b4d987dd233.tgz" + "@saga-a2ui/react": "file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-0.0.0-candidate.g8b4d987dd233.tgz" + "@saga-a2ui/react-mcp-stack": "file:apps/mcp/candidates/saga-0.0.0-candidate.g8b4d987dd233/saga-a2ui-react-mcp-stack-0.0.0-candidate.g8b4d987dd233.tgz" + # The SDK's documented overrides for its consumers (from `candidate:tarballs`); apps/mcp is their only consumer here. + dompurify: 3.4.17 + "@hono/node-server": 2.1.5 + # Security overrides for transitive Dependabot alerts. # next@15.5 declares optionalDependencies.sharp ^0.34.3 — GHSA-f88m-g3jw-g9cj sharp: ^0.35.0 From ad631fed1f56cd4ebc8098301cdf015d4902c714 Mon Sep 17 00:00:00 2001 From: Younes Abouelnagah Date: Thu, 5 Nov 2026 11:22:27 -0500 Subject: [PATCH 2/5] refactor(mcp): serve /mcp through SAGA's createMcpFetchApp and retire duplicated tests SAGA's fetch app now serves /mcp: Host and Origin admission, body bounds, the request budget, lifetime attachment and the official stateless handler. Ansari keeps only its own routes (/health and the Dev-only diagnostics beacon) and its logs around /mcp. The server factory receives the request lifetime instead of creating its own budget, and the request budget stays the tool's 60 s bound. mcp.error now carries SAGA's fixed failure kind. Tests that only re-checked what SAGA's fetch app tests itself are retired: - request-timer release when a server closes, with or without a transport (the server-close and closed-subscription fixtures); - malformed and oversize body refusals. Ansari's own checks stay: the 60 s budget, the deployment allowlists replacing localhost on both targets, the upstream abort on timeout, and the Node listener's SIGTERM shutdown. The app version is 0.17.0: the card address and SAGA version change. Co-Authored-By: Claude Opus 5.5 --- apps/mcp/README.md | 4 +-- apps/mcp/package.json | 2 +- apps/mcp/src/server/create-server.ts | 16 +++------ apps/mcp/src/server/fetch-app.ts | 30 ++++++++++------ apps/mcp/src/version.ts | 2 +- apps/mcp/test/fixtures/closed-subscription.ts | 35 ------------------- apps/mcp/test/fixtures/server-close.ts | 34 ------------------ apps/mcp/test/lifecycle.test.ts | 22 ++---------- apps/mcp/test/packaging.test.ts | 2 +- apps/mcp/test/parity-cases.ts | 15 +++----- apps/mcp/test/transport.test.ts | 11 +----- 11 files changed, 37 insertions(+), 136 deletions(-) delete mode 100644 apps/mcp/test/fixtures/closed-subscription.ts delete mode 100644 apps/mcp/test/fixtures/server-close.ts diff --git a/apps/mcp/README.md b/apps/mcp/README.md index 841e9901..e1c4e5df 100644 --- a/apps/mcp/README.md +++ b/apps/mcp/README.md @@ -104,7 +104,7 @@ The Worker takes the variables in the table below as Wrangler `vars` or secrets, | `MCP_VIEW_DIAGNOSTICS_ORIGIN` | Set only on a deployment being diagnosed: its own public origin, such as `https://ansari-mcp-development.up.railway.app`. The card may then connect to that one origin and reports its start-up milestones to `POST /diag/view`; this changes the card's bytes, address and permissions. Unset, the card, its address and its closed permissions are unchanged and the route does not exist. A value that is not a bare `https` origin (`http` only for localhost) stops startup. Implies `MCP_LOG_LEVEL=debug`. See [First-load diagnosis](#first-load-diagnosis). | | `MCP_LOG_LEVEL` | `info` (default) or `debug`. `debug` also writes the first-load measurement records; set it only on a deployment being measured. Any other value, or `info` together with `MCP_VIEW_DIAGNOSTICS_ORIGIN`, stops startup. | -`POST /mcp` serves stateless MCP requests through Hono and the official MCP request handler. Modern requests need no initialization; older hosts can use the handler’s stateless compatibility path. No MCP session IDs, session map, expiry timer or replay store are retained. `GET /mcp` and `DELETE /mcp` return 405. `/health` exposes the release. The HTML is supplied by the hosting target (read from `dist/` at Node start, bundled into the Worker), revision-stamped once before the first request is served. The release stamp changes the card's bytes, not its address, which is `ui://views/answer-card.v1.html` for every compatible release. Each request creates its own lightweight MCP server using that prepared view; resource bytes and identity stay fixed until restart. No demo, font server, alternative renderer or historical resource is served. Tool calls have a fresh 60-second budget; timeout yields a safe error and leaves subsequent calls usable. The same lifetime signal aborts the upstream fetch and response-body read when the request ends or the budget expires. +`POST /mcp` serves stateless MCP requests through SAGA's fetch app (`createMcpFetchApp`), which admits by Host and Origin, bounds the body and the request budget, ends each request's lifetime, and runs the official MCP request handler. The application adds only `/health`, the Dev-only diagnostics beacon and its logs around it. Modern requests need no initialization; older hosts can use the handler’s stateless compatibility path. No MCP session IDs, session map, expiry timer or replay store are retained. `GET /mcp` and `DELETE /mcp` return 405. `/health` exposes the release. The HTML is supplied by the hosting target (read from `dist/` at Node start, bundled into the Worker), revision-stamped once before the first request is served. The release stamp changes the card's bytes, not its address, which is `ui://views/answer-card.v1.html` for every compatible release. Each request creates its own lightweight MCP server using that prepared view; resource bytes and identity stay fixed until restart. No demo, font server, alternative renderer or historical resource is served. Tool calls have a fresh 60-second budget; timeout yields a safe error and leaves subsequent calls usable. The same lifetime signal aborts the upstream fetch and response-body read when the request ends or the budget expires. Closing a request server releases its budget even if it was never connected to a transport. On SIGINT or SIGTERM the listener stops accepting requests, closes MCP handlers and HTTP connections, and exits; unfinished calls are interrupted, including older-host SSE calls. Fetch cancellation does not guarantee that the remote backend has stopped processing. Caller-disconnect propagation depends on the host transport; the local Workers runtime does not establish immediate upstream cancellation from a client disconnect. Actual fetch cancellation at the request deadline is covered on both hosting targets. @@ -116,7 +116,7 @@ the host gave up before the card showed anything. The aim is to locate the first the card's start, the host handshake, tool-result arrival and the first rendered answer, where that step can be observed at all. After the trials, this is removed or narrowed to what proved useful. -**Log levels.** Every record carries a `level`. `error`: `mcp.error` and `source.error`, by error name and code only. +**Log levels.** Every record carries a `level`. `error`: `mcp.error` (SAGA's fixed failure `kind` for `/mcp`: `server-factory`, `handler` or `route`; or, for a failure outside it, the error name and code) and `source.error`. `warn`: rejected or rate-limited card reports. `info`: the operational records (`startup`, `mcp.request` with the HTTP method, `source.start`, `source.complete`). `debug`: the measurement records below, written only with `MCP_LOG_LEVEL=debug`. At `info` the server neither inspects nor wraps an exchange, and it writes the records of a diff --git a/apps/mcp/package.json b/apps/mcp/package.json index b1e9726a..7eba2975 100644 --- a/apps/mcp/package.json +++ b/apps/mcp/package.json @@ -1,6 +1,6 @@ { "name": "ansari-mcp", - "version": "0.16.6", + "version": "0.17.0", "private": true, "type": "module", "description": "Ansari's MCP application", diff --git a/apps/mcp/src/server/create-server.ts b/apps/mcp/src/server/create-server.ts index b58e4576..371e1d67 100644 --- a/apps/mcp/src/server/create-server.ts +++ b/apps/mcp/src/server/create-server.ts @@ -1,5 +1,5 @@ import {McpServer} from '@modelcontextprotocol/server'; -import {attachRequestLifetime, createServerBudgets, registerPublicOperation, type OperationView} from '@saga-a2ui/react-mcp-stack/server'; +import {registerPublicOperation, type OperationView, type RequestLifetime} from '@saga-a2ui/react-mcp-stack/server'; import {z} from 'zod'; import type {AnswerCompleter} from './ansari-client.js'; import {writeOperationLog,type OperationLogger} from './operation-log.js'; @@ -11,25 +11,19 @@ import {ANSWER_ENVELOPE_VERSION} from '../view/envelope.js'; // Existing application identity and text, not a new release declaration. export const SERVER_NAME='ansari-mcp'; export const TOOL_UNAVAILABLE_TEXT='Ansari could not complete this request.'; -/** The handler wait the tool declares; the request budget of each call below is the same, never the SDK default. */ +/** The handler wait the tool declares. The fetch app gives each request the same budget, never the SDK default. */ export const HANDLER_BOUND_MS=60_000; export type CreateMcpServerOptions = { completer: AnswerCompleter; view: OperationView; logger: OperationLogger; release?: string; - requestMs?: number; + /** The request's lifetime, from the SDK's fetch app, which also ends it when this server closes. */ + lifetime: RequestLifetime; }; export function createAnsariMcpServer(options:CreateMcpServerOptions):McpServer{ - // Without a context the SDK default 10 s request budget would clamp the declared handler bound below. The request - // budget is the declared bound itself: no new timeout target and no change to the SDK defaults. Each call gets its own. - const budgets=createServerBudgets({requestMs:options.requestMs??HANDLER_BOUND_MS}); - const lifetime=budgets.startRequest(); const server=new McpServer({name:SERVER_NAME,version:APP_VERSION},{capabilities:{tools:{},resources:{}}}); - // The request's timer ends when this server does: on its transport closing, and on close() with or without a transport - // (the handler also disposes a server it never connected). The SDK owns that rule; the application subclasses nothing. - attachRequestLifetime(server,lifetime); registerPublicOperation(server,{ name:'answer_islamic_question', title:'Answer Islamic Question', @@ -59,6 +53,6 @@ export function createAnsariMcpServer(options:CreateMcpServerOptions):McpServer{ return {kind:'record' as const,record:{question,answer}}; }, project:record=>({text:record.answer,data:{version:ANSWER_ENVELOPE_VERSION,question:record.question,answer:record.answer}}), - },{lifetime}); + },{lifetime:options.lifetime}); return server; } diff --git a/apps/mcp/src/server/fetch-app.ts b/apps/mcp/src/server/fetch-app.ts index 8b82aa64..07aeb45b 100644 --- a/apps/mcp/src/server/fetch-app.ts +++ b/apps/mcp/src/server/fetch-app.ts @@ -1,8 +1,8 @@ -import {hostHeaderValidation, originValidation} from '@modelcontextprotocol/hono'; -import {createMcpHandler} from '@modelcontextprotocol/server'; +import {hostHeaderValidation} from '@modelcontextprotocol/hono'; +import {createMcpFetchApp} from '@saga-a2ui/react-mcp-stack/server/http'; import {Hono} from 'hono'; import type {AnswerCompleter} from './ansari-client.js'; -import {createAnsariMcpServer} from './create-server.js'; +import {HANDLER_BOUND_MS, createAnsariMcpServer} from './create-server.js'; import {errorIdentity, inspectRequest, observeResponse, readBounded} from './exchange-log.js'; import {VIEW_DIAGNOSTICS_PATH, prepareAnswerView} from './view-artifact.js'; import {MAX_VIEW_REPORT_BYTES, VIEW_REPORTS_PER_MINUTE, originHost, parseViewReport} from './view-report.js'; @@ -23,6 +23,7 @@ export type FetchAppOptions = { allowedOrigins: string[]; enableJsonResponse: boolean; logger: OperationLogger; + /** Each request's budget, from admission. Defaults to the tool's declared handler bound. */ requestMs?: number; /** Dev-only: the public origin a diagnostic card reports its milestones to (see `VIEW_DIAGNOSTICS_PATH`). */ viewDiagnosticsOrigin?: string; @@ -35,7 +36,11 @@ export type FetchApp = { close: () => Promise; }; -/** One Hono application over the official stateless MCP handler. Hosting adapters only supply a listener or an entry point. */ +/** + * The SDK's fetch app serves `/mcp`: Host and Origin admission, body bounds, the request budget and lifetime, and the + * official stateless handler. Around it, this application adds only its own routes (`/health`, and the Dev-only + * diagnostics beacon) and its logs. Hosting adapters only supply a listener or an entry point. + */ export function createFetchApp(options: FetchAppOptions): FetchApp { const {completer, logger, release} = options; // Measuring adds `debug` records and inspects each exchange; otherwise the exchange is passed straight through. @@ -45,16 +50,19 @@ export function createFetchApp(options: FetchAppOptions): FetchApp { }; // The view is prepared once: release stamping first, then the resource identity from the final bytes. const view = prepareAnswerView(options.html, release, options.viewDiagnosticsOrigin); - // The official handler owns per-request transports, protocol negotiation and cleanup. // Both modern MCP and its older-host fallback are stateless; only the prepared view is shared. - const mcp = createMcpHandler( - () => createAnsariMcpServer({completer, view, logger, release, requestMs: options.requestMs}), - {responseMode: options.enableJsonResponse ? 'json' : 'sse', onerror: (error: unknown) => log({level: 'error', event: 'mcp.error', ...errorIdentity(error)})}, - ); + const mcp = createMcpFetchApp({ + createServer: lifetime => createAnsariMcpServer({completer, view, logger, release, lifetime}), + allowedHosts: options.allowedHosts, + allowedOrigins: options.allowedOrigins, + path: MCP_PATH, + responseMode: options.enableJsonResponse ? 'json' : 'sse', + // The request budget is the tool's declared bound, not the SDK's 10 s default, which would cut a long answer short. + budgets: {requestMs: options.requestMs ?? HANDLER_BOUND_MS}, + onFailure: kind => log({level: 'error', event: 'mcp.error', kind}), + }); const app = new Hono(); app.get('/health', c => c.json({ok: true, mcp: MCP_PATH, release})); - app.use(MCP_PATH, hostHeaderValidation(options.allowedHosts)); - app.use(MCP_PATH, originValidation(options.allowedOrigins)); // The exact card this instance serves: a diagnostic card differs from the closed one in bytes, address and permissions. log({level: 'debug', event: 'view.prepared', at: Date.now(), uri: view.uri, bytes: new TextEncoder().encode(view.html).byteLength, diagnostics: options.viewDiagnosticsOrigin !== undefined, connectDomains: view.csp.connectDomains.join(',')}); app.all(MCP_PATH, async c => { diff --git a/apps/mcp/src/version.ts b/apps/mcp/src/version.ts index 291bf61a..253591dc 100644 --- a/apps/mcp/src/version.ts +++ b/apps/mcp/src/version.ts @@ -1,2 +1,2 @@ // One application identity, shared by the server and built view. -export const APP_VERSION = '0.16.6'; +export const APP_VERSION = '0.17.0'; diff --git a/apps/mcp/test/fixtures/closed-subscription.ts b/apps/mcp/test/fixtures/closed-subscription.ts deleted file mode 100644 index 89300139..00000000 --- a/apps/mcp/test/fixtures/closed-subscription.ts +++ /dev/null @@ -1,35 +0,0 @@ -import assert from 'node:assert/strict'; -import {request} from 'node:http'; -import {listen} from '../../src/node/http-server.ts'; - -// This modern path disposes its MCP server before connecting a transport. -// With no live HTTP sockets, the process must also release the request timer. -const service = await listen({ - host:'127.0.0.1', port:0, html:'synthetic', - logger:()=>{}, completer:{async complete(){throw new Error('not a tool call');}}, -}); -try { - const body = JSON.stringify({jsonrpc:'2.0',id:1,method:'subscriptions/listen',params:{ - notifications:{},_meta:{ - 'io.modelcontextprotocol/protocolVersion':'2026-07-28', - 'io.modelcontextprotocol/clientInfo':{name:'cleanup-test',version:'1'}, - 'io.modelcontextprotocol/clientCapabilities':{}, - }, - }}); - const response = await new Promise((resolve,reject)=>{ - const req = request(`http://127.0.0.1:${service.port}/mcp`,{ - method:'POST',agent:false,headers:{ - 'content-type':'application/json',accept:'application/json, text/event-stream', - 'MCP-Protocol-Version':'2026-07-28','Mcp-Method':'subscriptions/listen', - }, - },res=>{ - assert.equal(res.statusCode,200); - let text='';res.setEncoding('utf8');res.on('data',chunk=>text+=chunk); - res.on('end',()=>resolve(text));res.on('error',reject); - }); - req.on('error',reject);req.end(body); - }); - assert.match(response,/notifications\/subscriptions\/acknowledged/); - assert.match(response,/"resultType":"complete"/); -} finally {await service.close();} -console.log('exchange and listener closed'); diff --git a/apps/mcp/test/fixtures/server-close.ts b/apps/mcp/test/fixtures/server-close.ts deleted file mode 100644 index 4c71fb75..00000000 --- a/apps/mcp/test/fixtures/server-close.ts +++ /dev/null @@ -1,34 +0,0 @@ -import assert from 'node:assert/strict'; -import {createAnsariMcpServer} from '../../src/server/create-server.ts'; - -// Each factory call builds its own server and request lifetime. Whatever way a server ends, its request -// timer must be released, or this process stays alive until the 60 s request budget: the parent test -// gives it a few seconds to exit on its own. -const make = () => createAnsariMcpServer({ - completer: {async complete() { throw new Error('not a tool call'); }}, - view: {uri: 'ui://views/answer-card.00000000000000000000000000000000.html', title: 'synthetic', html: '', csp: {connectDomains: [], resourceDomains: [], frameDomains: [], baseUriDomains: []}}, - logger: () => {}, -}); -type Closing = {start(): Promise; send(): Promise; close(): Promise; onclose?: () => void}; -const transport = (closeError?: Error): Closing => { - const t: Closing = {async start() {}, async send() {}, async close() { t.onclose?.(); if (closeError) throw closeError; }}; - return t; -}; - -// 1. Disposed before any transport was connected, then closed again: the repeated close is harmless. -const unconnected = make(); -await unconnected.close(); -await unconnected.close(); - -// 2. Connected, then closed through its transport and again through the server. -const connected = make(); -await connected.connect(transport() as never); -await connected.close(); -await connected.close(); - -// 3. Closing fails: the lifetime still ends and the failure is the caller's to see. -const failing = make(); -await failing.connect(transport(new Error('transport close failed')) as never); -await assert.rejects(failing.close(), /transport close failed/); - -console.log('servers closed'); diff --git a/apps/mcp/test/lifecycle.test.ts b/apps/mcp/test/lifecycle.test.ts index ec33e0af..cce5184d 100644 --- a/apps/mcp/test/lifecycle.test.ts +++ b/apps/mcp/test/lifecycle.test.ts @@ -1,20 +1,13 @@ import assert from 'node:assert/strict'; -import {execFile,spawn} from 'node:child_process'; +import {spawn} from 'node:child_process'; import {once} from 'node:events'; import {createServer} from 'node:http'; import {createInterface} from 'node:readline'; import {fileURLToPath} from 'node:url'; import {test} from 'node:test'; -test('a completed subscription exchange releases timers even when its MCP server was never connected',async()=>{ - const fixture=fileURLToPath(new URL('./fixtures/closed-subscription.ts',import.meta.url)); - const result=await new Promise<{error:Error|null;stdout:string;stderr:string}>(resolve=>{ - execFile(process.execPath,['--import','tsx',fixture],{timeout:2500},(error,stdout,stderr)=>resolve({error,stdout,stderr})); - }); - assert.match(result.stdout,/exchange and listener closed/,'the HTTP exchange itself must finish'); - assert.equal(result.error,null,`a disposed request still keeps the process alive: ${result.error?.message}\n${result.stderr}`); -}); - +// Request lifetimes (a server closed with or without a transport, a request that ends before a server exists) are the +// SDK fetch app's and are tested there. This file keeps the Node listener's own signal shutdown. for(const modern of [true,false]) test(`SIGTERM exits with an in-flight ${modern?'modern':'older-host'} SSE tool request`,async()=>{ let started!:()=>void; const sourceStarted=new Promise(resolve=>{started=resolve;}); @@ -61,12 +54,3 @@ for(const modern of [true,false]) test(`SIGTERM exits with an in-flight ${modern const stopped=new Promise(resolve=>upstream.close(()=>resolve()));upstream.closeAllConnections();await stopped; } }); - -test('every way a per-request MCP server ends releases its request timer',async()=>{ - const fixture=fileURLToPath(new URL('./fixtures/server-close.ts',import.meta.url)); - const result=await new Promise<{error:Error|null;stdout:string;stderr:string}>(resolve=>{ - execFile(process.execPath,['--import','tsx',fixture],{timeout:2500},(error,stdout,stderr)=>resolve({error,stdout,stderr})); - }); - assert.match(result.stdout,/servers closed/,result.stderr); - assert.equal(result.error,null,`a closed server still keeps the process alive: ${result.error?.message}\n${result.stderr}`); -}); diff --git a/apps/mcp/test/packaging.test.ts b/apps/mcp/test/packaging.test.ts index bfa0e0b3..23c94b4b 100644 --- a/apps/mcp/test/packaging.test.ts +++ b/apps/mcp/test/packaging.test.ts @@ -136,7 +136,7 @@ test('production code imports SAGA only through the one stack, and the browser b const sources=(dir:string):string[]=>readdirSync(join(root,dir),{withFileTypes:true}).flatMap(entry=>entry.isDirectory()?sources(`${dir}/${entry.name}`):/\.(?:ts|tsx)$/.test(entry.name)?[`${dir}/${entry.name}`]:[]); for(const file of [...sources('src'),'scripts/build.ts']) { const imported=[...readFileSync(join(root,file),'utf8').matchAll(/from\s+'(@saga-a2ui\/[^']+)'/g)].map(match=>match[1]); - for(const specifier of imported) assert.match(specifier,/^@saga-a2ui\/react-mcp-stack(?:\/(?:faithful-card|faithful-card\.css|content-policy|server))?$/,`${file} imports ${specifier}`); + for(const specifier of imported) assert.match(specifier,/^@saga-a2ui\/react-mcp-stack(?:\/(?:faithful-card|faithful-card\.css|content-policy|server|server\/http))?$/,`${file} imports ${specifier}`); if(file.startsWith('src/view/')) assert.ok(!imported.some(specifier=>specifier.endsWith('/server')),`${file} (browser graph) imports no server entry`); } const html=readFileSync(join(root,'dist/view.html'),'utf8'); diff --git a/apps/mcp/test/parity-cases.ts b/apps/mcp/test/parity-cases.ts index 1550f0e5..c77aaf06 100644 --- a/apps/mcp/test/parity-cases.ts +++ b/apps/mcp/test/parity-cases.ts @@ -180,8 +180,10 @@ export function defineParityCases(kind: RuntimeKind): void { }); }); - describe(`${kind} ${mode}: Host and Origin checks, body bounds and requested progress`, () => { - it('rejects an untrusted Host or Origin and a malformed body before calling Ansari, and accepts a configured Origin', async () => { + // The SDK's fetch app owns Host/Origin admission and body bounds and tests them itself; these check that each built + // target applies Ansari's configured lists. + describe(`${kind} ${mode}: Ansari's Host and Origin settings and requested progress`, () => { + it('rejects a Host or Origin outside Ansari\'s settings before calling Ansari, and accepts a configured Origin', async () => { const origin = runtime().origin; const before = upstream.seen.length; const params = {name: 'answer_islamic_question', arguments: {question: 'guarded'}}; @@ -191,8 +193,6 @@ export function defineParityCases(kind: RuntimeKind): void { }); assert.equal(hostStatus, 403); assert.equal((await post(origin, 'tools/call', params, {headers: {origin: 'https://other.example'}})).status, 403); - const malformed = await fetch(`${origin}/mcp`, {method: 'POST', headers: {'content-type': 'application/json', accept: 'application/json, text/event-stream'}, body: '{'}); - assert.equal(malformed.status, 400); assert.equal(upstream.seen.length, before, 'no rejected request reached Ansari'); assert.equal((await post(origin, 'tools/call', params, {headers: {origin: 'http://localhost:1234'}})).status, 403, 'configured origins do not inherit localhost'); assert.equal(upstream.seen.length, before); @@ -203,13 +203,6 @@ export function defineParityCases(kind: RuntimeKind): void { } }); - for (const modern of [true, false]) it(`${modern ? 'modern' : 'older-host'} refuses a body over the SDK limit before calling Ansari`, async () => { - const before = upstream.seen.length; - const response = await post(runtime().origin, 'tools/call', {name: 'answer_islamic_question', arguments: {question: 'x'.repeat(4 * 1024 * 1024)}}, {modern}); - assert.equal(response.status, 413); - assert.match(await response.text(), /Payload Too Large/); - assert.equal(upstream.seen.length, before); - }); it('delivers the answer, and sends progress only when requested and only over SSE', async () => { const origin = runtime().origin; diff --git a/apps/mcp/test/transport.test.ts b/apps/mcp/test/transport.test.ts index 916760c3..be703e8b 100644 --- a/apps/mcp/test/transport.test.ts +++ b/apps/mcp/test/transport.test.ts @@ -153,13 +153,4 @@ for(const json of [false,true]) test(`modern ${json?'JSON':'SSE'} delivers the a } finally {await service.close();} }); -for(const modern of [true,false]) test(`${modern?'modern':'older-host'} refuses a body over the SDK limit before calling Ansari`,async()=>{ - let calls=0; - const service=await listen({host:'127.0.0.1',port:0,html:'bounded body',logger:()=>{},completer:{async complete(){calls++;return answer;}}}); - try { - const response=await postRpc(service.port,'tools/call',{name:'answer_islamic_question',arguments:{question:'x'.repeat(4*1024*1024)}},{},modern); - assert.equal(response.status,413); - assert.match(await response.text(),/Payload Too Large/); - assert.equal(calls,0); - } finally {await service.close();} -}); +// Body bounds are the SDK fetch app's and are tested there. From 4fb0ae17be120ff06b3c04c4cd2f3c9c760bb9d9 Mon Sep 17 00:00:00 2001 From: Younes Abouelnagah Date: Thu, 5 Nov 2026 11:23:58 -0500 Subject: [PATCH 3/5] test(mcp): expect the compatibility-line card address in the container smoke check Co-Authored-By: Claude Opus 5.5 --- apps/mcp/scripts/docker-smoke.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mcp/scripts/docker-smoke.mjs b/apps/mcp/scripts/docker-smoke.mjs index 00d1965e..e9c40375 100644 --- a/apps/mcp/scripts/docker-smoke.mjs +++ b/apps/mcp/scripts/docker-smoke.mjs @@ -1,6 +1,5 @@ // Run through docker exec: the container has no external network or mounted files. import assert from 'node:assert/strict'; -import {createHash} from 'node:crypto'; import {createServer} from 'node:http'; import {setTimeout as delay} from 'node:timers/promises'; const answer='3. Synthetic complete answer\n 1. Nested item\n\nالإجابة العربية\n\n*Answered by [Ansari](https://askansari.ai).*\n'; @@ -47,7 +46,8 @@ try { assert.deepEqual(result.content,[{type:'text',text:answer}]); assert.equal(result._meta.ui.resourceUri,uri); const resource=await rpc('resources/read',{uri});const html=resource.contents[0].text; - assert.equal(uri,`ui://views/answer-card.${createHash('sha256').update(html).digest('hex').slice(0,32)}.html`); + // The address names the card's compatibility line; the release stamp is in the bytes. + assert.equal(uri,'ui://views/answer-card.v1.html'); assert.ok(html.includes('ci-public-smoke')); assert.ok(!html.includes('version https://git-lfs.github.com/spec/v1')); const failure=await rpc('tools/call',{name:'answer_islamic_question',arguments:{question:'fail'}}); From 1121cb6b95c05ba4385911ca0604afaa1ba344ff Mon Sep 17 00:00:00 2001 From: Younes Abouelnagah Date: Thu, 5 Nov 2026 11:33:03 -0500 Subject: [PATCH 4/5] docs(mcp): describe the card address as its compatibility line in fetch-app comments Co-Authored-By: Claude Opus 5.5 --- apps/mcp/src/server/fetch-app.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mcp/src/server/fetch-app.ts b/apps/mcp/src/server/fetch-app.ts index 07aeb45b..c2252bd0 100644 --- a/apps/mcp/src/server/fetch-app.ts +++ b/apps/mcp/src/server/fetch-app.ts @@ -48,7 +48,7 @@ export function createFetchApp(options: FetchAppOptions): FetchApp { const log = (record: OperationRecord) => { if (record.level !== 'debug' || measuring) writeOperationLog(record, logger, release); }; - // The view is prepared once: release stamping first, then the resource identity from the final bytes. + // The view is prepared once, release-stamped, at its compatibility-line address. const view = prepareAnswerView(options.html, release, options.viewDiagnosticsOrigin); // Both modern MCP and its older-host fallback are stateless; only the prepared view is shared. const mcp = createMcpFetchApp({ @@ -63,7 +63,7 @@ export function createFetchApp(options: FetchAppOptions): FetchApp { }); const app = new Hono(); app.get('/health', c => c.json({ok: true, mcp: MCP_PATH, release})); - // The exact card this instance serves: a diagnostic card differs from the closed one in bytes, address and permissions. + // The exact card this instance serves: a diagnostic card differs from the closed one in bytes and permissions, not address. log({level: 'debug', event: 'view.prepared', at: Date.now(), uri: view.uri, bytes: new TextEncoder().encode(view.html).byteLength, diagnostics: options.viewDiagnosticsOrigin !== undefined, connectDomains: view.csp.connectDomains.join(',')}); app.all(MCP_PATH, async c => { log({level: 'info', event: 'mcp.request', method: c.req.method}); From 21cc90761acbc542d56c6660f358b527aa18695a Mon Sep 17 00:00:00 2001 From: Younes Abouelnagah Date: Thu, 5 Nov 2026 11:33:03 -0500 Subject: [PATCH 5/5] docs(mcp): update the walkthrough for the SAGA 1.0 candidate and the v1 card address The walkthrough now describes: - the SAGA 1.0 candidate install; - the card at ui://views/answer-card.v1.html; - /mcp served through SAGA's createMcpFetchApp; - app 0.17.0. Its embedded sources match the code at the commit SOURCE_BASE names. Co-Authored-By: Claude Opus 5.5 --- apps/mcp/docs/show-me-ansari-mcp.html | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/apps/mcp/docs/show-me-ansari-mcp.html b/apps/mcp/docs/show-me-ansari-mcp.html index 3799d81b..13b7e95d 100644 --- a/apps/mcp/docs/show-me-ansari-mcp.html +++ b/apps/mcp/docs/show-me-ansari-mcp.html @@ -42,19 +42,21 @@ @media(max-width:900px){.tabs{grid-template-columns:repeat(3,1fr)}.responsibility,.lifecards{grid-template-columns:1fr 1fr}.journey{grid-template-columns:220px 1fr}} @media(max-width:600px){.tabs{grid-template-columns:repeat(2,1fr);gap:7px}.tabs button{min-height:46px}.top{flex-wrap:wrap}.theme{margin-left:auto}.top .titleblock{order:2;width:100%}.top>.mark{width:46px}.journey{grid-template-columns:1fr}.minirow,.scopegrid,.responsibility,.lifecards,.sourceindex{grid-template-columns:1fr}.questionbar img{width:48px;height:48px}.steps{grid-template-columns:1fr 1fr}.step{font-size:12px;padding:8px;min-height:44px}.detailgrid{grid-template-columns:1fr}.groupbuttons{grid-template-columns:1fr 1fr}.map{grid-template-columns:1fr}.map>.arrow{display:none}.map>.mapbox:nth-child(5){grid-column:auto}.mapbox{margin-bottom:7px}.runtime-counter{min-width:0}.runtime-counter strong{font-size:23px}.source-exact{line-height:1.6}header,main,footer{padding-left:18px;padding-right:18px}pre{font-size:11px}.detail{padding:18px}} .whycards{grid-template-columns:repeat(3,1fr)}@media(max-width:850px){.whycards{grid-template-columns:1fr}}@media(min-width:951px){.tabs{grid-template-columns:repeat(7,minmax(0,1fr))}} -
Ansari floral artwork
A source-guided, interactive walkthrough

Ansari MCP

From a question in a conversation to a complete, attributed answer in a branded card. Explore the whole application: its data flow, rendering contract, hosting boundaries and release lifecycle.

React FaithfulCardSAGA 0.7.6Hono · stateless MCPNode + Cloudflare WorkersOffline walkthrough · no live API calls
+
Ansari floral artwork
A source-guided, interactive walkthrough

Ansari MCP

From a question in a conversation to a complete, attributed answer in a branded card. Explore the whole application: its data flow, rendering contract, hosting boundaries and release lifecycle.

React FaithfulCardSAGA 1.0 candidateHono · stateless MCPNode + Cloudflare WorkersOffline walkthrough · no live API calls
Choose a chapter. Each is a view of the complete application.

One question, end to end

The answer service owns the answer. Ansari owns the application. The SAGA stack connects that meaning to an MCP card.

HostAnsari appSAGA stackAnsari API
HostConversationDiscovers, invokes and displays
→
Ansari appHono + MCP operationDeclares the input, answer envelope and view
↔
Ansari APIComplete answerReturns text and attribution unchanged
→
SAGA stackFaithfulCardRenders inside the host’s card surface
- - -