chore: migrate to oxlint and oxfmt
Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
This commit is contained in:
@@ -21,10 +21,7 @@ function isAccountEnabled(account: unknown): boolean {
|
||||
return enabled !== false;
|
||||
}
|
||||
|
||||
async function isPluginConfigured(
|
||||
plugin: ChannelPlugin,
|
||||
cfg: ClawdbotConfig,
|
||||
): Promise<boolean> {
|
||||
async function isPluginConfigured(plugin: ChannelPlugin, cfg: ClawdbotConfig): Promise<boolean> {
|
||||
const accountIds = plugin.config.listAccountIds(cfg);
|
||||
if (accountIds.length === 0) return false;
|
||||
|
||||
@@ -78,8 +75,6 @@ export async function resolveMessageChannelSelection(params: {
|
||||
throw new Error("Channel is required (no configured channels detected).");
|
||||
}
|
||||
throw new Error(
|
||||
`Channel is required when multiple channels are configured: ${configured.join(
|
||||
", ",
|
||||
)}`,
|
||||
`Channel is required when multiple channels are configured: ${configured.join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import {
|
||||
deliverOutboundPayloads,
|
||||
normalizeOutboundPayloads,
|
||||
} from "./deliver.js";
|
||||
import { deliverOutboundPayloads, normalizeOutboundPayloads } from "./deliver.js";
|
||||
|
||||
describe("deliverOutboundPayloads", () => {
|
||||
it("chunks telegram markdown and passes through accountId", async () => {
|
||||
const sendTelegram = vi
|
||||
.fn()
|
||||
.mockResolvedValue({ messageId: "m1", chatId: "c1" });
|
||||
const sendTelegram = vi.fn().mockResolvedValue({ messageId: "m1", chatId: "c1" });
|
||||
const cfg: ClawdbotConfig = {
|
||||
channels: { telegram: { botToken: "tok-1", textChunkLimit: 2 } },
|
||||
};
|
||||
@@ -27,9 +22,7 @@ describe("deliverOutboundPayloads", () => {
|
||||
|
||||
expect(sendTelegram).toHaveBeenCalledTimes(2);
|
||||
for (const call of sendTelegram.mock.calls) {
|
||||
expect(call[2]).toEqual(
|
||||
expect.objectContaining({ accountId: undefined, verbose: false }),
|
||||
);
|
||||
expect(call[2]).toEqual(expect.objectContaining({ accountId: undefined, verbose: false }));
|
||||
}
|
||||
expect(results).toHaveLength(2);
|
||||
expect(results[0]).toMatchObject({ channel: "telegram", chatId: "c1" });
|
||||
@@ -43,9 +36,7 @@ describe("deliverOutboundPayloads", () => {
|
||||
});
|
||||
|
||||
it("passes explicit accountId to sendTelegram", async () => {
|
||||
const sendTelegram = vi
|
||||
.fn()
|
||||
.mockResolvedValue({ messageId: "m1", chatId: "c1" });
|
||||
const sendTelegram = vi.fn().mockResolvedValue({ messageId: "m1", chatId: "c1" });
|
||||
const cfg: ClawdbotConfig = {
|
||||
channels: { telegram: { botToken: "tok-1", textChunkLimit: 2 } },
|
||||
};
|
||||
@@ -67,9 +58,7 @@ describe("deliverOutboundPayloads", () => {
|
||||
});
|
||||
|
||||
it("uses signal media maxBytes from config", async () => {
|
||||
const sendSignal = vi
|
||||
.fn()
|
||||
.mockResolvedValue({ messageId: "s1", timestamp: 123 });
|
||||
const sendSignal = vi.fn().mockResolvedValue({ messageId: "s1", timestamp: 123 });
|
||||
const cfg: ClawdbotConfig = { channels: { signal: { mediaMaxMb: 2 } } };
|
||||
|
||||
const results = await deliverOutboundPayloads({
|
||||
@@ -166,8 +155,6 @@ describe("deliverOutboundPayloads", () => {
|
||||
|
||||
expect(sendWhatsApp).toHaveBeenCalledTimes(2);
|
||||
expect(onError).toHaveBeenCalledTimes(1);
|
||||
expect(results).toEqual([
|
||||
{ channel: "whatsapp", messageId: "w2", toJid: "jid" },
|
||||
]);
|
||||
expect(results).toEqual([{ channel: "whatsapp", messageId: "w2", toJid: "jid" }]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,10 +49,7 @@ type ChannelHandler = {
|
||||
chunker: Chunker | null;
|
||||
textChunkLimit?: number;
|
||||
sendText: (text: string) => Promise<OutboundDeliveryResult>;
|
||||
sendMedia: (
|
||||
caption: string,
|
||||
mediaUrl: string,
|
||||
) => Promise<OutboundDeliveryResult>;
|
||||
sendMedia: (caption: string, mediaUrl: string) => Promise<OutboundDeliveryResult>;
|
||||
};
|
||||
|
||||
function throwIfAborted(abortSignal?: AbortSignal): void {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import type { ReplyPayload } from "../../auto-reply/types.js";
|
||||
import type { OutboundDeliveryJson } from "./format.js";
|
||||
import {
|
||||
normalizeOutboundPayloadsForJson,
|
||||
type OutboundPayloadJson,
|
||||
} from "./payloads.js";
|
||||
import { normalizeOutboundPayloadsForJson, type OutboundPayloadJson } from "./payloads.js";
|
||||
|
||||
export type OutboundResultEnvelope = {
|
||||
payloads?: OutboundPayloadJson[];
|
||||
@@ -35,12 +32,7 @@ export function buildOutboundResultEnvelope(
|
||||
? (params.payloads as OutboundPayloadJson[])
|
||||
: normalizeOutboundPayloadsForJson(params.payloads as ReplyPayload[]);
|
||||
|
||||
if (
|
||||
params.flattenDelivery !== false &&
|
||||
params.delivery &&
|
||||
!params.meta &&
|
||||
!hasPayloads
|
||||
) {
|
||||
if (params.flattenDelivery !== false && params.delivery && !params.meta && !hasPayloads) {
|
||||
return params.delivery;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,7 @@ export function formatOutboundDeliverySummary(
|
||||
|
||||
if ("chatId" in result) return `${base} (chat ${result.chatId})`;
|
||||
if ("channelId" in result) return `${base} (channel ${result.channelId})`;
|
||||
if ("conversationId" in result)
|
||||
return `${base} (conversation ${result.conversationId})`;
|
||||
if ("conversationId" in result) return `${base} (conversation ${result.conversationId})`;
|
||||
return base;
|
||||
}
|
||||
|
||||
@@ -70,11 +69,7 @@ export function buildOutboundDeliveryJson(params: {
|
||||
if (result && "channelId" in result && result.channelId !== undefined) {
|
||||
payload.channelId = result.channelId;
|
||||
}
|
||||
if (
|
||||
result &&
|
||||
"conversationId" in result &&
|
||||
result.conversationId !== undefined
|
||||
) {
|
||||
if (result && "conversationId" in result && result.conversationId !== undefined) {
|
||||
payload.conversationId = result.conversationId;
|
||||
}
|
||||
if (result && "timestamp" in result && result.timestamp !== undefined) {
|
||||
|
||||
@@ -13,10 +13,7 @@ import type {
|
||||
ChannelThreadingToolContext,
|
||||
} from "../../channels/plugins/types.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import type {
|
||||
GatewayClientMode,
|
||||
GatewayClientName,
|
||||
} from "../../utils/message-channel.js";
|
||||
import type { GatewayClientMode, GatewayClientName } from "../../utils/message-channel.js";
|
||||
import { resolveMessageChannelSelection } from "./channel-selection.js";
|
||||
import type { OutboundSendDeps } from "./deliver.js";
|
||||
import type { MessagePollResult, MessageSendResult } from "./message.js";
|
||||
@@ -97,10 +94,7 @@ function extractToolPayload(result: AgentToolResult<unknown>): unknown {
|
||||
return result.content ?? result;
|
||||
}
|
||||
|
||||
function readBooleanParam(
|
||||
params: Record<string, unknown>,
|
||||
key: string,
|
||||
): boolean | undefined {
|
||||
function readBooleanParam(params: Record<string, unknown>, key: string): boolean | undefined {
|
||||
const raw = params[key];
|
||||
if (typeof raw === "boolean") return raw;
|
||||
if (typeof raw === "string") {
|
||||
@@ -141,9 +135,7 @@ function resolveContextGuardTarget(
|
||||
if (!CONTEXT_GUARDED_ACTIONS.has(action)) return undefined;
|
||||
|
||||
if (action === "thread-reply" || action === "thread-create") {
|
||||
return (
|
||||
readStringParam(params, "channelId") ?? readStringParam(params, "to")
|
||||
);
|
||||
return readStringParam(params, "channelId") ?? readStringParam(params, "to");
|
||||
}
|
||||
|
||||
return readStringParam(params, "to") ?? readStringParam(params, "channelId");
|
||||
@@ -165,8 +157,7 @@ function enforceContextIsolation(params: {
|
||||
const normalizedTarget =
|
||||
normalizeTargetForProvider(params.channel, target) ?? target.toLowerCase();
|
||||
const normalizedCurrent =
|
||||
normalizeTargetForProvider(params.channel, currentTarget) ??
|
||||
currentTarget.toLowerCase();
|
||||
normalizeTargetForProvider(params.channel, currentTarget) ?? currentTarget.toLowerCase();
|
||||
|
||||
if (!normalizedTarget || !normalizedCurrent) return;
|
||||
if (normalizedTarget === normalizedCurrent) return;
|
||||
@@ -176,10 +167,7 @@ function enforceContextIsolation(params: {
|
||||
);
|
||||
}
|
||||
|
||||
async function resolveChannel(
|
||||
cfg: ClawdbotConfig,
|
||||
params: Record<string, unknown>,
|
||||
) {
|
||||
async function resolveChannel(cfg: ClawdbotConfig, params: Record<string, unknown>) {
|
||||
const channelHint = readStringParam(params, "channel");
|
||||
const selection = await resolveMessageChannelSelection({
|
||||
cfg,
|
||||
@@ -197,8 +185,7 @@ export async function runMessageAction(
|
||||
|
||||
const action = input.action;
|
||||
const channel = await resolveChannel(cfg, params);
|
||||
const accountId =
|
||||
readStringParam(params, "accountId") ?? input.defaultAccountId;
|
||||
const accountId = readStringParam(params, "accountId") ?? input.defaultAccountId;
|
||||
const dryRun = Boolean(input.dryRun ?? readBooleanParam(params, "dryRun"));
|
||||
|
||||
enforceContextIsolation({
|
||||
@@ -294,8 +281,7 @@ export async function runMessageAction(
|
||||
const question = readStringParam(params, "pollQuestion", {
|
||||
required: true,
|
||||
});
|
||||
const options =
|
||||
readStringArrayParam(params, "pollOption", { required: true }) ?? [];
|
||||
const options = readStringArrayParam(params, "pollOption", { required: true }) ?? [];
|
||||
if (options.length < 2) {
|
||||
throw new Error("pollOption requires at least two values");
|
||||
}
|
||||
@@ -376,9 +362,7 @@ export async function runMessageAction(
|
||||
dryRun,
|
||||
});
|
||||
if (!handled) {
|
||||
throw new Error(
|
||||
`Message action ${action} not supported for channel ${channel}.`,
|
||||
);
|
||||
throw new Error(`Message action ${action} not supported for channel ${channel}.`);
|
||||
}
|
||||
return {
|
||||
kind: "action",
|
||||
|
||||
@@ -26,10 +26,7 @@ describe("sendMessage channel normalization", () => {
|
||||
deps: { sendMSTeams },
|
||||
});
|
||||
|
||||
expect(sendMSTeams).toHaveBeenCalledWith(
|
||||
"conversation:19:abc@thread.tacv2",
|
||||
"hi",
|
||||
);
|
||||
expect(sendMSTeams).toHaveBeenCalledWith("conversation:19:abc@thread.tacv2", "hi");
|
||||
expect(result.channel).toBe("msteams");
|
||||
});
|
||||
|
||||
@@ -43,11 +40,7 @@ describe("sendMessage channel normalization", () => {
|
||||
deps: { sendIMessage },
|
||||
});
|
||||
|
||||
expect(sendIMessage).toHaveBeenCalledWith(
|
||||
"someone@example.com",
|
||||
"hi",
|
||||
expect.any(Object),
|
||||
);
|
||||
expect(sendIMessage).toHaveBeenCalledWith("someone@example.com", "hi", expect.any(Object));
|
||||
expect(result.channel).toBe("imessage");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import {
|
||||
getChannelPlugin,
|
||||
normalizeChannelId,
|
||||
} from "../../channels/plugins/index.js";
|
||||
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
|
||||
import type { ChannelId } from "../../channels/plugins/types.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
@@ -101,9 +98,7 @@ function resolveGatewayOptions(opts?: MessageGatewayOptions) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function sendMessage(
|
||||
params: MessageSendParams,
|
||||
): Promise<MessageSendResult> {
|
||||
export async function sendMessage(params: MessageSendParams): Promise<MessageSendResult> {
|
||||
const cfg = params.cfg ?? loadConfig();
|
||||
const channel = params.channel?.trim()
|
||||
? normalizeChannelId(params.channel)
|
||||
@@ -187,9 +182,7 @@ export async function sendMessage(
|
||||
};
|
||||
}
|
||||
|
||||
export async function sendPoll(
|
||||
params: MessagePollParams,
|
||||
): Promise<MessagePollResult> {
|
||||
export async function sendPoll(params: MessagePollParams): Promise<MessagePollResult> {
|
||||
const cfg = params.cfg ?? loadConfig();
|
||||
const channel = params.channel?.trim()
|
||||
? normalizeChannelId(params.channel)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
formatOutboundPayloadLog,
|
||||
normalizeOutboundPayloadsForJson,
|
||||
} from "./payloads.js";
|
||||
import { formatOutboundPayloadLog, normalizeOutboundPayloadsForJson } from "./payloads.js";
|
||||
|
||||
describe("normalizeOutboundPayloadsForJson", () => {
|
||||
it("normalizes payloads with mediaUrl and mediaUrls", () => {
|
||||
|
||||
@@ -11,32 +11,24 @@ export type OutboundPayloadJson = {
|
||||
mediaUrls?: string[];
|
||||
};
|
||||
|
||||
export function normalizeOutboundPayloads(
|
||||
payloads: ReplyPayload[],
|
||||
): NormalizedOutboundPayload[] {
|
||||
export function normalizeOutboundPayloads(payloads: ReplyPayload[]): NormalizedOutboundPayload[] {
|
||||
return payloads
|
||||
.map((payload) => ({
|
||||
text: payload.text ?? "",
|
||||
mediaUrls:
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []),
|
||||
mediaUrls: payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []),
|
||||
}))
|
||||
.filter((payload) => payload.text || payload.mediaUrls.length > 0);
|
||||
}
|
||||
|
||||
export function normalizeOutboundPayloadsForJson(
|
||||
payloads: ReplyPayload[],
|
||||
): OutboundPayloadJson[] {
|
||||
export function normalizeOutboundPayloadsForJson(payloads: ReplyPayload[]): OutboundPayloadJson[] {
|
||||
return payloads.map((payload) => ({
|
||||
text: payload.text ?? "",
|
||||
mediaUrl: payload.mediaUrl ?? null,
|
||||
mediaUrls:
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : undefined),
|
||||
mediaUrls: payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : undefined),
|
||||
}));
|
||||
}
|
||||
|
||||
export function formatOutboundPayloadLog(
|
||||
payload: NormalizedOutboundPayload,
|
||||
): string {
|
||||
export function formatOutboundPayloadLog(payload: NormalizedOutboundPayload): string {
|
||||
const lines: string[] = [];
|
||||
if (payload.text) lines.push(payload.text.trimEnd());
|
||||
for (const url of payload.mediaUrls) lines.push(`MEDIA:${url}`);
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import {
|
||||
getChannelPlugin,
|
||||
normalizeChannelId,
|
||||
} from "../../channels/plugins/index.js";
|
||||
import type {
|
||||
ChannelId,
|
||||
ChannelOutboundTargetMode,
|
||||
} from "../../channels/plugins/types.js";
|
||||
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
|
||||
import type { ChannelId, ChannelOutboundTargetMode } from "../../channels/plugins/types.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import type { SessionEntry } from "../../config/sessions.js";
|
||||
import type {
|
||||
@@ -24,9 +18,7 @@ export type OutboundTarget = {
|
||||
reason?: string;
|
||||
};
|
||||
|
||||
export type OutboundTargetResolution =
|
||||
| { ok: true; to: string }
|
||||
| { ok: false; error: Error };
|
||||
export type OutboundTargetResolution = { ok: true; to: string } | { ok: false; error: Error };
|
||||
|
||||
// Channel docking: prefer plugin.outbound.resolveTarget + allowFrom to normalize destinations.
|
||||
export function resolveOutboundTarget(params: {
|
||||
@@ -151,7 +143,5 @@ export function resolveHeartbeatDeliveryTarget(params: {
|
||||
}
|
||||
}
|
||||
|
||||
return reason
|
||||
? { channel, to: resolved.to, reason }
|
||||
: { channel, to: resolved.to };
|
||||
return reason ? { channel, to: resolved.to, reason } : { channel, to: resolved.to };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user