chore: update molt.bot domains

This commit is contained in:
Peter Steinberger
2026-01-27 11:27:41 +00:00
parent f4004054ab
commit 83460df96f
137 changed files with 653 additions and 538 deletions

View File

@@ -21,7 +21,7 @@ export function registerAcpCli(program: Command) {
.option("--verbose, -v", "Verbose logging to stderr", false)
.addHelpText(
"after",
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/acp", "docs.clawd.bot/cli/acp")}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/acp", "docs.molt.bot/cli/acp")}\n`,
)
.action((opts) => {
try {
@@ -46,7 +46,7 @@ export function registerAcpCli(program: Command) {
.command("client")
.description("Run an interactive ACP client against the local ACP bridge")
.option("--cwd <dir>", "Working directory for the ACP session")
.option("--server <command>", "ACP server command (default: clawdbot)")
.option("--server <command>", "ACP server command (default: moltbot)")
.option("--server-args <args...>", "Extra arguments for the ACP server")
.option("--server-verbose", "Enable verbose logging on the ACP server", false)
.option("--verbose, -v", "Verbose client logging", false)

View File

@@ -2,6 +2,7 @@ import { resolveCommitHash } from "../infra/git-commit.js";
import { visibleWidth } from "../terminal/ansi.js";
import { isRich, theme } from "../terminal/theme.js";
import { pickTagline, type TaglineOptions } from "./tagline.js";
import { resolveCliName } from "./cli-name.js";
type BannerOptions = TaglineOptions & {
argv?: string[];
@@ -37,7 +38,8 @@ export function formatCliBannerLine(version: string, options: BannerOptions = {}
const commitLabel = commit ?? "unknown";
const tagline = pickTagline(options);
const rich = options.richTty ?? isRich();
const title = "🦞 Clawdbot";
const cliName = resolveCliName(options.argv ?? process.argv, options.env);
const title = cliName === "clawdbot" ? "🦞 Clawdbot" : "🦞 Moltbot";
const prefix = "🦞 ";
const columns = options.columns ?? process.stdout.columns ?? 120;
const plainFullLine = `${title} ${version} (${commitLabel}) — ${tagline}`;

View File

@@ -90,7 +90,7 @@ export function registerBrowserExtensionCommands(
`- “Load unpacked” → select: ${displayPath}`,
`- Pin “Clawdbot Browser Relay”, then click it on the tab (badge shows ON)`,
"",
`${theme.muted("Docs:")} ${formatDocsLink("/tools/chrome-extension", "docs.clawd.bot/tools/chrome-extension")}`,
`${theme.muted("Docs:")} ${formatDocsLink("/tools/chrome-extension", "docs.molt.bot/tools/chrome-extension")}`,
].join("\n"),
),
);
@@ -107,7 +107,7 @@ export function registerBrowserExtensionCommands(
danger(
[
`Chrome extension is not installed. Run: "${formatCliCommand("clawdbot browser extension install")}"`,
`Docs: ${formatDocsLink("/tools/chrome-extension", "docs.clawd.bot/tools/chrome-extension")}`,
`Docs: ${formatDocsLink("/tools/chrome-extension", "docs.molt.bot/tools/chrome-extension")}`,
].join("\n"),
),
);

View File

@@ -31,7 +31,7 @@ export function registerBrowserCli(program: Command) {
true,
)}\n\n${theme.muted("Docs:")} ${formatDocsLink(
"/cli/browser",
"docs.clawd.bot/cli/browser",
"docs.molt.bot/cli/browser",
)}\n`,
)
.action(() => {

View File

@@ -76,7 +76,7 @@ export function registerChannelsCli(program: Command) {
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink(
"/cli/channels",
"docs.clawd.bot/cli/channels",
"docs.molt.bot/cli/channels",
)}\n`,
);

View File

@@ -1,6 +1,7 @@
import { normalizeProfileName } from "./profile-utils.js";
import { replaceCliName, resolveCliName } from "./cli-name.js";
const CLI_PREFIX_RE = /^(?:pnpm|npm|bunx|npx)\s+clawdbot\b|^clawdbot\b/;
const CLI_PREFIX_RE = /^(?:pnpm|npm|bunx|npx)\s+(?:clawdbot|moltbot)\b|^(?:clawdbot|moltbot)\b/;
const PROFILE_FLAG_RE = /(?:^|\s)--profile(?:\s|=|$)/;
const DEV_FLAG_RE = /(?:^|\s)--dev(?:\s|$)/;
@@ -8,9 +9,13 @@ export function formatCliCommand(
command: string,
env: Record<string, string | undefined> = process.env as Record<string, string | undefined>,
): string {
const cliName = resolveCliName(undefined, env);
const normalizedCommand = replaceCliName(command, cliName);
const profile = normalizeProfileName(env.CLAWDBOT_PROFILE);
if (!profile) return command;
if (!CLI_PREFIX_RE.test(command)) return command;
if (PROFILE_FLAG_RE.test(command) || DEV_FLAG_RE.test(command)) return command;
return command.replace(CLI_PREFIX_RE, (match) => `${match} --profile ${profile}`);
if (!profile) return normalizedCommand;
if (!CLI_PREFIX_RE.test(normalizedCommand)) return normalizedCommand;
if (PROFILE_FLAG_RE.test(normalizedCommand) || DEV_FLAG_RE.test(normalizedCommand)) {
return normalizedCommand;
}
return normalizedCommand.replace(CLI_PREFIX_RE, (match) => `${match} --profile ${profile}`);
}

View File

@@ -185,7 +185,7 @@ export function registerConfigCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/config", "docs.clawd.bot/cli/config")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/config", "docs.molt.bot/cli/config")}\n`,
)
.option(
"--section <section>",

View File

@@ -15,7 +15,7 @@ export function registerCronCli(program: Command) {
.description("Manage cron jobs (via Gateway)")
.addHelpText(
"after",
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/cron", "docs.clawd.bot/cli/cron")}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/cron", "docs.molt.bot/cli/cron")}\n`,
);
registerCronStatusCommand(cron);

View File

@@ -18,7 +18,7 @@ export function registerDaemonCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/gateway", "docs.clawd.bot/cli/gateway")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/gateway", "docs.molt.bot/cli/gateway")}\n`,
);
daemon

View File

@@ -322,5 +322,5 @@ export function printDaemonStatus(status: DaemonStatus, opts: { json: boolean })
}
defaultRuntime.log(`${label("Troubles:")} run ${formatCliCommand("clawdbot status")}`);
defaultRuntime.log(`${label("Troubleshooting:")} https://docs.clawd.bot/troubleshooting`);
defaultRuntime.log(`${label("Troubleshooting:")} https://docs.molt.bot/troubleshooting`);
}

