Branding: update bot.molt bundle IDs + launchd labels

This commit is contained in:
Shadow
2026-01-27 14:46:27 -06:00
parent 1d37815443
commit f7a0b0934d
108 changed files with 11111 additions and 112 deletions

View File

@@ -14,7 +14,7 @@ describe("resolveGatewayLaunchAgentLabel", () => {
it("returns default label when no profile is set", () => {
const result = resolveGatewayLaunchAgentLabel();
expect(result).toBe(GATEWAY_LAUNCH_AGENT_LABEL);
expect(result).toBe("com.clawdbot.gateway");
expect(result).toBe("bot.molt.gateway");
});
it("returns default label when profile is undefined", () => {
@@ -34,17 +34,17 @@ describe("resolveGatewayLaunchAgentLabel", () => {
it("returns profile-specific label when profile is set", () => {
const result = resolveGatewayLaunchAgentLabel("dev");
expect(result).toBe("com.clawdbot.dev");
expect(result).toBe("bot.molt.dev");
});
it("returns profile-specific label for custom profile", () => {
const result = resolveGatewayLaunchAgentLabel("work");
expect(result).toBe("com.clawdbot.work");
expect(result).toBe("bot.molt.work");
});
it("trims whitespace from profile", () => {
const result = resolveGatewayLaunchAgentLabel(" staging ");
expect(result).toBe("com.clawdbot.staging");
expect(result).toBe("bot.molt.staging");
});
it("returns default label for empty string profile", () => {

View File

@@ -1,16 +1,19 @@
// Default service labels (for backward compatibility and when no profile specified)
export const GATEWAY_LAUNCH_AGENT_LABEL = "com.clawdbot.gateway";
export const GATEWAY_LAUNCH_AGENT_LABEL = "bot.molt.gateway";
export const GATEWAY_SYSTEMD_SERVICE_NAME = "moltbot-gateway";
export const GATEWAY_WINDOWS_TASK_NAME = "Moltbot Gateway";
export const GATEWAY_SERVICE_MARKER = "moltbot";
export const GATEWAY_SERVICE_KIND = "gateway";
export const NODE_LAUNCH_AGENT_LABEL = "com.clawdbot.node";
export const NODE_LAUNCH_AGENT_LABEL = "bot.molt.node";
export const NODE_SYSTEMD_SERVICE_NAME = "moltbot-node";
export const NODE_WINDOWS_TASK_NAME = "Moltbot Node";
export const NODE_SERVICE_MARKER = "moltbot";
export const NODE_SERVICE_KIND = "node";
export const NODE_WINDOWS_TASK_SCRIPT_NAME = "node.cmd";
export const LEGACY_GATEWAY_LAUNCH_AGENT_LABELS = ["com.steipete.clawdbot.gateway"];
export const LEGACY_GATEWAY_LAUNCH_AGENT_LABELS = [
"com.clawdbot.gateway",
"com.steipete.clawdbot.gateway",
];
export const LEGACY_GATEWAY_SYSTEMD_SERVICE_NAMES: string[] = [];
export const LEGACY_GATEWAY_WINDOWS_TASK_NAMES: string[] = [];
@@ -30,7 +33,15 @@ export function resolveGatewayLaunchAgentLabel(profile?: string): string {
if (!normalized) {
return GATEWAY_LAUNCH_AGENT_LABEL;
}
return `com.clawdbot.${normalized}`;
return `bot.molt.${normalized}`;
}
export function resolveLegacyGatewayLaunchAgentLabels(profile?: string): string[] {
const normalized = normalizeGatewayProfile(profile);
if (!normalized) {
return [...LEGACY_GATEWAY_LAUNCH_AGENT_LABELS];
}
return [...LEGACY_GATEWAY_LAUNCH_AGENT_LABELS, `com.clawdbot.${normalized}`];
}
export function resolveGatewaySystemdServiceName(profile?: string): string {

View File

@@ -6,12 +6,12 @@ import { promisify } from "node:util";
import {
GATEWAY_SERVICE_KIND,
GATEWAY_SERVICE_MARKER,
LEGACY_GATEWAY_LAUNCH_AGENT_LABELS,
LEGACY_GATEWAY_SYSTEMD_SERVICE_NAMES,
LEGACY_GATEWAY_WINDOWS_TASK_NAMES,
resolveGatewayLaunchAgentLabel,
resolveGatewaySystemdServiceName,
resolveGatewayWindowsTaskName,
resolveLegacyGatewayLaunchAgentLabels,
} from "./constants.js";
export type ExtraGatewayService = {
@@ -78,7 +78,7 @@ function isMoltbotGatewayLaunchdService(label: string, contents: string): boolea
if (hasGatewayServiceMarker(contents)) return true;
const lowerContents = contents.toLowerCase();
if (!lowerContents.includes("gateway")) return false;
return label.startsWith("com.clawdbot.");
return label.startsWith("bot.molt.") || label.startsWith("com.clawdbot.");
}
function isMoltbotGatewaySystemdService(name: string, contents: string): boolean {
@@ -102,7 +102,8 @@ function tryExtractPlistLabel(contents: string): string | null {
function isIgnoredLaunchdLabel(label: string): boolean {
return (
label === resolveGatewayLaunchAgentLabel() || LEGACY_GATEWAY_LAUNCH_AGENT_LABELS.includes(label)
label === resolveGatewayLaunchAgentLabel() ||
resolveLegacyGatewayLaunchAgentLabels(process.env.CLAWDBOT_PROFILE).includes(label)
);
}

View File

@@ -107,7 +107,7 @@ describe("launchd runtime parsing", () => {
describe("launchctl list detection", () => {
it("detects the resolved label in launchctl list", async () => {
await withLaunchctlStub({ listOutput: "123 0 com.clawdbot.gateway\n" }, async ({ env }) => {
await withLaunchctlStub({ listOutput: "123 0 bot.molt.gateway\n" }, async ({ env }) => {
const listed = await isLaunchAgentListed({ env });
expect(listed).toBe(true);
});
@@ -133,7 +133,7 @@ describe("launchd bootstrap repair", () => {
.map((line) => JSON.parse(line) as string[]);
const domain = typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501";
const label = "com.clawdbot.gateway";
const label = "bot.molt.gateway";
const plistPath = resolveLaunchAgentPlistPath(env);
expect(calls).toContainEqual(["bootstrap", domain, plistPath]);
@@ -201,7 +201,7 @@ describe("launchd install", () => {
.map((line) => JSON.parse(line) as string[]);
const domain = typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501";
const label = "com.clawdbot.gateway";
const label = "bot.molt.gateway";
const plistPath = resolveLaunchAgentPlistPath(env);
const serviceId = `${domain}/${label}`;
@@ -231,21 +231,21 @@ describe("resolveLaunchAgentPlistPath", () => {
it("uses default label when CLAWDBOT_PROFILE is default", () => {
const env = { HOME: "/Users/test", CLAWDBOT_PROFILE: "default" };
expect(resolveLaunchAgentPlistPath(env)).toBe(
"/Users/test/Library/LaunchAgents/com.clawdbot.gateway.plist",
"/Users/test/Library/LaunchAgents/bot.molt.gateway.plist",
);
});
it("uses default label when CLAWDBOT_PROFILE is unset", () => {
const env = { HOME: "/Users/test" };
expect(resolveLaunchAgentPlistPath(env)).toBe(
"/Users/test/Library/LaunchAgents/com.clawdbot.gateway.plist",
"/Users/test/Library/LaunchAgents/bot.molt.gateway.plist",
);
});
it("uses profile-specific label when CLAWDBOT_PROFILE is set to a custom value", () => {
const env = { HOME: "/Users/test", CLAWDBOT_PROFILE: "jbphoenix" };
expect(resolveLaunchAgentPlistPath(env)).toBe(
"/Users/test/Library/LaunchAgents/com.clawdbot.jbphoenix.plist",
"/Users/test/Library/LaunchAgents/bot.molt.jbphoenix.plist",
);
});
@@ -277,28 +277,28 @@ describe("resolveLaunchAgentPlistPath", () => {
CLAWDBOT_LAUNCHD_LABEL: " ",
};
expect(resolveLaunchAgentPlistPath(env)).toBe(
"/Users/test/Library/LaunchAgents/com.clawdbot.myprofile.plist",
"/Users/test/Library/LaunchAgents/bot.molt.myprofile.plist",
);
});
it("handles case-insensitive 'Default' profile", () => {
const env = { HOME: "/Users/test", CLAWDBOT_PROFILE: "Default" };
expect(resolveLaunchAgentPlistPath(env)).toBe(
"/Users/test/Library/LaunchAgents/com.clawdbot.gateway.plist",
"/Users/test/Library/LaunchAgents/bot.molt.gateway.plist",
);
});
it("handles case-insensitive 'DEFAULT' profile", () => {
const env = { HOME: "/Users/test", CLAWDBOT_PROFILE: "DEFAULT" };
expect(resolveLaunchAgentPlistPath(env)).toBe(
"/Users/test/Library/LaunchAgents/com.clawdbot.gateway.plist",
"/Users/test/Library/LaunchAgents/bot.molt.gateway.plist",
);
});
it("trims whitespace from CLAWDBOT_PROFILE", () => {
const env = { HOME: "/Users/test", CLAWDBOT_PROFILE: " myprofile " };
expect(resolveLaunchAgentPlistPath(env)).toBe(
"/Users/test/Library/LaunchAgents/com.clawdbot.myprofile.plist",
"/Users/test/Library/LaunchAgents/bot.molt.myprofile.plist",
);
});
});

View File

@@ -7,8 +7,8 @@ import { colorize, isRich, theme } from "../terminal/theme.js";
import {
formatGatewayServiceDescription,
GATEWAY_LAUNCH_AGENT_LABEL,
LEGACY_GATEWAY_LAUNCH_AGENT_LABELS,
resolveGatewayLaunchAgentLabel,
resolveLegacyGatewayLaunchAgentLabels,
} from "./constants.js";
import {
buildLaunchAgentPlist as buildLaunchAgentPlistImpl,
@@ -248,7 +248,7 @@ export async function findLegacyLaunchAgents(
): Promise<LegacyLaunchAgent[]> {
const domain = resolveGuiDomain();
const results: LegacyLaunchAgent[] = [];
for (const label of LEGACY_GATEWAY_LAUNCH_AGENT_LABELS) {
for (const label of resolveLegacyGatewayLaunchAgentLabels(env.CLAWDBOT_PROFILE)) {
const plistPath = resolveLaunchAgentPlistPathForLabel(env, label);
const res = await execLaunchctl(["print", `${domain}/${label}`]);
const loaded = res.code === 0;
@@ -384,7 +384,7 @@ export async function installLaunchAgent({
const domain = resolveGuiDomain();
const label = resolveLaunchAgentLabel({ env });
for (const legacyLabel of LEGACY_GATEWAY_LAUNCH_AGENT_LABELS) {
for (const legacyLabel of resolveLegacyGatewayLaunchAgentLabels(env.CLAWDBOT_PROFILE)) {
const legacyPlistPath = resolveLaunchAgentPlistPathForLabel(env, legacyLabel);
await execLaunchctl(["bootout", domain, legacyPlistPath]);
await execLaunchctl(["unload", legacyPlistPath]);

View File

@@ -230,7 +230,7 @@ describe("buildServiceEnvironment", () => {
expect(typeof env.CLAWDBOT_SERVICE_VERSION).toBe("string");
expect(env.CLAWDBOT_SYSTEMD_UNIT).toBe("moltbot-gateway.service");
if (process.platform === "darwin") {
expect(env.CLAWDBOT_LAUNCHD_LABEL).toBe("com.clawdbot.gateway");
expect(env.CLAWDBOT_LAUNCHD_LABEL).toBe("bot.molt.gateway");
}
});
@@ -241,7 +241,7 @@ describe("buildServiceEnvironment", () => {
});
expect(env.CLAWDBOT_SYSTEMD_UNIT).toBe("moltbot-gateway-work.service");
if (process.platform === "darwin") {
expect(env.CLAWDBOT_LAUNCHD_LABEL).toBe("com.clawdbot.work");
expect(env.CLAWDBOT_LAUNCHD_LABEL).toBe("bot.molt.work");
}
});
});