<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Kokosa&apos;s Intensive Care Unit | Kokosa&apos;s Blog</title><description/><link>https://kokosa.icu/</link><language>en-US</language><item><title>the TZ Bug in Chill with You on Linux</title><link>https://kokosa.icu/en-us/blog/1-chill-with-you/</link><guid isPermaLink="true">https://kokosa.icu/en-us/blog/1-chill-with-you/</guid><description>There&apos;s a game on Steam called Chill with You ~ Lofi Story (is it even a game? it&apos;s basically a pomodoro timer!). It&apos;s one of my favorites - the protagonist is adorable and provides great companionship...

</description><pubDate>Sun, 08 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h3 id=&quot;whats-this-about&quot;&gt;What’s This About&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;There’s a game on Steam called &lt;strong&gt;Chill with You ~ Lofi Story&lt;/strong&gt; (is it even a game? it’s basically a pomodoro timer!). It’s one of my favorites - the protagonist is adorable and provides great companionship.&lt;/p&gt;
&lt;p&gt;The setting is that you and the protagonist exist in different parallel universes, so I always assumed the time difference between the game and my local time was intentional. I never bothered to look into it.&lt;/p&gt;
&lt;p&gt;Until the 1.2 update (January 27th), when I saw a comment in Steam’s discussion board: basically saying that when running this game on Linux with Proton, the in-game time always shows UTC+0.&lt;/p&gt;
&lt;p&gt;For those unfamiliar with UTC (Universal Coordinated Time), here’s a simple example: I’m in UTC+8, so if my actual time is 8:00 AM, the game would show 0:00 AM - an 8-hour difference.&lt;/p&gt;
&lt;p&gt;Wait, what? So it wasn’t some parallel universe setting after all, just the timezone not being read correctly. No wonder it was exactly 8 hours off.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;problem-analysis&quot;&gt;Problem Analysis&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;It’s actually a pretty simple issue, and I quickly found the cause: Proton-run Windows programs can’t correctly read the Linux system’s timezone information. On Linux, timezone data is usually stored in &lt;code dir=&quot;auto&quot;&gt;/usr/share/zoneinfo/&lt;/code&gt;, while on NixOS it’s in &lt;code dir=&quot;auto&quot;&gt;/etc/zoneinfo/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The solution is simple - just manually specify the timezone in the launch options. Go to Steam → Game Properties → Launch Options and add:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;TZ=Asia/Shanghai&lt;/code&gt;: Sets the timezone to Shanghai (Beijing Time)&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;TZDIR=/etc/zoneinfo&lt;/code&gt;: Specifies the timezone file directory location&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It should look something like this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;TZDIR&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;/usr/share/zoneinfo&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TZ&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Asia/Shanghai&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%command%&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;After adding these launch parameters and restarting the game, the time displays correctly. 9:31 is now 9:31.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://kokosa.icu/posts/1-chill-with-you/utcp8.avif&quot; alt=&quot;Something like this, it was originally showing 1:31&quot;&gt;&lt;figcaption&gt;Something like this, it was originally showing 1:31&lt;/figcaption&gt;&lt;/figure&gt;
&lt;div&gt;&lt;h3 id=&quot;afterword&quot;&gt;Afterword&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;That pretty much solves the problem. I also replied to that discussion comment with the solution. If you’ve encountered the same issue, I hope this post helps you.&lt;/p&gt;
&lt;p&gt;By the way, I use NixOS, so normally I should use &lt;code dir=&quot;auto&quot;&gt;/etc/zoneinfo&lt;/code&gt; instead of &lt;code dir=&quot;auto&quot;&gt;/usr/share/zoneinfo&lt;/code&gt;, since NixOS doesn’t have the &lt;code dir=&quot;auto&quot;&gt;/usr/share/zoneinfo&lt;/code&gt; directory. However, this still works because Steam’s environment handles it for you.&lt;/p&gt;
&lt;p&gt;Belike:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;~&lt;/span&gt;&lt;span&gt; $ steam-run ls /usr/share/zoneinfo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Africa&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Egypt&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;Hongkong&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Mexico&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;ROK&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;America&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Eire&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;span&gt;HST&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;MST&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Singapore&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Antarctica&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;EST&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Iceland&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;MST7MDT&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;Turkey&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Arctic&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;EST5EDT&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Indian&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Navajo&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;tzdata.zi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Asia&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Etc&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Iran&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;NZ&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;UCT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Atlantic&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Europe&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;iso3166.tab&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;NZ-CHAT&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;Universal&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Australia&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;Factory&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Israel&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Pacific&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;US&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Brazil&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;GB&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Jamaica&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Poland&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;UTC&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Canada&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;GB-Eire&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Japan&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Portugal&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;WET&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;CET&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;GMT&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Kwajalein&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;posix&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;W-SU&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Chile&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;GMT+0&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;leapseconds&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;PRC&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;zone1970.tab&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;CST6CDT&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;GMT-0&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;leap-seconds.list&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;PST8PDT&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;zonenow.tab&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Cuba&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;GMT0&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;span&gt;Libya&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;right&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;zone.tab&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;EET&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Greenwich&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;MET&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;ROC&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;Zulu&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;~&lt;/span&gt;&lt;span&gt; $ ls /usr/share/zoneinfo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;lsd:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/usr/share/zoneinfo:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;No&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;such&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;file&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;or&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;directory&lt;/span&gt;&lt;span&gt; (os &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded><category>Gaming</category><category>Proton</category></item><item><title>Rebuilding My TG Forward Bot</title><link>https://kokosa.icu/en-us/blog/tgbot/</link><guid isPermaLink="true">https://kokosa.icu/en-us/blog/tgbot/</guid><description>The forwarding bot I was using kept receiving tons of spam. The developer never added a blocking feature, and the project had been abandoned for a year. Getting bombarded daily with VPN promotions, adult content, and scam messages... I couldn&apos;t take it anymore and decided to rebuild it myself...

</description><pubDate>Thu, 18 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h3 id=&quot;the-beginning&quot;&gt;The Beginning&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The forwarding bot I was using was &lt;a href=&quot;https://github.com/LloydAsp/nfd&quot;&gt;Node Forward Bot&lt;/a&gt;. I used it for quite a while, but kept getting bombarded with ads. Looking again, the project had been abandoned for a year. NFD2 isn’t open source (I think? Couldn’t find the repo), so I hadn’t tried it. I don’t know if it has ad blocking either. So I decided to build another wheel for my own use.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;keyword-filtering&quot;&gt;Keyword filtering?&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;First I tried stuffing in a bunch of &lt;strong&gt;sensitive words&lt;/strong&gt; to auto-block. Then I got results like blocking &lt;code dir=&quot;auto&quot;&gt;x86_64&lt;/code&gt; (for “64”), &lt;code dir=&quot;auto&quot;&gt;Steam platform exclusive&lt;/code&gt; (for containing banned substring), &lt;code dir=&quot;auto&quot;&gt;Python scripts&lt;/code&gt; (for “scripts”), &lt;code dir=&quot;auto&quot;&gt;listening port&lt;/code&gt; (for “listening”)… yeah, not great.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;how-about-regex&quot;&gt;How about regex?&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Ugh… clearly this path wasn’t working. So I listened to friends and tried writing a bunch of &lt;strong&gt;regular expressions&lt;/strong&gt;. But as we all know, Chinese spam is wild: &lt;code dir=&quot;auto&quot;&gt;weìrd sp4cing&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;微 P 嗯&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;emoji puzzles&lt;/code&gt;… Can regex really catch all these? Maybe, but my brain definitely isn’t that powerful (sweat), so I decided to use LLM for moderation.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;gemini-yes&quot;&gt;Gemini! Yes!&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;I needed a model that’s as fast as possible - doesn’t need to be super smart, just able to understand language. At the time I didn’t know Google had cut AI Studio’s quota again. Google has a model called &lt;code dir=&quot;auto&quot;&gt;gemini-flash-lite&lt;/code&gt; that seemed suitable for content moderation, so I used it. Wrote a simple Prompt to have it judge user input and output &lt;code dir=&quot;auto&quot;&gt;SAFE&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;UNSAFE&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;payload&lt;/span&gt;&lt;span&gt; = {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;contents:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;parts: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;text: &lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;# Role&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Content Moderator API. Output one word only.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;# Rules&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;UNSAFE if:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- Real human nudity/sex&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- QR codes/spam/ads&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- Real gore/shock content&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- Illegal content promotion&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SAFE if:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- 2D/Anime/Cartoon (even suggestive)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- Normal photos/text/screenshots&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;# Output&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;One word: &quot;SAFE&quot; or &quot;UNSAFE&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Analyze: &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stringify&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;There’s a slight delay, but it’s negligible. Compared to traditional rule matching, LLM can understand context and semantics with much lower false positive rates. The downside might be cost, but Gemini has a free tier - not much though. With three API keys I get about 60 calls per day, barely enough for ad blocking.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;refactoring-the-entire-project&quot;&gt;Refactoring the entire project&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Since I’d already changed so much, might as well refactor the whole project. The original code architecture was messy, all logic crammed in one file, painful to maintain (though this kind of project barely needs maintenance).&lt;/p&gt;
&lt;p&gt;So I battled with various LLMs for a night - they all went stupid. Finally downloaded Antigravity and refactored the whole project into a modular architecture in one go:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├── src&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   ├── ai.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   ├── config.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   ├── handlers&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │   ├── admin.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   │   └── guest.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   ├── index.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   ├── storage.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   └── telegram.js&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;└── wrangler.toml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;I have to say Antigravity is really good. Free Claude Opus 4, generous quota.&lt;/p&gt;
&lt;p&gt;Implemented these features:&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;AI Content Moderation&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;AI-based harmful content detection&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Ban List&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;View all banned users&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Stats System&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Message count, user count, AI blocks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Multi API Key Rotation&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Fucking Google&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Multi API Key rotation is to handle Google’s Rate Limit. 20 API calls per day - who can use that? It used to be 100 per day. Gemini CLI and Antigravity have generous quotas, but the API is stingy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The whole project runs on Cloudflare Workers (nice touch from the original project - convenient, useful, and free). Completely zero-cost solution. LLM is also free. The whole project is just JavaScript.&lt;/p&gt;
&lt;p&gt;Finally pushed the code to GitHub, open sourced under BSD2 license.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;link&quot;&gt;Link~&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/hatanokokosa/kokosa-forward-bot&quot;&gt;GitHub: kokosa-forward-bot&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://linux.do/t/topic/1340613&quot;&gt;LinuxDo: KFB — A Telegram DM Forward Bot with AI Moderation&lt;/a&gt;&lt;/p&gt;</content:encoded><category>Bot</category><category>AI</category></item><item><title>From configuration.nix to Flake</title><link>https://kokosa.icu/en-us/blog/flake/</link><guid isPermaLink="true">https://kokosa.icu/en-us/blog/flake/</guid><description>With less than 240 days until the Gaokao (college entrance exam), time is tight and I don&apos;t have much time to blog. But after being urged by friends, I figured I should at least write one post. Actually, I&apos;ve been keeping a diary, but it&apos;s too personal to share...

</description><pubDate>Sat, 04 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h3 id=&quot;whats-up&quot;&gt;What’s up&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;With less than 240 days until the Gaokao (college entrance exam), time is tight and I don’t have much time to blog. But after being urged by friends, I figured I should at least write one post. Actually, I’ve been keeping a diary, but it’s too personal to share publicly.&lt;/p&gt;
&lt;p&gt;Amid all the busyness, I managed to get some things done. For example, last weekend I finally set up Flakes, which I’d been wanting to do for a while. With the help of CodeX CLI, it didn’t take too long - I let the AI Agent handle the trickiest parts, and it was almost a one-shot success. Here’s my current directory structure:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├── flake.lock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├── flake.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├── home&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│   └── modules&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│       ├── dae.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│       ├── fzf.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;│       └── niri.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;├── Justfile&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;└── nixos&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── configs&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│   ├── dae&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│   │   └── config.dae&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│   └── niri&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│       └── config.kdl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── hosts&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│   └── kokosa&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│       ├── default.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;│       └── hardware.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;└── modules&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── boot.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── desktop.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── locale.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── networking.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── nix-settings.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── packages.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── security.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── services.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;└── users.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Of the programs managed by Home Manager, only fzf is actually in use. The other two are planned for future use, so I’ve written the configs but they’re disabled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;h3 id=&quot;why-switch-from-channels-to-flakes&quot;&gt;Why switch from Channels to Flakes?&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Compared to &lt;code dir=&quot;auto&quot;&gt;configuration.nix&lt;/code&gt;, Flakes solves many problems. It can lock all packages and dependencies to specific versions - a single config file can precisely restore an entire system down to version numbers and commits. Channels, on the other hand, follow updates and can’t do this.&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;&lt;th&gt;&lt;strong&gt;Channels&lt;/strong&gt;&lt;/th&gt;&lt;th&gt;&lt;strong&gt;Flakes&lt;/strong&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Implicit (channels)&lt;/td&gt;&lt;td&gt;Explicit (inputs)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Rebuild&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;sudo nixos-rebuild switch&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;nh os switch .&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Reproducibility&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Depends on individual channel versions&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;flake.lock&lt;/code&gt; ensures consistency&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;nix-shell&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;nix develop&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;nh is a NixOS helper tool. Its support for configuration was a bit mysterious, but after switching to flakes I found it to be a really useful tool. Highly recommended!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Additionally, Flakes can easily reference other Flakes through Inputs, like &lt;code dir=&quot;auto&quot;&gt;sodiboo/niri-flake&lt;/code&gt;, enabling declarative management of software that isn’t officially supported. I don’t actually plan to use HM to manage Niri though.&lt;/p&gt;
&lt;p&gt;For development environments, you might have noticed that many open source projects on GitHub/Codeberg now have a &lt;code dir=&quot;auto&quot;&gt;flake.nix&lt;/code&gt; file in their root directory. With this file, you can easily reproduce the entire development environment with Nix, isolated from your main system - all with just one command: &lt;code dir=&quot;auto&quot;&gt;nix develop&lt;/code&gt;. Most modern Nix projects (even non-Nix projects) are starting to use this because it’s genuinely useful.&lt;/p&gt;
&lt;p&gt;Of course, there are some drawbacks, like unstable APIs (still “experimental” since 2019) and mandatory Git dependency. There are other pitfalls too. &lt;em&gt;Determinate Nix&lt;/em&gt; solves some of these, but it’s partially closed-source (like nixd). Despite the pitfalls, Flakes is more convenient than Channels, and with AI managing my configs, the migration wasn’t too complex.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;file-showcase&quot;&gt;File showcase?&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;First, &lt;code dir=&quot;auto&quot;&gt;flake.nix&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Kokosa&apos;s Nix Flake&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;inputs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# Nixpkgs &amp;#x26; NUR&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;nixpkgs&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github:NixOS/nixpkgs/nixos-unstable&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;nur&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github:nix-community/NUR&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# Flake-parts&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;flake-parts&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github:hercules-ci/flake-parts&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# Home Manager&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;home-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github:nix-community/home-manager&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;inputs&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;nixpkgs&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;follows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;nixpkgs&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# Other&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;hid-bpf-uclogic&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github:dramforever/hid-bpf-uclogic&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;outputs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;inputs&lt;/span&gt;&lt;span&gt; @ {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;nixpkgs,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;flake-parts,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;}:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;flake-parts&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lib&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;&lt;span&gt;mkFlake&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span&gt;inherit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;inputs&lt;/span&gt;&lt;span&gt;;} {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;systems&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;x86_64-linux&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;perSystem&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;pkgs,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;}: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;formatter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pkgs&lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;&lt;span&gt;alejandra&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;flake&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;nixosConfigurations&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;kokosa&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nixpkgs&lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lib&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;&lt;span&gt;nixosSystem&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;x86_64-linux&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;specialArgs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;inherit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;inputs&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;modules&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;./nixos/hosts/kokosa/default.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The single file imported, &lt;code dir=&quot;auto&quot;&gt;default.nix&lt;/code&gt;, is what used to be my machine’s &lt;code dir=&quot;auto&quot;&gt;configuration.nix&lt;/code&gt;, though it’s now been completely transformed. The original massive file has been sliced into many smaller files and unified through imports. Besides that, this file only contains some Home Manager settings.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;imports&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputs&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;home-manager&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;nixosModules&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;home-manager&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/nix-settings.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/networking.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/security.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/packages.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/services.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/desktop.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/locale.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/users.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;../../modules/boot.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;./hardware.nix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The rest isn’t much different from my old config. They haven’t been uploaded to GitHub yet, but I’ll probably get around to it when I have time. Here’s a screenshot:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://kokosa.icu/posts/flake/rice.avif&quot; alt=&quot;I love this wallpaper&quot;&gt;&lt;figcaption&gt;I love this wallpaper&lt;/figcaption&gt;&lt;/figure&gt;</content:encoded><category>NixOS</category></item></channel></rss>