View File

@@ -39,7 +39,7 @@ export function registerDirectoryCli(program: Command) {
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink(
"/cli/directory",
"docs.clawd.bot/cli/directory",
"docs.molt.bot/cli/directory",
)}\n`,
)
.action(() => {

View File

@@ -97,7 +97,7 @@ export function registerDnsCli(program: Command) {
.description("DNS helpers for wide-area discovery (Tailscale + CoreDNS)")
.addHelpText(
"after",
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/dns", "docs.clawd.bot/cli/dns")}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/dns", "docs.molt.bot/cli/dns")}\n`,
);
dns

View File

@@ -13,7 +13,7 @@ export function registerDocsCli(program: Command) {
.argument("[query...]", "Search query")
.addHelpText(
"after",
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/docs", "docs.clawd.bot/cli/docs")}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/docs", "docs.molt.bot/cli/docs")}\n`,
)
.action(async (queryParts: string[]) => {
await runCommandWithRuntime(defaultRuntime, async () => {

View File

@@ -233,7 +233,7 @@ export function registerExecApprovalsCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/approvals", "docs.clawd.bot/cli/approvals")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/approvals", "docs.molt.bot/cli/approvals")}\n`,
);
const getCmd = approvals
@@ -337,7 +337,7 @@ export function registerExecApprovalsCli(program: Command) {
)}\n${formatExample(
'clawdbot approvals allowlist remove "~/Projects/**/bin/rg"',
"Remove an allowlist pattern.",
)}\n\n${theme.muted("Docs:")} ${formatDocsLink("/cli/approvals", "docs.clawd.bot/cli/approvals")}\n`,
)}\n\n${theme.muted("Docs:")} ${formatDocsLink("/cli/approvals", "docs.molt.bot/cli/approvals")}\n`,
);
const allowlistAdd = allowlist

