refactor: rename clawdbot to moltbot with legacy compat

This commit is contained in:
Peter Steinberger
2026-01-27 12:19:58 +00:00
parent 83460df96f
commit 6d16a658e5
1839 changed files with 11250 additions and 11199 deletions

View File

@@ -12,7 +12,7 @@ vi.mock("./agent.js", () => ({
agentCommand: vi.fn(),
}));
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import * as configModule from "../config/config.js";
import { callGateway } from "../gateway/call.js";
import type { RuntimeEnv } from "../runtime.js";
@@ -27,7 +27,7 @@ const runtime: RuntimeEnv = {
const configSpy = vi.spyOn(configModule, "loadConfig");
function mockConfig(storePath: string, overrides?: Partial<ClawdbotConfig>) {
function mockConfig(storePath: string, overrides?: Partial<MoltbotConfig>) {
configSpy.mockReturnValue({
agents: {
defaults: {
@@ -50,7 +50,7 @@ beforeEach(() => {
describe("agentCliCommand", () => {
it("uses gateway by default", async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-agent-cli-"));
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-agent-cli-"));
const store = path.join(dir, "sessions.json");
mockConfig(store);
@@ -75,7 +75,7 @@ describe("agentCliCommand", () => {
});
it("falls back to embedded agent when gateway fails", async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-agent-cli-"));
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-agent-cli-"));
const store = path.join(dir, "sessions.json");
mockConfig(store);
@@ -97,7 +97,7 @@ describe("agentCliCommand", () => {
});
it("skips gateway when --local is set", async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-agent-cli-"));
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-agent-cli-"));
const store = path.join(dir, "sessions.json");
mockConfig(store);

View File

@@ -93,7 +93,7 @@ export async function agentViaGatewayCommand(opts: AgentCliOpts, runtime: Runtim
const knownAgents = listAgentIds(cfg);
if (!knownAgents.includes(agentId)) {
throw new Error(
`Unknown agent id "${agentIdRaw}". Use "${formatCliCommand("clawdbot agents list")}" to see configured agents.`,
`Unknown agent id "${agentIdRaw}". Use "${formatCliCommand("moltbot agents list")}" to see configured agents.`,
);
}
}

View File

@@ -1,7 +1,7 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { CliDeps } from "../cli/deps.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import type { SessionEntry } from "../config/sessions.js";
@@ -37,7 +37,7 @@ describe("deliverAgentCommandResult", () => {
});
it("prefers explicit accountId for outbound delivery", async () => {
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
const deps = {} as CliDeps;
const runtime = {
log: vi.fn(),
@@ -74,7 +74,7 @@ describe("deliverAgentCommandResult", () => {
});
it("falls back to session accountId for implicit delivery", async () => {
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
const deps = {} as CliDeps;
const runtime = {
log: vi.fn(),
@@ -110,7 +110,7 @@ describe("deliverAgentCommandResult", () => {
});
it("does not infer accountId for explicit delivery targets", async () => {
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
const deps = {} as CliDeps;
const runtime = {
log: vi.fn(),
@@ -150,7 +150,7 @@ describe("deliverAgentCommandResult", () => {
});
it("skips session accountId when channel differs", async () => {
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
const deps = {} as CliDeps;
const runtime = {
log: vi.fn(),
@@ -186,7 +186,7 @@ describe("deliverAgentCommandResult", () => {
});
it("uses session last channel when none is provided", async () => {
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
const deps = {} as CliDeps;
const runtime = {
log: vi.fn(),
@@ -221,7 +221,7 @@ describe("deliverAgentCommandResult", () => {
});
it("uses reply overrides for delivery routing", async () => {
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
const deps = {} as CliDeps;
const runtime = {
log: vi.fn(),
@@ -261,7 +261,7 @@ describe("deliverAgentCommandResult", () => {
});
it("prefixes nested agent outputs with context", async () => {
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
const deps = {} as CliDeps;
const runtime = {
log: vi.fn(),

View File

@@ -16,7 +16,7 @@ vi.mock("../agents/model-catalog.js", () => ({
import { loadModelCatalog } from "../agents/model-catalog.js";
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import * as configModule from "../config/config.js";
import { emitAgentEvent, onAgentEvent } from "../infra/agent-events.js";
import type { RuntimeEnv } from "../runtime.js";
@@ -38,14 +38,14 @@ const runtime: RuntimeEnv = {
const configSpy = vi.spyOn(configModule, "loadConfig");
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
return withTempHomeBase(fn, { prefix: "clawdbot-agent-" });
return withTempHomeBase(fn, { prefix: "moltbot-agent-" });
}
function mockConfig(
home: string,
storePath: string,
agentOverrides?: Partial<NonNullable<NonNullable<ClawdbotConfig["agents"]>["defaults"]>>,
telegramOverrides?: Partial<NonNullable<ClawdbotConfig["telegram"]>>,
agentOverrides?: Partial<NonNullable<NonNullable<MoltbotConfig["agents"]>["defaults"]>>,
telegramOverrides?: Partial<NonNullable<MoltbotConfig["telegram"]>>,
agentsList?: Array<{ id: string; default?: boolean }>,
) {
configSpy.mockReturnValue({

View File

@@ -78,7 +78,7 @@ export async function agentCommand(
const knownAgents = listAgentIds(cfg);
if (!knownAgents.includes(agentIdOverride)) {
throw new Error(
`Unknown agent id "${agentIdOverrideRaw}". Use "${formatCliCommand("clawdbot agents list")}" to see configured agents.`,
`Unknown agent id "${agentIdOverrideRaw}". Use "${formatCliCommand("moltbot agents list")}" to see configured agents.`,
);
}
}

View File

@@ -1,7 +1,7 @@
import { AGENT_LANE_NESTED } from "../../agents/lanes.js";
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
import { createOutboundSendDeps, type CliDeps } from "../../cli/outbound-send-deps.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import type { SessionEntry } from "../../config/sessions.js";
import { deliverOutboundPayloads } from "../../infra/outbound/deliver.js";
import { buildOutboundResultEnvelope } from "../../infra/outbound/envelope.js";
@@ -46,7 +46,7 @@ function logNestedOutput(runtime: RuntimeEnv, opts: AgentCommandOpts, output: st
}
export async function deliverAgentCommandResult(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
deps: CliDeps;
runtime: RuntimeEnv;
opts: AgentCommandOpts;

View File

@@ -3,7 +3,7 @@ import { lookupContextTokens } from "../../agents/context.js";
import { DEFAULT_CONTEXT_TOKENS } from "../../agents/defaults.js";
import { isCliProvider } from "../../agents/model-selection.js";
import { hasNonzeroUsage } from "../../agents/usage.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import { type SessionEntry, updateSessionStore } from "../../config/sessions.js";
type RunResult = Awaited<
@@ -11,7 +11,7 @@ type RunResult = Awaited<
>;
export async function updateSessionStoreAfterAgentRun(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
contextTokensOverride?: number;
sessionId: string;
sessionKey: string;

View File

@@ -7,7 +7,7 @@ import {
type ThinkLevel,
type VerboseLevel,
} from "../../auto-reply/thinking.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import {
evaluateSessionFreshness,
loadSessionStore,
@@ -40,7 +40,7 @@ type SessionKeyResolution = {
};
export function resolveSessionKeyForRequest(opts: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
to?: string;
sessionId?: string;
sessionKey?: string;
@@ -81,7 +81,7 @@ export function resolveSessionKeyForRequest(opts: {
}
export function resolveSession(opts: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
to?: string;
sessionId?: string;
sessionKey?: string;

View File

@@ -25,7 +25,7 @@ const runtime: RuntimeEnv = {
};
const baseSnapshot = {
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},

View File

@@ -1,7 +1,7 @@
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js";
import type { ChannelId } from "../channels/plugins/types.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { AgentBinding } from "../config/types.js";
import { DEFAULT_ACCOUNT_ID, normalizeAgentId } from "../routing/session-key.js";
import type { ChannelChoice } from "./onboard-types.js";
@@ -29,10 +29,10 @@ export function describeBinding(binding: AgentBinding) {
}
export function applyAgentBindings(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
bindings: AgentBinding[],
): {
config: ClawdbotConfig;
config: MoltbotConfig;
added: AgentBinding[];
skipped: AgentBinding[];
conflicts: Array<{ binding: AgentBinding; existingAgentId: string }>;
@@ -81,7 +81,7 @@ export function applyAgentBindings(
};
}
function resolveDefaultAccountId(cfg: ClawdbotConfig, provider: ChannelId): string {
function resolveDefaultAccountId(cfg: MoltbotConfig, provider: ChannelId): string {
const plugin = getChannelPlugin(provider);
if (!plugin) return DEFAULT_ACCOUNT_ID;
return resolveChannelDefaultAccountId({ plugin, cfg });
@@ -90,7 +90,7 @@ function resolveDefaultAccountId(cfg: ClawdbotConfig, provider: ChannelId): stri
export function buildChannelBindings(params: {
agentId: string;
selection: ChannelChoice[];
config: ClawdbotConfig;
config: MoltbotConfig;
accountIds?: Partial<Record<ChannelChoice, string>>;
}): AgentBinding[] {
const bindings: AgentBinding[] = [];
@@ -114,7 +114,7 @@ export function buildChannelBindings(params: {
export function parseBindingSpecs(params: {
agentId: string;
specs?: string[];
config: ClawdbotConfig;
config: MoltbotConfig;
}): { bindings: AgentBinding[]; errors: string[] } {
const bindings: AgentBinding[] = [];
const errors: string[] = [];

View File

@@ -1,5 +1,5 @@
import { formatCliCommand } from "../cli/command-format.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { readConfigFileSnapshot } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
@@ -7,7 +7,7 @@ export function createQuietRuntime(runtime: RuntimeEnv): RuntimeEnv {
return { ...runtime, log: () => {} };
}
export async function requireValidConfig(runtime: RuntimeEnv): Promise<ClawdbotConfig | null> {
export async function requireValidConfig(runtime: RuntimeEnv): Promise<MoltbotConfig | null> {
const snapshot = await readConfigFileSnapshot();
if (snapshot.exists && !snapshot.valid) {
const issues =
@@ -15,7 +15,7 @@ export async function requireValidConfig(runtime: RuntimeEnv): Promise<ClawdbotC
? snapshot.issues.map((issue) => `- ${issue.path}: ${issue.message}`).join("\n")
: "Unknown validation issue.";
runtime.error(`Config invalid:\n${issues}`);
runtime.error(`Fix the config or run ${formatCliCommand("clawdbot doctor")}.`);
runtime.error(`Fix the config or run ${formatCliCommand("moltbot doctor")}.`);
runtime.exit(1);
return null;
}

View File

@@ -172,7 +172,7 @@ export async function agentsAddCommand(
const prompter = createClackPrompter();
try {
await prompter.intro("Add Clawdbot agent");
await prompter.intro("Add Moltbot agent");
const name =
nameInput ??
(await prompter.text({

View File

@@ -118,7 +118,7 @@ export async function agentsListCommand(
const lines = ["Agents:", ...summaries.map(formatSummary)];
lines.push("Routing rules map channel/account/peer to an agent. Use --bindings for full rules.");
lines.push(
`Channel status reflects local config/creds. For live health: ${formatCliCommand("clawdbot channels status --probe")}.`,
`Channel status reflects local config/creds. For live health: ${formatCliCommand("moltbot channels status --probe")}.`,
);
runtime.log(lines.join("\n"));
}

View File

@@ -9,7 +9,7 @@ import {
loadAgentIdentityFromWorkspace,
parseIdentityMarkdown as parseIdentityMarkdownFile,
} from "../agents/identity-file.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { normalizeAgentId } from "../routing/session-key.js";
export type AgentSummary = {
@@ -28,11 +28,11 @@ export type AgentSummary = {
isDefault: boolean;
};
type AgentEntry = NonNullable<NonNullable<ClawdbotConfig["agents"]>["list"]>[number];
type AgentEntry = NonNullable<NonNullable<MoltbotConfig["agents"]>["list"]>[number];
export type AgentIdentity = AgentIdentityFile;
export function listAgentEntries(cfg: ClawdbotConfig): AgentEntry[] {
export function listAgentEntries(cfg: MoltbotConfig): AgentEntry[] {
const list = cfg.agents?.list;
if (!Array.isArray(list)) return [];
return list.filter((entry): entry is AgentEntry => Boolean(entry && typeof entry === "object"));
@@ -43,14 +43,14 @@ export function findAgentEntryIndex(list: AgentEntry[], agentId: string): number
return list.findIndex((entry) => normalizeAgentId(entry.id) === id);
}
function resolveAgentName(cfg: ClawdbotConfig, agentId: string) {
function resolveAgentName(cfg: MoltbotConfig, agentId: string) {
const entry = listAgentEntries(cfg).find(
(agent) => normalizeAgentId(agent.id) === normalizeAgentId(agentId),
);
return entry?.name?.trim() || undefined;
}
function resolveAgentModel(cfg: ClawdbotConfig, agentId: string) {
function resolveAgentModel(cfg: MoltbotConfig, agentId: string) {
const entry = listAgentEntries(cfg).find(
(agent) => normalizeAgentId(agent.id) === normalizeAgentId(agentId),
);
@@ -78,7 +78,7 @@ export function loadAgentIdentity(workspace: string): AgentIdentity | null {
return identityHasValues(parsed) ? parsed : null;
}
export function buildAgentSummaries(cfg: ClawdbotConfig): AgentSummary[] {
export function buildAgentSummaries(cfg: MoltbotConfig): AgentSummary[] {
const defaultAgentId = normalizeAgentId(resolveDefaultAgentId(cfg));
const configuredAgents = listAgentEntries(cfg);
const orderedIds =
@@ -122,7 +122,7 @@ export function buildAgentSummaries(cfg: ClawdbotConfig): AgentSummary[] {
}
export function applyAgentConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
params: {
agentId: string;
name?: string;
@@ -130,7 +130,7 @@ export function applyAgentConfig(
agentDir?: string;
model?: string;
},
): ClawdbotConfig {
): MoltbotConfig {
const agentId = normalizeAgentId(params.agentId);
const name = params.name?.trim();
const list = listAgentEntries(cfg);
@@ -162,10 +162,10 @@ export function applyAgentConfig(
}
export function pruneAgentConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
agentId: string,
): {
config: ClawdbotConfig;
config: MoltbotConfig;
removedBindings: number;
removedAllow: number;
} {

View File

@@ -29,7 +29,7 @@ const runtime: RuntimeEnv = {
};
const baseSnapshot = {
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -49,7 +49,7 @@ describe("agents set-identity command", () => {
});
it("sets identity from workspace IDENTITY.md", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-identity-"));
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-identity-"));
const workspace = path.join(root, "work");
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(
@@ -92,7 +92,7 @@ describe("agents set-identity command", () => {
});
it("errors when multiple agents match the same workspace", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-identity-"));
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-identity-"));
const workspace = path.join(root, "shared");
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(path.join(workspace, "IDENTITY.md"), "- Name: Echo\n", "utf-8");
@@ -117,7 +117,7 @@ describe("agents set-identity command", () => {
});
it("overrides identity file values with explicit flags", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-identity-"));
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-identity-"));
const workspace = path.join(root, "work");
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(
@@ -161,7 +161,7 @@ describe("agents set-identity command", () => {
});
it("reads identity from an explicit IDENTITY.md path", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-identity-"));
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-identity-"));
const workspace = path.join(root, "work");
const identityPath = path.join(workspace, "IDENTITY.md");
await fs.mkdir(workspace, { recursive: true });
@@ -197,7 +197,7 @@ describe("agents set-identity command", () => {
});
it("accepts avatar-only identity from IDENTITY.md", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-identity-"));
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-identity-"));
const workspace = path.join(root, "work");
await fs.mkdir(workspace, { recursive: true });
await fs.writeFile(
@@ -243,7 +243,7 @@ describe("agents set-identity command", () => {
});
it("errors when identity data is missing", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-identity-"));
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-identity-"));
const workspace = path.join(root, "work");
await fs.mkdir(workspace, { recursive: true });

View File

@@ -5,7 +5,7 @@ import {
normalizeChannelId,
} from "../channels/plugins/index.js";
import type { ChannelId } from "../channels/plugins/types.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { AgentBinding } from "../config/types.js";
import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js";
@@ -43,7 +43,7 @@ function formatProviderState(entry: ProviderAccountStatus): string {
}
export async function buildProviderStatusIndex(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
): Promise<Map<string, ProviderAccountStatus>> {
const map = new Map<string, ProviderAccountStatus>();
@@ -91,13 +91,13 @@ export async function buildProviderStatusIndex(
return map;
}
function resolveDefaultAccountId(cfg: ClawdbotConfig, provider: ChannelId): string {
function resolveDefaultAccountId(cfg: MoltbotConfig, provider: ChannelId): string {
const plugin = getChannelPlugin(provider);
if (!plugin) return DEFAULT_ACCOUNT_ID;
return resolveChannelDefaultAccountId({ plugin, cfg });
}
function shouldShowProviderEntry(entry: ProviderAccountStatus, cfg: ClawdbotConfig): boolean {
function shouldShowProviderEntry(entry: ProviderAccountStatus, cfg: MoltbotConfig): boolean {
const plugin = getChannelPlugin(entry.provider);
if (!plugin) return Boolean(entry.configured);
if (plugin.meta.showConfigured === false) {
@@ -116,7 +116,7 @@ function formatProviderEntry(entry: ProviderAccountStatus): string {
return `${label}: ${formatProviderState(entry)}`;
}
export function summarizeBindings(cfg: ClawdbotConfig, bindings: AgentBinding[]): string[] {
export function summarizeBindings(cfg: MoltbotConfig, bindings: AgentBinding[]): string[] {
if (bindings.length === 0) return [];
const seen = new Map<string, string>();
for (const binding of bindings) {
@@ -137,7 +137,7 @@ export function summarizeBindings(cfg: ClawdbotConfig, bindings: AgentBinding[])
export function listProvidersForAgent(params: {
summaryIsDefault: boolean;
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
bindings: AgentBinding[];
providerStatus: Map<string, ProviderAccountStatus>;
}): string[] {

View File

@@ -3,7 +3,7 @@ import path from "node:path";
import { describe, expect, it } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import {
applyAgentBindings,
applyAgentConfig,
@@ -13,7 +13,7 @@ import {
describe("agents helpers", () => {
it("buildAgentSummaries includes default + configured agents", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
agents: {
defaults: {
workspace: "/main-ws",
@@ -59,7 +59,7 @@ describe("agents helpers", () => {
});
it("applyAgentConfig merges updates", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
agents: {
list: [{ id: "work", workspace: "/old-ws", model: "anthropic/claude" }],
},
@@ -80,7 +80,7 @@ describe("agents helpers", () => {
});
it("applyAgentBindings skips duplicates and reports conflicts", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
bindings: [
{
agentId: "main",
@@ -111,7 +111,7 @@ describe("agents helpers", () => {
});
it("pruneAgentConfig removes agent, bindings, and allowlist entries", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
agents: {
list: [
{ id: "work", default: true, workspace: "/work-ws" },

View File

@@ -1,4 +1,4 @@
import { resolveClawdbotAgentDir } from "../agents/agent-paths.js";
import { resolveMoltbotAgentDir } from "../agents/agent-paths.js";
import {
resolveDefaultAgentId,
resolveAgentDir,
@@ -7,7 +7,7 @@ import {
import { upsertAuthProfile } from "../agents/auth-profiles.js";
import { normalizeProviderId } from "../agents/model-selection.js";
import { resolveDefaultAgentWorkspaceDir } from "../agents/workspace.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { enablePluginInConfig } from "../plugins/enable.js";
import { resolvePluginProviders } from "../plugins/providers.js";
import type { ProviderAuthMethod, ProviderPlugin } from "../plugins/types.js";
@@ -72,7 +72,7 @@ function mergeConfigPatch<T>(base: T, patch: unknown): T {
return next as T;
}
function applyDefaultModel(cfg: ClawdbotConfig, model: string): ClawdbotConfig {
function applyDefaultModel(cfg: MoltbotConfig, model: string): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[model] = models[model] ?? {};
@@ -115,7 +115,7 @@ export async function applyAuthChoicePluginProvider(
const defaultAgentId = resolveDefaultAgentId(nextConfig);
const agentDir =
params.agentDir ??
(agentId === defaultAgentId ? resolveClawdbotAgentDir() : resolveAgentDir(nextConfig, agentId));
(agentId === defaultAgentId ? resolveMoltbotAgentDir() : resolveAgentDir(nextConfig, agentId));
const workspaceDir =
resolveAgentWorkspaceDir(nextConfig, agentId) ?? resolveDefaultAgentWorkspaceDir();

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { applyAuthChoiceAnthropic } from "./auth-choice.apply.anthropic.js";
@@ -15,7 +15,7 @@ import type { AuthChoice } from "./onboard-types.js";
export type ApplyAuthChoiceParams = {
authChoice: AuthChoice;
config: ClawdbotConfig;
config: MoltbotConfig;
prompter: WizardPrompter;
runtime: RuntimeEnv;
agentDir?: string;
@@ -28,7 +28,7 @@ export type ApplyAuthChoiceParams = {
};
export type ApplyAuthChoiceResult = {
config: ClawdbotConfig;
config: MoltbotConfig;
agentModelOverride?: string;
};

View File

@@ -1,16 +1,16 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { WizardPrompter } from "../wizard/prompts.js";
export async function applyDefaultModelChoice(params: {
config: ClawdbotConfig;
config: MoltbotConfig;
setDefaultModel: boolean;
defaultModel: string;
applyDefaultConfig: (config: ClawdbotConfig) => ClawdbotConfig;
applyProviderConfig: (config: ClawdbotConfig) => ClawdbotConfig;
applyDefaultConfig: (config: MoltbotConfig) => MoltbotConfig;
applyProviderConfig: (config: MoltbotConfig) => MoltbotConfig;
noteDefault?: string;
noteAgentModel: (model: string) => Promise<void>;
prompter: WizardPrompter;
}): Promise<{ config: ClawdbotConfig; agentModelOverride?: string }> {
}): Promise<{ config: MoltbotConfig; agentModelOverride?: string }> {
if (params.setDefaultModel) {
const next = params.applyDefaultConfig(params.config);
if (params.noteDefault) {

View File

@@ -4,12 +4,12 @@ import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
import { getCustomProviderApiKey, resolveEnvApiKey } from "../agents/model-auth.js";
import { loadModelCatalog } from "../agents/model-catalog.js";
import { resolveConfiguredModelRef } from "../agents/model-selection.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { OPENAI_CODEX_DEFAULT_MODEL } from "./openai-codex-model-default.js";
export async function warnIfModelConfigLooksOff(
config: ClawdbotConfig,
config: MoltbotConfig,
prompter: WizardPrompter,
options?: { agentId?: string; agentDir?: string },
) {

View File

@@ -82,7 +82,7 @@ describe("applyAuthChoice", () => {
});
it("prompts and writes MiniMax API key when selecting minimax-api", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -135,7 +135,7 @@ describe("applyAuthChoice", () => {
});
it("prompts and writes Synthetic API key when selecting synthetic-api-key", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -188,7 +188,7 @@ describe("applyAuthChoice", () => {
});
it("sets default model when selecting github-copilot", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -231,7 +231,7 @@ describe("applyAuthChoice", () => {
});
it("does not override the default model when selecting opencode-zen without setDefaultModel", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -282,7 +282,7 @@ describe("applyAuthChoice", () => {
});
it("uses existing OPENROUTER_API_KEY when selecting openrouter-api-key", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -343,7 +343,7 @@ describe("applyAuthChoice", () => {
});
it("uses existing AI_GATEWAY_API_KEY when selecting ai-gateway-api-key", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -406,7 +406,7 @@ describe("applyAuthChoice", () => {
});
it("writes Chutes OAuth credentials when selecting chutes (remote/manual)", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -493,7 +493,7 @@ describe("applyAuthChoice", () => {
});
it("writes Qwen credentials when selecting qwen-portal", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-auth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;

View File

@@ -50,7 +50,7 @@ const runtime: RuntimeEnv = {
};
const baseSnapshot = {
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -370,7 +370,7 @@ describe("channels command", () => {
});
expect(lines.join("\n")).toMatch(/Warnings:/);
expect(lines.join("\n")).toMatch(/Message Content Intent is disabled/i);
expect(lines.join("\n")).toMatch(/Run: (?:clawdbot|moltbot)( --profile isolated)? doctor/);
expect(lines.join("\n")).toMatch(/Run: (?:moltbot|moltbot)( --profile isolated)? doctor/);
});
it("surfaces Discord permission audit issues in channels status output", () => {
@@ -425,12 +425,12 @@ describe("channels command", () => {
accountId: "default",
enabled: true,
configured: true,
probe: { ok: true, bot: { username: "clawdbot_bot" } },
probe: { ok: true, bot: { username: "moltbot_bot" } },
},
],
},
});
expect(lines.join("\n")).toMatch(/bot:@clawdbot_bot/);
expect(lines.join("\n")).toMatch(/bot:@moltbot_bot/);
});
it("surfaces Telegram group membership audit issues in channels status output", () => {

View File

@@ -40,7 +40,7 @@ const runtime: RuntimeEnv = {
};
const _baseSnapshot = {
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},

View File

@@ -1,16 +1,16 @@
import { getChannelPlugin } from "../../channels/plugins/index.js";
import type { ChannelId, ChannelSetupInput } from "../../channels/plugins/types.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import { normalizeAccountId } from "../../routing/session-key.js";
type ChatChannel = ChannelId;
export function applyAccountName(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
channel: ChatChannel;
accountId: string;
name?: string;
}): ClawdbotConfig {
}): MoltbotConfig {
const accountId = normalizeAccountId(params.accountId);
const plugin = getChannelPlugin(params.channel);
const apply = plugin?.setup?.applyAccountName;
@@ -18,7 +18,7 @@ export function applyAccountName(params: {
}
export function applyChannelAccountConfig(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
channel: ChatChannel;
accountId: string;
name?: string;
@@ -52,7 +52,7 @@ export function applyChannelAccountConfig(params: {
groupChannels?: string[];
dmAllowlist?: string[];
autoDiscoverChannels?: boolean;
}): ClawdbotConfig {
}): MoltbotConfig {
const accountId = normalizeAccountId(params.accountId);
const plugin = getChannelPlugin(params.channel);
const apply = plugin?.setup?.applyAccountConfig;

View File

@@ -2,7 +2,7 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/ag
import { listChannelPluginCatalogEntries } from "../../channels/plugins/catalog.js";
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
import type { ChannelId } from "../../channels/plugins/types.js";
import { writeConfigFile, type ClawdbotConfig } from "../../config/config.js";
import { writeConfigFile, type MoltbotConfig } from "../../config/config.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
import { createClackPrompter } from "../../wizard/clack-prompter.js";
@@ -60,7 +60,7 @@ function parseList(value: string | undefined): string[] | undefined {
return parsed.length > 0 ? parsed : undefined;
}
function resolveCatalogChannelEntry(raw: string, cfg: ClawdbotConfig | null) {
function resolveCatalogChannelEntry(raw: string, cfg: MoltbotConfig | null) {
const trimmed = raw.trim().toLowerCase();
if (!trimmed) return undefined;
const workspaceDir = cfg ? resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg)) : undefined;

View File

@@ -89,7 +89,7 @@ describe("channelsCapabilitiesCommand", () => {
botToken: "xoxb-bot",
config: { userToken: "xoxp-user" },
},
probe: { ok: true, bot: { name: "clawdbot" }, team: { name: "team" } },
probe: { ok: true, bot: { name: "moltbot" }, team: { name: "team" } },
});
vi.mocked(listChannelPlugins).mockReturnValue([plugin]);
vi.mocked(getChannelPlugin).mockReturnValue(plugin);

View File

@@ -4,7 +4,7 @@ import type { ChannelCapabilities, ChannelPlugin } from "../../channels/plugins/
import { fetchChannelPermissionsDiscord } from "../../discord/send.js";
import { parseDiscordTarget } from "../../discord/targets.js";
import { danger } from "../../globals.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
import { fetchSlackScopes, type SlackScopesResult } from "../../slack/scopes.js";
import { theme } from "../../terminal/theme.js";
@@ -291,7 +291,7 @@ async function buildDiscordPermissions(params: {
async function resolveChannelReports(params: {
plugin: ChannelPlugin;
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
timeoutMs: number;
accountOverride?: string;
target?: string;

View File

@@ -4,7 +4,7 @@ import {
listChannelPlugins,
normalizeChannelId,
} from "../../channels/plugins/index.js";
import { type ClawdbotConfig, writeConfigFile } from "../../config/config.js";
import { type MoltbotConfig, writeConfigFile } from "../../config/config.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
import { createClackPrompter } from "../../wizard/clack-prompter.js";
@@ -16,7 +16,7 @@ export type ChannelsRemoveOptions = {
delete?: boolean;
};
function listAccountIds(cfg: ClawdbotConfig, channel: ChatChannel): string[] {
function listAccountIds(cfg: MoltbotConfig, channel: ChatChannel): string[] {
const plugin = getChannelPlugin(channel);
if (!plugin) return [];
return plugin.config.listAccountIds(cfg);

View File

@@ -1,6 +1,6 @@
import { type ChannelId, getChannelPlugin } from "../../channels/plugins/index.js";
import { formatCliCommand } from "../../cli/command-format.js";
import { type ClawdbotConfig, readConfigFileSnapshot } from "../../config/config.js";
import { type MoltbotConfig, readConfigFileSnapshot } from "../../config/config.js";
import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
@@ -8,7 +8,7 @@ export type ChatChannel = ChannelId;
export async function requireValidConfig(
runtime: RuntimeEnv = defaultRuntime,
): Promise<ClawdbotConfig | null> {
): Promise<MoltbotConfig | null> {
const snapshot = await readConfigFileSnapshot();
if (snapshot.exists && !snapshot.valid) {
const issues =
@@ -16,7 +16,7 @@ export async function requireValidConfig(
? snapshot.issues.map((issue) => `- ${issue.path}: ${issue.message}`).join("\n")
: "Unknown validation issue.";
runtime.error(`Config invalid:\n${issues}`);
runtime.error(`Fix the config or run ${formatCliCommand("clawdbot doctor")}.`);
runtime.error(`Fix the config or run ${formatCliCommand("moltbot doctor")}.`);
runtime.exit(1);
return null;
}

View File

@@ -2,7 +2,7 @@ import { listChannelPlugins } from "../../channels/plugins/index.js";
import { buildChannelAccountSnapshot } from "../../channels/plugins/status.js";
import type { ChannelAccountSnapshot } from "../../channels/plugins/types.js";
import { withProgress } from "../../cli/progress.js";
import { type ClawdbotConfig, readConfigFileSnapshot } from "../../config/config.js";
import { type MoltbotConfig, readConfigFileSnapshot } from "../../config/config.js";
import { callGateway } from "../../gateway/call.js";
import { formatAge } from "../../infra/channel-summary.js";
import { collectChannelStatusIssues } from "../../infra/channels-status-issues.js";
@@ -143,7 +143,7 @@ export function formatGatewayChannelsStatusLines(payload: Record<string, unknown
`- ${issue.channel} ${issue.accountId}: ${issue.message}${issue.fix ? ` (${issue.fix})` : ""}`,
);
}
lines.push(`- Run: ${formatCliCommand("clawdbot doctor")}`);
lines.push(`- Run: ${formatCliCommand("moltbot doctor")}`);
lines.push("");
}
lines.push(
@@ -153,7 +153,7 @@ export function formatGatewayChannelsStatusLines(payload: Record<string, unknown
}
async function formatConfigChannelsStatusLines(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
meta: { path?: string; mode?: "local" | "remote" },
): Promise<string[]> {
const lines: string[] = [];

View File

@@ -84,7 +84,7 @@ async function waitForLocalCallback(params: {
"<!doctype html>",
"<html><head><meta charset='utf-8' /></head>",
"<body><h2>Chutes OAuth complete</h2>",
"<p>You can close this window and return to clawdbot.</p></body></html>",
"<p>You can close this window and return to moltbot.</p></body></html>",
].join(""),
);
if (timeout) clearTimeout(timeout);

View File

@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
import path from "node:path";
import { resolveDefaultAgentWorkspaceDir } from "../agents/workspace.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import { resolveHomeDir, resolveUserPath, shortenHomeInString } from "../utils.js";
@@ -11,7 +11,7 @@ export type RemovalResult = {
skipped?: boolean;
};
export function collectWorkspaceDirs(cfg: ClawdbotConfig | undefined): string[] {
export function collectWorkspaceDirs(cfg: MoltbotConfig | undefined): string[] {
const dirs = new Set<string>();
const defaults = cfg?.agents?.defaults;
if (typeof defaults?.workspace === "string" && defaults.workspace.trim()) {

View File

@@ -1,7 +1,7 @@
import { getChannelPlugin, listChannelPlugins } from "../channels/plugins/index.js";
import { formatCliCommand } from "../cli/command-format.js";
import type { ClawdbotConfig } from "../config/config.js";
import { CONFIG_PATH_CLAWDBOT } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { CONFIG_PATH } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import { note } from "../terminal/note.js";
import { shortenHomePath } from "../utils.js";
@@ -9,9 +9,9 @@ import { confirm, select } from "./configure.shared.js";
import { guardCancel } from "./onboard-helpers.js";
export async function removeChannelConfigWizard(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
runtime: RuntimeEnv,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
let next = { ...cfg };
const listConfiguredChannels = () =>
@@ -24,8 +24,8 @@ export async function removeChannelConfigWizard(
if (configured.length === 0) {
note(
[
"No channel config found in clawdbot.json.",
`Tip: \`${formatCliCommand("clawdbot channels status")}\` shows what is configured and enabled.`,
"No channel config found in moltbot.json.",
`Tip: \`${formatCliCommand("moltbot channels status")}\` shows what is configured and enabled.`,
].join("\n"),
"Remove channel",
);
@@ -52,7 +52,7 @@ export async function removeChannelConfigWizard(
const label = getChannelPlugin(channel)?.meta.label ?? channel;
const confirmed = guardCancel(
await confirm({
message: `Delete ${label} configuration from ${shortenHomePath(CONFIG_PATH_CLAWDBOT)}?`,
message: `Delete ${label} configuration from ${shortenHomePath(CONFIG_PATH)}?`,
initialValue: false,
}),
runtime,
@@ -64,7 +64,7 @@ export async function removeChannelConfigWizard(
next = {
...next,
channels: Object.keys(nextChannels).length
? (nextChannels as ClawdbotConfig["channels"])
? (nextChannels as MoltbotConfig["channels"])
: undefined,
};

View File

@@ -1,5 +1,5 @@
import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
import type { ClawdbotConfig, GatewayAuthConfig } from "../config/config.js";
import type { MoltbotConfig, GatewayAuthConfig } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { applyAuthChoice, resolvePreferredProviderForAuthChoice } from "./auth-choice.js";
@@ -37,10 +37,10 @@ export function buildGatewayAuthConfig(params: {
}
export async function promptAuthConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
runtime: RuntimeEnv,
prompter: WizardPrompter,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
const authChoice = await promptAuthChoiceGrouped({
prompter,
store: ensureAuthProfileStore(undefined, {

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { resolveGatewayPort } from "../config/config.js";
import { findTailscaleBinary } from "../infra/tailscale.js";
import type { RuntimeEnv } from "../runtime.js";
@@ -10,10 +10,10 @@ import { guardCancel, randomToken } from "./onboard-helpers.js";
type GatewayAuthChoice = "token" | "password";
export async function promptGatewayConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
runtime: RuntimeEnv,
): Promise<{
config: ClawdbotConfig;
config: MoltbotConfig;
port: number;
token?: string;
}> {

View File

@@ -1,6 +1,6 @@
import { describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
const mocks = vi.hoisted(() => ({
clackIntro: vi.fn(),
@@ -30,7 +30,7 @@ vi.mock("@clack/prompts", () => ({
}));
vi.mock("../config/config.js", () => ({
CONFIG_PATH_CLAWDBOT: "~/.clawdbot/clawdbot.json",
CONFIG_PATH: "~/.clawdbot/moltbot.json",
readConfigFileSnapshot: mocks.readConfigFileSnapshot,
writeConfigFile: mocks.writeConfigFile,
resolveGatewayPort: mocks.resolveGatewayPort,
@@ -50,7 +50,7 @@ vi.mock("../terminal/note.js", () => ({
vi.mock("./onboard-helpers.js", () => ({
DEFAULT_WORKSPACE: "~/.clawdbot/workspace",
applyWizardMetadata: (cfg: ClawdbotConfig) => cfg,
applyWizardMetadata: (cfg: MoltbotConfig) => cfg,
ensureWorkspaceAndSessions: vi.fn(),
guardCancel: <T>(value: T) => value,
printWizardHeader: mocks.printWizardHeader,

View File

@@ -1,5 +1,5 @@
import { formatCliCommand } from "../cli/command-format.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { readConfigFileSnapshot, resolveGatewayPort, writeConfigFile } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import { ensureControlUiAssetsBuilt } from "../infra/control-ui-assets.js";
@@ -79,7 +79,7 @@ async function promptChannelMode(runtime: RuntimeEnv): Promise<ChannelsWizardMod
{
value: "remove",
label: "Remove channel config",
hint: "Delete channel tokens/settings from clawdbot.json",
hint: "Delete channel tokens/settings from moltbot.json",
},
],
initialValue: "configure",
@@ -89,9 +89,9 @@ async function promptChannelMode(runtime: RuntimeEnv): Promise<ChannelsWizardMod
}
async function promptWebToolsConfig(
nextConfig: ClawdbotConfig,
nextConfig: MoltbotConfig,
runtime: RuntimeEnv,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
const existingSearch = nextConfig.tools?.web?.search;
const existingFetch = nextConfig.tools?.web?.fetch;
const hasSearchKey = Boolean(existingSearch?.apiKey);
@@ -175,11 +175,11 @@ export async function runConfigureWizard(
) {
try {
printWizardHeader(runtime);
intro(opts.command === "update" ? "Clawdbot update wizard" : "Clawdbot configure");
intro(opts.command === "update" ? "Moltbot update wizard" : "Moltbot configure");
const prompter = createClackPrompter();
const snapshot = await readConfigFileSnapshot();
const baseConfig: ClawdbotConfig = snapshot.valid ? snapshot.config : {};
const baseConfig: MoltbotConfig = snapshot.valid ? snapshot.config : {};
if (snapshot.exists) {
const title = snapshot.valid ? "Existing config detected" : "Invalid config";
@@ -196,7 +196,7 @@ export async function runConfigureWizard(
}
if (!snapshot.valid) {
outro(
`Config invalid. Run \`${formatCliCommand("clawdbot doctor")}\` to repair it, then re-run configure.`,
`Config invalid. Run \`${formatCliCommand("moltbot doctor")}\` to repair it, then re-run configure.`,
);
runtime.exit(1);
return;

View File

@@ -34,11 +34,11 @@ afterEach(() => {
describe("resolveGatewayDevMode", () => {
it("detects dev mode for src ts entrypoints", () => {
expect(resolveGatewayDevMode(["node", "/Users/me/clawdbot/src/cli/index.ts"])).toBe(true);
expect(resolveGatewayDevMode(["node", "C:\\Users\\me\\clawdbot\\src\\cli\\index.ts"])).toBe(
expect(resolveGatewayDevMode(["node", "/Users/me/moltbot/src/cli/index.ts"])).toBe(true);
expect(resolveGatewayDevMode(["node", "C:\\Users\\me\\moltbot\\src\\cli\\index.ts"])).toBe(
true,
);
expect(resolveGatewayDevMode(["node", "/Users/me/clawdbot/dist/cli/index.js"])).toBe(false);
expect(resolveGatewayDevMode(["node", "/Users/me/moltbot/dist/cli/index.js"])).toBe(false);
});
});
@@ -235,7 +235,7 @@ describe("gatewayInstallErrorHint", () => {
it("returns platform-specific hints", () => {
expect(gatewayInstallErrorHint("win32")).toContain("Run as administrator");
expect(gatewayInstallErrorHint("linux")).toMatch(
/(?:clawdbot|moltbot)( --profile isolated)? gateway install/,
/(?:moltbot|moltbot)( --profile isolated)? gateway install/,
);
});
});

View File

@@ -8,7 +8,7 @@ import {
import { buildServiceEnvironment } from "../daemon/service-env.js";
import { formatCliCommand } from "../cli/command-format.js";
import { collectConfigEnvVars } from "../config/env-vars.js";
import type { ClawdbotConfig } from "../config/types.js";
import type { MoltbotConfig } from "../config/types.js";
import type { GatewayDaemonRuntime } from "./daemon-runtime.js";
type WarnFn = (message: string, title?: string) => void;
@@ -34,7 +34,7 @@ export async function buildGatewayInstallPlan(params: {
nodePath?: string;
warn?: WarnFn;
/** Full config to extract env vars from (env vars + inline env keys). */
config?: ClawdbotConfig;
config?: MoltbotConfig;
}): Promise<GatewayInstallPlan> {
const devMode = params.devMode ?? resolveGatewayDevMode();
const nodePath =
@@ -77,5 +77,5 @@ export async function buildGatewayInstallPlan(params: {
export function gatewayInstallErrorHint(platform = process.platform): string {
return platform === "win32"
? "Tip: rerun from an elevated PowerShell (Start → type PowerShell → right-click → Run as administrator) or skip service install."
: `Tip: rerun \`${formatCliCommand("clawdbot gateway install")}\` after fixing the error.`;
: `Tip: rerun \`${formatCliCommand("moltbot gateway install")}\` after fixing the error.`;
}

View File

@@ -42,7 +42,7 @@ function resetRuntime() {
function mockSnapshot(token = "abc") {
mocks.readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -87,7 +87,7 @@ describe("dashboardCommand", () => {
expect(mocks.copyToClipboard).toHaveBeenCalledWith("http://127.0.0.1:18789/?token=abc123");
expect(mocks.openUrl).toHaveBeenCalledWith("http://127.0.0.1:18789/?token=abc123");
expect(runtime.log).toHaveBeenCalledWith(
"Opened in your browser. Keep that tab to control Clawdbot.",
"Opened in your browser. Keep that tab to control Moltbot.",
);
});

View File

@@ -57,7 +57,7 @@ export async function dashboardCommand(
}
if (opened) {
runtime.log("Opened in your browser. Keep that tab to control Clawdbot.");
runtime.log("Opened in your browser. Keep that tab to control Moltbot.");
} else if (hint) {
runtime.log(hint);
}

View File

@@ -5,7 +5,7 @@ import { formatDocsLink } from "../terminal/links.js";
import { isRich, theme } from "../terminal/theme.js";
import { formatCliCommand } from "../cli/command-format.js";
const SEARCH_TOOL = "https://docs.molt.bot/mcp.SearchClawdbot";
const SEARCH_TOOL = "https://docs.molt.bot/mcp.SearchMoltbot";
const SEARCH_TIMEOUT_MS = 30_000;
const DEFAULT_SNIPPET_MAX = 220;
@@ -151,10 +151,10 @@ export async function docsSearchCommand(queryParts: string[], runtime: RuntimeEn
const docs = formatDocsLink("/", "docs.molt.bot");
if (isRich()) {
runtime.log(`${theme.muted("Docs:")} ${docs}`);
runtime.log(`${theme.muted("Search:")} ${formatCliCommand('clawdbot docs "your query"')}`);
runtime.log(`${theme.muted("Search:")} ${formatCliCommand('moltbot docs "your query"')}`);
} else {
runtime.log("Docs: https://docs.molt.bot/");
runtime.log(`Search: ${formatCliCommand('clawdbot docs "your query"')}`);
runtime.log(`Search: ${formatCliCommand('moltbot docs "your query"')}`);
}
return;
}

View File

@@ -26,7 +26,7 @@ function makePrompter(confirmValue: boolean): DoctorPrompter {
beforeEach(() => {
originalAgentDir = process.env.CLAWDBOT_AGENT_DIR;
originalPiAgentDir = process.env.PI_CODING_AGENT_DIR;
tempAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-auth-"));
tempAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-auth-"));
process.env.CLAWDBOT_AGENT_DIR = tempAgentDir;
process.env.PI_CODING_AGENT_DIR = tempAgentDir;
});

View File

@@ -12,15 +12,15 @@ import {
resolveProfileUnusableUntilForDisplay,
} from "../agents/auth-profiles.js";
import { updateAuthProfileStoreWithLock } from "../agents/auth-profiles/store.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { note } from "../terminal/note.js";
import { formatCliCommand } from "../cli/command-format.js";
import type { DoctorPrompter } from "./doctor-prompter.js";
export async function maybeRepairAnthropicOAuthProfileId(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
prompter: DoctorPrompter,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
const store = ensureAuthProfileStore();
const repair = repairOAuthProfileIdMismatch({
cfg,
@@ -55,9 +55,9 @@ function pruneAuthOrder(
}
function pruneAuthProfiles(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
profileIds: Set<string>,
): { next: ClawdbotConfig; changed: boolean } {
): { next: MoltbotConfig; changed: boolean } {
const profiles = cfg.auth?.profiles;
const order = cfg.auth?.order;
const nextProfiles = profiles ? { ...profiles } : undefined;
@@ -96,9 +96,9 @@ function pruneAuthProfiles(
}
export async function maybeRemoveDeprecatedCliAuthProfiles(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
prompter: DoctorPrompter,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
const store = ensureAuthProfileStore(undefined, { allowKeychainPrompt: false });
const deprecated = new Set<string>();
if (store.profiles[CLAUDE_CLI_PROFILE_ID] || cfg.auth?.profiles?.[CLAUDE_CLI_PROFILE_ID]) {
@@ -113,13 +113,13 @@ export async function maybeRemoveDeprecatedCliAuthProfiles(
const lines = ["Deprecated external CLI auth profiles detected (no longer supported):"];
if (deprecated.has(CLAUDE_CLI_PROFILE_ID)) {
lines.push(
`- ${CLAUDE_CLI_PROFILE_ID} (Anthropic): use setup-token → ${formatCliCommand("clawdbot models auth setup-token")}`,
`- ${CLAUDE_CLI_PROFILE_ID} (Anthropic): use setup-token → ${formatCliCommand("moltbot models auth setup-token")}`,
);
}
if (deprecated.has(CODEX_CLI_PROFILE_ID)) {
lines.push(
`- ${CODEX_CLI_PROFILE_ID} (OpenAI Codex): use OAuth → ${formatCliCommand(
"clawdbot models auth login --provider openai-codex",
"moltbot models auth login --provider openai-codex",
)}`,
);
}
@@ -190,16 +190,16 @@ type AuthIssue = {
function formatAuthIssueHint(issue: AuthIssue): string | null {
if (issue.provider === "anthropic" && issue.profileId === CLAUDE_CLI_PROFILE_ID) {
return `Deprecated profile. Use ${formatCliCommand("clawdbot models auth setup-token")} or ${formatCliCommand(
"clawdbot configure",
return `Deprecated profile. Use ${formatCliCommand("moltbot models auth setup-token")} or ${formatCliCommand(
"moltbot configure",
)}.`;
}
if (issue.provider === "openai-codex" && issue.profileId === CODEX_CLI_PROFILE_ID) {
return `Deprecated profile. Use ${formatCliCommand(
"clawdbot models auth login --provider openai-codex",
)} or ${formatCliCommand("clawdbot configure")}.`;
"moltbot models auth login --provider openai-codex",
)} or ${formatCliCommand("moltbot configure")}.`;
}
return `Re-auth via \`${formatCliCommand("clawdbot configure")}\` or \`${formatCliCommand("clawdbot onboard")}\`.`;
return `Re-auth via \`${formatCliCommand("moltbot configure")}\` or \`${formatCliCommand("moltbot onboard")}\`.`;
}
function formatAuthIssueLine(issue: AuthIssue): string {
@@ -210,7 +210,7 @@ function formatAuthIssueLine(issue: AuthIssue): string {
}
export async function noteAuthProfileHealth(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
prompter: DoctorPrompter;
allowKeychainPrompt: boolean;
}): Promise<void> {

View File

@@ -12,7 +12,7 @@ describe("doctor config flow", () => {
const configDir = path.join(home, ".clawdbot");
await fs.mkdir(configDir, { recursive: true });
await fs.writeFile(
path.join(configDir, "clawdbot.json"),
path.join(configDir, "moltbot.json"),
JSON.stringify(
{
gateway: { auth: { mode: "token", token: 123 } },
@@ -40,7 +40,7 @@ describe("doctor config flow", () => {
const configDir = path.join(home, ".clawdbot");
await fs.mkdir(configDir, { recursive: true });
await fs.writeFile(
path.join(configDir, "clawdbot.json"),
path.join(configDir, "moltbot.json"),
JSON.stringify(
{
bridge: { bind: "auto" },

View File

@@ -1,9 +1,9 @@
import type { ZodIssue } from "zod";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import {
ClawdbotSchema,
CONFIG_PATH_CLAWDBOT,
MoltbotSchema,
CONFIG_PATH,
migrateLegacyConfig,
readConfigFileSnapshot,
} from "../config/config.js";
@@ -60,16 +60,16 @@ function resolvePathTarget(root: unknown, path: Array<string | number>): unknown
return current;
}
function stripUnknownConfigKeys(config: ClawdbotConfig): {
config: ClawdbotConfig;
function stripUnknownConfigKeys(config: MoltbotConfig): {
config: MoltbotConfig;
removed: string[];
} {
const parsed = ClawdbotSchema.safeParse(config);
const parsed = MoltbotSchema.safeParse(config);
if (parsed.success) {
return { config, removed: [] };
}
const next = structuredClone(config) as ClawdbotConfig;
const next = structuredClone(config) as MoltbotConfig;
const removed: string[] = [];
for (const issue of parsed.error.issues) {
if (!isUnrecognizedKeysIssue(issue)) continue;
@@ -88,7 +88,7 @@ function stripUnknownConfigKeys(config: ClawdbotConfig): {
return { config: next, removed };
}
function noteOpencodeProviderOverrides(cfg: ClawdbotConfig) {
function noteOpencodeProviderOverrides(cfg: MoltbotConfig) {
const providers = cfg.models?.providers;
if (!providers) return;
@@ -124,8 +124,8 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
const shouldRepair = params.options.repair === true || params.options.yes === true;
const snapshot = await readConfigFileSnapshot();
const baseCfg = snapshot.config ?? {};
let cfg: ClawdbotConfig = baseCfg;
let candidate = structuredClone(baseCfg) as ClawdbotConfig;
let cfg: MoltbotConfig = baseCfg;
let candidate = structuredClone(baseCfg) as MoltbotConfig;
let pendingChanges = false;
let shouldWriteConfig = false;
const fixHints: string[] = [];
@@ -156,7 +156,7 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
if (migrated) cfg = migrated;
} else {
fixHints.push(
`Run "${formatCliCommand("clawdbot doctor --fix")}" to apply legacy migrations.`,
`Run "${formatCliCommand("moltbot doctor --fix")}" to apply legacy migrations.`,
);
}
}
@@ -169,7 +169,7 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
if (shouldRepair) {
cfg = normalized.config;
} else {
fixHints.push(`Run "${formatCliCommand("clawdbot doctor --fix")}" to apply these changes.`);
fixHints.push(`Run "${formatCliCommand("moltbot doctor --fix")}" to apply these changes.`);
}
}
@@ -181,7 +181,7 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
if (shouldRepair) {
cfg = autoEnable.config;
} else {
fixHints.push(`Run "${formatCliCommand("clawdbot doctor --fix")}" to apply these changes.`);
fixHints.push(`Run "${formatCliCommand("moltbot doctor --fix")}" to apply these changes.`);
}
}
@@ -195,7 +195,7 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
note(lines, "Doctor changes");
} else {
note(lines, "Unknown config keys");
fixHints.push('Run "clawdbot doctor --fix" to remove these keys.');
fixHints.push('Run "moltbot doctor --fix" to remove these keys.');
}
}
@@ -214,5 +214,5 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
noteOpencodeProviderOverrides(cfg);
return { cfg, path: snapshot.path ?? CONFIG_PATH_CLAWDBOT, shouldWriteConfig };
return { cfg, path: snapshot.path ?? CONFIG_PATH, shouldWriteConfig };
}

View File

@@ -70,10 +70,10 @@ export function buildGatewayRuntimeHints(
hints.push(
`LaunchAgent label cached but plist missing. Clear with: launchctl bootout gui/$UID/${label}`,
);
hints.push(`Then reinstall: ${formatCliCommand("clawdbot gateway install", env)}`);
hints.push(`Then reinstall: ${formatCliCommand("moltbot gateway install", env)}`);
}
if (runtime.missingUnit) {
hints.push(`Service not installed. Run: ${formatCliCommand("clawdbot gateway install", env)}`);
hints.push(`Service not installed. Run: ${formatCliCommand("moltbot gateway install", env)}`);
if (fileLog) hints.push(`File logs: ${fileLog}`);
return hints;
}

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { resolveGatewayPort } from "../config/config.js";
import {
resolveGatewayLaunchAgentLabel,
@@ -76,7 +76,7 @@ async function maybeRepairLaunchAgentBootstrap(params: {
}
export async function maybeRepairGatewayDaemon(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
runtime: RuntimeEnv;
prompter: DoctorPrompter;
options: DoctorOptions;
@@ -209,7 +209,7 @@ export async function maybeRepairGatewayDaemon(params: {
if (process.platform === "darwin") {
const label = resolveGatewayLaunchAgentLabel(process.env.CLAWDBOT_PROFILE);
note(
`LaunchAgent loaded; stopping requires "${formatCliCommand("clawdbot gateway stop")}" or launchctl bootout gui/$UID/${label}.`,
`LaunchAgent loaded; stopping requires "${formatCliCommand("moltbot gateway stop")}" or launchctl bootout gui/$UID/${label}.`,
"Gateway",
);
}

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { buildGatewayConnectionDetails, callGateway } from "../gateway/call.js";
import { collectChannelStatusIssues } from "../infra/channels-status-issues.js";
import type { RuntimeEnv } from "../runtime.js";
@@ -8,7 +8,7 @@ import { formatHealthCheckFailure } from "./health-format.js";
export async function checkGatewayHealth(params: {
runtime: RuntimeEnv;
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
timeoutMs?: number;
}) {
const gatewayDetails = buildGatewayConnectionDetails({ config: params.cfg });

View File

@@ -1,6 +1,6 @@
import path from "node:path";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { resolveGatewayPort, resolveIsNixMode } from "../config/paths.js";
import { findExtraGatewayServices, renderGatewayServiceCleanupHints } from "../daemon/inspect.js";
import { findLegacyGatewayServices, uninstallLegacyGatewayServices } from "../daemon/legacy.js";
@@ -43,7 +43,7 @@ function normalizeExecutablePath(value: string): string {
}
export async function maybeMigrateLegacyGatewayService(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
mode: "local" | "remote",
runtime: RuntimeEnv,
prompter: DoctorPrompter,
@@ -57,7 +57,7 @@ export async function maybeMigrateLegacyGatewayService(
);
const migrate = await prompter.confirmSkipInNonInteractive({
message: "Migrate legacy gateway services to Clawdbot now?",
message: "Migrate legacy gateway services to Moltbot now?",
initialValue: true,
});
if (!migrate) return;
@@ -85,12 +85,12 @@ export async function maybeMigrateLegacyGatewayService(
const service = resolveGatewayService();
const loaded = await service.isLoaded({ env: process.env });
if (loaded) {
note(`Clawdbot ${service.label} already ${service.loadedText}.`, "Gateway");
note(`Moltbot ${service.label} already ${service.loadedText}.`, "Gateway");
return;
}
const install = await prompter.confirmSkipInNonInteractive({
message: "Install Clawdbot gateway service now?",
message: "Install Moltbot gateway service now?",
initialValue: true,
});
if (!install) return;
@@ -127,7 +127,7 @@ export async function maybeMigrateLegacyGatewayService(
}
export async function maybeRepairGatewayServiceConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
mode: "local" | "remote",
runtime: RuntimeEnv,
prompter: DoctorPrompter,

View File

@@ -16,7 +16,7 @@ describe("normalizeLegacyConfigValues", () => {
beforeEach(() => {
previousOauthDir = process.env.CLAWDBOT_OAUTH_DIR;
tempOauthDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-oauth-"));
tempOauthDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-oauth-"));
process.env.CLAWDBOT_OAUTH_DIR = tempOauthDir;
});
@@ -94,7 +94,7 @@ describe("normalizeLegacyConfigValues", () => {
});
it("copies legacy ack reaction when authDir override exists", () => {
const customDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-wa-auth-"));
const customDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-wa-auth-"));
try {
writeCreds(customDir);

View File

@@ -1,10 +1,10 @@
import type { ClawdbotConfig } from "../config/config.js";
export function normalizeLegacyConfigValues(cfg: ClawdbotConfig): {
config: ClawdbotConfig;
import type { MoltbotConfig } from "../config/config.js";
export function normalizeLegacyConfigValues(cfg: MoltbotConfig): {
config: MoltbotConfig;
changes: string[];
} {
const changes: string[] = [];
let next: ClawdbotConfig = cfg;
let next: MoltbotConfig = cfg;
const legacyAckReaction = cfg.messages?.ackReaction?.trim();
const hasWhatsAppConfig = cfg.channels?.whatsapp !== undefined;

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { describe, expect, it, vi } from "vitest";
@@ -16,7 +16,7 @@ describe("noteMacLaunchctlGatewayEnvOverrides", () => {
token: "config-token",
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
await noteMacLaunchctlGatewayEnvOverrides(cfg, { platform: "darwin", getenv, noteFn });
@@ -34,7 +34,7 @@ describe("noteMacLaunchctlGatewayEnvOverrides", () => {
it("does nothing when config has no gateway credentials", async () => {
const noteFn = vi.fn();
const getenv = vi.fn(async () => "launchctl-token");
const cfg = {} as ClawdbotConfig;
const cfg = {} as MoltbotConfig;
await noteMacLaunchctlGatewayEnvOverrides(cfg, { platform: "darwin", getenv, noteFn });
@@ -51,7 +51,7 @@ describe("noteMacLaunchctlGatewayEnvOverrides", () => {
token: "config-token",
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
await noteMacLaunchctlGatewayEnvOverrides(cfg, { platform: "linux", getenv, noteFn });

View File

@@ -4,7 +4,7 @@ import os from "node:os";
import path from "node:path";
import { promisify } from "node:util";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { note } from "../terminal/note.js";
import { shortenHomePath } from "../utils.js";
@@ -39,7 +39,7 @@ async function launchctlGetenv(name: string): Promise<string | undefined> {
}
}
function hasConfigGatewayCreds(cfg: ClawdbotConfig): boolean {
function hasConfigGatewayCreds(cfg: MoltbotConfig): boolean {
const localToken =
typeof cfg.gateway?.auth?.token === "string" ? cfg.gateway?.auth?.token.trim() : "";
const localPassword =
@@ -52,7 +52,7 @@ function hasConfigGatewayCreds(cfg: ClawdbotConfig): boolean {
}
export async function noteMacLaunchctlGatewayEnvOverrides(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
deps?: {
platform?: NodeJS.Platform;
getenv?: (name: string) => Promise<string | undefined>;

View File

@@ -7,7 +7,7 @@ import {
DEFAULT_SANDBOX_IMAGE,
resolveSandboxScope,
} from "../agents/sandbox.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { runCommandWithTimeout, runExec } from "../process/exec.js";
import type { RuntimeEnv } from "../runtime.js";
import { note } from "../terminal/note.js";
@@ -87,17 +87,17 @@ async function dockerImageExists(image: string): Promise<boolean> {
}
}
function resolveSandboxDockerImage(cfg: ClawdbotConfig): string {
function resolveSandboxDockerImage(cfg: MoltbotConfig): string {
const image = cfg.agents?.defaults?.sandbox?.docker?.image?.trim();
return image ? image : DEFAULT_SANDBOX_IMAGE;
}
function resolveSandboxBrowserImage(cfg: ClawdbotConfig): string {
function resolveSandboxBrowserImage(cfg: MoltbotConfig): string {
const image = cfg.agents?.defaults?.sandbox?.browser?.image?.trim();
return image ? image : DEFAULT_SANDBOX_BROWSER_IMAGE;
}
function updateSandboxDockerImage(cfg: ClawdbotConfig, image: string): ClawdbotConfig {
function updateSandboxDockerImage(cfg: MoltbotConfig, image: string): MoltbotConfig {
return {
...cfg,
agents: {
@@ -116,7 +116,7 @@ function updateSandboxDockerImage(cfg: ClawdbotConfig, image: string): ClawdbotC
};
}
function updateSandboxBrowserImage(cfg: ClawdbotConfig, image: string): ClawdbotConfig {
function updateSandboxBrowserImage(cfg: MoltbotConfig, image: string): MoltbotConfig {
return {
...cfg,
agents: {
@@ -170,10 +170,10 @@ async function handleMissingSandboxImage(
}
export async function maybeRepairSandboxImages(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
runtime: RuntimeEnv,
prompter: DoctorPrompter,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
const sandbox = cfg.agents?.defaults?.sandbox;
const mode = sandbox?.mode ?? "off";
if (!sandbox || mode === "off") return cfg;
@@ -230,7 +230,7 @@ export async function maybeRepairSandboxImages(
return next;
}
export function noteSandboxScopeWarnings(cfg: ClawdbotConfig) {
export function noteSandboxScopeWarnings(cfg: MoltbotConfig) {
const globalSandbox = cfg.agents?.defaults?.sandbox;
const agents = Array.isArray(cfg.agents?.list) ? cfg.agents.list : [];
const warnings: string[] = [];

View File

@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
const note = vi.hoisted(() => vi.fn());
@@ -36,7 +36,7 @@ describe("noteSecurityWarnings gateway exposure", () => {
const lastMessage = () => String(note.mock.calls.at(-1)?.[0] ?? "");
it("warns when exposed without auth", async () => {
const cfg = { gateway: { bind: "lan" } } as ClawdbotConfig;
const cfg = { gateway: { bind: "lan" } } as MoltbotConfig;
await noteSecurityWarnings(cfg);
const message = lastMessage();
expect(message).toContain("CRITICAL");
@@ -45,7 +45,7 @@ describe("noteSecurityWarnings gateway exposure", () => {
it("uses env token to avoid critical warning", async () => {
process.env.CLAWDBOT_GATEWAY_TOKEN = "token-123";
const cfg = { gateway: { bind: "lan" } } as ClawdbotConfig;
const cfg = { gateway: { bind: "lan" } } as MoltbotConfig;
await noteSecurityWarnings(cfg);
const message = lastMessage();
expect(message).toContain("WARNING");
@@ -55,14 +55,14 @@ describe("noteSecurityWarnings gateway exposure", () => {
it("treats whitespace token as missing", async () => {
const cfg = {
gateway: { bind: "lan", auth: { mode: "token", token: " " } },
} as ClawdbotConfig;
} as MoltbotConfig;
await noteSecurityWarnings(cfg);
const message = lastMessage();
expect(message).toContain("CRITICAL");
});
it("skips warning for loopback bind", async () => {
const cfg = { gateway: { bind: "loopback" } } as ClawdbotConfig;
const cfg = { gateway: { bind: "loopback" } } as MoltbotConfig;
await noteSecurityWarnings(cfg);
const message = lastMessage();
expect(message).toContain("No channel security warnings detected");

View File

@@ -1,16 +1,16 @@
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
import { listChannelPlugins } from "../channels/plugins/index.js";
import type { ChannelId } from "../channels/plugins/types.js";
import type { ClawdbotConfig, GatewayBindMode } from "../config/config.js";
import type { MoltbotConfig, GatewayBindMode } from "../config/config.js";
import { readChannelAllowFromStore } from "../pairing/pairing-store.js";
import { note } from "../terminal/note.js";
import { formatCliCommand } from "../cli/command-format.js";
import { resolveGatewayAuth } from "../gateway/auth.js";
import { isLoopbackHost, resolveGatewayBindHost } from "../gateway/net.js";
export async function noteSecurityWarnings(cfg: ClawdbotConfig) {
export async function noteSecurityWarnings(cfg: MoltbotConfig) {
const warnings: string[] = [];
const auditHint = `- Run: ${formatCliCommand("clawdbot security audit --deep")}`;
const auditHint = `- Run: ${formatCliCommand("moltbot security audit --deep")}`;
// ===========================================
// GATEWAY NETWORK EXPOSURE CHECK
@@ -48,19 +48,19 @@ export async function noteSecurityWarnings(cfg: ClawdbotConfig) {
const authFixLines =
resolvedAuth.mode === "password"
? [
` Fix: ${formatCliCommand("clawdbot configure")} to set a password`,
` Or switch to token: ${formatCliCommand("clawdbot config set gateway.auth.mode token")}`,
` Fix: ${formatCliCommand("moltbot configure")} to set a password`,
` Or switch to token: ${formatCliCommand("moltbot config set gateway.auth.mode token")}`,
]
: [
` Fix: ${formatCliCommand("clawdbot doctor --fix")} to generate a token`,
` Fix: ${formatCliCommand("moltbot doctor --fix")} to generate a token`,
` Or set token directly: ${formatCliCommand(
"clawdbot config set gateway.auth.mode token",
"moltbot config set gateway.auth.mode token",
)}`,
];
warnings.push(
`- CRITICAL: Gateway bound to ${bindDescriptor} without authentication.`,
` Anyone on your network (or internet if port-forwarded) can fully control your agent.`,
` Fix: ${formatCliCommand("clawdbot config set gateway.bind loopback")}`,
` Fix: ${formatCliCommand("moltbot config set gateway.bind loopback")}`,
...authFixLines,
);
} else {

View File

@@ -3,7 +3,7 @@ import os from "node:os";
import path from "node:path";
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { resolveOAuthDir, resolveStateDir } from "../config/paths.js";
import {
loadSessionStore,
@@ -117,7 +117,7 @@ function findOtherStateDirs(stateDir: string): string[] {
}
export async function noteStateIntegrity(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
prompter: DoctorPrompterLike,
configPath?: string,
) {

View File

@@ -4,7 +4,7 @@ import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import {
autoMigrateLegacyState,
detectLegacyStateMigrations,
@@ -15,7 +15,7 @@ import {
let tempRoot: string | null = null;
async function makeTempRoot() {
const root = await fs.promises.mkdtemp(path.join(os.tmpdir(), "clawdbot-doctor-"));
const root = await fs.promises.mkdtemp(path.join(os.tmpdir(), "moltbot-doctor-"));
tempRoot = root;
return root;
}
@@ -35,7 +35,7 @@ function writeJson5(filePath: string, value: unknown) {
describe("doctor legacy state migrations", () => {
it("migrates legacy sessions into agents/<id>/sessions", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const legacySessionsDir = path.join(root, "sessions");
fs.mkdirSync(legacySessionsDir, { recursive: true });
@@ -79,7 +79,7 @@ describe("doctor legacy state migrations", () => {
it("migrates legacy agent dir with conflict fallback", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const legacyAgentDir = path.join(root, "agent");
fs.mkdirSync(legacyAgentDir, { recursive: true });
@@ -103,7 +103,7 @@ describe("doctor legacy state migrations", () => {
it("auto-migrates legacy agent dir on startup", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const legacyAgentDir = path.join(root, "agent");
fs.mkdirSync(legacyAgentDir, { recursive: true });
@@ -125,7 +125,7 @@ describe("doctor legacy state migrations", () => {
it("auto-migrates legacy sessions on startup", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const legacySessionsDir = path.join(root, "sessions");
fs.mkdirSync(legacySessionsDir, { recursive: true });
@@ -154,7 +154,7 @@ describe("doctor legacy state migrations", () => {
it("migrates legacy WhatsApp auth files without touching oauth.json", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const oauthDir = path.join(root, "credentials");
fs.mkdirSync(oauthDir, { recursive: true });
@@ -177,7 +177,7 @@ describe("doctor legacy state migrations", () => {
it("no-ops when nothing detected", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const detected = await detectLegacyStateMigrations({
cfg,
env: { CLAWDBOT_STATE_DIR: root } as NodeJS.ProcessEnv,
@@ -188,7 +188,7 @@ describe("doctor legacy state migrations", () => {
it("routes legacy state to the default agent entry", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
agents: { list: [{ id: "alpha", default: true }] },
};
const legacySessionsDir = path.join(root, "sessions");
@@ -212,7 +212,7 @@ describe("doctor legacy state migrations", () => {
it("honors session.mainKey when seeding the direct-chat bucket", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = { session: { mainKey: "work" } };
const cfg: MoltbotConfig = { session: { mainKey: "work" } };
const legacySessionsDir = path.join(root, "sessions");
fs.mkdirSync(legacySessionsDir, { recursive: true });
writeJson5(path.join(legacySessionsDir, "sessions.json"), {
@@ -236,7 +236,7 @@ describe("doctor legacy state migrations", () => {
it("canonicalizes legacy main keys inside the target sessions store", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const targetDir = path.join(root, "agents", "main", "sessions");
writeJson5(path.join(targetDir, "sessions.json"), {
main: { sessionId: "legacy", updatedAt: 10 },
@@ -258,7 +258,7 @@ describe("doctor legacy state migrations", () => {
it("prefers the newest entry when collapsing main aliases", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = { session: { mainKey: "work" } };
const cfg: MoltbotConfig = { session: { mainKey: "work" } };
const targetDir = path.join(root, "agents", "main", "sessions");
writeJson5(path.join(targetDir, "sessions.json"), {
"agent:main:main": { sessionId: "legacy", updatedAt: 50 },
@@ -280,7 +280,7 @@ describe("doctor legacy state migrations", () => {
it("lowercases agent session keys during canonicalization", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const targetDir = path.join(root, "agents", "main", "sessions");
writeJson5(path.join(targetDir, "sessions.json"), {
"agent:main:slack:channel:C123": { sessionId: "legacy", updatedAt: 10 },
@@ -301,7 +301,7 @@ describe("doctor legacy state migrations", () => {
it("auto-migrates when only target sessions contain legacy keys", async () => {
const root = await makeTempRoot();
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const targetDir = path.join(root, "agents", "main", "sessions");
writeJson5(path.join(targetDir, "sessions.json"), {
main: { sessionId: "legacy", updatedAt: 10 },

View File

@@ -1,6 +1,6 @@
import fs from "node:fs/promises";
import path from "node:path";
import { resolveClawdbotPackageRoot } from "../infra/clawdbot-root.js";
import { resolveMoltbotPackageRoot } from "../infra/moltbot-root.js";
import { runCommandWithTimeout } from "../process/exec.js";
import type { RuntimeEnv } from "../runtime.js";
import { note } from "../terminal/note.js";
@@ -10,7 +10,7 @@ export async function maybeRepairUiProtocolFreshness(
_runtime: RuntimeEnv,
prompter: DoctorPrompter,
) {
const root = await resolveClawdbotPackageRoot({
const root = await resolveMoltbotPackageRoot({
moduleUrl: import.meta.url,
argv1: process.argv[1],
cwd: process.cwd(),

View File

@@ -6,7 +6,7 @@ import { note } from "../terminal/note.js";
import { formatCliCommand } from "../cli/command-format.js";
import type { DoctorOptions } from "./doctor-prompter.js";
async function detectClawdbotGitCheckout(root: string): Promise<"git" | "not-git" | "unknown"> {
async function detectMoltbotGitCheckout(root: string): Promise<"git" | "not-git" | "unknown"> {
const res = await runCommandWithTimeout(["git", "-C", root, "rev-parse", "--show-toplevel"], {
timeoutMs: 5000,
}).catch(() => null);
@@ -38,10 +38,10 @@ export async function maybeOfferUpdateBeforeDoctor(params: {
Boolean(process.stdin.isTTY);
if (!canOfferUpdate || !params.root) return { updated: false };
const git = await detectClawdbotGitCheckout(params.root);
const git = await detectMoltbotGitCheckout(params.root);
if (git === "git") {
const shouldUpdate = await params.confirm({
message: "Update Clawdbot from git before running doctor?",
message: "Update Moltbot from git before running doctor?",
initialValue: true,
});
if (!shouldUpdate) return { updated: false };
@@ -72,7 +72,7 @@ export async function maybeOfferUpdateBeforeDoctor(params: {
note(
[
"This install is not a git checkout.",
`Run \`${formatCliCommand("clawdbot update")}\` to update via your package manager (npm/pnpm), then rerun doctor.`,
`Run \`${formatCliCommand("moltbot update")}\` to update via your package manager (npm/pnpm), then rerun doctor.`,
].join("\n"),
"Update",
);

View File

@@ -1,11 +1,11 @@
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import { buildWorkspaceSkillStatus } from "../agents/skills-status.js";
import type { ClawdbotConfig } from "../config/config.js";
import { loadClawdbotPlugins } from "../plugins/loader.js";
import type { MoltbotConfig } from "../config/config.js";
import { loadMoltbotPlugins } from "../plugins/loader.js";
import { note } from "../terminal/note.js";
import { detectLegacyWorkspaceDirs, formatLegacyWorkspaceWarning } from "./doctor-workspace.js";
export function noteWorkspaceStatus(cfg: ClawdbotConfig) {
export function noteWorkspaceStatus(cfg: MoltbotConfig) {
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
const legacyWorkspace = detectLegacyWorkspaceDirs({ workspaceDir });
if (legacyWorkspace.legacyDirs.length > 0) {
@@ -25,7 +25,7 @@ export function noteWorkspaceStatus(cfg: ClawdbotConfig) {
"Skills status",
);
const pluginRegistry = loadClawdbotPlugins({
const pluginRegistry = loadMoltbotPlugins({
config: cfg,
workspaceDir,
logger: {

View File

@@ -5,10 +5,10 @@ import { describe, expect, it } from "vitest";
import { detectLegacyWorkspaceDirs } from "./doctor-workspace.js";
describe("detectLegacyWorkspaceDirs", () => {
it("ignores ~/clawdbot when it doesn't look like a workspace (e.g. install dir)", () => {
it("ignores ~/moltbot when it doesn't look like a workspace (e.g. install dir)", () => {
const home = "/home/user";
const workspaceDir = "/home/user/clawd";
const candidate = path.join(home, "clawdbot");
const candidate = path.join(home, "moltbot");
const detection = detectLegacyWorkspaceDirs({
workspaceDir,
@@ -20,10 +20,10 @@ describe("detectLegacyWorkspaceDirs", () => {
expect(detection.legacyDirs).toEqual([]);
});
it("flags ~/clawdbot when it contains workspace markers", () => {
it("flags ~/moltbot when it contains workspace markers", () => {
const home = "/home/user";
const workspaceDir = "/home/user/clawd";
const candidate = path.join(home, "clawdbot");
const candidate = path.join(home, "moltbot");
const agentsPath = path.join(candidate, "AGENTS.md");
const detection = detectLegacyWorkspaceDirs({

View File

@@ -15,8 +15,8 @@ export const MEMORY_SYSTEM_PROMPT = [
"Paste this into your agent:",
"",
"Install the memory system by applying:",
"https://github.com/clawdbot/clawdbot/commit/9ffea23f31ca1df5183b25668f8f814bee0fb34e",
"https://github.com/clawdbot/clawdbot/commit/7d1fee70e76f2f634f1b41fca927ee663914183a",
"https://github.com/moltbot/moltbot/commit/9ffea23f31ca1df5183b25668f8f814bee0fb34e",
"https://github.com/moltbot/moltbot/commit/7d1fee70e76f2f634f1b41fca927ee663914183a",
].join("\n");
export async function shouldSuggestMemorySystem(workspaceDir: string): Promise<boolean> {
@@ -66,7 +66,7 @@ export function detectLegacyWorkspaceDirs(params: {
const exists = params.exists ?? fs.existsSync;
const home = homedir();
const activeWorkspace = path.resolve(params.workspaceDir);
const candidates = [path.join(home, "clawdbot")];
const candidates = [path.join(home, "moltbot")];
const legacyDirs = candidates
.filter((candidate) => {
if (!exists(candidate)) return false;
@@ -83,6 +83,6 @@ export function formatLegacyWorkspaceWarning(detection: LegacyWorkspaceDetection
"Extra workspace directories detected (may contain old agent files):",
...detection.legacyDirs.map((dir) => `- ${shortenHomePath(dir)}`),
`Active workspace: ${shortenHomePath(detection.activeWorkspace)}`,
"If unused, archive or move to Trash (e.g. trash ~/clawdbot).",
"If unused, archive or move to Trash (e.g. trash ~/moltbot).",
].join("\n");
}

View File

@@ -26,7 +26,7 @@ beforeEach(() => {
readConfigFileSnapshot.mockReset();
writeConfigFile.mockReset().mockResolvedValue(undefined);
resolveClawdbotPackageRoot.mockReset().mockResolvedValue(null);
resolveMoltbotPackageRoot.mockReset().mockResolvedValue(null);
runGatewayUpdate.mockReset().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -34,7 +34,7 @@ beforeEach(() => {
durationMs: 0,
});
legacyReadConfigFileSnapshot.mockReset().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -55,7 +55,7 @@ beforeEach(() => {
killed: false,
});
ensureAuthProfileStore.mockReset().mockReturnValue({ version: 1, profiles: {} });
loadClawdbotPlugins.mockReset().mockReturnValue({ plugins: [], diagnostics: [] });
loadMoltbotPlugins.mockReset().mockReturnValue({ plugins: [], diagnostics: [] });
migrateLegacyConfig.mockReset().mockImplementation((raw: unknown) => ({
config: raw as Record<string, unknown>,
changes: ["Moved routing.allowFrom → channels.whatsapp.allowFrom."],
@@ -79,7 +79,7 @@ beforeEach(() => {
originalStateDir = process.env.CLAWDBOT_STATE_DIR;
originalUpdateInProgress = process.env.CLAWDBOT_UPDATE_IN_PROGRESS;
process.env.CLAWDBOT_UPDATE_IN_PROGRESS = "1";
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-doctor-state-"));
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-doctor-state-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
fs.mkdirSync(path.join(tempStateDir, "agents", "main", "sessions"), {
recursive: true,
@@ -110,7 +110,7 @@ const confirm = vi.fn().mockResolvedValue(true);
const select = vi.fn().mockResolvedValue("node");
const note = vi.fn();
const writeConfigFile = vi.fn().mockResolvedValue(undefined);
const resolveClawdbotPackageRoot = vi.fn().mockResolvedValue(null);
const resolveMoltbotPackageRoot = vi.fn().mockResolvedValue(null);
const runGatewayUpdate = vi.fn().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -132,10 +132,10 @@ const runCommandWithTimeout = vi.fn().mockResolvedValue({
});
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
const loadClawdbotPlugins = vi.fn().mockReturnValue({ plugins: [], diagnostics: [] });
const loadMoltbotPlugins = vi.fn().mockReturnValue({ plugins: [], diagnostics: [] });
const legacyReadConfigFileSnapshot = vi.fn().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -175,13 +175,13 @@ vi.mock("../agents/skills-status.js", () => ({
}));
vi.mock("../plugins/loader.js", () => ({
loadClawdbotPlugins,
loadMoltbotPlugins,
}));
vi.mock("../config/config.js", async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
CONFIG_PATH: "/tmp/moltbot.json",
createConfigIO,
readConfigFileSnapshot,
writeConfigFile,
@@ -216,8 +216,8 @@ vi.mock("../process/exec.js", () => ({
runCommandWithTimeout,
}));
vi.mock("../infra/clawdbot-root.js", () => ({
resolveClawdbotPackageRoot,
vi.mock("../infra/moltbot-root.js", () => ({
resolveMoltbotPackageRoot,
}));
vi.mock("../infra/update-runner.js", () => ({
@@ -327,7 +327,7 @@ vi.mock("./doctor-state-migrations.js", () => ({
describe("doctor command", () => {
it("runs legacy state migrations in non-interactive mode without prompting", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},

View File

@@ -26,7 +26,7 @@ beforeEach(() => {
readConfigFileSnapshot.mockReset();
writeConfigFile.mockReset().mockResolvedValue(undefined);
resolveClawdbotPackageRoot.mockReset().mockResolvedValue(null);
resolveMoltbotPackageRoot.mockReset().mockResolvedValue(null);
runGatewayUpdate.mockReset().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -34,7 +34,7 @@ beforeEach(() => {
durationMs: 0,
});
legacyReadConfigFileSnapshot.mockReset().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -78,7 +78,7 @@ beforeEach(() => {
originalStateDir = process.env.CLAWDBOT_STATE_DIR;
originalUpdateInProgress = process.env.CLAWDBOT_UPDATE_IN_PROGRESS;
process.env.CLAWDBOT_UPDATE_IN_PROGRESS = "1";
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-doctor-state-"));
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-doctor-state-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
fs.mkdirSync(path.join(tempStateDir, "agents", "main", "sessions"), {
recursive: true,
@@ -109,7 +109,7 @@ const confirm = vi.fn().mockResolvedValue(true);
const select = vi.fn().mockResolvedValue("node");
const note = vi.fn();
const writeConfigFile = vi.fn().mockResolvedValue(undefined);
const resolveClawdbotPackageRoot = vi.fn().mockResolvedValue(null);
const resolveMoltbotPackageRoot = vi.fn().mockResolvedValue(null);
const runGatewayUpdate = vi.fn().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -133,7 +133,7 @@ const runCommandWithTimeout = vi.fn().mockResolvedValue({
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
const legacyReadConfigFileSnapshot = vi.fn().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -173,14 +173,14 @@ vi.mock("../agents/skills-status.js", () => ({
}));
vi.mock("../plugins/loader.js", () => ({
loadClawdbotPlugins: () => ({ plugins: [], diagnostics: [] }),
loadMoltbotPlugins: () => ({ plugins: [], diagnostics: [] }),
}));
vi.mock("../config/config.js", async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
CONFIG_PATH: "/tmp/moltbot.json",
createConfigIO,
readConfigFileSnapshot,
writeConfigFile,
@@ -215,8 +215,8 @@ vi.mock("../process/exec.js", () => ({
runCommandWithTimeout,
}));
vi.mock("../infra/clawdbot-root.js", () => ({
resolveClawdbotPackageRoot,
vi.mock("../infra/moltbot-root.js", () => ({
resolveMoltbotPackageRoot,
}));
vi.mock("../infra/update-runner.js", () => ({
@@ -326,7 +326,7 @@ vi.mock("./doctor-state-migrations.js", () => ({
describe("doctor command", () => {
it("migrates routing.allowFrom to channels.whatsapp.allowFrom", { timeout: 60_000 }, async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: { routing: { allowFrom: ["+15555550123"] } },
@@ -370,7 +370,7 @@ describe("doctor command", () => {
it("migrates legacy gateway services", { timeout: 60_000 }, async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -406,8 +406,8 @@ describe("doctor command", () => {
it("offers to update first for git checkouts", async () => {
delete process.env.CLAWDBOT_UPDATE_IN_PROGRESS;
const root = "/tmp/clawdbot";
resolveClawdbotPackageRoot.mockResolvedValueOnce(root);
const root = "/tmp/moltbot";
resolveMoltbotPackageRoot.mockResolvedValueOnce(root);
runCommandWithTimeout.mockResolvedValueOnce({
stdout: `${root}\n`,
stderr: "",
@@ -424,7 +424,7 @@ describe("doctor command", () => {
});
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},

View File

@@ -26,7 +26,7 @@ beforeEach(() => {
readConfigFileSnapshot.mockReset();
writeConfigFile.mockReset().mockResolvedValue(undefined);
resolveClawdbotPackageRoot.mockReset().mockResolvedValue(null);
resolveMoltbotPackageRoot.mockReset().mockResolvedValue(null);
runGatewayUpdate.mockReset().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -34,7 +34,7 @@ beforeEach(() => {
durationMs: 0,
});
legacyReadConfigFileSnapshot.mockReset().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -78,7 +78,7 @@ beforeEach(() => {
originalStateDir = process.env.CLAWDBOT_STATE_DIR;
originalUpdateInProgress = process.env.CLAWDBOT_UPDATE_IN_PROGRESS;
process.env.CLAWDBOT_UPDATE_IN_PROGRESS = "1";
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-doctor-state-"));
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-doctor-state-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
fs.mkdirSync(path.join(tempStateDir, "agents", "main", "sessions"), {
recursive: true,
@@ -109,7 +109,7 @@ const confirm = vi.fn().mockResolvedValue(true);
const select = vi.fn().mockResolvedValue("node");
const note = vi.fn();
const writeConfigFile = vi.fn().mockResolvedValue(undefined);
const resolveClawdbotPackageRoot = vi.fn().mockResolvedValue(null);
const resolveMoltbotPackageRoot = vi.fn().mockResolvedValue(null);
const runGatewayUpdate = vi.fn().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -133,7 +133,7 @@ const runCommandWithTimeout = vi.fn().mockResolvedValue({
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
const legacyReadConfigFileSnapshot = vi.fn().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -173,14 +173,14 @@ vi.mock("../agents/skills-status.js", () => ({
}));
vi.mock("../plugins/loader.js", () => ({
loadClawdbotPlugins: () => ({ plugins: [], diagnostics: [] }),
loadMoltbotPlugins: () => ({ plugins: [], diagnostics: [] }),
}));
vi.mock("../config/config.js", async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
CONFIG_PATH: "/tmp/moltbot.json",
createConfigIO,
readConfigFileSnapshot,
writeConfigFile,
@@ -215,8 +215,8 @@ vi.mock("../process/exec.js", () => ({
runCommandWithTimeout,
}));
vi.mock("../infra/clawdbot-root.js", () => ({
resolveClawdbotPackageRoot,
vi.mock("../infra/moltbot-root.js", () => ({
resolveMoltbotPackageRoot,
}));
vi.mock("../infra/update-runner.js", () => ({
@@ -326,7 +326,7 @@ vi.mock("./doctor-state-migrations.js", () => ({
describe("doctor command", () => {
it("runs legacy state migrations in yes mode without prompting", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -385,7 +385,7 @@ describe("doctor command", () => {
it("skips gateway restarts in non-interactive mode", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -417,7 +417,7 @@ describe("doctor command", () => {
it("migrates anthropic oauth config profile id when only email profile exists", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},

View File

@@ -10,13 +10,13 @@ import {
resolveHooksGmailModel,
} from "../agents/model-selection.js";
import { formatCliCommand } from "../cli/command-format.js";
import type { ClawdbotConfig } from "../config/config.js";
import { CONFIG_PATH_CLAWDBOT, readConfigFileSnapshot, writeConfigFile } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { CONFIG_PATH, readConfigFileSnapshot, writeConfigFile } from "../config/config.js";
import { logConfigUpdated } from "../config/logging.js";
import { resolveGatewayService } from "../daemon/service.js";
import { resolveGatewayAuth } from "../gateway/auth.js";
import { buildGatewayConnectionDetails } from "../gateway/call.js";
import { resolveClawdbotPackageRoot } from "../infra/clawdbot-root.js";
import { resolveMoltbotPackageRoot } from "../infra/moltbot-root.js";
import type { RuntimeEnv } from "../runtime.js";
import { defaultRuntime } from "../runtime.js";
import { note } from "../terminal/note.js";
@@ -58,7 +58,7 @@ import { ensureSystemdUserLingerInteractive } from "./systemd-linger.js";
const intro = (message: string) => clackIntro(stylePromptTitle(message) ?? message);
const outro = (message: string) => clackOutro(stylePromptTitle(message) ?? message);
function resolveMode(cfg: ClawdbotConfig): "local" | "remote" {
function resolveMode(cfg: MoltbotConfig): "local" | "remote" {
return cfg.gateway?.mode === "remote" ? "remote" : "local";
}
@@ -68,9 +68,9 @@ export async function doctorCommand(
) {
const prompter = createDoctorPrompter({ runtime, options });
printWizardHeader(runtime);
intro("Clawdbot doctor");
intro("Moltbot doctor");
const root = await resolveClawdbotPackageRoot({
const root = await resolveMoltbotPackageRoot({
moduleUrl: import.meta.url,
argv1: process.argv[1],
cwd: process.cwd(),
@@ -92,17 +92,17 @@ export async function doctorCommand(
options,
confirm: (p) => prompter.confirm(p),
});
let cfg: ClawdbotConfig = configResult.cfg;
let cfg: MoltbotConfig = configResult.cfg;
const configPath = configResult.path ?? CONFIG_PATH_CLAWDBOT;
const configPath = configResult.path ?? CONFIG_PATH;
if (!cfg.gateway?.mode) {
const lines = [
"gateway.mode is unset; gateway start will be blocked.",
`Fix: run ${formatCliCommand("clawdbot configure")} and set Gateway mode (local/remote).`,
`Or set directly: ${formatCliCommand("clawdbot config set gateway.mode local")}`,
`Fix: run ${formatCliCommand("moltbot configure")} and set Gateway mode (local/remote).`,
`Or set directly: ${formatCliCommand("moltbot config set gateway.mode local")}`,
];
if (!fs.existsSync(configPath)) {
lines.push(`Missing config: run ${formatCliCommand("clawdbot setup")} first.`);
lines.push(`Missing config: run ${formatCliCommand("moltbot setup")} first.`);
}
note(lines.join("\n"), "Gateway");
}
@@ -179,7 +179,7 @@ export async function doctorCommand(
}
}
await noteStateIntegrity(cfg, prompter, configResult.path ?? CONFIG_PATH_CLAWDBOT);
await noteStateIntegrity(cfg, prompter, configResult.path ?? CONFIG_PATH);
cfg = await maybeRepairSandboxImages(cfg, runtime, prompter);
noteSandboxScopeWarnings(cfg);
@@ -277,12 +277,12 @@ export async function doctorCommand(
cfg = applyWizardMetadata(cfg, { command: "doctor", mode: resolveMode(cfg) });
await writeConfigFile(cfg);
logConfigUpdated(runtime);
const backupPath = `${CONFIG_PATH_CLAWDBOT}.bak`;
const backupPath = `${CONFIG_PATH}.bak`;
if (fs.existsSync(backupPath)) {
runtime.log(`Backup: ${shortenHomePath(backupPath)}`);
}
} else {
runtime.log(`Run "${formatCliCommand("clawdbot doctor --fix")}" to apply changes.`);
runtime.log(`Run "${formatCliCommand("moltbot doctor --fix")}" to apply changes.`);
}
if (options.workspaceSuggestions !== false) {

View File

@@ -26,7 +26,7 @@ beforeEach(() => {
readConfigFileSnapshot.mockReset();
writeConfigFile.mockReset().mockResolvedValue(undefined);
resolveClawdbotPackageRoot.mockReset().mockResolvedValue(null);
resolveMoltbotPackageRoot.mockReset().mockResolvedValue(null);
runGatewayUpdate.mockReset().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -34,7 +34,7 @@ beforeEach(() => {
durationMs: 0,
});
legacyReadConfigFileSnapshot.mockReset().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -78,7 +78,7 @@ beforeEach(() => {
originalStateDir = process.env.CLAWDBOT_STATE_DIR;
originalUpdateInProgress = process.env.CLAWDBOT_UPDATE_IN_PROGRESS;
process.env.CLAWDBOT_UPDATE_IN_PROGRESS = "1";
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-doctor-state-"));
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-doctor-state-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
fs.mkdirSync(path.join(tempStateDir, "agents", "main", "sessions"), {
recursive: true,
@@ -109,7 +109,7 @@ const confirm = vi.fn().mockResolvedValue(true);
const select = vi.fn().mockResolvedValue("node");
const note = vi.fn();
const writeConfigFile = vi.fn().mockResolvedValue(undefined);
const resolveClawdbotPackageRoot = vi.fn().mockResolvedValue(null);
const resolveMoltbotPackageRoot = vi.fn().mockResolvedValue(null);
const runGatewayUpdate = vi.fn().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -133,7 +133,7 @@ const runCommandWithTimeout = vi.fn().mockResolvedValue({
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
const legacyReadConfigFileSnapshot = vi.fn().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -173,14 +173,14 @@ vi.mock("../agents/skills-status.js", () => ({
}));
vi.mock("../plugins/loader.js", () => ({
loadClawdbotPlugins: () => ({ plugins: [], diagnostics: [] }),
loadMoltbotPlugins: () => ({ plugins: [], diagnostics: [] }),
}));
vi.mock("../config/config.js", async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
CONFIG_PATH: "/tmp/moltbot.json",
createConfigIO,
readConfigFileSnapshot,
writeConfigFile,
@@ -215,8 +215,8 @@ vi.mock("../process/exec.js", () => ({
runCommandWithTimeout,
}));
vi.mock("../infra/clawdbot-root.js", () => ({
resolveClawdbotPackageRoot,
vi.mock("../infra/moltbot-root.js", () => ({
resolveMoltbotPackageRoot,
}));
vi.mock("../infra/update-runner.js", () => ({
@@ -326,7 +326,7 @@ vi.mock("./doctor-state-migrations.js", () => ({
describe("doctor command", () => {
it("warns when per-agent sandbox docker/browser/prune overrides are ignored under shared scope", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -383,7 +383,7 @@ describe("doctor command", () => {
it("warns when extra workspace directories exist", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -398,14 +398,10 @@ describe("doctor command", () => {
note.mockClear();
const homedirSpy = vi.spyOn(os, "homedir").mockReturnValue("/Users/steipete");
const realExists = fs.existsSync;
const legacyPath = path.join("/Users/steipete", "clawdbot");
const legacyPath = path.join("/Users/steipete", "moltbot");
const legacyAgentsPath = path.join(legacyPath, "AGENTS.md");
const existsSpy = vi.spyOn(fs, "existsSync").mockImplementation((value) => {
if (
value === "/Users/steipete/clawdbot" ||
value === legacyPath ||
value === legacyAgentsPath
)
if (value === "/Users/steipete/moltbot" || value === legacyPath || value === legacyAgentsPath)
return true;
return realExists(value as never);
});
@@ -422,9 +418,7 @@ describe("doctor command", () => {
expect(
note.mock.calls.some(
([message, title]) =>
title === "Extra workspace" &&
typeof message === "string" &&
message.includes("clawdbot"),
title === "Extra workspace" && typeof message === "string" && message.includes("moltbot"),
),
).toBe(true);

View File

@@ -26,7 +26,7 @@ beforeEach(() => {
readConfigFileSnapshot.mockReset();
writeConfigFile.mockReset().mockResolvedValue(undefined);
resolveClawdbotPackageRoot.mockReset().mockResolvedValue(null);
resolveMoltbotPackageRoot.mockReset().mockResolvedValue(null);
runGatewayUpdate.mockReset().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -34,7 +34,7 @@ beforeEach(() => {
durationMs: 0,
});
legacyReadConfigFileSnapshot.mockReset().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -78,7 +78,7 @@ beforeEach(() => {
originalStateDir = process.env.CLAWDBOT_STATE_DIR;
originalUpdateInProgress = process.env.CLAWDBOT_UPDATE_IN_PROGRESS;
process.env.CLAWDBOT_UPDATE_IN_PROGRESS = "1";
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-doctor-state-"));
tempStateDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-doctor-state-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
fs.mkdirSync(path.join(tempStateDir, "agents", "main", "sessions"), {
recursive: true,
@@ -109,7 +109,7 @@ const confirm = vi.fn().mockResolvedValue(true);
const select = vi.fn().mockResolvedValue("node");
const note = vi.fn();
const writeConfigFile = vi.fn().mockResolvedValue(undefined);
const resolveClawdbotPackageRoot = vi.fn().mockResolvedValue(null);
const resolveMoltbotPackageRoot = vi.fn().mockResolvedValue(null);
const runGatewayUpdate = vi.fn().mockResolvedValue({
status: "skipped",
mode: "unknown",
@@ -133,7 +133,7 @@ const runCommandWithTimeout = vi.fn().mockResolvedValue({
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
const legacyReadConfigFileSnapshot = vi.fn().mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: false,
raw: null,
parsed: {},
@@ -173,14 +173,14 @@ vi.mock("../agents/skills-status.js", () => ({
}));
vi.mock("../plugins/loader.js", () => ({
loadClawdbotPlugins: () => ({ plugins: [], diagnostics: [] }),
loadMoltbotPlugins: () => ({ plugins: [], diagnostics: [] }),
}));
vi.mock("../config/config.js", async (importOriginal) => {
const actual = await importOriginal();
return {
...actual,
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
CONFIG_PATH: "/tmp/moltbot.json",
createConfigIO,
readConfigFileSnapshot,
writeConfigFile,
@@ -215,8 +215,8 @@ vi.mock("../process/exec.js", () => ({
runCommandWithTimeout,
}));
vi.mock("../infra/clawdbot-root.js", () => ({
resolveClawdbotPackageRoot,
vi.mock("../infra/moltbot-root.js", () => ({
resolveMoltbotPackageRoot,
}));
vi.mock("../infra/update-runner.js", () => ({
@@ -330,7 +330,7 @@ vi.mock("./doctor-update.js", () => ({
describe("doctor command", () => {
it("warns when the state directory is missing", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -340,7 +340,7 @@ describe("doctor command", () => {
legacyIssues: [],
});
const missingDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-missing-state-"));
const missingDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-missing-state-"));
fs.rmSync(missingDir, { recursive: true, force: true });
process.env.CLAWDBOT_STATE_DIR = missingDir;
note.mockClear();
@@ -358,7 +358,7 @@ describe("doctor command", () => {
it("warns about opencode provider overrides", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -392,7 +392,7 @@ describe("doctor command", () => {
it("skips gateway auth warning when CLAWDBOT_GATEWAY_TOKEN is set", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},

View File

@@ -276,8 +276,8 @@ export async function gatewayStatusCommand(
runtime.log(colorize(rich, theme.heading, "Discovery (this machine)"));
runtime.log(
discovery.length > 0
? `Found ${discovery.length} gateway(s) via Bonjour (local. + clawdbot.internal.)`
: "Found 0 gateways via Bonjour (local. + clawdbot.internal.)",
? `Found ${discovery.length} gateway(s) via Bonjour (local. + moltbot.internal.)`
: "Found 0 gateways via Bonjour (local. + moltbot.internal.)",
);
if (discovery.length === 0) {
runtime.log(

View File

@@ -1,5 +1,5 @@
import { resolveGatewayPort } from "../../config/config.js";
import type { ClawdbotConfig, ConfigFileSnapshot } from "../../config/types.js";
import type { MoltbotConfig, ConfigFileSnapshot } from "../../config/types.js";
import type { GatewayProbeResult } from "../../gateway/probe.js";
import { pickPrimaryTailnetIPv4 } from "../../infra/tailnet.js";
import { colorize, theme } from "../../terminal/theme.js";
@@ -79,7 +79,7 @@ function normalizeWsUrl(value: string): string | null {
return trimmed;
}
export function resolveTargets(cfg: ClawdbotConfig, explicitUrl?: string): GatewayStatusTarget[] {
export function resolveTargets(cfg: MoltbotConfig, explicitUrl?: string): GatewayStatusTarget[] {
const targets: GatewayStatusTarget[] = [];
const add = (t: GatewayStatusTarget) => {
if (!targets.some((x) => x.url === t.url)) targets.push(t);
@@ -124,7 +124,7 @@ export function sanitizeSshTarget(value: unknown): string | null {
}
export function resolveAuthForTarget(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
target: GatewayStatusTarget,
overrides: { token?: string; password?: string },
): { token?: string; password?: string } {
@@ -239,7 +239,7 @@ export function extractConfigSummary(snapshotUnknown: unknown): GatewayConfigSum
};
}
export function buildNetworkHints(cfg: ClawdbotConfig) {
export function buildNetworkHints(cfg: MoltbotConfig) {
const tailnetIPv4 = pickPrimaryTailnetIPv4();
const port = resolveGatewayPort(cfg);
return {

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import {
applyGoogleGeminiModelDefault,
GOOGLE_GEMINI_DEFAULT_MODEL,
@@ -8,7 +8,7 @@ import {
describe("applyGoogleGeminiModelDefault", () => {
it("sets gemini default when model is unset", () => {
const cfg: ClawdbotConfig = { agents: { defaults: {} } };
const cfg: MoltbotConfig = { agents: { defaults: {} } };
const applied = applyGoogleGeminiModelDefault(cfg);
expect(applied.changed).toBe(true);
expect(applied.next.agents?.defaults?.model).toEqual({
@@ -17,7 +17,7 @@ describe("applyGoogleGeminiModelDefault", () => {
});
it("overrides existing model", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
agents: { defaults: { model: "anthropic/claude-opus-4-5" } },
};
const applied = applyGoogleGeminiModelDefault(cfg);
@@ -28,7 +28,7 @@ describe("applyGoogleGeminiModelDefault", () => {
});
it("no-ops when already gemini default", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
agents: { defaults: { model: GOOGLE_GEMINI_DEFAULT_MODEL } },
};
const applied = applyGoogleGeminiModelDefault(cfg);

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { AgentModelListConfig } from "../config/types.js";
export const GOOGLE_GEMINI_DEFAULT_MODEL = "google/gemini-3-pro-preview";
@@ -11,8 +11,8 @@ function resolvePrimaryModel(model?: AgentModelListConfig | string): string | un
return undefined;
}
export function applyGoogleGeminiModelDefault(cfg: ClawdbotConfig): {
next: ClawdbotConfig;
export function applyGoogleGeminiModelDefault(cfg: MoltbotConfig): {
next: MoltbotConfig;
changed: boolean;
} {
const current = resolvePrimaryModel(cfg.agents?.defaults?.model)?.trim();

View File

@@ -20,7 +20,7 @@ describe("formatHealthCheckFailure", () => {
"gateway closed (1006 abnormal closure (no close frame)): no close reason",
"Gateway target: ws://127.0.0.1:19001",
"Source: local loopback",
"Config: /Users/steipete/.clawdbot-dev/clawdbot.json",
"Config: /Users/steipete/.clawdbot-dev/moltbot.json",
"Bind: loopback",
].join("\n"),
);
@@ -30,7 +30,7 @@ describe("formatHealthCheckFailure", () => {
"Health check failed: gateway closed (1006 abnormal closure (no close frame)): no close reason",
" Gateway target: ws://127.0.0.1:19001",
" Source: local loopback",
" Config: /Users/steipete/.clawdbot-dev/clawdbot.json",
" Config: /Users/steipete/.clawdbot-dev/moltbot.json",
" Bind: loopback",
].join("\n"),
);

View File

@@ -135,7 +135,7 @@ describe("getHealthSnapshot", () => {
});
it("treats telegram.tokenFile as configured", async () => {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-health-"));
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-health-"));
const tokenFile = path.join(tmpDir, "telegram-token");
fs.writeFileSync(tokenFile, "t-file\n", "utf-8");
testConfig = { channels: { telegram: { tokenFile } } };

View File

@@ -3,7 +3,7 @@ import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
import { getChannelPlugin, listChannelPlugins } from "../channels/plugins/index.js";
import type { ChannelAccountSnapshot } from "../channels/plugins/types.js";
import { withProgress } from "../cli/progress.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { loadConfig } from "../config/config.js";
import { loadSessionStore, resolveStorePath } from "../config/sessions.js";
import { buildGatewayConnectionDetails, callGateway } from "../gateway/call.js";
@@ -502,7 +502,7 @@ export async function getHealthSnapshot(params?: {
}
export async function healthCommand(
opts: { json?: boolean; timeoutMs?: number; verbose?: boolean; config?: ClawdbotConfig },
opts: { json?: boolean; timeoutMs?: number; verbose?: boolean; config?: MoltbotConfig },
runtime: RuntimeEnv,
) {
const cfg = opts.config ?? loadConfig();

View File

@@ -1,6 +1,6 @@
import { describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { makePrompter } from "./onboarding/__tests__/test-utils.js";
import {
applyModelAllowlist,
@@ -53,7 +53,7 @@ describe("promptDefaultModel", () => {
return first?.value ?? "";
});
const prompter = makePrompter({ select });
const config = { agents: { defaults: {} } } as ClawdbotConfig;
const config = { agents: { defaults: {} } } as MoltbotConfig;
await promptDefaultModel({
config,
@@ -90,7 +90,7 @@ describe("promptModelAllowlist", () => {
params.options.map((option: { value: string }) => option.value),
);
const prompter = makePrompter({ multiselect });
const config = { agents: { defaults: {} } } as ClawdbotConfig;
const config = { agents: { defaults: {} } } as MoltbotConfig;
await promptModelAllowlist({ config, prompter });
@@ -126,7 +126,7 @@ describe("promptModelAllowlist", () => {
params.options.map((option: { value: string }) => option.value),
);
const prompter = makePrompter({ multiselect });
const config = { agents: { defaults: {} } } as ClawdbotConfig;
const config = { agents: { defaults: {} } } as MoltbotConfig;
await promptModelAllowlist({
config,
@@ -152,7 +152,7 @@ describe("applyModelAllowlist", () => {
},
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
const next = applyModelAllowlist(config, ["openai/gpt-5.2"]);
expect(next.agents?.defaults?.models).toEqual({
@@ -169,7 +169,7 @@ describe("applyModelAllowlist", () => {
},
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
const next = applyModelAllowlist(config, []);
expect(next.agents?.defaults?.models).toBeUndefined();
@@ -184,7 +184,7 @@ describe("applyModelFallbacksFromSelection", () => {
model: { primary: "anthropic/claude-opus-4-5" },
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
const next = applyModelFallbacksFromSelection(config, [
"anthropic/claude-opus-4-5",
@@ -203,7 +203,7 @@ describe("applyModelFallbacksFromSelection", () => {
model: { primary: "anthropic/claude-opus-4-5", fallbacks: ["openai/gpt-5.2"] },
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
const next = applyModelFallbacksFromSelection(config, ["openai/gpt-5.2"]);
expect(next.agents?.defaults?.model).toEqual({

View File

@@ -9,7 +9,7 @@ import {
normalizeProviderId,
resolveConfiguredModelRef,
} from "../agents/model-selection.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { WizardPrompter, WizardSelectOption } from "../wizard/prompts.js";
import { formatTokenK } from "./models/shared.js";
@@ -23,7 +23,7 @@ const PROVIDER_FILTER_THRESHOLD = 30;
const HIDDEN_ROUTER_MODELS = new Set(["openrouter/auto"]);
type PromptDefaultModelParams = {
config: ClawdbotConfig;
config: MoltbotConfig;
prompter: WizardPrompter;
allowKeep?: boolean;
includeManual?: boolean;
@@ -38,7 +38,7 @@ type PromptModelAllowlistResult = { models?: string[] };
function hasAuthForProvider(
provider: string,
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
store: ReturnType<typeof ensureAuthProfileStore>,
) {
if (listProfilesForProvider(store, provider).length > 0) return true;
@@ -47,13 +47,13 @@ function hasAuthForProvider(
return false;
}
function resolveConfiguredModelRaw(cfg: ClawdbotConfig): string {
function resolveConfiguredModelRaw(cfg: MoltbotConfig): string {
const raw = cfg.agents?.defaults?.model as { primary?: string } | string | undefined;
if (typeof raw === "string") return raw.trim();
return raw?.primary?.trim() ?? "";
}
function resolveConfiguredModelKeys(cfg: ClawdbotConfig): string[] {
function resolveConfiguredModelKeys(cfg: MoltbotConfig): string[] {
const models = cfg.agents?.defaults?.models ?? {};
return Object.keys(models)
.map((key) => String(key ?? "").trim())
@@ -266,7 +266,7 @@ export async function promptDefaultModel(
}
export async function promptModelAllowlist(params: {
config: ClawdbotConfig;
config: MoltbotConfig;
prompter: WizardPrompter;
message?: string;
agentDir?: string;
@@ -387,7 +387,7 @@ export async function promptModelAllowlist(params: {
return { models: [] };
}
export function applyPrimaryModel(cfg: ClawdbotConfig, model: string): ClawdbotConfig {
export function applyPrimaryModel(cfg: MoltbotConfig, model: string): MoltbotConfig {
const defaults = cfg.agents?.defaults;
const existingModel = defaults?.model;
const existingModels = defaults?.models;
@@ -414,7 +414,7 @@ export function applyPrimaryModel(cfg: ClawdbotConfig, model: string): ClawdbotC
};
}
export function applyModelAllowlist(cfg: ClawdbotConfig, models: string[]): ClawdbotConfig {
export function applyModelAllowlist(cfg: MoltbotConfig, models: string[]): MoltbotConfig {
const defaults = cfg.agents?.defaults;
const normalized = normalizeModelKeys(models);
if (normalized.length === 0) {
@@ -448,9 +448,9 @@ export function applyModelAllowlist(cfg: ClawdbotConfig, models: string[]): Claw
}
export function applyModelFallbacksFromSelection(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
selection: string[],
): ClawdbotConfig {
): MoltbotConfig {
const normalized = normalizeModelKeys(selection);
if (normalized.length <= 1) return cfg;

View File

@@ -1,14 +1,14 @@
import { describe, expect, it, vi } from "vitest";
const loadConfig = vi.fn();
const ensureClawdbotModelsJson = vi.fn().mockResolvedValue(undefined);
const resolveClawdbotAgentDir = vi.fn().mockReturnValue("/tmp/clawdbot-agent");
const ensureMoltbotModelsJson = vi.fn().mockResolvedValue(undefined);
const resolveMoltbotAgentDir = vi.fn().mockReturnValue("/tmp/moltbot-agent");
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
const listProfilesForProvider = vi.fn().mockReturnValue([]);
const resolveAuthProfileDisplayLabel = vi.fn(({ profileId }: { profileId: string }) => profileId);
const resolveAuthStorePathForDisplay = vi
.fn()
.mockReturnValue("/tmp/clawdbot-agent/auth-profiles.json");
.mockReturnValue("/tmp/moltbot-agent/auth-profiles.json");
const resolveProfileUnusableUntilForDisplay = vi.fn().mockReturnValue(null);
const resolveEnvApiKey = vi.fn().mockReturnValue(undefined);
const resolveAwsSdkEnvVarName = vi.fn().mockReturnValue(undefined);
@@ -17,17 +17,17 @@ const discoverAuthStorage = vi.fn().mockReturnValue({});
const discoverModels = vi.fn();
vi.mock("../config/config.js", () => ({
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
STATE_DIR_CLAWDBOT: "/tmp/clawdbot-state",
CONFIG_PATH: "/tmp/moltbot.json",
STATE_DIR: "/tmp/moltbot-state",
loadConfig,
}));
vi.mock("../agents/models-config.js", () => ({
ensureClawdbotModelsJson,
ensureMoltbotModelsJson,
}));
vi.mock("../agents/agent-paths.js", () => ({
resolveClawdbotAgentDir,
resolveMoltbotAgentDir,
}));
vi.mock("../agents/auth-profiles.js", () => ({

View File

@@ -5,7 +5,7 @@ const writeConfigFile = vi.fn().mockResolvedValue(undefined);
const loadConfig = vi.fn().mockReturnValue({});
vi.mock("../config/config.js", () => ({
CONFIG_PATH_CLAWDBOT: "/tmp/clawdbot.json",
CONFIG_PATH: "/tmp/moltbot.json",
readConfigFileSnapshot,
writeConfigFile,
loadConfig,
@@ -19,7 +19,7 @@ describe("models set + fallbacks", () => {
it("normalizes z.ai provider in models set", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -46,7 +46,7 @@ describe("models set + fallbacks", () => {
it("normalizes z-ai provider in models fallbacks add", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},
@@ -73,7 +73,7 @@ describe("models set + fallbacks", () => {
it("normalizes provider casing in models set", async () => {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/clawdbot.json",
path: "/tmp/moltbot.json",
exists: true,
raw: "{}",
parsed: {},

View File

@@ -10,7 +10,7 @@ import {
import { resolveDefaultAgentWorkspaceDir } from "../../agents/workspace.js";
import { parseDurationMs } from "../../cli/parse-duration.js";
import { formatCliCommand } from "../../cli/command-format.js";
import { readConfigFileSnapshot, type ClawdbotConfig } from "../../config/config.js";
import { readConfigFileSnapshot, type MoltbotConfig } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import type { RuntimeEnv } from "../../runtime.js";
import { stylePromptHint, stylePromptMessage } from "../../terminal/prompt-style.js";
@@ -283,7 +283,7 @@ function mergeConfigPatch<T>(base: T, patch: unknown): T {
return next as T;
}
function applyDefaultModel(cfg: ClawdbotConfig, model: string): ClawdbotConfig {
function applyDefaultModel(cfg: MoltbotConfig, model: string): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[model] = models[model] ?? {};
@@ -332,7 +332,7 @@ export async function modelsAuthLoginCommand(opts: LoginOptions, runtime: Runtim
const providers = resolvePluginProviders({ config, workspaceDir });
if (providers.length === 0) {
throw new Error(
`No provider plugins found. Install one via \`${formatCliCommand("clawdbot plugins install")}\`.`,
`No provider plugins found. Install one via \`${formatCliCommand("moltbot plugins install")}\`.`,
);
}

View File

@@ -7,14 +7,14 @@ import {
resolveProfileUnusableUntilForDisplay,
} from "../../agents/auth-profiles.js";
import { getCustomProviderApiKey, resolveEnvApiKey } from "../../agents/model-auth.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import { shortenHomePath } from "../../utils.js";
import { maskApiKey } from "./list.format.js";
import type { ProviderAuthOverview } from "./list.types.js";
export function resolveProviderAuthOverview(params: {
provider: string;
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
store: AuthProfileStore;
modelsPath: string;
}): ProviderAuthOverview {

View File

@@ -4,11 +4,11 @@ import {
resolveConfiguredModelRef,
resolveModelRefFromString,
} from "../../agents/model-selection.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import type { ConfiguredEntry } from "./list.types.js";
import { DEFAULT_MODEL, DEFAULT_PROVIDER, modelKey } from "./shared.js";
export function resolveConfiguredEntries(cfg: ClawdbotConfig) {
export function resolveConfiguredEntries(cfg: MoltbotConfig) {
const resolvedDefault = resolveConfiguredModelRef({
cfg,
defaultProvider: DEFAULT_PROVIDER,

View File

@@ -1,7 +1,7 @@
import crypto from "node:crypto";
import fs from "node:fs/promises";
import { resolveClawdbotAgentDir } from "../../agents/agent-paths.js";
import { resolveMoltbotAgentDir } from "../../agents/agent-paths.js";
import {
ensureAuthProfileStore,
listProfilesForProvider,
@@ -15,7 +15,7 @@ import { getCustomProviderApiKey, resolveEnvApiKey } from "../../agents/model-au
import { normalizeProviderId, parseModelRef } from "../../agents/model-selection.js";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
import { resolveDefaultAgentWorkspaceDir } from "../../agents/workspace.js";
import type { ClawdbotConfig } from "../../config/config.js";
import type { MoltbotConfig } from "../../config/config.js";
import {
resolveSessionTranscriptPath,
resolveSessionTranscriptsDirForAgent,
@@ -117,7 +117,7 @@ function selectProbeModel(params: {
}
function buildProbeTargets(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
providers: string[];
modelCandidates: string[];
options: AuthProbeOptions;
@@ -260,7 +260,7 @@ function buildProbeTargets(params: {
}
async function probeTarget(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
agentId: string;
agentDir: string;
workspaceDir: string;
@@ -335,7 +335,7 @@ async function probeTarget(params: {
}
async function runTargetsWithConcurrency(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
targets: AuthProbeTarget[];
timeoutMs: number;
maxTokens: number;
@@ -346,7 +346,7 @@ async function runTargetsWithConcurrency(params: {
const concurrency = Math.max(1, Math.min(targets.length || 1, params.concurrency));
const agentId = resolveDefaultAgentId(cfg);
const agentDir = resolveClawdbotAgentDir();
const agentDir = resolveMoltbotAgentDir();
const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId) ?? resolveDefaultAgentWorkspaceDir();
const sessionDir = resolveSessionTranscriptsDirForAgent(agentId);
@@ -389,7 +389,7 @@ async function runTargetsWithConcurrency(params: {
}
export async function runAuthProbes(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
providers: string[];
modelCandidates: string[];
options: AuthProbeOptions;

View File

@@ -1,7 +1,7 @@
import type { Api, Model } from "@mariozechner/pi-ai";
import { discoverAuthStorage, discoverModels } from "@mariozechner/pi-coding-agent";
import { resolveClawdbotAgentDir } from "../../agents/agent-paths.js";
import { resolveMoltbotAgentDir } from "../../agents/agent-paths.js";
import type { AuthProfileStore } from "../../agents/auth-profiles.js";
import { listProfilesForProvider } from "../../agents/auth-profiles.js";
import {
@@ -9,8 +9,8 @@ import {
resolveAwsSdkEnvVarName,
resolveEnvApiKey,
} from "../../agents/model-auth.js";
import { ensureClawdbotModelsJson } from "../../agents/models-config.js";
import type { ClawdbotConfig } from "../../config/config.js";
import { ensureMoltbotModelsJson } from "../../agents/models-config.js";
import type { MoltbotConfig } from "../../config/config.js";
import type { ModelRow } from "./list.types.js";
import { modelKey } from "./shared.js";
@@ -30,7 +30,7 @@ const isLocalBaseUrl = (baseUrl: string) => {
}
};
const hasAuthForProvider = (provider: string, cfg: ClawdbotConfig, authStore: AuthProfileStore) => {
const hasAuthForProvider = (provider: string, cfg: MoltbotConfig, authStore: AuthProfileStore) => {
if (listProfilesForProvider(authStore, provider).length > 0) return true;
if (provider === "amazon-bedrock" && resolveAwsSdkEnvVarName()) return true;
if (resolveEnvApiKey(provider)) return true;
@@ -38,9 +38,9 @@ const hasAuthForProvider = (provider: string, cfg: ClawdbotConfig, authStore: Au
return false;
};
export async function loadModelRegistry(cfg: ClawdbotConfig) {
await ensureClawdbotModelsJson(cfg);
const agentDir = resolveClawdbotAgentDir();
export async function loadModelRegistry(cfg: MoltbotConfig) {
await ensureMoltbotModelsJson(cfg);
const agentDir = resolveMoltbotAgentDir();
const authStorage = discoverAuthStorage(agentDir);
const registry = discoverModels(authStorage, agentDir);
const models = registry.getAll() as Model<Api>[];
@@ -55,7 +55,7 @@ export function toModelRow(params: {
tags: string[];
aliases?: string[];
availableKeys?: Set<string>;
cfg?: ClawdbotConfig;
cfg?: MoltbotConfig;
authStore?: AuthProfileStore;
}): ModelRow {
const { model, key, tags, aliases = [], availableKeys, cfg, authStore } = params;

View File

@@ -1,5 +1,5 @@
import path from "node:path";
import { resolveClawdbotAgentDir } from "../../agents/agent-paths.js";
import { resolveMoltbotAgentDir } from "../../agents/agent-paths.js";
import {
buildAuthHealthSummary,
DEFAULT_OAUTH_WARN_MS,
@@ -17,7 +17,7 @@ import {
resolveConfiguredModelRef,
resolveModelRefFromString,
} from "../../agents/model-selection.js";
import { CONFIG_PATH_CLAWDBOT, loadConfig } from "../../config/config.js";
import { CONFIG_PATH, loadConfig } from "../../config/config.js";
import { getShellEnvAppliedKeys, shouldEnableShellEnvFallback } from "../../infra/shell-env.js";
import { withProgressTotals } from "../../cli/progress.js";
import {
@@ -93,7 +93,7 @@ export async function modelsStatusCommand(
);
const allowed = Object.keys(cfg.agents?.defaults?.models ?? {});
const agentDir = resolveClawdbotAgentDir();
const agentDir = resolveMoltbotAgentDir();
const store = ensureAuthProfileStore();
const modelsPath = path.join(agentDir, "models.json");
@@ -294,7 +294,7 @@ export async function modelsStatusCommand(
runtime.log(
JSON.stringify(
{
configPath: CONFIG_PATH_CLAWDBOT,
configPath: CONFIG_PATH,
agentDir,
defaultModel: defaultLabel,
resolvedDefault: resolvedLabel,
@@ -341,7 +341,7 @@ export async function modelsStatusCommand(
rawModel && rawModel !== resolvedLabel ? `${resolvedLabel} (from ${rawModel})` : resolvedLabel;
runtime.log(
`${label("Config")}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.info, shortenHomePath(CONFIG_PATH_CLAWDBOT))}`,
`${label("Config")}${colorize(rich, theme.muted, ":")} ${colorize(rich, theme.info, shortenHomePath(CONFIG_PATH))}`,
);
runtime.log(
`${label("Agent dir")}${colorize(rich, theme.muted, ":")} ${colorize(
@@ -487,8 +487,8 @@ export async function modelsStatusCommand(
for (const provider of missingProvidersInUse) {
const hint =
provider === "anthropic"
? `Run \`claude setup-token\`, then \`${formatCliCommand("clawdbot models auth setup-token")}\` or \`${formatCliCommand("clawdbot configure")}\`.`
: `Run \`${formatCliCommand("clawdbot configure")}\` or set an API key env var.`;
? `Run \`claude setup-token\`, then \`${formatCliCommand("moltbot models auth setup-token")}\` or \`${formatCliCommand("moltbot configure")}\`.`
: `Run \`${formatCliCommand("moltbot configure")}\` or set an API key env var.`;
runtime.log(`- ${theme.heading(provider)} ${hint}`);
}
}

View File

@@ -29,7 +29,7 @@ const mocks = vi.hoisted(() => {
return {
store,
resolveClawdbotAgentDir: vi.fn().mockReturnValue("/tmp/clawdbot-agent"),
resolveMoltbotAgentDir: vi.fn().mockReturnValue("/tmp/moltbot-agent"),
ensureAuthProfileStore: vi.fn().mockReturnValue(store),
listProfilesForProvider: vi.fn((s: typeof store, provider: string) => {
return Object.entries(s.profiles)
@@ -39,7 +39,7 @@ const mocks = vi.hoisted(() => {
resolveAuthProfileDisplayLabel: vi.fn(({ profileId }: { profileId: string }) => profileId),
resolveAuthStorePathForDisplay: vi
.fn()
.mockReturnValue("/tmp/clawdbot-agent/auth-profiles.json"),
.mockReturnValue("/tmp/moltbot-agent/auth-profiles.json"),
resolveEnvApiKey: vi.fn((provider: string) => {
if (provider === "openai") {
return {
@@ -72,7 +72,7 @@ const mocks = vi.hoisted(() => {
});
vi.mock("../../agents/agent-paths.js", () => ({
resolveClawdbotAgentDir: mocks.resolveClawdbotAgentDir,
resolveMoltbotAgentDir: mocks.resolveMoltbotAgentDir,
}));
vi.mock("../../agents/auth-profiles.js", async (importOriginal) => {
@@ -118,7 +118,7 @@ describe("modelsStatusCommand auth overview", () => {
const payload = JSON.parse(String((runtime.log as vi.Mock).mock.calls[0][0]));
expect(payload.defaultModel).toBe("anthropic/claude-opus-4-5");
expect(payload.auth.storePath).toBe("/tmp/clawdbot-agent/auth-profiles.json");
expect(payload.auth.storePath).toBe("/tmp/moltbot-agent/auth-profiles.json");
expect(payload.auth.shellEnvFallback.enabled).toBe(true);
expect(payload.auth.shellEnvFallback.appliedKeys).toContain("OPENAI_API_KEY");
expect(payload.auth.missingProvidersInUse).toEqual([]);

View File

@@ -6,7 +6,7 @@ import {
resolveModelRefFromString,
} from "../../agents/model-selection.js";
import {
type ClawdbotConfig,
type MoltbotConfig,
readConfigFileSnapshot,
writeConfigFile,
} from "../../config/config.js";
@@ -31,8 +31,8 @@ export const formatMs = (value?: number | null) => {
};
export async function updateConfig(
mutator: (cfg: ClawdbotConfig) => ClawdbotConfig,
): Promise<ClawdbotConfig> {
mutator: (cfg: MoltbotConfig) => MoltbotConfig,
): Promise<MoltbotConfig> {
const snapshot = await readConfigFileSnapshot();
if (!snapshot.valid) {
const issues = snapshot.issues.map((issue) => `- ${issue.path}: ${issue.message}`).join("\n");
@@ -43,7 +43,7 @@ export async function updateConfig(
return next;
}
export function resolveModelTarget(params: { raw: string; cfg: ClawdbotConfig }): {
export function resolveModelTarget(params: { raw: string; cfg: MoltbotConfig }): {
provider: string;
model: string;
} {
@@ -62,7 +62,7 @@ export function resolveModelTarget(params: { raw: string; cfg: ClawdbotConfig })
return resolved.ref;
}
export function buildAllowlistSet(cfg: ClawdbotConfig): Set<string> {
export function buildAllowlistSet(cfg: MoltbotConfig): Set<string> {
const allowed = new Set<string>();
const models = cfg.agents?.defaults?.models ?? {};
for (const raw of Object.keys(models)) {

View File

@@ -10,7 +10,7 @@ import {
VENICE_DEFAULT_MODEL_REF,
VENICE_MODEL_CATALOG,
} from "../agents/venice-models.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import {
OPENROUTER_DEFAULT_MODEL_REF,
VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
@@ -27,7 +27,7 @@ import {
MOONSHOT_DEFAULT_MODEL_REF,
} from "./onboard-auth.models.js";
export function applyZaiConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyZaiConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[ZAI_DEFAULT_MODEL_REF] = {
...models[ZAI_DEFAULT_MODEL_REF],
@@ -55,7 +55,7 @@ export function applyZaiConfig(cfg: ClawdbotConfig): ClawdbotConfig {
};
}
export function applyOpenrouterProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyOpenrouterProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[OPENROUTER_DEFAULT_MODEL_REF] = {
...models[OPENROUTER_DEFAULT_MODEL_REF],
@@ -74,7 +74,7 @@ export function applyOpenrouterProviderConfig(cfg: ClawdbotConfig): ClawdbotConf
};
}
export function applyVercelAiGatewayProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyVercelAiGatewayProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF] = {
...models[VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF],
@@ -93,7 +93,7 @@ export function applyVercelAiGatewayProviderConfig(cfg: ClawdbotConfig): Clawdbo
};
}
export function applyVercelAiGatewayConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyVercelAiGatewayConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applyVercelAiGatewayProviderConfig(cfg);
const existingModel = next.agents?.defaults?.model;
return {
@@ -115,7 +115,7 @@ export function applyVercelAiGatewayConfig(cfg: ClawdbotConfig): ClawdbotConfig
};
}
export function applyOpenrouterConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyOpenrouterConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applyOpenrouterProviderConfig(cfg);
const existingModel = next.agents?.defaults?.model;
return {
@@ -137,7 +137,7 @@ export function applyOpenrouterConfig(cfg: ClawdbotConfig): ClawdbotConfig {
};
}
export function applyMoonshotProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyMoonshotProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[MOONSHOT_DEFAULT_MODEL_REF] = {
...models[MOONSHOT_DEFAULT_MODEL_REF],
@@ -180,7 +180,7 @@ export function applyMoonshotProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig
};
}
export function applyMoonshotConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyMoonshotConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applyMoonshotProviderConfig(cfg);
const existingModel = next.agents?.defaults?.model;
return {
@@ -202,7 +202,7 @@ export function applyMoonshotConfig(cfg: ClawdbotConfig): ClawdbotConfig {
};
}
export function applyKimiCodeProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyKimiCodeProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[KIMI_CODE_MODEL_REF] = {
...models[KIMI_CODE_MODEL_REF],
@@ -245,7 +245,7 @@ export function applyKimiCodeProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig
};
}
export function applyKimiCodeConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyKimiCodeConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applyKimiCodeProviderConfig(cfg);
const existingModel = next.agents?.defaults?.model;
return {
@@ -267,7 +267,7 @@ export function applyKimiCodeConfig(cfg: ClawdbotConfig): ClawdbotConfig {
};
}
export function applySyntheticProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applySyntheticProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[SYNTHETIC_DEFAULT_MODEL_REF] = {
...models[SYNTHETIC_DEFAULT_MODEL_REF],
@@ -314,7 +314,7 @@ export function applySyntheticProviderConfig(cfg: ClawdbotConfig): ClawdbotConfi
};
}
export function applySyntheticConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applySyntheticConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applySyntheticProviderConfig(cfg);
const existingModel = next.agents?.defaults?.model;
return {
@@ -340,7 +340,7 @@ export function applySyntheticConfig(cfg: ClawdbotConfig): ClawdbotConfig {
* Apply Venice provider configuration without changing the default model.
* Registers Venice models and sets up the provider, but preserves existing model selection.
*/
export function applyVeniceProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyVeniceProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[VENICE_DEFAULT_MODEL_REF] = {
...models[VENICE_DEFAULT_MODEL_REF],
@@ -389,7 +389,7 @@ export function applyVeniceProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
* Apply Venice provider configuration AND set Venice as the default model.
* Use this when Venice is the primary provider choice during onboarding.
*/
export function applyVeniceConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyVeniceConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applyVeniceProviderConfig(cfg);
const existingModel = next.agents?.defaults?.model;
return {
@@ -412,7 +412,7 @@ export function applyVeniceConfig(cfg: ClawdbotConfig): ClawdbotConfig {
}
export function applyAuthProfileConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
params: {
profileId: string;
provider: string;
@@ -420,7 +420,7 @@ export function applyAuthProfileConfig(
email?: string;
preferProfileFirst?: boolean;
},
): ClawdbotConfig {
): MoltbotConfig {
const profiles = {
...cfg.auth?.profiles,
[params.profileId]: {

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import {
buildMinimaxApiModelDefinition,
buildMinimaxModelDefinition,
@@ -12,7 +12,7 @@ import {
MINIMAX_LM_STUDIO_COST,
} from "./onboard-auth.models.js";
export function applyMinimaxProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyMinimaxProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models["anthropic/claude-opus-4-5"] = {
...models["anthropic/claude-opus-4-5"],
@@ -59,9 +59,9 @@ export function applyMinimaxProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig
}
export function applyMinimaxHostedProviderConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
params?: { baseUrl?: string },
): ClawdbotConfig {
): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[MINIMAX_HOSTED_MODEL_REF] = {
...models[MINIMAX_HOSTED_MODEL_REF],
@@ -103,7 +103,7 @@ export function applyMinimaxHostedProviderConfig(
};
}
export function applyMinimaxConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyMinimaxConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applyMinimaxProviderConfig(cfg);
return {
...next,
@@ -126,9 +126,9 @@ export function applyMinimaxConfig(cfg: ClawdbotConfig): ClawdbotConfig {
}
export function applyMinimaxHostedConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
params?: { baseUrl?: string },
): ClawdbotConfig {
): MoltbotConfig {
const next = applyMinimaxHostedProviderConfig(cfg, params);
return {
...next,
@@ -147,9 +147,9 @@ export function applyMinimaxHostedConfig(
// MiniMax Anthropic-compatible API (platform.minimax.io/anthropic)
export function applyMinimaxApiProviderConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
modelId: string = "MiniMax-M2.1",
): ClawdbotConfig {
): MoltbotConfig {
const providers = { ...cfg.models?.providers };
const existingProvider = providers.minimax;
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
@@ -190,9 +190,9 @@ export function applyMinimaxApiProviderConfig(
}
export function applyMinimaxApiConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
modelId: string = "MiniMax-M2.1",
): ClawdbotConfig {
): MoltbotConfig {
const next = applyMinimaxApiProviderConfig(cfg, modelId);
return {
...next,

View File

@@ -1,7 +1,7 @@
import { OPENCODE_ZEN_DEFAULT_MODEL_REF } from "../agents/opencode-zen-models.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
export function applyOpencodeZenProviderConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyOpencodeZenProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
// Use the built-in opencode provider from pi-ai; only seed the allowlist alias.
const models = { ...cfg.agents?.defaults?.models };
models[OPENCODE_ZEN_DEFAULT_MODEL_REF] = {
@@ -21,7 +21,7 @@ export function applyOpencodeZenProviderConfig(cfg: ClawdbotConfig): ClawdbotCon
};
}
export function applyOpencodeZenConfig(cfg: ClawdbotConfig): ClawdbotConfig {
export function applyOpencodeZenConfig(cfg: MoltbotConfig): MoltbotConfig {
const next = applyOpencodeZenProviderConfig(cfg);
return {
...next,

View File

@@ -1,8 +1,8 @@
import type { OAuthCredentials } from "@mariozechner/pi-ai";
import { resolveClawdbotAgentDir } from "../agents/agent-paths.js";
import { resolveMoltbotAgentDir } from "../agents/agent-paths.js";
import { upsertAuthProfile } from "../agents/auth-profiles.js";
const resolveAuthAgentDir = (agentDir?: string) => agentDir ?? resolveClawdbotAgentDir();
const resolveAuthAgentDir = (agentDir?: string) => agentDir ?? resolveMoltbotAgentDir();
export async function writeOAuthCredentials(
provider: string,

View File

@@ -59,7 +59,7 @@ describe("writeOAuthCredentials", () => {
});
it("writes auth-profiles.json under CLAWDBOT_AGENT_DIR when set", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-oauth-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-oauth-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
@@ -118,7 +118,7 @@ describe("setMinimaxApiKey", () => {
});
it("writes to CLAWDBOT_AGENT_DIR when set", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-minimax-"));
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-minimax-"));
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
process.env.CLAWDBOT_AGENT_DIR = path.join(tempStateDir, "custom-agent");
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { setupChannels } from "./onboard-channels.js";
@@ -76,7 +76,7 @@ describe("setupChannels", () => {
}),
};
await setupChannels({} as ClawdbotConfig, runtime, prompter, {
await setupChannels({} as MoltbotConfig, runtime, prompter, {
skipConfirm: true,
quickstartDefaults: true,
forceAllowFromChannels: ["whatsapp"],
@@ -127,7 +127,7 @@ describe("setupChannels", () => {
botToken: "token",
},
},
} as ClawdbotConfig,
} as MoltbotConfig,
runtime,
prompter,
{
@@ -189,7 +189,7 @@ describe("setupChannels", () => {
enabled: false,
},
},
} as ClawdbotConfig,
} as MoltbotConfig,
runtime,
prompter,
{

View File

@@ -7,7 +7,7 @@ import {
formatChannelSelectionLine,
listChatChannels,
} from "../channels/registry.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { isChannelConfigured } from "../config/plugin-auto-enable.js";
import type { DmPolicy } from "../config/types.js";
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
@@ -82,7 +82,7 @@ async function promptConfiguredAction(params: {
}
async function promptRemovalAccountId(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
prompter: WizardPrompter;
label: string;
channel: ChannelChoice;
@@ -105,7 +105,7 @@ async function promptRemovalAccountId(params: {
}
async function collectChannelStatus(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
options?: SetupChannelsOptions;
accountOverrides: Partial<Record<ChannelChoice, string>>;
}): Promise<ChannelStatusSummary> {
@@ -157,7 +157,7 @@ async function collectChannelStatus(params: {
}
export async function noteChannelStatus(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
prompter: WizardPrompter;
options?: SetupChannelsOptions;
accountOverrides?: Partial<Record<ChannelChoice, string>>;
@@ -188,7 +188,7 @@ async function noteChannelPrimer(
await prompter.note(
[
"DM security: default is pairing; unknown DMs get a pairing code.",
`Approve with: ${formatCliCommand("clawdbot pairing approve <channel> <code>")}`,
`Approve with: ${formatCliCommand("moltbot pairing approve <channel> <code>")}`,
'Public DMs require dmPolicy="open" + allowFrom=["*"].',
'Multi-user DMs: set session.dmScope="per-channel-peer" to isolate sessions.',
`Docs: ${formatDocsLink("/start/pairing", "start/pairing")}`,
@@ -213,11 +213,11 @@ function resolveQuickstartDefault(
}
async function maybeConfigureDmPolicies(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
selection: ChannelChoice[];
prompter: WizardPrompter;
accountIdsByChannel?: Map<ChannelChoice, string>;
}): Promise<ClawdbotConfig> {
}): Promise<MoltbotConfig> {
const { selection, prompter, accountIdsByChannel } = params;
const dmPolicies = selection
.map((channel) => getChannelOnboardingAdapter(channel)?.dmPolicy)
@@ -235,7 +235,7 @@ async function maybeConfigureDmPolicies(params: {
await prompter.note(
[
"Default: pairing (unknown DMs get a pairing code).",
`Approve: ${formatCliCommand(`clawdbot pairing approve ${policy.channel} <code>`)}`,
`Approve: ${formatCliCommand(`moltbot pairing approve ${policy.channel} <code>`)}`,
`Allowlist DMs: ${policy.policyKey}="allowlist" + ${policy.allowFromKey} entries.`,
`Public DMs: ${policy.policyKey}="open" + ${policy.allowFromKey} includes "*".`,
'Multi-user DMs: set session.dmScope="per-channel-peer" to isolate sessions.',
@@ -275,11 +275,11 @@ async function maybeConfigureDmPolicies(params: {
// Channel-specific prompts moved into onboarding adapters.
export async function setupChannels(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
runtime: RuntimeEnv,
prompter: WizardPrompter,
options?: SetupChannelsOptions,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
let next = cfg;
const forceAllowFromChannels = new Set(options?.forceAllowFromChannels ?? []);
const accountOverrides: Partial<Record<ChannelChoice, string>> = {
@@ -584,7 +584,7 @@ export async function setupChannels(
{
value: "__skip__",
label: "Skip for now",
hint: `You can add channels later via \`${formatCliCommand("clawdbot channels add")}\``,
hint: `You can add channels later via \`${formatCliCommand("moltbot channels add")}\``,
},
],
initialValue: quickstartDefault,

View File

@@ -6,8 +6,8 @@ import { inspect } from "node:util";
import { cancel, isCancel } from "@clack/prompts";
import { DEFAULT_AGENT_WORKSPACE_DIR, ensureAgentWorkspace } from "../agents/workspace.js";
import type { ClawdbotConfig } from "../config/config.js";
import { CONFIG_PATH_CLAWDBOT } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { CONFIG_PATH } from "../config/config.js";
import { resolveSessionTranscriptsDirForAgent } from "../config/sessions.js";
import { callGateway } from "../gateway/call.js";
import { normalizeControlUiBasePath } from "../gateway/control-ui-shared.js";
@@ -36,7 +36,7 @@ export function guardCancel<T>(value: T | symbol, runtime: RuntimeEnv): T {
return value as T;
}
export function summarizeExistingConfig(config: ClawdbotConfig): string {
export function summarizeExistingConfig(config: MoltbotConfig): string {
const rows: string[] = [];
const defaults = config.agents?.defaults;
if (defaults?.workspace) rows.push(shortenHomeInString(`workspace: ${defaults.workspace}`));
@@ -75,9 +75,9 @@ export function printWizardHeader(runtime: RuntimeEnv) {
}
export function applyWizardMetadata(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
params: { command: string; mode: OnboardMode },
): ClawdbotConfig {
): MoltbotConfig {
const commit = process.env.GIT_COMMIT?.trim() || process.env.GIT_SHA?.trim() || undefined;
return {
...cfg,
@@ -274,7 +274,7 @@ export async function moveToTrash(pathname: string, runtime: RuntimeEnv): Promis
}
export async function handleReset(scope: ResetScope, workspaceDir: string, runtime: RuntimeEnv) {
await moveToTrash(CONFIG_PATH_CLAWDBOT, runtime);
await moveToTrash(CONFIG_PATH, runtime);
if (scope === "config") return;
await moveToTrash(path.join(CONFIG_DIR, "credentials"), runtime);
await moveToTrash(resolveSessionTranscriptsDirForAgent(), runtime);

View File

@@ -1,6 +1,6 @@
import { describe, expect, it, vi, beforeEach } from "vitest";
import { setupInternalHooks } from "./onboard-hooks.js";
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import type { HookStatusReport } from "../hooks/hooks-status.js";
@@ -47,7 +47,7 @@ describe("onboard-hooks", () => {
{
name: "session-memory",
description: "Save session context to memory when /new command is issued",
source: "clawdbot-bundled",
source: "moltbot-bundled",
pluginId: undefined,
filePath: "/mock/workspace/hooks/session-memory/HOOK.md",
baseDir: "/mock/workspace/hooks/session-memory",
@@ -80,7 +80,7 @@ describe("onboard-hooks", () => {
{
name: "command-logger",
description: "Log all command events to a centralized audit file",
source: "clawdbot-bundled",
source: "moltbot-bundled",
pluginId: undefined,
filePath: "/mock/workspace/hooks/command-logger/HOOK.md",
baseDir: "/mock/workspace/hooks/command-logger",
@@ -118,7 +118,7 @@ describe("onboard-hooks", () => {
const { buildWorkspaceHookStatus } = await import("../hooks/hooks-status.js");
vi.mocked(buildWorkspaceHookStatus).mockReturnValue(createMockHookReport());
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const prompter = createMockPrompter(["session-memory"]);
const runtime = createMockRuntime();
@@ -151,7 +151,7 @@ describe("onboard-hooks", () => {
const { buildWorkspaceHookStatus } = await import("../hooks/hooks-status.js");
vi.mocked(buildWorkspaceHookStatus).mockReturnValue(createMockHookReport());
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const prompter = createMockPrompter(["__skip__"]);
const runtime = createMockRuntime();
@@ -165,7 +165,7 @@ describe("onboard-hooks", () => {
const { buildWorkspaceHookStatus } = await import("../hooks/hooks-status.js");
vi.mocked(buildWorkspaceHookStatus).mockReturnValue(createMockHookReport(false));
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const prompter = createMockPrompter([]);
const runtime = createMockRuntime();
@@ -183,7 +183,7 @@ describe("onboard-hooks", () => {
const { buildWorkspaceHookStatus } = await import("../hooks/hooks-status.js");
vi.mocked(buildWorkspaceHookStatus).mockReturnValue(createMockHookReport());
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
hooks: {
enabled: true,
path: "/webhook",
@@ -208,7 +208,7 @@ describe("onboard-hooks", () => {
const { buildWorkspaceHookStatus } = await import("../hooks/hooks-status.js");
vi.mocked(buildWorkspaceHookStatus).mockReturnValue(createMockHookReport());
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
agents: { defaults: { workspace: "/workspace" } },
};
const prompter = createMockPrompter(["__skip__"]);
@@ -224,7 +224,7 @@ describe("onboard-hooks", () => {
const { buildWorkspaceHookStatus } = await import("../hooks/hooks-status.js");
vi.mocked(buildWorkspaceHookStatus).mockReturnValue(createMockHookReport());
const cfg: ClawdbotConfig = {};
const cfg: MoltbotConfig = {};
const prompter = createMockPrompter(["session-memory"]);
const runtime = createMockRuntime();
@@ -239,7 +239,7 @@ describe("onboard-hooks", () => {
// Second note should confirm configuration
expect(noteCalls[1][0]).toContain("Enabled 1 hook: session-memory");
expect(noteCalls[1][0]).toMatch(/(?:clawdbot|moltbot)( --profile isolated)? hooks list/);
expect(noteCalls[1][0]).toMatch(/(?:moltbot|moltbot)( --profile isolated)? hooks list/);
});
});
});

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { buildWorkspaceHookStatus } from "../hooks/hooks-status.js";
@@ -6,10 +6,10 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent
import { formatCliCommand } from "../cli/command-format.js";
export async function setupInternalHooks(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
runtime: RuntimeEnv,
prompter: WizardPrompter,
): Promise<ClawdbotConfig> {
): Promise<MoltbotConfig> {
await prompter.note(
[
"Hooks let you automate actions when agent commands are issued.",
@@ -58,7 +58,7 @@ export async function setupInternalHooks(
entries[name] = { enabled: true };
}
const next: ClawdbotConfig = {
const next: MoltbotConfig = {
...cfg,
hooks: {
...cfg.hooks,
@@ -74,9 +74,9 @@ export async function setupInternalHooks(
`Enabled ${selected.length} hook${selected.length > 1 ? "s" : ""}: ${selected.join(", ")}`,
"",
"You can manage hooks later with:",
` ${formatCliCommand("clawdbot hooks list")}`,
` ${formatCliCommand("clawdbot hooks enable <name>")}`,
` ${formatCliCommand("clawdbot hooks disable <name>")}`,
` ${formatCliCommand("moltbot hooks list")}`,
` ${formatCliCommand("moltbot hooks enable <name>")}`,
` ${formatCliCommand("moltbot hooks disable <name>")}`,
].join("\n"),
"Hooks Configured",
);

Some files were not shown because too many files have changed in this diff Show More