refactor: rename clawdbot to moltbot with legacy compat
This commit is contained in:
@@ -239,7 +239,7 @@ html.theme-transition::view-transition-new(theme) {
|
||||
}
|
||||
}
|
||||
|
||||
clawdbot-app {
|
||||
moltbot-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 { ClawdbotApp } from "./app";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { NostrProfile } from "./types";
|
||||
import { createNostrProfileFormState } from "./views/channels.nostr-profile-form";
|
||||
|
||||
export async function handleWhatsAppStart(host: ClawdbotApp, force: boolean) {
|
||||
export async function handleWhatsAppStart(host: MoltbotApp, force: boolean) {
|
||||
await startWhatsAppLogin(host, force);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleWhatsAppWait(host: ClawdbotApp) {
|
||||
export async function handleWhatsAppWait(host: MoltbotApp) {
|
||||
await waitWhatsAppLogin(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleWhatsAppLogout(host: ClawdbotApp) {
|
||||
export async function handleWhatsAppLogout(host: MoltbotApp) {
|
||||
await logoutWhatsApp(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleChannelConfigSave(host: ClawdbotApp) {
|
||||
export async function handleChannelConfigSave(host: MoltbotApp) {
|
||||
await saveConfig(host);
|
||||
await loadConfig(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
|
||||
export async function handleChannelConfigReload(host: ClawdbotApp) {
|
||||
export async function handleChannelConfigReload(host: MoltbotApp) {
|
||||
await loadConfig(host);
|
||||
await loadChannels(host, true);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ function parseValidationErrors(details: unknown): Record<string, string> {
|
||||
return errors;
|
||||
}
|
||||
|
||||
function resolveNostrAccountId(host: ClawdbotApp): string {
|
||||
function resolveNostrAccountId(host: MoltbotApp): 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: ClawdbotApp,
|
||||
host: MoltbotApp,
|
||||
accountId: string,
|
||||
profile: NostrProfile | null,
|
||||
) {
|
||||
@@ -67,13 +67,13 @@ export function handleNostrProfileEdit(
|
||||
host.nostrProfileFormState = createNostrProfileFormState(profile ?? undefined);
|
||||
}
|
||||
|
||||
export function handleNostrProfileCancel(host: ClawdbotApp) {
|
||||
export function handleNostrProfileCancel(host: MoltbotApp) {
|
||||
host.nostrProfileFormState = null;
|
||||
host.nostrProfileAccountId = null;
|
||||
}
|
||||
|
||||
export function handleNostrProfileFieldChange(
|
||||
host: ClawdbotApp,
|
||||
host: MoltbotApp,
|
||||
field: keyof NostrProfile,
|
||||
value: string,
|
||||
) {
|
||||
@@ -92,7 +92,7 @@ export function handleNostrProfileFieldChange(
|
||||
};
|
||||
}
|
||||
|
||||
export function handleNostrProfileToggleAdvanced(host: ClawdbotApp) {
|
||||
export function handleNostrProfileToggleAdvanced(host: MoltbotApp) {
|
||||
const state = host.nostrProfileFormState;
|
||||
if (!state) return;
|
||||
host.nostrProfileFormState = {
|
||||
@@ -101,7 +101,7 @@ export function handleNostrProfileToggleAdvanced(host: ClawdbotApp) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function handleNostrProfileSave(host: ClawdbotApp) {
|
||||
export async function handleNostrProfileSave(host: MoltbotApp) {
|
||||
const state = host.nostrProfileFormState;
|
||||
if (!state || state.saving) return;
|
||||
const accountId = resolveNostrAccountId(host);
|
||||
@@ -167,7 +167,7 @@ export async function handleNostrProfileSave(host: ClawdbotApp) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleNostrProfileImport(host: ClawdbotApp) {
|
||||
export async function handleNostrProfileImport(host: MoltbotApp) {
|
||||
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 { ClawdbotApp } from "./app";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { ChatAttachment, ChatQueueItem } from "./ui-types";
|
||||
|
||||
type ChatHost = {
|
||||
@@ -44,7 +44,7 @@ export function isChatStopCommand(text: string) {
|
||||
export async function handleAbortChat(host: ChatHost) {
|
||||
if (!host.connected) return;
|
||||
host.chatMessage = "";
|
||||
await abortChatRun(host as unknown as ClawdbotApp);
|
||||
await abortChatRun(host as unknown as MoltbotApp);
|
||||
}
|
||||
|
||||
function enqueueChatMessage(host: ChatHost, text: string, attachments?: ChatAttachment[]) {
|
||||
@@ -74,7 +74,7 @@ async function sendChatMessageNow(
|
||||
},
|
||||
) {
|
||||
resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
|
||||
const ok = await sendChatMessage(host as unknown as ClawdbotApp, message, opts?.attachments);
|
||||
const ok = await sendChatMessage(host as unknown as MoltbotApp, message, opts?.attachments);
|
||||
if (!ok && opts?.previousDraft != null) {
|
||||
host.chatMessage = opts.previousDraft;
|
||||
}
|
||||
@@ -154,8 +154,8 @@ export async function handleSendChat(
|
||||
|
||||
export async function refreshChat(host: ChatHost) {
|
||||
await Promise.all([
|
||||
loadChatHistory(host as unknown as ClawdbotApp),
|
||||
loadSessions(host as unknown as ClawdbotApp),
|
||||
loadChatHistory(host as unknown as MoltbotApp),
|
||||
loadSessions(host as unknown as MoltbotApp),
|
||||
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 { ClawdbotApp } from "./app";
|
||||
import type { MoltbotApp } from "./app";
|
||||
import type { ExecApprovalRequest } from "./controllers/exec-approval";
|
||||
import { loadAssistantIdentity } from "./controllers/assistant-identity";
|
||||
|
||||
@@ -120,7 +120,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: "clawdbot-control-ui",
|
||||
clientName: "moltbot-control-ui",
|
||||
mode: "webchat",
|
||||
onHello: (hello) => {
|
||||
host.connected = true;
|
||||
@@ -133,10 +133,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 ClawdbotApp);
|
||||
void loadAgents(host as unknown as ClawdbotApp);
|
||||
void loadNodes(host as unknown as ClawdbotApp, { quiet: true });
|
||||
void loadDevices(host as unknown as ClawdbotApp, { quiet: true });
|
||||
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 refreshActiveTab(host as unknown as Parameters<typeof refreshActiveTab>[0]);
|
||||
},
|
||||
onClose: ({ code, reason }) => {
|
||||
@@ -188,14 +188,14 @@ function handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {
|
||||
payload.sessionKey,
|
||||
);
|
||||
}
|
||||
const state = handleChatEvent(host as unknown as ClawdbotApp, payload);
|
||||
const state = handleChatEvent(host as unknown as MoltbotApp, payload);
|
||||
if (state === "final" || state === "error" || state === "aborted") {
|
||||
resetToolStream(host as unknown as Parameters<typeof resetToolStream>[0]);
|
||||
void flushChatQueueForEvent(
|
||||
host as unknown as Parameters<typeof flushChatQueueForEvent>[0],
|
||||
);
|
||||
}
|
||||
if (state === "final") void loadChatHistory(host as unknown as ClawdbotApp);
|
||||
if (state === "final") void loadChatHistory(host as unknown as MoltbotApp);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ function handleGatewayEventUnsafe(host: GatewayHost, evt: GatewayEventFrame) {
|
||||
}
|
||||
|
||||
if (evt.event === "device.pair.requested" || evt.event === "device.pair.resolved") {
|
||||
void loadDevices(host as unknown as ClawdbotApp, { quiet: true });
|
||||
void loadDevices(host as unknown as MoltbotApp, { 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 { ClawdbotApp } from "./app";
|
||||
import type { MoltbotApp } 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 ClawdbotApp, { quiet: true }),
|
||||
() => void loadNodes(host as unknown as MoltbotApp, { 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 ClawdbotApp, { quiet: true });
|
||||
void loadLogs(host as unknown as MoltbotApp, { 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 ClawdbotApp);
|
||||
void loadDebug(host as unknown as MoltbotApp);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,10 +129,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="Clawdbot" />
|
||||
<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" />
|
||||
</div>
|
||||
<div class="brand-text">
|
||||
<div class="brand-title">CLAWDBOT</div>
|
||||
<div class="brand-title">MOLTBOT</div>
|
||||
<div class="brand-sub">Gateway Dashboard</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 = `clawdbot-logs-${label}-${stamp}.log`;
|
||||
anchor.download = `moltbot-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 { ClawdbotApp } from "./app";
|
||||
import type { MoltbotApp } from "./app";
|
||||
|
||||
type SettingsHost = {
|
||||
settings: UiSettings;
|
||||
@@ -144,15 +144,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 ClawdbotApp);
|
||||
if (host.tab === "sessions") await loadSessions(host as unknown as ClawdbotApp);
|
||||
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 === "cron") await loadCron(host);
|
||||
if (host.tab === "skills") await loadSkills(host as unknown as ClawdbotApp);
|
||||
if (host.tab === "skills") await loadSkills(host as unknown as MoltbotApp);
|
||||
if (host.tab === "nodes") {
|
||||
await loadNodes(host as unknown as ClawdbotApp);
|
||||
await loadDevices(host as unknown as ClawdbotApp);
|
||||
await loadConfig(host as unknown as ClawdbotApp);
|
||||
await loadExecApprovals(host as unknown as ClawdbotApp);
|
||||
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);
|
||||
}
|
||||
if (host.tab === "chat") {
|
||||
await refreshChat(host as unknown as Parameters<typeof refreshChat>[0]);
|
||||
@@ -162,16 +162,16 @@ export async function refreshActiveTab(host: SettingsHost) {
|
||||
);
|
||||
}
|
||||
if (host.tab === "config") {
|
||||
await loadConfigSchema(host as unknown as ClawdbotApp);
|
||||
await loadConfig(host as unknown as ClawdbotApp);
|
||||
await loadConfigSchema(host as unknown as MoltbotApp);
|
||||
await loadConfig(host as unknown as MoltbotApp);
|
||||
}
|
||||
if (host.tab === "debug") {
|
||||
await loadDebug(host as unknown as ClawdbotApp);
|
||||
await loadDebug(host as unknown as MoltbotApp);
|
||||
host.eventLog = host.eventLogBuffer;
|
||||
}
|
||||
if (host.tab === "logs") {
|
||||
host.logsAtBottom = true;
|
||||
await loadLogs(host as unknown as ClawdbotApp, { reset: true });
|
||||
await loadLogs(host as unknown as MoltbotApp, { reset: true });
|
||||
scheduleLogsScroll(
|
||||
host as unknown as Parameters<typeof scheduleLogsScroll>[0],
|
||||
true,
|
||||
@@ -307,26 +307,26 @@ export function syncUrlWithSessionKey(
|
||||
|
||||
export async function loadOverview(host: SettingsHost) {
|
||||
await Promise.all([
|
||||
loadChannels(host as unknown as ClawdbotApp, false),
|
||||
loadPresence(host as unknown as ClawdbotApp),
|
||||
loadSessions(host as unknown as ClawdbotApp),
|
||||
loadCronStatus(host as unknown as ClawdbotApp),
|
||||
loadDebug(host as unknown as ClawdbotApp),
|
||||
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),
|
||||
]);
|
||||
}
|
||||
|
||||
export async function loadChannelsTab(host: SettingsHost) {
|
||||
await Promise.all([
|
||||
loadChannels(host as unknown as ClawdbotApp, true),
|
||||
loadConfigSchema(host as unknown as ClawdbotApp),
|
||||
loadConfig(host as unknown as ClawdbotApp),
|
||||
loadChannels(host as unknown as MoltbotApp, true),
|
||||
loadConfigSchema(host as unknown as MoltbotApp),
|
||||
loadConfig(host as unknown as MoltbotApp),
|
||||
]);
|
||||
}
|
||||
|
||||
export async function loadCron(host: SettingsHost) {
|
||||
await Promise.all([
|
||||
loadChannels(host as unknown as ClawdbotApp, false),
|
||||
loadCronStatus(host as unknown as ClawdbotApp),
|
||||
loadCronJobs(host as unknown as ClawdbotApp),
|
||||
loadChannels(host as unknown as MoltbotApp, false),
|
||||
loadCronStatus(host as unknown as MoltbotApp),
|
||||
loadCronJobs(host as unknown as MoltbotApp),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ function resolveOnboardingMode(): boolean {
|
||||
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
||||
}
|
||||
|
||||
@customElement("clawdbot-app")
|
||||
export class ClawdbotApp extends LitElement {
|
||||
@customElement("moltbot-app")
|
||||
export class MoltbotApp extends LitElement {
|
||||
@state() settings: UiSettings = loadSettings();
|
||||
@state() password = "";
|
||||
@state() tab: Tab = "chat";
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { ClawdbotApp } from "./app";
|
||||
import { MoltbotApp } from "./app";
|
||||
|
||||
const originalConnect = ClawdbotApp.prototype.connect;
|
||||
const originalConnect = MoltbotApp.prototype.connect;
|
||||
|
||||
function mountApp(pathname: string) {
|
||||
window.history.replaceState({}, "", pathname);
|
||||
const app = document.createElement("clawdbot-app") as ClawdbotApp;
|
||||
const app = document.createElement("moltbot-app") as MoltbotApp;
|
||||
document.body.append(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
ClawdbotApp.prototype.connect = () => {
|
||||
MoltbotApp.prototype.connect = () => {
|
||||
// no-op: avoid real gateway WS connections in browser tests
|
||||
};
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
@@ -21,7 +21,7 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
ClawdbotApp.prototype.connect = originalConnect;
|
||||
MoltbotApp.prototype.connect = originalConnect;
|
||||
window.__CLAWDBOT_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/clawdbot/clawdbot/issues/1909
|
||||
// See https://github.com/moltbot/moltbot/issues/1909
|
||||
if (
|
||||
payload.runId &&
|
||||
state.chatRunId &&
|
||||
|
||||
@@ -11,7 +11,7 @@ type DeviceAuthStore = {
|
||||
tokens: Record<string, DeviceAuthEntry>;
|
||||
};
|
||||
|
||||
const STORAGE_KEY = "clawdbot.device.auth.v1";
|
||||
const STORAGE_KEY = "moltbot.device.auth.v1";
|
||||
|
||||
function normalizeRole(role: string): string {
|
||||
return role.trim();
|
||||
|
||||
@@ -14,7 +14,7 @@ export type DeviceIdentity = {
|
||||
privateKey: string;
|
||||
};
|
||||
|
||||
const STORAGE_KEY = "clawdbot-device-identity-v1";
|
||||
const STORAGE_KEY = "moltbot-device-identity-v1";
|
||||
|
||||
function base64UrlEncode(bytes: Uint8Array): string {
|
||||
let binary = "";
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { ClawdbotApp } from "./app";
|
||||
import { MoltbotApp } from "./app";
|
||||
|
||||
const originalConnect = ClawdbotApp.prototype.connect;
|
||||
const originalConnect = MoltbotApp.prototype.connect;
|
||||
|
||||
function mountApp(pathname: string) {
|
||||
window.history.replaceState({}, "", pathname);
|
||||
const app = document.createElement("clawdbot-app") as ClawdbotApp;
|
||||
const app = document.createElement("moltbot-app") as MoltbotApp;
|
||||
document.body.append(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
ClawdbotApp.prototype.connect = () => {
|
||||
MoltbotApp.prototype.connect = () => {
|
||||
// no-op: avoid real gateway WS connections in browser tests
|
||||
};
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
@@ -21,7 +21,7 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
ClawdbotApp.prototype.connect = originalConnect;
|
||||
MoltbotApp.prototype.connect = originalConnect;
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = "";
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { ClawdbotApp } from "./app";
|
||||
import { MoltbotApp } from "./app";
|
||||
import "../styles.css";
|
||||
|
||||
const originalConnect = ClawdbotApp.prototype.connect;
|
||||
const originalConnect = MoltbotApp.prototype.connect;
|
||||
|
||||
function mountApp(pathname: string) {
|
||||
window.history.replaceState({}, "", pathname);
|
||||
const app = document.createElement("clawdbot-app") as ClawdbotApp;
|
||||
const app = document.createElement("moltbot-app") as MoltbotApp;
|
||||
document.body.append(app);
|
||||
return app;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ function nextFrame() {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
ClawdbotApp.prototype.connect = () => {
|
||||
MoltbotApp.prototype.connect = () => {
|
||||
// no-op: avoid real gateway WS connections in browser tests
|
||||
};
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = undefined;
|
||||
@@ -28,7 +28,7 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
ClawdbotApp.prototype.connect = originalConnect;
|
||||
MoltbotApp.prototype.connect = originalConnect;
|
||||
window.__CLAWDBOT_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/clawdbot/cron");
|
||||
const app = mountApp("/apps/moltbot/cron");
|
||||
await app.updateComplete;
|
||||
|
||||
expect(app.basePath).toBe("/apps/clawdbot");
|
||||
expect(app.basePath).toBe("/apps/moltbot");
|
||||
expect(app.tab).toBe("cron");
|
||||
expect(window.location.pathname).toBe("/apps/clawdbot/cron");
|
||||
expect(window.location.pathname).toBe("/apps/moltbot/cron");
|
||||
});
|
||||
|
||||
it("honors explicit base path overrides", async () => {
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = "/clawdbot";
|
||||
const app = mountApp("/clawdbot/sessions");
|
||||
window.__CLAWDBOT_CONTROL_UI_BASE_PATH__ = "/moltbot";
|
||||
const app = mountApp("/moltbot/sessions");
|
||||
await app.updateComplete;
|
||||
|
||||
expect(app.basePath).toBe("/clawdbot");
|
||||
expect(app.basePath).toBe("/moltbot");
|
||||
expect(app.tab).toBe("sessions");
|
||||
expect(window.location.pathname).toBe("/clawdbot/sessions");
|
||||
expect(window.location.pathname).toBe("/moltbot/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(
|
||||
"clawdbot.control.settings.v1",
|
||||
"moltbot.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("clawdbot.json");
|
||||
expect(subtitleForTab("config")).toContain("moltbot.json");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -95,7 +95,7 @@ describe("normalizeBasePath", () => {
|
||||
});
|
||||
|
||||
it("handles nested paths", () => {
|
||||
expect(normalizeBasePath("/apps/clawdbot")).toBe("/apps/clawdbot");
|
||||
expect(normalizeBasePath("/apps/moltbot")).toBe("/apps/moltbot");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("pathForTab", () => {
|
||||
|
||||
it("prepends base path", () => {
|
||||
expect(pathForTab("chat", "/ui")).toBe("/ui/chat");
|
||||
expect(pathForTab("sessions", "/apps/clawdbot")).toBe("/apps/clawdbot/sessions");
|
||||
expect(pathForTab("sessions", "/apps/moltbot")).toBe("/apps/moltbot/sessions");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -139,7 +139,7 @@ describe("tabFromPath", () => {
|
||||
|
||||
it("handles base paths", () => {
|
||||
expect(tabFromPath("/ui/chat", "/ui")).toBe("chat");
|
||||
expect(tabFromPath("/apps/clawdbot/sessions", "/apps/clawdbot")).toBe("sessions");
|
||||
expect(tabFromPath("/apps/moltbot/sessions", "/apps/moltbot")).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/clawdbot/sessions")).toBe("/apps/clawdbot");
|
||||
expect(inferBasePathFromPathname("/apps/moltbot/sessions")).toBe("/apps/moltbot");
|
||||
});
|
||||
|
||||
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/clawdbot.json safely.";
|
||||
return "Edit ~/.clawdbot/moltbot.json safely.";
|
||||
case "debug":
|
||||
return "Gateway snapshots, events, and manual RPC calls.";
|
||||
case "logs":
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const KEY = "clawdbot.control.settings.v1";
|
||||
const KEY = "moltbot.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: "Clawdbot",
|
||||
assistantName: "Moltbot",
|
||||
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">clawdbot security audit --deep</span> for details.
|
||||
<span class="mono">moltbot security audit --deep</span> for details.
|
||||
</div>`
|
||||
: nothing}
|
||||
<pre class="code-block">${JSON.stringify(props.status ?? {}, null, 2)}</pre>
|
||||
|
||||
@@ -43,8 +43,8 @@ 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">clawdbot dashboard --no-open</span> → tokenized URL<br />
|
||||
<span class="mono">clawdbot doctor --generate-gateway-token</span> → set token
|
||||
<span class="mono">moltbot dashboard --no-open</span> → tokenized URL<br />
|
||||
<span class="mono">moltbot doctor --generate-gateway-token</span> → set token
|
||||
</div>
|
||||
<div style="margin-top: 6px;">
|
||||
<a
|
||||
@@ -62,7 +62,7 @@ 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">clawdbot dashboard --no-open</span>, or update the token,
|
||||
<span class="mono">moltbot dashboard --no-open</span>, or update the token,
|
||||
then click Connect.
|
||||
<div style="margin-top: 6px;">
|
||||
<a
|
||||
|
||||
Reference in New Issue
Block a user