View File

@@ -103,7 +103,7 @@ export function registerGatewayCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/gateway", "docs.clawd.bot/cli/gateway")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/gateway", "docs.molt.bot/cli/gateway")}\n`,
),
);

View File

@@ -16,7 +16,7 @@ const report: HookStatusReport = {
handlerPath: "/tmp/hooks/session-memory/handler.js",
hookKey: "session-memory",
emoji: "💾",
homepage: "https://docs.clawd.bot/hooks#session-memory",
homepage: "https://docs.molt.bot/hooks#session-memory",
events: ["command:new"],
always: false,
disabled: false,

View File

@@ -424,7 +424,7 @@ export function registerHooksCli(program: Command): void {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/hooks", "docs.clawd.bot/cli/hooks")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/hooks", "docs.molt.bot/cli/hooks")}\n`,
);
hooks

View File

@@ -180,7 +180,7 @@ export function registerLogsCli(program: Command) {
.option("--no-color", "Disable ANSI colors")
.addHelpText(
"after",
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/logs", "docs.clawd.bot/cli/logs")}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/logs", "docs.molt.bot/cli/logs")}\n`,
);
addGatewayClientOptions(logs);

View File

@@ -424,7 +424,7 @@ export function registerMemoryCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/memory", "docs.clawd.bot/cli/memory")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/memory", "docs.molt.bot/cli/memory")}\n`,
);
memory

View File

@@ -44,7 +44,7 @@ export function registerModelsCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/models", "docs.clawd.bot/cli/models")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/models", "docs.molt.bot/cli/models")}\n`,
);
models

View File

@@ -23,7 +23,7 @@ export function registerNodeCli(program: Command) {
.description("Run a headless node host (system.run/system.which)")
.addHelpText(
"after",
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/node", "docs.clawd.bot/cli/node")}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/node", "docs.molt.bot/cli/node")}\n`,
);
node

View File

@@ -51,11 +51,11 @@ describe("nodes camera helpers", () => {
tmpDir: "/tmp",
id: "id1",
});
expect(p).toBe(path.join("/tmp", "clawdbot-camera-snap-front-id1.jpg"));
expect(p).toBe(path.join("/tmp", "moltbot-camera-snap-front-id1.jpg"));
});
it("writes base64 to file", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-test-"));
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-test-"));
const out = path.join(dir, "x.bin");
await writeBase64ToFile(out, "aGk=");
await expect(fs.readFile(out, "utf8")).resolves.toBe("hi");

View File

@@ -3,6 +3,8 @@ import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { resolveCliName } from "./cli-name.js";
export type CameraFacing = "front" | "back";
export type CameraSnapPayload = {
@@ -70,7 +72,8 @@ export function cameraTempPath(opts: {
const id = opts.id ?? randomUUID();
const facingPart = opts.facing ? `-${opts.facing}` : "";
const ext = opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`;
return path.join(tmpDir, `clawdbot-camera-${opts.kind}${facingPart}-${id}${ext}`);
const cliName = resolveCliName();
return path.join(tmpDir, `${cliName}-camera-${opts.kind}${facingPart}-${id}${ext}`);
}
export async function writeBase64ToFile(filePath: string, base64: string) {

View File

@@ -2,6 +2,8 @@ import { randomUUID } from "node:crypto";
import * as os from "node:os";
import * as path from "node:path";
import { resolveCliName } from "./cli-name.js";
export type CanvasSnapshotPayload = {
format: string;
base64: string;
@@ -29,5 +31,6 @@ export function canvasSnapshotTempPath(opts: { ext: string; tmpDir?: string; id?
const tmpDir = opts.tmpDir ?? os.tmpdir();
const id = opts.id ?? randomUUID();
const ext = opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`;
return path.join(tmpDir, `clawdbot-canvas-snapshot-${id}${ext}`);
const cliName = resolveCliName();
return path.join(tmpDir, `${cliName}-canvas-snapshot-${id}${ext}`);
}

View File

@@ -17,7 +17,7 @@ export function registerNodesCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/nodes", "docs.clawd.bot/cli/nodes")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/nodes", "docs.molt.bot/cli/nodes")}\n`,
);
registerNodesStatusCommands(nodes);

View File

@@ -53,7 +53,7 @@ export function registerPairingCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/pairing", "docs.clawd.bot/cli/pairing")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/pairing", "docs.molt.bot/cli/pairing")}\n`,
);
pairing

