JetBrains Plugin Developer Conf 2025 ![rw-book-cover](https://img.youtube.com/vi/0D3sYiT2Ca0/maxresdefault.jpg) ## Metadata - Author: [[YouTube]] - Full Title: JetBrains Plugin Developer Conf 2025 - Category: #articles - Document Tags: [[video-notes]] [[youtube]] - Summary: JetBrains Plugin Developer Conf 2025 - URL: https://www.youtube.com/watch?v=0D3sYiT2Ca0 Heat. Heat. Heat. Heat. Heat. Heat. Welcome to the JetBrains Plug-in Developer Conference 2025. We are really happy to have you here uh from all around around the world. um during the conference uh that Jet Brains has organized to bring more knowledge about uh creating plugins for Jet Brains ids and making our whole ecosystem better. During this conference, uh we are going to um discuss basics of plug-in developments but um also dive into uh more advanced uh setup and uh share some additional stories around that. Um so everything related to plug-in development. Uh my name is Yakobski. I'm a developer advocate at Jet Brains responsible for uh platform advocacy and together with me is uh my colleague Patrick Shaver. >> Hi everyone, morning >> welcome. Uh yeah so basically uh we are going to run um round six 7ish uh long conference with a small break uh in between. Um we will run some raffles so please stay with us uh because um between talks obviously not during them uh we'll ask questions uh for you um we have around 12 questions um ABCD so it's easier than last year because this is the the second uh conference uh we're running like that and yeah we will start with keynote talks. >> So before that right we do some housekeeping. So hello everyone. So you will have a chat and if you have any questions about um the talks um or the contents of the talks just type them a chat. We have lots of folks behind the scenes that uh will take of take care of them uh and note them. So and we will answer every question after the talk. Um additionally keep it polite in chat. Have fun. Say hi. Say who you are. Say what you're doing. Right. Enjoy the company of each other. Um we will record the whole event here and we will uh share the recording after that. And as mentioned already uh we'll have a raffle. We will do them in between the talks and um we'll give away some swag and hoodies and stuff. Um so I think that's all. Uh I go back to Jacob and then we start with the first session. Okay, thank you. Um, just for the record, um, here is the link to agenda. Um, yeah, it's already posted. Uh, yeah, and we are starting with uh three keynote talks. Please welcome Ian and Robert uh who will um do those talks together with us. Uh yeah, Patrick, could you introduce our folks? >> Yeah, I can introduce ours. So, you already uh saw Jacob who is the team lead and the advocacy. I'm Patrick. I'm also working at Vocacy. Robert is as well in um platform advocacy at Jet Brains and Ivan is um I think uh from the marketplace, right? >> Yeah. So, um, and Jacob, Robert, and I will have the first three talks. And I think without further ado, we can jump right in. Right, Jacob? You ready? >> Yeah. Yeah, we are ready. Ian, are you ready? >> Yeah, I'm ready to go. Hey, welcome again to Jet Brains Plug-in Developer Conference 2025. Yeah. Uh my name is Ivan and I've joined Jet Brains in 2010 and contributed to different teams including business application development and idea ultimate. I've joined the marketplace team in its early stage in 2016 and took uh major took part in major transformations including launching of PL paid plugins. That's mean one slide. Now let's uh jump to what actually matters the ecosystem. Here's 2025 in numbers. We continue to welcome new plug-in authors to the marketplace. We now crossed 10,000 authors who have published at least one plug-in. And we had a notable uptick over the past year. This year we also have seen significant number of new plugins. The marketplace now hosts over 11,000 plugins. That's an incredible amount of work from you. Thank you folks. Together those plugins reach more than 3 million unique downloads every months. Talking about the downloads, here are more specific numbers for some plugins that are already making money. Let's take a quick look at them. But you're familiar with some of those names. Overall, in 2025, paid plugins have seen total revenue increase of 13% compared to to 2024 and 12% increase in the number of licenses sold. Note that we've excluded plugins that became free this year from this comparison to keep it meaningful. I'd like to remind that plugins matter to Jet Brains products. Our products are rich out of the box, but plugins cover the long tail frameworks, languages, themes, and localization while marketplace keeps the pass from idea to install short. So, how did we keep that pass short this year? 2025's updates, the changes that went live for authors and users. Staying on the topic of paid plugins, this year we've introduced a couple of long- aaited features for them. Perpetual license support, a one-time payment for a lifetime access to a plug-in, but please note that only one paid license option is still uh available at the same time, either recurring or perpetual. Many of you decided to introduce a separate often called lifetime version of your plug-in to overcome this restriction. We also introduced an option to cancel continuity discounts. It still continues to apply to licenses purchased before the cancellation date and it is disabled by default for the new plugins. Earlier we asked vendors to indicate whether they are trader or non-trader. This year to stay compliant we introduced trader verification. It adds a bit of friction for authors but it gives end users more trust uh providing clear verified vendor details and it keeps the marketplace aligned with regulations. Alongside we've updated our digital services act processes. If something on a plug-in page looks inappropriate or harmful, users can report it directly. We try reports with a predictable review flow and share outcomes in our transparency summary. We handled 670 reports in 2024 and over 1,000 in 2025 25. Thanks to our support team for handling the edit compliance workload smoothly. We've improved work with the reviews. Sometimes plug-in received low scores because of some problems that have been fixed in later versions. Previously, the only option was to remove such re such reviews as inappropriate and many believed that was not the right way to process them because it hided them. You can now mark plug-in reviews as resolved if they address issues that have been already fixed in current versions of your plug-in. Once marked and approved by marketplace team, the review stays visible but no longer affects your plug-in rating. Also, since the beginning of this year, you also have access to the detailed reviews of your plug-in features. Some users share their views about integration with IDE, performance, features, UI, or documentation of your plug-in. And you can see this on the review tab. We care a lot about plug-in quality, and we are always looking for the ways to better check plugins. Last year we received enthusiastic response to plug-in testing performance UI and functional testing session at Jet Brains plug-in developer conference. We introduced extensive documentation about plug-in testing strategies and we also introduced automated check for the uploaded plugins. It results in a ID run with a plug-in installed and we check that no major issues happen during this run. Another aspect of plug-in verifi verifications is the plug-in verifier tool that many of you know and that Robert will talk extensively later. The platform team is actively working on plug-in model to improve plug-in loading performance and improve and improve dependencies man management. Unfortunately, sometimes plug-in verifier lags behind those changes which leads to not so useful verification results. Also, some plugins use specific code that is hard to properly support in plug-in verifier which results in false positives. That's why we introduced option to ignore errors on marketplace side. This makes verification results more reliable and allows us to proceed with them before the corresponding fixes arrive to the plug-in verifier. Please bear in mind that we don't ignore problems on requests but only after thorough investigation. We spent a big part of this year working on introduction of automations and horistics to shorten response time for approval requests. Plug-in authors receive quickly replies when we detect problems with our automated checks. both plug-in verifier or the newly introduced IDE integration UI test that I mentioned earlier. All of this helps for authors to get a response faster so that they can fix their plug-in and uh proceed with the upload. Also, it helped us improve uh significantly improve average plug-in approval time. And now it's less than an hour for a new plug-in version update. And some of you not only noticed that, but also shared this with us. All those improvements in verifications and approval processes also allow us to work better with different aspects of verification results. To make platform API stable, we'll continue work to eliminate internal API usages using uh our uh newly introduced abilities to work better with the verification results and have less false positives. detected for your plugins. Another thing that those changes simplified for us is active work with verification results against upcoming idea releases which helps us uh detect that some problems with the new release uh would be would be faced earlier. and notify authors or in cases when the plug-in is abundant and rarely updated. It helps us uh to limit its until build and uh not uh provide it further to the end users so that they don't have problems in their IDE. useful resources about marketplace changes uh our platform, our blog about the platform and also our documentation at uh the marketplace. Thank you for attention and I give to Jakob. Okay, thank you very much Ivan. Um the next uh short talk uh will be about uh a I hope well-known IntelligJ platform gradal plug-in. The the name is pretty long but we made it longer um with the 2.0 release last year um to avoid confusion u with the actual gradal plugin uh gradal support plug-in in ID. Um long story short uh it didn't work but uh the longer name is with us um and it's but but it better reflects the actual state. So today I'm going to talk about uh changes uh we have done in 2025 and uh there were a lot of them. Um but first uh what is intelligent platform gradal plug-in as we explain uh its definition already. This is a plug-in for the gradal build system um which you use uh for creating plugins uh for Jet Brains IDEs. Yeah, a lot of plugins names. Um the current version is 2.10.4 uh released on November the 2nd. So three days ago. Yeah, we are busy with that. And as you can see, we have around 500 commits uh pushed this year. uh mostly about uh related to to performance enhancements because working with the intelligent platform which is pretty huge one to two GB uh requires some optimizations and uh changes to align the changes in the platform itself to make your life easier. Uh that's why we try to improve developer experience here. And uh something that is coming this month actually uh unified intelligj idea um 2025.3 which means unified intelligj platform as well. All right. Um and during this uh presentation we will cover this single intellig idea distribution um some dependency helpers uh that were introduced during the year to make your development faster more rel reliable and so um custom caching this is this is really something I'm I'm excited about uh isolated custom test test task class path this is boring but and annoying but we we we have to uh tell you what changed don't make you surprised and problems API to make problems more visible because everyone has problems yeah intelligent idea unified distribution um this is um probably you know uh we were publishing for many many years um intellig G idea ultimate and community editions. Those were two separated builds. Uh one for free users uh limited uh set of features and the ultimate uh was fully fledged IDE with support for um all languages almost uh almost all languages uh we could support and frameworks etc. So that was this um one big idea to rule everything with the 2025.3 um release cycle. Uh we are no longer going to distribute uh intelligent community. So IC code. Um therefore if you want to target this uh intellig intellig idea uh for plug-in development um to make your plug-in available to all IDE that we we have in uh including Android Studio which is Google's um you're supposed to use a shortened version uh of the helper which is IntelligJ I idea uh instead of Intelligj Idea community or intelligent idea ultimate if you are using the product code uh do not use IC anymore because it's not there since this version but IU will remain working uh because this new distribution also use the same IU code name same happened already uh for PyCharm so starting with 2025.1 um PyCharm community and professional distributions uh were merged and same uh PC so PyCharm community uh will no longer be distributed uh from now on starting with 2025.3 and you PyCharm professional pi y uh this u this code will uh remain the same in the unified distribution. So again, PyCharm helper instead of PyCharm community or PyCharm professional. Okay. Uh but what's the difference for end users? Well, the unified IDE uh will be available for free um with a possible um with a possibility to um pay for more features. So there is still some basic functionalities provided with in this in unified um IDE but if you have a paid subscription um paid for yourself or uh through uh company license or um well academic university you'll get all the features and how to distinguish if user is using this or that version. Well, now you build just one plug-in and uh while depending on the com intellig modules ultimate module. Um this plug-in will not be loaded in a free um free instance. Um so it is also wise to use uh optional dependencies um like depends on uh to to enable some features if you are providing some premium uh plug-in. More about uh the unified distribution um of intellig idea in PyCharm you can read uh in a blog post I published on Monday. And yeah, here is uh the yeah here is uh the QR code QR code and link. Um so basically this is uh probably the second first uh article in the JetBrings platform category on our blog. And that's about unified distributions. Let's let's dive into uh more technical details. um compatible plug-in resolution. Um yeah, this is one of helpers uh that were introduced during the year. Uh dependency helper. What does that mean? Um well in gradal you are defining uh a dependencies block um where you put dependencies on external libraries and within this block we have also uh this uh sub block let's say intelligj platform which contain contains dependency helpers. So that's that's the name we use. Um so um one of those dependencies helper introduced this year is compatible plug-in um and it is similar to plug-in uh which is used when you set a dependency on a plug-in from marketplace. It's not a bundle plug-in but plug-in on marketplace JR marketplace. Um, but when using the plug-in helper, you're supposed to use plug-in ID and exact version you are requesting. with compatible plug-in. It's no longer necessary uh because under the hood it is checking which uh intelligent platform you using you are using for building uh the project and it requests marketplace API to get the latest available plug-in matching um your build uh number and um intellig platform type obviously. Um, so this is a a great um feature to to kind of make the process of development a bit easier. However, you're supposed to remember it is requesting the latest available plug-in which is not um it's not a fixed version. So on your CI if someone updates their plug-in you will get the latest version and something may be broken still. So your build will not be fully reproducible um in time and but yeah that that's a trade-off. Another um dependency helpers uh that we've introduced are exclude cotlin std lip and exclude corines. those helper are excluding cotton acid lip and cordines. Um why we have created that as uh additional um helpers? Well, to avoid situations like um you when building your plug-in are depending on uh something from Maven Central for example that is also depending that is that also has a transitive dependency on cotlin coroutines for example but intelligent idea intelligent platform in general so all our um ideas are already providing you with uh cotling cordins and uh cotling sdip. Therefore um bringing them uh with your plug-in is first redundant. Second, it is creating a way bigger build that you are publishing to marketplace and people have to download and we are talking about well bigger numbers here um megabytes not gigabytes for but still and uh in context of um corines things may simply get broken because um when running your plug-in in um IDE runtime. So as end user it is requesting some library but you are providing the same library from different in different version or even the same version but it's in different class and well we can end up with some clashes and um weird exceptions in the in the users um console users logs. Yeah, that's that would be three uh new things that we have introduced in terms of uh dependency helpers. And here is also something use in dependencies block and I'm really happy uh that we managed to introduce this one. It is intelligent platform artifact custom cache. Well, why custom cache? Well, the reason is really um simple for that. When you are depending on some dependencies uh from Maven central or our intelligent maven repositories, they are cached by gradal the integr. So, it's downloaded um put in the gradal directory in your um users home home directory. But um in terms of Intelligj platform artifacts, the thing is a bit more complex because we are not downloading jars uh from repository but um zip archives for example zip tz or dmg for Mac OS. Um so they are downloaded by gradal um to your local cache and then we are involving gradal transformers to extract them to another cache directory still within gradal um boundaries. Unfortunately, Gradle is running extractors uh transformers, I'm sorry. um pretty often. It's not visible when you work with dependencies of regular libraries which are one two megabytes but one two gigabytes makes the difference and gradal reuns this extractor transformer for you if for example your build setup is changed and and yeah this this is pretty annoying because gradal cache can go pretty fast. Um unfort unfortunately we weren't able to um optimize that in any reasonable way and this is why uh the use cache uh was introduced here. Uh so when defining a dependency on IntellJ IDE uh you can open the um closure and type use cache equals true. And on the screenshot uh you can see that the intellig ultimate um intellig unified uh was extracted to intellig platform IDE directory and this is the default default location. Next to to this default approach we can uh still configure um the the the caching behavior. So um using the top level intelligent platform extension so below dependencies you can uh open caching ids um blocks and define exact path where you want to store those extracted ids. Uh so if you work on multiple projects it's better to uh use refer to your home directory for example. you can enable it by default. So uh not only the main uh build configuration will rely on this cache but also all custom tasks uh like run ID, test ID, uh plug-in verifier will reuse the same location, the same cache and the name parameter well this is this is obvious by default it's just type version um but in terms of EP releases which are changing in in time you can um define some additional naming rule for this directory. So, EAP cache will be I don't will be uh invalidated daily, weekly, monthly, it's up to you. Yeah. And uh one last thing about uh dependencies block is model module dependencies refactoring. Um this is a breaking change. Um unfortunately uh yeah fortunately uh we figure out that um the plug-in module version two which is not publicly announced and not documented yet but it is still there. We are using heavily um this mechanism has some rules and those rules um should be uh soon default. Uh that's why the plug-in module um dependency was renamed to something secondary called plug-in compost module and the plug-in module is the new um new feature. Um but what's that? If you are working on multiodule project uh so you have some core you have some dependencies uh shared module uh if you are releasing um if you if your uh plug-in is created in a way that you have um this module for PHP storm this for uh some other dependency this is already multimodel product and uh those are supposed to be composed um into one um one jar. Uh that's why compost you should use the plug-in compost module. Um the plug-in module um this is something we will announce um next year hopefully and document it, share with you and run more content materials about it. Yeah. Uh another pretty important change um we've spotted uh during the year uh that if you create your plug-in setup based on specific version um like 2025.2 um for building the plugin. So it is still available for 2025.3 and up. Um it had a glitch uh where if creating custom tasks like uh custom test ID task or custom run ID task um the class path from the build setup was passed further uh to the custom tasks as it is. uh in um accept the the all the IntelligJ uh platform path. So eventually okay when building the plug-in uh the class path of um your project uh is composed of intelligent platform dependency but also bundled plugins uh you are defining you are declaring you want to use uh for development um external plugins test framework etc etc and because this class path was passed as is uh still to custom tasks uh replacing just the intellig platform. So eventually the the test custom IDE task was composed of intelligj platform 2025.3 but also bundled plug-in from 2025.2. um the issues were annoying and pretty serious. So as a result uh of this change uh I'm talking about we are no longer uh in the custom uh test ID run ID tasks we are no longer passing this the whole setup uh from the base setup to um custom class path. So when defining defining this test custom ID you have only um custom intelligent platform available. Uh so to get everything working um you're supposed to have the again define bundle plugins plugins test framework etc etc. So for now um you will have to build uh this dependency set um again um I hope with the next maybe 3.0 So release uh we will uh face um some improvements in that matter uh like uh what was the name um testing suits u from gradal if that will be stable stable enough uh we'll start um refactoring um all all the setups uh into that direction. Yes. And I was talking about problems we are trying to avoid. And here is a bit about problems we don't want to avoid but uh highlight to you. So whenever you run verify plug-in task or verify plug-in project configuration which is run for you um automatically um those tasks are reporting issues uh in logs like you are using outdated uh intg platform grade plug-in or uh your Java version is not correct uh comparing to the platform you're using um or some issues with uh since build many possible issues are um here possible uh but they are uh locked in plain text in in the console only. uh this year uh during the Google summer of code uh our contributor um improved this situation uh so now we are integrating with problems API uh from gradal still it's not um it is pretty incubating feature um but we are already trying to integrate integrated with it and pass um not only issues um like single line issues uh to Gradal AP problems API but also solutions, links to documentation and more valuable information about uh the problems themselves. Um so this is now enabled by default and to get um to see this generated by gradal report uh look in your logs uh for problems report. Uh there will be a working local um link to local file where you can uh insight all the issues uh that Gly reported and the small feature also released actually last week and this is uh just useful for uh debugging. Uh so when you run verify plug-in uh you can use this uh list ID is switch it will not run uh verify plug-in verifier itself but uh it will resolve all dependencies and show which versions will be used for running verifications and exact paths of of those. Yeah but so I'm preventing from running plifier. Sorry, Robert. Um, yeah, useful links, three links. Uh, first one is, uh, JetBrains platform forum. If you don't know it, uh, this is the place we are gathering together to discuss, um, plug-in issues, uh, new features, uh, sharing knowledge. So, this is a place to be. GitHub repository. Uh so github.com/jadbain/integlatform grading plugin you can uh search there for uh new releases or uh contribute I hope and yeah documentation of this particular project and the long the link is uh pretty short jb.gg GG EJPG. So, intelligent platform gradal plug-in docs. Thank you. Now, I would like to pass the sage to Robert. >> Thank you, Akub. That has been a huge list of contributions. I'm Robert, developer advocate and a part-time maintainer of the Intelligj plug-in verifier. What is the purpose of the intellig plug-in verifier? If I am a plug-in author, basically I might have two questions. Will Jet brand marketplace approve my plug-in? And the second question is will the plug-in run correctly in the target users IDE? The plug-in verifier is a another tool in the puzzle of Intelligj platform gradu plug-in jet brands marketplace and intelligj SDK. It makes sure that the plug-in descriptor is correct. That means if the mandatory values in the plug-in XML are put in place, if the particular required values uh within the ranges are correct, if the since build and probably until built are properly composed and many other semantic and syntactic information is checked. Furthermore and more importantly, it checks whether the IntelliJ platform API in the target ID is accessible and available. Since the IntelliJ platform SDK is constantly evolving, some methods might be introduced, some methods might be deprecated, some methods might be marked as scheduled for removal and uh some functionality in the API landscape might become internal or experimental. So, plug-in verifier checks all of the things and when everything is checked, we as a plug-in authors might uh probably have seen uh such report as this one. This is the report from the JetBrand marketplace for JWT plug-in. And we can see that this plug-in in version 0.19 is not very compatible with the IntelliJ Idea Ultimate 2025.1.1 because there are two compatibility problems and one usage of scheduled for removal API. On the other hand, in the bottom, we see that this plug-in is fully compatible with 2024.2.6. 6 which is quite an old version of ID now but the plug-in works there. This report as I have said is produced by the plug-in verifier. So my job as a plug-in author is to investigate those reports and try to address them because plug-in verifier on the Jet brand marketplace is a mandatory quality gate. Severe compatibility problems will prevent upload of the plug-in. Uh we are constantly reviewing uh all new uploads of plug-in versions and whenever we see that plug-in might might be problematic. Uh it in the worst case scenario it might be even unlisted. One way how to check the plug-in uh is to upload it to the Jabbrand marketplace, wait for the verification report and investigate that in the browser. However, this might take quite a long time and uh therefore the better solution would be to run the plug-in verifier locally or within the CI/CD. This is one approach. However, uh even in the Jet Brains marketplace, the verification can be triggered and rerun uh manually. Uh as I have said there are two options either to run it in the Jetrain marketplace but this might be complicated because it might involve uh plug-in version upload waiting for our infrastructure to run the actual verifications and wait for the reports for the local development. The better option definitely which I would heartfully recommend is to integrate with the intellig platform grab a plug-in and to run the verification locally or as an alternative uh the plug-in verifier is available as a standalone CLI tool that can be executed from the command line. So feel free to choose either one option integration with the intelligent platform gradu plug-in or the standalone CLI tool run. Uh as I have said I strongly recommend to integrate this option because it saves the round trip to the jetream marketplace and there is a better control when running this locally. uh the intelligent platform gradual plug-in uh integration is uh quite straightforward because uh Yakub uh is providing multiple uh extensions in this landscape. So this is the minimalistic but fully working scenario when the plug-in built by Gredle on top of the IntelliJ platform Gradle plug-in will run the verification against set of recommended idees and all of the verifications will be run locally and reports will be will be also saved into the local file system as the set of HTML ML files. uh I won't be going uh too much into the depth of verification process because in May 2025 so few months ago we published a high level overview webinar plug-in verifier and API compatibility maintenance which shows the full scope of the tooling and uh I fully recommend uh going over this because it shows exact scenarios of verification uh cases about integration with the IntelligJ platform Grego plug-in and uh also integration with the JetBrains marketplace. Intelligj plug-in verifier is open source. It is public. So it is available on GitHub. uh contributions are welcome uh because there is a huge amount of work to be done uh and plug-in verifier is deeply integrated with uh Jet Brains marketplace and intelligent platform Redwood plug-in. Whenever a new functionality is proposed, uh we sit with the Jet Brains marketplace team and we sit with the intelligent platform grad plug-in team and we coordinate uh our approaches. So the plug-in verifier which can be run locally uh is usually the same version that is running on JR marketplace. Currently uh the version is 1.397 uh which was released uh in October 28 and there is one more version being uploaded uh any day now there is a quite an activity in this project so it is not uh that at all however in the last two months the major report was uh devoted to the internals because the IDE distribution layout has dramatically changed. This doesn't impact uh plug-in development much. However, this uh required many improvements behind the scenes and uh under the bonnet of the plug-in verifier. Uh we aim to support the V2 plug-in model as Yakub uh uh has mentioned. Uh this is currently in the works and it is slowly being documented to be used uh for the plug-in developers. We use that extensively uh in the IntelliJ ID layout already. Uh but we had to adapt plug-in verifier to support that. Uh there were many performance improvements and there are many more on the road map because we are aware of the few issues that should be fixed especially with the performance on the windows and most importantly uh currently we are going through the list of false positives because there are lots of false positives now and trying to see what can be uh implemented in the upcoming months. because there were lots of false positives in the dependency check resolutions, some false positives in the API availability in the V2 modules and we try to remove as many of them as possible because they confuse uh everybody. Uh more details and documentations are in the intellig SDK docs. uh I am actively monitoring the jet brains platform forum. So whenever there are any questions in the area of plug-in verifier or integration with the intelligj platform gra the plug-in uh you are heartfully welcome to join the forum and I will be uh replying and handling relevant questions personally and of course as I have said you can join the development at the GitHub opensource repository. Yeah thank you that's all. probably now it's time for a Q&A session. >> You're right. Thank you very much. Uh thank you Robert, thank you and for your talks and yeah as you said let's check if we have any questions about any of our talks. >> I think we got one question but I'm not able to answer it. So um it's from Anuma and the question is how jet brains intellig idea um plugins are deployed for interconnected um cloud shell that can handle AI or ML file type API through its compatible cotlin script function. >> I'm not sure if I understand this question to be fair. >> Me too. I have to say me too. So um maybe Anuman you can clarify a bit. Okay. In the meantime uh we have a new question. Um I feel uh from Mr. Toby. Uh I feel the intelligent gradal platform plugin uh is very slow on Windows. uh building takes much more time when on our CI. Um yeah, any update on this it is slower and the reason for that uh is Windows uh Windows file system. Well, we already notice and we are aware that um working with files on Windows, extracting them, reading files is way slower than on Linux or Mac OS. Um I'm not sure if well from gradal part in in gradal part uh there is not much we can do probably you can um involve caching here uh to avoid re-extracting those intelligent platform archives but in uh so Robert this is this will go um to you >> do you think we can somehow optimize the plug-in verifier which is used internally by gradal plug-in. >> Yeah, that's exactly the question I was uh I've been waiting for from your side. Uh and this was the reason what I mentioned in the plug-in verifier part. uh Intelligj platform gradu plug-in and plug-in verifier share a common library called IntelligJ structure that is used to create a type- safe model of plugins and uh we are aware that this library uh has performance issue on Windows as Jakob said it is connected with the zip parsing and jar extractions uh we are aware of this issue and I'm not giving any promises because the issue is quite complex but we will try to at least broadly address this and improve that. Uh it is on our it is in our on our radar and we are aware of that. >> Okay, maybe we can continue since robot is already talking. So there's a question from Roman. Does the verifier check for any infinity loops in the plug-in? Do we have any information what the infinity loop like? Uh endless loops like while while loops that go infinitely. If this is the case uh then no. uh as a plug-in author I can uh I can introduce a simple plug-in that will create an infinite loop. Plug-in verifier will not check that because plug-in verifier is targeted for the uh invocations of intelligj SDK APIs. However, uh I can imagine that this is the question if my plug-in can hang the IDE. Uh there are other mechanisms internally and externally that uh check for the uh basic performance stuff and try to avoid that. I'd like to add that as I mentioned this year we provided uh integration with the UI tests that we run for every uploaded plugin. So if the plug-in hangs the IDE freezes it uh we would detect it and uh we would not approve such a plugin but again I should mention that it's uh just a simple check. Uh it yeah just runs the plugin uh the ID with the plug-in installed. >> Yes. Uh in the JetBrain marketplace there are already at least two mechanisms to uh verify the plug-in. Uh one is the traditional one with the plug-in verifier. Uh but there is a newly introduced one with the gray IDE bubble next to the verification results. that is handling the integration tests. >> Okay. So, I will go a bit quicker because we got quite some questions. So, does anyone here have a insight into basically uh compos UI for plugins? So, the question is from Andre and it's um are there any official or unofficial milestones for compos UI for plugins? Probably Jacob would know most about that. >> Yeah. Yeah, definitely. Um, yep, that's the question. Yeah. Um, there are some plans, uh, unofficial so far, but, um, we are heading this direction. Uh, in the intellig plug-in, there is already, uh, compose UI helper dependency inter uh, bringing all necessary uh, compose UI dependencies to the game. Um and yes, as for content materials and uh making it public, we are currently internally um creating tests around that uh to make sure everything is working correctly and nothing is missing. Right now something is missing. So we are filling those gaps and as soon as we'll be ready uh we will shout about that because this is really exciting. Okay, next question is from unfortunately I can't read it and I won't butcher the name but the question is um should I declare a dependency to the ultimate module in the plug-in XML when targeting PHP storm or is it uh only about UI uh uh IU or PyCharm? So basically I think it's about the unified. >> Yeah. Uh it's about unified. Well, yeah. First of all, if you want to create plug-in uh for PHP Storm and other ids, you're supposed to use uh unified uh distribution if targeting 2025.3 and up. And yes um depending on this ultimate module mentioned in the presentation um should um make everything clear that user is using paid subscription because this model is supposed to be enabled by default in PHP store PHP storm which is paid right. Yeah. >> Okay. Going to the next question. We still have a minute or two from Yahim. Not sure if this belongs here, but what's the new security verification section in quotes uh for a plug-in update on the marketplace? I think that's maybe something that Ivan can say, right? >> Uh yeah, I'm not sure what uh the Yah is mentioning specifically, but uh we introducing uh internal security checks for the plugins. I can't share the exact details uh exact specifics right now. Uh but this is uh the thing that uh we are actively working on and because this is a very important thing we are distributing uh lots of plugins to millions of users around the world. So we want to be sure that uh the plugins uh are secure. >> Okay. Lovely. I hope that that answers it. Um, so we got another question from Marina, I think. Can you provide examples of syntax in buildg gradal.kts for plugins that support both 2025.2 and 2025.3 using new functions uh like intelligj idea uh and compatible plugins raise errors. >> Uh so yeah, that's for me. Uh so yes I can however not here well in chat that would be pretty um yeah terrible experience. Uh please raise a question uh in our forum I will answer to you verify that first and answer to you right away. >> Lovely platform.jbins.com. >> Yeah. So and I think the last question is uh from Sally. Is there a sample repo uh that includes custom UI windows and code generation? I'm not sure we have that. >> Uh custom UI windows code generation. I'm not sure we have that. >> No. >> Okay, folks. Um >> let's wrap it up, >> right? Let's wrap it up. We're one minute overtime for the first session, so we're pretty good. Uh the next session um will be from uh Dimmitri the Repco and he will have a a talk about from templates to marketplace creating your first uh plug-in. So Dimmitri is a full stack developer for over 10 years and I think he works intensively um on uh PHP storm plugins and intelligj plugins and uh he's a core member of the Yee PHP framework. I had to look up how how to pronounce that and um unfortunately Dimmitri won't be here with us so we show you a recorded thing. If you have questions, put them still in the chat. Uh what we can try to do is basically get the answer from Dimitry and then put it into the recording in post-prouction. That's our secret plan. Um so with that being said, I think we can go ahead and uh start Dimitri's presentation. >> Okay. Thank you, Evan. Thank you. >> Exactly. Thanks everyone else. Uh see you later. Hello everyone. My name is Ditri Dong and usually I speak about PHP because I code in PHP more than 10 years. But a year ago I wanted to craft a plug-in for PHP store to support E3 PHP framework and today I have I have published more than 25 plugins. I remember that days and how it was hard to start. I have prepared a guide for you uh how to create your first plug-in and publish it to the Jet Brains marketplace. So let's get started. The first most important thing is to start from the template. As you can see on your screen, there is a repository which you can fork and use or just push the the this use this template button and create a new repository. There is just one required field repository name which I feel is GR plug-in. Guess what does it mean? After that click the create button down the page. Refresh the page. That's it. This is your first plug-in for intellig idea which probably supports almost all IDE versions. But our journey is just beginning here. As you can see, there is only one commit. But if you refresh the page and open commits, you can see another one which which made by the actions user bot. And don't worry um they just basically clean um all the template repo stuff and rename the template to your project name. That's really convenient. So uh let's go further and clone our repo. Open Intellig Idea and click the clone repository button. Uh choose how you clone the rapper by URL or with connected GitHub account. Uh when the project opens, you will probably see something like this. There is no project files. Um read tab has brown background. Nothing worse. Don't panic. Uh press common and semicolon. Uh keys on Mac OS or similar um shortcuts on Windows and Linux uh or click click on the project structure in the menu or even use double shift shortcut. And finally you open project structure settings. After that you'll notice no SDK uh warning in the SDK field. So click on it and select one. This is recommended to use 21st SDK version if you build new plugins. Fishial documentation recommends to use JR runtime. It has JBR prefix but you can use any If you don't have any of this, click on the download GDK button which is loader list. Next, choose language level as SDK default. Save the changes and then click on this elephant button in your editor to sync uh gradal changes. This floating button indicate that something has changed in your project dependencies and you probably should click there. In case the icon is not available or you want to sync it manually in the side toolbar, you can find the grid open it and this first button in the new toolbar do the same thing. So uh sync the changes, wait a bit while all project dependencies are downloaded and indexed and now you're ready to work. If you use Intellig Idea for the first time, please check if these plugins are installed. If not, find them on the marketplace and install. They totally save your time. Structure. I will briefly describe uh what a typical project looks like. These files you most likely won't ever touch but know they are. Caches, settings, builds, and more. The SRC folder contains all of your plug-in source code including test and some settings. There are test itself and test features under the test data folder. In the resources folder, you can find a file with messages or strings. It's usually it's used to format and translate messages that you show to users. These two files describe your plug-in settings, extensions, features, dependencies. Let's deep dive a bit. In the plug-in.xml, you can find some metadata information about the plug-in. its ID, name, your render name, other plugins used as dependencies, link messages, bundles, and extension points. Um, there also could be declare texts, listeners, services, and more. Grad of properties. This file is used to declare another meta information such as plug-in name, repository URL, plug-in version. Um the difference between this file and the plug-in.xml that uh this file is used to build your plug-in while plugin.xml is used by IDE to extract properties from the plug-in build. There were also uh plugins since build which describe a lower bound of ID version which can install the plug-in. Um platform type and version describe uh which ID uh plug-in will be run on while development. We will back to it in a moment. As you can see on this slide, 243 isn't just magical number. It describes the ID version. This is pretty simple. The platform type is an abbreviation which describe ID platform which which will be installed locally to run your plug-in. IC for idea community, PS for PHP storm and so on. Actually, it defines a platform which can install your plug-in. I recommend using uh Intellig Ultimate if you want wider support for your products. The last file I wanted to mention here is the build.gradal.kts. This file describes how to build your plug-in which depend system download and bundle into the plug-in build. It's like a package song from JavaScript world, but it may way more powerful. Um, there are also scripts to reduce plug-in boiler plate and automate things such as plug-in version and description patching. Um, building a change log file and others. For instance, you may add test dependency there. Uh this is a part of integration testing structure that you can find on the um platform documentation website. A bit more about dependencies in the intellig idea. Almost all features are made by plugins. Some of them from chat drawings, some of them from external contributors like me and you. There are several types of dependencies, platform dependencies and project dependencies. Let's imagine that we want to craft a plug-in to support a PHP framework like me in a year ago. First of all, we need to have the PHP plug-in installed to work with its classes and functions. It's like a shared library. This plug-in is installed on our platform and we can use it directly and to implement some co serialization in our plug-in. We want to use cutlin x serialization package. This is not a shared library. It should be bundled into our plug-in because others may use totally different versions of the same dependency and we don't want to solve this this version help remember this um test implementation calls describe project dependencies. In case of cutlin x seralizer, we should add the grado plugin and source dependency as is described in the cutlin xeralizer documentation. Regarding the platform dependencies, here we can make a choice. The first option is to build our plug-in against um intellig ultimate platform and require a PHP plug-in installed. In this case, we should specify what dependency version we are expecting 2003 200 yeah 2003 44 49 and so on. Another option is to build our plugin against PHP storm platform which has PHP bundled onto the PL platform. No version is required is in this case that um 2003 4449 version is taken from the marketplace. Open the main page. Find the plugin. Open the version tabs and there you can find the version and compatibility range. You cannot use the builds with ids outside the range and yeah plugin ID could be found on the plug-in page right on the bottom of the page. Previously we described which plugins we want to install on our plat development platform and now we can declare how to how our uh plug-in depend on them. You may make these dependencies optional or required and declare all correspondent extensions in a separate file. It's really convenient when you separate uh optional things. For instance, it is metastastorm dependencies. It could work uh with any of installed plugins, PHP, JSON, XML, database. Um but it doesn't require them to be installed. Um but maybe some of them I know it was hard. And you probably face with this dependencies errors from time to time and today we won't use any dependencies. Now let's move on and build our plug-in. Open the gradal panel and find build plug-in script. Run it. Uh when it's done, you can find a zip file with your plug-in inside the build/ distributions folder. You can also change the build name and the project name in the settings.gradal.kts file. Um it may be useful when you want to trim some characters from the original plug-in name. Now our plug-in is ready to be distributed and we can upload it to the Japan's marketplace. Of course, you should create an account there to continue the distribution. After you're done with the reg registration, uh click on your name from the top menu and choose upload plug-in. Choose the file we have built a moment ago. um view license agreement source URL if it's open source it and text which describe your plug-in only a few not all so the form and yeah we did it usually moderation time takes up to two business days but the plug-in page is ready to be used now this is how plug-in developers see There are plugins, add my own admin panels. Uh there are several tabs that you may edit from the website. But um some of fields are filled automatically with the plug-in meta information which is declared in the plug-in.xml file. On the versions tab, you can find all uploaded builds and their statuses. There are also a compatibility table which is under the image. Uh you can also open the plug-in page of your uh public page. Yeah. Of your plug-in. And you may notice this not compatible warning because there is no builds available to be installed because the first build is under review. Uh the most watchful of you may notice that the plugin has a custom icon and description and I will tell you how to change it. Plug description is patch it to the plug-in.xml from this section in the readmi file. Just place your description in markdown for format uh and build scripts will parse and copy paste it to the plug-in.xml XML file when you build the plug-in. This is way uh convenient to keep the description here instead of the original uh plug-in.xml file. Login icons should be stored under the meta dash in order with names plugin icon and plugin icon underscore dark or light and dark modes respectively. The platform uh website also describes what icons uh should look like, their sizes, um colors, formats, um folders, and names. There are also colors for light and dark mode. You can use your own colors for sure. Um, these are just convenient examples that look good. Discover idea icon on the website you see on the slide or craft an SVG by yourself. I have chosen the target icon, downloaded it and place it in my project. Oh, features. We want to code features. We need features. There are a lot of features that idea platform provides. Some of them are good described, some of them not described at all, some already deprecated. But the best recommendation from my side is to go through this custom language guide. Do every step there. clone and run examples from the GitHub and read all the information on this website from the beginning. Unfortunately, we won't touch features today. But uh you can find some of them in the repositories under the J plugins organization on the GitHub. There are more than two dozen plugins available for free which you can contribute into or use as a reference. So we're finishing here. I hope it was helpful. I'm open to your questions via telegram or email. Wish you green builds and panda moderation. See you next time. Lovely. So, thanks Dimmitri. A virtual heart goes out to you. Um, right. So, we already posted the the guide from uh from Dimmitri and um so this session was basically because of the several requests from last year that we should have a very introductory thing where we show how to build from templates and um get basically going with the first plug-in. Right. So since we don't have an official Q&A, we can basically now continue with the raffle that we forgot uh after our last session. So what we have is basically a raffle where we ask questions in chat and the first one to answer will get um a bag of things from us. So uh we can share later what's in there. The question is, do you want a hard question first or or a not so hard one for the introductory? So, >> let's make it hard. >> Let's make it hard. Right. So, is everyone ready? Easy. Chris says easy. So, is everyone ready? Because basically, we post the question and the first one to answer will get the raffle back. >> Yeah. We also um next to the question uh suggest answers. So there are four possible answers. Well, one is correct only. So you can either um type the full answer or the number. So just to make things easier. >> So let's make it on a count of five. So I count backwards. Jacob, you ready? >> Yeah, I'm ready. >> So five, four, three, two, one, and go. >> Okay. So the question is which of the following shows the correct spelling of the company's name that develops intelligj I idea we have many okay >> so Jacob what is the correct answer >> for sure it's not Jed Brazin and Jed Brian >> Jed Bryan Yeah. Uh, it's J brains. So, the correct answer is two, >> right? With a capital B. So, >> yes. And no typos. >> And no typos. So, if you think, "Oh god, I missed that." Uh, don't bother. You're not the first one. We have a lot of these things um internally. That's why we made that the first question. So, let me scroll up. I think the first one who typed is Andre. No, no, no. Mr. Toby, am I right? No. Ah, no. I need to go up. I'm sorry. Pelco was the first one who typed. >> Yes. Yes. Yes. This is what I see in YouTube because we will use YouTube as a reference to chat. >> Pelco, what we want you and everyone else who wins to do is to reach out to marketplace. We will um post the email address shortly and so we can sync all uh the things where we have to basically send you the gift. So since we didn't have a raffle question last session, we can do another one. Now you know how that how it works. Next question. >> Okay, the next question. >> The next question. Okay, we do it again on the uh on the count of five. Is that okay? Are you ready, Jacob? >> I am. >> All right. >> Always. >> So, okay. On the count of five. So, we go five, four, 3, two, one, and go. >> Okay, let's show it. >> Mhm. >> So, the question is, what is the current version of the intelligent platform gradal plugin? Is it 210.2, 210.3, 210.4 or 210.5? Okay, looking at answers, I'm already confused because I don't remember if I I've released something yesterday evening or not because the the actual version I I know about is 2.10.4, four which will make the question number answer number three correct and I think it is Marco please confirm yeah I think um so option three I see first um I see Marco first >> yeah congratulations >> congratulations That's fun. All right, we still we still have some time left to our next session. Um, we prepared for that. Uh, Jacob, should I ask you a question? >> Oh my god, I'm not prepared for that. Yeah, go on. >> You You are You are because it's >> Am I? Okay. >> It's live. So, I want to know how did you first get into plug-in development uh and become part of the intelligent platform team? Uh yeah, I don't I I do remember. Yeah, I was working as a PHP developer. Uh yes, because I'm a former web developer. Thanks for asking, by the way. That remains pretty nice things to me. Um so yeah I was a PHP developer working in a basement literally because uh our office building had a basement where they put all developers >> all the PHP de all the PHP developers down there >> all three developers that was not IT company but we were um working on um yeah backend stuff for them and WordPress extensions etc. Uh, and that was my very first contact with Japanese IDs and that was like 15 years ago or something probably. Yes. Um, so yeah, we had PHP Storm um installed on our machines and we were working on WordPress extensions. Terrible experience. Uh but we managed that and so yeah you are about to use git ignore there obviously to exclude some environment variables. >> Git ignore is your is your plugin >> and yeah uh >> is it the first one >> that that was the very first uh plugin I've created. So yeah because of this needs I've created extension for Japanese ids uh called idea git ignore org ignore later or ignore later because name was changing over time. Um so yeah it was highlighting the syntax of g ignore files and then and npm ignore docker ignore everything that was eventually requested because it's still all about the same syntax and the same features. Um and then someone suggested to um help with generating such git ignore files uh by utilizing some opensource listings of git ignore templates. So there was git ignore.io website uh with uh github repos public github repository. It's it's down right now I believe or not I don't know. uh and obviously GitHubs uh templates. Um so yeah, I was in the build time I was u fetching all those repositories into the plug-in. Uh so they were distributed in a fixed version but yeah no internet connection was required and nice UI etc. So yeah, turned out that was a really requested feature later and really useful and I hit millions of downloads. That was crazy. >> Yeah. >> Um Yeah. Uh then uh half a year six months before joining Jet Brains um um J Misha Ving reached out to me. He's he was involved in marketplace before but not anymore. Uh sadly uh yeah he he pinged me that uh they JetB wants to purchase this plug-in open source plug-in. That was weird. >> U because IntelligJ idea was supposed to consume some features of my plug-in and to make uh the situation nice to to both sides. um they made me this offer. So I I was really tired of supporting it and I was take it even for free. But yeah uh we made the deal. >> Mhm. >> And three months later uh Jet Brains reached out to me again uh offering a position at Jet Brains as a developer advocate. So again uh I was web developer knowing almost nothing about JVM and yeah here this American dream >> I started well I jo I said okay let's do it I had only experience with Slack overflow some open source projects um supporting plug-in developers to some degree on Slack um yeah we don't use Slack anymore for that um yeah but it clicked and I'm always almost for six years here. Uh yeah, time flies. This is this is really crazy. >> Yeah. >> I think I think the the um >> one one more thing this plugin is again with me. >> Yeah. Yeah, I know. I know. So I think I think basically the thing that um just starting out trying something very simple and then you get the big wall of the million lines of code of the intellig platform right and have to deal with this. I mean I think that's uh one experience most of us um went through no matter um how small your plug-in is. So I see that um Alexandre is already with us. Shall we bring him to the stage and have a quick chat? Yeah. >> Hi, Alexandra. >> Hi, everyone. >> How are you? >> Good. How are you doing? >> Well, great. Busy as you can see. It's all great really. >> Uh, yeah. So, maybe yeah, please tell something about about us about yourself. >> Yeah, I have the slide in my presentation, but I I can start right now. So my name is Alexander and I'm working as a front end engineer at Evil Martians. It's consultant agency. Yeah. So where I work with a lot of stuff and sometimes with different languages. So that was a thing that lead me to create a plug-in for Lu language which I'll be talking today about. >> Yeah. So I see that you worked in bioinformatics. So you have a background in bioinformatics. >> Yes. I have a master degree in biology and then some binformatics over education. >> Yeah, that's lovely because um basically when I studied uh and then did my PhD, I was sitting exactly in the in our department in Leipic, Germany um with the bioinformatics team. >> Um that's nice. >> Yeah. Yeah, that's nice. So they did all um a lot of stuff around um around uh RNA and mRNA and they used all these nice tools with which were written in pearl uh incredibly horrible scripts that no one could ever read. Okay. So I see you feel me. It's it's the >> bioat that that's still the case. I would say more because my wife is doing a PhD now at the same university. So typic university >> with binformatics. So she's working with this RNA. Mhm. And the tools are still >> ugly. Yeah, >> they're not in Pearl anymore. They're mostly Python now, but still, >> yeah, they were they were in Pearl and used all the command line hacks like or and set and all these tools to uh go through the sequencing stuff and do all the alignments and things they were doing. Great. Actually, that's that's nice. Yeah, I I don't know anything about that really. And I tried pearl, but it's like my cats join me on my desk and start typing. >> I mean, since we have some time, >> right? I mean, we could we could deviate a bit here and just say, so basically, it's just string manipulation because um what you have in the sequences and DNA and and RNAs, right? It's just strings and not even very um complicated strings. It's only I don't know four letters. How many do we have? >> Yeah, it depends mostly four like in RNA for in RNA there are more but yeah. >> Yeah. So and you try to find structures and you try to align two of these strings and they are massive and they were massive 10 20 years ago right where we had really where did where we did not have the compute power that we have right now. So I guess the ch the field is changing. Yeah, now it's much better. But still, if you have to assemble genomes of some weird organisms like the crusted science like the small crabs and stuff, let's call them like that. Yeah, they may have a lot of repetitions in their genome and assembly could still take weeks and months. >> Yeah. To run through. So, Alexandra, so how did you make the transition from basically Pearl and all the stuff to Java and Cotlin? How did that >> Yeah, I was working as a bionformatician with pipelines and all this stuff and then we had also the small software department at my previous job place. >> So yeah and and then like I I may I did all the I completed all the tasks I had as a bionformatician and then I asked like could I maybe join software development stuff and then I worked a bit of spring boot a bit of front end. So it was kind of fullstack experience and then I started learning cotlin. So it was the time when the cotlin was f first version. So I visited like the first meetups in St. Petersburg connected with cotlin release >> and I was choosing between cotlin and go and I chose cotlin and I'm happy about it. >> Lovely. That's that's great. So and and when did you and when did you wrote write your first plug-in? I think it was 2017 or something I think it yeah around that time when I was a binatician I was working with pipeline language CWL and it's like a YAML based language but it has a lot of specific stuff and I was it was hard working with the Justin sublime it's like similar to snakem make that has support in PyCharm but there was no support for CWL so >> I tried to make a plug-in to do this and I like it worked but then it was hard to support it and I didn't have time so it's just there. >> Did Did we already have Gradle back then in 2017 Jacob? >> No >> because I started with Maven with some horrible Maven >> I think so there were no plug-in repository like the template there were less documentation. Yeah. So that was much harder than now. >> Yeah. when I started I was using intelligent platform as this uh well in this JPS um based build >> and and did you so I remember that I I had a very big and very complex Maven build file that I could run on Travis CI and uh so it's one of the things you don't want to touch and you're just glad that it runs right so um did you did you have CI Jacob back then back in the day >> back in the Yeah, Travis Travis and then GitHub actions. >> Mhm. >> Uh but yeah, who who would bother about CI? >> Yeah, >> those days, right? >> Uh yeah, but I jumped uh to Gradal plug. What was the name? Intelligj Gradel plugin. That was the initial name. uh still I I started exploring that uh with this 0.3 or 4 release. >> Mhm. >> Uh and yeah, it it was already something. So I I kind of have this background and I'm I didn't move smoothly to this graduate system. I I was still exploring other open source projects. So I was copy pasting uh stuff from others. then adjusted that then others started copying that from me and yeah that was ping pong for years. >> Mhm. Right. So today uh Alexander you will be talking about um LSP versus the joy of learning. So I guess it's basically the big contrast of using a language server right in contrast to okay I really need to hack a paser and a lexer and do all the integration. Yeah, >> exactly. >> I'm really looking forward to that. I think we can start. Oh, we got a couple of seconds left. We don't have to, right? Um, give the stage to you, Alexandra. Have fun. And >> thank you already. >> Thank you. So, yeah, I I've already presented myself. So we'll be talking today about an experience of developing a language plug-in and how it feels when you are using language server instead of a native intelligj support. So couple words about me just to reiterate. So I was biologist in Birmutician in the past and then I switched to front- end engineering and now I'm working at consultant agency and sometimes we need to work with different technologies and I stumbled upon a language that's called LU that's like derivation of Lua with types which didn't have any support in Intelligj. Yeah. And given that I like IntelligJ idea and all other ideas and I hate VS Code, I was like thinking that it would be easier to write a plug-in than to make my piece of VS code. So I decided to do that. And let's start with the answering the question, do people still create new languages? Because you may think that I just stumbled upon a language no one uses and then nowadays you don't need to do that. But actually it's not exactly like that because there like we're not creating that many languages nowadays. So it was only like 29 new languages since 2010 and free languages since 20120s. That was Gleim modu for AI stuff and carbon that's the letter C on the slide. It's not C language it's a carbon. Yeah but also language support is not limited by the language itself. It's also frameworks and stuff around them. So frameworks still emerge and on the front end every day I guess. So we have things to work with languages and create plugins for. So you can see that there are 293 programming language plugins now on the marketplace. So what ID gives us I think like everyone on this talk accepts that ID is better than no ID like working with just sublime. We only have the highlight. So ids gives us uh clever completions which you can rate and do some AI stuff nowadays. We have inline hints. We have a lot of clever documentation. We have quick fixes and different sophisticated things like this one. So for example, we can check if the documentation is in sync with the code. So the code here is returning list of strings and the documentation says that it's an array. So we can check that with some like language models I think and then provide some diagnostics. So how intellig native support looks like? I dig up some from web archive some 2008 jet brains documentation and actually it looks almost the same. So like the set of features that was supported is the same except for the inline inlay hints that are the most recent edition and how much code does it take. So I was while working on my plug-in I was using a lot of plugins like as a reference to see how the things are done and I was mostly using these five and they are not that big actually like under 50 case of lines of code and unless you're working on Rust and Rust is a big programming language with a lot of stuff to do so it's quite manageable I would say to create a native support but Then there are other IDs as well. So for example, we have new ids like helix, we have zed and we have the old older ones. We have the most famous escape room for programmers that steam. We have neim and stuff like that. And so we don't want to write the plug-in for every single ID out there. So there should be a solution to it. So and there is a solution. There is an language server protocol created by Microsoft back in the days when they were releasing VS Code. I think around 2016 or something. Yeah. And this protocol grew to kind of a common protocol for language support and other IDs as well. So the idea behind it, it's that simple. We have a client which is integrated into ID and we have a server that's shared for all the like that we can use the same server for all the ids. Yeah. And server is doing all the heavy lifting and client is just like showing the results that server pro provides. So the idea sounds great. So let's then ask answer a question. How hard is it to how hard it is to build a plug-in using the language server? Now, of course, taking as granted that the language server already exists for your language. So, two two years ago, Jet Brains added native support for LSPs and now creating plug-in using LSP is very easy. So the first thing you have to do is to inherit the LSP server support provider and then it will the main method that has this file open that will be called on every file being open as the name suggests and then you just check do you want to start the server the LSP server for your file or not and then we can just check the extension for example if we are supporting the language and then we start the server using the descriptor that we also also have to provide and this descriptor mostly says like this the common line we should create and start the server with and there is also one more thing to check the do we want to track the file content in editor and sync it with the language server or we're fine with just using the version on the disk so given all this 50 lines of code we've got our LSP working but not exactly because after we are Doing that we get almost white document with some powerful letters but yeah it still looks quite bland. So actually this is specific of my LSP server because it doesn't provide a lot of semantic highlighting but there is another specification that can help us here. There's a text made grammar and if you have a language server for your language you most likely have text mate as well and we can bundle text made grammar with our plug-in with like five more lines of code and then we'll have the full highlight the semantic one and the usual one regx paste. So that's good. So under the 100 lines of code we did all the work. So we have LSP working, we have autocomp completion, we have I know all the documentation, all the pop-ups, all the quick fixes and like isn't life is kind of sad when we are writing only 100 lines of code. Every software developer wants to write more and learn something new. And actually we are not living in a fairy tale. So this is only the start because we have several questions to address as well. So the first one and the obvious one is the LSP server distribution. So what I did uh when implementing the descriptor is just running the bundled server and it's bundled only for my platform. So I'm on Windows so it's only for Windows but there are some people using MacBooks and I heard that it's finally year of Linux on the desktop again. So we need more binaries and then our plug-in size will be bigger. So for example like 15 megabytes for my LSP and it's I would say it's not not ideal and then also plug-in releases will be tied to the language server releases because if something new is out then you have to update your plug-in and it can be like every week and then still marketplace reviews could be fast but it's not ideal to do them every week I think and also if the new LSP version is back some somehow then you'll be like the users will have a hard time to switching back to the older version of the plug-in because most likely they will have to go to a marketplace page and then download the older version. So there is a better solution. Let the user decide it's not that UX friendly but at least we provide some possibilities. So user can just choose any binary on their system and the like the most ideal solution in my opinion is implementing some kind of auto download. So you download the LSP binary for the platform which you can get with the uh thej APIs and then use it. So I ended up doing both. So I have the auto download system which downloads latest by default and then you can still choose another version if you prefer it or if there are some bugs that prevent you from working happily and if you need for some corner cases of for some testing you can still provide the binary manually as well. So that's the first problem we solved. It took me around 500 of lines to do this. And we we also had to learn corines along the way. So that's funny. And I also had to manage a lot of other file downloads for my language because it needs some definitions to work properly. So that's why it took so much. But then before then before that moment we were treating LSP like as a black box. So we we didn't try to see what's inside. But from time to time you get some bugs both in LSP and maybe in the LSP support. So you need to debug them and to debug them you need to understand how the LSP works. And the LSP is quite simple. It's a JSON RPC protocol with two types of messages. So we have requests which requires a response and we have notifications. Both of these messages could be initiated by server and the client. So request can be sent from client and request can be sent from a server. And the message structure is also straightforward. So it's we have basic JSON RPC fields here. We have method to say to the server which action do we want to do now? And then we have params and we also have ID and ID is used to find the response for the request because they of course send all asynchronously and can come up in different order. So to match them we use ids and one day LSP started stopped working in my ID and I spent some time debugging and the reason turned out to be simple. This ID can actually be both number and a string. So LSP protocol allows both. But LSP offer was doing some internal refactoring and since the LSP offer only works on VS code, uh they ignored that the ID could be a string and IntelligJ uses strings. So the plug-in was broken for a week unless I have this fancy version like fancy mechanism to choose a version. So I just switch to the older version of the LSP for the time being. So then to fix this bugs like this, you don't need to write anything, but you still get to read some C++ code if your language server is written with that. So that's interesting. And then also as always introducing one more layer in your architecture increases the amount of work you have to do while debugging. So bugs are everywhere. They can be both in LSP, both in your implementation and both in ID support for like in client in LSP client. So one day I was happily updating my webtorm to 2025.1.1 and all the errors were gone from my projects. Like while it's good to have no errors, there was something wrong definitely. So it took me a couple of hours to find the reason and along the way I learned more about the protocol. Yeah. And like small note as a biologist the spiders are not bugs actually. So they are from a separate group. So the to learn to debug this issue about diagnostics I had to learn about them. So there are two types of diagnostics in LSP protocol. There are publish diagnostics. The older one they are notification based. So the server sends a notification with diagnostics like with all the problems like type issues and other issues as well when it feels like it. So you don't have any control and that's the problem because you can have an open file and the LSP server can try to analyze the rest of the project instead. And there is a new model newer model that's pull diagnostics. It's request based. So the client requests diagnostics for the specific file or the specific set of files and then gets them. And so if there are older and newer versions uh of some stuff and there are different features in LSP, there should be definitely a way for both server and client to communicate which versions do they support and there is one version. So when you start the LSP, the client sends an initialized request to the language server listing all the capabilities it supports. So like does it support hover popups? Does it support semantic highlighting? Does it support diagnostic like older diagnostic, newer diagnostic and stuff like that and then server also responses with the capabilities it has and can provide. And after client receives the server response, it also after some time sends initialized notification to say that yeah, I'm completely done with digesting all that you sent to me and we're happy and can start working. So in the 2025.04.1 zero for.1 there was a new feature the support for pull diagnostics but it it's not turned on by default but the configuration for the initialization has changed so there was added just two lines so we support diagnostic and it can be dynamically registered and seeing these two lines my language server decided that oh okay so the client can support pullbased so we will just turn off the pushbased the older one and ID didn't have P version the newer one on so like ID is doing nothing server is doing nothing they're all happy except for me so I have to fix this the simplest fix is just this two line would just change the capabilities and rewrite them to be as they were before the update the better I the better fix would of course be turning them off if we can turning them on if we can, but it will since I support several versions before the diagnostics were introduced. I'll have to do some fancy reflexing to use a class that's not existing in some older binaries. So I just decided to turn it off for now and starts working with it when we update to 2025.1 as like the baseline. So yeah, the fix for this problem was one line more code, but you read a lot of C++ stuff and a bit of LSP spec and LSP spec is quite big I would say. So to debug all these problems, we also have to know where the logs live. So to turn on the LSP logs, you need to provide this like debug handler in debug lock settings. And then if you are using if you are running your plug-in in the older versions of ID then the logs will be in the main log like they will be just among other logs ID does and if it's you are on the if if you are on the newer version then you have separate file per lsp in language services folder and you can find this folder where all actions pallet so you can just click show login explorer and see them there and also this change to diagnostic may raise a question. So like if there are some changes you are not aware about how you can know about them. So of course the best source is LSP sources. So you can download them and look for them. There are still some issues with the download sources button regarding LSP in ID. So there is an issue mentioned on the slide. So there are some ways to overcome this. Then the next place would be UTRA. You can set up a filter for core LSP features and then you'll see all this stuff happening with LSP when the support was added and what will be supported and maybe some future plans because usually all the issues are well documented. And of course there is a Jet Brains platform already mentioned where you can ask other people or Jet Brains what's happening. Okay. And finishing on the initialization part. Uh if you want to show the this pretty language services pop up with the version of your language service protocol also handles that. And there is a special field in initialize result. The server sends the server info which you can populate and use to display the version automatically. But it's not implemented in OSPs because usually VS code ignores that. So you have to contribute that if you need. So yeah, it's 10 lines of C++ code as well and CMake. So it's not the funniest thing to do. Okay, talking about all that we have a vague idea I guess that there are different features supported by LSP. But how many features are there in general? We have quite a lot actually. So we can support llinters because there are diagnostics and code actions. We can support formatterers because there are different formatting actions we can take. We can enhance documentation with LSPs. For example, like on hover, we can add new refactorings because there are actions like code action and apply edit. So a server can send you edits and then ID will apply them. And we can also support frameworks with LSP of course because we can use all the above for this. And actually we can do even more because LSP protocol allows custom messages as well. So you can do whatever you want. Basically, you can send a message to turn off the heating or turn on the refrigerator if you want as well. So with all these features, there should be some configuration as well. So there is a special request response for that. So the idea is still simple. We we the client in this case the server is requesting the configuration and the client responses with it and then language server usually caches this configuration and uses it. So there is a special mechanism to update them. So in this case client should say a not send a notification saying to the server like hey I have updated my configuration could you request it again please? And then after some time when the server feels like it, it can send a request configuration again and then get a response. I still don't know how this is is this supported by Intelligj because I haven't found any information on the UTRA and in the docs. So that would be nice to get an answer later in the discussion. So currently I'm just reloading my language server when I apply some configuration changes. Since the LSP support by IntelligJ is uh quite new and it's still experimental not all the features are supported but like most of them are like more than 50%. So the ones that are not supported are rename and there in parenthesis there statistics from ID. How many times do I use the feature? Rename is not supported. Then selection range is not supported as well. That's the clever selection when you go up to semantic units in the code. Code lenses and code vision are not supported as well for LSPs. And like code vision is the stuff almost like inlay hints but they can be both above and in lay and they do some action when you click on them. So the new code vision stuff opens the blame and uses usages just opens a popup in this case with the usages that you can navigate to and then document symbols is also not supported. So all this stuff like breadcrumbs, sticky lines and the structure of view is not always supported. But actually that's the problem of doing talks on experimental technologies because while I was doing the talk two weeks ago there was no support but then when I tried it couple days ago the support is there already. So in 2025.3 there will be support for document symbols. What should we do if the feature is missing like the it is there in LSP for example but it's missing in the native support for now you can either implement it yourself because you can get the language server and send all the commands manually get the results and then process them as you want or you can also use some alternative clients because there is a LSP for IntelliJ client made by someone from Redhead I guess which supports more things currently but the J brains native support is almost full as well so I think in a year it should be on the same level so if we want to do things manually it's quite simple so we can get our language server via the LSP server manager so usually we use one language server per project so it's fine to just the language server given your provider and then use it. So and then yeah you can see that we are using here the rename command. So we are sending it then we are waiting for the results and then we're applying workspace edits and there is 100 lines more above to apply them. So totally we can implement rename even right now with 150 lines of code but it's infinite amount of bugs because the feature is actually quite sophisticated because we need to rename across several documents. We LSP supports two actions actually. So there is a prepare rename and rename and prepare a name just checks if we can rename the stuff. It's like a simple fast check and then if it works then we can send a rename one and do all the stuff get all the edits and apply them and there are even I think there are more corner cases because when I looked at the LSP for intelligj sources where they implement rename they actually doing the reference resolution themsel like they are asking LSP especially to get them all the references to the variable they are renaming and renaming them as well manually. I think that's what language servers should do. But if they have this code, maybe that's not supported by all language servers. So it's safer or easier to also handle on the client, which is a bit weird, but still while living in the real world. Yeah. And having learned all this about LSPs, uh the we still have two more exciting things. So like the first one is that all the parsing, language analysis, indexing and all the stuff is still there. So like we are not doing it in Intelligj, but we are still doing it on the language server side. So there are still indexing. So for example, next time when you think that IntelliJ is slow, you can remember that it takes LS Ruby LSP in VS codes 40 seconds to start because it's also indexing files. They are just usually not reporting it to VS codes. So you have no progress bar and you think that it's already working but it's not. Yeah. And the second good thing is that LSP is made as language agnostic is as possible. So the client is supposed to is not supposed to do anything clever. So all you get is just results to the actions you send but you don't have any a to work with client side because it would actually be quite slow to send it for all the file edits as well. So if your LSP doesn't do the thing you want the only way is to work on the LSP itself. So you'll have to go to the language server and add the features there. And usually they are built in the same language you are writing the LSP for. So for example like Ruby LSP is written in Ruby and Huskll LSP is written in Huskll and so on. But in my case the LSP is written in C++. So I have a hard time contributing. So in reality you can write as much code as you wish and learn as much stuff as you want while still using language server. they simplify some things but you still have other things to concentrate on. So let's sum up some pros and cons of relying on language server protocol and language servers. So the the biggest advantage is of course simply maintenance because if there is a language server already maintained by the way for example by uh language team itself it's much easier for them to support it. So you don't have to do that. And then the minuses like the disadvantages are quite small. So you have less control over implementation of some front end like features like selections and foldings and stuff like that. You don't have support for all the intellig features from LSP. And there is also some minor performance overhead because you have to send all the messages get them back and it's not instant. So, and I also have a final advice for you. If you will be building a language, if you're building a language plug-in, I would still suggest starting with language server if it if it's there for your language because it will be much faster start and you can publish the language plug-in as early as possible and the people will be happy. Then you still can gradually build extra support with Intelligj platform. So you still can be your lexer parser in intelligj with all the grammar kit stuff and support some fancy refactorings support your own foldings support your own selection ranges and stuff like that because it's an easy part of a language you can do whatever you want there but I would still advise to keep reference resolution type inference and completion LSP side because this is the hardest part and for example I I I remember that there was a talk about types script and the webtorm team had a hard time trying to replicate all the TypeScript in type inference because it's always updating and then you can also implement some missing features manually or just trying other LSP clients in intelligj as well. So that's all and I also have a like since the conference is free there should be some ads and I have an ad for you. I have an small article about building the same plug-in, but it's mostly about lexer and parser stuff. So, if you need some advice and help there, you can check the article and I know ping me and I can try to help. So, that's all. So, I see I have uh here I have some useful links. the playground repo with the basic code for the LSP support that I used. Then there's a L plugin that I created and there are of course links to just brains platform and the main LSP docs. So thank you all for the attention. >> Okay, thank you very much. That was a really great talk. Um and with the last slide you actually answered the question uh that appeared in our chat. I will uh quickly showcase it. Yeah. Is there any open source plug-in for language support uh with LSP? So yes uh yeah that there are actually quite a lot. So mine is not the first one. There there is a I think it's Prisma OM for front end development that's like the jet brains example and there are other plugins as well >> which already >> what I would like to add uh here is also um mention the tool that we have uh at jet brains it is called intellg platform explorer uh let me bring my screen to the stage. Yes. Uh I've pasted link in chat. Uh so basically this is uh plugins.con/intellig platform explorer. And here you can search for opensource uh repositories and open source code uh that is implementing specific extension points. So here we can also search for LSP and yeah here is uh server support provider extension point for example. Okay, not much to show here but yeah many many other um extension points are already implemented by third party plugins. >> Yeah, I think it's because the language support was migrated. So LSP is now in a different package. So what that's why the previous link was almost empty. >> Yeah. Yeah. Thanks for clarification. Yes. Uh yeah. So >> I got a question. >> Yeah. Go on. >> So um I mean you aware of I mean uh Jetrain gets often a lot of heat about the indexing and stuff, right? And from the users perspective I really understand that because you don't care how something works. It just needs to work and it needs to work fast, right? But if you have a bigger code base and basically what we do is parsing everything through and storing the information and the model of the code so that we can do all the clever things that we do. Right? So if you have an LSP and I think you said that already perfectly either it doesn't have the feature or it needs to do a similar amount of work to have the feature. Right. So, um, can you say something about, so you you mentioned renaming on the LSP. Can you say something about what they need to do behind the scenes because they also need to build an index because they need to know where some code is used, where it's imported from, and what are all the references that need to be renamed, right? >> Yeah, for sure. So, that depends on the language. In in my language, renames are a bit easier like some renames because they are mostly in terms of one file of a single file. But still there is indexing of course and there's even a setting for max files to be indexed which you never see in intelligj because it can digest I guess an infinite amount or like almost infinite and language servers cannot. So I have like 10,000 files in index maximum and then it will just not work. Yeah. So all the reference res resolution is still has to be done. >> Mhm. >> So language server is not something magical. It's almost the same thing but just like platform agnostic. >> Mhm. Yeah. So because I'm I'm always a bit um confused about the all um the whole lightweight editor versus very heavy IDE discussion. Right? So the answer is simple. If you want a lightweight editor, just open an editor that does basic highlighting for a file. But then you're missing out on all the features, all the code analysis, inspections, and so on, all the things you get basically when you have a deep code analysis. And it doesn't matter if it's done in Intelligj or if it's done in an LSP server, right? So that's always a bit worrying. So I think we have some more question. So from Chris um who asks Jacob can you bring it up? Um is it possible to have an IDE native feature function slashf functionality also implemented in an LSP? I think you answered that already right but maybe you can repeat it. Yeah, I'm not sure what exactly the question is about like which functionality for example, but yeah, any extension point you have in IntelliJ, you can just run the LSP server there and run the like the your own custom command or the existing comment in LSP that does exactly that. So I think some sophisticated refactorings can be implemented like that because there is no built-in support for like change signature. I think >> yeah let's say let's say let's say you have a very complicated feature in your language like for instance changing the signature or changing the type or something and it's not implemented LSP then you have the choice to implement it in your plug-in and do the edit just over the LSP and inform the LSP is that correct >> yeah so you you have two you have two ways either you build it like full LSP mode so you go to the length language server and build there the stuff because changing the signature will also require some reference resolution to update all the usages. So it will have to be built on the language server and then from ID you will just send a custom message for example you have a change signature method with all the custom params and then a language server does that either you do this on the ID stuff if you have lex bars already so you have some basic a you can for example rename like trigger the built-in intelligj feature and then just apply the edits >> through lsp I think should work as So, but if you if you want to change it on the LSP, you probably need to work with the language that the LSP is written in, right? So, you mentioned that already. And it might be C++, it might be, I don't know, Okamel or some other um obscure language. >> Yeah. Usually, it's the language you are working with. So, >> you're working with, right? Okay. I think um Chris has a follow-up question. So if so, how do you deal with turning off the functionality on LSP side so that it does not interfere with the IDE native implementation or is that uh is there no need to uh no need for concern? >> Yeah, there could be some concern about it but you can do the configuration. So you have this capabilities and you can just turn off the capability. So you just say that intelligj idea does not support and does not need for example refactorings or completion and then it will never ask for them. >> Yeah, that's the idea. >> Yeah, a very good question Chris. Um I think Andre has another question. If the LSP needs to be aware of all the project files written in my DSL, can I send them to all the initialization or does each file need to be opened before it's sent to the LSP? So the server, the language server is usually working on the same machine. So language server has access to all the files on the file system on its own. So you don't need to send all the files to the LSP. It can just read them. What IntelligJ is done is doing it's sending the currently like files currently being added to LSP because they are not on disk they are in some v virtual file system. So this one's idea should synchronize but I don't think you have like all project files being edited at the same point. So >> you just send the small amount and it's done automatically by >> Intelligj because there is support for that like did open and did change notifications >> and the rest LSP can read on its own. >> Yeah. >> So you don't need to open all the files. That's to answer answering the question. >> Okay. Thank you. Um, so I think finally could you have a summary because I think your your your talk was called LSP versus the joy of learning, right? So I did my language with a custom paraser because there was no LSP when I started. It came later. uh and also I wanted the joy because I wanted to one of the goals was to understand the language to a degree where I really have the full view of how basically things are evaluated in code. So what would be your path? I mean you mentioned it start with an LSP in your talk and then because um maybe we should point out one thing which is how hard it is or how hard it can be to implement a pause or a custom pauser right um so that's one thing that because I brought it here because when you were talking so these are one of the two books I have I think one is the standard guide and the other one um I'm not sure which one because there are really many ways of parsing language um language syntax and it depends on the syntax and what what class of language um the syntax is right and there are many ways and we have one thing with IntelliJ or with the platform that people are usually not aware of which is you have a parser that can parse through and that's okay but for IntelliJ and for idees in principle you need a parser that parses every crap you throw at it right and doesn't stop because the user the user is not helped if you stop right through the the file and doesn't do the work to the end. You need to go through so you need a very error resistant pauser that that pauses everything and that is a bit tricky because no compiler um will do that. all the compilers will just stop when they reach an error and um or most of the compilers I'm not sure if if all right so this it's it's a thing on top so do you have any recommendation >> yeah so I think not not all the compilers are like that I was also making this point in my article but then I thought that rust compiler is quite clever so they're highlighting all the errors and I think like our compiler is also quite clever >> but yeah writing lexer and parser is hard, but it's not as hard as indexing and type inference if you need it because you do it once and language changes very slowly. But type inference can change like faster and it's hard to keep in sync. So writing your lexer and parser is easy to some extent easy depending on the language of course. If it's hacks where you have C injections that's much harder. >> Yeah. So answering the question which path do I choose and did I have the joy? Yeah, I actually start with a custom lexer and parser because I my goal was not just to support the language. My goal was to learn how it's done properly finally because my previous attempt was like more toy examples. So yeah and I also tried reading dragon book about compilers. I'm like halfway through it. It's quite interesting. So I did all the stuff but there like the point was that there is still some joy as well even if you're used to language server. So like using language server just speeds up the initial development I think and it may help you in some places but you still have a lot to do if you want a decent support in the end. >> Okay so let that be the final words. Alexandra I thank you very much for joining was really nice talk. Um we will continue. So thank you everyone. >> Um yeah thanks again. >> One one more uh thing uh in terms of LSP API uh I'm not sure if uh you missed that or not. Yesterday I asked uh our colleague Tomas Buut uh who is working on LSP API to uh post the status update of uh what is going to be introduced in 2025.3. So in our forum I'll just paste the link. We have a nice list of features um what what is going to be available and we updating uh SDK docs uh in that matter as well. Yeah, I I just saw it like couple days ago because Yeah, I understand that updating docs on the experimental features is hard. Yeah. And I also wanted to maybe briefly mention that LSP will be available for free like for all the ids now starting 2025.3. So now it's only in paid versions but it will be for everyone so much. >> Yeah, exactly. Thanks for saying that. >> Yeah. All right. See you Alexander. Great to have you here. >> Byebye. So next talk we can keep the introduction pretty short. Um so Jacob will talk about cotlin notebooks meets intelligj platform. I will >> give hand over to you right and give you the word and you can do anything else. >> All right thank you very much. Um so yeah I believe I can skip self introductory right now and j just yeah dive into um the introduction of cotton notebook and intelligj platform integration instead on the screen I do not have any pro uh presentation and slides but um the intellig idea in version 2025 two three three so it's already.3 um with cotling notebook file opened uh prepared for this presentation so I will just scroll and click and tell what is here and what you can do but let's start with uh an introduction what cotlin notebook is pro probably many of you uh already heard about Jupyter notebook book um and it is um pretty often associated with data science and all the rocket science stuff. Um so yeah it's all about one big file that in which you can write um content code and markdown and mix that and present data and that was the Jupyter notebook uh works with Python here uh since 2025 one I believe I don't really remember uh we have als or even earlier uh cotling notebook available for everyone. Um so in intellig idea having cotlin support already present you can start using uh notebooks and notebooks are a bunch of cells um markdown cells for example. So I believe yeah you can see me clicking on specific cells and they are highlighted. So this is a single cell in which we can type markdown and it is eventually rendered as a markdown um output links uh formatting everything is here. So this is already great for creating maybe readme files but divided into cells and mix with code cells. Here is code cell. If we double click on that it's already in its natural form because this is code but uh comparing to markdown cell we have on the left side display button. Um so as soon as we hit it it will render the code the response from the code. So here print line printed something to the standard output sd out and here it is but we do not need to print something explicitly. uh cell is taking the latest um kind of the latest statement uh from the code block uh as an answer and it renders it automatically. So here we have just number 44 42 and here it comes. The next one um x= 10 20. So in a result we got 30 already. So yeah the latest statement is taking into consideration here. So yeah we have different output types string rendered as a string list which is converted into um into a list with uh square brackets. uh data classes can be also nicely rendered and maps and many many more. So everything that can be well it's it's not uh exactly two string but they are providing with uh multiple mappers to to make it look nice. So yes um markdown cells um code cells and they can be um written down in different order. And about order it is really important to highlight that order matters but not order of um cells placement but um their execution time. Uh so let's let's make it more visible. Here we have declared a message uh variable in the first cell and in the second cell we can already use it. If we will start with this cell, uh the message variable will not be here with us yet. And yeah, we'll get error. Exactly. Um how we can use it for some better purposes? Let's say uh if we define uh mut mutable variable counter here in next cell, we can increase it. So yeah it is one right now. If we hit it multiple times it is increasing even more. So the order matters and execution order matters because um if we have uh just placement order that most likely will stay um to be set to one. But yeah later we can reset it and set to 100. But if we get back we are already starting with 100 and going up. Uh yeah. Um so so far um in our cells we were using the latest statement uh to present output and uh printing stuff to the uh standard output. We have more options still which are yeah repeating the basic approach here. Um again only second line is displayed but if we like to print more we can use a display helper here. So when running the cell uh that contains of uh three display um invocations all of them will be printed uh as an output of the cell and yeah display is only to uh print something in a raw form like uh plain text. Uh but we have more. We can uh render HTML as an output even emoji and uh CSS styles uh can be used here. Next JSON because PJ JSON we don't really want to display everything in in one line. uh with JSON uh helper we can have it uh pretty nicely formatted. Next to that obviously it's it's easy to achieve. Um we can display images with display and this is not only image uh that we have uh stored locally. Uh this is something that we create dynamically. So with AWT uh Java AWT library uh we can yeah render this nice image and we can with double click zoom it in. Having that already in place, it's easy to request something from the internet with UR. Um, yeah, and it gets fetched and displayed for us. Okay. But so far we've been using uh some basic libraries uh basic classes available in um JVM. It is still possible to um attach more uh than just uh more libraries uh using for example uh stuff from Maven central with the uh at file depends on syntax. We can simply specify um Maven coordinates of a specific library. Um and it will get downloaded our local cache and from now on we can start uh using some external libraries. will not invent the wheel from the scratch. And yeah, pretty print again. Um, next to this file depends on uh syntax we can use a gradal like syntax. So here we have the use uh helper function in which we can uh still define repositories and dependencies that we know from uh gradal. Uh so this is pretty useful uh for folks already working with uh plug-in development because this is how you can get some dependencies you are already using in your code into this playground. Um yeah the third possibility for um including some external libraries is using so-called line magics. line magics start with uh the percentage uh character and yeah use use candy. Candy is a visualization library that we'll use in a second. So yeah, from now on it is already loaded and we'll simply start using it but uh by um invoking the plot DSL and passing some basic data there. So here it is already rendered as a nice chart which is not static but actually dynamic. So as you can see on highlighting something clicking around uh it is already interactive. Um I'm not fluent in candy but uh for sure if uh you are curious how to use this particular library uh we have documentation provided in um cotling notebook and cotling documentation pages so it's it's easy to google that. So yeah, many of magic words but uh there is one that you should remember and this is a great starting point uh for exploring cotling notebook and this is the help command. when we trigger it uh we'll get the basic information about the JVM version and um all kernels and cotling versions and available commands. So yeah help is mentioned in the first place and then uh there are again classpath and farce um commands which we will explore right now. What is classpath? This one is printing um all jars or all all libraries that we have uh currently in the the current cotlin notebook uh classpath. Uh so we can figure out what is available uh what we can use uh in code cells. So if we try to search for candy as you can see it is already here because we have loaded uh this library few cells um earlier and uh it is in time growing uh as soon as we execute more and more code. Um for figuring out what we already what we also have uh available for ourselves. There is this vars uh so variable state uh command which is rendering some um variables names that we defined or were defined by um libraries we loaded. And for example here we have this counter set to 106. And this is the current state. If we um increase it again and call vars again this uh value will change. And yeah before I will not print help again just going a bit above. Uh the next section is magics. So those use magics. Uh there is a full list of all features uh that are available for you uh when working with cotling notebooks and supported libraries. So candy is somewhere here but we have multiple other libraries for working with data with uh images uh HTTP um APIs uh daytime. There is also cook uh for AI agents and so and so. Uh and those are in most cases not only uh a set of libraries loaded from Maven central for example but also additional uh DSL helpers functions variables um crafted especially for uh cotton notebook purposes. One of those um integrations um probably okay we can see it here is intelligj platform and uh this is something I would like to uh showcase you as well um how we can use it um for plug-in development um purposes for creating proof of concepts. So this is where the magic begins. As soon as we execute the use intellig platform, we will get this error. And this is something uh that I wanted to show you um because cotling notebook um is executed in a running JVM. So it is creating some um let's call it JVM environment in which uh the code is simply executed. So on the top of Cotlin notebook you can see a drop-down with uh an option of uh run in a separate process. So if you click click it uh there is another option run in id process. And what does that mean? Well, we will simply start running the code in in the current IDE. So again, when we load this uh integration, it is already correctly loaded. How to prove uh this is uh this is the current IDE. Um as mentioned before the intellig platform integration is exposing uh not only um well dependencies library so dependency on the current IDE. So under the hood it is um resolving uh your the location of the current IDE going into the lip directory and picking proper jars in the same way uh great the intellig platform grad plugin is doing for development. So this is exactly the same approach but using the current ID. So nothing extra is downloaded. Um and it is exposing some uh basic uh global variables like product info or ID path. So here um you can see I'm running the uh intelligent idea in version uh 2025.3 uh with my local uh installation path applications. Okay. Uh but the question number one uh is always how to get the current project. Um to make things simpler, we are exposing current project helper. So as soon as we run it, we can see uh the project name. Um so this is exactly the same project that we are using. uh for showcasing this uh integration its location and project file etc etc. So this is a regular um project instance that you know it uh from plug-in development because it is exactly the same uh the same variable. We can try printing it here. So yeah, this is this is how uh how it's rendered to string. If we start typing here, yeah, you can see a well-known um fields available in this uh in this project instance. easy post message bus and everything that is basically available for plug-in development. So yeah, why it's revolution revolutionary? Let me just render again this. I'm not sure if the the font isn't too small. Uh I will read it aloud anyway. Um so yeah uh you can use uh cotling notebook with uh intelligent platform integration uh for making things way faster because uh in a traditional way you need to create a project um from template or uh wizard within the IDE um adjust plug-in XML file build a plug-in run IDE in a with the run ID task uh test changes and repeat the cycle and it takes time especially when you uh work on UI. Uh with Cotlin notebook uh you just need to use Intelligj platform uh instruction write the code below execute the cell and see the results immediately. Um and yeah reiteration is is way way shorter uh comparing to regular approach. And what about yeah seeing the results immediately um above I've explained that we can render um plain text or HTML or images uh right below the code uh cell here. Um note that some code is red and this is by purpose. We can render also UI components. So when we run it, we'll see that there is some unresolved reference to columns and text um functions. With alt enter, we can import missing stuff. run it again. So below we can see rendered um UI interface using UI interface uh rendered uh UI um which is dynamic still dynamic. So yeah those fields are responsive. We can start typing here. Buttons are executing the code. So here we are defining uh button to shake the IDE. And yeah, this this funny helper will shake our IDE. Yep, I believe it is visible um during the presentation. Um so yeah uh we can see uh results right away. So here run it again and shake it again. Um so yeah the feedback loop is is really short here. Um, cotton notebook is also respecting the ed so event dispatch thread because some actions related to UI are supposed to be executed in UI. And here we are um using the run in ed helper uh to invoke something in ed. Simple as that. And yep, each shows dialogue which we can close and everything works. We can uh still adjust that to uh error icon and from now on it will be error. Okay. But uh you may say that this is not enough for uh plug-in development. Um that's true. We can uh still do way more than that. Uh we can register actions. Uh so here I have a snippet uh for registering action in the current IE. Um okay, that's unexpected but expected. I'm I'm on um EAP release still. Uh but here as you can see we can search for this action already. So it was uh correctly registered in IDE and it displays it is executing this show info message uh with the text you can see in code cell. Yeah. Um, next loading plugins. Uh so um by default we start with uh just a plain uh intelligent platform um basic libraries uh which are basic and we can still load um bundled plugins uh bundle bundled modules or plugins that are currently installed in the IDE. So we are not playing here with uh resolving something extra uh from marketplace uh but instead uh to make it uh solid and do not play with uh your current IDE permanently we are referring to the current state of IDE. So here we are loading uh Java plug-in cotlin plug-in and kit for idea. Uh still everything that I have installed uh even third party can be loaded here. To do that uh we can simply uh print all the stuff uh using plug-in manager core because this is the the starting point for uh all the knowledge about plugins. Uh yeah, with another um magic use magic data frame, we can have all the output in a pretty nice um format with cells and we can explore all plugins uh available for us for development. What to do with that? We can load for example AI assistant uh plug-in register an extension point it is exposing. Uh so here is some chat agent extension point name and in the actual okay we have a lot here. Uh in actual plug-in we can use our uh custom implementation and yeah let's try it out. And it is responding to us with the answer that I expect to have. Okay. But we are modifying everything. Should we restart IDE? No, we just need to restart kernel. Uh everything is back to red. But um let me just quit it. Uh everything we added to the IDE al is also gone. So all the implementation we did uh is uh got disposed. Uh so we need to load the intelligent platform again and this magic happened because well thanks to uh dispos uh disposer. Um to quickly showcase you that um this code created to window when we um yep expected uh well with uh notebook disposable um things should uh get disposed immediately uh meaning uh restarting uh apply some additional effort And we can use resp uh disposer register um to remove uh something from your current instance. Okay. Um here best practices to to sum summarize everything. Restart kernel after modifying project codes. Run everything again. And remember that execution uh order matters. So if you rerun everything at once uh with this button remember uh that it will be executed uh as it was placed uh run in ed for threading and UI uh operations and remember ed uh doesn't forgive um to clean up uh your mess um you're supposed to use dispo uh notebook disposable Um and basically use load plugins for loading third party or bundled plugins and modules. Um everything is limit limited to your uh current um state um current current IDE and basically yeah uh this notebook file is not um published yet. Uh but we can do it with the um create jist button and I will do it right now. Um so yeah we we can view it in browser. It will still be rendered properly in browser as we can see it um here. But instead of pasting that right in the chat, I will just ask to uh create a QR code image with link following link. So yeah, it is um generating some code cells. As we can see, it's using ZX in uh library and yes, let's accept that um run it one by one for um to make sure it works properly. But it's okay. What a surprise. This morning it was working correctly. So uh this is probably uh yeah how demos are supposed to work. Uh render QR I have it again. What's that? Okay, this be was here with us. We are almost there. Yep, it is here. So uh from now on you can uh scan the QR code but I will share uh the link in the chat anyway. So thank you very much. That was lovely. Thank you very much Jacob. >> Thank you. >> So um I think we have we should have some questions. If not um we can principally just discuss the the implications here. We have five minutes left. Um, so I'm I'm sure most of you will know Python notebooks. The the concept of notebooks and basically doing work and um documenting it in the cells between and then running cells, right, is really really old. Um, I think it goes back to 1988. Uh, Warframe Mathematica had it first. Um, I'm sure at least that's what Steven Warframe always claims, but I'm pretty sure it was one of the first instances. And um basically the success of notebooks um are pretty obvious because uh we see um working on prototypes and doing quick work in Python and a Jupyter notebook um is basically everyone knows about that and as you saw on the presentation of Jacob it's really nice if we have the same thing where we can basically work with the IDE in a notebook and evaluate code that directly affects the tool you're working in. And this could be a very nice addition to um to prototyping features and stuff for uh for plug-in development. So, does anyone have a question about that? Otherwise, I would go ahead and ask one. So, um, Jacob, one of the things you did was all using these magic things, these use things and stuff, right? >> Right. >> So, um, are they documented already correctly? Because I haven't checked the documentation. I just saw some examples and played around with examples. >> Yes, they are. Um if I would search for cotlin notebook uh use magics probably they will appear. >> Mhm. >> Um so yeah basically use documentation >> okay >> or AI for two times. >> Yeah. Yeah. So the other question I would have is so we saw that it's pretty hot right now uh and not everything works and it's kind of expected because it's pretty new. So what is so as a normal user, right? Can I use it right now um to prototype stuff? What do I have to do? >> I have to use an EIP version and so on and so forth. >> Uh the blog post I uh have posted in the chat uh was based on the 2025.2 already. So since that version >> um everything should be already stable. Now I'm using E release so something changed overnight because I'm still on the nightly build. Um but with the 2025.3 release um again uh we expect to have everything uh to work solid. So yeah, basically get the latest table IDE uh create new notebook uh with file new cotton notebook or even in the welcome screen uh there is this uh on the left side projects uh settings and also cotling notebooks. >> So use that as a starting point as well. >> That's sounds good. So yeah, if ID is stable, C notebook and intelligent platform integration is supposed to be stable as well. >> So that basically leads directly uh to the call to action to the audience, right? So please try it out, play around it with with this uh tell us what doesn't work, tell us what works, uh >> give us nice examples, right? so that we know um basically what to work on and what doesn't work and what works and how you want to use that >> exactly and uh if we have still a few minutes well the launch break will be a bit shorter but I can show you that well uh in the blog post and documentation we have this repository linked and there are examples um and yeah in those examples. There is a bunch of code. >> Mhm. >> Uh I'll just run it. >> Keep your fingers crossed it works. >> No. Yeah, but we got we got a question to just gloss gloss over the the error. >> I know Robert uh did. Okay. So first let's comment on Robert's uh so Robert already said Robert said that um Donald Kut actually uh introduced um literate programming and it was called C web and CW weeave and it was for C where it could basically combine it with your latte latte code for document uh documenting your your code and actually that was the very first plug-in I worked on in probably 2005 to 2010 I'm not So, but we got a question from Roman um who asked what is the expected workflow of the production produ production of the prototypes written in the notebook as a plug-in that can be shared with others. Uh that's a good question. uh well we can still prototype something in the notebook uh if even if it is just a simple UI or uh imple implementation of extension points and then having this code we can start copy pasting it to actual project uh so you can use plug-in template of ours uh hosted on GitHub or create a new project from ID wizard and move um the code in proper places. Uh that part I hear that's uh going to be tricky but uh with okay uh AI agents uh some people are skeptics some are not but they are actually really helpful in working on something that is already in place. So you are not u making something up but you have the scaffold you have the code you want to use and you can mix it and put in proper um in in the production ready uh version as a standalone plug-in instead of um cotton notebook uh scaffold. I think one of the two major um points where where this could be helpful that I see right now is is first prototype something quickly try out a feature or an extension point and see how it behaves and what you need to to do to implement it correctly. That's the first uh application and the second one is we could share examples pretty easy about how to use features with a cotton notebook because as um Jacob said you don't need a whole project you just need a small notebook that you can evaluate directly in your IDE and then you see what what happens and how a feature is used right >> yeah exactly and um because we are expecting to have compose UI available uh soon next there. Uh I will uh yeah I hope cotton notebook will catch up with that as well. Uh so as a result we'll be able to render compose UI immediately and share that with others. Uh so whenever a team will work on plug-in internally or or for uh to make it public in marketplace they will be well it will be easier to to share the knowledge and uh prototype interface for example with this brand new uh technology UI framework. >> So with that I want everyone to go off to have some lunch break. We will have some we will reconvene um in 25 minutes half one um European time. So this is something else in UTC I'm sure. So, see you all back in 25 minutes and have a good lunch. Heat up. Hey. Hey. Hey. Yeah, aha. Down here down here. Hey, hey, hey. Okay. >> Okay. I'll do that now. Hey. Hey. Hey. Hey. Hey, hey, hey. Heat. Heat. N. Hey every feel. Well, well, Heat. Heat. N. Heat. Heat. Heat. Heat. Hey, hey, hey. Hey. Hey. Hey. Uh-huh. Uh-huh. Uh-huh. Heat. Heat. Heat. Heat. Heat. Heat. Hey, hey, hey. Heat. Heat. Hey, do it. Heat. Heat. Hey, hey, hey. Heat. Heat. Welcome back. >> Oh, there's the cat. >> All right, everyone. Um, I hope everyone had a nice lunch. So, next speaker, Jacob, it's your turn, actually. It's my turn. Okay. >> Okay. It's my turn. Um, so the next speaker uh that we're going to uh have today with us is Tomaso. Oh my god. I'm sorry. >> Gian Fredo and I hope didn't butcher that. >> We'll ask Tomaso to to correct. >> Yes, we will ask him right now. >> Okay. and his talk will be about building in constraint environments lessons from us apps. Uh >> hello Tomaso. >> Hello. >> Hi. >> Hi. Can Can you say can you say your name for us? >> Yeah. No, you you got it. You got it pretty right. Yeah. Tomaso John Fredo. >> That's crazy. I mean it sounds a bit Italian the name. >> It it Yeah, it sounds a lot more Italian than I sound. That's for sure. But then you have a really strong Australian accent which is really great. >> Yeah. Lovely. >> Okay. Um, Jacob, should we jump right in? >> Yes. Well, let's not >> let's not waste anything. Um, Tomaso, the floor is yours. Um, pretty good to have you here. Go ahead. >> Yeah. No, thank you. Yeah. No, thank you both. Um, yeah. So obviously as uh as as we just mentioned, my name is Tomaso Johnfredo. I'm the director and the principal engineer at Adept Task. Um I've been working in the project management tools consulting space for about six years now. Uh and I specialize in technical solutions and generally do my best to take software that an organization already has and origami it into solving problems that it really wasn't designed to solve. Um now around six months ago I started a debt task. We're a jet brands consulting partner. Um we're UTRA certified and that was our goal was to build apps for UTRA. Uh in a time where you know seemingly every project management tool is cloud only and pushing all of these new unused features instead of fixing bugs in the year old years old features. Um, Utrak really came to me as a breath of fresh air and uh now I'm working full-time at developing solutions for Utra. Uh, and that's really what we're going to be talking about today. Um, we're going to be talking about uh our journey, Adeptus's journey to building what we consider production ready Utra apps. Um, now on paper, these apps are not particularly special or complex from a technical perspective. And uh for most of the developers who are listening and watching um you're going to think that some of these problems are a bit simple and I'll talk a little bit about why I think they're still interesting at the end. Um but uh yeah really it's it's the constraints that are imposed by the Utra platform uh that I think make these problems so interesting. I'm going to talk about some of the challenges that we've faced uh and how we overcame them with some creative thinking. And perhaps uh if you're not going to apply these to your Utre apps, you may still even find some inspiration for uh solving some problems in your own projects. So let's talk about building an app. Now before starting to build our Utre apps, it was important that we revisit our understanding of what's important in a software product. In particular, we needed to adjust to the fact that we weren't just building a software product, like a normal piece of software that exists on its own, but an app within UTRA. Now, UTRA apps are somewhat different from other software products because they're always accessed from within UTRA. For example, when you're building a traditional bit of software, you could uh choose to design the UI however you'd like. For example, here's the uh spring pet clinic example you're probably a lot of you are familiar with. But if we did that with the Utre app, it would stick out like a sore thumb. And you know we that's because we need to think about uh where the the software is existing and and then we need to conform to those constraints and and um yeah now this is not objectively a bad thing and particularly in this in this screenshot uh we get a lot of contrast and you might be thinking hey that's a great way to make my product stand out um from the crowd and and that's fair enough. Um but that's why it was important for us to identify these considerations upfront and then make decisions about them before we started building. Um now I'm a longtime consumer and purchasing stakeholder of similar software products in the form of nor mainly the Alassian tools. Um and these are the following these are the uh some of the key areas that I found to be most impactful to my my users and my stakeholders perceptions of an app. Um this is the user perception uh or user experience like what are their thoughts? How do they feel about the app? Uh the security so there's a bunch of security uh things that we need to think about and the administration complexity. Now the app ecosystem is very new. The UTRA app ecosystem is very new and now is the time to nurture it. Uh you know they say first impressions count. Uh, and so it's paramount that the UTRE apps that we release are good, not just for our business, but for the Utre ecosystem as a whole, right? If the first 20 UTRE apps come out are terrible. Then that's going to set a bit of a precedent. People might look at the beginning and they might say, "Oh, what's this? Oh, they're crap." Well, we just might not look again, right? So, it's important that we put in a bit of effort. At least that's how we feel about it. Um, so if we think about user perception, uh, I I call these cohesiveness and user experience. User experience, that's pretty standard. Cohesiveness, well, we're thinking about how does the app fit in within the larger uh, context of you UTRA. Um, does it look like it belongs or does it look like that pet clinic example that I showed before? And security, we've got some things to consider. isolated environments. So, UTRA can be run uh as on Utre server. That means it can be installed and hosted on any uh server environment and those environments may not be connected to the internet. So, our applications need to be able to run without an internet connection or at least without a connection from the Utre server to uh the internet. That'll cause a whole bunch of problems later on. Um there's also data residency requirements kind of the same as the first. Um but if we're hosting any data then we need to consider the data residency requirements of our potential customers. There's also just the vendor trust. um we need to not uh come across as you know well ideally we don't want to come across as the traditional SAS uh application company where we're saying hey give us all your data uh we're going to charge you a lot to then give us your data and then you've got to hope that we uh store it correctly and so on so forth. Uh administration complexity uh we need to keep things easy to maintain, easy to support. uh license management is tricky and understanding ROI is tricky. Um we're not really going to cover these today, but it was a consideration worth making and um yeah, cool. So now that we know what we need to keep in mind while building out, let's uh look at our constraints. So this is the anatomy of a UTRE app. Um they're structured similar to most modern web apps. We've got a front end, a back end, and a data layer. Um, but I wouldn't really be doing this talk if it was actually that simple. See, pretty much every part of Utre app is sandboxed from the rest of UTRA. Uh, this sandbox is both a uh a blessing and a major pain point when we're developing these apps. So, on the one hand, we're severely limited in how we can manipulate UTRA's UI and data and that limits our options for design and functionality. But on the other hand, we are severely limited in how we can manipulate UTRA UI and data, which limits our ability to accidentally break our customers UTRA sites, leak their credentials and data, perform actions to data in ways that, you know, would break their auditability requirements and other things like that. That's not to say that we have no responsibilities when building our apps, but UTRA customers can be confident that UTRA provided safeguards will be in place regarded regardless of the laciness of the individual app devs and that helps provide a base level of security confidence to our customers. Now let's uh let's look at some of the uh the problems. Um actually before we do so we'll quickly just talk through the anatomy. Um so yeah we we've got kind of your standard uh web app. Um but the sandboxing works uh like so uh essentially from the the front end the UI uh we have app widgets uh and they're embedded into the UTRA UI in a sandboxed iframe. Um, Utra applies some modifications to the code that is inserted into the iframe. Um, uh, and that allows it to then communicate, allows the sandboxed apps to communicate with UTRA via post message. And that allows UTRA our apps to speak to UTRA and send um requests to UTRA's back end without actually ever needing to touch any authorization. Um, which is great because it means that we don't ever have to think about it. Uh then the back end we've got uh JavaScript uh for you running Utre workflows. That's what they traditionally were. That's JavaScript running on the JVM. Um now this JavaScript uh doesn't have access to any much of like modern JavaScript features that we'd know. It's not running NodeJS. It's not a web um it's not a browser based thing obviously. So we don't have access to crypto. That's the main uh that's the main issue, the main thing that we miss. Um our uh our back end for our apps is stateless. So we don't get any persistent memory between uh API calls. Um and uh yeah, that's the the main the main things. We also can't uh from within these these the app backends, we can't hit the uh the UTRA rest API. Um, and the JavaScript API is quite is mostly read only. There's only a few bits of data that we can actually manipulate. Um, which again, great. Um, but does make things a little trickier. Cool. Uh, oh, and finally, database access. There's no direct database access. Our only two options with for storing data in our apps is either to store it in what are called extension properties um which allows us to basically define kind of keyed yeah it's basically a key value store that we can apply to different entities in UTRA. um we need to define each uh extension property manually uh and then we can only store a specific uh kind of set of data in that. Um or our other option is to store it on the UTRA issues and articles themselves. Um now that's pretty pretty useful but but works pretty well. Um but we'll talk about some problems that we encounter later on. Cool. So we're uh yeah, we're now armed with enough knowledge and requirements to go build some apps. So let's talk about what went wrong. So the first problem I want to tackle here also happens to be the very first thing that happens with essentially all software, and that's loading. Yeah, I'm going to talk about a problem that's played the web for much longer than I've been alive. Uh it's not something we encounter too often anymore. Um, but I'm sure any of you that were around, you know, using the internet in the kind of early 2000s and maybe late 2010s, uh, would be familiar with FO, uh, flashes of unstyled content. Um, and it's certainly something I'm very familiar with now, and I'll explain why. So, here's what loading an app looks like in UTRA. Okay, so once the uh the attract page is finished loading uh but while the widget is still loading, the area where the widget's going to be rendered uh is filled with a loading indicator. Now the size of this loading indicator uh is either just kind of guessed for you by UTRA or it's set by uh a specified dimension that you set uh when you create your um when you define the properties of your uh your app widget. Now this loading indicator will be displayed until the widgets entry point HTML has been received from the server. Uh and once the HTML has been received uh the new track will transform the HTML with some custom tags and whatnot um as we described before and then it'll put the uh the iframe into the page replacing this loading indicator. If your app's a simple HTML file with just you know some vanilla JavaScript and CSS um then uh you know so like there's examples provided in the track documentation for example um then you'll probably see your app instantly appear after the loading indicators disappear something like this right we saw that that loading indicator then the appeared however most apps aren't this simple um for example our apps use React uh ring UI, TypeScript, and uh they're built with Vit. Um we use a lot more libraries than that, but these are the main ones that are kind of come in here and cause some I'm not going to say problems, but it is a problem in this case. Uh and yeah, this is where we start to run into some problems. So, here's an example uh entry point HTML for one of our apps. This is one of our older apps, article presentations for UTRA. This is what the entry point looks like once built with vape. Um, so we wouldn't write it like this. Obviously, we're not manually writing our JavaScript files and giving them a little hash at the end. Um, but uh, yeah, if you are familiar with HTML, you can probably look at this code and understand that nothing's going to be displayed on the page uh because there's there's there's nothing in there um, until that JavaScript is loaded and then perhaps that JavaScript is going to do something. And that's exactly the case. So until React begins placing content on the page, uh it'll remain visibly empty. Um and so the widgets iframe will just revert to or sorry default to being displayed as a a white block. Um because uh all of the app's JavaScript uh is deferred. It's a a module script. Uh because it's deferred until after the HTML has been rendered, we're going to be stuck looking at a blank white box. um somewhat like this. We see we get the loading indicator, it disappears for a sec, and then we get the app. Um and that's not really a problem. It was not that big a deal. Like it didn't look that bad, right? But it does get worse when uh we haven't defined the dimensions of our app. We'll see here as it the content of the page kind of uh swipes in to to to cover the the spot where it's disappeared and then it pops back out again. Uh, and it is absolutely the worst in dark theme. Bang, we get a big white splash of uh white and then the uploads. And here's an example in the real UI where we can see all of the problems really come to life at once. There we go. We can see the uploads. We get a flash of white uh and then the actual content of the uploads. So, how do we get around this? Well, our first solution uh was uh to just do our best to cover up the problem, not actually fix it. And this just meant adding styles to the entry point HTML. Um ideally in a way that would look nicer than a flash of white. So we take our old entry point from something like this with a white output and then we apply some color, maybe a gradient, something that ideally looks good in both the white and the light and dark thing. Um, we used this for a bit. It looks okay in the light theme. It looks okay in the dark theme. Um, wasn't great, but you know, it wasn't terrible. And this approach meant that although we always have a flash of color, uh, even in the white theme where we didn't have that before, um, we're at least able to control what is in that flash and, you know, choose colors that feel a bit more intentional. Um uh ultimately we then chose to add a a different gradient uh and add our app's logo uh as well as um as well as an indicator saying what was going on in the app. So initially the loading would start there'd be just text saying loading. Uh and then using in the code we're able to grab onto that text and uh kind of and and provide an indication of here's how things are going. We're loading settings. we're loading loces, etc., etc. Cool. So, let's look at the uh the more unconventional solution. So, whilst that option was better than a flash of white, we uh we found that it wasn't like ideal, it didn't look great. Um and so, uh while we were trying to come up with the better solution, I thought back to my first released app, better backlog. Um, now when I wrote that, I had very little experience with VIT and I made an absolute mess of the build process and I was unable to get the app to load just at all. Was unable to find the JavaScript that was bundled all sorts. Um, but I did find that if I simply bundled the entire application, all of the JavaScript, all of the CSS, everything into a single HTML file, it worked no problem. And so that's what I did cuz uh, you know, I was sick of troubleshooting it. Um, and uh, you know, it looks something like this, right? Instead of having uh, all of our JavaScript, CSS, etc., got one index file, one HTML file. Um, and then I thought about it and went, "Oh, why don't we just do that for all of our apps, right?" Uh, and surprise surprise, it works, right? We can see here the app loads. Now, this gif takes quite a while to repeat, but uh the app loads. We get no flash of color uh and it's all perfect, and that's because the JavaScript is able to run as soon as the uh HTML file is loaded, there's no additional fetching that needs to be done. Um yeah, interestingly, because each app uh because each app resource, so every JavaScript file, CSS file, HTML, etc. uh generally takes the same amount of time to be requested and received from the server from the server and isn't ced. We can't c any of these files. Um we actually reduce the overall loading time of our apps drastically. Um in some cases we found each of the additional uh resources uh to take up to like three times longer than the initial HTML file. So we might start with a HTML file that that like that index HTML file maybe takes 300 milliseconds. Um we could have had uh then each JavaScript file taking maybe 500 milliseconds to 600 like yeah we we were able to reduce the loading times actually quite substantially as a result as we can see here. Um and that's a little example. Cool. Let's move on to our next loading problem which is uh the app actually loading uh its content once it's uh going. So um once it's load done loading the files it needs to now start loading data from the back end. Uh we've got a few different steps here. It needs to register the app widget with UTRA. It needs to pull settings needs to pull local files and it needs to pull the license status. Uh then it needs to perform any app specific data. So everything prior to get app specific data that is uh just built into our app framework that we uh that we've made. Now anyone looking at this that's uh thought much about loading before has probably already noticed that what I'm describing is a classic waterfall pattern. Um and because each of these uh steps is performed sequentially the loading time through the entire widget is equal to the sum of the loading times for each step. Uh unfortunately this is not particularly avoidable because each of the steps kind of relies on the previous step. Um so we if we can't like uh if we can't shorten the waterfall by paral paralyzing the steps uh then our next best option is to shorten the loading time for each step. But how can we do that? Well if we take a look we can see that the register the app widget step takes 2 milliseconds. I think that one's fine. We can leave that. But we can see that the settings the internationalization license status and um the o tok to tokens and app specific setting app specific step we can see they all take around about the same amount of time and that's because there's some latency that is introduced by the UTRA app back end um uh which just no matter what code you're running on the back end it's going to take at least in our testing about 100 milliseconds and depending on the time of day and we actually found it could go up to about 500 milliseconds. Um, so okay, so what I've just said is we can't reduce this time that each of these requests takes either. So where are we getting? What are we getting at, right? How how are we going to reduce this? Well, cing. Um, now these loading steps are performed every time the app's widget is loaded. Uh and if you're clicking through a list of issues trying to find one uh the right one for example uh then that means loading the settings loc information etc etc once per widget per issue and that would make sense if the data was constantly changing but how often are you planning to change your your app settings for example not that often. So, well, we can put a cing header on onto our responses. Um, and that's what we do. We take a C header, C control, give it an age, maybe a short age, and then use a revalidation. Um, set it to revalidate. So, this example, we c it for a minute and allow revalidation for 3 hours. Um, what that means is for the first minute after it's initially loaded, it's just going to use the C result. No questions asked as asked. We do want the app to be fairly responsive though. So we then set for another 3 hours. We stale while revalidate and that means that it'll use the uh the caged value and then it'll also refetch uh from the server just to say is it still the same value. Um that means at worst let's say you change a setting and you've still got a cached value. Um at worst you'll just have to reload the page once uh after you've changed that value and then you'll have the new values. Um yeah so whilst cing does nothing for the worst case uh load times map it does significantly improve the subsequent loads. Um we saw a reduction in the best case loading times which is also the most common loading times of up to like way over 90% um for each step with this cing in place. Uh you can see here we go from an average of nearly 500 milliseconds of loading um to 31. And here we can see in the UI uh there we go. We can see a really really fast load. Cool. So why is this important? Right? You're probably going look these millisecond improvements are tiny, right? and and they they are but they actually represent a pretty substantial user experience improvement particularly when we look at the future of your check app adoption. Um so browsers currently support an a certain number of concurrent connections and if the maximum number of concurrent connections is reached then each additional request will need to wait until the ongoing request finished. Um, it shouldn't be a problem for individual apps, but uh, as Utra apps become more widely uh, used and customers begin installing more of them, we we run the risk of oversaturating um, our current request capacity uh, and causing delayed loading for all of our apps. This is especially a concern for apps which are displayed on issues. Um, as that's going to be quite common. We'll have lots of apps displaying on issues and you'll be flicking through them. it's gonna just really hit a lot. Um, here's a a little example I have where the same app is loading eight times on the single page and you'll see that it's really quite slow. Yeah. Cool. So, that's the loading. Um, now let's quickly talk about storage. Yeah, the really fun stuff. Um so in our upcoming app uh SharePoint one drive connector for UTRA we need to follow an oorthth 2.0 uh orth code with PKC flow to allow our users to connect between UTRA and SharePoint. Uh and we do that so that they don't have to generate any API tokens and we don't have to handle them great. Um now in the case of the Microsoft oorthth uh they provide us a shortlived access token and a refresh token. Um and they have an expiry of 24 hours. Uh and now normally we would store them we'd store these these tokens JWTs. Um these aren't anyway. Uh we store them locally uh in a cookie or something. Um that means that each time we move to a different page we can still have that token and we don't have to run the ooth process again each time. Um but unfortunately uh app widgets are sandbox inside iframes without any storage access. So um without any browser storage access we have no way to store the app data any app data locally. So what are our options um with no ways to store the access tokens locally uh we really we have two options store them on the server or don't store them. Uh now not storing them that's a really simple option but it would introduce a massive problem which is the user would have to reauthenticate go through the oorthth flow every single time they want to use the app. Um, and for an app that is supposed to provide at a glance information uh per like on on your issues, that's going to be a pain. That's just not possible, not feasible. So, cool. Our only option is to store them server side. Um, now we store this for a bit. Store them in an extension property uh on each user. Great. It works fine. Um, and then we send it to them when they request it. And yeah, it it worked. But we weren't happy with the idea of turning UTRA into a repository for an entire organization's SharePoint tokens. There didn't really seem to be another option. Um, we started looking at implementing encryption and blah blah blah. But then while I was implementing the cing for the app settings, I had an idea. If we do things the wrong way, well, what do we know? We know that we can send data to the back end in a request. Our back end can access data it can it receives in the request. A back end can respond with any data that it has access to. Then we can c responses from request to our back end. So what if we make the back a request to the back end and then include uh access tokens in the request essentially. Yeah. Then when the back end receives our request simply returns the access token back to us tells the browser how to c the response and so the next time we'd like to access token we can simply make a request to the back end and then use that c value instantly. essentially, can we use the HTTP cache as a database? Um, now I'm a little low on time, so I'm going to skip through some of the naive attempts. Essentially, a get request isn't going to work because the only way to include data in a get request is to put it in the uh query parameters. And when we put when we change the query parameters, uh we also change the which cache we're going to access, which cache value. Um so the only way to access that cached value would be to have the access token already and at that point there's no point uh searching or getting requesting it. Um here as we can see there food does not equal bar. So next option we can post it right we can put it in the body of a post request. Well no post requests are not ced by the browser. So the nails in the coffin, right? It's not possible to hijack the HTTP cache to use it as a database. Always give up, right? With a newfound respect for and a mild frustration at the, you know, browser security, uh, I gave up. Um, wanting a break from tackling problems, I started to inspect the network traffic involved in general Utre use. You know, sometimes when things aren't working, it's fun to watch things that are. And then I I saw a header in one of the requests. um Utre user Tom and that's not a standard header, right? You wouldn't see that anywhere outside of UTRA. Uh and that's because we can define custom headers. And so I thought, hey, what if we pass it as a header? Uh and that's exactly what we did, right? So we can pass uh some data as a header. uh and then we can send it uh sorry we can pass the data as a header uh in our request our get request uh to the back end uh back end can read the uh the header it can then echo it back to us as we see here uh and then we can just make the same request without the uh without the header and we'll still get the same response we've now used the HTTP cache as a database. Um, cool. Now, you're probably wondering if storing tokens like this is secure. And the answer is no. Uh, and so you probably shouldn't do it. Uh, so why am I mentioning this? Well, yeah, it's not great for secure like for for sensitive data, but we can use this for more ephemeral, less uh less important information. um uh for example right we can just use it for arbitrary data we can basically what if we create we have an API uh that is uh yeah basically it's it's a database that's keyed by the uh the query parameter that you send to it so for example if we make a call the local cache with the storage key of fu then the next time you make a request to uh storage key fu you're going to get your cached response Um and you'll get a different one if you make a request with storage key bar. Um we've essentially created a database a quick access database. It takes a bit longer to write takes you know however long the uh the time to send a response send and receive a response to the back end is but the read times provided the values are still there going to be in the milliseconds the like single digit milliseconds. Um and why is this helpful? Well, you know, before uh for our developers, if they wanted to store some data, they had very few options, right? The complexities uh of storing particularly something temporary like let's say we want to check is a tab selected or not. We just want to keep some like reactive UI state. Um well, for a front-end developer to to do that, they're going to have to get a new user extension property uh saved somewhere. They're going to have to def create two new uh HTTP handlers. Those are API endpoints. They're also going to have to then except that they're going to wait for a response which means the UI has to be paused or something so the user can't click the whatever. Um we got to wait for the server and that's another backend request to add to that that stream um of uh of concurrent request max like that we've got the maximum of. Now the only thing we really need to think about is is our key unique? Um yeah so to wrap things up um yeah building for track has been I'd say one of the most creatively challenging experiences of my career and probably in many ways some of the most educational the uh the constraints. So the sandboxing the missing APIs and the visual weirdness they uh they force us to solve problems that for basically every other platform have already been solved. Um, and and I think that's really a lot of fun. Um, thank you all for listening to me talking about loading and HP caches for 30 minutes. I hope some of you are still awake. Uh, and thanks to Jet Brains and the Utra team for continuing to build project management software that allows us to own our own data. Um, yeah, if you'd like to chat more about Utre apps, Depask or anything else, feel free to connect with me on LinkedIn or contact me via the uh Deep Task website. Yeah, thank you. >> Thank you very Thank you very much. So before I let Jacob talk because he not he knows much more about webdev and I hate it for passion but what I really admire is that you're scraping off some time to make it more performant because that's one of the complaints I also have in today's web appbased world where everything is a web app starting from your chat client to trading view right and all it always feels like I got a a big graphics card here I got a horribly large computer and it still feels sluggish. So, >> right. Yeah. Yeah. No, hey, I I echo your sentiment there 100%. >> Yeah. Yeah. Micro optimizations. This is just a part of the webdev game. Been there. That's why I'm uh involved in JVM for five years. >> Yeah. >> Awesome. >> Really? Well, uh um when you mentioned all the ReactJS libraries and uh other stuff you have to load and I bet there is many of them. >> There are many of them. Well, I just got goosebumps. >> Uh what about CSP content security policy? Uh is UTRA even allowing you to load something from external resources right now or you upload everything to UTRA? >> Everything everything goes into the uh into the the bundle. I actually haven't tried loading from a um yeah we haven't really tried loading for from a CDN um or anything. Uh and that's part of the uh it's because we we want the apps to be able to run without an internet connection. Um it's highly unlikely that our apps uh end up uh like even the users end up without a proper internet connection but just keeping it uh entirely bundled with the app uh ensures that it will always work. Uh and that's a big part of of what we want with our apps is for it to just always work. >> Yeah, that's great. Uh well, I I never dived into UTRA uh apps at all really. I tried but no I don't even try. I will not lie. >> Uh but do they really? >> Yeah. >> Sorry. >> Do you have any experience with our competitors like uh well Atlasian things? Well apps from Atlasian. >> Yeah. Yeah. Absolutely. So I mean I I was uh primarily an Atlassian um so Jira admin for the majority of my career and so spent a lot of time working with the Atlassian apps with apps from Atlassian. They've renamed anyway um built some both for for both their data center and their uh cloud platforms and certainly it's quite different. They they've put I mean they're much more uh much more mature ecosystems. Um, but what I'm really loving about uh, Utra app ecosystem is that it's kind of the perfect middle ground. Um, the apps run both on both cloud and server. It's the same build for both. Uh, and that means that we don't have to, you know, on on on server build these behemoth JavaS Java apps for doing something tiny on on cloud. We don't have to build SAS applications and keep everyone's data on cloud, which is kind of ideal, right? I don't want to have to touch anyone's data. I don't want to have to host it. That's not that shouldn't be my problem. But um it kind of becomes it when you work with some of the other app platforms of the other competitors. >> Yeah, that's awesome. Uh well we are a bit uh well we are heading 10 past 2 uh CCT time which means we have another uh talk around the corner but uh Patrick Ruffles. >> Yeah Ruffles I think Tomaso stays and Tomasa does the countdown from 52 to zero. Okay. Um, are you ready, Jacob? So, we're doing another raffle. We will we will post the question in chat. The first two answers and who did not already win will get a package from Jet Brains. So, um, Tomaso, please just count down from five to zero and then it goes up. >> Sure. Five, four, three, two, one, zero. >> Okay, >> lovely. So the question is what term describes reusable build steps introduced in team city to simplify CI/CD pipelines? First answer qu actions, second recipes, third workflows and the fourth is add-ons. Okay. Who knows the answer? Do you know the answer? >> It's not your area of expertise. >> You know what? I used to be have a team city certification. I've forgotten the term though. >> So I think the correct answer is two recipes. >> Exactly. And I see that correctly that Michael >> Miho okay Mihal okay was the first to answer. So Mihal please reach out to uh market bra marketplace and we will do another one because for we forgot the raffle and this time it's last time this time it's my my turn to um to countdown. Uh so Jacob you ready? >> Ready. >> Four three I started with four right. Yeah. >> Four, three, two, one, go. >> Okay. Is there >> All right. So, if you if you paid attention to Jacob's first talk, you should know that. Which dependency helper do you use to target Intelli? I couldn't even read it out and the first answers came flying in. >> I paint it to the screen. So, you can read it from the screen. >> Yeah. So to target intellig idea 2025.3 or later and the correct answer is one >> one >> and the winner is >> intellig idea. >> Yeah just intelligent idea. So um and the winner is deep. So deep if you would reach out to marketplace I'm sure we will post the um the email address again and then you will get a package. All right, Tomaso, thank you very much for joining us. >> Thank you. >> It was was really nice to have a a completely different type and learn something about webdev and focusing on performance. Lovely. Thank you very much. >> Thank you for having me. >> Yeah. Bye. >> Thank you. >> So the next speaker um is Mikail. >> Um >> um we should have Mikail with us, right? Mikail Solov. >> Yeah. Yeah. Hi. Okay. >> Hi, Mikail. So, >> um I see that that you're an experienced I I wanted to say old like me, >> but I didn't. So, you're very a seasoned a seasoned developer with more than 15 years of experience. Um >> you already have Jet Brains plugins. One is the Perforator and the other one is Desert, which is an AI powered context driven generation. >> Yeah. And today you want to talk about AI powered test generation straight from your debugger. And this is >> that's correct. >> And this is right up my lane with um with Rex and AI combination. So I'd say without any further ado, we give you the floor. >> Yeah. Thank you so much. >> Please, the floor is yours. >> Um yeah, so um I'll probably um um make some some comment about my experience. I'm not programming since a long time. These are my pad projects um desert and the perforated plugins and these are vcoded projects. So it will be my v coding experience and trying to build the plugins that would help developers. Um yeah so um it's the first one is a dert and I think I released it five to six months ago. Um and I will just probably describe how it works, what was the concept or idea behind it first and then I share my experience, issues I faced and the lessons I learned um on the way uh on releasing this this plug-in. So that was my first one. Um and I will probably start from how we write unit test, how developers write unit test and usually it consists of three parts. the arrange part where we describe our dependencies where we say okay we have um this input values which we are going to use in our test we will do something with this values and this objects we mock let's say um so in the second part in the act part we just describe what we exactly doing with this um with this values yeah if we have a calculator and we want to to add uh two to three and then we do the calculator add let's say and the last part is assert part where we uh check if our actual result is matching the expected result. Um that's like basics of of writing the unit test and um the question is um when we are using the LLMs um the LLMs really has issues of knowing what values to use and what are the dependencies and sometimes it's just the the place where we have a lot of hallucinations and we need to retry and and correct just to have a good unit test. Uh so the question is yeah um if it's if the values input values and the output values are not in the codebase so where we're going to take them yeah so what will be our source and the question is is it good way to predict them uh or maybe there is an option to retrieve them um from somewhere um so prediction means yeah it could be accurate because we're just predicting it based on our codebase so if we Say it's calculator. Okay, it's an easy example. But if it's something more complex, then it could be something tricky. Yeah. And then um you will just have more iterations to to to generate your unit test. So what about the retrieval um where we can retrieve this information and I would say there are two sources um or where we can get this information. The first source is human. Yeah. So we as a developers we know that um we need two and three and we will get five. Um so that's pretty clear. Another source of this information is our runtime of the application. So we can retrieve this information from our debugger which has all like the call stack. We see how we ended up here in this part of the code which input values produced and what are the output values. Um so it could be um an option for us um to to use a debugger which is already present in the IDE and contains this information and use it for the uh for the LLMs. So yeah as you can see here um when you're asking yourself what should I mock or LLM is asking itself probably what should I mock you can provide this information. So this was your uh call stack. So you ended up in this method uh and previously you called this method with this values. So you can it could be useful as a context for the the unit test generation and yeah so the same for the input and output values. So the debugger has answers for this and um I just wanted to um to have a big picture of how I wanted to build it um and what could be useful as a context for the unit test generation. So yes, we have our debugger as we discussed um we have all our values and dependencies there. Um we have our build configuration so we can see which uh libraries we are using. It could be also very useful when we generate the test. So we are not using some frameworks or libraries which are not used in our project. Uh so we can use the gradal file to um as a as a context um and our codebase. So it's it's also a good context um which helps LLM to uh to understand what are the dependencies and what sections of the code I should use to create this unit test. So our task is to get all this data uh all this context and maybe make one prompt that um that would contain all the necessary parts uh which would narrow down the the hallucination of the of the of the LLM and use um an LLM model. So in my case I used the Gemini. It also supports open open AI and entropic model um and then let the model generate the the file with test or update the existing file with some new unit test. And um the concept the idea here is very simple. So it's called theert because it's debugging and asserting. So it describes the workflow I think pretty clear. So that was an idea to to call it the desert. Um and and here is a short demonstration on how it works. Um so um I took the um the the sample uh application from the cotlin multiplatform. It's um um gallery where you can apply different filters and you will see how um I use it. I use the plugin to uh to generate tests for this for this application. So yeah, I put the break point um and start debugging. Uh so I want to debug the applying the grayscale filter. We're running the uh the app in a debug mode and the debugger stops on this line and now I can generate tests from from the values and it takes some time for Gemini to respond of course and then you have your file which exactly tests um what what is supposed to test. Yeah. So if it's a grayscale uh image at the end um so it's pretty easy and it's uh multiplatform compatible. So you can also use it for um for different platforms. I think it's pretty um handy. So and the the plug-in is available now. So as I said, I released this uh five or six months ago. Um it's available in your ID and you can also uh uh download it from the website. Um it's a open source project so everyone could contribute. Um and uh it's MIT license so you can do whatever you want and you can see on here on the screenshots how it works in in the basic yes so you have your ID where you can right click and generate the test. So the only thing you need is just to run this in in a debugging mode which means you need to configure your debugger. Um so the the problem the the the technical challenge for me was um even though it's a webcoded project you need to understand how it would generally work to to to write the prompt and the first thing uh was to understand how I can access the runtime data. So how I can access the the debugger and the Intelj platform SDK has this um part that the the framework or library a common Intelligj X debugger. It's an abstraction layer that allows PL plug-in developers to interact with debugging sessions. Um and basically it has different layers which you can uh use to access this data. So first is a debugger X debugger manager which contains different debugging sessions as far as I understand. Um and you can through this manager you can access your X debug session which is current session you you use in your uh debugger. Um and then the next step is you have an access to your uh stack frame. Um and you can see your call stack and then you can compute children uh which means populate the values from the current uh debugging session into the values. Um so then you can use it for the as a context for the prompt. So you can take the real values from from the methods you use. can take the call stack and use it as as a text in the prompt that you send to your l um and yeah so um there there are issues of course while web coding the plug-in so of course it's highlyating APIs that don't exist generic answers not specific to used versions so you start um building the project it fails all the time because something just wrong um uh and um yeah so it's uh it's completely random sometimes and you need to iterate over and over just to make things work and I try to do some basic things first and then on top of this build some additional functionality um so I have some some working state I can roll back and try again um and the third thing is missing clear documentation for the X debugger usage so the I found the the GitHub project where I looked how how it works just to understand for myself to validate the output of the of the model I used but still it's it's it's a it's a source it's not just a um damor it's not that easy for a beginner to to start with so that was my um my difficulties I faced and the lesson I learned that it would be great to have um u the documentation as a context uh for the LLM to generate the the plug-in. Um if you know or or some other developers know there is a context 7 MCP server which is basically um the database of documentation for different libraries frameworks um including uh intelligj ID um community edition uh which contains this um debugger API which I used um but I didn't use it back then so that was my issue that I uh I used um child GPT um it was even version four back then I think um and it was hallucinating a lot but if you want to uh reduce uh the number of hallucinations and reduce the budget you spend on on creating the the intellig idea uh ID plugin I would highly recommend to use the the context 7 I think it's free as far as I remember it's vector search behind it so it means that it will find semantically closer um pieces of the of the API and and it will just use it as a context for generating the new code for the for your IDE. Um yeah, so that's the lesson learned for for me. Um and other lessons I think it's general for for the software development right now and pipe coding is how to reduce a number of like the amount of hallucination and how to u build more accurate um and more specific software. So and what could be like what could be the source of the context in general apart from our codebase. Yeah, because yes we uh we we build software currently based on on what we already have in our codebase but there are a lot of other sources which u would be very useful same as for uh human developer but also for the llm uh so first of course it's it's a source yeah as I said uh and and here the different approaches um um cloud code as far as I know from reverse engineered um documents it's using the the grab and allows just to navigate through your codebase and find the relevant pieces which it includes into the um into the prompt. Uh maybe I'm not sure about the Juny maybe Juny use uh PSI the program structure interface which is basically a tree to traverse and find the relevant pieces of your code. It could be um also a good way of um um of of finding the relevant parts. Um yes um I'm not sure what what currently exists um what what navigates and index the code. Maybe there are some semantic search solution but it's quite quite challenging right now at the moment um as far as I know. Um yeah what else could be uh useful is data. So the MCP server that can access your test database and retrieve some values. So for example, if you're generating integration test, that could be very useful um to find some test values um like test products or test users. So that would be also relevant when you build some logic that is based on the current structure of your database. So everything which is related to the database including your schemas or including the direct connection to your database and retrieval data from there that could be also useful. Um three, infrastructure. Infrastructure is code. If you have like Terraform um there or you have something else that represents your uh infrastructure for example, you know your radius version and you know that this API would work in this radius version. Um this could be also valuable information for LLM. So it's not hallucinating too much and giving you something that wouldn't work in your case. Yeah. So it's taking versioning into consideration. force is a documentation um as a code. Uh yeah, it makes sense to to to keep it in in the codebase and and um as a context for for the new code generation to give a to narrow down again and giving a little bit more insights for the L model what's uh how it works without getting deeper into the methods and the code lines and as I mentioned context 7 is a great uh addition to that if it's if you are dependent on some other libraries um and in frameworks or programming languages. So you can contact Context 7 contains the up-to-ate documentation or and can also help you to reduce the budget on generating um your code. Uh and the fifth is where I tried to focus um is uh to use the runtime information uh which includes a debugger which I use in the in the desert plug-in um which which takes the runtime data. Um there also I know that the corsur is also looking into the debugger to get the runtime uh data to identify the memory leaks and so on. Uh so that could be also helpful when you're trying to generate or refactor the code and make it more performant. Um also observability tools is a great source of of um often context for the LLM um because uh it like what you see locally with your profiler is not the same as you see in production. You have way more use cases. You see what works slow, what affects conversion and where you have the bottlenecks. Um basically because you have a bigger database in comparison to your local database um usually yeah so it doesn't mean that it's always like this but uh usually it is like this um and that could be very useful to get this bottlenecks um and the flame graphs and um to use it to refactor your your code um also BI tools which is potentially could could be also helpful uh and and to to retrieve the information about what the customer journeys are, what the places which are most critical for the conversion and so on. So that could be also very useful. Um and talking about observability, um that's a topic I wanted to start with talking while talking about my second plugin which I released about months ago which is uh called perforator. Um and yes, as I said this, um this is a Graphana Pyroscope by the way. It's a continuous profiling tool same as new relic or maybe data dog or in stano if if you use something of that I think that's that's a great help for every developer because you see how your software behaves in in real life and where you have the bottlenecks um so um yeah so you can use the flame graph view and to identify this bottlenecks and um Here is just an example. This is a screen I took from from their uh GitHub repository. Um so yeah, you can see that there is an example of the application where you can order car or bike or scooter ride and you can see in this application that yeah we have a car service order car uh method which takes most of the time. So this is a place where you want to focus and to improve your performance. And the question is would it be helpful for developers to see uh this uh continuous profiling information in the ID and I think yes it is um it is useful um so it's it's more visual for you uh how your code affects the customer experience and where you want to focus um um your your efforts to optimize. uh also would be great to have this information to uh to refactor it with the AI agents. So yes, talking about the the plug-in, it's called perforator um because of performance and it was just the the name I wanted to use. Um and this is the workflow how how it works. So um I took this um Java application sample Java application which um uh where you can book the ride um and it collects the Java flight recorder profiling data and exports this data in a periscope which I think stores it in in a um PROF uh format and um with a perforator I retrieve this data over API in PROF and then I render it uh in the IDE itself in the intellig idea and I showed this this labels with a red or silver showing this is the the the places where it takes most of the time and these are places where it's it's okay. Um I also added integration for Google Cloud Profiler. It's the same concept as Graphana Pyroscope. The only difference is uh that Google cloud profiler provides API but it seems like it doesn't work uh uh in in terms of retrieving the CPU data and memory data. So it gives some general information but I wasn't able to extract this data the performance data from there. So I built a a smaller version where uh you can download the the profiling information and upload this in the IDE. So Pyroscope the the perforate is using API to connect to the Pyroscope and retrieve the data and it's using the file for from the Google cloud profiler. So you need to go there they load the file and upload it into the perforator. Um so yeah unfortunately that's not working with the API for for Google but hopefully they fix it and or maybe I find the way how to make it work and then um I can also add it. So it's very simple to use. Uh it's in the tools you just fetch profiling data. Previously you need to configure in in the backend settings um uh your API endpoints your credentials and what type of data you would like to retrieve and what will be the time span. But when it's configured you just fetch providing data. It will collect all the data for your application for specific period of time. Um and then you will be able to see the the bottlenecks on this left side from your from your source code. Um it's similar to uh to the um profiler which is built in into the ultimate version into idea but uh I had to build it from scratch because it's um it's not part of the community. I just wanted to have this uh plugin available for everyone. And at the final you can adjust settings. So you can choose if it's CPU or memory. U so you can find how much memory is allocated for specific method or you can you can uh change it to CPU and see um what's the what the time used for the specific method and all the methods which are used in this method. And then you can also switch to the CPU time uh sorry to the wall clock time in the Google cloud profiler. Um there is some difference but I will not get deep into this. um so yeah you can define the threshold and you can define the time. So you can say okay I need the information uh providing information for the last 1 hour 3 hours one week uh and this is my threshold. So I want to IDE to show me uh all the methods which are above let's say 50 milliseconds. Um yeah so that's how it works and this is the demo uh this is the application I used it's also uh taken from the GitHub repository of the profana pyroscope uh it's basically simulating the uh bride booking uh uh application that works in different regions and collect the profiling data from different regions into Pyroscope server and my plug-in is connecting to the server through and retrieve the data and shows all these labels in the in the ID. So here is a short video. Um I think I start with yeah fetch profiling data and it's the pyroscope. So you can see and you can right click on the badge copy the prompt and use juni to to refactor um this piece of code and juni connects to the pyroscope through the MCP server. So it collects also all the relevant information uh which is specific to this method. So it's uh it's it's not just uh taking the information hey um make this uh make this method more performant but it also takes uh information if necessary from the relevant method and its performance. So I think it's quite useful way and quite um efficient way of doing the performance optimization. Yeah. So in case let's say you have an application and you have an SLO um and you see that you are over your error budget for this month and you want to invest more time into the um into the performance optimization uh make your website respond in a faster time. So you you just do this and it would save you a lot of time I believe and I hope um so yeah another uh use case is uh is cloud code um in uh in intell ID so it's a Google cloud profiler you download it from the uh Google cloud profiler and you upload the data so you just upload the file here it will parse it uh from the pro format and also will render the badges Um, so you can just rightclick paste the same workflow place the the the prompt submit the prompt and let cloud code uh do the stuff for you. So I think here it just suggests improvements or you can in my preferred way to use journey um same um same approach copy uh apply threshold paste here and Juny will just do all the work for you uh will suggest the refactoring so it's also very very useful um I would say um also available right now as I said one month ago I I released it I don't have many up uh downloads but uh maybe after this event it will be more so I hope so. Um and the cool thing is um um it was uh u so the developer of the Pyroscope the graphan Pyroscope the ramper he sold this plugin and he said well that's cool I want to uh I want to make my own for for VS Code and he released uh his own for VS Code as as being inspired by this this plug-in. So I'm very proud that my second plugin was already um had some influence and that for me it's it's a pleasure um that that it happens. Yes. Um uh the issues I faced uh as I mentioned um I wanted to reuse the the performance badges uh into of the profiler which is built in into the intellig ID ultimate but I didn't find how I can do this. I think they are not part of the community um um source. So probably probably that's correct that I wasn't able to do them to implement them. So I was uh able to make them from scratch. Um and that was I think the trickiest part of all the wipe coding part. Um yeah, so I I think it's well better done as in comparison to my badges because you can see a lot of valuable information and my version was very uh simple but I wanted to start simple and um so making uh own good is not wasn't that easy. So I had to um create my own renderer for the icon and use graphics 2D library to to draw the pages. And the second step was to implement the annotator which is waiting uh it has a dumperware which means it's waiting for the indexer to finish indexing the project. So it can identify and map um the the methods which I take from the flame graph um to the methods I have in the project. So I can so the the plug-in can understand where to render this badges next to which which methods. Um and third was to to override the annotate uh method which decides which lines needs badges and um yeah you have the range highlighter where I where you add this um this renderer uh to so that was the final step of uh of the logic that renders this. So I think if if someone is interested can have a look into the the source code. It's not the best. As I said, it's webcoded. So, um I I I just wanted to make it work until I uh until I focus or spend time on making it really nice and um and easy to for for other developers to contribute. But if you're interested right now how it works, you can have a look. And if you have some ideas for your plugins which you want to add some information um next to to the code that would be also maybe helpful for you because there's not much documentation online which you can use to implement something like this. Um and probably some thoughts I would like to share uh the role of ID uh and for me personally it feels like it's getting more a context manager for the code generation. Yeah. So I was talking about the different sources of the context not just the codebase but also all all the ecosystem documentation infrastructure database um maybe something else runtime uh which I use uh and I see that other people go into this direction so that's probably the next role of ID if it's not already a role of ID to manage this context and to get all this information which I think in most of the cases is bigger than the context window and try to summarize it and put it together in a way that it reduce the budget for the code generation make it more accurate um and saves time um and while I was developing my plugin um the second plugin the the the perforator I faced the issue that yes I want to use the AI agents uh like Juny or cloud code but I'm not able to send my prompts and and trigger the the the process. So, um it would I think it would be very useful. Um and I think that could be also uh an addition to my first plug-in to desert to let the AI agent to change the code according to the context I give. Um maybe I didn't find the way how to do this but I checked the the if there are any actions which I can use from the Juni um plugin or cloud code plugin and I didn't find it. So that would be a a better way because currently I implement the copy and paste. So I copy the prompt and paste this into the into the journey or cloud code and let it um and and submit this prompt. So it would be great if I can do this automatic. that would be my way smoother approach in my opinion. So uh I took an action and created tickets uh to to make it happen. So I created ticket for Juni um in in a youth truck and everyone who is with me and and um and want to to have an possibility to send prompts from your plug-in to Juny to let Juny do something for you. uh you can go to this uh to to UTRA and vote for this and maybe add your comments that it's would be very helpful for you too or if you are uh developing for cloud code it's also an option you can go to the entropic git repository um and for the ticket 7005 you can also vote and uh add your comment there I would it would be very appreciated if if you if you could do this and then if you think that would be valuable for you too of course. So please vote um and um yes so these projects are open source they are on uh GitHub everyone who who wants can just join and and do whatever you want with this um um and uh they under MIT license. So yeah um and this my first uh two plugins so please don't be uh too uh uh picky about this. So and of course um everyone who wants to contribute are very very welcome. Um yeah so I would say that's uh it from my side. Um and um if you have any questions I would be glad to answer. Thank you very much. So, um, we need to hurry up because I have a million questions and I want to at least ask one or two. So, um, you were asking about Juni and how it feeds basically how it gets the context. So, we have several things. So, until a few until a few weeks ago, that's my my my up-to-date version, right? Juny was able to read files and get parts of it and include it in the context but it did not use the PSI to traverse the thing >> and I think um what you mentioned we have basically two use cases also for your plug-in. So first we have we we have code where you want to create a test from and you probably want to discover where functions are defined that are used within your stack frame right so that's where you would use the psi for but also you have probably the thing of discoverability where you say okay I need to find a function that does something like that right and that's where a vector store comes in and you can compare the vectors so my question is and that's a problem in general we need to include all the information in the context and send everything over. So this is probably the whole stack trace, right? A lot of uh context values like your variables and then an unknown amount of of code that we need to give basically the LLM to make good good decisions what what code to create and what to look at. Right? So did you ever think about or run into problems basically where the context is just so big that your tokens explode? >> Yeah. Uh in my case um I had just some limits on how many um like what what the amount of uh of the data I sent. So the number of um uh of the the call stack methods which I which I use. So of course it's uh I think in some cases it could be fragile to be honest with you because it's yeah it's it's the first plugin I created. So I wasn't that didn't didn't try to make it perfect. Um so but in in a test I made it was um enough to to not to explode and not to break the the functionality. So I was even using the um the flex version of the Gemini which was free uh to use um and that was sufficient enough um uh to to provide some input values the output value and and few um few methods which were called in a in a call stack. >> Yeah. But yes, you're right. I mean, um, again, uh, it's the same point that I was talking about how to fit all that stuff, all this context into the limited, um, >> context window. And I know that Google goes in direction of having big context windows in comparison to other models. >> Uh, but I think at the end it will be still smaller than everything you can put into. Um and regarding the vector search I was wondering if if it already exists or somebody's work actively working on it and I thought okay that's very challenging problem because if you want to let's say build embeddings for for a method which is less than 4 kilobytes and you use thousand embeddings you have four bytes uh coordinate then you have 4 kilobytes for one less than 1 kilobyt of code then it will be a higher ratio of space you're using for the vector. I was wondering if if there is a good solution which currently Jet Brains is working on um that that would allow developers to use the the vector search and semantically find the relevant pieces of the code. >> Yeah. So I I can assure you we have something in the oven that I'm probably not allowed to talk about so I won't do that. Um but we are aware of the problems right? Um and as you can imagine if you develop plugins right you have to you have to base it. So any if you want AI help uh in from in plug-in writing then you have the whole platform code that you probably need to give access give access to and then >> right you have I don't know 15 million lines of code or 10 million lines of code right >> so we need we are working on that and that needs to be solved and not only for us for basically everything >> right yeah because as soon as you're not working on a a medium-sized project where you can pick the information uh you're basically uh really bounded by by the context. >> Yeah. I'm looking forward. I think that could be very very helpful. >> Yeah. Yeah. All right, Michael. Thank you very much for your talk. Um glad to have you here. >> You're well welcome. Thank you. >> Come come back. Come back again. >> Yeah. >> Thanks. Thanks for having me. Yeah. >> Okay. I think the the next step is to bring Matias on stage, right? So >> good morning >> everyone. Welcome Matias. So Matias is working in the net advocacy team and he wrote plugins for I think reharper. Is that right? >> Android and Ryder. Yeah. So >> Ryder Ryder. >> Ryder. >> So we thought we just bring another advocate advocate here. Um and Matias will basically uh take over as a host for the next um for the next talk. So I give Matias the stage. Please. >> But we should run raffles. >> Ah, yeah. I forgot. I'm sorry. I'm sorry. So, Matias, we need to run raffles. So, you do you don't need to do anything except say count from five backwards and Jacob will post the question and the first two answers correctly in chat will get a package. >> Can I can I also can I also count? >> Yeah, you can also do that if you like. >> No. Okay. 5 4 3 2 1 Be quick. >> Be quick. >> So the question is which mode do you need to switch to in Cotlin notebook to enable intelligent platform integration? One run in debug mode, two run in IDE process, three run in platform mode, and four run in notebook runtime. Okay, >> Jet Brazen. >> Answer is >> Jet Brazen. I I wish I was there for for for that raffle, man. >> Yeah, everyone said Jet Brian and it was good because we we do this ourselves. >> Okay. Uh the correct answer is uh run in ID process and Christian Schuler. It's >> Christian Dish. Okay. Uh, so >> and I think we shoot we shoot another one right after it. >> Yes. Yes. Yes. Yes. Yes. >> Everyone get ready. >> Matias your job. >> Okay. Now I count the other way. Okay. No. >> They're coming. And the question is which product doesn't have extensions available in jet brains marketplace one matter two team city free utrees >> okay team city and utra do have access >> okay so okay people we just had we just had a presentation about UTRA who voted for UTRA Yeah. Uh so yeah, it's all about matter. >> Okay, maybe I read again. Which product does not have extensions available? Oh, and there we have it, Andre. >> Um actually, we had a call answer posted before by Mr. Toby. >> Mr. Toby. Yeah. >> I don't see it either. >> I don't see it either. I I thought that was for the previous question. >> Maybe, maybe, maybe. Yeah. I think Okay. >> No, no, no, no, no. Jacob is correct. >> You need to look into the into the you uh YouTube chat. >> Yes. >> So, Mr. Toby, I'm sorry. Um we didn't see it here in the streaming software. So, I think Mr. Toby was first. >> Mhm. >> Mhm. Okay. >> Congratulations. >> Yep. >> Congratulations. a Jet Brian's >> Jet Bry >> package. >> All right, I think we can move forward to the next talk. >> Yeah, good good job by the way, Jacob. I think you had two already. I was I was um joining in a little bit later, but you had two talks already, right? To you and everyone else, great job so far. I watched a couple. >> Yeah, it's it's really great great show today. Okay. So then let's uh bring on the next uh speaker Nikita Katkov. Uh he's very very interesting topic actually because Ryder was yeah kind of had to deal with this uh a lot. Um the the topic is uh is titled making an IntelliJ plug-in remote development friendly. I'm really looking forward to see some Necad being synchronized on two ants, but yeah, probably it's a little bit different. But folks, everyone have fun and yeah, see you after for the Q&A. >> Hello plug-in developer community. This is Nikita Katkov, a member of the remote development team at Jet Brains. Today we'll explore what makes a plug-in remote development friendly and how to adopt existing plugins for working in a distributed environment. First of all, let's get ourselves familiar with the terms I'll be using. Remote development or remdev for short or split mode simply means that IDE runs as two separate processes, front end and back end. The front end handles the UI while the back end manages the business logic, works with project and does all the heavy lifting. We'll cover the following topics in our presentation. First, why remote development compatibility matters to you. That includes what motivates users to switch to remote development, what's wrong with existing non-native remote development plugins, and how the UX differs between a regular and remote development native plug-in. Second, we'll cover how to write or migrate a plug-in to make it remote development friendly. That includes what project module structure we'll be using, how to set up a front and backend communication, how to organize build scripts. We'll also look through a backend frontend specific APIs list. And finally, we'll assemble a stepbystep refactoring guide. At last, there will be a question section. Since unfortunately this time it's a pre-recorded video, kindly save your questions until the end of the presentation when I'll do my best to give you even more information and context. First of all, let's answer the question why the remote development might even be important for you. According to both internal and external surveys, cloud-based development is gaining widespread adoption. Up to 52% of developers have tried remote development solutions and around 36% of them use them daily. Chances are your users already need to work in a distributed environment. This info in the slide is taken from the deva survey conducted by Jet Brains at 2025 and the state of application development survey conducted by Docker. Is there any difference from the UX perspective between the native and non-native plugins? In this slide, you can see the two screencasts. I try to select the same three node in both of them. On the left, an action takes a long time to complete. There is a clear delay between the click and the reaction. On the right, an action is instant and the user experience is very smooth. The node expands immediately after clicking on it. What happens here is simple. If you do nothing with an existing plug-in and use it in a split mode, you'll likely get an experience show on the left. The plug-in runs only on the back end and every UI interaction goes through the network, which adds latency. This setup works out of the box, but it's slow and frustrating when the connection isn't perfect. On the right, the same plug-in was split for remote development. The UI part now runs on the front end and only data is exchanged with the back end. That's why it behaves fast just like in a regular monolithic ID. So the goal of this talk is to explain how to move from the left side to the right from legend and back end only to smooth and remote friendly. This slide attempts to demonstrate even more frustrating thing, scrolling. I scroll the mouse wheel at exactly the same pace, starting the same moment on both pictures. On the left picture, it takes about a second for the actual scroll to happen after I touch the mouse wheel. On the right picture, scroll itself happens immediately, just as you may expect from any UI application. It is quite hard to depict the UX through a screencast, but believe me, it's enough to experience it yourself only once to realize how poor the UX feels. The good news is you can adopt the existing plug-in to work smoothly in remote development, making it indistinguishable from monolithic one. But before discussing the ideal setup, let's briefly take a look at the very simple regular plug-in that doesn't know anything about remote development at all. This will help us understand the general idea behind the refactoring approach I'll soon present to you. Imagine we've got a plug-in that's simple as in the picture. It implements a go to declaration feature for, I don't know, a proto file. Doesn't really matter. The plug-in finds a corresponding Python script generated from it and provides ability to navigate there. Very likely such a plug-in looks like this. There is a single plug-in.xml file describing all extensions and dependencies. UI and business logic are separated at the classes level, for example, via the MVC pattern, but they're living in the very same project module. Plug-in descriptor declares a dependency on Python module as well as registers its extension to do the actual job. Look up the appropriate Python files. Now we want to extend the plug-in functionality by introducing another navigation handler. This time for generated goal and code. Our project has grown and we've hired new programmers who write their microservices in Go. Okay, let's try making their life a bit more convenient as well. The plug-in can now assist both Python and Go developers. But wait a minute, what does it plug in XML looks like now? To be able to access some Go specific classes in runtime, we had to declare one more dependency on the Go module. Well, currently our plug-in is twice as smart as before. It supports two languages simultaneously. What it also does simultaneously, it depends on both Python and Go at the same time. That in turn means that Go developers will have to have Python plug-in installed just to be able to work with Go code. That sounds strange, doesn't it? On one hand, luckily, our users can set up the ID with both languages supported at once. But on the other, does it even make sense? And what would happen when we add more and more features to our plug-in? What if only one of features A and B can work at a time? It seems that we lack a way to add the specific functionality to our plug-in that will turn itself off in case it's not applicable. And by turning off, we mean not even trying to load the corresponding classes since their dependencies are not available either. A solution would be to introduce a dedicated model for each independent major feature. Goan code will reside in the golden module. Python code will reside in Python module respectively. There also might be something in common between the two. Let's put it into a shared module between the two to benefit from reusing the same utility code here and there. Now we are getting back on track with the remote development. Finally, let's imagine another a bit more different and complicated plug-in that employs an external process to provide some useful data to the end user. Let it be an LSP server or you can pick any technology of your personal choice. Server returns validation data regarding a file currently being opened. To display the results of validation, the server needs some UI. For simplicity, let it be a dedicated tool window that renders beautiful validation results page. So again, what we are going to do here is to register both tool window factory and the LSP server provider in the plug-in.xml file. We were told to do so by the official documentation in the first place. That's right. However, we have now encountered the very same problem we faced with our previous Python and Go plug-in that handled both Python and Golden. The perspective has changed slightly though. Previously, we supported the same feature from different language perspectives and now we support the same feature from a UI and interprocess communication point of view. Any chance we can solve the identify problem with conditional loading? Are there any ways to have a single plug-in capable of working with many kinds of environments? Be it PyCharm or Goland, front end or back end. A remote development native plug-in mirrors the split ID architecture and it includes a set of front-end specific features enabled only on the front end. a set of backend specific features running only on the back end and shared logic between the two. So how do we implement such a layout? Okay, for a while we've been internally using the so-called content modules concept to handle different dependencies effectively. For example, if your plug-in provides Goland specific functionality but should still run in PyCharm, which lacks go related code, of course, you can extract the Go features into an optional content module. If its dependencies are not satisfied, that module simply doesn't get loaded, but the rest of the plug-in does. Now, imagine replacing Goland with front end, PyCharm with back end. Nothing changes. And the very same concept applies. Remote development native plug-in therefore consists of a dedicated front-end module with mostly UI components and its dependencies. A dedicated backend module with mostly business logic and its dependencies as well. A shared module with common code mostly RPC interfaces for bridging front end and back end. A root plug-in.xml XML file listing all plug-in modules that can be enabled and disabled independently. On the slide, you may observe a special syntax to use in the root plug-in.xml file should you decide to modularize the plug-in you are responsible for. Note how our front end module declares dependency on platform.frontend front end to indicate it has to work in the front end ID where the UI is. It also depends on its own shared content module just to be able to use classes from it. Same goes for the backend module. It depends on platform.backend and its own shared module as well. After creating a few modules, we now have to link or connect front end and backend code. But how can they communicate without having a direct dependency on each other? Here we use RPC or remote procedure call, a familiar concept for many developers. From the example on the slide, you can see a small RPC interface that the front end uses to retrieve information from the back end. The back end in turn must provide an implementation for the method being called. Our implementation runs over a secure protocol and it utilizes the cotlin x.zation framework for data exchange between front end and back end. By the way, it's Cine friendly. On this slide, you may see an example of serializable classes that are transferred through a wire when a function argument is passed from the front end via an RPC call or when a result is returned from the back end. Getting back to our sample plug-in with good module structure. To make it actually work, we now have to add RPC interface and its implementation to the appropriate modules. And we are good to go. Last but not least question, how do we build a plug-in like that? The answer is using the intellig platform gradal plug-in and some of the gradal best practices. With our help, we have created a plug-in template that includes all necessary infrastructure to start development right away. This template provides a multiodule gradal project with properly configured dependencies between front end, back end, and shared modules. There are a bunch of tools in our Gradel plug-in to tweak the ID you are building a plug-in against. Among others, there are remote development configuration options depicted on the slide. Should you decide to test an old plug-in installed solely on the back end or play with its new version available on both ends, everything is possible out of the box. The template also includes RPC and serialization plugins extracted into so-called cradle convention plug-in and the example feature implementation as well. Namely, it is a mock AI chat because it's never too many of them I guess right. The presentation will of course be shared by conference organizers and you'll be able to look through the links given in it including the template of course. Please refer to it when it comes to splitting the existing or writing your new plug-in. What else do we have to cover? It's a general guideline which APIs to use where. The platform does have a lot of them and it's not obvious which things belong to front end to back end or can be touched anywhere regardless the IDE mode. I'd love to get you familiar with a short list of core APIs one should use on either front end or backend side. First consider having the following API usages in your front end module. any UI components, dialogues with tool windows, editor UI, JCF, browser, etc. Secondly, action system. Since actions are essentially a reaction to user input, they must be quick and they must get updated in time. So they naturally belong to front end. Should they do something heavyweight and touch entities not present on the front end, it is fine to delegate execution to the back end but not the update. Next is PSI3 if available for a particular language. Of course, please note that we have already migrated a lot of languages that have bundled support in intelligj based ids. And last but not least, RPC calls also belong to front end. The next list is purely backend APIs. First it is a virtual file system. Next indexes again very heavyweight. Then goes version control system as well as external processes related stuff. It might be exec util process handlers run debug or build related stuff and so on and so forth. PSI tree is here again because usually it is a shared entity. In fact, front does need it because it handles typing while back might need it to perform some heavy and possibly even projectwide analyszis like inspections. Next thing in the list is remote topic. It's a sort of reverse RPC uh meaning that it's a backend initiated signal to the front end. And last RPC implementations belong to back end as well. Okay, who let's summarize this talk with a stepbystep guide on how to create or migrate an IntelligJ plug-in to make it remote development friendly. First step is to create a set of modules. Use the provided template as a reference. There will be shared front end, back end, and maybe some other modules of your choice. But this is the baseline. Next step is to decide whether your plug-in is more UI oriented or it has more business logic code in it. After making such a decision, you have to move existing code to one of the modules we recently introduced. If it's UI heavy, move the code to the front end module for the sake of simplicity of further refactoring. Otherwise, if it's logic heavy, move the code to the backend module accordingly. Let's assume our plug-in has more UI related code inside it and less business logic. It makes sense to try having all the code in the front end module and then switch to the next step which is very crucial by the way. It sounds rather simple yet it requires quite some attention and analyzis. It is to identify the boundary between the UI and business logic. For instance, if there is more UI related code in the plug-in, we have to find where the components do get their data model from. Then we'll have to extract the backend specific code into its own module which we have luckily created on one of the previous steps. You might expect broken compilation at this stage and that's totally fine. It's going to be addressed really soon. Next step number four I believe is to introduce an intermediate abstraction layer. Let's call it remote feature model. It should belong to the front end module. We will now start fixing compilation issues introduced on the previous step. To do so, we have to replace direct backend API calls in the front end module with this very new obstruction we have recently introduced. Finally, in our new remote feature model, we'll have to employ RPC to get the actual backend model state. Where there was a request to find a file in the file system, there will be an RPC call that shadows this operation on the back end. Where there was a search for all usages of a particular Java method declaration to estimate their number, for instance, there will be again an RPC call that retrieves the information from the back end. who actually knows about Java, its declarations as well as the other files in a project. Either we can make a direct RPC calls on background threads or we can introduce a more sophisticated distributed model with eventual synchronized state and uh use it on the front end side. The model will get subscribed to the backend state updates and will eventually reflect these changes in your UI component. And we're finally done. Congratulations. Next, I have a few really frequently asked questions which I'll like to address before switching to your questions. And first of all it is well how does the suggested plug-in architecture work in a monolithic ID and the answer is just fine because the monolithic ID is essentially both front end and back end in a single process all dependencies will be satisfied and RPC calls will be just a suspend function calls with little to no overhead so you don't have to worry about it a single single architecture for your plug-in which will work in any environment. The next question is is it even safe and secure to send some data over RPC and the answer is yes it is. Our protocol which we use underneath the RPC is encrypted with TLS. So no worries about it either. And the last question is whether it's okay to call RPC methods during UI components initialization. And here the answer is no. It is not. Please consider either fetching the necessary data beforehand under a progress indicator by the way or implement a background data synchronization between the back end and the front end and always work with the data snapshot that is already available on the front end side. And that's it finally from my side. Thank you very very much for your attention. Your questions are very welcome. Please. >> Thank you Nikita. So finally we have you live here. Hi. >> Hi. You're very welcome. >> Great. Great detail. Uh very good practical advice also. And last but not least, applause for doing this pre-recorded because this is takes some time. Yeah, I >> can imagine. I can imagine. >> Um, so yeah, we have a couple of questions. It was actually also very interesting to see this, you know, with a background about uh writers uh work there with remote development. Um but yeah, one one question that I'm curious to ask is uh how do you actually test this you know under certain conditions like something that I remember from from web development is that you can select okay what is my connection uh how much data can it transport do you have something similar for testing uh remote dev scenarios as well >> or how do you prepare for for uh you know >> problematic situations? >> That's actually a good question. I should have covered it in the presentation. Um, yes, we do have a quite easy opportunity to test the remote development setup which is uh called like connection widget. uh to be able to access it one has to enable the internal mode in the ID I believe and that's all the requirements and on the upper left corner there will be a widget with u actually many many settings in it but what you should seek in it is a direct delay option uh you simply specify some value in milesc like 100 a thousand or whatever you choose and uh that simulates a connection like poor quality connection. Okay. >> Uh and with this setup uh you can just click uh in your plug-in features like test the UI, test some I don't know completions whatever it provides and see whether the feature a specific feature you are developing at the moment is affected or it is not. Um that's it. That's what we mostly use ourselves. And of course you can try the the real world setup a little bit more complicated. So for local development it's really good one. >> Exactly. And also start an ISO download dur during trying this out. Okay. So um internal mode and connection widget it was called right. >> Yes. Correct. >> Yeah. All right. Thanks. That's that sounds good. Another question. Um Patrick or Jacob? Anyone of you wants to ask a question or should I ask all the questions? I'm also fine with that. We have one from Y. Yeah, we got a question from Yahim in chat. So Yahim asks, "Are common features like inspections and intentions remote friendly by default or would I have to implement this for each of my inspections and intentions?" >> Mhm. Got it. Good question. Um, so inspections it's definitely yes. uh in general all the highlighting related stuff be inspections annmentators maybe we do have something else that remember uh quickly uh they naturally belong to the back end I would say because they usually require some additional knowledge either about the project about the files about name your technology here um so they work there and they deliver the uh ranges they would love to highlight and uh some fixes as well to the front end where they get applied to the actual editor. Uh as for intentions, uh here I would say it's a little bit more complicated. By default, they do belong to back end as well. So they will work definitely. Uh it might be that if the intention like affects a very um let's say it's a really really local thing. So it does affect only the current file or maybe I don't know what exactly your specific intention does. Uh it might be better to register it on the client side so that it just gets uh executed quickly but uh in general I would say that it works fine out of the box. >> Mhm. So uh I may I maybe have a question regarding that because I think um intentions and my question about action. So when I think about an action right so right now you have basically all the implementation so you have your front end implementation into one file and as when I understand you correctly now I have to split it into back end and front end right so for an action I have basically the quick check if the action is available which should run um in the EDT and then basically the hard stuff when you invoke the action is not run on the ED or can be can access basically um the the real heavy backend stuff, right? So, do I need to split up the action code now into the hard part which goes into the backend module and the the light part that that stays on the front end? Um I'm not sure I I got that. >> Mhm. Okay. So, small correction before I try to answer the question. Uh so when I spoke about actions I meant uh like the real uh action system API which is an action class action right yeah >> yes and uh what it does internally is essentially two methods it's first it's the update and second is uh action performed so update is uh uh executed it it know only gets executed on ed by the way but uh it should be executed on the front end side so that the update uh doesn't uh get affected by the latency. Uh otherwise you'll see this weird loading indicator somewhere in the context menu for example and that doesn't really make sense and usually the update is quite simple. So it is enough for it to just check whether I'm displayed in a some specific place which is correct. Maybe I'm touching the right file which is uh which the action is applicable to and that's fine. Uh but the action performed it's a little bit different story because it really depends what the feature is. If the action performed actually does I don't know print something to console. Okay you you may do it on the client side and do not split the action. >> Let let's assume it's something heavy right? Something really heavy. >> Mhm. uh if it's something heavy, it probably belongs to back end because it usually touches entities uh that are registered on the back end and they belong to the back end. Uh and this in this case it makes sense to just extract the implementation of action performed method into the backend module and connect them via RPC as I described. That's it. >> Okay. >> So usually it's like reasonable amount of job. >> Mhm. Mhm. Okay. It's it's highly interesting topic by the way. It's really nice, right? I mean, >> yes. And it's also evolving. So, we do realize that something is still not like far from perfect. Uh, but we're working on it. I promise it will get better. >> If no one has a question, I have another one. >> Okay. I should So, go ahead. Um I mean it's not remote development but we have code with me which touches a similar topic. I type something and it needs to be synchronized with with the other client who is coding with me. Um will basically your work on the remote development influence that so basically that that code with me um uh works better. >> Mhm. Uh that's >> you're laughing. I I see I see you laughing. I'm thinking so honestly I don't have a really good uh good answer to this question because it uh sorry again it depends um in general one may implement a remote development friendly feature which will also work well in uh uh code with me but that requires additional efforts because you know many clients you have to maintain this uh connection between second and the first client, the second and all the the rest of them. Some features are like client independent. So you show the very same content and in this case it is like literally the same as remote development but uh others they are not that simple and uh they will likely require something else. Uh I'm not sure what exactly it again depends. So okay in the scope of this presentation I decided specific not to mention it because it's too complicated I think let's start with remote development and as soon as it works well we'll think about the many clients case >> fair enough I I think we got another question from Yakim are read action write action and so on expected to run only on the back end or are there additional threading requirements uh for split plugins plugins Good question as well. Thank you. >> We're asking a lot ones here. >> Uh yes. So uh let's split the question into two parts probably. Uh so read and write locks, read and write actions, they exist, uh for the cases when your feature touches any uh project related model be it PSI like file system uh maybe something else. Um and in case for example if you do touch those systems on the front end side in your split plug-in that just does make sense to employ the very same approach you did uh before in the monolithic plugins. Um for example if you do work with PSI um as for anything other than the existing APIs uh there is nothing I think nothing specific. So it's just a uh good practice or okay it's not even good practice it's a requirement not to try uh invoke RPC calls on EDT because you know it it's a very bad practice and it will uh you'll end up having either freeze or some weird behavior uh just like with any other IO operation which is done on ed other than that I think that's nothing I might be missing something but uh what comes to my mind quickly is that >> all right so if there are no other questions >> it's interesting Patrick I had a I I had a very similar question to yours but uh related to the RD protocol and writer because I think they faced a sim a similar architecture uh but not the problem of it doesn't happen on a single machine you know so they had the problem of uh communicating between front and back end um but all same machines so no latency probably but still keeping uh data in sync and etc. So yeah, we same thought there. Um, thanks Nikita. That was that was really great. Uh, thanks also for actually joining because I heard you're on vacation right now, right? Is that right? >> Uh, yes I am. I'm I was mostly concerned not about the vacation but about the construction works that uh does happen at the moment as well as about the connection quality. So I collect all the possible excuses for uh making It worked great. I I I guess uh YouTube uh worked worked very good on there, you know, uh keeping keeping latency low and um fixing connection issues there. So, no problems at all really. Um >> thank you for that. Um I think we head over to our next speaker, right? >> Raffles again. >> Raffles think you need ah Ruffles. Okay, then Nikita, it's your it's your stage to count. Yeah. I had the pleasure already. >> So, we have Raffles, Nikita, quickly, right? You need to count backwards from five and then when you're at zero, Jacob will post the question and the and the viewers can answer and who who is the fastest to answer gets a bag of presents. >> Okay. Shall I start counting right now? Okay. So, it's five, four, three, two, one, let's go. So the question is what is the latest version of intellig idea? Is it 202517, 2025 24, 2025 27 or 2025 free >> and we're talking about GA not EPS. >> Don't ask this question as at the beginning of the year because you feel like you're still in the last year. Okay. Uh, we have already some answers. >> So, I think Andre was the first one, but I think Andre already received you. You already won, right Andre? So, if that is correct that Andre already won, then the second first one would be um Jerome Jeron Stroom. Is that right? looks like. >> Oh no. Andre Andre says nope, not yet. Okay, perfect. So then um the win goes to Andre. Um reach reach out. Search your own. You have um you have a chance in our next question. We do one right right now. Right, Jacob? >> Yes. >> Please do us the honors. Um Nikita, and count once more. >> Sure. So it's five, four, three, two, one, go. >> This is the real struggle counting. >> Yeah. So the the question is which module do you need to include in plug-in XML to use LSP API? Is it com.intelligjate.lsp com.intelligj my goodness reading modules.Lsp or is it orc.jetbrains.lsp LSP or is it intelligj.platform.lsp. >> Yes, exactly. >> Next time the numbers. >> Yeah. Yeah. >> Is it one, two, three, or five? >> Well, I have no idea. >> Uh >> I think I think the right answer was really the first one, right? Bodhan nailed it. >> Bordon. >> Okay. So, Bodan, you please reach out to marketplace. the usual email address and then >> for the record this is com intelligj modules lp the longest one >> the longest one >> all right >> we can go with third question sorry because we can >> mhm >> you really like how you do comment yes >> I'm not even sure who decided that I have to read them >> the next one Matias you count Okay. Five, four, three, two, one, go. >> Remember to read it, Patrick. >> Uh, I can read it. Um, to depend on paid features in IntelligJ 2025.3. Which modules do you use? First, uh, com.intelligj.modules.premium. Uh, two, com.inttellj.mmodules.imate. Three, com. Intelligj.modules.paid. M4 com.intelligj.mmodus.pro. So premium ultimate paid or pro? >> No idea, >> right? Well, but Patrick, you you still have to tell me which answer is correct. >> Do I? >> Yeah, because I don't know the answer. Okay. >> So, I think um >> you think >> I'm in a I'm in No, no. I'm I'm in a I'm in a pickle right now. So, because um as far as I can see, Bodon delivered the right answer again. Right. It's uh com IntelligJ modules ultimate, but Bodon already won in the first round. So, why why don't we give the win to Jerome who delivered the first wrong answer? >> Sounds fair. >> Is that okay with everyone? Sounds fair. Works for me. >> Works for Okay, perfect. Finally, Nikita, we can um give you your vacation, even if it's just construction. Enjoy enjoy the noise. Thanks very very much um for joining. We see you. >> Thank you. >> Bye-bye. >> Bye-bye. >> Thank you very much. Bye. >> That was good. That was cool. Very insightful. Um okay, next one up is also very related actually uh because it's still about you know providing a great uh UX uh you know user experience having no delays etc. So next talk is given by Constantine Nisht um and it's about how to investigate UI freezes. So ah I forgot to Yeah, we forgot to add you. >> I'm not sure who was in charge for that. >> You >> It was me. Really? >> No, >> I I don't I don't have an admin. >> Constantine. Um welcome. >> Yeah. >> Sorry you came late to the stage. >> No, that's okay. I think we have lots of time now. >> Yeah. So basically the floors is yours. um please >> give us your presentation. >> Yeah. >> Yeah. So let's start then. Uh this is a presentation about how to investigate UI freezes. And uh one important detail is that I will tell you how to investigate them, not how to fix them. Uh but I'll try my best to give some advices uh what to actually do with this u this problem of our ideas. uh about a little about me uh I am software developer in intellig platform I work on our threading model and concurrency and curtins all that stuff currently uh but let's dive into the presentation so to understand uh why do we have freezes uh in regular ID or in the plug-in we need to understand the architecture of intellig platform so you could notice that our ID These u are UI applications and as uh regular UI applications they have UI framework. Our UI framework is based on top of uh Java AWT. Uh and also as a way to work with our model kind of uh structures that uh contain data about users code we use readr logs. Yeah. And recently uh for the last maybe five years we started adopting cotling routines uh which need to be integrated nicely into both these concepts. Yeah. So let's talk about consequences of uh building an application on top of AWT. So we have a dedicated single UI thread uh which is called the EDT or the event dispatch thread u and it's this is basically a thread where all interaction with the screen works in in simple terms. Uh basically all painting requests are performed as events on EDT. Uh yes uh well uh it is called event dispatch thread because it runs events. um should be pretty obvious. Now uh also uh all interactions with swing uh UI framework which is built on top of AWT and this a bit higher level they also happen on EDT and there is one important thing is that anyone basically can submit their code for execution on EDT that's free that uh uh that approach follows uh swing um standard s and practices. Uh you just hit swing tools invoke later and then you can run arbitrary thing on DT and you can do whatever you want like you can access files or you can simply run an infinite loop and it will freeze free the ID. That's about ed. Well, we also have uh read write log. Uh we had it from the very beginning uh from 25 years ago and our ids are uh we rely on this model of having the read write log. So first of all why do we need it? We have several structures that uh basically mutable shared state and we need to ensure exclusive access to them. Such structures include psi which is our representation of syntax trees, vfs which is uh our representation of file system um indexes project model. Well, project model is how we understand uh the build system uh that is used to um to import a project. Um as of as about the API, we have basically two methods. Uh there are plenty of flavors for these two methods, but basically we have read actions and write actions. And uh uh basically if we have read write lock uh then read actions uh allow executing some code inside read and write action allow to do the same under right lock. Uh we use read write lock and it means that we can read the same mutable shared structures in parallel but we want to ensure that only one thread writes them. So uh write locks are mutually exclusive with everything else. Um yeah as we were writing the code uh the acquisition of read and write logs uh was usually uh usually proceeded in blocking way. So that thread that wants to acquire a lock gets blocked like in thread park way or with corines it gets suspended which is slightly nicer nicer yes. Um yeah so there is an important thing about intelligent platform is that right actions can run only on the DT. There are lots of reasons uh for this behavior. It makes writing the code very uh convenient. writing the plugins. I mean for our ID because your UI thread is only consistent um uh state of uh data structures but it has also lots of disadvantages like uh it should seem logical that right actions should not run on the DT right but unfortunately they do. Um here I need to say that uh we are aware of this problem and we know that it's a problem. We are working on it. Uh but it's not that easy to fix 25 year old codebase. So we we're getting there actually. Uh so yeah the bad consequences of write actions on the DT is uh that they freeze UI because they're just a code that does not allow to paint anything. Uh for example, you could see have seen the following uh model dialogue. Well, this particular dialogue uh just uh is a little bit fake. It looks like a model dialogue, but in fact, it is a long write action and that's why you cannot cancel it. You cannot do anything uh with it. Uh yeah, it is animated. But that's because we have some tricks to uh run animation while write action proceeds. Uh but yeah, the sad thing here is that it's uh you as a plug-in developer can actually do nothing with this. This is a platform platform problem, but we're working on it. Uh another less obvious case of why we have UI freezes is that uh reduction on background can actually freeze UI. That sounds strange, but let's dive into this example. So let's use the following two uh two two diagrams for uh for expressing threads. So on top we have EDT uh and in the bottom we have uh some background thread and we have a timeline uh which goes from left to right. So imagine that we have a background thread that runs some long red action. Completely normal stuff, right? Background threads want to sometimes read PSI for their purposes. Meanwhile, the EDT does some painting. Uh that's also totally normal behavior of EDT. But then EDT wants to run a right action and you cannot actually predict where it happens. Uh I mean usually right actions are consequence of user actions but sometimes the platform decides to just fail right action randomly after a certain timeline uh delay after a certain time out I mean uh yeah and because this is EDT and we need usually to start this right action like right now uh we cannot postpone it uh this right action blocks EDT uh and we cannot run some other painting events because they might rely on the result on this right action and basically we have this situation where a read action on the background causes a UI freeze. Yeah. And after some time reduction stops and then our right action proceeds doing whatever it wanted to do. Uh but we had a freeze unfortunately in this case. So uh let's figure out how to investigate such uh scenarios or maybe something more uh at least if we understand uh how to uh where to look into intelligent diagnostic uh data it might prove useful in other sorts of UI freezes. So uh basically investigations uh should start with opening a thread dump. IntelligJ creates a predump on a plenty of actions. When you have a UI freeze, there will likely be a a freeze dump and you will probably get somehow notified about it. Uh you can capture a thread dump manually with JStack. Uh yeah, but let's assume that you actually have a thread dump. The problem is that it can be quite huge. Uh for example, this is uh only one thread. Uh personally I get it looks scary. Uh it's a lot of text and this is just a thread dump of EDT and we have like a hund of other threads which are also doing some non-trivial work and also we have corine dumps which I will cover a bit later. Uh but yeah I I get that it might be intimidating. So let's uh look at where where should we look in this uh in this mess. So uh we have a UI freeze right? It means that EDT cannot paint uh whatever it wants to paint or process user events uh if it needs to. Well, let's search for EDT. It is in our thread dumps. It's called AWT event Q0. Um and in the vast majority of cases, it is blocked on the read write log. The one that's used to protect our SH data structure. This is the most frequent source of our UI freezes. There are others but that's the the most popular one. So that's a bit shortened example of a uh thread dump um of of a thread dump that is uh narrowed to one thread to EDT. Uh it also contains lots of symbols. So first of all we have the name of the thread. It is indeed ET. You probably uh found it already with a text charge. Then we see that it is blocked. Uh thread state could be waiting uh blocked time and waiting if the thread is blocked on thread sleep. Here we see that it's blocked on monitor because it is javalang object by zero. Uh and if we uh scroll in uh a little bit lower, we could find uh the phrase run action. Uh basically the next step after you found uh uh thread that you're interested in is to uh search for these magical strings like run right action or run redaction. Uh they will tell you about what it what the it tries to run like here it tries to run right action for whatever reason and it cannot acquire uh the the right action. uh which means uh wait uh let's let's think why the IDT cannot run reduction that's because there is some alive reduction somewhere in a background thread uh that's most often the case uh so next we need to search for this reduction and here we can look for reduction this thread dump most likely it will show us a thread which uh basically runs that reduction um here it is I took at from our random thread dump with a freeze. So this is a background thread. Uh this particular thread was taken from from corines. Uh this a transform corine thread pool. Uh we see that it actually does some non-trivial work. It uh does something connected to serialization in Java. uh in VFS basically uh this persistent FS tree accessor um is uh part of our virtual file system uh but yeah we see that uh there is a background thread that does not work and it is reduction uh which means that while this reduction runs we experience a freeze in our ID and um that's basically it that's how to investigate it Congratulations, you found out why your ID is frozen. Uh but to not make this talk uh so useless, I'll actually tell about ways of resolving uh long uh redactions. So uh the best advice I could get and that uh works in majority of cases is to use non-blocking reductions. Uh let's figure out what it is. So let's recall our previous uh hitch diagram with two threads EDT and the background thread where right action blocked uh while read action runs. Uh well here we can notice that EDT wants to run a right action and it wants to run it fast because we want EDT to uh be done with this right action and continue do some doing some useful work. So uh yeah uh this read action that runs on background and blocks right action is uh called blocking in our terminology um but there is an alternative. So imagine that there is some ongoing read action in a background thread uh and does some painting or some interaction with the UI. Then the the ADT in this its next event wants to start a right action. We as as intelligent platform understand that uh right action is about to start and we uh give a signal to the running reduction that it needs to finish. Then this reduction transitions into a special can cancelling state uh where it continues to run but on the next call of progress manager. Cancelled it throws a special kind of exception that aborts its execution. Uh well when the this reduction reaches the cancellation point uh it means that reduction is um done. It is not done gracefully but there is no red action now nothing holds read lock and we can start uh doing our right action. Uh so right action can run meanwhile this read action gets blocked uh if it wanted to execute like synchronously on this background thread or it gets just uh kind of suspended and gets stored in the queue and then it gets rescheduled once the right action is done. uh but effectively this reduction is blocked. So once action is done the ADT can continue doing uh other work like it uh can process other user events or do painting and this red action uh it now knows uh because the platform signals it that the right action is done and it can be restarted and that's a very important point that this read action is restarted from scratch like it gets aborted and then the logic that was previously executing it starts running again. Um yeah that's important point I'd like to reiterate it here. Uh there is a mathematical property that's called item potence which means that if you execute a function several times then it results it subsequent execution does not uh affect uh some global state and it's important to know that uh non-blocking reductions uh yeah reduction that confirms this scenario is called unblocking. Uh so such reductions need to be ite important. It means that if you want to run uh HTTP request uh if you want to fire HTTP request from an unblocking reductions, you need to think twice because your request can be actually resend several times because redaction can be aborted. Uh yeah and like I said uh in our code the cancellation points is a call to calls to progress manager check canceled which throws a special exception and that's why uh and that's how reduction gets aborted. So while the in this blue segment um after the first reduction uh the reduction continues running uh until it reaches the check cancelled and basically if uh you don't have any uh check cancelled in your reduction uh then you uh have kind of a blocking reduction uh because the right action cannot start for the whole duration of of reduction. Yeah, that's was the first advice in our API. It's called redaction.nonb blocking. That's a Java friendly version of running non-blocking reductions. Uh and yeah another advice is to place progress manager check cancel frequently enough like the platform calls a lot of plug-in code under reduction under already provided reduction and to behave nicely the plugins need to call check it uh frequently enough so that uh the outer reductions can be cancelled. All right, let's switch to Corins and how they fit into this uh perhaps convaluted picture. Right, so uh our Corin API uh has functions like read actions, EDT write actions and read EDT write actions. First you could ask uh why is why do we need this weird name? Why is EDT write action not just write action? Well, the reason is that because we are um on the way of introducing background right actions. Uh I think in 2025.3 these functions are stable. It's called background action but it might not work that smoothly with everything else. Um yeah uh read edction uh is a function that uh helps to do a very specific pattern. So imagine that you need to compute something uh uh in redaction and then apply this result in a right action. Uh there is an API for this in our reduction.blocking builder Java builder and this is a corin version. Um yeah and reduction well it's reduction but there is a twist reduction in corine world is always non-blocking. Uh that's because we uh started using non-blocking reductions in our platform. We saw that they work very nice and we made them a default uh a default option of executing code under reduction in curtain world. All right. So yeah one one important point about reductions is that they are suspending functions but they accept a nonsuspend lambda. This action as as a parameter inside the redaction is non-suspending. Uh that might be inconvenient cuz I mean we want to you could want to have suspense everywhere but we want to uh keep actions short and uh not having a suspend modifier uh does not allow you to suspend inside and it is much more difficult to do some long task like um in cotlin the API for sending uh uh some web request is um in the vast majority of cases uh suspending because it's cotlin everything is suspending and we want to avoid that someone tries to uh do someone tries to send a web request inside the reduction that's why there is no suspend uh just to uh avoid these things yeah and also it's important to remember that this lambda can be executed multiple times inside the single redaction because right action can cancel it. Um let's proceed. Uh uh yeah so pins are nice but they are uh they introduce additional level of complexity and we need to investigate issues in corines. Um, I'll be honest, it is harder than uh doing the same in plain Java and we have a plenty plenty of diagnostic tools for uh investigating Corins. One particularly useful is CI dumps. Basically every time you uh get a thread dump from our ID with JST or when ID captures a thread dump itself they the thread dumps also include corine dumps that's kind of a state of corine tree uh at the moment of uh capturing the uh the thread dump. So curtins look scary. They look unfamiliar. There is a lot of information and you also need to uh know what to look for in them. Uh so let's look at how what we can find in uh curtain dumps. Um that's an example from from the same uh thump I used before, but that's uh a part of curtain dumps. Uh uh oh wait no no no no not really that's actually a thread we'll come to corine later. Yeah so that's some other thread from that corin dump. Uh uh yeah we see again that this is a background thread and it is blocked. Uh yeah uh and one interesting thing here is that it is blocked on run blocking. So run blocking is a special function in cotling corines library that allows you to call C routines from uh blocking code without suspense and then wait until these corines finish to execute. Uh naturally the thread that codes run blocking gets blocked uh until all the corines inside finish. Uh and here we we see this unblocking. So our sorry our thread dump actually has a an identifier of this blocked uh of this run blocking. We can search for this identifier in curtain dumps and find this snippet of uh code. Uh yeah. So here we see uh this is taken from curtain dumps and we see it is the same identifier 32E 180. Uh you can check it. It's the same uh so it's the same run blocking uh that matches uh that thread and we can now investigate what's this uh thread doing and why it cannot finish. So we see that this C is suspended. It means that it's it's waiting for something. It is stored in some queue. uh we can see corin context that's associated with this uh corine uh from this particular snippet we see that it runs on a dispatcher IO scheduleuler uh that's limited to 11 threads uh and and yeah these curtain are taken from our scanning process uh it is visible here and we have uh this x8 off uh it's kind of a duplication of identical corines it means that we have eight identical cines that are suspended on something. But what are they suspended on? Uh we see here that they they are suspended on a reduction. It means that this Cine wants to run a suspending reduction but it cannot uh because there is uh because a right action wants to start. Yeah, that's a very nice property of uh intelligent platform. when right action wants to start it does not allow read actions to actually even start. Uh so they wouldn't uh even prevent uh right actions from proceeding as fast as it can. Um yeah that's uh that was a small guide on how to uh look at security and dumps and not be that scared. Uh in conclusion uh what do you need to remember after this talk? So use not blocking reductions. They are nice uh but you you you also need to keep them short enough so that they don't want to want to uh so they wouldn't take lots of CPU and the restart wouldn't be that bad. Uh but they are actually better than regular blocking reductions. Um yeah, you also need to use check and frequently enough uh to help in Asia platform uh being responsive. Uh and yeah, uh I understand that thread dumps are scary and curtain dumps even more so. But uh once you get a little comfortable with them, they contain lots of useful information and they help you to introspect the state of ID and uh figure out what's your plug-in doing. So it might worth worth some time to invest into understanding these formats. Uh that's it basically. Thank you for your attention. >> Great talk. Thank you very much. Uh someone in the chat already said this should be put up on the on the docsk. >> I think it already is >> this talk. I mean the whole talk actually. >> Oh the whole talk. Anyway, thank you. Thank you very much. Uh I'm a net guy. Uh so for me this looks a little bit less uh scary now. Um good job on that. Um we do have a couple of questions. Um so one question that I actually also understand is that's why I'm going to pick this. Um what is the process of deciding when you call um and how is this call exactly called? Progress manager. Cancelled. um to kind of you know have the help with the maximum uh responsiveness um of EDT. Uh well basically the platform has uh already strategically placed cancel it in important places like when you call platform functions like when you request a service um the you transfer control to the platform and platform already has check consultants in there. So if you call check consult inside uh if if you retrieve a service inside a reduction uh most likely you are fine here the platform will check it for you but sometimes you in your plug-in do um some non-trivial work like you have recussion or you have loops where you iterate in on over long lists and that can introduce uh problems in cancellation. So my advice is uh that if you have long loops um it might be nice to inert check there. There is one pitfall though. Uh check unfortunately it's it is not free. Uh so uh you need to inject it with some debounce like check consolation once in 100 iterations so that it wouldn't be visible in profiles or um it wouldn't harm performance but still give you enough responsiveness so that reduction gets aborted promptly. >> Mhm. So I think one one >> sorry I just to follow up. So one question would be um so where I use it is when I do heavy work on the PSI right I have a visitor who has to go through a lot of structure and recursively >> so um can you say something about the so what's actually done in check canceled how how um how heavy is this the function call >> we're right I don't I don't need I don't need an exact answer but just an estimate so that because I have so if it's just a a quick all that takes nothing. I can place it anywhere, right? But maybe I want to consider it every 2,000 iterations or strategically placed as you said. >> So, >> so with this particular example with the recursive visitor uh there are already checklets in the platform like when before the platform calls your visitor method, it checks cancellation and it does it uh when it needs to do so. about how heavy check cancelled and what's what what can be so heavy inside it. Um to be honest in progress manager check cancelled there is a bit heavy logic with tracking of threads that run under progress indicators that's kind of an an old class alacy class for managing consolation and progress reporting. Uh so yeah there is some uh heavy stuff like uh threads get stored to concurrent hashmaps. Uh these hashmaps can get resized at some random points. There are some synchronized. Uh there is a bit lighter version cancellation check it. Uh it should also work but not with progress indic progress indicators and it is much lighter but but generally I think you would be fine if you use progress manager to cancel it. I mean having compilation even that slow is much better than not having it at all. >> Yeah. Yeah. I know. I know. I know. Mhm. We we got a a question in chat. Uh put it on. >> I I asked that question because it could come from me. >> Right. >> So why write actions have to be executed on the EDT? Uh EDT D is already for threat right there. See not Java. It was just decided on the very beginning of intellig idea that we will run write actions on EDT. Uh it has advantages. Um it is more convenient to write such code like when you have uh write actions only on EDT when you have this invariant. Uh first of all you don't need to take a read lock on EDT. If you want just to read uh your data uh then you on ed then you can read it right away because you know nothing else can mutate this data in parallel. Uh second uh option second answer is that uh when you have this restriction you can implement a much more performant version of log. So uh since 2016 up to 2022, we had a a very performant lock uh in the platform. It was it was really fast. Uh what we have now is not that fast. Uh but the old version worked only with this assumption uh that we have uh this restriction that right actions can run only on DDT. Uh now we are running action sum of right actions on background. uh and uh yeah our current lock is slower but it allows us to actually run things on background. Uh third answer is that uh you don't need to care about consistency in your uh EDT uh because when you when you read data it's always consistent you know nothing changed it uh I yeah but you can also ask okay uh it's bad actually let's just run all red actions on background unfortunately uh intelligent platform is a very old code base there are lots of assumptions s and uh there are lots of listeners synchronous listeners inside these write actions. Uh and these listeners uh do whatever they were allowed to do. For example, you can um add the listener to some VFS which will run inside the right action and you can uh draw something on the screen in this listener. nothing prevented you to do so because uh right actions were running on the DT uh it is naturally allowed uh and that's the reason why we cannot just take all right write actions and run them on the DT because we have our own code and we have third party plug-in code which relies on this property and it is lots of work to untangle uh EDT and write actions but but we are working on All right, thank you. Clears things up. Um, another question. I would have one definitely for my for my times when I when I deal with an IntelliJ platform. Um, so beyond simple search, what advanced tools do you recommend for analyzing large threat and corotine dumps to pinpoint root causes quickly to to to so to ease the scariness even more? >> Well, we have internal action which is called analyze tech trace or thread dump. Uh basically it takes uh the what whatever it is in your clipboard uh whatever you copied now and tries to parse it. It displays uh the uh dump in a nicer way. So you can navigate uh in actual uh frames in actual ST frame into your source code and also there is a built-in tool which is called freeze analyzer. So in some uh simple and understandable cases, it can even show you a a threat where it uh says why this threat is a reason of a freeze and who who to blame in it. Maybe it's platform, maybe it's something else. Uh but yeah, it displays a human readable reason of a freeze. Uh so yeah, the internal election analyze text trace or thread dump that's how it it's called. Okay, thank you. And one more question. Any of you too, Patrick or Jacob wants to ask that? Chris Chris just pointed out that cancel um the check cancel doesn't seem to be on the threading docs page in the SDK docs. >> Um I didn't want to type Yeah, we need to fix that. I didn't want to type and search myself, but I just take uh Chris's answer for granted. So, we need to fix that. So, we will take that into consideration. Yeah. >> Yeah. cancellation token.net. Okay, I will just follow up with with another question. Um, also sounds very interesting. Um, so non-blocking read actions require EDM potent. I never I never said that word. I just read. Um, what are common pitfalls when converting existing blocking read actions to this non-blocking uh pattern? Uh well basically I mean they are non-blocking reductions are better than regular blocking reductions but we could not just take and uh convert everything automatically in in the platform because the existing code sometimes relies on uh on the computation not being run several times. I I I think that's the biggest pitfall. It's very important to remember that uh it it is executed several times. I mean it's it's fine in the majority of cases like when you just uh find something in PSI hierarchy uh but if you do something non-trivial uh it is very unexpected behavior then it it runs several times and that's why we have two separate kinds of reductions. Yeah that's the biggest pitfall. Okay. So individual to um to the specific actions basically. Yeah. When they deal with PSI then it's cheap more or less comes automatically otherwise you have to you know consider what the action is actually doing. >> Yeah. >> Okay. Um I can see a last question here but you know I have no idea I cannot ask the question if I have no idea what it is about. So question question number two um one of you please. >> Yeah. Okay. So can you elaborate on the difference uh in how read action in co- routines and read action non-blocking handle cancellation and restarts? >> Uh well in cor routines there is a slightly different way of managing cancellation. actually uh we re reuse and extend in some sense the the consolation model from from corines. So in cines there is a kind of implicit all present curtin context. If you know husk a little that's kind of a reader monot that's associated with your every your computation and there is um a special uh thing that's called job in cotlink corines uh and uh every time you call a suspend function this job is checked for cancellation and if it is it throws an exception. We used this in suspending reduction. So basically when you run a suspending reduction the job from coring context is taken and it is kind of installed in the computation that runs under reduction and we uh every progress manager check cancel checks this job for cancellation. So it means that if something outside um cancelled your whole routine then your reduction will also be cancelled. >> Uh there is very similar thing with non-blocking reduction but because uh I mean Java uh version of the same pattern uh but it was old it also uh respects progress indicators. Uh so it's uh slightly more complicated. Uh I think that's the difference. There are very very subtle uh differences between them currently also uh like uh the Java version of non-blocking reductions u uses uh EDT to reschedu itself in case of cancellation and suspending reduction does not uh but I think it's more of a technical depth from from my side so >> will be fixed but I mean the answer is that ideally they are the same and Uh B basically need to think of them as as the same. Okay. >> Okay. One more. >> You have one more. >> Go ahead. >> Well, about tooling that could help uh in analyzing thread dumps and scrolling. >> Oh, we got that already. >> Yeah. >> Yeah, it's action analyze. Um so uh I wasn't aware that um analyze threat dump is an internal action. Maybe I always have internal action on >> well just a followup question to that one actually. Okay. >> Uh but any any external tools I think that your kit could help to some degree. Um your >> I am not actually sure to analyze >> not not really. I mean your kit is a tool for analyze profiles and hip dumps. uh for for investigation of freezes uh in the vast majority of cases it is enough to use just a thread dump. I mean I personally almost never use uh profiles or I mean there are very difficult freezes where I have to use heat dumps but uh it's very rare and it's enough just to use thread dumps. >> Okay. So so as mentioned before mostly our internal tools. >> Yep. I have other questions but not related to the talk you know. >> Okay. Should we should we first thank Constantine and let him off? >> Thank you very much for joining us and for answering so patiently all the questions and trying to get this hard topic a bit more understandable for us. Uh thank you very much for joining. Thanks and have a great day. >> Yeah. So, um, now we got a few more things to do. Um, and one of the things is we should raffle some more stuff off. Okay. So, now without counting and Jacob will just post it. Let's do it differently so no one knows when the question is coming. So here we have the question in cotlin notebook and uh image platform. What is the name of a variable used to register and dispose of code when running it from a notebook? Is it global dispose first notebook disposable three IDE disposable or four platform disposable? >> Madan was very fast but I'm not sure if it's correct. >> It's not. >> It's not. Okay. Oo, >> we didn't get the answer yet. >> I think that was the one that didn't work, right? That crashed your notebook earlier because it did not deinstall the the tool window that you were >> Yeah, actually it worked uh when I used it uh for AI assistant extension because I reloaded that and it was >> Yeah, properly >> I think um Chris was first. >> Chris, am I right? >> Yes, >> you are right. It's correct. >> It is notebook dispos disposable. >> Notebook disposable. Correct. All right. So, congratulations, Chris. Chris, you finally got it. And um how many more questions do we have? >> Two. >> Two quick questions. Short >> two quick questions. Okay. >> Okay. With no more counting. Here it is. >> No more. So, what is the current version of Gradel? Oh, now I need to read version numbers. Okay. Is it 810.0? Is it 8.14.3? Is it 9.1.0? Or is it 9.2.0? I honestly have no clue, but I have the answer here somewhere. >> Mhm. I think it's either three or four. >> It's four. >> It was released pretty recently. I mean, last week only or this week. >> So, Nikita Nikita was was the first one. >> Congratulations, Nikita. Um, and now let's shoot the last one. >> The last one. Here it comes. >> Okay. So, pitch task. >> Which task? Sorry. >> Do you run to locally verify your plugins compatibility? Is it first run plug-in verifier, two verify plug-in, three plug-in verifier, or four check plugin? >> Mhm. We already got the right answer. >> Uh this time Doran, you're right. So Doron is the first one who got it right. It's the second choice. It's verify plugin. That was an actually a complicated question because I think we have another run verify or verify plugin um task in Gradel, right? >> It was called before uh run plug-in verifier. >> Ah okay. But but do we have we I thought we have another one another task that is unrelated. It just just check just checks the the plug-in XML correctness. Wasn't there another task that was called verify plugin or something? >> No. >> Plug in verify. Okay. So then I'm mistaken. >> Okay. We are >> wait out of questions. >> We have we have was before Nikita. So Jonathan said he was before Nikita. Maybe our chats or >> Well, I'm looking at YouTube. >> I'm looking at YouTube. >> Refresh the chat. >> Maybe one uh small information in between. So, I just read uh uh Constantine now has also set visibility for uh everyone for the slides. So in case you've missed that uh they should be now available. >> So Jonathan so both in our in our chat software here in our uh StreamYard software and in the YouTube chat you are after Boddan and Nikita with the number four. Huh. So do we have some desynchronization here? H I don't know. Well, looking at well I I I just refreshed the the YouTube chat and for the gradal question grad version it was the correct answer was number four and Nikita is definitely the first person I see. >> Me too. >> All right. Um >> it's a corin issue. >> It's a issue correctly. So um but I see basically so the the the gradal question was pretty quick right so we had Nikita Boddan and Jonathan who both answered four uh who who all answered four in a very quick session so why don't we give uh three bags away one to Nikita one to Boddan and one to Jonathan would that be a viable solution for everyone okay so everyone who won please write marketplace and marketplace team will take care of sending the packages out. That being done, we have some final housekeeping. So, first of all, um we and I really like to thank all the attendees and all the speakers we had. Um and most of all, we like to see uh we like to thank the people that you don't see because there are two important people behind the scenes. One is Sergey who's taking care of all the technical stuff because we don't have to do anything. I can have my hands free here and he takes care of all the transitions, putting me on screen, silencing me if I talk too much, all these things. So, thank you uh thank you Sergey. And then we have Elena who basically uh managed the whole event, put everything together. I think she invited most of the stuff uh most of the people and so on and so forth. So thank you very much Elena for that. Um the rest of us you see here which is Matias, Jacob, me and also um Robert who's also part of the advocacy team. So thanks again everyone for putting such a great event together. >> Second to second to last point um recording and slides. So um we will prepare a final recording of the event and we put it online. Everyone who registered at the event will get a message um so so they can access it but also we will publish it on YouTube uh under the Jet Brains TV channel I'm sure so you can see uh see it there. Um the last thing is action for you. So it's a call to action. Go out, try the things we learned today, which is try the latest uh intelligent uh platform Gradel. Uh run the plug-in verifier, check it out, play around with cotton notebooks, tell us about it, right? Check out the plugins we saw we saw today, which is uh what the AI stuff, right? The LSP stuff. try this um work or look into LSP before you maybe jump into hard pausing stuff when you try to uh create a language plugin and check out UTRA extensibility. So um and the final point is if you post something on social media somewhere please link us mention us um we will put our our coordinates of the platform um of the jet brains platform in chat. Can someone take care of that? Um and basically uh if you link us we will link you back and we will write nice things. Tell us if you liked it. Tell us what you want to see next time and so on and so forth. Okay, Jacob Matias. >> I know what I want to see next time. >> Uh, more about net >> more about net. So, we could I don't know. We have so much stuff we could do there, right? I mean, isn't isn't the whole isn't the whole ecosystem with Godo with Unity and stuff, right? I mean, that that's extensibility, >> is it? >> Mhm. >> Yeah. Yep. >> So, I definitely played around with Godo and C and I would like to see more of that. >> Yeah, it's a whole new world that opens up, you know, because it's a ReSharper platform. >> Yeah. >> Not sure it's Intelligj idea platform. No, you call it No, you call it Intelligj platform. Yeah, sorry. >> Yeah, that would that would be very cool. >> Folks, if you have if you have ideas, then please apply for for next year. I think the closing words should go to Jacob, >> right? >> Thank you. >> All right. >> Yeah, it was it was great. Six and a half hours >> a lot of time. Um yeah, thank you. See you online platform. You can get in touch there. This is a great place to to start your plug development journey or rant about issues etc. We are there. We we can help. We feel you. We're the same. We're trying to write code. We run into the same issues, right? Don't be afraid to reach out. So, thanks everyone. And I think we >> Yeah, we're out. Bye-bye everyone. >> Bye-bye., JetBrains Plugin Developer Conf 2025, YouTube, 01k9at223rmvsrhjkzx7x6c2dp.