<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>viktorm.link</title><link>https://viktorm.link/</link><description>Some of the awesome thoughts, projects and lessons I had.</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>Viktor Melnikov</managingEditor><webMaster>Viktor Melnikov</webMaster><lastBuildDate>Tue, 23 Jun 2026 17:40:50 +0200</lastBuildDate><atom:link href="https://viktorm.link/feed.xml" rel="self" type="application/rss+xml"/><item><title>Kubernetes Pods Are Not New Servers</title><link>https://viktorm.link/til/kubernetes-pods-share-nodes/</link><pubDate>Tue, 23 Jun 2026 17:40:50 +0200</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/kubernetes-pods-share-nodes/</guid><description>&lt;p&gt;A while ago I started &lt;a href="https://www.udemy.com/course/docker-kubernetes-the-practical-guide/"&gt;Docker &amp;amp; Kubernetes: The Practical Guide&lt;/a&gt; on Udemy. I got through about half, then stopped when the Kubernetes section began — it did not feel relevant yet.&lt;/p&gt;
&lt;p&gt;At my current job I keep hearing Kubernetes terms, so I picked the course back up. First surprise: I always thought a new pod meant a new tiny server — a small EC2 or Azure VM, one per pod.&lt;/p&gt;</description></item><item><title>Terminal Line Shortcuts: Ctrl+U, Ctrl+K, Ctrl+A, Ctrl+E</title><link>https://viktorm.link/til/terminal-line-shortcuts/</link><pubDate>Tue, 02 Jun 2026 10:01:32 +0200</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/terminal-line-shortcuts/</guid><description>&lt;p&gt;I started using OpenCode and often needed to wipe or fix a long text quickly. It is a terminal based app, so removing line is what I needed. A few terminal shortcuts made that much easier.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Ctrl+U&lt;/code&gt; — delete from the cursor to the start of the line&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctrl+K&lt;/code&gt; — delete from the cursor to the end of the line&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Copilot also pointed me to &lt;code&gt;Ctrl+A&lt;/code&gt; and &lt;code&gt;Ctrl+E&lt;/code&gt;, and now I use them all the time.&lt;/p&gt;</description></item><item><title>lean-ctx for Lower AI Token Usage</title><link>https://viktorm.link/til/lean-ctx/</link><pubDate>Mon, 01 Jun 2026 19:42:00 +0200</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/lean-ctx/</guid><description>&lt;p&gt;At work I hit 100% of quota and had to find a way to cut usage without slowing down. I started using &lt;a href="https://leanctx.com/"&gt;lean-ctx&lt;/a&gt; — a context layer that sits between AI coding tool and the codebase.&lt;/p&gt;
&lt;p&gt;Instead of sending raw file contents and full shell output straight to the model, lean-ctx intercepts those reads and commands, compresses them, and caches repeats.It uses MCP server for that and prompt in Agents.md to use its tools instead of default ones. File reads go through MCP tools like &lt;code&gt;ctx_read&lt;/code&gt; and &lt;code&gt;ctx_search&lt;/code&gt;. Terminal output gets compressed via shell hooks. Re-reading a cached file costs far fewer tokens than sending the whole file again.&lt;/p&gt;</description></item><item><title>See Where a Function Is Called in VS Code</title><link>https://viktorm.link/til/vscode-ctrl-click-navigation/</link><pubDate>Thu, 28 May 2026 12:00:00 +0200</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/vscode-ctrl-click-navigation/</guid><description>&lt;p&gt;Another day, I was trying to find where function was called, so I copied the name and went to search tab to find the references. At that moment my college Robbe showed me easier way.&lt;/p&gt;
&lt;p&gt;In VS Code, place your cursor on a defined function and hold &lt;code&gt;Ctrl&lt;/code&gt; and click its name. Usually you jump to the definition, but if you are already at the definition, you can quickly jump to references. On macOS, use &lt;code&gt;Cmd+Click&lt;/code&gt;. VS Code opens a references panel with every file and line where that function is called.&lt;/p&gt;</description></item><item><title>Git Commands Beyond add/commit/checkout</title><link>https://viktorm.link/til/git-commands-beyond-basics/</link><pubDate>Mon, 13 Apr 2026 18:13:00 +0200</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/git-commands-beyond-basics/</guid><description>&lt;p&gt;I decided that basic &lt;code&gt;git add&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;, and &lt;code&gt;git checkout&lt;/code&gt; is not enough anymore, so I started a quick Git course to go deeper. I often end up in situations where I need more advanced commands, so here is my compact reference.&lt;/p&gt;
&lt;h2 id="preview-clean-up-before-deleting-files"&gt;Preview clean-up before deleting files&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clean -dnf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt; includes untracked directories&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; is a dry run (preview only)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; is required to actually allow &lt;code&gt;git clean&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="restore-changes-in-working-tree"&gt;Restore changes in working tree&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git restore .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git restore name-of-the-file
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git restore .&lt;/code&gt; restores all tracked files in the current directory tree&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git restore name-of-the-file&lt;/code&gt; restores only one file&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="list-tracked-files"&gt;List tracked files&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git ls-files
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Shows files tracked by Git in the current repository.&lt;/p&gt;</description></item><item><title>No to Generic Names in Prompts</title><link>https://viktorm.link/til/no-to-generic-names-in-prompts/</link><pubDate>Wed, 08 Apr 2026 17:43:12 +0200</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/no-to-generic-names-in-prompts/</guid><description>&lt;p&gt;Lately, I have been working on extracting information from different sources. I combined those sources into a prompt and asked the LLM to extract key details, justify them, and cite the source.&lt;/p&gt;
&lt;p&gt;Everything worked well, but I used generic labels for different sources, like &amp;ldquo;Section 1&amp;rdquo; and &amp;ldquo;Section 2&amp;rdquo;. Those labels eventually leaked into some of the justification text. For example: &amp;ldquo;According to Section 2, this customer is eligible for a refund,&amp;rdquo; instead of &amp;ldquo;According to the Billing Policy, this customer is eligible for a refund.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Pi-hole on Raspberry Pi to block ads and enhance security</title><link>https://viktorm.link/blog/pi-hole-on-raspberry-pi/</link><pubDate>Thu, 19 Feb 2026 22:20:00 +0100</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/blog/pi-hole-on-raspberry-pi/</guid><description>&lt;h2 id="context"&gt;Context&lt;/h2&gt;
&lt;p&gt;A while ago, I bought an electronic kit secondhand, and the previous owner included a Raspberry Pi 3. To be honest, I had no idea what to do with it. I tried connecting it to a screen, and I could browse the web, but that was about it. It is a very small computer, and I had no experience or idea of what to do with it. I resold the kit a few months later but decided to keep the Raspberry Pi for myself.&lt;/p&gt;</description></item><item><title>Useful cli tools - grep and tee</title><link>https://viktorm.link/til/cli-grep-tee/</link><pubDate>Fri, 30 Jan 2026 07:51:57 +0100</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/cli-grep-tee/</guid><description>&lt;p&gt;Last month I was working on a big project, that consists of multiple pipelines, complicated envirinment settings, and I found that I use several tools all the time.&lt;/p&gt;
&lt;h2 id="grep"&gt;grep&lt;/h2&gt;
&lt;p&gt;I often use it with &lt;code&gt;env&lt;/code&gt;, for example I need to check whether current devcontainer has access to azure, I need to check if i have access to &lt;code&gt;AZURE__DATABASE__CONNECTION_STRING&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I could easily find out it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env &lt;span class="p"&gt;|&lt;/span&gt; grep AZURE__DATABASE__CONNECTION_STRING
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;env&lt;/code&gt; shows all environment variables&lt;/li&gt;
&lt;li&gt;&lt;code&gt;|&lt;/code&gt; is a pipe, it takes output of the &lt;code&gt;env&lt;/code&gt; and puts it as input to the next command - &lt;code&gt;grep&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep&lt;/code&gt; filters the input, and only shows lines that contain &lt;code&gt;AZURE__DATABASE__CONNECTION_STRING&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is still a bit combursome, so I use a simplified version usually:&lt;/p&gt;</description></item><item><title>Order of Fields Matters in Structured LLM Responses</title><link>https://viktorm.link/til/pydantic-order-of-fields/</link><pubDate>Sun, 23 Nov 2025 22:37:00 +0100</pubDate><author>Viktor Melnikov</author><guid>https://viktorm.link/til/pydantic-order-of-fields/</guid><description>&lt;p&gt;I had a very strange behavior with my responses. I was working on an email-processing tool. We use Pydantic models for structured responses.&lt;/p&gt;
&lt;p&gt;We have something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;actionType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IGNORE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;REPLY_WITH_TEMPLATE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;GENERATE_CUSTOM_EMAIL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;reasoning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I had strange responses like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;actionType&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;REPLY_WITH_TEMPLATE&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;reasoning&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;There is no template available, &amp;#34;&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;we need to generate response using company&amp;#39;s FAQ&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My first instinct was to fine-tune the prompt, and although it relatively helped, these weird errors were still present.&lt;/p&gt;</description></item></channel></rss>