View File

@@ -98,7 +98,7 @@ export function registerPluginsCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/plugins", "docs.clawd.bot/cli/plugins")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/plugins", "docs.molt.bot/cli/plugins")}\n`,
);
plugins
@@ -521,7 +521,7 @@ export function registerPluginsCli(program: Command) {
lines.push(`- ${target}${diag.message}`);
}
}
const docs = formatDocsLink("/plugin", "docs.clawd.bot/plugin");
const docs = formatDocsLink("/plugin", "docs.molt.bot/plugin");
lines.push("");
lines.push(`${theme.muted("Docs:")} ${docs}`);
defaultRuntime.log(lines.join("\n"));

View File

@@ -80,60 +80,60 @@ describe("applyCliProfileEnv", () => {
describe("formatCliCommand", () => {
it("returns command unchanged when no profile is set", () => {
expect(formatCliCommand("clawdbot doctor --fix", {})).toBe("clawdbot doctor --fix");
expect(formatCliCommand("clawdbot doctor --fix", {})).toBe("moltbot doctor --fix");
});
it("returns command unchanged when profile is default", () => {
expect(formatCliCommand("clawdbot doctor --fix", { CLAWDBOT_PROFILE: "default" })).toBe(
"clawdbot doctor --fix",
"moltbot doctor --fix",
);
});
it("returns command unchanged when profile is Default (case-insensitive)", () => {
expect(formatCliCommand("clawdbot doctor --fix", { CLAWDBOT_PROFILE: "Default" })).toBe(
"clawdbot doctor --fix",
"moltbot doctor --fix",
);
});
it("returns command unchanged when profile is invalid", () => {
expect(formatCliCommand("clawdbot doctor --fix", { CLAWDBOT_PROFILE: "bad profile" })).toBe(
"clawdbot doctor --fix",
"moltbot doctor --fix",
);
});
it("returns command unchanged when --profile is already present", () => {
expect(
formatCliCommand("clawdbot --profile work doctor --fix", { CLAWDBOT_PROFILE: "work" }),
).toBe("clawdbot --profile work doctor --fix");
).toBe("moltbot --profile work doctor --fix");
});
it("returns command unchanged when --dev is already present", () => {
expect(formatCliCommand("clawdbot --dev doctor", { CLAWDBOT_PROFILE: "dev" })).toBe(
"clawdbot --dev doctor",
"moltbot --dev doctor",
);
});
it("inserts --profile flag when profile is set", () => {
expect(formatCliCommand("clawdbot doctor --fix", { CLAWDBOT_PROFILE: "work" })).toBe(
"clawdbot --profile work doctor --fix",
"moltbot --profile work doctor --fix",
);
});
it("trims whitespace from profile", () => {
expect(formatCliCommand("clawdbot doctor --fix", { CLAWDBOT_PROFILE: " jbclawd " })).toBe(
"clawdbot --profile jbclawd doctor --fix",
"moltbot --profile jbclawd doctor --fix",
);
});
it("handles command with no args after clawdbot", () => {
expect(formatCliCommand("clawdbot", { CLAWDBOT_PROFILE: "test" })).toBe(
"clawdbot --profile test",
"moltbot --profile test",
);
});
it("handles pnpm wrapper", () => {
expect(formatCliCommand("pnpm clawdbot doctor", { CLAWDBOT_PROFILE: "work" })).toBe(
"pnpm clawdbot --profile work doctor",
"pnpm moltbot --profile work doctor",
);
});
});

View File

@@ -174,7 +174,7 @@ describe("cli program (nodes media)", () => {
const out = String(runtime.log.mock.calls[0]?.[0] ?? "");
const mediaPath = out.replace(/^MEDIA:/, "").trim();
expect(mediaPath).toMatch(/clawdbot-camera-clip-front-.*\.mp4$/);
expect(mediaPath).toMatch(/moltbot-camera-clip-front-.*\.mp4$/);
try {
await expect(fs.readFile(mediaPath, "utf8")).resolves.toBe("hi");
@@ -421,7 +421,7 @@ describe("cli program (nodes media)", () => {
const out = String(runtime.log.mock.calls[0]?.[0] ?? "");
const mediaPath = out.replace(/^MEDIA:/, "").trim();
expect(mediaPath).toMatch(/clawdbot-canvas-snapshot-.*\.png$/);
expect(mediaPath).toMatch(/moltbot-canvas-snapshot-.*\.png$/);
try {
await expect(fs.readFile(mediaPath, "utf8")).resolves.toBe("hi");

View File

@@ -2,8 +2,11 @@ import type { Command } from "commander";
import { formatDocsLink } from "../../terminal/links.js";
import { isRich, theme } from "../../terminal/theme.js";
import { formatCliBannerLine, hasEmittedCliBanner } from "../banner.js";
import { replaceCliName, resolveCliName } from "../cli-name.js";
import type { ProgramContext } from "./context.js";
const CLI_NAME = resolveCliName();
const EXAMPLES = [
[
"clawdbot channels login --verbose",
@@ -29,7 +32,7 @@ const EXAMPLES = [
export function configureProgramHelp(program: Command, ctx: ProgramContext) {
program
.name("clawdbot")
.name(CLI_NAME)
.description("")
.version(ctx.programVersion)
.option(
@@ -77,12 +80,12 @@ export function configureProgramHelp(program: Command, ctx: ProgramContext) {
});
const fmtExamples = EXAMPLES.map(
([cmd, desc]) => ` ${theme.command(cmd)}\n ${theme.muted(desc)}`,
([cmd, desc]) => ` ${theme.command(replaceCliName(cmd, CLI_NAME))}\n ${theme.muted(desc)}`,
).join("\n");
program.addHelpText("afterAll", ({ command }) => {
if (command !== program) return "";
const docs = formatDocsLink("/cli", "docs.clawd.bot/cli");
const docs = formatDocsLink("/cli", "docs.molt.bot/cli");
return `\n${theme.heading("Examples:")}\n${fmtExamples}\n\n${theme.muted("Docs:")} ${docs}\n`;
});
}

View File

@@ -6,6 +6,7 @@ import { ensureConfigReady } from "./config-guard.js";
import { ensurePluginRegistryLoaded } from "../plugin-registry.js";
import { isTruthyEnvValue } from "../../infra/env.js";
import { setVerbose } from "../../globals.js";
import { resolveCliName } from "../cli-name.js";
function setProcessTitleForCommand(actionCommand: Command) {
let current: Command = actionCommand;
@@ -13,8 +14,9 @@ function setProcessTitleForCommand(actionCommand: Command) {
current = current.parent;
}
const name = current.name();
if (!name || name === "clawdbot") return;
process.title = `clawdbot-${name}`;
const cliName = resolveCliName();
if (!name || name === cliName) return;
process.title = `${cliName}-${name}`;
}
// Commands that need channel plugins loaded

View File

@@ -68,7 +68,7 @@ ${formatHelpExamples([
],
])}
${theme.muted("Docs:")} ${formatDocsLink("/cli/agent", "docs.clawd.bot/cli/agent")}`,
${theme.muted("Docs:")} ${formatDocsLink("/cli/agent", "docs.molt.bot/cli/agent")}`,
)
.action(async (opts) => {
const verboseLevel = typeof opts.verbose === "string" ? opts.verbose.toLowerCase() : "";
@@ -86,7 +86,7 @@ ${theme.muted("Docs:")} ${formatDocsLink("/cli/agent", "docs.clawd.bot/cli/agent
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/agents", "docs.clawd.bot/cli/agents")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/agents", "docs.molt.bot/cli/agents")}\n`,
);
agents

