Spaces:
Paused
Paused
File size: 2,713 Bytes
fb4d8fe | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | import type { RuntimeEnv } from "../runtime.js";
import { detectBinary } from "../commands/onboard-helpers.js";
import { loadConfig } from "../config/config.js";
import { runCommandWithTimeout } from "../process/exec.js";
import { createIMessageRpcClient } from "./client.js";
export type IMessageProbe = {
ok: boolean;
error?: string | null;
fatal?: boolean;
};
export type IMessageProbeOptions = {
cliPath?: string;
dbPath?: string;
runtime?: RuntimeEnv;
};
type RpcSupportResult = {
supported: boolean;
error?: string;
fatal?: boolean;
};
const rpcSupportCache = new Map<string, RpcSupportResult>();
async function probeRpcSupport(cliPath: string): Promise<RpcSupportResult> {
const cached = rpcSupportCache.get(cliPath);
if (cached) {
return cached;
}
try {
const result = await runCommandWithTimeout([cliPath, "rpc", "--help"], { timeoutMs: 2000 });
const combined = `${result.stdout}\n${result.stderr}`.trim();
const normalized = combined.toLowerCase();
if (normalized.includes("unknown command") && normalized.includes("rpc")) {
const fatal = {
supported: false,
fatal: true,
error: 'imsg CLI does not support the "rpc" subcommand (update imsg)',
};
rpcSupportCache.set(cliPath, fatal);
return fatal;
}
if (result.code === 0) {
const supported = { supported: true };
rpcSupportCache.set(cliPath, supported);
return supported;
}
return {
supported: false,
error: combined || `imsg rpc --help failed (code ${String(result.code ?? "unknown")})`,
};
} catch (err) {
return { supported: false, error: String(err) };
}
}
export async function probeIMessage(
timeoutMs = 2000,
opts: IMessageProbeOptions = {},
): Promise<IMessageProbe> {
const cfg = opts.cliPath || opts.dbPath ? undefined : loadConfig();
const cliPath = opts.cliPath?.trim() || cfg?.channels?.imessage?.cliPath?.trim() || "imsg";
const dbPath = opts.dbPath?.trim() || cfg?.channels?.imessage?.dbPath?.trim();
const detected = await detectBinary(cliPath);
if (!detected) {
return { ok: false, error: `imsg not found (${cliPath})` };
}
const rpcSupport = await probeRpcSupport(cliPath);
if (!rpcSupport.supported) {
return {
ok: false,
error: rpcSupport.error ?? "imsg rpc unavailable",
fatal: rpcSupport.fatal,
};
}
const client = await createIMessageRpcClient({
cliPath,
dbPath,
runtime: opts.runtime,
});
try {
await client.request("chats.list", { limit: 1 }, { timeoutMs });
return { ok: true };
} catch (err) {
return { ok: false, error: String(err) };
} finally {
await client.stop();
}
}
|