mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 02:11:23 +00:00
iMessage: promote BlueBubbles and refresh docs/skills (#8415)
* feat: Make BlueBubbles the primary iMessage integration - Remove old imsg skill (skills/imsg/SKILL.md) - Create new BlueBubbles skill (skills/bluebubbles/SKILL.md) with message tool examples - Add keep-alive script documentation for VM/headless setups to docs/channels/bluebubbles.md - AppleScript that pokes Messages.app every 5 minutes - LaunchAgent configuration for automatic execution - Prevents Messages.app from going idle in VM environments - Update all documentation to prioritize BlueBubbles over legacy imsg: - Mark imsg channel as legacy throughout docs - Update README.md channel lists - Update wizard, hubs, pairing, and index docs - Update FAQ to recommend BlueBubbles for iMessage - Update RPC docs to note imsg as legacy pattern - Update Chinese documentation (zh-CN) - Replace imsg examples with generic macOS skill examples where appropriate BlueBubbles is now the recommended first-class iMessage integration, with the legacy imsg integration marked for potential future removal. * refactor: Update import paths and improve code formatting - Adjusted import paths in session-status-tool.ts, whatsapp-heartbeat.ts, and heartbeat-runner.ts for consistency. - Reformatted code for better readability by aligning and grouping related imports and function parameters. - Enhanced error messages and conditional checks for clarity in heartbeat-runner.ts. * skills: restore imsg skill and align bluebubbles skill * docs: update FAQ for clarity and formatting - Adjusted the formatting of the FAQ section to ensure consistent bullet point alignment. - No content changes were made, only formatting improvements for better readability. * style: oxfmt touched files * fix: preserve BlueBubbles developer reference (#8415) (thanks @tyler6204)
This commit is contained in:
@@ -34,13 +34,12 @@ import {
|
||||
saveSessionStore,
|
||||
updateSessionStore,
|
||||
} from "../config/sessions.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { peekSystemEvents } from "../infra/system-events.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import { getQueueSize } from "../process/command-queue.js";
|
||||
import { CommandLane } from "../process/lanes.js";
|
||||
import { normalizeAgentId, toAgentStoreSessionKey } from "../routing/session-key.js";
|
||||
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
|
||||
import { formatErrorMessage } from "./errors.js";
|
||||
import { emitHeartbeatEvent, resolveIndicatorType } from "./heartbeat-events.js";
|
||||
import { resolveHeartbeatVisibility } from "./heartbeat-visibility.js";
|
||||
import {
|
||||
@@ -54,6 +53,7 @@ import {
|
||||
resolveHeartbeatDeliveryTarget,
|
||||
resolveHeartbeatSenderContext,
|
||||
} from "./outbound/targets.js";
|
||||
import { peekSystemEvents } from "./system-events.js";
|
||||
|
||||
type HeartbeatDeps = OutboundSendDeps &
|
||||
ChannelHeartbeatDeps & {
|
||||
@@ -349,7 +349,9 @@ function resolveHeartbeatSession(
|
||||
const mainSessionKey =
|
||||
scope === "global" ? "global" : resolveAgentMainSessionKey({ cfg, agentId: resolvedAgentId });
|
||||
const storeAgentId = scope === "global" ? resolveDefaultAgentId(cfg) : resolvedAgentId;
|
||||
const storePath = resolveStorePath(sessionCfg?.store, { agentId: storeAgentId });
|
||||
const storePath = resolveStorePath(sessionCfg?.store, {
|
||||
agentId: storeAgentId,
|
||||
});
|
||||
const store = loadSessionStore(storePath);
|
||||
const mainEntry = store[mainSessionKey];
|
||||
|
||||
@@ -380,7 +382,12 @@ function resolveHeartbeatSession(
|
||||
if (canonical !== "global") {
|
||||
const sessionAgentId = resolveAgentIdFromSessionKey(canonical);
|
||||
if (sessionAgentId === normalizeAgentId(resolvedAgentId)) {
|
||||
return { sessionKey: canonical, storePath, store, entry: store[canonical] };
|
||||
return {
|
||||
sessionKey: canonical,
|
||||
storePath,
|
||||
store,
|
||||
entry: store[canonical],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,7 +716,11 @@ export async function runHeartbeatOnce(opts: {
|
||||
}
|
||||
|
||||
if (!visibility.showAlerts) {
|
||||
await restoreHeartbeatUpdatedAt({ storePath, sessionKey, updatedAt: previousUpdatedAt });
|
||||
await restoreHeartbeatUpdatedAt({
|
||||
storePath,
|
||||
sessionKey,
|
||||
updatedAt: previousUpdatedAt,
|
||||
});
|
||||
emitHeartbeatEvent({
|
||||
status: "skipped",
|
||||
reason: "alerts-disabled",
|
||||
@@ -908,10 +919,16 @@ export function startHeartbeatRunner(opts: {
|
||||
|
||||
const run: HeartbeatWakeHandler = async (params) => {
|
||||
if (!heartbeatsEnabled) {
|
||||
return { status: "skipped", reason: "disabled" } satisfies HeartbeatRunResult;
|
||||
return {
|
||||
status: "skipped",
|
||||
reason: "disabled",
|
||||
} satisfies HeartbeatRunResult;
|
||||
}
|
||||
if (state.agents.size === 0) {
|
||||
return { status: "skipped", reason: "disabled" } satisfies HeartbeatRunResult;
|
||||
return {
|
||||
status: "skipped",
|
||||
reason: "disabled",
|
||||
} satisfies HeartbeatRunResult;
|
||||
}
|
||||
|
||||
const reason = params?.reason;
|
||||
|
||||
Reference in New Issue
Block a user