<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>nsys.dev Tech Blog</title>
		<link>https://blog.nsys.dev/en/</link>
		<description>Recent content on nsys.dev Tech Blog</description>
		<generator>Hugo</generator>
		<language>en</language>
		
		
		
		
			<lastBuildDate>Mon, 15 Jun 2026 15:00:00 +0900</lastBuildDate>
		
			<atom:link href="https://blog.nsys.dev/en/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Designing a CLI on the premise that an AI will drive it</title>
				<link>https://blog.nsys.dev/en/posts/cli-for-agents/</link>
				<pubDate>Mon, 15 Jun 2026 15:00:00 +0900</pubDate>
				<guid>https://blog.nsys.dev/en/posts/cli-for-agents/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Part 5 of 5 (finale)&lt;/strong&gt; — series: &lt;em&gt;Building a publishing tool, and shipping it&lt;/em&gt;. Last time was &lt;a href=&#34;https://blog.nsys.dev/en/posts/brew-scoop-release/&#34;&gt;shipping with brew and scoop&lt;/a&gt;. See the &lt;a href=&#34;https://blog.nsys.dev/en/tags/crofty/&#34;&gt;series index&lt;/a&gt;. This time: designing the CLI on the premise that an AI drives it.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;crofty is a plain CLI you type at the terminal. But one premise of its design is a little different.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;A person installs crofty and does the first setup; after that, their AI (an agent) runs it.&amp;rdquo; That&amp;rsquo;s the usage it assumes. Rather than a person remembering and typing commands every time, an agent drives crofty on their behalf — and the build is meant not to get in the way when it does.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Shipping a CLI with brew and scoop — all at once via GoReleaser</title>
				<link>https://blog.nsys.dev/en/posts/brew-scoop-release/</link>
				<pubDate>Mon, 15 Jun 2026 14:00:00 +0900</pubDate>
				<guid>https://blog.nsys.dev/en/posts/brew-scoop-release/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Part 4 of 5&lt;/strong&gt; — series: &lt;em&gt;Building a publishing tool, and shipping it&lt;/em&gt;. Last time was &lt;a href=&#34;https://blog.nsys.dev/en/posts/i18n-design/&#34;&gt;designing a multilingual site&lt;/a&gt;. See the &lt;a href=&#34;https://blog.nsys.dev/en/tags/crofty/&#34;&gt;series index&lt;/a&gt;. This time: the practical side of shipping with brew and scoop.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Once the CLI exists, the next question is &amp;ldquo;how do I ship it?&amp;rdquo; &lt;code&gt;go install&lt;/code&gt; works, but being installable with Homebrew or Scoop is much easier on the people using it.&lt;/p&gt;&#xA;&lt;p&gt;That said, building by hand for mac, Windows, and Linux, then hand-writing a Homebrew formula and a Scoop manifest… isn&amp;rsquo;t something you keep doing every release. So I had GoReleaser do it all in one go — including the one place macOS tripped me up (signing).&lt;/p&gt;</description>
			</item>
			<item>
				<title>Designing a multilingual site — holding text in three kinds</title>
				<link>https://blog.nsys.dev/en/posts/i18n-design/</link>
				<pubDate>Mon, 15 Jun 2026 13:00:00 +0900</pubDate>
				<guid>https://blog.nsys.dev/en/posts/i18n-design/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Part 3 of 5&lt;/strong&gt; — series: &lt;em&gt;Building a publishing tool, and shipping it&lt;/em&gt;. Last time was &lt;a href=&#34;https://blog.nsys.dev/en/posts/contract-the-output/&#34;&gt;contracting the output&lt;/a&gt;. See the &lt;a href=&#34;https://blog.nsys.dev/en/tags/crofty/&#34;&gt;series index&lt;/a&gt;. This time: how to design multilingual support.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;When you hear &amp;ldquo;make the site multilingual,&amp;rdquo; translating the body comes to mind first. But once you actually do it, the body isn&amp;rsquo;t the only text that needs translating. Nav labels, a profile, config values — each has a different nature, and forcing them into one container strains.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Contract the output — keep changing the inside, even after you ship</title>
				<link>https://blog.nsys.dev/en/posts/contract-the-output/</link>
				<pubDate>Mon, 15 Jun 2026 11:00:00 +0900</pubDate>
				<guid>https://blog.nsys.dev/en/posts/contract-the-output/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Part 2 of 5&lt;/strong&gt; — series: &lt;em&gt;Building a publishing tool, and shipping it&lt;/em&gt;. Last time I shared the &lt;a href=&#34;https://blog.nsys.dev/en/posts/own-your-writing/&#34;&gt;overall picture and premises&lt;/a&gt;. Each part stands alone; see the &lt;a href=&#34;https://blog.nsys.dev/en/tags/crofty/&#34;&gt;series index&lt;/a&gt;. This time: keeping the inside changeable even after you ship.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;A tool only you use, you can rebuild however you like. The trouble starts after you publish it and other people begin using it.&lt;/p&gt;&#xA;&lt;p&gt;Rename a single config key, say, and anyone who wrote settings with the old key suddenly finds their setup broken. Once it&amp;rsquo;s out, you can&amp;rsquo;t casually change the parts people lean on. &amp;ldquo;Whatever is visible from the outside, someone will eventually rely on&amp;rdquo; — this is the everyday face of what&amp;rsquo;s known as Hyrum&amp;rsquo;s Law.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Keeping what you write in your own hands — a small publishing tool</title>
				<link>https://blog.nsys.dev/en/posts/own-your-writing/</link>
				<pubDate>Mon, 15 Jun 2026 10:00:00 +0900</pubDate>
				<guid>https://blog.nsys.dev/en/posts/own-your-writing/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Part 1 of 5&lt;/strong&gt; — series: &lt;em&gt;Building a publishing tool, and shipping it&lt;/em&gt;. Each part stands on its own; to follow the whole thing, see the &lt;a href=&#34;https://blog.nsys.dev/en/tags/crofty/&#34;&gt;series index&lt;/a&gt;. This part is the groundwork — what I wanted, and how the pieces fit. The individual design decisions come in later parts.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Where does what you write end up?&lt;/p&gt;&#xA;&lt;p&gt;Most of the places we write are on someone else&amp;rsquo;s platform. They&amp;rsquo;re easy to be read on, but the post&amp;rsquo;s address (its URL), its look, and your connection to readers all live by that platform&amp;rsquo;s rules. If the service changes course or shuts down, your writing goes with it.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Stopping distributed scraping with country-level CIDR, on stock nginx</title>
				<link>https://blog.nsys.dev/en/posts/nginx-geo-country-block/</link>
				<pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://blog.nsys.dev/en/posts/nginx-geo-country-block/</guid>
				<description>&lt;p&gt;On a certain website, I noticed traffic from a particular country&amp;rsquo;s IPs had grown noticeably. Looking closer, it wasn&amp;rsquo;t the usual &amp;ldquo;one server hammering you&amp;rdquo; type — it was scraping &lt;strong&gt;spread across a great many IPs, each at a modest pace&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This is a record of how I read its nature, chose how to block it by &amp;ldquo;blast radius&amp;rdquo; (the range of damage if something breaks), and rolled it out without stopping the running servers. I hope it offers a clue to anyone troubled by similar distributed access.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Adding a blog</title>
				<link>https://blog.nsys.dev/en/posts/blog-start/</link>
				<pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
				<guid>https://blog.nsys.dev/en/posts/blog-start/</guid>
				<description>&lt;p&gt;I&amp;rsquo;ve set up a place to jot down, little by little, the things I work on in day-to-day development — as a notebook. Nothing formal; partly a way to look back on my own work, written at an easy pace.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-its-built&#34;&gt;How it&amp;rsquo;s built&lt;/h2&gt;&#xA;&lt;p&gt;The homepage at &lt;a href=&#34;https://nsys.dev&#34;&gt;https://nsys.dev&lt;/a&gt; prioritizes loading speed, keeping a perfect 100 on every PageSpeed Insights metric. I designed the blog on the premise that adding it would not break that.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
