mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 10:00:44 +00:00
fix(imessage): report non-mac default imsg hosts
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
"name": "@openclaw/imessage",
|
||||
"version": "2026.5.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw iMessage channel plugin",
|
||||
"description": "OpenClaw iMessage channel plugin using imsg on a signed-in Mac",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
@@ -19,7 +19,7 @@
|
||||
"detailLabel": "iMessage",
|
||||
"docsPath": "/channels/imessage",
|
||||
"docsLabel": "imessage",
|
||||
"blurb": "this is still a work in progress.",
|
||||
"blurb": "iMessage via the imsg CLI on a signed-in Mac or SSH wrapper.",
|
||||
"aliases": [
|
||||
"imsg"
|
||||
],
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import path from "node:path";
|
||||
import type { BaseProbeResult } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { runCommandWithTimeout } from "openclaw/plugin-sdk/process-runtime";
|
||||
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
||||
@@ -17,6 +18,7 @@ export type IMessageProbe = BaseProbeResult & {
|
||||
export type IMessageProbeOptions = {
|
||||
cliPath?: string;
|
||||
dbPath?: string;
|
||||
platform?: NodeJS.Platform;
|
||||
runtime?: RuntimeEnv;
|
||||
};
|
||||
|
||||
@@ -28,6 +30,21 @@ type RpcSupportResult = {
|
||||
|
||||
const rpcSupportCache = new Map<string, RpcSupportResult>();
|
||||
|
||||
function isDefaultLocalIMessageCliPath(cliPath: string): boolean {
|
||||
const trimmed = cliPath.trim();
|
||||
return trimmed === "imsg" || (!trimmed.includes("/") && path.basename(trimmed) === "imsg");
|
||||
}
|
||||
|
||||
export function resolveIMessageNonMacHostError(
|
||||
cliPath: string,
|
||||
platform: NodeJS.Platform = process.platform,
|
||||
): string | undefined {
|
||||
if (platform === "darwin" || !isDefaultLocalIMessageCliPath(cliPath)) {
|
||||
return undefined;
|
||||
}
|
||||
return "iMessage via the default imsg CLI must run on macOS. Run OpenClaw on the signed-in Messages Mac, or set channels.imessage.cliPath to an SSH wrapper that runs imsg on that Mac.";
|
||||
}
|
||||
|
||||
async function probeRpcSupport(cliPath: string, timeoutMs: number): Promise<RpcSupportResult> {
|
||||
const cached = rpcSupportCache.get(cliPath);
|
||||
if (cached) {
|
||||
@@ -76,6 +93,11 @@ export async function probeIMessage(
|
||||
const effectiveTimeout =
|
||||
timeoutMs ?? cfg?.channels?.imessage?.probeTimeoutMs ?? DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS;
|
||||
|
||||
const nonMacHostError = resolveIMessageNonMacHostError(cliPath, opts.platform);
|
||||
if (nonMacHostError) {
|
||||
return { ok: false, fatal: true, error: nonMacHostError };
|
||||
}
|
||||
|
||||
const detected = await detectBinary(cliPath);
|
||||
if (!detected) {
|
||||
return { ok: false, error: `imsg not found (${cliPath})` };
|
||||
|
||||
@@ -169,7 +169,8 @@ export function createIMessageCliPathTextInput(
|
||||
export const imessageCompletionNote = {
|
||||
title: "iMessage next steps",
|
||||
lines: [
|
||||
"This is still a work in progress.",
|
||||
"Run OpenClaw on the Mac signed into Messages, or set cliPath to an SSH wrapper that runs imsg on that Mac.",
|
||||
"Linux/Windows hosts cannot run the default local imsg path directly.",
|
||||
"Ensure OpenClaw has Full Disk Access to Messages DB.",
|
||||
"Grant Automation permission for Messages when prompted.",
|
||||
"List chats with: imsg chats --limit 20",
|
||||
|
||||
@@ -169,6 +169,24 @@ describe("probeIMessage", () => {
|
||||
expect(createIMessageRpcClientMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("fails fast for default local imsg probes on non-mac hosts", async () => {
|
||||
const createIMessageRpcClientMock = vi
|
||||
.spyOn(clientModule, "createIMessageRpcClient")
|
||||
.mockResolvedValue({
|
||||
request: vi.fn(),
|
||||
stop: vi.fn(),
|
||||
} as unknown as Awaited<ReturnType<typeof clientModule.createIMessageRpcClient>>);
|
||||
|
||||
const result = await probeIMessage(1000, { cliPath: "imsg", platform: "linux" });
|
||||
|
||||
expect(result.ok).toBe(false);
|
||||
expect(result.fatal).toBe(true);
|
||||
expect(result.error).toMatch(/macOS/i);
|
||||
expect(result.error).toMatch(/SSH wrapper/i);
|
||||
expect(setupRuntime.detectBinary).not.toHaveBeenCalled();
|
||||
expect(createIMessageRpcClientMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("status probe uses account-scoped cliPath and dbPath", async () => {
|
||||
const probeSpy = vi.spyOn(channelRuntimeModule, "probeIMessageAccount").mockResolvedValue({
|
||||
ok: true,
|
||||
|
||||
Reference in New Issue
Block a user