<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Calvin's Dev Logs</title>
    <link>https://calvin.my/</link>
    <description>Calvin's dev logs — code snippets, demos, tutorials, and solutions across software topics. Tracking my coding journey and discoveries.</description>
    <language>en-us</language>
    <pubDate>Mon, 31 Aug 2026 02:59:50 +0800</pubDate>
    <atom:link href="https://calvin.my/feed" rel="self" type="application/rss+xml"/>
    <item>
      <title>Migrating Rails System Tests from Selenium to Playwright</title>
      <link>https://calvin.my/posts/migrating-rails-system-tests-from-selenium-to-playwright</link>
      <description>Rails applications can often migrate system tests from Selenium to Playwright by changing the driver, since Capybara preserves most test APIs. The main effort is identifying Selenium-specific calls and subtle behavioral differences in script results and missing attributes, which can cause silent failures. The post covers installing compatible Node and browser dependencies, updating CI, translating affected tests, removing unneeded Chrome dependencies, and validating the suite with repeatable test seeds.</description>
      <pubDate>Mon, 31 Aug 2026 02:59:50 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:243</guid>
    </item>
    <item>
      <title>Migrate a Single Repository from Bitbucket to GitHub</title>
      <link>https://calvin.my/posts/migrate-a-single-repository-from-bitbucket-to-github</link>
      <description>This guide explains how to migrate a Bitbucket repository to GitHub while preserving branches, tags, and commit history. It requires an accessible empty GitHub repository, local Git, and authenticated GitHub CLI. The process uses a bare clone and mirror push, then reclones the GitHub repository. It also covers optionally renaming the default branch from master to main, warns that mirroring can overwrite destination references, and recommends verifying branches, tracking, and working-tree status.</description>
      <pubDate>Thu, 27 Aug 2026 12:03:14 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:242</guid>
    </item>
    <item>
      <title>Chrome on-device AI with Gemma4 (Aug 2026)</title>
      <link>https://calvin.my/posts/chrome-on-device-ai-with-gemma4-aug-2026</link>
      <description>The post tests Chrome’s Dev-channel on-device Gemma4 summarization on a 1,300-word technical deployment article. After enabling the model and disabling Nano v3 to isolate results, Gemma4 produced a more context-aware summary than Nano, though with minor wording errors. The author finds local summarization useful for reader-triggered tl;drs because it is private, offline, and free, but retains server-side summaries for metadata due to stronger reliability and model-selection control.</description>
      <pubDate>Wed, 26 Aug 2026 01:33:57 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:241</guid>
    </item>
    <item>
      <title>Deploying Rails with Capistrano in 2026</title>
      <link>https://calvin.my/posts/deploying-rails-with-capistrano-in-2026</link>
      <description>This updated guide explains how to deploy a modern Rails application with Capistrano, covering current credentials, Propshaft, Ruby 4 and Bundler 4, Passenger, and Solid Queue workers. It recommends linking shared configuration files, validating server setup before deployment, and correcting outdated defaults for Bundler, migrations, and Passenger restarts. It also addresses accumulating Bootsnap cache files caused by release-specific paths, recommending delayed cleanup to reduce disk use.</description>
      <pubDate>Sat, 22 Aug 2026 16:45:47 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:240</guid>
    </item>
    <item>
      <title>Few ways to ask an AI provider how much credit you have left</title>
      <link>https://calvin.my/posts/few-ways-to-ask-an-ai-provider-how-much-credit-you-have-left</link>
      <description>Managing prepaid credits across AI providers requires different monitoring methods because billing visibility varies widely. DeepSeek and Kimi provide balances directly, while xAI requires a separate management credential and interpretation of its billing format. Anthropic and OpenAI expose spending rather than balances, requiring manually recorded starting balances and periodic recalculation. Gemini offers no usable billing API, leaving its web console as the only option.</description>
      <pubDate>Wed, 19 Aug 2026 02:18:05 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:239</guid>
    </item>
    <item>
      <title>Rewriting a web app against a frozen API contract</title>
      <link>https://calvin.my/posts/rewriting-a-web-app-against-a-frozen-api-contract</link>
      <description>A team rebuilt an unmaintained, money-handling Rails application while preserving its frozen third-party API contract. They separated behavioral documentation from improvement reviews, delivered migration phases with tests, and used captured requests, database changes, and screenshots to verify parity against the running system rather than legacy source. The work also exposed safe deletions, strengthened server-side security, and refined rate limits. Modernizing the stack was less demanding than proving equivalent behavior.</description>
      <pubDate>Sun, 16 Aug 2026 15:19:52 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:238</guid>
    </item>
    <item>
      <title>Ruby Bundler’s cooldown Feature for Safer Gem Updates</title>
      <link>https://calvin.my/posts/ruby-bundler-s-cooldown-feature-for-safer-gem-updates</link>
      <description>Bundler 4.0.13 adds a new cooldown feature that blocks gem versions published within the last N days, giving maintainers a safer delay before adopting updates. The post explains that this can reduce supply-chain risk and provide time to catch issues such as account takeovers. It also shows how to enable cooldown in the Gemfile or via Bundler commands, and notes that setting it to 0 bypasses the filter when needed.</description>
      <pubDate>Sat, 06 Jun 2026 14:56:50 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:237</guid>
    </item>
    <item>
      <title>SQLite3 as Production Database</title>
      <link>https://calvin.my/posts/sqlite3-as-production-database</link>
      <description>The post outlines practical steps for running SQLite as a production database in a Rails app. It recommends splitting workloads into separate database files to reduce lock contention, tuning SQLite with pragmas such as larger cache, WAL mode, and a busy timeout to improve performance and reliability, and setting up backups with verified restore testing. It also notes that some settings trade memory for speed, so they should be chosen carefully.</description>
      <pubDate>Fri, 08 May 2026 16:20:55 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:236</guid>
    </item>
    <item>
      <title>Interesting features in Claude Code CLI</title>
      <link>https://calvin.my/posts/interesting-features-in-claude-code-cli</link>
      <description>The post highlights several lesser-known Claude Code CLI features that improve usability and personalization. It covers customizing the terminal status line, enabling push-to-talk voice input, accessing an official sticker store, and using an environment variable that changes the input layout. It also notes an insights command that reviews the past month of sessions and summarizes usage patterns, helping users understand and improve how they work with Claude.</description>
      <pubDate>Sun, 05 Apr 2026 12:54:42 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:235</guid>
    </item>
    <item>
      <title>Warning: connection is not using a post-quantum key exchange algorithm</title>
      <link>https://calvin.my/posts/warning-connection-is-not-using-a-post-quantum-key-exchange-algorithm</link>
      <description>The post explains an OpenSSH warning about connections not using a post-quantum key exchange method, noting that it is a precaution against future “store now, decrypt later” risks rather than an immediate security problem. It outlines three responses: upgrade the server to OpenSSH 10 or later, configure the client to prefer quantum-resistant key exchanges and test whether the server supports them, or suppress the warning in the SSH config if needed.</description>
      <pubDate>Thu, 26 Mar 2026 14:18:18 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:234</guid>
    </item>
    <item>
      <title>Warning 'mysql_native_password' authentication type is disabled by default in MySQL 8.4</title>
      <link>https://calvin.my/posts/warning-mysql_native_password-authentication-type-is-disabled-by-default-in-mysql-8-4</link>
      <description>Upgrading from MySQL 8.0 to 8.4 can trigger a warning because `mysql_native_password` is deprecated and disabled by default. The post explains that affected accounts should be identified and moved to a newer authentication method, preferably `caching_sha2_password`. It recommends first updating to the latest 8.0 minor release, then reviewing user plugins, changing each impacted account, and testing connections to ensure clients still authenticate successfully.</description>
      <pubDate>Thu, 26 Mar 2026 01:07:53 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:233</guid>
    </item>
    <item>
      <title>The Chrome DevTool MCP General Availability</title>
      <link>https://calvin.my/posts/the-chrome-devtool-mcp-general-availability</link>
      <description>The Chrome DevTools MCP server is now generally available in Chrome stable (v146). After enabling remote debugging, you can connect it to developer CLIs like Gemini or Claude so agents can access your browser session. In tests Claude listed open tabs, took screenshots, navigated and reloaded pages, inspected templates, and adjusted layout—widening a form and its inputs—demonstrating live, programmatic browser interaction for debugging and UI fixes.</description>
      <pubDate>Sun, 15 Mar 2026 13:07:37 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:232</guid>
    </item>
    <item>
      <title>Enabling agentic coding in Xcode</title>
      <link>https://calvin.my/posts/enabling-agentic-coding-in-xcode</link>
      <description>This guide shows how to enable Xcode v26.3’s agentic coding feature: update Xcode, open the Coding Agent panel, pick a provider (the demo uses Anthropic Claude), link your subscription, install the Claude Agent tool, and authorize Xcode to consume your code quota. After setup a chat interface appears; you can send requests, report issues via a per-message Report button, switch to the Claude Agent with the edit control, and start building with the agent tool.</description>
      <pubDate>Sun, 01 Mar 2026 12:36:28 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:231</guid>
    </item>
    <item>
      <title>Gemini 3.1 Flash image (Nano Banana 2) preview</title>
      <link>https://calvin.my/posts/gemini-3-1-flash-image-nano-banana-2-preview</link>
      <description>Google's Nano Banana 2 (Gemini 3.1 Flash Image) preview outlines API changes and tests. The gemini-3.1-flash-image-preview model adds a 0.5K (512px) size, several new aspect ratios including ultra-wide and tall formats, and Google Search grounding (including image search), and can return images or combined text+image outputs. Tests produced a small app icon, 8:1 panoramic landscape, 1:8 film-strip graphic, and a currency-rate board using live search, demonstrating practical uses for varied assets and grounded visual queries.</description>
      <pubDate>Fri, 27 Feb 2026 15:06:26 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:230</guid>
    </item>
    <item>
      <title>Rails Solid Queue async mode</title>
      <link>https://calvin.my/posts/rails-solid-queue-async-mode</link>
      <description>Solid Queue reintroduced an Async Mode that runs Supervisor, Worker, Dispatcher and Scheduler in a single process to reduce memory usage and improve suitability for resource-constrained deployments. To use it, upgrade the gem to v1.3.0 or later and start your supervisor with the mode set to async, then reread/update the supervisor configuration. Verify the mode by checking the supervisor process name, which will indicate async.</description>
      <pubDate>Wed, 07 Jan 2026 11:36:50 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:229</guid>
    </item>
    <item>
      <title>Adding a catch all black hole blocks in Nginx</title>
      <link>https://calvin.my/posts/adding-a-catch-all-black-hole-blocks-in-nginx</link>
      <description>This post describes adding a catch‑all black‑hole server block in Nginx to handle requests that don't match defined domains. The approach uses a default server with a placeholder SSL certificate and immediately drops unwanted connections, preventing misrouted traffic from reaching real applications, reducing bandwidth used by IP‑based scanners, and avoiding accidental exposure of valid site certificates during HTTPS handshakes. Restart Nginx after adding the block to activate it.</description>
      <pubDate>Mon, 05 Jan 2026 13:21:56 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:228</guid>
    </item>
    <item>
      <title>Using simplecov code coverage with Rails &amp; Minitest</title>
      <link>https://calvin.my/posts/using-simplecov-code-coverage-with-rails-minitest</link>
      <description>This post shows how to integrate SimpleCov with a Rails 8 app using Minitest. It covers adding the gem and enabling SimpleCov in the test helper with branch coverage, per‑suite command names and a merge timeout, plus optional filters to exclude very small files. You can add custom groups (for example, providers). Run unit and system suites with per‑suite environment names so reports merge, and find the combined HTML coverage in the coverage directory.</description>
      <pubDate>Fri, 02 Jan 2026 14:23:46 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:227</guid>
    </item>
    <item>
      <title>A simple Ruby::Box demo</title>
      <link>https://calvin.my/posts/a-simple-ruby-box-demo</link>
      <description>This post demos Ruby 4.0's experimental Ruby Box, which creates in-process isolated execution spaces. It contrasts an unsafe eval of LLM-generated code with running that code inside a Ruby Box, showing the unsafe approach can reach a global user object and leak credentials while the box blocks that access. The author says the feature could enable safer LLM-driven code execution but remains experimental and needs measures like restricting libraries and scanning for malicious patterns.</description>
      <pubDate>Sat, 27 Dec 2025 15:21:58 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:226</guid>
    </item>
    <item>
      <title>Litestream 0.5.x updates</title>
      <link>https://calvin.my/posts/litestream-0-5-x-updates</link>
      <description>This post explains using Litestream v0.5.x to back up SQLite databases to S3: install the matching release, enable and start the Litestream service, then edit its configuration to provide AWS credentials, set a sync interval, and define S3 replica targets. After restarting, snapshots appear in the configured S3 bucket. To restore, ensure you have valid S3 credentials and use Litestream’s restore functionality to recover a database.</description>
      <pubDate>Thu, 25 Dec 2025 16:29:32 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:225</guid>
    </item>
    <item>
      <title>Build a simple app that describes an image and works offline</title>
      <link>https://calvin.my/posts/build-a-simple-app-that-describes-an-image-and-works-offline</link>
      <description>This post demonstrates building an Android app that uses the Gemini Image Description API to generate English image descriptions locally. It outlines prerequisites (SDK 29+, limited flagship-device support, no emulator), initializing the image describer, checking feature status, triggering model download when needed, running on-device inference with timeout handling, and cleaning up resources. The UI flow prompts users to download the model and grant storage permission; once downloaded, descriptions work offline on supported devices.</description>
      <pubDate>Sun, 14 Dec 2025 21:11:09 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:224</guid>
    </item>
    <item>
      <title>API Error: claude block must have a corresponding `tool_use` block in the previous message</title>
      <link>https://calvin.my/posts/api-error-claude-block-must-have-a-corresponding-tool_use-block-in-the-previous-message</link>
      <description>The post explains how to resolve Claude Code's blocking error indicating a missing tool-use block. Remedies include starting a new conversation, using a compact feature to clear history while preserving a summary, or using a rewind feature to step back one or two checkpoints and restore a chosen checkpoint's conversation, code, or both. Restoring removes the problematic recent conversation so you can continue from the earlier state. A related bug report is noted.</description>
      <pubDate>Tue, 02 Dec 2025 18:39:00 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:223</guid>
    </item>
    <item>
      <title>Gemini 3 Pro image (Nano Banana Pro) early preview</title>
      <link>https://calvin.my/posts/gemini-3-pro-image-nano-banana-pro-early-preview</link>
      <description>Google's Nano Banana Pro image model (Gemini 3 Pro) was evaluated via its API to assess image generation, reference-image guidance, conversational edits, and mixed realistic/illustrative outputs. The API supports configurable resolutions up to 4K and enforces a mandatory internal thinking process that returns a large signature which must be supplied to continue conversations. Tests produced high-quality 4K JPEGs but with multi-minute streaming latency, larger file sizes, increased token usage, and substantial signature storage considerations.</description>
      <pubDate>Sun, 23 Nov 2025 22:37:47 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:222</guid>
    </item>
    <item>
      <title>Adding sub-resource integrity with Importmap &amp; Rails</title>
      <link>https://calvin.my/posts/adding-sub-resource-integrity-with-importmap-rails</link>
      <description>Subresource Integrity requires a cryptographic hash for resources; while CDN or static assets provide fixed hashes, build-time generated files need per-build hash calculation. Rails can handle this: configure the hashing algorithm, enable integrity on stylesheet tags, and activate integrity support for importmap-managed modules. After setup, Rails adds integrity attributes to stylesheet and modulepreload links so browsers can verify fetched assets' integrity.</description>
      <pubDate>Sat, 15 Nov 2025 22:53:12 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:221</guid>
    </item>
    <item>
      <title>Adding sub-resource integrity with Vite build</title>
      <link>https://calvin.my/posts/adding-sub-resource-integrity-with-vite-build</link>
      <description>Vite doesn't natively produce subresource integrity hashes for build-generated assets, so the post shows using a plugin to compute them during build. It recommends vite-plugin-manifest-sri: install the package, enable it in Vite config, and run the build. The generated manifest includes integrity hashes and the served HTML will include integrity attributes; you can also opt for stronger algorithms such as SHA‑512, enabling SRI protection for build artifacts.</description>
      <pubDate>Thu, 13 Nov 2025 10:28:47 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:220</guid>
    </item>
    <item>
      <title>Install the missing ext-intl PHP extension in MacOS</title>
      <link>https://calvin.my/posts/install-the-missing-ext-intl-php-extension-in-macos</link>
      <description>Homebrew removed the intl extension from its PHP formulae, so after updating PHP on macOS apps that require ext-intl may report the extension is missing. To fix this, either switch to another PHP provider (for example Laravel Herd) or compile PHP yourself, or install Homebrew’s separate php-intl formula which provides the intl extension and can be added alongside the installed PHP.</description>
      <pubDate>Wed, 12 Nov 2025 15:58:58 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:219</guid>
    </item>
    <item>
      <title>New ways to install Claude Code on macOS</title>
      <link>https://calvin.my/posts/new-ways-to-install-claude-code-on-macos</link>
      <description>Anthropic previously distributed Claude Code via NPM, but now offers two macOS alternatives: a one-line installer script and a Homebrew cask, both of which remove the NPM prerequisite. To switch, uninstall the global NPM package first, then install Claude Code using either alternative and run the CLI. These options simplify installation for users who prefer not to use NPM.</description>
      <pubDate>Tue, 04 Nov 2025 20:47:53 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:218</guid>
    </item>
    <item>
      <title>Breaking change in net-http gem to exclude default content type</title>
      <link>https://calvin.my/posts/breaking-change-in-net-http-gem-to-exclude-default-content-type</link>
      <description>The net-http gem (from v0.7.0) no longer sets a default Content-Type header. That change can alter HTTP request behavior for clients and libraries that depended on the prior default—examples include HTTP wrappers and Google reCAPTCHA verification, which may return invalid-input-response when the header is missing. The remedy is to explicitly set the appropriate Content-Type header (for example, the form-encoding content type) on affected requests.</description>
      <pubDate>Sat, 01 Nov 2025 16:57:41 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:217</guid>
    </item>
    <item>
      <title>Claude Code's vision - The Chrome DevTool MCP</title>
      <link>https://calvin.my/posts/claude-code-s-vision-the-chrome-devtool-mcp</link>
      <description>The post explains using Claude Code with Chrome DevTools MCP on a Mac to let AI agents access browser data for frontend debugging. It outlines installing and enabling macOS permissions, pointing Claude at a local site, and launching a standalone browser instance. Through the MCP the agent can capture screenshots, inspect console errors, and use debugging and performance tools, simplifying communication of UI issues between developers and agents.</description>
      <pubDate>Sat, 18 Oct 2025 23:05:20 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:216</guid>
    </item>
    <item>
      <title>Gemini Robotics-ER 1.5: High real world accuracy?</title>
      <link>https://calvin.my/posts/gemini-robotics-er-1-5-high-real-world-accuracy</link>
      <description>Google’s preview Gemini Robotics ER 1.5, claimed to specialize in physical-world understanding, was evaluated on three vision tasks: counting overlapping cookies, estimating steps to the end of a path, and reading a rim size from a wet tire. In each test the author reports Robotics ER produced the correct answer while competing models (GPT‑5 mini and Grok 4) erred, suggesting Robotics ER offers notably stronger real-world visual reasoning and measurement accuracy.</description>
      <pubDate>Sat, 18 Oct 2025 21:10:15 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:215</guid>
    </item>
    <item>
      <title>Error: certificate verify failed (unable to get certificate CRL) (OpenSSL::SSL::SSLError)</title>
      <link>https://calvin.my/posts/error-certificate-verify-failed-unable-to-get-certificate-crl-openssl-ssl-sslerror</link>
      <description>A change in the underlying OpenSSL library can cause Ruby’s OpenSSL gem to fail certificate verification when connecting to Google services. The issue is fixed in a patched openssl gem (version 3.3.1) and documented upstream. To ensure your application uses the corrected release instead of an older one, explicitly declare the openssl gem in your project’s Gemfile so dependency resolution picks the patched version.</description>
      <pubDate>Wed, 15 Oct 2025 14:23:34 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:214</guid>
    </item>
  </channel>
</rss>
