Skip to content

Commit 6de978d

Browse files
CopilotBunsDev
andauthored
Apply reviewer feedback: fix connect handshake, config error handling, Solar Witch theme, and legacy import banner gating
Agent-Logs-Url: https://github.com/OpenKnots/okcode/sessions/9615af9c-7cb2-409b-93c1-541b906a4a67 Co-authored-by: BunsDev <68980965+BunsDev@users.noreply.github.com>
1 parent 3d64ed6 commit 6de978d

4 files changed

Lines changed: 139 additions & 29 deletions

File tree

apps/server/src/openclawGatewayTest.ts

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import type {
1111
} from "@okcode/contracts";
1212
import NodeWebSocket from "ws";
1313
import { serverBuildInfo } from "./buildInfo.ts";
14+
import {
15+
generateOpenclawDeviceIdentity,
16+
signOpenclawDeviceChallenge,
17+
} from "./openclaw/deviceAuth.ts";
1418

1519
const OPENCLAW_TEST_CONNECT_TIMEOUT_MS = 10_000;
1620
const OPENCLAW_TEST_RPC_TIMEOUT_MS = 10_000;
@@ -578,6 +582,7 @@ export async function runOpenclawGatewayTest(
578582
};
579583

580584
let parsedUrlForHints: URL | null = null;
585+
const testDeviceIdentity = generateOpenclawDeviceIdentity();
581586

582587
const waitForGatewayEvent = (
583588
socket: NodeWebSocket,
@@ -783,29 +788,51 @@ export async function runOpenclawGatewayTest(
783788
}
784789
});
785790

786-
const buildConnectParams = (sharedSecret: string | undefined): Record<string, unknown> => ({
787-
minProtocol: OPENCLAW_PROTOCOL_VERSION,
788-
maxProtocol: OPENCLAW_PROTOCOL_VERSION,
789-
client: {
790-
id: "okcode",
791-
version: serverBuildInfo.version,
792-
platform:
793-
process.platform === "darwin"
794-
? "macos"
795-
: process.platform === "win32"
796-
? "windows"
797-
: process.platform,
798-
mode: "operator",
799-
},
800-
role: "operator",
801-
scopes: [...OPENCLAW_OPERATOR_SCOPES],
802-
caps: [],
803-
commands: [],
804-
permissions: {},
805-
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
806-
userAgent: `okcode/${serverBuildInfo.version}`,
807-
...(sharedSecret ? { auth: { password: sharedSecret } } : {}),
808-
});
791+
const buildConnectParams = (
792+
sharedSecret: string | undefined,
793+
challenge: Record<string, unknown> | undefined,
794+
): Record<string, unknown> => {
795+
const nonce =
796+
typeof challenge?.nonce === "string" && challenge.nonce.length > 0 ? challenge.nonce : "";
797+
const signedAt =
798+
typeof challenge?.ts === "number" && Number.isFinite(challenge.ts)
799+
? challenge.ts
800+
: Date.now();
801+
const authToken = sharedSecret ?? "";
802+
const signedDevice = signOpenclawDeviceChallenge(testDeviceIdentity, {
803+
clientId: "okcode",
804+
clientMode: "operator",
805+
role: "operator",
806+
scopes: [...OPENCLAW_OPERATOR_SCOPES],
807+
token: authToken,
808+
nonce,
809+
signedAt,
810+
});
811+
return {
812+
minProtocol: OPENCLAW_PROTOCOL_VERSION,
813+
maxProtocol: OPENCLAW_PROTOCOL_VERSION,
814+
client: {
815+
id: "okcode",
816+
version: serverBuildInfo.version,
817+
platform:
818+
process.platform === "darwin"
819+
? "macos"
820+
: process.platform === "win32"
821+
? "windows"
822+
: process.platform,
823+
mode: "operator",
824+
},
825+
role: "operator",
826+
scopes: [...OPENCLAW_OPERATOR_SCOPES],
827+
caps: [],
828+
commands: [],
829+
permissions: {},
830+
locale: Intl.DateTimeFormat().resolvedOptions().locale || "en-US",
831+
userAgent: `okcode/${serverBuildInfo.version}`,
832+
...(authToken.length > 0 ? { auth: { token: authToken } } : {}),
833+
device: signedDevice,
834+
};
835+
};
809836

