mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-03 03:03:24 -04:00
refactor: rename to openclaw
This commit is contained in:
@@ -3,12 +3,12 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Moltbot Control</title>
|
||||
<title>OpenClaw Control</title>
|
||||
<meta name="color-scheme" content="dark light" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
</head>
|
||||
<body>
|
||||
<moltbot-app></moltbot-app>
|
||||
<openclaw-app></openclaw-app>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "moltbot-control-ui",
|
||||
"name": "openclaw-control-ui",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -239,7 +239,7 @@ html.theme-transition::view-transition-new(theme) {
|
||||
}
|
||||
}
|
||||
|
||||
moltbot-app {
|
||||
openclaw-app {
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
@@ -5,32 +5,32 @@ import {
|
||||
waitWhatsAppLogin,
|
||||
} from "./controllers/channels";
|
||||
import { loadConfig, saveConfig } from "./controllers/config";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { OpenClawApp } from "./app";
|
||||
import type { NostrProfile } from "./types";
|
||||
import { createNostrProfileFormState } from "./views/channels.nostr-profile-form";
|
||||
|
||||
export async function handleWhatsAppStart(host: MoltbotApp, force: boolean) {
|
||||
export async function handleWhatsAppStart(host: OpenClawApp, force: boolean) {
|
||||
await startWhatsAppLogin(host, force);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleWhatsAppWait(host: MoltbotApp) {
|
||||
export async function handleWhatsAppWait(host: OpenClawApp) {
|
||||
await waitWhatsAppLogin(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleWhatsAppLogout(host: MoltbotApp) {
|
||||
export async function handleWhatsAppLogout(host: OpenClawApp) {
|
||||
await logoutWhatsApp(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleChannelConfigSave(host: MoltbotApp) {
|
||||
export async function handleChannelConfigSave(host: OpenClawApp) {
|
||||
await saveConfig(host);
|
||||
await loadConfig(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleChannelConfigReload(host: MoltbotApp) {
|
||||
export async function handleChannelConfigReload(host: OpenClawApp) {
|
||||
await loadConfig(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ function parseValidationErrors(details: unknown): Record<string, string> {
|
||||
return errors;
|
||||
}
|
||||
|
||||
function resolveNostrAccountId(host: MoltbotApp): string {
|
||||
function resolveNostrAccountId(host: OpenClawApp): string {
|
||||
const accounts = host.channelsSnapshot?.channelAccounts?.nostr ?? [];
|
||||
return accounts[0]?.accountId ?? host.nostrProfileAccountId ?? "default";
|
||||
}
|
||||
@@ -59,7 +59,7 @@ function buildNostrProfileUrl(accountId: string, suffix = ""): string {
|
||||
}
|
||||
|
||||
export function handleNostrProfileEdit(
|
||||
host: MoltbotApp,
|
||||
host: OpenClawApp,
|
||||
accountId: string,
|
||||
profile: NostrProfile | null,
|
||||
) {
|
||||
@@ -67,13 +67,13 @@ export function handleNostrProfileEdit(
|
||||
host.nostrProfileFormState = createNostrProfileFormState(profile ?? undefined);
|
||||
}
|
||||
|
||||
export function handleNostrProfileCancel(host: MoltbotApp) {
|
||||
export function handleNostrProfileCancel(host: OpenClawApp) {
|
||||
host.nostrProfileFormState = null;
|
||||
host.nostrProfileAccountId = null;
|
||||
}
|
||||
|
||||
export function handleNostrProfileFieldChange(
|
||||
host: MoltbotApp,
|
||||
host: OpenClawApp,
|
||||
field: keyof NostrProfile,
|
||||
value: string,
|
||||
) {
|
||||
@@ -92,7 +92,7 @@ export function handleNostrProfileFieldChange(
|
||||
};
|
||||
}
|
||||
|
||||
export function handleNostrProfileToggleAdvanced(host: MoltbotApp) {
|
||||
export function handleNostrProfileToggleAdvanced(host: OpenClawApp) {
|
||||
const state = host.nostrProfileFormState;
|
||||
if (!state) return;
|
||||
host.nostrProfileFormState = {
|
||||
@@ -101,7 +101,7 @@ export function handleNostrProfileToggleAdvanced(host: MoltbotApp) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function handleNostrProfileSave(host: MoltbotApp) {
|
||||
export async function handleNostrProfileSave(host: OpenClawApp) {
|
||||
const state = host.nostrProfileFormState;
|
||||
if (!state || state.saving) return;
|
||||
const accountId = resolveNostrAccountId(host);
|
||||
@@ -167,7 +167,7 @@ export async function handleNostrProfileSave(host: MoltbotApp) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleNostrProfileImport(host: MoltbotApp) {
|
||||
export async function handleNostrProfileImport(host: OpenClawApp) {
|
||||
const state = host.nostrProfileFormState;
|
||||
if (!state || state.importing) return;
|
||||
const accountId = resolveNostrAccountId(host);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { setLastActiveSessionKey } from "./app-settings";
|
||||
import { normalizeBasePath } from "./navigation";
|
||||
import type { GatewayHelloOk } from "./gateway";
|
||||
import { parseAgentSessionKey } from "../../../src/sessions/session-key-utils.js";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { OpenClawApp } from "./app";
|
||||
import type { ChatAttachment, ChatQueueItem } from "./ui-types";
|
||||
|
||||
type ChatHost = {
|
||||
@@ -53,7 +53,7 @@ function isChatResetCommand(text: string) {
|
||||
export async function handleAbortChat(host: ChatHost) {
|
||||
if (!host.connected) return;
|
||||
host.chatMessage = "";
|
||||
await abortChatRun(host as unknown as MoltbotApp);
|
||||
await abortChatRun(host as unknown as OpenClawApp);
|
||||
}
|
||||
|
||||
function enqueueChatMessage(host: ChatHost, text: string, attachments?: ChatAttachment[]) {
|
||||
@@ -84,7 +84,7 @@ async function sendChatMessageNow(
|
||||
},
|
||||
) {
|
||||
resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
|
||||
const ok = await sendChatMessage(host as unknown as MoltbotApp, message, opts?.attachments);
|
||||
const ok = await sendChatMessage(host as unknown as OpenClawApp, message, opts?.attachments);
|
||||
if (!ok && opts?.previousDraft != null) {
|
||||
host.chatMessage = opts.previousDraft;
|
||||
}
|
||||
@@ -169,8 +169,8 @@ export async function handleSendChat(
|
||||
|
||||
export async function refreshChat(host: ChatHost) {
|
||||
await Promise.all([
|
||||
loadChatHistory(host as unknown as MoltbotApp),
|
||||
loadSessions(host as unknown as MoltbotApp, { activeMinutes: 0 }),
|
||||
loadChatHistory(host as unknown as OpenClawApp),
|
||||
loadSessions(host as unknown as OpenClawApp, { activeMinutes: 0 }),
|
||||
refreshChatAvatar(host),
|
||||
]);
|
||||
scheduleChatScroll(host as unknown as Parameters<typeof scheduleChatScroll>[0], true);
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
parseExecApprovalResolved,
|
||||
removeExecApproval,
|
||||
} from "./controllers/exec-approval";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { OpenClawApp } from "./app";
|
||||
import type { ExecApprovalRequest } from "./controllers/exec-approval";
|
||||
import { loadAssistantIdentity } from "./controllers/assistant-identity";
|
||||
import { loadSessions } from "./controllers/sessions";
|
||||
@@ -122,7 +122,7 @@ export function connectGateway(host: GatewayHost) {
|
||||
url: host.settings.gatewayUrl,
|
||||
token: host.settings.token.trim() ? host.settings.token : undefined,
|
||||
password: host.password.trim() ? host.password : undefined,
|
||||
clientName: "moltbot-control-ui",
|
||||
clientName: "openclaw-control-ui",
|
||||
mode: "webchat",
|
||||
onHello: (hello) => {
|
||||
host.connected = true;
|
||||
@@ -135,10 +135,10 @@ export function connectGateway(host: GatewayHost) {
|
||||
(host as unknown as { chatStream: string | null }).chatStream = null;
|
||||
(host as unknown as { chatStreamStartedAt: number | null }).chatStreamStartedAt = null;
|
||||
resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
|
||||
void loadAssistantIdentity(host as unknown as MoltbotApp);
|
||||
void loadAgents(host as unknown as MoltbotApp);
|
||||
void loadNodes(host as unknown as MoltbotApp, { quiet: true });
|
||||
void loadDevices(host as unknown as MoltbotApp, { quiet: true });
|
||||
void loadAssistantIdentity(host as unknown as OpenClawApp);
|
||||
void loadAgents(host as unknown as OpenClawApp);
|
||||
void loadNodes(host as unknown as OpenClawApp, { quiet: true });
|
||||
void loadDevices(host as unknown as OpenClawApp, { quiet: true });
|
||||
void refreshActiveTab(host as unknown as Parameters<typeof refreshActiveTab>[0]);
|
||||
},
|
||||
onClose: ({ code, reason }) => {
|
||||
@@ -190,7 +190,7 @@ function handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {
|
||||
payload.sessionKey,
|
||||
);
|
||||
}
|
||||
const state = handleChatEvent(host as unknown as MoltbotApp, payload);
|
||||
const state = handleChatEvent(host as unknown as OpenClawApp, payload);
|
||||
if (state === "final" || state === "error" || state === "aborted") {
|
||||
resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
|
||||
void flushChatQueueForEvent(
|
||||
@@ -199,11 +199,11 @@ function handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {
|
||||
if (host.refreshSessionsAfterChat) {
|
||||
host.refreshSessionsAfterChat = false;
|
||||
if (state === "final") {
|
||||
void loadSessions(host as unknown as MoltbotApp, { activeMinutes: 0 });
|
||||
void loadSessions(host as unknown as OpenClawApp, { activeMinutes: 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state === "final") void loadChatHistory(host as unknown as MoltbotApp);
|
||||
if (state === "final") void loadChatHistory(host as unknown as OpenClawApp);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ function handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {
|
||||
}
|
||||
|
||||
if (evt.event === "device.pair.requested" || evt.event === "device.pair.resolved") {
|
||||
void loadDevices(host as unknown as MoltbotApp, { quiet: true });
|
||||
void loadDevices(host as unknown as OpenClawApp, { quiet: true });
|
||||
}
|
||||
|
||||
if (evt.event === "exec.approval.requested") {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { loadLogs } from "./controllers/logs";
|
||||
import { loadNodes } from "./controllers/nodes";
|
||||
import { loadDebug } from "./controllers/debug";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { OpenClawApp } from "./app";
|
||||
|
||||
type PollingHost = {
|
||||
nodesPollInterval: number | null;
|
||||
@@ -13,7 +13,7 @@ type PollingHost = {
|
||||
export function startNodesPolling(host: PollingHost) {
|
||||
if (host.nodesPollInterval != null) return;
|
||||
host.nodesPollInterval = window.setInterval(
|
||||
() => void loadNodes(host as unknown as MoltbotApp, { quiet: true }),
|
||||
() => void loadNodes(host as unknown as OpenClawApp, { quiet: true }),
|
||||
5000,
|
||||
);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export function startLogsPolling(host: PollingHost) {
|
||||
if (host.logsPollInterval != null) return;
|
||||
host.logsPollInterval = window.setInterval(() => {
|
||||
if (host.tab !== "logs") return;
|
||||
void loadLogs(host as unknown as MoltbotApp, { quiet: true });
|
||||
void loadLogs(host as unknown as OpenClawApp, { quiet: true });
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ export function startDebugPolling(host: PollingHost) {
|
||||
if (host.debugPollInterval != null) return;
|
||||
host.debugPollInterval = window.setInterval(() => {
|
||||
if (host.tab !== "debug") return;
|
||||
void loadDebug(host as unknown as MoltbotApp);
|
||||
void loadDebug(host as unknown as OpenClawApp);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,10 +130,10 @@ export function renderApp(state: AppViewState) {
|
||||
</button>
|
||||
<div class="brand">
|
||||
<div class="brand-logo">
|
||||
<img src="https://mintcdn.com/clawdhub/4rYvG-uuZrMK_URE/assets/pixel-lobster.svg?fit=max&auto=format&n=4rYvG-uuZrMK_URE&q=85&s=da2032e9eac3b5d9bfe7eb96ca6a8a26" alt="Moltbot" />
|
||||
<img src="https://mintcdn.com/clawdhub/4rYvG-uuZrMK_URE/assets/pixel-lobster.svg?fit=max&auto=format&n=4rYvG-uuZrMK_URE&q=85&s=da2032e9eac3b5d9bfe7eb96ca6a8a26" alt="OpenClaw" />
|
||||
</div>
|
||||
<div class="brand-text">
|
||||
<div class="brand-title">MOLTBOT</div>
|
||||
<div class="brand-title">OPENCLAW</div>
|
||||
<div class="brand-sub">Gateway Dashboard</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -181,7 +181,7 @@ export function renderApp(state: AppViewState) {
|
||||
<div class="nav-group__items">
|
||||
<a
|
||||
class="nav-item nav-item--external"
|
||||
href="https://docs.molt.bot"
|
||||
href="https://docs.openclaw.ai"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title="Docs (opens in new tab)"
|
||||
|
||||
@@ -103,7 +103,7 @@ export function exportLogs(lines: string[], label: string) {
|
||||
const anchor = document.createElement("a");
|
||||
const stamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, "-");
|
||||
anchor.href = url;
|
||||
anchor.download = `moltbot-logs-${label}-${stamp}.log`;
|
||||
anchor.download = `openclaw-logs-${label}-${stamp}.log`;
|
||||
anchor.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { startThemeTransition, type ThemeTransitionContext } from "./theme-trans
|
||||
import { scheduleChatScroll, scheduleLogsScroll } from "./app-scroll";
|
||||
import { startLogsPolling, stopLogsPolling, startDebugPolling, stopDebugPolling } from "./app-polling";
|
||||
import { refreshChat } from "./app-chat";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { OpenClawApp } from "./app";
|
||||
|
||||
type SettingsHost = {
|
||||
settings: UiSettings;
|
||||
@@ -145,15 +145,15 @@ export function setTheme(
|
||||
export async function refreshActiveTab(host: SettingsHost) {
|
||||
if (host.tab === "overview") await loadOverview(host);
|
||||
if (host.tab === "channels") await loadChannelsTab(host);
|
||||
if (host.tab === "instances") await loadPresence(host as unknown as MoltbotApp);
|
||||
if (host.tab === "sessions") await loadSessions(host as unknown as MoltbotApp);
|
||||
if (host.tab === "instances") await loadPresence(host as unknown as OpenClawApp);
|
||||
if (host.tab === "sessions") await loadSessions(host as unknown as OpenClawApp);
|
||||
if (host.tab === "cron") await loadCron(host);
|
||||
if (host.tab === "skills") await loadSkills(host as unknown as MoltbotApp);
|
||||
if (host.tab === "skills") await loadSkills(host as unknown as OpenClawApp);
|
||||
if (host.tab === "nodes") {
|
||||
await loadNodes(host as unknown as MoltbotApp);
|
||||
await loadDevices(host as unknown as MoltbotApp);
|
||||
await loadConfig(host as unknown as MoltbotApp);
|
||||
await loadExecApprovals(host as unknown as MoltbotApp);
|
||||
await loadNodes(host as unknown as OpenClawApp);
|
||||
await loadDevices(host as unknown as OpenClawApp);
|
||||
await loadConfig(host as unknown as OpenClawApp);
|
||||
await loadExecApprovals(host as unknown as OpenClawApp);
|
||||
}
|
||||
if (host.tab === "chat") {
|
||||
await refreshChat(host as unknown as Parameters<typeof refreshChat>[0]);
|
||||
@@ -163,16 +163,16 @@ export async function refreshActiveTab(host: SettingsHost) {
|
||||
);
|
||||
}
|
||||
if (host.tab === "config") {
|
||||
await loadConfigSchema(host as unknown as MoltbotApp);
|
||||
await loadConfig(host as unknown as MoltbotApp);
|
||||
await loadConfigSchema(host as unknown as OpenClawApp);
|
||||
await loadConfig(host as unknown as OpenClawApp);
|
||||
}
|
||||
if (host.tab === "debug") {
|
||||
await loadDebug(host as unknown as MoltbotApp);
|
||||
await loadDebug(host as unknown as OpenClawApp);
|
||||
host.eventLog = host.eventLogBuffer;
|
||||
}
|
||||
if (host.tab === "logs") {
|
||||
host.logsAtBottom = true;
|
||||
await loadLogs(host as unknown as MoltbotApp, { reset: true });
|
||||
await loadLogs(host as unknown as OpenClawApp, { reset: true });
|
||||
scheduleLogsScroll(
|
||||
host as unknown as Parameters<typeof scheduleLogsScroll>[0],
|
||||
true,
|
||||
@@ -182,7 +182,7 @@ export async function refreshActiveTab(host: SettingsHost) {
|
||||
|
||||
export function inferBasePath() {
|
||||
if (typeof window === "undefined") return "";
|
||||
const configured = window.__CLAWDBOT_CONTROL_UI_BASE_PATH__;
|
||||
const configured = window.__OPENCLAW_CONTROL_UI_BASE_PATH__;
|
||||
if (typeof configured === "string" && configured.trim()) {
|
||||
return normalizeBasePath(configured);
|
||||
}
|
||||
@@ -308,26 +308,26 @@ export function syncUrlWithSessionKey(
|
||||
|
||||
export async function loadOverview(host: SettingsHost) {
|
||||
await Promise.all([
|
||||
loadChannels(host as unknown as MoltbotApp, false),
|
||||
loadPresence(host as unknown as MoltbotApp),
|
||||
loadSessions(host as unknown as MoltbotApp),
|
||||
loadCronStatus(host as unknown as MoltbotApp),
|
||||
loadDebug(host as unknown as MoltbotApp),
|
||||
loadChannels(host as unknown as OpenClawApp, false),
|
||||
loadPresence(host as unknown as OpenClawApp),
|
||||
loadSessions(host as unknown as OpenClawApp),
|
||||
loadCronStatus(host as unknown as OpenClawApp),
|
||||
loadDebug(host as unknown as OpenClawApp),
|
||||
]);
|
||||
}
|
||||
|
||||
export async function loadChannelsTab(host: SettingsHost) {
|
||||
await Promise.all([
|
||||
loadChannels(host as unknown as MoltbotApp, true),
|
||||
loadConfigSchema(host as unknown as MoltbotApp),
|
||||
loadConfig(host as unknown as MoltbotApp),
|
||||
loadChannels(host as unknown as OpenClawApp, true),
|
||||
loadConfigSchema(host as unknown as OpenClawApp),
|
||||
loadConfig(host as unknown as OpenClawApp),
|
||||
]);
|
||||
}
|
||||
|
||||
export async function loadCron(host: SettingsHost) {
|
||||
await Promise.all([
|
||||
loadChannels(host as unknown as MoltbotApp, false),
|
||||
loadCronStatus(host as unknown as MoltbotApp),
|
||||
loadCronJobs(host as unknown as MoltbotApp),
|
||||
loadChannels(host as unknown as OpenClawApp, false),
|
||||
loadCronStatus(host as unknown as OpenClawApp),
|
||||
loadCronJobs(host as unknown as OpenClawApp),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ import { loadAssistantIdentity as loadAssistantIdentityInternal } from "./contro
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__CLAWDBOT_CONTROL_UI_BASE_PATH__?: string;
|
||||
__OPENCLAW_CONTROL_UI_BASE_PATH__?: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ function resolveOnboardingMode(): boolean {
|
||||
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
||||
}
|
||||
|
||||
@customElement("moltbot-app")
|
||||
export class MoltbotApp extends LitElement {
|
||||
@customElement("openclaw-app")
|
||||
export class OpenClawApp extends LitElement {
|
||||
@state() settings: UiSettings = loadSettings();
|
||||
@state() password = "";
|
||||
@state() tab: Tab = "chat";
|
||||
|
||||
@@ -12,8 +12,8 @@ export type AssistantIdentity = {
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__CLAWDBOT_ASSISTANT_NAME__?: string;
|
||||
__CLAWDBOT_ASSISTANT_AVATAR__?: string;
|
||||
__OPENCLAW_ASSISTANT_NAME__?: string;
|
||||
__OPENCLAW_ASSISTANT_AVATAR__?: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export function resolveInjectedAssistantIdentity(): AssistantIdentity {
|
||||
return normalizeAssistantIdentity({});
|
||||
}
|
||||
return normalizeAssistantIdentity({
|
||||
name: window.__CLAWDBOT_ASSISTANT_NAME__,
|
||||
avatar: window.__CLAWDBOT_ASSISTANT_AVATAR__,
|
||||
name: window.__OPENCLAW_ASSISTANT_NAME__,
|
||||
avatar: window.__OPENCLAW_ASSISTANT_AVATAR__,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { MoltbotApp } from "./app";
|
||||
import { OpenClawApp } from "./app";
|
||||
|
||||
const originalConnect = MoltbotApp.prototype.connect;
|
||||
const originalConnect = OpenClawApp.prototype.connect;
|
||||
|
||||
function mountApp(pathname: string) {
|
||||
window.history.replaceState({}, "", pathname);
|
||||
const app = document.createElement("moltbot-app") as MoltbotApp;
|
||||
const app = document.createElement("openclaw-app") as OpenClawApp;
|
||||
document.body.append(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
MoltbotApp.prototype.connect = () => {
|
||||
OpenClawApp.prototype.connect = () => {
|
||||
// no-op: avoid real gateway WS connections in browser tests
|
||||
};
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
MoltbotApp.prototype.connect = originalConnect;
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
OpenClawApp.prototype.connect = originalConnect;
|
||||
window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
@@ -163,7 +163,7 @@ export function handleChatEvent(
|
||||
if (payload.sessionKey !== state.sessionKey) return null;
|
||||
|
||||
// Final from another run (e.g. sub-agent announce): refresh history to show new message.
|
||||
// See https://github.com/moltbot/moltbot/issues/1909
|
||||
// See https://github.com/openclaw/openclaw/issues/1909
|
||||
if (
|
||||
payload.runId &&
|
||||
state.chatRunId &&
|
||||
|
||||
@@ -142,7 +142,7 @@ describe("applyConfig", () => {
|
||||
state.client = { request } as unknown as ConfigState["client"];
|
||||
state.applySessionKey = "agent:main:whatsapp:dm:+15555550123";
|
||||
state.configFormMode = "raw";
|
||||
state.configRaw = "{\n agent: { workspace: \"~/clawd\" }\n}\n";
|
||||
state.configRaw = "{\n agent: { workspace: \"~/openclaw\" }\n}\n";
|
||||
state.configSnapshot = {
|
||||
hash: "hash-123",
|
||||
};
|
||||
@@ -150,7 +150,7 @@ describe("applyConfig", () => {
|
||||
await applyConfig(state);
|
||||
|
||||
expect(request).toHaveBeenCalledWith("config.apply", {
|
||||
raw: "{\n agent: { workspace: \"~/clawd\" }\n}\n",
|
||||
raw: "{\n agent: { workspace: \"~/openclaw\" }\n}\n",
|
||||
baseHash: "hash-123",
|
||||
sessionKey: "agent:main:whatsapp:dm:+15555550123",
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ type DeviceAuthStore = {
|
||||
tokens: Record<string, DeviceAuthEntry>;
|
||||
};
|
||||
|
||||
const STORAGE_KEY = "moltbot.device.auth.v1";
|
||||
const STORAGE_KEY = "openclaw.device.auth.v1";
|
||||
|
||||
function normalizeRole(role: string): string {
|
||||
return role.trim();
|
||||
|
||||
@@ -14,7 +14,7 @@ export type DeviceIdentity = {
|
||||
privateKey: string;
|
||||
};
|
||||
|
||||
const STORAGE_KEY = "moltbot-device-identity-v1";
|
||||
const STORAGE_KEY = "openclaw-device-identity-v1";
|
||||
|
||||
function base64UrlEncode(bytes: Uint8Array): string {
|
||||
let binary = "";
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { MoltbotApp } from "./app";
|
||||
import { OpenClawApp } from "./app";
|
||||
|
||||
const originalConnect = MoltbotApp.prototype.connect;
|
||||
const originalConnect = OpenClawApp.prototype.connect;
|
||||
|
||||
function mountApp(pathname: string) {
|
||||
window.history.replaceState({}, "", pathname);
|
||||
const app = document.createElement("moltbot-app") as MoltbotApp;
|
||||
const app = document.createElement("openclaw-app") as OpenClawApp;
|
||||
document.body.append(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
MoltbotApp.prototype.connect = () => {
|
||||
OpenClawApp.prototype.connect = () => {
|
||||
// no-op: avoid real gateway WS connections in browser tests
|
||||
};
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
MoltbotApp.prototype.connect = originalConnect;
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
OpenClawApp.prototype.connect = originalConnect;
|
||||
window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { MoltbotApp } from "./app";
|
||||
import { OpenClawApp } from "./app";
|
||||
import "../styles.css";
|
||||
|
||||
const originalConnect = MoltbotApp.prototype.connect;
|
||||
const originalConnect = OpenClawApp.prototype.connect;
|
||||
|
||||
function mountApp(pathname: string) {
|
||||
window.history.replaceState({}, "", pathname);
|
||||
const app = document.createElement("moltbot-app") as MoltbotApp;
|
||||
const app = document.createElement("openclaw-app") as OpenClawApp;
|
||||
document.body.append(app);
|
||||
return app;
|
||||
}
|
||||
@@ -19,17 +19,17 @@ function nextFrame() {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
MoltbotApp.prototype.connect = () => {
|
||||
OpenClawApp.prototype.connect = () => {
|
||||
// no-op: avoid real gateway WS connections in browser tests
|
||||
};
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
MoltbotApp.prototype.connect = originalConnect;
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
OpenClawApp.prototype.connect = originalConnect;
|
||||
window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = "";
|
||||
});
|
||||
@@ -53,22 +53,22 @@ describe("control UI routing", () => {
|
||||
});
|
||||
|
||||
it("infers nested base paths", async () => {
|
||||
const app = mountApp("/apps/moltbot/cron");
|
||||
const app = mountApp("/apps/openclaw/cron");
|
||||
await app.updateComplete;
|
||||
|
||||
expect(app.basePath).toBe("/apps/moltbot");
|
||||
expect(app.basePath).toBe("/apps/openclaw");
|
||||
expect(app.tab).toBe("cron");
|
||||
expect(window.location.pathname).toBe("/apps/moltbot/cron");
|
||||
expect(window.location.pathname).toBe("/apps/openclaw/cron");
|
||||
});
|
||||
|
||||
it("honors explicit base path overrides", async () => {
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = "/moltbot";
|
||||
const app = mountApp("/moltbot/sessions");
|
||||
window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = "/openclaw";
|
||||
const app = mountApp("/openclaw/sessions");
|
||||
await app.updateComplete;
|
||||
|
||||
expect(app.basePath).toBe("/moltbot");
|
||||
expect(app.basePath).toBe("/openclaw");
|
||||
expect(app.tab).toBe("sessions");
|
||||
expect(window.location.pathname).toBe("/moltbot/sessions");
|
||||
expect(window.location.pathname).toBe("/openclaw/sessions");
|
||||
});
|
||||
|
||||
it("updates the URL when clicking nav items", async () => {
|
||||
@@ -169,7 +169,7 @@ describe("control UI routing", () => {
|
||||
|
||||
it("hydrates token from URL params even when settings already set", async () => {
|
||||
localStorage.setItem(
|
||||
"moltbot.control.settings.v1",
|
||||
"openclaw.control.settings.v1",
|
||||
JSON.stringify({ token: "existing-token" }),
|
||||
);
|
||||
const app = mountApp("/ui/overview?token=abc123");
|
||||
|
||||
@@ -73,7 +73,7 @@ describe("subtitleForTab", () => {
|
||||
|
||||
it("returns descriptive subtitles", () => {
|
||||
expect(subtitleForTab("chat")).toContain("chat session");
|
||||
expect(subtitleForTab("config")).toContain("moltbot.json");
|
||||
expect(subtitleForTab("config")).toContain("openclaw.json");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -95,7 +95,7 @@ describe("normalizeBasePath", () => {
|
||||
});
|
||||
|
||||
it("handles nested paths", () => {
|
||||
expect(normalizeBasePath("/apps/moltbot")).toBe("/apps/moltbot");
|
||||
expect(normalizeBasePath("/apps/openclaw")).toBe("/apps/openclaw");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("pathForTab", () => {
|
||||
|
||||
it("prepends base path", () => {
|
||||
expect(pathForTab("chat", "/ui")).toBe("/ui/chat");
|
||||
expect(pathForTab("sessions", "/apps/moltbot")).toBe("/apps/moltbot/sessions");
|
||||
expect(pathForTab("sessions", "/apps/openclaw")).toBe("/apps/openclaw/sessions");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -139,7 +139,7 @@ describe("tabFromPath", () => {
|
||||
|
||||
it("handles base paths", () => {
|
||||
expect(tabFromPath("/ui/chat", "/ui")).toBe("chat");
|
||||
expect(tabFromPath("/apps/moltbot/sessions", "/apps/moltbot")).toBe("sessions");
|
||||
expect(tabFromPath("/apps/openclaw/sessions", "/apps/openclaw")).toBe("sessions");
|
||||
});
|
||||
|
||||
it("returns null for unknown path", () => {
|
||||
@@ -164,7 +164,7 @@ describe("inferBasePathFromPathname", () => {
|
||||
|
||||
it("infers base path from nested paths", () => {
|
||||
expect(inferBasePathFromPathname("/ui/chat")).toBe("/ui");
|
||||
expect(inferBasePathFromPathname("/apps/moltbot/sessions")).toBe("/apps/moltbot");
|
||||
expect(inferBasePathFromPathname("/apps/openclaw/sessions")).toBe("/apps/openclaw");
|
||||
});
|
||||
|
||||
it("handles index.html suffix", () => {
|
||||
|
||||
@@ -177,7 +177,7 @@ export function subtitleForTab(tab: Tab) {
|
||||
case "chat":
|
||||
return "Direct gateway chat session for quick interventions.";
|
||||
case "config":
|
||||
return "Edit ~/.clawdbot/moltbot.json safely.";
|
||||
return "Edit ~/.openclaw/openclaw.json safely.";
|
||||
case "debug":
|
||||
return "Gateway snapshots, events, and manual RPC calls.";
|
||||
case "logs":
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const KEY = "moltbot.control.settings.v1";
|
||||
const KEY = "openclaw.control.settings.v1";
|
||||
|
||||
import type { ThemeMode } from "./theme";
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ function createProps(overrides: Partial<ChatProps> = {}): ChatProps {
|
||||
error: null,
|
||||
sessions: createSessions(),
|
||||
focusMode: false,
|
||||
assistantName: "Moltbot",
|
||||
assistantName: "OpenClaw",
|
||||
assistantAvatar: null,
|
||||
onRefresh: () => undefined,
|
||||
onToggleFocusMode: () => undefined,
|
||||
|
||||
@@ -55,7 +55,7 @@ export function renderDebug(props: DebugProps) {
|
||||
${securitySummary
|
||||
? html`<div class="callout ${securityTone}" style="margin-top: 8px;">
|
||||
Security audit: ${securityLabel}${info > 0 ? ` · ${info} info` : ""}. Run
|
||||
<span class="mono">moltbot security audit --deep</span> for details.
|
||||
<span class="mono">openclaw security audit --deep</span> for details.
|
||||
</div>`
|
||||
: nothing}
|
||||
<pre class="code-block">${JSON.stringify(props.status ?? {}, null, 2)}</pre>
|
||||
|
||||
@@ -43,13 +43,13 @@ export function renderOverview(props: OverviewProps) {
|
||||
<div class="muted" style="margin-top: 8px;">
|
||||
This gateway requires auth. Add a token or password, then click Connect.
|
||||
<div style="margin-top: 6px;">
|
||||
<span class="mono">moltbot dashboard --no-open</span> → tokenized URL<br />
|
||||
<span class="mono">moltbot doctor --generate-gateway-token</span> → set token
|
||||
<span class="mono">openclaw dashboard --no-open</span> → tokenized URL<br />
|
||||
<span class="mono">openclaw doctor --generate-gateway-token</span> → set token
|
||||
</div>
|
||||
<div style="margin-top: 6px;">
|
||||
<a
|
||||
class="session-link"
|
||||
href="https://docs.molt.bot/web/dashboard"
|
||||
href="https://docs.openclaw.ai/web/dashboard"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title="Control UI auth docs (opens in new tab)"
|
||||
@@ -62,12 +62,12 @@ export function renderOverview(props: OverviewProps) {
|
||||
return html`
|
||||
<div class="muted" style="margin-top: 8px;">
|
||||
Auth failed. Re-copy a tokenized URL with
|
||||
<span class="mono">moltbot dashboard --no-open</span>, or update the token,
|
||||
<span class="mono">openclaw dashboard --no-open</span>, or update the token,
|
||||
then click Connect.
|
||||
<div style="margin-top: 6px;">
|
||||
<a
|
||||
class="session-link"
|
||||
href="https://docs.molt.bot/web/dashboard"
|
||||
href="https://docs.openclaw.ai/web/dashboard"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title="Control UI auth docs (opens in new tab)"
|
||||
@@ -96,7 +96,7 @@ export function renderOverview(props: OverviewProps) {
|
||||
<div style="margin-top: 6px;">
|
||||
<a
|
||||
class="session-link"
|
||||
href="https://docs.molt.bot/gateway/tailscale"
|
||||
href="https://docs.openclaw.ai/gateway/tailscale"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title="Tailscale Serve docs (opens in new tab)"
|
||||
@@ -105,7 +105,7 @@ export function renderOverview(props: OverviewProps) {
|
||||
<span class="muted"> · </span>
|
||||
<a
|
||||
class="session-link"
|
||||
href="https://docs.molt.bot/web/control-ui#insecure-http"
|
||||
href="https://docs.openclaw.ai/web/control-ui#insecure-http"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title="Insecure HTTP docs (opens in new tab)"
|
||||
@@ -141,7 +141,7 @@ export function renderOverview(props: OverviewProps) {
|
||||
const v = (e.target as HTMLInputElement).value;
|
||||
props.onSettingsChange({ ...props.settings, token: v });
|
||||
}}
|
||||
placeholder="CLAWDBOT_GATEWAY_TOKEN"
|
||||
placeholder="OPENCLAW_GATEWAY_TOKEN"
|
||||
/>
|
||||
</label>
|
||||
<label class="field">
|
||||
|
||||
@@ -13,7 +13,7 @@ function normalizeBase(input: string): string {
|
||||
}
|
||||
|
||||
export default defineConfig(({ command }) => {
|
||||
const envBase = process.env.CLAWDBOT_CONTROL_UI_BASE_PATH?.trim();
|
||||
const envBase = process.env.OPENCLAW_CONTROL_UI_BASE_PATH?.trim();
|
||||
const base = envBase ? normalizeBase(envBase) : "./";
|
||||
return {
|
||||
base,
|
||||
|
||||
Reference in New Issue
Block a user