dsh-lark-bot 0.19.12 → 0.19.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/plugin.d.ts CHANGED
@@ -1104,12 +1104,15 @@ declare class PermissionPolicyStore {
1104
1104
  flush(): Promise<void>;
1105
1105
  }
1106
1106
 
1107
- type NotificationEvent = 'completed' | 'failed' | 'approval';
1107
+ type NotificationEvent = 'completed' | 'failed' | 'approval' | 'urgent';
1108
1108
  interface NotificationPreference {
1109
1109
  target?: string;
1110
1110
  events: NotificationEvent[];
1111
+ /** Feishu open_ids to @mention in the primary Feishu notification. */
1111
1112
  mentionUserIds: string[];
1112
1113
  approvalReminderMs: number;
1114
+ /** Outbound notification channel ids (see `/channels`) fanned out on top of the Feishu route. */
1115
+ sinks: string[];
1113
1116
  }
1114
1117
  /** Opt-in notification preferences keyed by immutable bridge scope. */
1115
1118
  declare class NotificationPreferenceStore {
@@ -1124,6 +1127,113 @@ declare class NotificationPreferenceStore {
1124
1127
  flush(): Promise<void>;
1125
1128
  }
1126
1129
 
1130
+ /** Supported outbound notification-only sink platforms. */
1131
+ type SinkType = 'telegram' | 'wecom';
1132
+ /**
1133
+ * A configured outbound notification channel. The bridge is the only consumer
1134
+ * of these entries; each channel is a notification-only sink (no inbound).
1135
+ *
1136
+ * Secrets (telegram bot token / wecom webhook key) live in
1137
+ * `<profile>/notification-channels.json` written at mode 0600 and must never
1138
+ * appear in logs, cards, diagnostics or channel output. `mask()` is the single
1139
+ * place that renders a safe, non-echoing description.
1140
+ */
1141
+ interface SinkChannel {
1142
+ /** Stable channel id, unique within a profile (admin chosen). */
1143
+ id: string;
1144
+ type: SinkType;
1145
+ /** Human-facing label shown by `/channels` and `/status`. */
1146
+ label: string;
1147
+ /**
1148
+ * Platform destination:
1149
+ * - telegram: target chat_id / @handle that messages are sent to.
1150
+ * - wecom : the webhook key (the value after `?key=`).
1151
+ */
1152
+ destination: string;
1153
+ /**
1154
+ * Secret credential:
1155
+ * - telegram: the bot token (`<bot_id>:<secret>`).
1156
+ * - wecom : the webhook key (kept mirrored from `destination` so a single
1157
+ * redaction helper always covers the credential; only ever read by the
1158
+ * sink itself, never logged).
1159
+ */
1160
+ secret: string;
1161
+ enabled: boolean;
1162
+ /** Optional feishu user_id -> platform user id mapping for mentions. */
1163
+ mentionMap?: Record<string, string>;
1164
+ }
1165
+ /** A rendered notification delivered to sinks, independent of any Feishu routing. */
1166
+ interface SinkMessage {
1167
+ /** Immutable bridge scope that produced the event. */
1168
+ scope: string;
1169
+ event: NotificationEvent;
1170
+ /** Localized title (zh_cn / en_us) as the sink content headline. */
1171
+ title: {
1172
+ zh: string;
1173
+ en: string;
1174
+ };
1175
+ /** Optional free-form detail appended to the headline. */
1176
+ detail?: string;
1177
+ }
1178
+ /** An outbound notification sink (mirrors the `AgentAdapter` pluggable seam). */
1179
+ interface OutboundSink {
1180
+ readonly type: SinkType;
1181
+ /**
1182
+ * Deliver one notification. Must resolve to `false` — not throw — on a
1183
+ * transport failure so the dispatcher can keep fanning out to the remaining
1184
+ * channels without corrupting the Feishu terminal state.
1185
+ */
1186
+ send(channel: SinkChannel, message: SinkMessage): Promise<boolean>;
1187
+ }
1188
+
1189
+ /**
1190
+ * Persisted outbound notification channel configuration
1191
+ * (`<profile>/notification-channels.json`, mode 0600). The secrets stored here
1192
+ * are the credential for each push-only sink; they are never echoed by the
1193
+ * `/channels` / `/status` surfaces, the command layer, or the logger.
1194
+ */
1195
+ declare class NotificationChannelStore {
1196
+ private readonly path;
1197
+ private data;
1198
+ private saving;
1199
+ constructor(path: string);
1200
+ load(): Promise<void>;
1201
+ list(): SinkChannel[];
1202
+ get(id: string): SinkChannel | undefined;
1203
+ add(channel: SinkChannel): Promise<void>;
1204
+ update(id: string, patch: Partial<Pick<SinkChannel, 'label' | 'enabled' | 'destination' | 'secret' | 'mentionMap'>>): Promise<boolean>;
1205
+ setEnabled(id: string, enabled: boolean): Promise<boolean>;
1206
+ remove(id: string): Promise<boolean>;
1207
+ flush(): Promise<void>;
1208
+ private mutate;
1209
+ }
1210
+
1211
+ interface BroadcastSummary {
1212
+ /** Number of channels that acknowledged the notification. */
1213
+ delivered: number;
1214
+ /** Channel ids that failed (never the secret). */
1215
+ failures: string[];
1216
+ total: number;
1217
+ }
1218
+ /**
1219
+ * Builds and owns the concrete sink instances (mirror of the `AgentAdapter`
1220
+ * seam) and fans a notification out to every enabled, configured channel for a
1221
+ * scope. The Feishu path is not part of this registry: it stays the default
1222
+ * first-class route and remains wired through `NotificationDispatcher`.
1223
+ */
1224
+ declare class OutboundSinkRegistry {
1225
+ private readonly store;
1226
+ private readonly sinks;
1227
+ constructor(store: NotificationChannelStore, sinks?: OutboundSink[]);
1228
+ /** Resolve only the enabled channels referenced by `channelIds`. */
1229
+ channelsForIds(channelIds: string[]): SinkChannel[];
1230
+ /** Channels currently enabled (for `/status` and `/channels`). */
1231
+ enabledChannels(): SinkChannel[];
1232
+ /** Best-effort fan-out; a failing channel never blocks the others. */
1233
+ broadcast(channelIds: string[], message: SinkMessage): Promise<BroadcastSummary>;
1234
+ private sinkFor;
1235
+ }
1236
+
1127
1237
  interface ReplyPolicy {
1128
1238
  mergeWindowMs: number;
1129
1239
  maxBatchSize: number;
@@ -1526,6 +1636,15 @@ interface StartChannelDeps {
1526
1636
  permissionPolicies?: PermissionPolicyStore;
1527
1637
  notificationPreferences?: NotificationPreferenceStore;
1528
1638
  defaultNotificationPreference?: NotificationPreference;
1639
+ /** Configurable push-only outbound notification channels (issue #113). */
1640
+ notificationChannels?: NotificationChannelStore;
1641
+ /** Fan-out registry backed by `notificationChannels` (issue #113). */
1642
+ notificationSinks?: OutboundSinkRegistry;
1643
+ /** Route reconnect / crash / heartbeat fault classes to outbound sinks. */
1644
+ faultNotifier?: (scope: string, title: {
1645
+ zh: string;
1646
+ en: string;
1647
+ }, detail?: string) => Promise<void>;
1529
1648
  replyPolicies?: ReplyPolicyStore;
1530
1649
  executionModes?: ExecutionModeStore;
1531
1650
  languagePolicies?: LanguagePolicyStore;