← Back to Blog

Day 3: Encryption, Onboarding, and a Trojan Horse

30 commits. 57 files changed. 7,652 lines added. Day 3 was intense.

API keys deserve better than plaintext

The first thing we tackled: API key storage. Yesterday, provider keys were stored in plain JSON. Today, they're encrypted with AES-256-GCM — the same standard banks use.

Why this matters early: Pinchy is a multi-user platform. The moment you have more than one person using the system, you can't have API keys sitting around in readable config files. The admin who sets up the OpenAI key shouldn't have to worry about other users (or a compromised agent) reading it.

The implementation encrypts on write, decrypts on read. Keys at rest are always encrypted. It's transparent to the rest of the codebase — the settings API handles it.

The provider setup nobody wants to think about

Setting up an AI provider (Anthropic, OpenAI, etc.) sounds trivial — just paste an API key. But the UX has a lot of edge cases:

I built the full flow: /setup/provider as an onboarding page, a shared ProviderKeyForm component used in both setup and settings, automatic redirect middleware, and visual states for "configuring" and "disconnected" in the chat UI.

After setup, Smithers (Pinchy's default agent) greets you automatically. Small touch, but it makes the first moment feel alive instead of staring at an empty chat window.

Docker that doesn't fight you

Docker Compose was working since Day 2, but developing inside it was painful. Change a file, rebuild the container, wait, repeat.

Today I added proper dev mode: hot reload inside Docker, volumes mounted for live code changes, and an inotify wrapper so OpenClaw picks up config changes without restarting. I also bound OpenClaw to the LAN interface and switched from config overwrite to config merge — so Pinchy's settings layer doesn't blow away manual gateway tweaks.

The result: docker compose up for production, docker compose -f docker-compose.dev.yml up for development. Both just work.

Documentation from day one

This might be controversial: I scaffolded a full Starlight documentation site on day 3 of a project that barely has features yet.

Here's why: documentation isn't just for users. It's a forcing function for clarity. Writing docs for the setup flow made me realize three UX issues I hadn't noticed. Writing the architecture overview made me question two design decisions.

Plus: Pinchy with good docs beats a competitor with more features but no docs. Every time. I added Pinchy branding, GitHub Actions CI for automatic deployment, and initial content covering setup, architecture, and conventions.

Oh, and I built an npm package

Almost forgot — I also extracted Pinchy's WebSocket bridge into a standalone npm package: openclaw-node.

It's the first Node.js client for OpenClaw's Gateway protocol. Connect, chat, stream responses, manage sessions — five lines of code:

import { OpenClawClient } from "openclaw-node";

const client = new OpenClawClient({
  url: "ws://localhost:18789",
});

await client.connect();

for await (const chunk of client.chat("Hello!")) {
  process.stdout.write(chunk.text);
}

Let's be honest: it's a Trojan Horse. A genuinely useful utility that happens to live under the heypinchy GitHub org, with "Built for Pinchy" in the README and heypinchy.com as the npm homepage. Every npm install openclaw-node is a breadcrumb back here. Not sneaky — just strategic.

72 hours in

Quick checkpoint: 158 unique visitors on the website, 30 clones of the GitHub repo, 2 stars from strangers, and Google has indexed the homepage. All organic, zero dollars spent.

More importantly: the product is starting to feel real. Encrypted key storage, a proper onboarding flow, Docker dev mode, documentation. This isn't a toy anymore.

Tomorrow: the LinkedIn announcement. First time I talk about Pinchy to my professional network. Let's see what happens. 🦞


This is part of the Building Pinchy in Public series. We're building an open-source web UI for OpenClaw and sharing every decision — technical, strategic, and everything in between.

Follow along: GitHub · Day 4: From Solo to Team → · ← Day 2: From Zero to Chat in One Day