@helyx/bot 1.0.1 → 1.2.0

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.
Files changed (88) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +27 -2
  3. package/dist/auto-moderation-scanner-registry.d.ts +27 -0
  4. package/dist/auto-moderation-scanner-registry.js +172 -0
  5. package/dist/cloud-connector.js +3 -0
  6. package/dist/cloud-control-dispatcher.js +32 -0
  7. package/dist/command-path-contract.js +1 -0
  8. package/dist/control-permissions.d.ts +2 -2
  9. package/dist/control-permissions.js +4 -2
  10. package/dist/control-server.d.ts +72 -16
  11. package/dist/control-server.js +150 -250
  12. package/dist/dashboard-action-control.d.ts +25 -0
  13. package/dist/dashboard-action-control.js +73 -0
  14. package/dist/dashboard-action-routes.d.ts +9 -0
  15. package/dist/dashboard-action-routes.js +36 -0
  16. package/dist/dashboard-feature-control.d.ts +37 -0
  17. package/dist/dashboard-feature-control.js +206 -0
  18. package/dist/dashboard-module-projection.d.ts +9 -0
  19. package/dist/dashboard-module-projection.js +15 -0
  20. package/dist/dashboard-preview-import-routes.d.ts +6 -0
  21. package/dist/dashboard-preview-import-routes.js +121 -0
  22. package/dist/developer-operations-module.d.ts +2 -0
  23. package/dist/developer-operations-module.js +136 -2
  24. package/dist/discord-analytics.d.ts +3 -0
  25. package/dist/discord-analytics.js +49 -5
  26. package/dist/discord-auto-moderation-service.d.ts +21 -0
  27. package/dist/discord-auto-moderation-service.js +425 -0
  28. package/dist/discord-guild-health.d.ts +2 -2
  29. package/dist/discord-member-enforcement-service.d.ts +26 -0
  30. package/dist/discord-member-enforcement-service.js +590 -0
  31. package/dist/discord-message-enforcement-service.d.ts +9 -0
  32. package/dist/discord-message-enforcement-service.js +102 -0
  33. package/dist/discord-violation-thread-service.d.ts +33 -0
  34. package/dist/discord-violation-thread-service.js +789 -0
  35. package/dist/ecko-evidence-receiver.d.ts +32 -0
  36. package/dist/ecko-evidence-receiver.js +173 -0
  37. package/dist/ecko-transport-auth.d.ts +19 -0
  38. package/dist/ecko-transport-auth.js +80 -0
  39. package/dist/ecko-transport-routes.d.ts +19 -0
  40. package/dist/ecko-transport-routes.js +130 -0
  41. package/dist/embedded-auto-moderation-pool.d.ts +46 -0
  42. package/dist/embedded-auto-moderation-pool.js +324 -0
  43. package/dist/embedded-auto-moderation-scanner.d.ts +34 -0
  44. package/dist/embedded-auto-moderation-scanner.js +263 -0
  45. package/dist/embedded-auto-moderation-worker-runtime.d.ts +37 -0
  46. package/dist/embedded-auto-moderation-worker-runtime.js +37 -0
  47. package/dist/embedded-auto-moderation-worker.d.ts +2 -0
  48. package/dist/embedded-auto-moderation-worker.js +13 -0
  49. package/dist/events.d.ts +5 -1
  50. package/dist/events.js +275 -9
  51. package/dist/guilds.d.ts +2 -1
  52. package/dist/guilds.js +164 -5
  53. package/dist/hosted-server-moderation.d.ts +100 -0
  54. package/dist/hosted-server-moderation.js +226 -0
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.js +101 -12
  57. package/dist/moderation-action-registry.d.ts +11 -0
  58. package/dist/moderation-action-registry.js +375 -0
  59. package/dist/moderation-case-disassociation.d.ts +13 -0
  60. package/dist/moderation-case-disassociation.js +83 -0
  61. package/dist/moderation-platform-services.d.ts +27 -0
  62. package/dist/moderation-platform-services.js +47 -0
  63. package/dist/modules.d.ts +6 -0
  64. package/dist/modules.js +65 -3
  65. package/dist/premium-activation-module.js +2 -0
  66. package/dist/privileged-message-metadata-cache.d.ts +35 -0
  67. package/dist/privileged-message-metadata-cache.js +70 -0
  68. package/dist/scheduled-task-runner.js +24 -1
  69. package/dist/shard-contracts.d.ts +151 -1
  70. package/dist/shard-contracts.js +142 -1
  71. package/dist/shard-coordinator.d.ts +1 -1
  72. package/dist/shard-ecko-scanner-registry.d.ts +38 -0
  73. package/dist/shard-ecko-scanner-registry.js +96 -0
  74. package/dist/shard-router.d.ts +23 -0
  75. package/dist/shard-router.js +69 -5
  76. package/dist/shard-supervisor.d.ts +11 -0
  77. package/dist/shard-supervisor.js +72 -6
  78. package/dist/shard-worker.d.ts +16 -1
  79. package/dist/shard-worker.js +108 -10
  80. package/dist/transient-violation-evidence.d.ts +39 -0
  81. package/dist/transient-violation-evidence.js +132 -0
  82. package/documentation/README.md +2 -0
  83. package/documentation/examples/.env.example +13 -0
  84. package/documentation/guides/self-hosting.md +17 -1
  85. package/documentation/modules/auto-moderation.md +51 -0
  86. package/documentation/modules/moderation.md +42 -0
  87. package/documentation/reference/environment.md +11 -0
  88. package/package.json +17 -5
