2025-11-24 11:23:15 +01:00
|
|
|
#!/usr/bin/env node
|
2025-11-25 03:42:12 +01:00
|
|
|
import process from "node:process";
|
2025-11-24 17:33:59 +01:00
|
|
|
import { fileURLToPath } from "node:url";
|
2026-02-01 10:03:47 +09:00
|
|
|
import { formatUncaughtError } from "./infra/errors.js";
|
2025-12-20 18:39:02 +01:00
|
|
|
import { isMainModule } from "./infra/is-main.js";
|
2026-01-07 20:59:49 +00:00
|
|
|
import { installUnhandledRejectionHandler } from "./infra/unhandled-rejections.js";
|
2025-11-24 11:23:15 +01:00
|
|
|
|
2026-03-18 15:33:33 +00:00
|
|
|
type LegacyCliDeps = {
|
|
|
|
|
installGaxiosFetchCompat: () => Promise<void>;
|
|
|
|
|
runCli: (argv: string[]) => Promise<void>;
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-19 10:34:29 +05:30
|
|
|
type LibraryExports = typeof import("./library.js");
|
|
|
|
|
|
|
|
|
|
// These bindings are populated only for library consumers. The CLI entry stays
|
|
|
|
|
// on the lean path and must not read them while running as main.
|
|
|
|
|
export let assertWebChannel: LibraryExports["assertWebChannel"];
|
|
|
|
|
export let applyTemplate: LibraryExports["applyTemplate"];
|
|
|
|
|
export let createDefaultDeps: LibraryExports["createDefaultDeps"];
|
|
|
|
|
export let deriveSessionKey: LibraryExports["deriveSessionKey"];
|
|
|
|
|
export let describePortOwner: LibraryExports["describePortOwner"];
|
|
|
|
|
export let ensureBinary: LibraryExports["ensureBinary"];
|
|
|
|
|
export let ensurePortAvailable: LibraryExports["ensurePortAvailable"];
|
|
|
|
|
export let getReplyFromConfig: LibraryExports["getReplyFromConfig"];
|
|
|
|
|
export let handlePortError: LibraryExports["handlePortError"];
|
|
|
|
|
export let loadConfig: LibraryExports["loadConfig"];
|
|
|
|
|
export let loadSessionStore: LibraryExports["loadSessionStore"];
|
|
|
|
|
export let monitorWebChannel: LibraryExports["monitorWebChannel"];
|
|
|
|
|
export let normalizeE164: LibraryExports["normalizeE164"];
|
|
|
|
|
export let PortInUseError: LibraryExports["PortInUseError"];
|
|
|
|
|
export let promptYesNo: LibraryExports["promptYesNo"];
|
|
|
|
|
export let resolveSessionKey: LibraryExports["resolveSessionKey"];
|
|
|
|
|
export let resolveStorePath: LibraryExports["resolveStorePath"];
|
|
|
|
|
export let runCommandWithTimeout: LibraryExports["runCommandWithTimeout"];
|
|
|
|
|
export let runExec: LibraryExports["runExec"];
|
|
|
|
|
export let saveSessionStore: LibraryExports["saveSessionStore"];
|
|
|
|
|
export let toWhatsappJid: LibraryExports["toWhatsappJid"];
|
|
|
|
|
export let waitForever: LibraryExports["waitForever"];
|
|
|
|
|
|
2026-03-18 15:33:33 +00:00
|
|
|
async function loadLegacyCliDeps(): Promise<LegacyCliDeps> {
|
2026-03-16 08:21:40 +00:00
|
|
|
const [{ installGaxiosFetchCompat }, { runCli }] = await Promise.all([
|
|
|
|
|
import("./infra/gaxios-fetch-compat.js"),
|
|
|
|
|
import("./cli/run-main.js"),
|
|
|
|
|
]);
|
2026-03-18 15:33:33 +00:00
|
|
|
return { installGaxiosFetchCompat, runCli };
|
|
|
|
|
}
|
2026-03-16 08:21:40 +00:00
|
|
|
|
2026-03-18 15:33:33 +00:00
|
|
|
// Legacy direct file entrypoint only. Package root exports now live in library.ts.
|
|
|
|
|
export async function runLegacyCliEntry(
|
|
|
|
|
argv: string[] = process.argv,
|
|
|
|
|
deps?: LegacyCliDeps,
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
const { installGaxiosFetchCompat, runCli } = deps ?? (await loadLegacyCliDeps());
|
2026-03-16 17:21:18 -05:00
|
|
|
await installGaxiosFetchCompat();
|
2026-03-15 20:02:24 -07:00
|
|
|
await runCli(argv);
|
|
|
|
|
}
|
2025-11-24 17:23:59 +01:00
|
|
|
|
2025-12-20 18:39:02 +01:00
|
|
|
const isMain = isMainModule({
|
|
|
|
|
currentFile: fileURLToPath(import.meta.url),
|
|
|
|
|
});
|
2025-11-24 17:23:59 +01:00
|
|
|
|
2026-03-19 10:34:29 +05:30
|
|
|
if (!isMain) {
|
|
|
|
|
({
|
|
|
|
|
assertWebChannel,
|
|
|
|
|
applyTemplate,
|
|
|
|
|
createDefaultDeps,
|
|
|
|
|
deriveSessionKey,
|
|
|
|
|
describePortOwner,
|
|
|
|
|
ensureBinary,
|
|
|
|
|
ensurePortAvailable,
|
|
|
|
|
getReplyFromConfig,
|
|
|
|
|
handlePortError,
|
|
|
|
|
loadConfig,
|
|
|
|
|
loadSessionStore,
|
|
|
|
|
monitorWebChannel,
|
|
|
|
|
normalizeE164,
|
|
|
|
|
PortInUseError,
|
|
|
|
|
promptYesNo,
|
|
|
|
|
resolveSessionKey,
|
|
|
|
|
resolveStorePath,
|
|
|
|
|
runCommandWithTimeout,
|
|
|
|
|
runExec,
|
|
|
|
|
saveSessionStore,
|
|
|
|
|
toWhatsappJid,
|
|
|
|
|
waitForever,
|
|
|
|
|
} = await import("./library.js"));
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-24 17:23:59 +01:00
|
|
|
if (isMain) {
|
2025-11-27 18:21:14 +01:00
|
|
|
// Global error handlers to prevent silent crashes from unhandled rejections/exceptions.
|
|
|
|
|
// These log the error and exit gracefully instead of crashing without trace.
|
2026-01-07 20:59:49 +00:00
|
|
|
installUnhandledRejectionHandler();
|
2025-11-27 18:21:14 +01:00
|
|
|
|
|
|
|
|
process.on("uncaughtException", (error) => {
|
2026-01-30 03:15:10 +01:00
|
|
|
console.error("[openclaw] Uncaught exception:", formatUncaughtError(error));
|
2025-11-27 18:21:14 +01:00
|
|
|
process.exit(1);
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-15 20:02:24 -07:00
|
|
|
void runLegacyCliEntry(process.argv).catch((err) => {
|
2026-01-30 03:15:10 +01:00
|
|
|
console.error("[openclaw] CLI failed:", formatUncaughtError(err));
|
2025-12-23 00:28:40 +00:00
|
|
|
process.exit(1);
|
|
|
|
|
});
|
2025-11-24 17:23:59 +01:00
|
|
|
}
|