From 057e3a494cb6ee28ef058b6fd8d1122853596d65 Mon Sep 17 00:00:00 2001 From: Volodymyr Kartavyi Date: Wed, 11 Mar 2026 21:59:02 +0100 Subject: [PATCH 01/33] fix: ensure embedded PostgreSQL databases use UTF-8 encoding On macOS, `initdb` defaults to SQL_ASCII encoding because it infers locale from the system environment. When `ensurePostgresDatabase()` creates a database without specifying encoding, the new database inherits SQL_ASCII from the cluster. This causes string functions like `left()` to operate on bytes instead of characters, producing invalid UTF-8 when multi-byte characters are truncated. Two-part fix: 1. Pass `--encoding=UTF8 --locale=C` via `initdbFlags` to all EmbeddedPostgres constructors so the cluster defaults to UTF-8. 2. Explicitly set `encoding 'UTF8'` in the CREATE DATABASE statement with `template template0` (required because template1 may already have a different encoding) and `C` locale for portability. Existing databases created with SQL_ASCII are NOT automatically fixed; users must delete their local `data/db` directory and restart to re-initialize the cluster. Relates to #636 Co-Authored-By: Claude Opus 4.6 --- cli/src/commands/worktree.ts | 1 + packages/db/src/client.ts | 2 +- packages/db/src/migration-runtime.ts | 1 + server/src/index.ts | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/src/commands/worktree.ts b/cli/src/commands/worktree.ts index 8781b008..d956f3d3 100644 --- a/cli/src/commands/worktree.ts +++ b/cli/src/commands/worktree.ts @@ -505,6 +505,7 @@ async function ensureEmbeddedPostgres(dataDir: string, preferredPort: number): P password: "paperclip", port, persistent: true, + initdbFlags: ["--encoding=UTF8", "--locale=C"], onLog: () => {}, onError: () => {}, }); diff --git a/packages/db/src/client.ts b/packages/db/src/client.ts index c4275dc4..83b4aa78 100644 --- a/packages/db/src/client.ts +++ b/packages/db/src/client.ts @@ -730,7 +730,7 @@ export async function ensurePostgresDatabase( `; if (existing.length > 0) return "exists"; - await sql.unsafe(`create database "${databaseName}"`); + await sql.unsafe(`create database "${databaseName}" encoding 'UTF8' lc_collate 'C' lc_ctype 'C' template template0`); return "created"; } finally { await sql.end(); diff --git a/packages/db/src/migration-runtime.ts b/packages/db/src/migration-runtime.ts index bc90b762..10b7b9b1 100644 --- a/packages/db/src/migration-runtime.ts +++ b/packages/db/src/migration-runtime.ts @@ -96,6 +96,7 @@ async function ensureEmbeddedPostgresConnection( password: "paperclip", port: preferredPort, persistent: true, + initdbFlags: ["--encoding=UTF8", "--locale=C"], onLog: () => {}, onError: () => {}, }); diff --git a/server/src/index.ts b/server/src/index.ts index c220df92..50c6a7b2 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -334,6 +334,7 @@ export async function startServer(): Promise { password: "paperclip", port, persistent: true, + initdbFlags: ["--encoding=UTF8", "--locale=C"], onLog: appendEmbeddedPostgresLog, onError: appendEmbeddedPostgresLog, }); From b7744a221575a8eb1174a459f0496897c4b3ec13 Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 11 Mar 2026 11:40:38 -0500 Subject: [PATCH 02/33] Add direct onboarding routes Co-Authored-By: Paperclip --- ui/src/App.tsx | 55 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/ui/src/App.tsx b/ui/src/App.tsx index ed6c9c51..1cfdd9df 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef } from "react"; -import { Navigate, Outlet, Route, Routes, useLocation } from "@/lib/router"; +import { Navigate, Outlet, Route, Routes, useLocation, useParams } from "@/lib/router"; import { useQuery } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { Layout } from "./components/Layout"; @@ -108,6 +108,7 @@ function boardRoutes() { <> } /> } /> + } /> } /> } /> } /> @@ -164,6 +165,57 @@ function LegacySettingsRedirect() { return ; } +function OnboardingRoutePage() { + const { companies, loading } = useCompany(); + const { onboardingOpen, openOnboarding } = useDialog(); + const { companyPrefix } = useParams<{ companyPrefix?: string }>(); + const opened = useRef(false); + const matchedCompany = companyPrefix + ? companies.find((company) => company.issuePrefix.toUpperCase() === companyPrefix.toUpperCase()) ?? null + : null; + + useEffect(() => { + if (loading || opened.current || onboardingOpen) return; + opened.current = true; + if (matchedCompany) { + openOnboarding({ initialStep: 2, companyId: matchedCompany.id }); + return; + } + openOnboarding(); + }, [companyPrefix, loading, matchedCompany, onboardingOpen, openOnboarding]); + + const title = matchedCompany + ? `Add another agent to ${matchedCompany.name}` + : companies.length > 0 + ? "Create another company" + : "Create your first company"; + const description = matchedCompany + ? "Run onboarding again to add an agent and a starter task for this company." + : companies.length > 0 + ? "Run onboarding again to create another company and seed its first agent." + : "Get started by creating a company and your first agent."; + + return ( +
+
+

{title}

+

{description}

+
+ +
+
+
+ ); +} + function CompanyRootRedirect() { const { companies, selectedCompany, loading } = useCompany(); const { onboardingOpen } = useDialog(); @@ -242,6 +294,7 @@ export function App() { }> } /> + } /> } /> }> } /> From d4d1b2e7f924c60d999719846b807aa38408ee27 Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 11 Mar 2026 12:02:27 -0500 Subject: [PATCH 03/33] Style tweaks for onboarding wizard step 1 - Set animation panel (right half) background to #1d1d1d - Add more margin above Company name form label - Make form labels white when input is focused or has value using Tailwind group/focus-within pattern Co-Authored-By: Paperclip Co-Authored-By: Claude Opus 4.6 --- ui/src/components/OnboardingWizard.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/src/components/OnboardingWizard.tsx b/ui/src/components/OnboardingWizard.tsx index a043655f..31373344 100644 --- a/ui/src/components/OnboardingWizard.tsx +++ b/ui/src/components/OnboardingWizard.tsx @@ -593,8 +593,8 @@ export function OnboardingWizard() {

-
-