package/dist/modules.js CHANGED
@@ -31,12 +31,28 @@ export function platformServiceOptions(environment, modules) {
31
31
  const urls = environment.HELYX_DASHBOARD_PUBLIC_URL
32
32
  ? { dashboardBaseUrl: environment.HELYX_DASHBOARD_PUBLIC_URL }
33
33
  : {};
34
+ const runtimeProfile = environment.HELYX_RUNTIME_PROFILE ?? "hosted";
35
+ const featureAccess = {
36
+ runtimeProfile,
37
+ availableDiscordCapabilities: [
38
+ ...(environment.HELYX_GUILD_MEMBERS_ENABLED
39
+ ? ["guild-members"]
40
+ : []),
41
+ ...((runtimeProfile === "hosted" &&
42
+ environment.HELYX_ECKO_TRANSPORT_SECRET !== undefined) ||
43
+ (runtimeProfile === "self-hosted" &&
44
+ environment.HELYX_MESSAGE_CONTENT_ENABLED)
45
+ ? ["message-content"]
46
+ : []),
47
+ ],
48
+ };
34
49
  const internalSelectionKey = environment.HELYX_INTERNAL_SECURE_RANDOM_SELECTION_KEY;
35
50
  if (internalSelectionKey) {
36
51
  const selectionKey = decodeSecureRandomSelectionKey(internalSelectionKey, secureRandomSelectionWorkerKeyName);
37
52
  return {
38
53
  ...application,
39
54
  ...urls,
55
+ ...featureAccess,
40
56
  secureRandomSelectionKey: selectionKey,
41
57
  inviteFingerprintKey: deriveInviteFingerprintKey(selectionKey),
42
58
  };
@@ -48,12 +64,13 @@ export function platformServiceOptions(environment, modules) {
48
64
  if (keyRequired) {
49
65
  throw new Error("HELYX_DATA_ENCRYPTION_KEY is required when Giveaways or Invite Tracking is loaded");
50
66
  }
51
- return { ...application, ...urls };
67
+ return { ...application, ...urls, ...featureAccess };
52
68
  }
53
69
  const selectionKey = deriveSecureRandomSelectionKey(encodedKey);
54
70
  return {
55
71
  ...application,
56
72
  ...urls,
73
+ ...featureAccess,
57
74
  secureRandomSelectionKey: selectionKey,
58
75
  inviteFingerprintKey: deriveInviteFingerprintKey(selectionKey),
59
76
  };
@@ -162,6 +179,11 @@ export function validateContributionParity(definition) {
162
179
  }
163
180
  const executableEvents = [
164
181
  ...(definition.events?.privilegedMessageCreate ?? []),
182
+ ...(definition.events?.privilegedMessageUpdate ?? []),
183
+ ...(definition.events?.discordAutoModerationRuleCreate ?? []),
184
+ ...(definition.events?.discordAutoModerationRuleUpdate ?? []),
185
+ ...(definition.events?.discordAutoModerationRuleDelete ?? []),
186
+ ...(definition.events?.discordAutoModerationActionExecution ?? []),
165
187
  ...(definition.events?.guildMessageCreate ?? []),
166
188
  ...(definition.events?.guildVoiceSession ?? []),
167
189
  ...(definition.events?.messageReactionAdd ?? []),
@@ -180,6 +202,20 @@ export function validateContributionParity(definition) {
180
202
  ...(definition.events?.guildEmojiDelete ?? []),
181
203
  ...(definition.events?.guildEmojiUpdate ?? []),
182
204
  ].map(({ type }) => type);
205
+ const manifestFeatureIds = new Set(definition.manifest.manifestVersion === "0.5"
206
+ ? definition.manifest.features.map(({ id }) => id)
207
+ : []);
208
+ for (const contribution of [
209
+ ...(definition.events?.privilegedMessageCreate ?? []),
210
+ ...(definition.events?.privilegedMessageUpdate ?? []),
211
+ ]) {
212
+ if (contribution.featureId &&
213
+ !manifestFeatureIds.has(contribution.featureId))
214
+ throw new Error(`Module ${definition.manifest.id} message event binds undeclared feature ${contribution.featureId}`);
215
+ if (definition.manifest.id === "helyx.automod" &&
216
+ contribution.featureId !== "automod.enhanced-scanning")
217
+ throw new Error("Auto Moderation privileged message events require the Enhanced feature binding");
218
+ }
183
219
  const executableLogs = (definition.logging?.events ?? []).map(({ id }) => id);
184
220
  const executableSchedulableActions = [
185
221
  ...new Set((definition.schedulableActions ?? []).map(({ id }) => id)),
@@ -192,9 +228,16 @@ export function validateContributionParity(definition) {
192
228
  assertSameContributionIds(definition.manifest.contributions.schedulableActions ?? [], executableSchedulableActions, "schedulable actions");
193
229
  assertSameContributionIds(definition.manifest.dashboard?.actions?.map(({ id }) => id) ?? [], executableDashboardActions, "dashboard actions");
194
230
  assertSameContributionIds(definition.manifest.dashboard?.resources?.map(({ id }) => id) ?? [], executableManagedResources, "dashboard resources");
195
- if (definition.manifest.manifestVersion === "0.4") {
231
+ if (definition.manifest.manifestVersion === "0.4" ||
232
+ definition.manifest.manifestVersion === "0.5") {
196
233
  assertCommandPathContract(definition);
197
234
  }
235
+ if (definition.manifest.manifestVersion === "0.5") {
236
+ assertSameContributionIds(definition.manifest.permissionOperations.map(({ id }) => id), (definition.permissionOperations ?? []).map(({ id }) => id), "permission operations");
237
+ }
238
+ else if ((definition.permissionOperations?.length ?? 0) > 0) {
239
+ throw new Error("Module permission operations require manifest version 0.5 or later");
240
+ }
198
241
  validatePrivacyParity(definition);
199
242
  }
200
243
  function validatePrivacyParity(definition) {
@@ -219,6 +262,7 @@ function validatePrivacyParity(definition) {
219
262
  const privacyFields = [
220
263
  collectionDeclaration.createdAtField,
221
264
  ...collectionDeclaration.subjectFields.map(({ field }) => field),
265
+ ...(collectionDeclaration.subjectRelationships ?? []).map(({ localField }) => localField),
222
266
  ...(collectionDeclaration.contentFields ?? []).map(({ field }) => field),
223
267
  ];
224
268
  for (const field of privacyFields) {
@@ -226,16 +270,34 @@ function validatePrivacyParity(definition) {
226
270
  throw new Error(`Module privacy field is not declared in record collection ${collectionDeclaration.name}: ${field}`);
227
271
  }
228
272
  }
273
+ for (const relationship of collectionDeclaration.subjectRelationships ??
274
+ []) {
275
+ const target = definition.records?.[relationship.targetCollection];
276
+ const localField = collection.fields[relationship.localField];
277
+ const targetField = target?.fields[relationship.targetField];
278
+ if (target === undefined || targetField === undefined) {
279
+ throw new Error(`Module privacy relationship target is not declared: ${relationship.targetCollection}.${relationship.targetField}`);
280
+ }
281
+ if (localField?.type !== targetField.type) {
282
+ throw new Error(`Module privacy relationship fields have incompatible types: ${collectionDeclaration.name}.${relationship.localField}`);
283
+ }
284
+ }
229
285
  }
230
286
  const subjectFieldsByCollection = new Map(definition.manifest.privacy.collections.map((collection) => [
231
287
  collection.name,
232
288
  new Set(collection.subjectFields.map(({ field }) => field)),
233
289
  ]));
290
+ const relationshipFieldsByCollection = new Map(definition.manifest.privacy.collections.map((collection) => [
291
+ collection.name,
292
+ new Set((collection.subjectRelationships ?? []).map(({ localField }) => localField)),
293
+ ]));
234
294
  for (const [collectionName, collection] of Object.entries(definition.records ?? {})) {
235
295
  const declaredSubjectFields = subjectFieldsByCollection.get(collectionName);
296
+ const relationshipFields = relationshipFieldsByCollection.get(collectionName);
236
297
  for (const field of Object.keys(collection.fields)) {
237
298
  if (isDiscordIdentityRecordField(field) &&
238
- !declaredSubjectFields?.has(field)) {
299
+ !declaredSubjectFields?.has(field) &&
300
+ !relationshipFields?.has(field)) {
239
301
  throw new Error(`Module record field containing a Discord identity is not declared for privacy access: ${collectionName}.${field}`);
240
302
  }
241
303
  }
@@ -479,6 +479,8 @@ function successResponse(action, slot) {
479
479
  return message(`## Premium activated\nSlot ${String(slot.ordinal)} now supplies Premium to this server.`, GREEN);
480
480
  }
481
481
  function safeFailure(code) {
482
+ if (code === "target_blacklisted")
483
+ return message("Premium cannot be assigned to this server. No slot changes were made.", RED);
482
484
  if (code === "target_admin_override")
483
485
  return message("This server is already covered by an Admin override. No paid slot was used.", GREEN);
484
486
  if (code === "target_already_paid")
@@ -0,0 +1,35 @@
1
+ import type { PrivilegedMessageSourceContext } from "@helyx/sdk";
2
+ /**
3
+ * Process-local, content-free metadata used only to resolve partial message edits.
4
+ * Map insertion order provides deterministic least-recently-used eviction.
5
+ */
6
+ export declare class PrivilegedMessageMetadataCache {
7
+ #private;
8
+ private readonly maximumEntries;
9
+ private readonly ttlMs;
10
+ private readonly now;
11
+ constructor(maximumEntries?: number, ttlMs?: number, now?: () => number);
12
+ remember(input: {
13
+ guildId: string;
14
+ channelId: string;
15
+ messageId: string;
16
+ source: Extract<PrivilegedMessageSourceContext, {
17
+ resolved: true;
18
+ }>;
19
+ }): void;
20
+ resolve(input: {
21
+ guildId: string;
22
+ channelId: string;
23
+ messageId: string;
24
+ }): Extract<PrivilegedMessageSourceContext, {
25
+ resolved: true;
26
+ }> | null;
27
+ delete(input: {
28
+ guildId: string;
29
+ channelId: string;
30
+ messageId: string;
31
+ }): void;
32
+ clear(): void;
33
+ size(): number;
34
+ }
35
+ //# sourceMappingURL=privileged-message-metadata-cache.d.ts.map
@@ -0,0 +1,70 @@
1
+ const DEFAULT_MAX_ENTRIES = 10_000;
2
+ const DEFAULT_TTL_MS = 10 * 60 * 1_000;
3
+ /**
4
+ * Process-local, content-free metadata used only to resolve partial message edits.
5
+ * Map insertion order provides deterministic least-recently-used eviction.
6
+ */
7
+ export class PrivilegedMessageMetadataCache {
8
+ maximumEntries;
9
+ ttlMs;
10
+ now;
11
+ #entries = new Map();
12
+ constructor(maximumEntries = DEFAULT_MAX_ENTRIES, ttlMs = DEFAULT_TTL_MS, now = Date.now) {
13
+ this.maximumEntries = maximumEntries;
14
+ this.ttlMs = ttlMs;
15
+ this.now = now;
16
+ if (!Number.isInteger(maximumEntries) || maximumEntries < 1)
17
+ throw new Error("Privileged message cache size is invalid");
18
+ if (!Number.isInteger(ttlMs) || ttlMs < 1)
19
+ throw new Error("Privileged message cache TTL is invalid");
20
+ }
21
+ remember(input) {
22
+ const key = cacheKey(input);
23
+ this.#entries.delete(key);
24
+ this.#entries.set(key, {
25
+ expiresAt: this.now() + this.ttlMs,
26
+ source: input.source,
27
+ });
28
+ this.#evictExpiredAndOverflow();
29
+ }
30
+ resolve(input) {
31
+ const key = cacheKey(input);
32
+ const entry = this.#entries.get(key);
33
+ if (!entry)
34
+ return null;
35
+ if (entry.expiresAt <= this.now()) {
36
+ this.#entries.delete(key);
37
+ return null;
38
+ }
39
+ this.#entries.delete(key);
40
+ this.#entries.set(key, entry);
41
+ return entry.source;
42
+ }
43
+ delete(input) {
44
+ this.#entries.delete(cacheKey(input));
45
+ }
46
+ clear() {
47
+ this.#entries.clear();
48
+ }
49
+ size() {
50
+ return this.#entries.size;
51
+ }
52
+ #evictExpiredAndOverflow() {
53
+ const now = this.now();
54
+ for (const [key, entry] of this.#entries) {
55
+ if (entry.expiresAt > now)
56
+ continue;
57
+ this.#entries.delete(key);
58
+ }
59
+ while (this.#entries.size > this.maximumEntries) {
60
+ const oldest = this.#entries.keys().next().value;
61
+ if (!oldest)
62
+ break;
63
+ this.#entries.delete(oldest);
64
+ }
65
+ }
66
+ }
67
+ function cacheKey(input) {
68
+ return `${input.guildId}:${input.channelId}:${input.messageId}`;
69
+ }
70
+ //# sourceMappingURL=privileged-message-metadata-cache.js.map
@@ -1,5 +1,5 @@
1
1
  import { CORE_RECORD_RETENTION_TASK, MODULE_ACTIVATION_RECOVERY_TASK, ScheduledTaskRepository, } from "@helyx/database";
2
- import { getModuleScheduledTaskContribution, HELYX_SERVICE_NAMES, } from "@helyx/sdk";
2
+ import { getModuleScheduledTaskContribution, HELYX_SERVICE_NAMES, MODERATION_CASE_RETENTION_TASK, } from "@helyx/sdk";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { canAccessModule } from "./premium-access.js";
5
5
  const DEFAULT_POLL_INTERVAL_MS = 1_000;
@@ -296,6 +296,7 @@ export function createScheduledTaskRunner(input) {
296
296
  taskVersion: contribution.version,
297
297
  delivery: contribution.delivery,
298
298
  }))),
299
+ MODERATION_CASE_RETENTION_TASK,
299
300
  ],
300
301
  ...(input.workerId === undefined ? {} : { workerId: input.workerId }),
301
302
  });
