fix(signal): add groups schema support for Signal channel

This commit is contained in:
Alex Zaytsev 2026-02-26 00:01:06 -05:00 committed by Altay
parent 4e68684bd2
commit 975629ca0a
No known key found for this signature in database
3 changed files with 85 additions and 0 deletions

View File

@ -1,8 +1,15 @@
import type { CommonChannelMessagingConfig } from "./types.channel-messaging-common.js";
import type { GroupToolPolicyBySenderConfig, GroupToolPolicyConfig } from "./types.tools.js";
export type SignalReactionNotificationMode = "off" | "own" | "all" | "allowlist";
export type SignalReactionLevel = "off" | "ack" | "minimal" | "extensive";
export type SignalGroupConfig = {
requireMention?: boolean;
tools?: GroupToolPolicyConfig;
toolsBySender?: GroupToolPolicyBySenderConfig;
};
export type SignalAccountConfig = CommonChannelMessagingConfig & {
/** Optional explicit E.164 account for signal-cli. */
account?: string;
@ -24,6 +31,8 @@ export type SignalAccountConfig = CommonChannelMessagingConfig & {
ignoreAttachments?: boolean;
ignoreStories?: boolean;
sendReadReceipts?: boolean;
/** Per-group overrides keyed by Signal group id (or "*"). */
groups?: Record<string, SignalGroupConfig>;
/** Outbound text chunk size (chars). Default: 4000. */
textChunkLimit?: number;
/** Reaction notification mode (off|own|all|allowlist). Default: own. */

View File

@ -971,6 +971,16 @@ export const SlackConfigSchema = SlackAccountSchema.safeExtend({
validateSlackSigningSecretRequirements(value, ctx);
});
const SignalGroupEntrySchema = z
.object({
requireMention: z.boolean().optional(),
tools: ToolPolicySchema,
toolsBySender: ToolPolicyBySenderSchema,
})
.strict();
const SignalGroupsSchema = z.record(z.string(), SignalGroupEntrySchema.optional()).optional();
export const SignalAccountSchemaBase = z
.object({
name: z.string().optional(),
@ -995,6 +1005,7 @@ export const SignalAccountSchemaBase = z
defaultTo: z.string().optional(),
groupAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
groups: SignalGroupsSchema,
historyLimit: z.number().int().min(0).optional(),
dmHistoryLimit: z.number().int().min(0).optional(),
dms: z.record(z.string(), DmConfigSchema.optional()).optional(),

View File

@ -0,0 +1,65 @@
import { describe, expect, it } from "vitest";
import { validateConfigObject } from "./config.js";
describe("signal groups schema", () => {
it("accepts top-level Signal groups overrides", () => {
const res = validateConfigObject({
channels: {
signal: {
groups: {
"*": {
requireMention: false,
},
"+1234567890": {
requireMention: true,
},
},
},
},
});
expect(res.ok).toBe(true);
});
it("accepts per-account Signal groups overrides", () => {
const res = validateConfigObject({
channels: {
signal: {
accounts: {
primary: {
groups: {
"*": {
requireMention: false,
},
},
},
},
},
},
});
expect(res.ok).toBe(true);
});
it("rejects unknown keys in Signal groups entries", () => {
const res = validateConfigObject({
channels: {
signal: {
groups: {
"*": {
requireMention: false,
nope: true,
},
},
},
},
});
expect(res.ok).toBe(false);
if (!res.ok) {
expect(res.issues.some((issue) => issue.path.startsWith("channels.signal.groups"))).toBe(
true,
);
}
});
});