View File

@@ -16,7 +16,7 @@ export function registerConfigureCommand(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/configure", "docs.clawd.bot/cli/configure")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/configure", "docs.molt.bot/cli/configure")}\n`,
)
.option(
"--section <section>",

View File

@@ -15,7 +15,7 @@ export function registerMaintenanceCommands(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/doctor", "docs.clawd.bot/cli/doctor")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/doctor", "docs.molt.bot/cli/doctor")}\n`,
)
.option("--no-workspace-suggestions", "Disable workspace memory system suggestions", false)
.option("--yes", "Accept defaults without prompting", false)
@@ -45,7 +45,7 @@ export function registerMaintenanceCommands(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/dashboard", "docs.clawd.bot/cli/dashboard")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/dashboard", "docs.molt.bot/cli/dashboard")}\n`,
)
.option("--no-open", "Print URL but do not launch a browser", false)
.action(async (opts) => {
@@ -62,7 +62,7 @@ export function registerMaintenanceCommands(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/reset", "docs.clawd.bot/cli/reset")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/reset", "docs.molt.bot/cli/reset")}\n`,
)
.option("--scope <scope>", "config|config+creds+sessions|full (default: interactive prompt)")
.option("--yes", "Skip confirmation prompts", false)
@@ -85,7 +85,7 @@ export function registerMaintenanceCommands(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/uninstall", "docs.clawd.bot/cli/uninstall")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/uninstall", "docs.molt.bot/cli/uninstall")}\n`,
)
.option("--service", "Remove the gateway service", false)
.option("--state", "Remove state + config", false)

View File

@@ -46,7 +46,7 @@ ${formatHelpExamples([
],
])}
${theme.muted("Docs:")} ${formatDocsLink("/cli/message", "docs.clawd.bot/cli/message")}`,
${theme.muted("Docs:")} ${formatDocsLink("/cli/message", "docs.molt.bot/cli/message")}`,
)
.action(() => {
message.help({ error: true });

View File

@@ -38,7 +38,7 @@ export function registerOnboardCommand(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/onboard", "docs.clawd.bot/cli/onboard")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/onboard", "docs.molt.bot/cli/onboard")}\n`,
)
.option("--workspace <dir>", "Agent workspace directory (default: ~/clawd)")
.option("--reset", "Reset config + credentials + sessions + workspace before running wizard")