@@ -310,6 +311,28 @@ export function schedulerOperationalHealth(health) {
310
311
  export function createLocalScheduledTaskRoute(input) {
311
312
  const modules = new Map(input.modules.map((module) => [module.manifest.id, module]));
312
313
  return async (task, signal) => {
314
+ if (task.moduleId === MODERATION_CASE_RETENTION_TASK.moduleId &&
315
+ task.taskKind === MODERATION_CASE_RETENTION_TASK.taskKind &&
316
+ task.taskVersion === MODERATION_CASE_RETENTION_TASK.taskVersion &&
317
+ task.delivery === MODERATION_CASE_RETENTION_TASK.delivery) {
318
+ const { guildId, caseId } = task.payload;
319
+ if (Object.keys(task.payload).length !== 2 ||
320
+ typeof guildId !== "string" ||
321
+ !/^\d{17,20}$/u.test(guildId) ||
322
+ typeof caseId !== "string" ||
323
+ !/^[0-9a-f]{8}-[0-9a-f-]{27}$/iu.test(caseId))
324
+ return { outcome: "requires_review", safeCode: "payload_invalid" };
325
+ const result = await input.services
326
+ .get(HELYX_SERVICE_NAMES.atomicModerationCases)
327
+ .executeRetention({ guildId, caseId, occurredAt: new Date() });
328
+ return result.outcome === "deferred"
329
+ ? {
330
+ outcome: "deferred",
331
+ delayMs: Math.max(100, Math.min(86_400_000, result.deferredUntil.getTime() - Date.now())),
332
+ safeCode: `retention_${result.code}`,
333
+ }
334
+ : { outcome: "completed" };
335
+ }
313
336
  if (task.moduleId === CORE_RECORD_RETENTION_TASK.moduleId &&
314
337
  task.taskKind === CORE_RECORD_RETENTION_TASK.taskKind &&
315
338
  task.taskVersion === CORE_RECORD_RETENTION_TASK.taskVersion &&
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import type { ManagedResourceValue } from "@helyx/sdk";
2
+ import { type ManagedResourceValue } from "@helyx/sdk";
3
3
  import type { BotControlHandler } from "./control-server.js";
4
4
  export declare const SHARD_CONTRACT_VERSION: 1;
5
5
  export declare const SHARD_CONTROL_MAX_BYTES: number;
@@ -167,6 +167,31 @@ export declare const shardHealthSnapshotSchema: z.ZodObject<{
167
167
  }, z.core.$strict>;
168
168
  export type ShardHealthSnapshot = z.infer<typeof shardHealthSnapshotSchema>;
169
169
  export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
170
+ kind: z.ZodLiteral<"automod.enhanced.configuration.page">;
171
+ cursor: z.ZodOptional<z.ZodString>;
172
+ limit: z.ZodNumber;
173
+ knownFingerprint: z.ZodOptional<z.ZodString>;
174
+ }, z.core.$strict>, z.ZodObject<{
175
+ kind: z.ZodLiteral<"automod.enhanced.result.accept">;
176
+ guildId: z.ZodString;
177
+ result: z.ZodUnknown;
178
+ evidence: z.ZodOptional<z.ZodObject<{
179
+ sourceEventId: z.ZodString;
180
+ configurationRevision: z.ZodString;
181
+ guildId: z.ZodString;
182
+ channelId: z.ZodString;
183
+ messageId: z.ZodString;
184
+ authorUserId: z.ZodString;
185
+ content: z.ZodString;
186
+ }, z.core.$strict>>;
187
+ }, z.core.$strict>, z.ZodObject<{
188
+ kind: z.ZodLiteral<"hosted-server.leave.deliver">;
189
+ guildId: z.ZodString;
190
+ operationId: z.ZodUUID;
191
+ }, z.core.$strict>, z.ZodObject<{
192
+ kind: z.ZodLiteral<"hosted-server.owner.refresh">;
193
+ guildId: z.ZodString;
194
+ }, z.core.$strict>, z.ZodObject<{
170
195
  kind: z.ZodLiteral<"guild.state.get">;
171
196
  guildId: z.ZodString;
172
197
  }, z.core.$strict>, z.ZodObject<{
@@ -224,6 +249,14 @@ export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.Zod
224
249
  moduleId: z.ZodString;
225
250
  value: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNull, z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodString>]>>;
226
251
  expectedVersion: z.ZodNullable<z.ZodNumber>;
252
+ }, z.core.$strict>, z.ZodObject<{
253
+ actorUserId: z.ZodString;
254
+ correlationId: z.ZodString;
255
+ kind: z.ZodLiteral<"guild.module.configuration.preview">;
256
+ guildId: z.ZodString;
257
+ moduleId: z.ZodString;
258
+ value: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNull, z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodString>]>>;
259
+ input: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
227
260
  }, z.core.$strict>, z.ZodObject<{
228
261
  actorUserId: z.ZodString;
229
262
  correlationId: z.ZodString;
@@ -274,6 +307,14 @@ export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.Zod
274
307
  guildId: z.ZodString;
275
308
  moduleId: z.ZodString;
276
309
  actionId: z.ZodString;
310
+ inspectionRevision: z.ZodOptional<z.ZodString>;
311
+ }, z.core.$strict>, z.ZodObject<{
312
+ actorUserId: z.ZodString;
313
+ correlationId: z.ZodString;
314
+ kind: z.ZodLiteral<"guild.module.action.preview">;
315
+ guildId: z.ZodString;
316
+ moduleId: z.ZodString;
317
+ actionId: z.ZodString;
277
318
  }, z.core.$strict>, z.ZodObject<{
278
319
  kind: z.ZodLiteral<"guild.module.resource.access">;
279
320
  guildId: z.ZodString;
@@ -324,6 +365,15 @@ export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.Zod
324
365
  moduleId: z.ZodString;
325
366
  resourceType: z.ZodString;
326
367
  value: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
368
+ }, z.core.$strict>, z.ZodObject<{
369
+ actorUserId: z.ZodString;
370
+ correlationId: z.ZodString;
371
+ kind: z.ZodLiteral<"guild.module.resource.import">;
372
+ guildId: z.ZodString;
373
+ moduleId: z.ZodString;
374
+ resourceType: z.ZodString;
375
+ format: z.ZodLiteral<"utf8_text">;
376
+ content: z.ZodString;
327
377
  }, z.core.$strict>, z.ZodObject<{
328
378
  actorUserId: z.ZodString;
329
379
  correlationId: z.ZodString;
@@ -528,6 +578,31 @@ export declare const shardControlRequestSchema: z.ZodObject<{
528
578
  fencingToken: z.ZodNumber;
529
579
  deadlineAt: z.ZodISODateTime;
530
580
  operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
581
+ kind: z.ZodLiteral<"automod.enhanced.configuration.page">;
582
+ cursor: z.ZodOptional<z.ZodString>;
583
+ limit: z.ZodNumber;
584
+ knownFingerprint: z.ZodOptional<z.ZodString>;
585
+ }, z.core.$strict>, z.ZodObject<{
586
+ kind: z.ZodLiteral<"automod.enhanced.result.accept">;
587
+ guildId: z.ZodString;
588
+ result: z.ZodUnknown;
589
+ evidence: z.ZodOptional<z.ZodObject<{
590
+ sourceEventId: z.ZodString;
591
+ configurationRevision: z.ZodString;
592
+ guildId: z.ZodString;
593
+ channelId: z.ZodString;
594
+ messageId: z.ZodString;
595
+ authorUserId: z.ZodString;
596
+ content: z.ZodString;
597
+ }, z.core.$strict>>;
598
+ }, z.core.$strict>, z.ZodObject<{
599
+ kind: z.ZodLiteral<"hosted-server.leave.deliver">;
600
+ guildId: z.ZodString;
601
+ operationId: z.ZodUUID;
602
+ }, z.core.$strict>, z.ZodObject<{
603
+ kind: z.ZodLiteral<"hosted-server.owner.refresh">;
604
+ guildId: z.ZodString;
605
+ }, z.core.$strict>, z.ZodObject<{
531
606
  kind: z.ZodLiteral<"guild.state.get">;
532
607
  guildId: z.ZodString;
533
608
  }, z.core.$strict>, z.ZodObject<{
@@ -585,6 +660,14 @@ export declare const shardControlRequestSchema: z.ZodObject<{
585
660
  moduleId: z.ZodString;
586
661
  value: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNull, z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodString>]>>;
587
662
  expectedVersion: z.ZodNullable<z.ZodNumber>;
663
+ }, z.core.$strict>, z.ZodObject<{
664
+ actorUserId: z.ZodString;
665
+ correlationId: z.ZodString;
666
+ kind: z.ZodLiteral<"guild.module.configuration.preview">;
667
+ guildId: z.ZodString;
668
+ moduleId: z.ZodString;
669
+ value: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNull, z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodString>]>>;
670
+ input: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
588
671
  }, z.core.$strict>, z.ZodObject<{
589
672
  actorUserId: z.ZodString;
590
673
  correlationId: z.ZodString;
@@ -635,6 +718,14 @@ export declare const shardControlRequestSchema: z.ZodObject<{
635
718
  guildId: z.ZodString;
636
719
  moduleId: z.ZodString;
637
720
  actionId: z.ZodString;
721
+ inspectionRevision: z.ZodOptional<z.ZodString>;
722
+ }, z.core.$strict>, z.ZodObject<{
723
+ actorUserId: z.ZodString;
724
+ correlationId: z.ZodString;
725
+ kind: z.ZodLiteral<"guild.module.action.preview">;
726
+ guildId: z.ZodString;
727
+ moduleId: z.ZodString;
728
+ actionId: z.ZodString;
638
729
  }, z.core.$strict>, z.ZodObject<{
639
730
  kind: z.ZodLiteral<"guild.module.resource.access">;
640
731
  guildId: z.ZodString;
@@ -685,6 +776,15 @@ export declare const shardControlRequestSchema: z.ZodObject<{
685
776
  moduleId: z.ZodString;
686
777
  resourceType: z.ZodString;
687
778
  value: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
779
+ }, z.core.$strict>, z.ZodObject<{
780
+ actorUserId: z.ZodString;
781
+ correlationId: z.ZodString;
782
+ kind: z.ZodLiteral<"guild.module.resource.import">;
783
+ guildId: z.ZodString;
784
+ moduleId: z.ZodString;
785
+ resourceType: z.ZodString;
786
+ format: z.ZodLiteral<"utf8_text">;
787
+ content: z.ZodString;
688
788
  }, z.core.$strict>, z.ZodObject<{
689
789
  actorUserId: z.ZodString;
690
790
  correlationId: z.ZodString;
@@ -1394,6 +1494,31 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
1394
1494
  fencingToken: z.ZodNumber;
1395
1495
  deadlineAt: z.ZodISODateTime;
1396
1496
  operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
1497
+ kind: z.ZodLiteral<"automod.enhanced.configuration.page">;
1498
+ cursor: z.ZodOptional<z.ZodString>;
1499
+ limit: z.ZodNumber;
1500
+ knownFingerprint: z.ZodOptional<z.ZodString>;
1501
+ }, z.core.$strict>, z.ZodObject<{
1502
+ kind: z.ZodLiteral<"automod.enhanced.result.accept">;
1503
+ guildId: z.ZodString;
1504
+ result: z.ZodUnknown;
1505
+ evidence: z.ZodOptional<z.ZodObject<{
1506
+ sourceEventId: z.ZodString;
1507
+ configurationRevision: z.ZodString;
1508
+ guildId: z.ZodString;
1509
+ channelId: z.ZodString;
1510
+ messageId: z.ZodString;
1511
+ authorUserId: z.ZodString;
1512
+ content: z.ZodString;
1513
+ }, z.core.$strict>>;
1514
+ }, z.core.$strict>, z.ZodObject<{
1515
+ kind: z.ZodLiteral<"hosted-server.leave.deliver">;
1516
+ guildId: z.ZodString;
1517
+ operationId: z.ZodUUID;
1518
+ }, z.core.$strict>, z.ZodObject<{
1519
+ kind: z.ZodLiteral<"hosted-server.owner.refresh">;
1520
+ guildId: z.ZodString;
1521
+ }, z.core.$strict>, z.ZodObject<{
1397
1522
  kind: z.ZodLiteral<"guild.state.get">;
1398
1523
  guildId: z.ZodString;
1399
1524
  }, z.core.$strict>, z.ZodObject<{
@@ -1451,6 +1576,14 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
1451
1576
  moduleId: z.ZodString;
1452
1577
  value: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNull, z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodString>]>>;
1453
1578
  expectedVersion: z.ZodNullable<z.ZodNumber>;
1579
+ }, z.core.$strict>, z.ZodObject<{
1580
+ actorUserId: z.ZodString;
1581
+ correlationId: z.ZodString;
1582
+ kind: z.ZodLiteral<"guild.module.configuration.preview">;
1583
+ guildId: z.ZodString;
1584
+ moduleId: z.ZodString;
1585
+ value: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNull, z.ZodString, z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodString>]>>;
1586
+ input: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
1454
1587
  }, z.core.$strict>, z.ZodObject<{
1455
1588
  actorUserId: z.ZodString;
1456
1589
  correlationId: z.ZodString;
@@ -1501,6 +1634,14 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
1501
1634
  guildId: z.ZodString;
1502
1635
  moduleId: z.ZodString;
1503
1636
  actionId: z.ZodString;
1637
+ inspectionRevision: z.ZodOptional<z.ZodString>;
1638
+ }, z.core.$strict>, z.ZodObject<{
1639
+ actorUserId: z.ZodString;
1640
+ correlationId: z.ZodString;
1641
+ kind: z.ZodLiteral<"guild.module.action.preview">;
1642
+ guildId: z.ZodString;
1643
+ moduleId: z.ZodString;
1644
+ actionId: z.ZodString;
1504
1645
  }, z.core.$strict>, z.ZodObject<{
1505
1646
  kind: z.ZodLiteral<"guild.module.resource.access">;
1506
1647
  guildId: z.ZodString;
@@ -1551,6 +1692,15 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
1551
1692
  moduleId: z.ZodString;
1552
1693
  resourceType: z.ZodString;
1553
1694
  value: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
1695
+ }, z.core.$strict>, z.ZodObject<{
1696
+ actorUserId: z.ZodString;
1697
+ correlationId: z.ZodString;
1698
+ kind: z.ZodLiteral<"guild.module.resource.import">;
1699
+ guildId: z.ZodString;
1700
+ moduleId: z.ZodString;
1701
+ resourceType: z.ZodString;
1702
+ format: z.ZodLiteral<"utf8_text">;
1703
+ content: z.ZodString;
1554
1704
  }, z.core.$strict>, z.ZodObject<{
1555
1705
  actorUserId: z.ZodString;
1556
1706
  correlationId: z.ZodString;