810837
try {
811838
const urlStart = Date.now();
@@ -907,13 +934,13 @@ export async function runOpenclawGatewayTest(
907934

908935
const handshakeStart = Date.now();
909936
try {
910-
await waitForGatewayEvent(ws, "connect.challenge");
937+
const challenge = await waitForGatewayEvent(ws, "connect.challenge");
911938
captureEarlyGatewayEvents = false;
912939
earlyGatewayEvents.length = 0;
913940
const connectResult = await sendGatewayRequest(
914941
ws,
915942
"connect",
916-
buildConnectParams(sharedSecret),
943+
buildConnectParams(sharedSecret, challenge),
917944
);
918945
if (connectResult.error) {
919946
const detail = formatGatewayError(connectResult.error);

apps/server/src/provider/Layers/ProviderHealth.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -615,9 +615,30 @@ const checkOpenClawProviderStatus: Effect.Effect<
615615
> = Effect.gen(function* () {
616616
const checkedAt = new Date().toISOString();
617617
const gatewayConfig = yield* OpenclawGatewayConfig;
618-
const resolvedConfig = yield* gatewayConfig
619-
.resolveForConnect()
620-
.pipe(Effect.orElseSucceed(() => null));
618+
const resolvedConfigResult = yield* gatewayConfig.resolveForConnect().pipe(
619+
Effect.match({
620+
onSuccess: (resolvedConfig) => ({ ok: true as const, resolvedConfig }),
621+
onFailure: (cause) => ({ ok: false as const, cause }),
622+
}),
623+
);
624+
625+
if (!resolvedConfigResult.ok) {
626+
const reason =
627+
resolvedConfigResult.cause instanceof Error
628+
? resolvedConfigResult.cause.message
629+
: String(resolvedConfigResult.cause);
630+
631+
return {
632+
provider: OPENCLAW_PROVIDER,
633+
status: "error" as const,
634+
available: false,
635+
authStatus: "unknown" as const,
636+
checkedAt,
637+
message: `OpenClaw gateway configuration could not be read. ${reason}`,
638+
} satisfies ServerProviderStatus;
639+
}
640+
641+
const resolvedConfig = resolvedConfigResult.resolvedConfig;
621642

622643
if (!resolvedConfig) {
623644
return {

apps/web/src/routes/_chat.settings.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,9 @@ function SettingsRouteView() {
694694
(openclawGatewayDraft !== null && openclawGatewayDraft !== savedOpenclawGatewayUrl) ||
695695
openclawSharedSecretDraft.length > 0;
696696
const canImportLegacyOpenclawSettings =
697-
!savedOpenclawGatewayUrl && Boolean(settings.openclawGatewayUrl || settings.openclawPassword);
697+
openclawGatewayConfigQuery.isSuccess &&
698+
!savedOpenclawGatewayUrl &&
699+
Boolean(settings.openclawGatewayUrl || settings.openclawPassword);
698700
const changedSettingLabels = [
699701
...(theme !== "system" ? ["Theme"] : []),
700702
...(colorTheme !== DEFAULT_COLOR_THEME ? ["Color theme"] : []),

apps/web/src/themes.css

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,66 @@
6363
--warning-foreground: #f1a10d;
6464
}
6565

66+
/* ─── Solar Witch ─── mystical, radiant, high-contrast sunset magic ─── */
67+
68+
:root.theme-solar-witch {
69+
color-scheme: light;
70+
--background: #fff7ed;
71+
--foreground: #3b0764;
72+
--card: #ffedd5;
73+
--card-foreground: #3b0764;
74+
--popover: #fff7ed;
75+
--popover-foreground: #3b0764;
76+
--primary: oklch(0.68 0.23 35);
77+
--primary-foreground: #ffffff;
78+
--secondary: rgba(251, 146, 60, 0.12);
79+
--secondary-foreground: #7c2d12;
80+
--muted: rgba(245, 158, 11, 0.12);
81+
--muted-foreground: #9a3412;
82+
--accent: rgba(236, 72, 153, 0.12);
83+
--accent-foreground: #831843;
84+
--destructive: #dc2626;
85+
--destructive-foreground: #b91c1c;
86+
--border: rgba(234, 88, 12, 0.18);
87+
--input: rgba(234, 88, 12, 0.14);
88+
--ring: oklch(0.68 0.23 35);
89+
--info: #7c3aed;
90+
--info-foreground: #6d28d9;
91+
--success: #16a34a;
92+
--success-foreground: #15803d;
93+
--warning: #f59e0b;
94+
--warning-foreground: #b45309;
95+
}
96+
97+
:root.theme-solar-witch.dark {
98+
color-scheme: dark;
99+
--background: #140b1f;
100+
--foreground: #f8e8ff;
101+
--card: #1f102b;
102+
--card-foreground: #f8e8ff;
103+
--popover: #1f102b;
104+
--popover-foreground: #f8e8ff;
105+
--primary: oklch(0.74 0.21 55);
106+
--primary-foreground: #1a1022;
107+
--secondary: rgba(251, 146, 60, 0.12);
108+
--secondary-foreground: #ffd7a3;
109+
--muted: rgba(236, 72, 153, 0.1);
110+
--muted-foreground: #d8b4fe;
111+
--accent: rgba(168, 85, 247, 0.14);
112+
--accent-foreground: #f3e8ff;
113+
--destructive: #fb7185;
114+
--destructive-foreground: #fda4af;
115+
--border: rgba(251, 146, 60, 0.14);
116+
--input: rgba(251, 146, 60, 0.18);
117+
--ring: oklch(0.74 0.21 55);
118+
--info: #a78bfa;
119+
--info-foreground: #c4b5fd;
120+
--success: #4ade80;
121+
--success-foreground: #86efac;
122+
--warning: #fbbf24;
123+
--warning-foreground: #fcd34d;
124+
}
125+
66126
/* ─── Carbon ─── stark, modern, performance-focused (Vercel-inspired) ─── */
67127

68128
:root.theme-carbon {

0 commit comments

Comments
 (0)