View File

@@ -14,7 +14,7 @@ export function registerSetupCommand(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/setup", "docs.clawd.bot/cli/setup")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/setup", "docs.molt.bot/cli/setup")}\n`,
)
.option(
"--workspace <dir>",

View File

@@ -53,7 +53,7 @@ export function registerStatusHealthSessionsCommands(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/status", "docs.clawd.bot/cli/status")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/status", "docs.molt.bot/cli/status")}\n`,
)
.action(async (opts) => {
const verbose = resolveVerbose(opts);
@@ -87,7 +87,7 @@ export function registerStatusHealthSessionsCommands(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/health", "docs.clawd.bot/cli/health")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/health", "docs.molt.bot/cli/health")}\n`,
)
.action(async (opts) => {
const verbose = resolveVerbose(opts);
@@ -130,7 +130,7 @@ export function registerStatusHealthSessionsCommands(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sessions", "docs.clawd.bot/cli/sessions")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sessions", "docs.molt.bot/cli/sessions")}\n`,
)
.action(async (opts) => {
setVerbose(Boolean(opts.verbose));

View File

@@ -68,7 +68,7 @@ export function registerSandboxCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sandbox", "docs.clawd.bot/cli/sandbox")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sandbox", "docs.molt.bot/cli/sandbox")}\n`,
)
.action(() => {
sandbox.help({ error: true });

View File

@@ -34,7 +34,7 @@ export function registerSecurityCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/security", "docs.clawd.bot/cli/security")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/security", "docs.molt.bot/cli/security")}\n`,
);
security

View File

