diff --git a/BRANDING.md b/BRANDING.md
index 1a3fcd3f0..574381d65 100644
--- a/BRANDING.md
+++ b/BRANDING.md
@@ -13,10 +13,10 @@
| **Stage Label** | Dev (development only) |
| **Display Name** | OK Code |
| **Version** | 0.0.1 |
-| **Tagline** | `[TBD]` |
-| **One-liner Description** | `[TBD]` |
+| **Tagline** | A Minimal Web GUI for Coding Agents |
+| **One-liner Description** | Chat with Codex and Claude in a modern web UI. Git worktree isolation, diff review, integrated terminal, and more. |
| **Parent Organization** | OpenKnots |
-| **Website URL** | `[TBD]` |
+| **Website URL** | `[TBD]` |
| **Repository** | `OpenKnots/okcode` |
### Brand Voice & Tone
@@ -27,8 +27,8 @@
| **Tone** | Confident but not arrogant; technical but accessible |
| **Copy Style** | Action-oriented imperatives ("New Thread", "Terminal", "Settings"); no unnecessary filler words |
| **Audience** | Software engineers and technical users |
-| **Emoji Usage** | `[TBD — currently none in the UI]` |
-| **Error/Empty States Voice** | `[TBD]` |
+| **Emoji Usage** | None in UI copy; reserved for user-generated content only |
+| **Error/Empty States Voice** | Concise and helpful; state what happened and what to do next, no blame or humor |
---
@@ -256,7 +256,7 @@ A subtle **fractal noise SVG overlay** is applied to `body::after` at **3.5% opa
| Disabled opacity | `opacity-64` |
| Disabled interaction | `pointer-events: none` |
| Placeholder text | `muted-foreground/72` (72% opacity) |
-| Contrast standard | `[TBD — WCAG level target]` |
+| Contrast standard | WCAG 2.1 AA minimum |
---
@@ -321,7 +321,7 @@ The app includes bespoke SVG icons for:
| Property | Value |
| -------------------------------- | ------- |
-| `prefers-reduced-motion` support | `[TBD]` |
+| `prefers-reduced-motion` support | Respect; disable non-essential animations when set |
| Global animation toggle | `[TBD]` |
---
@@ -385,19 +385,19 @@ Built with:
The following need to be provided/decided:
-- [ ] **Tagline** — short memorable phrase
-- [ ] **One-liner description** — for app stores, meta tags, social cards
+- [x] **Tagline** — "A Minimal Web GUI for Coding Agents"
+- [x] **One-liner description** — see Brand Identity table above
+- [x] **WCAG contrast target** — AA minimum
+- [x] **Reduced motion support** — respect `prefers-reduced-motion`
+- [x] **Emoji policy** — none in UI copy
+- [x] **Error/empty state voice** — concise and helpful
- [ ] **Logo mark description** — what does the mark depict?
- [ ] **Logo usage guidelines** — minimum size, clear space, do's and don'ts
- [ ] **Heading type scale** — H1–H6 sizes and weights
-- [ ] **WCAG contrast target** — AA or AAA?
-- [ ] **Reduced motion support** — respect `prefers-reduced-motion`?
- [ ] **Website URL**
- [ ] **Social media handles / links**
- [ ] **App store descriptions**
- [ ] **Open Graph / social card image**
- [ ] **Brand color as hex** — the primary `oklch(0.488 0.217 264)` converts to approximately **#2b4acb** (a deep blue-violet); confirm this is the intended brand hex
- [ ] **Secondary brand color** — is there a distinct secondary brand color beyond the neutral system?
-- [ ] **Emoji policy** — use in UI copy, notifications, etc.?
-- [ ] **Error/empty state voice** — tone for error messages, empty states, onboarding
- [ ] **Icon stroke width** — confirm Lucide default (2) or custom
diff --git a/LICENSE b/LICENSE
index e3266a808..c11b137eb 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2026 OpenKnot
+Copyright (c) 2026 OpenKnots
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/apps/desktop/scripts/electron-launcher.mjs b/apps/desktop/scripts/electron-launcher.mjs
index 5e48b2866..9cd91ddd5 100644
--- a/apps/desktop/scripts/electron-launcher.mjs
+++ b/apps/desktop/scripts/electron-launcher.mjs
@@ -17,8 +17,10 @@ import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);
-const APP_DISPLAY_NAME = isDevelopment ? "OK Code (Dev)" : "OK Code";
-const APP_BUNDLE_ID = "com.okcode.okcode";
+// Keep in sync with APP_BASE_NAME from @okcode/shared/brand
+const APP_BASE_NAME = "OK Code";
+const APP_DISPLAY_NAME = isDevelopment ? `${APP_BASE_NAME} (Dev)` : APP_BASE_NAME;
+const APP_BUNDLE_ID = "com.openknots.okcode";
const LAUNCHER_VERSION = 1;
const __dirname = dirname(fileURLToPath(import.meta.url));
diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts
index 86d96efaa..18dfbeaa3 100644
--- a/apps/desktop/src/main.ts
+++ b/apps/desktop/src/main.ts
@@ -26,6 +26,7 @@ import type {
PreviewTabsState,
} from "@okcode/contracts";
import { autoUpdater } from "electron-updater";
+import { APP_BASE_NAME } from "@okcode/shared/brand";
import type { ContextMenuItem } from "@okcode/contracts";
import { NetService } from "@okcode/shared/Net";
@@ -79,8 +80,8 @@ const STATE_DIR = Path.join(BASE_DIR, "userdata");
const DESKTOP_SCHEME = "okcode";
const ROOT_DIR = Path.resolve(__dirname, "../../..");
const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);
-const APP_DISPLAY_NAME = isDevelopment ? "OK Code (Dev)" : "OK Code";
-const APP_USER_MODEL_ID = "com.okcode.okcode";
+const APP_DISPLAY_NAME = isDevelopment ? `${APP_BASE_NAME} (Dev)` : APP_BASE_NAME;
+const APP_USER_MODEL_ID = "com.openknots.okcode";
const USER_DATA_DIR_NAME = isDevelopment ? "okcode-dev" : "okcode";
const LEGACY_USER_DATA_DIR_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)";
const COMMIT_HASH_PATTERN = /^[0-9a-f]{7,40}$/i;
diff --git a/apps/marketing/components/workflows-section.tsx b/apps/marketing/components/workflows-section.tsx
index 1f29cbafc..d3d7dc11d 100644
--- a/apps/marketing/components/workflows-section.tsx
+++ b/apps/marketing/components/workflows-section.tsx
@@ -203,7 +203,7 @@ function ApiMockup() {
return (
- OK CODE API
+ OK Code API
);
diff --git a/apps/server/src/checkpointing/Layers/CheckpointStore.ts b/apps/server/src/checkpointing/Layers/CheckpointStore.ts
index 103043b88..7e32ba411 100644
--- a/apps/server/src/checkpointing/Layers/CheckpointStore.ts
+++ b/apps/server/src/checkpointing/Layers/CheckpointStore.ts
@@ -18,6 +18,7 @@ import { GitCommandError } from "../../git/Errors.ts";
import { GitCore } from "../../git/Services/GitCore.ts";
import { CheckpointStore, type CheckpointStoreShape } from "../Services/CheckpointStore.ts";
import { CheckpointRef } from "@okcode/contracts";
+import { GIT_IDENTITY_NAME } from "@okcode/shared/brand";
const makeCheckpointStore = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;
@@ -98,9 +99,9 @@ const makeCheckpointStore = Effect.gen(function* () {
const commitEnv: NodeJS.ProcessEnv = {
...process.env,
GIT_INDEX_FILE: tempIndexPath,
- GIT_AUTHOR_NAME: "OK Code",
+ GIT_AUTHOR_NAME: GIT_IDENTITY_NAME,
GIT_AUTHOR_EMAIL: "okcode@users.noreply.github.com",
- GIT_COMMITTER_NAME: "OK Code",
+ GIT_COMMITTER_NAME: GIT_IDENTITY_NAME,
GIT_COMMITTER_EMAIL: "okcode@users.noreply.github.com",
};
diff --git a/apps/server/src/provider/codexCliVersion.ts b/apps/server/src/provider/codexCliVersion.ts
index a24d66d54..893ba95b6 100644
--- a/apps/server/src/provider/codexCliVersion.ts
+++ b/apps/server/src/provider/codexCliVersion.ts
@@ -1,3 +1,5 @@
+import { APP_BASE_NAME } from "@okcode/shared/brand";
+
const CODEX_VERSION_PATTERN = /\bv?(\d+\.\d+(?:\.\d+)?(?:-[0-9A-Za-z.-]+)?)\b/;
export const MINIMUM_CODEX_CLI_VERSION = "0.37.0";
@@ -137,5 +139,5 @@ export function isCodexCliVersionSupported(version: string): boolean {
export function formatCodexCliUpgradeMessage(version: string | null): string {
const versionLabel = version ? `v${version}` : "the installed version";
- return `Codex CLI ${versionLabel} is too old for OK Code. Upgrade to v${MINIMUM_CODEX_CLI_VERSION} or newer and restart OK Code.`;
+ return `Codex CLI ${versionLabel} is too old for ${APP_BASE_NAME}. Upgrade to v${MINIMUM_CODEX_CLI_VERSION} or newer and restart ${APP_BASE_NAME}.`;
}
diff --git a/apps/web/src/branding.ts b/apps/web/src/branding.ts
index 28d72b856..66526c890 100644
--- a/apps/web/src/branding.ts
+++ b/apps/web/src/branding.ts
@@ -1,4 +1,5 @@
-export const APP_BASE_NAME = "OK Code";
+export { APP_BASE_NAME } from "@okcode/shared/brand";
+
export const APP_STAGE_LABEL = import.meta.env.DEV ? "Dev" : "";
export const APP_DISPLAY_NAME = APP_STAGE_LABEL
? `${APP_BASE_NAME} (${APP_STAGE_LABEL})`
diff --git a/apps/web/src/components/ChatHomeEmptyState.tsx b/apps/web/src/components/ChatHomeEmptyState.tsx
index a0fd6bc25..61a8c385e 100644
--- a/apps/web/src/components/ChatHomeEmptyState.tsx
+++ b/apps/web/src/components/ChatHomeEmptyState.tsx
@@ -15,7 +15,7 @@ import {
import { useCallback, useMemo, useState } from "react";
import { useAppSettings } from "../appSettings";
-import { APP_DISPLAY_NAME } from "../branding";
+import { APP_BASE_NAME, APP_DISPLAY_NAME } from "../branding";
import { isElectron } from "../env";
import { useHandleNewThread } from "../hooks/useHandleNewThread";
import { serverConfigQueryOptions } from "../lib/serverReactQuery";
@@ -363,7 +363,7 @@ export function ChatHomeEmptyState() {
Launch a premium coding workspace with reliable agent sessions built in.
- OK Code keeps threads tied to real repositories, preserves provider state,
+ {APP_BASE_NAME} keeps threads tied to real repositories, preserves provider state,
and gives your desktop a calmer control surface for deep, multi-session
work.
diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx
index 272a65aab..b159ac84d 100644
--- a/apps/web/src/components/Sidebar.tsx
+++ b/apps/web/src/components/Sidebar.tsx
@@ -50,7 +50,7 @@ import {
useAppSettings,
} from "../appSettings";
import { isElectron } from "../env";
-import { APP_VERSION } from "../branding";
+import { APP_BASE_NAME, APP_VERSION } from "../branding";
import { cn, isLinuxPlatform, isMacPlatform, newCommandId, newProjectId } from "../lib/utils";
import { useStore } from "../store";
import { shortcutLabelForCommand } from "../keybindings";
@@ -1805,8 +1805,8 @@ export default function Sidebar() {
render={
-
- OK Code
+
+ {APP_BASE_NAME}
}
@@ -1860,7 +1860,7 @@ export default function Sidebar() {
onClick={() => {
toastManager.add({
type: "info",
- title: `OK Code ${serverUpdateInfo.latestVersion} available`,
+ title: `${APP_BASE_NAME} ${serverUpdateInfo.latestVersion} available`,
description: `Update with: npm install -g okcodes@latest`,
});
}}
diff --git a/packages/shared/package.json b/packages/shared/package.json
index 2f0b4010f..01f71adca 100644
--- a/packages/shared/package.json
+++ b/packages/shared/package.json
@@ -47,6 +47,10 @@
"./skillCatalog": {
"types": "./src/skillCatalog.ts",
"import": "./src/skillCatalog.ts"
+ },
+ "./brand": {
+ "types": "./src/brand.ts",
+ "import": "./src/brand.ts"
}
},
"scripts": {
diff --git a/packages/shared/src/brand.ts b/packages/shared/src/brand.ts
new file mode 100644
index 000000000..bb9590c0d
--- /dev/null
+++ b/packages/shared/src/brand.ts
@@ -0,0 +1,13 @@
+/**
+ * Canonical brand constants for the OK Code product.
+ *
+ * Import from `@okcode/shared/brand` in any workspace package.
+ * The web app's `branding.ts` re-exports these with Vite-specific additions
+ * (stage labels, build-time version injection).
+ */
+
+/** Base product name — use for display text that should not include a stage label. */
+export const APP_BASE_NAME = "OK Code";
+
+/** Git committer identity used by OK Code's internal operations (checkpoints, etc.). */
+export const GIT_IDENTITY_NAME = APP_BASE_NAME;
diff --git a/scripts/build-desktop-artifact.ts b/scripts/build-desktop-artifact.ts
index 6c6dad829..33e5519f1 100644
--- a/scripts/build-desktop-artifact.ts
+++ b/scripts/build-desktop-artifact.ts
@@ -8,6 +8,7 @@ import rootPackageJson from "../package.json" with { type: "json" };
import desktopPackageJson from "../apps/desktop/package.json" with { type: "json" };
import serverPackageJson from "../apps/server/package.json" with { type: "json" };
+import { APP_BASE_NAME } from "@okcode/shared/brand";
import { BRAND_ASSET_PATHS } from "./lib/brand-assets.ts";
import { resolveCatalogDependencies } from "./lib/resolve-catalog.ts";
@@ -519,7 +520,7 @@ const createBuildConfig = Effect.fn("createBuildConfig")(function* (
macEntitlementsPlistAbsolutePath: string | undefined,
) {
const buildConfig: Record = {
- appId: "com.okcode.okcode",
+ appId: "com.openknots.okcode",
productName,
artifactName: "OK-Code-${version}-${arch}.${ext}",
directories: {
@@ -736,7 +737,7 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* (
build: yield* createBuildConfig(
options.platform,
options.target,
- desktopPackageJson.productName ?? "OK Code",
+ desktopPackageJson.productName ?? APP_BASE_NAME,
options.signed,
options.signed && options.platform === "mac" ? macEntitlementsPlistAbsolutePath : undefined,
),
diff --git a/scripts/generate-brand-assets.py b/scripts/generate-brand-assets.py
index de1d46597..ed9b84f01 100644
--- a/scripts/generate-brand-assets.py
+++ b/scripts/generate-brand-assets.py
@@ -1,8 +1,7 @@
#!/usr/bin/env python3
"""Regenerate favicons and desktop icon PNGs/ICOs from assets/source/okcode-mark-512.png.
-Windows `.ico` files use `assets/source/openknot-mark-512.png` when present (OpenKnots org
-mark); otherwise they fall back to the OK Code mark.
+All platforms (macOS, Windows, Linux, iOS, web) use the same OK Code mark as their source.
Requires Pillow (`python3 -m pip install pillow` if missing).
Run from repository root: python3 scripts/generate-brand-assets.py
@@ -22,7 +21,6 @@
ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / "assets/source/okcode-mark-512.png"
-OPENKNOT_MARK_SRC = ROOT / "assets/source/openknot-mark-512.png"
ICO_SIZES_WEB = (16, 32, 48)
ICO_SIZES_DESKTOP = (16, 32, 48, 64, 128, 256)
@@ -99,11 +97,6 @@ def main() -> None:
img = Image.open(SRC).convert("RGBA")
- if OPENKNOT_MARK_SRC.exists():
- windows_icon_source = Image.open(OPENKNOT_MARK_SRC).convert("RGBA")
- else:
- windows_icon_source = img
-
# Master 1024 for desktop / marketing hero
mark_1024 = resize(img, 1024)
prod_dir = ROOT / "assets/prod"
@@ -133,8 +126,8 @@ def main() -> None:
save_ico(prod_dir / "okcode-web-favicon.ico", img, ICO_SIZES_WEB)
save_ico(dev_dir / "okcode-dev-web-favicon.ico", img, ICO_SIZES_WEB)
- save_ico(prod_dir / "okcode-windows.ico", windows_icon_source, ICO_SIZES_DESKTOP)
- save_ico(dev_dir / "okcode-dev-windows.ico", windows_icon_source, ICO_SIZES_DESKTOP)
+ save_ico(prod_dir / "okcode-windows.ico", img, ICO_SIZES_DESKTOP)
+ save_ico(dev_dir / "okcode-dev-windows.ico", img, ICO_SIZES_DESKTOP)
# Marketing site: large nav icon + same favicons as prod web
mkt = ROOT / "apps/marketing/public"