chore: rename project to clawdbot

This commit is contained in:
Peter Steinberger
2026-01-04 14:32:47 +00:00
parent d48dc71fa4
commit 246adaa119
841 changed files with 4590 additions and 4328 deletions

View File

@@ -18,7 +18,7 @@ vi.mock("../agents/pi-embedded.js", () => ({
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
import { getReplyFromConfig } from "../auto-reply/reply.js";
import type { ClawdisConfig } from "../config/config.js";
import type { ClawdbotConfig } from "../config/config.js";
import { resetLogger, setLoggerOverride } from "../logging.js";
import {
HEARTBEAT_TOKEN,
@@ -58,7 +58,7 @@ const rmDirWithRetries = async (dir: string): Promise<void> => {
beforeEach(async () => {
previousHome = process.env.HOME;
tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "clawdis-web-home-"));
tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-web-home-"));
process.env.HOME = tempHome;
});
@@ -73,7 +73,7 @@ afterEach(async () => {
const makeSessionStore = async (
entries: Record<string, unknown> = {},
): Promise<{ storePath: string; cleanup: () => Promise<void> }> => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdis-session-"));
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-session-"));
const storePath = path.join(dir, "sessions.json");
await fs.writeFile(storePath, JSON.stringify(entries));
const cleanup = async () => {
@@ -112,7 +112,7 @@ describe("partial reply gating", () => {
const replyResolver = vi.fn().mockResolvedValue({ text: "final reply" });
const mockConfig: ClawdisConfig = {
const mockConfig: ClawdbotConfig = {
whatsapp: {
allowFrom: ["*"],
},
@@ -159,7 +159,7 @@ describe("partial reply gating", () => {
const replyResolver = vi.fn().mockResolvedValue(undefined);
const mockConfig: ClawdisConfig = {
const mockConfig: ClawdbotConfig = {
whatsapp: {
allowFrom: ["*"],
},
@@ -500,11 +500,11 @@ describe("web auto-reply", () => {
const firstArgs = resolver.mock.calls[0][0];
const secondArgs = resolver.mock.calls[1][0];
expect(firstArgs.Body).toContain(
"[WhatsApp +1 2025-01-01T01:00+01:00{Europe/Vienna}] [clawdis] first",
"[WhatsApp +1 2025-01-01T01:00+01:00{Europe/Vienna}] [clawdbot] first",
);
expect(firstArgs.Body).not.toContain("second");
expect(secondArgs.Body).toContain(
"[WhatsApp +1 2025-01-01T02:00+01:00{Europe/Vienna}] [clawdis] second",
"[WhatsApp +1 2025-01-01T02:00+01:00{Europe/Vienna}] [clawdbot] second",
);
expect(secondArgs.Body).not.toContain("first");
@@ -1265,7 +1265,7 @@ describe("web auto-reply", () => {
it("emits heartbeat logs with connection metadata", async () => {
vi.useFakeTimers();
const logPath = `/tmp/clawdis-heartbeat-${crypto.randomUUID()}.log`;
const logPath = `/tmp/clawdbot-heartbeat-${crypto.randomUUID()}.log`;
setLoggerOverride({ level: "trace", file: logPath });
const runtime = {
@@ -1307,7 +1307,7 @@ describe("web auto-reply", () => {
});
it("logs outbound replies to file", async () => {
const logPath = `/tmp/clawdis-log-test-${crypto.randomUUID()}.log`;
const logPath = `/tmp/clawdbot-log-test-${crypto.randomUUID()}.log`;
setLoggerOverride({ level: "trace", file: logPath });
let capturedOnMessage:

View File

@@ -943,7 +943,7 @@ export async function monitorWebProvider(
let messagePrefix = cfg.messages?.messagePrefix;
if (messagePrefix === undefined) {
const hasAllowFrom = (cfg.whatsapp?.allowFrom?.length ?? 0) > 0;
messagePrefix = hasAllowFrom ? "" : "[clawdis]";
messagePrefix = hasAllowFrom ? "" : "[clawdbot]";
}
const prefixStr = messagePrefix ? `${messagePrefix} ` : "";
const senderLabel =
@@ -1552,7 +1552,7 @@ export async function monitorWebProvider(
if (loggedOut) {
runtime.error(
"WhatsApp session logged out. Run `clawdis login --provider web` to relink.",
"WhatsApp session logged out. Run `clawdbot login --provider web` to relink.",
);
await closeListener();
break;

View File

@@ -20,7 +20,7 @@ vi.mock("../config/config.js", () => ({
const HOME = path.join(
os.tmpdir(),
`clawdis-inbound-media-${crypto.randomUUID()}`,
`clawdbot-inbound-media-${crypto.randomUUID()}`,
);
process.env.HOME = HOME;

View File

@@ -59,7 +59,7 @@ export async function loginWeb(
await fs.rm(resolveWebAuthDir(), { recursive: true, force: true });
console.error(
danger(
"WhatsApp reported the session is logged out. Cleared cached web session; please rerun clawdis login and scan the QR again.",
"WhatsApp reported the session is logged out. Cleared cached web session; please rerun clawdbot login and scan the QR again.",
),
);
throw new Error("Session logged out; cache cleared. Re-run login.");

View File

@@ -17,7 +17,7 @@ describe("web logout", () => {
beforeEach(() => {
vi.clearAllMocks();
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdis-logout-"));
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "clawdbot-logout-"));
vi.spyOn(os, "homedir").mockReturnValue(tmpDir);
vi.resetModules();
vi.doMock("../utils.js", async () => {
@@ -25,7 +25,7 @@ describe("web logout", () => {
await vi.importActual<typeof import("../utils.js")>("../utils.js");
return {
...actual,
CONFIG_DIR: path.join(tmpDir, ".clawdis"),
CONFIG_DIR: path.join(tmpDir, ".clawdbot"),
};
});
});
@@ -45,12 +45,12 @@ describe("web logout", () => {
"deletes cached credentials when present",
{ timeout: 15_000 },
async () => {
const credsDir = path.join(tmpDir, ".clawdis", "credentials");
const credsDir = path.join(tmpDir, ".clawdbot", "credentials");
fs.mkdirSync(credsDir, { recursive: true });
fs.writeFileSync(path.join(credsDir, "creds.json"), "{}");
const sessionsPath = path.join(
tmpDir,
".clawdis",
".clawdbot",
"sessions",
"sessions.json",
);

View File

@@ -27,7 +27,7 @@ describe("web media loading", () => {
.jpeg({ quality: 95 })
.toBuffer();
const file = path.join(os.tmpdir(), `clawdis-media-${Date.now()}.jpg`);
const file = path.join(os.tmpdir(), `clawdbot-media-${Date.now()}.jpg`);
tmpFiles.push(file);
await fs.writeFile(file, buffer);
@@ -45,7 +45,7 @@ describe("web media loading", () => {
})
.png()
.toBuffer();
const wrongExt = path.join(os.tmpdir(), `clawdis-media-${Date.now()}.bin`);
const wrongExt = path.join(os.tmpdir(), `clawdbot-media-${Date.now()}.bin`);
tmpFiles.push(wrongExt);
await fs.writeFile(wrongExt, pngBuffer);
@@ -110,7 +110,7 @@ describe("web media loading", () => {
0x3b, // minimal LZW data + trailer
]);
const file = path.join(os.tmpdir(), `clawdis-media-${Date.now()}.gif`);
const file = path.join(os.tmpdir(), `clawdbot-media-${Date.now()}.gif`);
tmpFiles.push(file);
await fs.writeFile(file, gifBuffer);

View File

@@ -322,7 +322,7 @@ describe("web monitor inbox", () => {
it("logs inbound bodies to file", async () => {
const logPath = path.join(
os.tmpdir(),
`clawdis-log-test-${crypto.randomUUID()}.log`,
`clawdbot-log-test-${crypto.randomUUID()}.log`,
);
setLoggerOverride({ level: "trace", file: logPath });

View File

@@ -4,7 +4,7 @@ import { renderQrPngBase64 } from "./qr-image.js";
describe("renderQrPngBase64", () => {
it("renders a PNG data payload", async () => {
const b64 = await renderQrPngBase64("clawdis");
const b64 = await renderQrPngBase64("clawdbot");
const buf = Buffer.from(b64, "base64");
expect(buf.subarray(0, 8).toString("hex")).toBe("89504e470d0a1a0a");
});

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import type { ClawdisConfig } from "../config/config.js";
import type { ClawdbotConfig } from "../config/config.js";
import {
computeBackoff,
DEFAULT_HEARTBEAT_SECONDS,
@@ -11,7 +11,7 @@ import {
} from "./reconnect.js";
describe("web reconnect helpers", () => {
const cfg: ClawdisConfig = {};
const cfg: ClawdbotConfig = {};
it("resolves sane reconnect defaults with clamps", () => {
const policy = resolveReconnectPolicy(cfg, {

View File

@@ -1,6 +1,6 @@
import { randomUUID } from "node:crypto";
import type { ClawdisConfig } from "../config/config.js";
import type { ClawdbotConfig } from "../config/config.js";
export type ReconnectPolicy = {
initialMs: number;
@@ -23,7 +23,7 @@ const clamp = (val: number, min: number, max: number) =>
Math.max(min, Math.min(max, val));
export function resolveHeartbeatSeconds(
cfg: ClawdisConfig,
cfg: ClawdbotConfig,
overrideSeconds?: number,
): number {
const candidate = overrideSeconds ?? cfg.web?.heartbeatSeconds;
@@ -32,7 +32,7 @@ export function resolveHeartbeatSeconds(
}
export function resolveReconnectPolicy(
cfg: ClawdisConfig,
cfg: ClawdbotConfig,
overrides?: Partial<ReconnectPolicy>,
): ReconnectPolicy {
const reconnectOverrides = cfg.web?.reconnect ?? {};

View File

@@ -111,7 +111,7 @@ describe("web session", () => {
});
it("does not clobber creds backup when creds.json is corrupted", async () => {
const credsSuffix = path.join(".clawdis", "credentials", "creds.json");
const credsSuffix = path.join(".clawdbot", "credentials", "creds.json");
const copySpy = vi
.spyOn(fsSync, "copyFileSync")
@@ -191,8 +191,8 @@ describe("web session", () => {
});
it("rotates creds backup when creds.json is valid JSON", async () => {
const credsSuffix = path.join(".clawdis", "credentials", "creds.json");
const backupSuffix = path.join(".clawdis", "credentials", "creds.json.bak");
const credsSuffix = path.join(".clawdbot", "credentials", "creds.json");
const backupSuffix = path.join(".clawdbot", "credentials", "creds.json.bak");
const copySpy = vi
.spyOn(fsSync, "copyFileSync")

View File

@@ -21,7 +21,7 @@ import { CONFIG_DIR, ensureDir, jidToE164 } from "../utils.js";
import { VERSION } from "../version.js";
export function resolveWebAuthDir() {
return path.join(os.homedir(), ".clawdis", "credentials");
return path.join(os.homedir(), ".clawdbot", "credentials");
}
function resolveWebCredsPath() {
@@ -143,7 +143,7 @@ export async function createWaSocket(
version,
logger,
printQRInTerminal: false,
browser: ["clawdis", "cli", VERSION],
browser: ["clawdbot", "cli", VERSION],
syncFullHistory: false,
markOnlineOnConnect: false,
});
@@ -165,7 +165,7 @@ export async function createWaSocket(
const status = getStatusCode(lastDisconnect?.error);
if (status === DisconnectReason.loggedOut) {
console.error(
danger("WhatsApp session logged out. Run: clawdis login"),
danger("WhatsApp session logged out. Run: clawdbot login"),
);
}
}
@@ -413,7 +413,7 @@ export async function pickProvider(pref: Provider | "auto"): Promise<Provider> {
const hasWeb = await webAuthExists();
if (!hasWeb) {
throw new Error(
"No WhatsApp Web session found. Run `clawdis login --verbose` to link.",
"No WhatsApp Web session found. Run `clawdbot login --verbose` to link.",
);
}
return choice;

View File

@@ -4,7 +4,7 @@ import type { MockBaileysSocket } from "../../test/mocks/baileys.js";
import { createMockBaileys } from "../../test/mocks/baileys.js";
// Use globalThis to store the mock config so it survives vi.mock hoisting
const CONFIG_KEY = Symbol.for("clawdis:testConfigMock");
const CONFIG_KEY = Symbol.for("clawdbot:testConfigMock");
const DEFAULT_CONFIG = {
whatsapp: {
// Tests can override; default remains open to avoid surprising fixtures
@@ -53,7 +53,7 @@ vi.mock("../media/store.js", () => ({
vi.mock("@whiskeysockets/baileys", () => {
const created = createMockBaileys();
(globalThis as Record<PropertyKey, unknown>)[
Symbol.for("clawdis:lastSocket")
Symbol.for("clawdbot:lastSocket")
] = created.lastSocket;
return created.mod;
});
@@ -75,7 +75,7 @@ export const baileys = (await import(
export function resetBaileysMocks() {
const recreated = createMockBaileys();
(globalThis as Record<PropertyKey, unknown>)[
Symbol.for("clawdis:lastSocket")
Symbol.for("clawdbot:lastSocket")
] = recreated.lastSocket;
baileys.makeWASocket.mockImplementation(recreated.mod.makeWASocket);
baileys.useMultiFileAuthState.mockImplementation(
@@ -91,7 +91,7 @@ export function resetBaileysMocks() {
export function getLastSocket(): MockBaileysSocket {
const getter = (globalThis as Record<PropertyKey, unknown>)[
Symbol.for("clawdis:lastSocket")
Symbol.for("clawdbot:lastSocket")
];
if (typeof getter === "function")
return (getter as () => MockBaileysSocket)();