RSSAmplifier

Blog

Krzysztof Kowalczyk blog

blog.kowalczyk.infoRSS feed ↗25 posts

Latest posts

Letting AI agents drive a GUI app with -dbg-control


 SumatraPDF is a Windows GUI application for viewing PDF, ePub and comic books written in C++. 

 Lately I do a lot of my SumatraPDF coding with AI agents: Claude Code, Grok Build, OpenAI Codex. 

 They’re good at writing code. They’re less good at knowing if the code works, especially for GUI apps. 

 The problem: agents don’t drive UI well 
…

Finding active GitHub forks from the command line


 I maintain SumatraPDF on GitHub. People fork it and make their own changes. I want to know which forks are active and what they’re working on. 

 GitHub has a Network tab for this. I find it lousy. 

 It’s hard to see active forks at a glance. Panning and zooming the UI is slow and fiddly. I just want a sorted list of forks with actual changes. 

 So I…

Speeding up JavaScript function with AI help


 A new JavaScript library pretext for fast text measuring / layout popped up on social media. 

 Potentially interesting given its focus on speeding up text rendering in web apps and me writing web apps and liking them being fast. 

 I looked at the code and saw a function isCJK() . Given my 3 decades of programming and performance optimization, it looked like it could be sped…

How to run msvc cl.exe from command-line (powershell)


 So you’ve installed Visual Studio and you want to run the compiler cl.exe from command-line. Microsoft makes it surprisingly hard. 

 They give you a shortcut which opens a terminal window with cmd.exe setup for compilation. But I don’t want a separate window, I want to use the terminal app. 

 You can run: 

 
 cmd.exe /k "C:\Program Files\Microsoft…

Novel login system for web apps


 Anna’s Archive implements an interesting, anonymous way to create an account for web applications. 

 They don’t use e-mail, Google or GitHub logins. When you create an account, they generate a secret key. That secret key is used to login. 

 The downside is that if you loose they, you loose access to the account. 

 The interesting thing is anonymity: the…

Benchmarking JSON vs TOON in Go


 Since I’ve decided to use TOON instead of JSON, I’ve benchmarked the performance of serialization of 2 Go TOON libraries compared to JSON built-in serialization. 

 Here are the results using current version of the libraries and go 1.25: 
 % go run .
 goos: darwin
 goarch: arm64
 pkg: bench_toon
 cpu: Apple M3 Pro
 BenchmarkJSONMarshalCompact-11…

From JSON to TOON


 TOON stands for a Token-Oriented Object Notation. 

 It’s a new text format that has the same capability as JSON but uses less space. 

 It was invented to lower costs of sending data (tokens) to LLM AIs but it has 2 advantages over JSON: 

 
 smaller than JSON 
 more readable than JSON 
 

 It has implementation in many programming…

Fixing Zed's debugger keybindings


 Zed has a good debugger built-in but their keybindings are crazy. Thankfully, you can remap them by opening menu Zed / Settings / Open key bindings and adding this to the file: 
 { 
 'use_key_equivalents' : true , 
 'bindings' : { 
 'f11' : 'debugger::StepInto' , 
 'f10' : 'debugger::StepOver' 
 // 'shift shift': 'file_finder::Toggle'
 } 
 }, 
 
 Those…

Ideas for faster web dev cycle


 I strongly believe that fast iteration cycle is important for productivity. In programming fast iteration means: how quickly can I go from finishing writing the code to testing it. That’s why I don’t like languages that compile slowly: slow compilation puts a hard limit on your iteration cycle. 

 That’s a general principle. How does it translate to actions?…

Zed debug setup for go server / Svelte web app


 Today I figured out how to setup Zed to debug, at the same time, my go server and Svelte web app. 

 My dev setup for working on my web app is: 

 
 go server is run with -run-dev arg 
 go server provides backend apis and proxies requests it doesn’t handle to a vite dev server that does the serving of JavaScript etc. files from my Svelte code 
 go server in…

Stage manager in Mac OS


 Stage Manager in Mac OS is not a secret, but I’ve only learned about it recently. 

 It’s off by default so you have to enable it in system settings:
 
It’s hard to describe in words, so you’ll have to try it. And experiment a bit because I didn’t get in the first hour. 

 It’s a certain way to manage windows for less clutter.…

AltTab for Mac OS


 AltTab solves a simple problem really well: it brings Windows-style Alt + Tab window switching to Mac OS. 

 That’s it. That’s all there is to it. 

 I think Windows way of Alt - tabbing windows is better than Mac’s. 

 It’s a must for someone like me, who switches between using Windows and Mac OS. That small difference drove me mad when using…

lazy import of JavaScript modules


 When working on big JavaScript web apps, you can split the bundle in multiple chunks and import selected chunks lazily, only when needed. That makes the main bundle smaller, faster to load and parse. 

 How to lazy import a module? 
 let hljs = await import ( 'highlight.js' ). default ; 
 
 is equivalent of: 
 import hljs from 'highlight.js' ; 
 
 Now: 
…

Using await in Svelte 5 components

&#xA; Svelte 5 just added a way to use async function in components. This is from Rich Harris talk &#xA;&#xA; The simplest component &#xA; &#xA;&#x9; &#xA;&#x9; &#xA; &#xA; &#xA; &#xA; < script > &#xA; async function multiply ( x , y ) { &#xA; &#x9; let uri = `/multiply?x= ${ x } &y= ${ y } ` &#xA; &#x9; let rsp = await fetch ( uri ) &#xA; &#x9; let resp = await rsp . text (); &#xA; &#x9; return…

