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

@@ -1,32 +1,32 @@
export const browserCoreExamples = [
"clawdis browser status",
"clawdis browser start",
"clawdis browser stop",
"clawdis browser tabs",
"clawdis browser open https://example.com",
"clawdis browser focus abcd1234",
"clawdis browser close abcd1234",
"clawdis browser screenshot",
"clawdis browser screenshot --full-page",
"clawdis browser screenshot --ref 12",
"clawdis browser snapshot",
"clawdis browser snapshot --format aria --limit 200",
"clawdbot browser status",
"clawdbot browser start",
"clawdbot browser stop",
"clawdbot browser tabs",
"clawdbot browser open https://example.com",
"clawdbot browser focus abcd1234",
"clawdbot browser close abcd1234",
"clawdbot browser screenshot",
"clawdbot browser screenshot --full-page",
"clawdbot browser screenshot --ref 12",
"clawdbot browser snapshot",
"clawdbot browser snapshot --format aria --limit 200",
];
export const browserActionExamples = [
"clawdis browser navigate https://example.com",
"clawdis browser resize 1280 720",
"clawdis browser click 12 --double",
'clawdis browser type 23 "hello" --submit',
"clawdis browser press Enter",
"clawdis browser hover 44",
"clawdis browser drag 10 11",
"clawdis browser select 9 OptionA OptionB",
"clawdis browser upload /tmp/file.pdf",
'clawdis browser fill --fields \'[{"ref":"1","value":"Ada"}]\'',
"clawdis browser dialog --accept",
'clawdis browser wait --text "Done"',
"clawdis browser evaluate --fn '(el) => el.textContent' --ref 7",
"clawdis browser console --level error",
"clawdis browser pdf",
"clawdbot browser navigate https://example.com",
"clawdbot browser resize 1280 720",
"clawdbot browser click 12 --double",
'clawdbot browser type 23 "hello" --submit',
"clawdbot browser press Enter",
"clawdbot browser hover 44",
"clawdbot browser drag 10 11",
"clawdbot browser select 9 OptionA OptionB",
"clawdbot browser upload /tmp/file.pdf",
'clawdbot browser fill --fields \'[{"ref":"1","value":"Ada"}]\'',
"clawdbot browser dialog --accept",
'clawdbot browser wait --text "Done"',
"clawdbot browser evaluate --fn '(el) => el.textContent' --ref 7",
"clawdbot browser console --level error",
"clawdbot browser pdf",
];

View File

