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() {
-
-