vite /rollup manualChunks

&#xA; In MS-DOS days programmers were limited to 640 kB of code. When their programs became bigger than that they had to implement tricky code to load / unload code chunks on demand. &#xA;&#xA; In web apps we&rsquo;re not limited by size but it&rsquo;s still a good idea to strive for the smallest possible JavaScript bundle. We can do it by extracting rarely used pieces of functionality into…

Increase software sales by 50% or more

&#xA; This is re-post of&#xA; How to Permanently Increase Your Sales by 50% or More in Only One Day article by Steve Pavlina &#xA;&#xA; Of all the things you can do to increase your sales, one of the highest leverage activities is attempting to increase your products&rsquo; registration rate. Increasing your registration rate from 1.0% to 1.5% means that you simply convince one more downloader out…

File sync is very slow

&#xA; I&rsquo;m working on a Go library appendstore for append-only store of lots of things in a single file. &#xA;&#xA; To make things as robust as possible I was calling os.File.Sync() after each append. Sync() is waiting until the data is acknowledged as truly, really written to disk (as opposed to maybe floating somewhere in disk drive&rsquo;s write buffer). &#xA;&#xA; Oh boy, is it slow. A…

Desktop UI frameworks written by a single person

&#xA; Less known desktop UI frameworks &#xA; &#xA;&#x9; &#xA;&#x9; &#xA; &#xA; &#xA; &#xA;&#xA; Writing desktop software is hard. The UI technologies of Windows or MacOS are awful compared to web technology. &#xA;&#xA; What can trivially be done with HTML/CSS/JavaScript in few minutes can take hours using Windows&rsquo;s win32 APIs or Mac&rsquo;s Cocoa. &#xA;&#xA; That&rsquo;s why the default…

Evolving Edna Ask AI UI

&#xA; This is a real life example of tweaking UI in Edna , my note taking application with super powers. &#xA;&#xA; Ask AI is a simple AI chat: you write a question, send it to LLM model and get a response. &#xA;&#xA; Here&rsquo;s my first version of the UI: &#xA;&#xA; &#xA;&#xA; What is good and bad about this version? &#xA;&#xA; Good : there&rsquo;s a learn more link. This is not an obvious…

Implementing UI translation in SumatraPDF, a C++ Windows application

&#xA; Translating user interface of SumatraPDF &#xA; &#xA;&#x9; &#xA;&#x9; &#xA; &#xA; &#xA; &#xA;&#xA; SumatraPDF is the best PDF/eBook/Comic Book viewer for Windows. It&rsquo;s small, fast, full of features, free and open-source. &#xA;&#xA; It became popular enough that it made sense to translate the UI for non-English users. Currently we support 72 languages. &#xA;&#xA; This article describes…

Calling Grok, OpenAI, Anthropic, Google, OpenRouter API from the browser

&#xA; Here&rsquo;s what I learned about calling LLM APIs from the browser when building AI chat functionality in my note taking app Edna . &#xA;&#xA; The API I care about is getting LLM response to a question in a streaming way. &#xA;&#xA; OpenAI pioneered this and created https://api.openai.com/v1/chat/completions POST API. Others created a compatible API for their LLM to make it easy for…

Case study of over-engineered C++ code

&#xA; You&rsquo;ve heard of over-engineered, unnecessarily complex code but what exactly is it? &#xA;&#xA; I believe it&rsquo;s best to show by example. &#xA;&#xA; While it&rsquo;s not my intention to criticize other people&rsquo;s code, I think it&rsquo;s better to show code and how to improve it rather than vaguely talk about principles. &#xA;&#xA; The code that I consider over-engineered:…

Increase open file limit on Ubuntu Linux

&#xA; What and why of open file limit &#xA; &#xA;&#x9; &#xA;&#x9; &#xA; &#xA; &#xA; &#xA;&#xA; If you run a webapp on a Linux server, your webapp needs to open files and make network connections. &#xA;&#xA; Most Linux servers have horrible default for this and limit the number of opened files at the same time to e.g. 1024. &#xA;&#xA; To check the limit run: ulimit -n . &#xA;&#xA; 1024 makes sense…

Explaining nil interface{} gotcha in Go

&#xA; Explaining nil interface{} gotcha in Go &#xA; &#xA;&#x9; &#xA;&#x9; &#xA; &#xA; &#xA; &#xA;&#xA; A footgun &#xA; &#xA;&#x9; &#xA;&#x9; &#xA; &#xA; &#xA; &#xA;&#xA; In Go empty interface is an interface without any methods, typed as interface{} . &#xA;&#xA; A zero value of interface{} is nil : &#xA; var v interface {} // compiler sets this to nil, you could explicitly write = nil &#xA; if v…

Size textarea to content

&#xA; To size textarea to content: &#xA; textarea { &#xA; &#x9; field-sizing : content ; &#xA; &#x9; min-height : 8 rem ; &#xA; &#x9; max-height : 70 vh ; &#xA; } &#xA; &#xA; Using tailwindcss: <textarea class="min-h-[8rem] max-h-[70vh] field-sizing-content"></textarea> &#xA;&#xA; Needs Chrome 123+, Firefox 126+ &#xA;&#xA; &#xA;