@@ -18,7 +18,7 @@ export function registerBrowserCli(program: Command) {
.description("Manage clawd's dedicated browser (Chrome/Chromium)")
.option(
"--url <url>",
"Override browser control URL (default from ~/.clawdis/clawdis.json)",
"Override browser control URL (default from ~/.clawdbot/clawdbot.json)",
)
.option("--profile <name>", "Browser profile name (default from config)")
.option("--json", "Output machine-readable JSON", false)
@@ -29,7 +29,7 @@ export function registerBrowserCli(program: Command) {
.action(() => {
browser.outputHelp();
defaultRuntime.error(
danger('Missing subcommand. Try: "clawdis browser status"'),
danger('Missing subcommand. Try: "clawdbot browser status"'),
);
defaultRuntime.exit(1);
});

View File

@@ -499,7 +499,7 @@ export function registerCanvasCli(program: Command) {
const { version, messageCount } = validateA2UIJsonl(jsonl);
if (version === "v0.9") {
throw new Error(
"Detected A2UI v0.9 JSONL (createSurface). Clawdis currently supports v0.8 only.",
"Detected A2UI v0.9 JSONL (createSurface). Clawdbot currently supports v0.8 only.",
);
}
await invokeCanvas(opts, "canvas.a2ui.pushJSONL", { jsonl });

View File

@@ -103,7 +103,7 @@ export function registerDnsCli(program: Command) {
dns
.command("setup")
.description(
"Set up CoreDNS to serve clawdis.internal for unicast DNS-SD (Wide-Area Bonjour)",
"Set up CoreDNS to serve clawdbot.internal for unicast DNS-SD (Wide-Area Bonjour)",
)
.option(
"--apply",
@@ -122,7 +122,7 @@ export function registerDnsCli(program: Command) {
`Detected tailnet IP: ${tailnetIPv4 ?? "—"}${tailnetIPv6 ? ` (v6 ${tailnetIPv6})` : ""}`,
);
console.log("");
console.log("Recommended ~/.clawdis/clawdis.json:");
console.log("Recommended ~/.clawdbot/clawdbot.json:");
console.log(
JSON.stringify(
{
@@ -138,7 +138,7 @@ export function registerDnsCli(program: Command) {
console.log(
`- Add nameserver: ${tailnetIPv4 ?? "<this machine's tailnet IPv4>"}`,
);
console.log(`- Restrict to domain (Split DNS): clawdis.internal`);
console.log(`- Restrict to domain (Split DNS): clawdbot.internal`);
if (!opts.apply) {
console.log("");
@@ -160,7 +160,7 @@ export function registerDnsCli(program: Command) {
const corefilePath = path.join(etcDir, "Corefile");
const confDir = path.join(etcDir, "conf.d");
const importGlob = path.join(confDir, "*.server");
const serverPath = path.join(confDir, "clawdis.internal.server");
const serverPath = path.join(confDir, "clawdbot.internal.server");
run("brew", ["list", "coredns"], { allowFailure: true });
run("brew", ["install", "coredns"], {
@@ -202,7 +202,7 @@ export function registerDnsCli(program: Command) {
const serial = `${y}${m}${d}01`;
const zoneLines = [
`; created by clawdis dns setup (will be overwritten by the gateway when wide-area discovery is enabled)`,
`; created by clawdbot dns setup (will be overwritten by the gateway when wide-area discovery is enabled)`,
`$ORIGIN ${WIDE_AREA_DISCOVERY_DOMAIN}`,
`$TTL 60`,
`@ IN SOA ns1 hostmaster ${serial} 7200 3600 1209600 60`,
@@ -224,7 +224,7 @@ export function registerDnsCli(program: Command) {
if (cfg.discovery?.wideArea?.enabled !== true) {
console.log("");
console.log(
"Note: enable discovery.wideArea.enabled in ~/.clawdis/clawdis.json on the gateway and restart the gateway so it writes the DNS-SD zone.",
"Note: enable discovery.wideArea.enabled in ~/.clawdbot/clawdbot.json on the gateway and restart the gateway so it writes the DNS-SD zone.",
);
}
});

View File

@@ -2,7 +2,7 @@ import fs from "node:fs";
import type { Command } from "commander";
import {
CONFIG_PATH_CLAWDIS,
CONFIG_PATH_CLAWDBOT,
loadConfig,
resolveGatewayPort,
} from "../config/config.js";
@@ -160,7 +160,7 @@ export function registerGatewayCli(program: Command) {
)
.option(
"--token <token>",
"Shared token required in connect.params.auth.token (default: CLAWDIS_GATEWAY_TOKEN env if set)",
"Shared token required in connect.params.auth.token (default: CLAWDBOT_GATEWAY_TOKEN env if set)",
)
.option("--auth <mode>", 'Gateway auth mode ("token"|"password")')
.option("--password <password>", "Password for auth mode=password")
@@ -218,7 +218,7 @@ export function registerGatewayCli(program: Command) {
return;
}
if (opts.token) {
process.env.CLAWDIS_GATEWAY_TOKEN = String(opts.token);
process.env.CLAWDBOT_GATEWAY_TOKEN = String(opts.token);
}
const authModeRaw = opts.auth ? String(opts.auth) : undefined;
const authMode =
@@ -305,7 +305,7 @@ export function registerGatewayCli(program: Command) {
)
.option(
"--token <token>",
"Shared token required in connect.params.auth.token (default: CLAWDIS_GATEWAY_TOKEN env if set)",
"Shared token required in connect.params.auth.token (default: CLAWDBOT_GATEWAY_TOKEN env if set)",
)
.option("--auth <mode>", 'Gateway auth mode ("token"|"password")')
.option("--password <password>", "Password for auth mode=password")
@@ -404,7 +404,7 @@ export function registerGatewayCli(program: Command) {
}
}
if (opts.token) {
process.env.CLAWDIS_GATEWAY_TOKEN = String(opts.token);
process.env.CLAWDBOT_GATEWAY_TOKEN = String(opts.token);
}
const authModeRaw = opts.auth ? String(opts.auth) : undefined;
const authMode =
@@ -430,12 +430,12 @@ export function registerGatewayCli(program: Command) {
defaultRuntime.exit(1);
return;
}
const configExists = fs.existsSync(CONFIG_PATH_CLAWDIS);
const configExists = fs.existsSync(CONFIG_PATH_CLAWDBOT);
const mode = cfg.gateway?.mode;
if (!opts.allowUnconfigured && mode !== "local") {
if (!configExists) {
defaultRuntime.error(
"Missing config. Run `clawdis setup` or set gateway.mode=local (or pass --allow-unconfigured).",
"Missing config. Run `clawdbot setup` or set gateway.mode=local (or pass --allow-unconfigured).",
);
} else {
defaultRuntime.error(

View File

@@ -78,7 +78,7 @@ describe("gateway SIGTERM", () => {
it("exits 0 on SIGTERM", { timeout: 90_000 }, async () => {
const port = await getFreePort();
const stateDir = fs.mkdtempSync(
path.join(os.tmpdir(), "clawdis-gateway-test-"),
path.join(os.tmpdir(), "clawdbot-gateway-test-"),
);
const out: string[] = [];
const err: string[] = [];
@@ -100,14 +100,14 @@ describe("gateway SIGTERM", () => {
cwd: process.cwd(),
env: {
...process.env,
CLAWDIS_STATE_DIR: stateDir,
CLAWDIS_CONFIG_PATH: path.join(stateDir, "clawdis.json"),
CLAWDIS_SKIP_PROVIDERS: "1",
CLAWDIS_SKIP_BROWSER_CONTROL_SERVER: "1",
CLAWDIS_SKIP_CANVAS_HOST: "1",
CLAWDBOT_STATE_DIR: stateDir,
CLAWDBOT_CONFIG_PATH: path.join(stateDir, "clawdbot.json"),
CLAWDBOT_SKIP_PROVIDERS: "1",
CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER: "1",
CLAWDBOT_SKIP_CANVAS_HOST: "1",
// Avoid port collisions with other test processes that may also start a bridge server.
CLAWDIS_BRIDGE_HOST: "127.0.0.1",
CLAWDIS_BRIDGE_PORT: "0",
CLAWDBOT_BRIDGE_HOST: "127.0.0.1",
CLAWDBOT_BRIDGE_PORT: "0",
},
stdio: ["ignore", "pipe", "pipe"],
},

View File

@@ -30,7 +30,7 @@ export function registerHooksCli(program: Command) {
gmail
.command("setup")
.description("Configure Gmail watch + Pub/Sub + Clawdis hooks")
.description("Configure Gmail watch + Pub/Sub + Clawdbot hooks")
.requiredOption("--account <email>", "Gmail account to watch")
.option("--project <id>", "GCP project id (OAuth client owner)")
.option("--topic <name>", "Pub/Sub topic name", DEFAULT_GMAIL_TOPIC)
@@ -40,8 +40,8 @@ export function registerHooksCli(program: Command) {
DEFAULT_GMAIL_SUBSCRIPTION,
)
.option("--label <label>", "Gmail label to watch", DEFAULT_GMAIL_LABEL)
.option("--hook-url <url>", "Clawdis hook URL")
.option("--hook-token <token>", "Clawdis hook token")
.option("--hook-url <url>", "Clawdbot hook URL")
.option("--hook-token <token>", "Clawdbot hook token")
.option("--push-token <token>", "Push token for gog watch serve")
.option(
"--bind <host>",
@@ -90,8 +90,8 @@ export function registerHooksCli(program: Command) {
.option("--topic <topic>", "Pub/Sub topic path (projects/.../topics/..)")
.option("--subscription <name>", "Pub/Sub subscription name")
.option("--label <label>", "Gmail label to watch")
.option("--hook-url <url>", "Clawdis hook URL")
.option("--hook-token <token>", "Clawdis hook token")
.option("--hook-url <url>", "Clawdbot hook URL")
.option("--hook-token <token>", "Clawdbot hook token")
.option("--push-token <token>", "Push token for gog watch serve")
.option("--bind <host>", "gog watch serve bind host")
.option("--port <port>", "gog watch serve port")

View File

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

View File

@@ -81,7 +81,7 @@ export function cameraTempPath(opts: {
const ext = opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`;
return path.join(
tmpDir,
`clawdis-camera-${opts.kind}${facingPart}-${id}${ext}`,
`clawdbot-camera-${opts.kind}${facingPart}-${id}${ext}`,
);
}

View File

@@ -37,5 +37,5 @@ export function canvasSnapshotTempPath(opts: {
const tmpDir = opts.tmpDir ?? os.tmpdir();
const id = opts.id ?? randomUUID();
const ext = opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`;
return path.join(tmpDir, `clawdis-canvas-snapshot-${id}${ext}`);
return path.join(tmpDir, `clawdbot-canvas-snapshot-${id}${ext}`);
}

View File

@@ -35,6 +35,6 @@ describe("nodes screen helpers", () => {
tmpDir: "/tmp",
id: "id1",
});
expect(p).toBe("/tmp/clawdis-screen-record-id1.mp4");
expect(p).toBe("/tmp/clawdbot-screen-record-id1.mp4");
});
});

View File

@@ -49,7 +49,7 @@ export function screenRecordTempPath(opts: {
const tmpDir = opts.tmpDir ?? os.tmpdir();
const id = opts.id ?? randomUUID();
const ext = opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`;
return path.join(tmpDir, `clawdis-screen-record-${id}${ext}`);
return path.join(tmpDir, `clawdbot-screen-record-${id}${ext}`);
}
export async function writeScreenRecordToFile(

View File

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

View File

@@ -34,12 +34,12 @@ export function buildProgram() {
const TAGLINE =
"Send, receive, and auto-reply on WhatsApp (web) and Telegram (bot).";
program.name("clawdis").description("").version(PROGRAM_VERSION);
program.name("clawdbot").description("").version(PROGRAM_VERSION);
const formatIntroLine = (version: string, rich = true) => {
const base = `📡 clawdis ${version}${TAGLINE}`;
const base = `📡 clawdbot ${version}${TAGLINE}`;
return rich && chalk.level > 0
? `${chalk.bold.cyan("📡 clawdis")} ${chalk.white(version)} ${chalk.gray("—")} ${chalk.green(TAGLINE)}`
? `${chalk.bold.cyan("📡 clawdbot")} ${chalk.white(version)} ${chalk.gray("—")} ${chalk.green(TAGLINE)}`
: base;
};
@@ -80,32 +80,32 @@ export function buildProgram() {
.join("\n");
defaultRuntime.error(
danger(
`Legacy config entries detected. Run "clawdis doctor" (or ask your agent) to migrate.\n${issues}`,
`Legacy config entries detected. Run "clawdbot doctor" (or ask your agent) to migrate.\n${issues}`,
),
);
process.exit(1);
});
const examples = [
[
"clawdis login --verbose",
"clawdbot login --verbose",
"Link personal WhatsApp Web and show QR + connection logs.",
],
[
'clawdis send --to +15555550123 --message "Hi" --json',
'clawdbot send --to +15555550123 --message "Hi" --json',
"Send via your web session and print JSON result.",
],
["clawdis gateway --port 18789", "Run the WebSocket Gateway locally."],
["clawdbot gateway --port 18789", "Run the WebSocket Gateway locally."],
[
"clawdis gateway --force",
"clawdbot gateway --force",
"Kill anything bound to the default gateway port, then start it.",
],
["clawdis gateway ...", "Gateway control via WebSocket."],
["clawdbot gateway ...", "Gateway control via WebSocket."],
[
'clawdis agent --to +15555550123 --message "Run summary" --deliver',
'clawdbot agent --to +15555550123 --message "Run summary" --deliver',
"Talk directly to the agent using the Gateway; optionally send the WhatsApp reply.",
],
[
'clawdis send --provider telegram --to @mychat --message "Hi"',
'clawdbot send --provider telegram --to @mychat --message "Hi"',
"Send via your Telegram bot.",
],
] as const;
@@ -121,7 +121,7 @@ export function buildProgram() {
program
.command("setup")
.description("Initialize ~/.clawdis/clawdis.json and the agent workspace")
.description("Initialize ~/.clawdbot/clawdbot.json and the agent workspace")
.option(
"--workspace <dir>",
"Agent workspace directory (default: ~/clawd; stored as agent.workspace)",
@@ -327,10 +327,10 @@ export function buildProgram() {
"after",
`
Examples:
clawdis send --to +15555550123 --message "Hi"
clawdis send --to +15555550123 --message "Hi" --media photo.jpg
clawdis send --to +15555550123 --message "Hi" --dry-run # print payload only
clawdis send --to +15555550123 --message "Hi" --json # machine-readable result`,
clawdbot send --to +15555550123 --message "Hi"
clawdbot send --to +15555550123 --message "Hi" --media photo.jpg
clawdbot send --to +15555550123 --message "Hi" --dry-run # print payload only
clawdbot send --to +15555550123 --message "Hi" --json # machine-readable result`,
)
.action(async (opts) => {
setVerbose(Boolean(opts.verbose));
@@ -377,10 +377,10 @@ Examples:
"after",
`
Examples:
clawdis agent --to +15555550123 --message "status update"
clawdis agent --session-id 1234 --message "Summarize inbox" --thinking medium
clawdis agent --to +15555550123 --message "Trace logs" --verbose on --json
clawdis agent --to +15555550123 --message "Summon reply" --deliver
clawdbot agent --to +15555550123 --message "status update"
clawdbot agent --session-id 1234 --message "Summarize inbox" --thinking medium
clawdbot agent --to +15555550123 --message "Trace logs" --verbose on --json
clawdbot agent --to +15555550123 --message "Summon reply" --deliver
`,
)
.action(async (opts) => {
@@ -420,10 +420,10 @@ Examples:
"after",
`
Examples:
clawdis status # show linked account + session store summary
clawdis status --json # machine-readable output
clawdis status --deep # run provider probes (WA + Telegram + Discord + Slack + Signal)
clawdis status --deep --timeout 5000 # tighten probe timeout`,
clawdbot status # show linked account + session store summary
clawdbot status --json # machine-readable output
clawdbot status --deep # run provider probes (WA + Telegram + Discord + Slack + Signal)
clawdbot status --deep --timeout 5000 # tighten probe timeout`,
)
.action(async (opts) => {
setVerbose(Boolean(opts.verbose));
@@ -501,10 +501,10 @@ Examples:
"after",
`
Examples:
clawdis sessions # list all sessions
clawdis sessions --active 120 # only last 2 hours
clawdis sessions --json # machine-readable output
clawdis sessions --store ./tmp/sessions.json
clawdbot sessions # list all sessions
clawdbot sessions --active 120 # only last 2 hours
clawdbot sessions --json # machine-readable output
clawdbot sessions --store ./tmp/sessions.json
Shows token usage per session when the agent reports it; set agent.contextTokens to see % of your model window.`,
)