@@ -337,7 +337,7 @@ export function registerSkillsCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/skills", "docs.clawd.bot/cli/skills")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/skills", "docs.molt.bot/cli/skills")}\n`,
);
skills

View File

@@ -23,7 +23,7 @@ export function registerSystemCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/system", "docs.clawd.bot/cli/system")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/system", "docs.molt.bot/cli/system")}\n`,
);
addGatewayClientOptions(

View File

@@ -20,7 +20,7 @@ export function registerTuiCli(program: Command) {
.option("--history-limit <n>", "History entries to load", "200")
.addHelpText(
"after",
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/tui", "docs.clawd.bot/cli/tui")}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/tui", "docs.molt.bot/cli/tui")}\n`,
)
.action(async (opts) => {
try {

View File

@@ -39,6 +39,7 @@ import { trimLogTail } from "../infra/restart-sentinel.js";
import { defaultRuntime } from "../runtime.js";
import { formatDocsLink } from "../terminal/links.js";
import { formatCliCommand } from "./command-format.js";
import { replaceCliName, resolveCliName } from "./cli-name.js";
import { stylePromptHint, stylePromptMessage } from "../terminal/prompt-style.js";
import { theme } from "../terminal/theme.js";
import { renderTable } from "../terminal/table.js";
@@ -81,6 +82,7 @@ const STEP_LABELS: Record<string, string> = {
build: "Building",
"ui:build": "Building UI",
"clawdbot doctor": "Running doctor checks",
"moltbot doctor": "Running doctor checks",
"git rev-parse HEAD (after)": "Verifying update",
"global update": "Updating via package manager",
"global install": "Installing global package",
@@ -110,6 +112,9 @@ const UPDATE_QUIPS = [
];
const MAX_LOG_CHARS = 8000;
const DEFAULT_PACKAGE_NAME = "moltbot";
const CORE_PACKAGE_NAMES = new Set([DEFAULT_PACKAGE_NAME, "clawdbot"]);
const CLI_NAME = resolveCliName();
const CLAWDBOT_REPO_URL = "https://github.com/clawdbot/clawdbot.git";
const DEFAULT_GIT_DIR = path.join(os.homedir(), "clawdbot");
@@ -117,7 +122,11 @@ function normalizeTag(value?: string | null): string | null {
if (!value) return null;
const trimmed = value.trim();
if (!trimmed) return null;
return trimmed.startsWith("clawdbot@") ? trimmed.slice("clawdbot@".length) : trimmed;
if (trimmed.startsWith("clawdbot@")) return trimmed.slice("clawdbot@".length);
if (trimmed.startsWith(`${DEFAULT_PACKAGE_NAME}@`)) {
return trimmed.slice(`${DEFAULT_PACKAGE_NAME}@`.length);
}
return trimmed;
}
function pickUpdateQuip(): string {
@@ -157,16 +166,22 @@ async function isGitCheckout(root: string): Promise<boolean> {
}
}
async function isClawdbotPackage(root: string): Promise<boolean> {
async function readPackageName(root: string): Promise<string | null> {
try {
const raw = await fs.readFile(path.join(root, "package.json"), "utf-8");
const parsed = JSON.parse(raw) as { name?: string };
return parsed?.name === "clawdbot";
const name = parsed?.name?.trim();
return name ? name : null;
} catch {
return false;
return null;
}
}
async function isCorePackage(root: string): Promise<boolean> {
const name = await readPackageName(root);
return Boolean(name && CORE_PACKAGE_NAMES.has(name));
}
async function pathExists(targetPath: string): Promise<boolean> {
try {
await fs.stat(targetPath);
@@ -269,8 +284,8 @@ async function ensureGitCheckout(params: {
});
}
if (!(await isClawdbotPackage(params.dir))) {
throw new Error(`CLAWDBOT_GIT_DIR does not look like a clawdbot checkout: ${params.dir}.`);
if (!(await isCorePackage(params.dir))) {
throw new Error(`CLAWDBOT_GIT_DIR does not look like a core checkout: ${params.dir}.`);
}
return null;
@@ -691,10 +706,13 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
return { stdout: res.stdout, stderr: res.stderr, code: res.code };
};
const pkgRoot = await resolveGlobalPackageRoot(manager, runCommand, timeoutMs ?? 20 * 60_000);
const packageName =
(pkgRoot ? await readPackageName(pkgRoot) : await readPackageName(root)) ??
DEFAULT_PACKAGE_NAME;
const beforeVersion = pkgRoot ? await readPackageVersion(pkgRoot) : null;
const updateStep = await runUpdateStep({
name: "global update",
argv: globalInstallArgs(manager, `clawdbot@${tag}`),
argv: globalInstallArgs(manager, `${packageName}@${tag}`),
timeoutMs: timeoutMs ?? 20 * 60_000,
progress,
});
@@ -705,7 +723,7 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
const entryPath = path.join(pkgRoot, "dist", "entry.js");
if (await pathExists(entryPath)) {
const doctorStep = await runUpdateStep({
name: "clawdbot doctor",
name: `${CLI_NAME} doctor`,
argv: [resolveNodeRunner(), entryPath, "doctor", "--non-interactive"],
timeoutMs: timeoutMs ?? 20 * 60_000,
progress,
@@ -806,11 +824,13 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
if (result.reason === "not-git-install") {
defaultRuntime.log(
theme.warn(
`Skipped: this Clawdbot install isn't a git checkout, and the package manager couldn't be detected. Update via your package manager, then run \`${formatCliCommand("clawdbot doctor")}\` and \`${formatCliCommand("clawdbot gateway restart")}\`.`,
`Skipped: this Clawdbot install isn't a git checkout, and the package manager couldn't be detected. Update via your package manager, then run \`${replaceCliName(formatCliCommand("clawdbot doctor"), CLI_NAME)}\` and \`${replaceCliName(formatCliCommand("clawdbot gateway restart"), CLI_NAME)}\`.`,
),
);
defaultRuntime.log(
theme.muted("Examples: `npm i -g clawdbot@latest` or `pnpm add -g clawdbot@latest`"),
theme.muted(
`Examples: \`${replaceCliName("npm i -g clawdbot@latest", CLI_NAME)}\` or \`${replaceCliName("pnpm add -g clawdbot@latest", CLI_NAME)}\``,
),
);
}
defaultRuntime.exit(0);
@@ -926,7 +946,7 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
defaultRuntime.log(theme.warn(`Daemon restart failed: ${String(err)}`));
defaultRuntime.log(
theme.muted(
`You may need to restart the service manually: ${formatCliCommand("clawdbot gateway restart")}`,
`You may need to restart the service manually: ${replaceCliName(formatCliCommand("clawdbot gateway restart"), CLI_NAME)}`,
),
);
}
@@ -936,13 +956,13 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise<void> {
if (result.mode === "npm" || result.mode === "pnpm") {
defaultRuntime.log(
theme.muted(
`Tip: Run \`${formatCliCommand("clawdbot doctor")}\`, then \`${formatCliCommand("clawdbot gateway restart")}\` to apply updates to a running gateway.`,
`Tip: Run \`${replaceCliName(formatCliCommand("clawdbot doctor"), CLI_NAME)}\`, then \`${replaceCliName(formatCliCommand("clawdbot gateway restart"), CLI_NAME)}\` to apply updates to a running gateway.`,
),
);
} else {
defaultRuntime.log(
theme.muted(
`Tip: Run \`${formatCliCommand("clawdbot gateway restart")}\` to apply updates to a running gateway.`,
`Tip: Run \`${replaceCliName(formatCliCommand("clawdbot gateway restart"), CLI_NAME)}\` to apply updates to a running gateway.`,
),
);
}
@@ -1137,7 +1157,7 @@ ${theme.heading("Notes:")}
- Downgrades require confirmation (can break configuration)
- Skips update if the working directory has uncommitted changes
${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.clawd.bot/cli/update")}`;
${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.molt.bot/cli/update")}`;
})
.action(async (opts) => {
try {
@@ -1161,7 +1181,7 @@ ${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.clawd.bot/cli/upda
.option("--timeout <seconds>", "Timeout for each update step in seconds (default: 1200)")
.addHelpText(
"after",
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.clawd.bot/cli/update")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.molt.bot/cli/update")}\n`,
)
.action(async (opts) => {
try {
@@ -1188,7 +1208,7 @@ ${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.clawd.bot/cli/upda
"- Shows current update channel (stable/beta/dev) and source",
)}\n${theme.muted("- Includes git tag/branch/SHA for source checkouts")}\n\n${theme.muted(
"Docs:",
)} ${formatDocsLink("/cli/update", "docs.clawd.bot/cli/update")}`,
)} ${formatDocsLink("/cli/update", "docs.molt.bot/cli/update")}`,
)
.action(async (opts) => {
try {

View File

@@ -28,7 +28,7 @@ export function registerWebhooksCli(program: Command) {
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/webhooks", "docs.clawd.bot/cli/webhooks")}\n`,
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/webhooks", "docs.molt.bot/cli/webhooks")}\n`,
);
const gmail = webhooks.command("gmail").description("Gmail Pub/Sub hooks (via gogcli)");