@helyx/bot 1.5.2 → 1.5.3

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 (114) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/command-root-catalogue.json +452 -0
  3. package/dist/cached-message-deletion-authority.d.ts +27 -0
  4. package/dist/cached-message-deletion-authority.js +288 -0
  5. package/dist/channel-audit-configuration.d.ts +11 -1
  6. package/dist/channel-audit-configuration.js +28 -6
  7. package/dist/channel-audit-control.js +42 -2
  8. package/dist/channel-audit-permissions.js +76 -3
  9. package/dist/cloud-command-policy-sync.d.ts +26 -0
  10. package/dist/cloud-command-policy-sync.js +198 -0
  11. package/dist/cloud-connector.d.ts +6 -1
  12. package/dist/cloud-connector.js +224 -53
  13. package/dist/cloud-control-dispatcher.js +18 -0
  14. package/dist/command-policy-runtime.d.ts +23 -0
  15. package/dist/command-policy-runtime.js +53 -0
  16. package/dist/command-root-catalogue.d.ts +5 -0
  17. package/dist/command-root-catalogue.js +16 -0
  18. package/dist/control-error-mapping.d.ts +8 -0
  19. package/dist/control-error-mapping.js +60 -0
  20. package/dist/control-errors.d.ts +3 -1
  21. package/dist/control-errors.js +4 -1
  22. package/dist/control-health-routes.d.ts +10 -0
  23. package/dist/control-health-routes.js +28 -0
  24. package/dist/control-server-schemas.d.ts +7 -0
  25. package/dist/control-server-schemas.js +9 -0
  26. package/dist/control-server.d.ts +27 -6
  27. package/dist/control-server.js +103 -122
  28. package/dist/dashboard-feature-control.d.ts +2 -1
  29. package/dist/dashboard-feature-control.js +1 -0
  30. package/dist/dashboard-logging.d.ts +20 -0
  31. package/dist/dashboard-logging.js +39 -0
  32. package/dist/dashboard-module-projection.d.ts +1 -1
  33. package/dist/dashboard-module-projection.js +5 -2
  34. package/dist/dashboard-preview-import-routes.js +8 -0
  35. package/dist/database-bootstrap.d.ts +1 -1
  36. package/dist/database-bootstrap.js +4 -3
  37. package/dist/discord-channel-audit.js +1 -0
  38. package/dist/discord-user-identities.d.ts +14 -0
  39. package/dist/discord-user-identities.js +64 -0
  40. package/dist/emergency-deletion-dispatcher.d.ts +68 -0
  41. package/dist/emergency-deletion-dispatcher.js +502 -0
  42. package/dist/emergency-deletion-rest-transport.d.ts +24 -0
  43. package/dist/emergency-deletion-rest-transport.js +253 -0
  44. package/dist/events.d.ts +5 -0
  45. package/dist/events.js +53 -10
  46. package/dist/guarded-discord-dispatcher.d.ts +29 -0
  47. package/dist/guarded-discord-dispatcher.js +204 -0
  48. package/dist/guild-command-discord-client.d.ts +2 -0
  49. package/dist/guild-command-discord-client.js +7 -0
  50. package/dist/guild-command-projection.d.ts +4 -1
  51. package/dist/guild-command-projection.js +25 -0
  52. package/dist/guild-command-read-service.d.ts +10 -1
  53. package/dist/guild-command-read-service.js +37 -0
  54. package/dist/guild-command-worker.d.ts +19 -4
  55. package/dist/guild-command-worker.js +356 -26
  56. package/dist/guild-message-protection-author-roles.d.ts +7 -0
  57. package/dist/guild-message-protection-author-roles.js +93 -0
  58. package/dist/guild-message-protection-deletion.d.ts +21 -0
  59. package/dist/guild-message-protection-deletion.js +138 -0
  60. package/dist/guild-message-protection-delivery.d.ts +41 -0
  61. package/dist/guild-message-protection-delivery.js +223 -0
  62. package/dist/guild-message-update-metadata.d.ts +32 -0
  63. package/dist/guild-message-update-metadata.js +255 -0
  64. package/dist/guilds.d.ts +2 -1
  65. package/dist/guilds.js +11 -1
  66. package/dist/hosted-server-moderation.d.ts +2 -2
  67. package/dist/index.js +68 -4
  68. package/dist/interactions.d.ts +3 -1
  69. package/dist/interactions.js +77 -12
  70. package/dist/invite-rollup-maintenance.d.ts +9 -0
  71. package/dist/invite-rollup-maintenance.js +12 -0
  72. package/dist/managed-resource-authorization.d.ts +15 -0
  73. package/dist/managed-resource-authorization.js +37 -0
  74. package/dist/managed-resource-create-defaults.d.ts +21 -0
  75. package/dist/managed-resource-create-defaults.js +83 -0
  76. package/dist/managed-resource-query.d.ts +6 -0
  77. package/dist/managed-resource-query.js +15 -0
  78. package/dist/member-role-ids.d.ts +17 -0
  79. package/dist/member-role-ids.js +66 -0
  80. package/dist/message-protection-admission.d.ts +60 -0
  81. package/dist/message-protection-admission.js +279 -0
  82. package/dist/message-protection-cold-data.d.ts +42 -0
  83. package/dist/message-protection-cold-data.js +180 -0
  84. package/dist/message-protection-coordinator.d.ts +73 -0
  85. package/dist/message-protection-coordinator.js +622 -0
  86. package/dist/message-protection-settings.d.ts +40 -0
  87. package/dist/message-protection-settings.js +275 -0
  88. package/dist/message-protection-summary.d.ts +8 -0
  89. package/dist/message-protection-summary.js +98 -0
  90. package/dist/module-availability-control.js +20 -12
  91. package/dist/module-logging.d.ts +3 -2
  92. package/dist/module-logging.js +6 -1
  93. package/dist/modules.js +56 -1
  94. package/dist/mysql-runtime-persistence.d.ts +1 -0
  95. package/dist/mysql-runtime-persistence.js +4 -1
  96. package/dist/nexus-command-recovery-control-routes.d.ts +5 -0
  97. package/dist/nexus-command-recovery-control-routes.js +48 -0
  98. package/dist/nexus-command-references.d.ts +6 -0
  99. package/dist/nexus-command-references.js +33 -0
  100. package/dist/scheduled-task-runner.js +23 -4
  101. package/dist/shard-command-startup.d.ts +13 -0
  102. package/dist/shard-command-startup.js +27 -0
  103. package/dist/shard-contracts.d.ts +84 -0
  104. package/dist/shard-contracts.js +33 -0
  105. package/dist/shard-core-readiness.d.ts +5 -0
  106. package/dist/shard-core-readiness.js +19 -0
  107. package/dist/shard-router.d.ts +3 -0
  108. package/dist/shard-router.js +10 -1
  109. package/dist/shard-supervisor.d.ts +1 -1
  110. package/dist/shard-supervisor.js +124 -43
  111. package/dist/shard-worker.js +25 -15
  112. package/documentation/README.md +1 -0
  113. package/documentation/guides/self-hosting.md +54 -0
  114. package/package.json +18 -17
@@ -0,0 +1,48 @@
1
+ import { nexusCommandRecoveryHistoryQuerySchema, nexusCommandRecoveryInputSchema, nexusCommandRecoveryRenameInputSchema, } from "@helyx/control-protocol/nexus-command-recovery";
2
+ import { NexusCommandRecoveryError } from "@helyx/platform";
3
+ import { NexusCoreError } from "@helyx/sdk";
4
+ import { z } from "zod";
5
+ const target = z.object({ guildId: z.string().regex(/^\d{17,20}$/u) });
6
+ const prefix = "/v1/admin-recovery/guilds/:guildId/nexus-command";
7
+ /** Register only on the private control server with its existing bearer hook. */
8
+ export function registerNexusCommandRecoveryControlRoutes(server, recovery) {
9
+ const run = async (reply, operation) => {
10
+ reply.header("Cache-Control", "no-store");
11
+ if (!recovery)
12
+ return reply
13
+ .code(503)
14
+ .send({ message: "Private Nexus command recovery is unavailable" });
15
+ try {
16
+ return await operation();
17
+ }
18
+ catch (error) {
19
+ if (error instanceof NexusCommandRecoveryError) {
20
+ const status = error.code === "invalid_input" ? 400 : 409;
21
+ return reply.code(status).send({ message: error.message });
22
+ }
23
+ if (error instanceof NexusCoreError)
24
+ return reply.code(409).send({ message: error.message });
25
+ throw error;
26
+ }
27
+ };
28
+ server.get(prefix, (request, reply) => run(reply, () => recovery.readState(target.parse(request.params).guildId)));
29
+ server.get(`${prefix}/history`, (request, reply) => run(reply, () => {
30
+ const filters = nexusCommandRecoveryHistoryQuerySchema.parse(request.query);
31
+ return recovery.listHistory({
32
+ ...target.parse(request.params),
33
+ limit: filters.limit,
34
+ ...(filters.beforeEventId
35
+ ? { beforeEventId: filters.beforeEventId }
36
+ : {}),
37
+ });
38
+ }));
39
+ server.post(`${prefix}/reset-timer`, (request, reply) => run(reply, () => recovery.resetTimer({
40
+ ...target.parse(request.params),
41
+ ...nexusCommandRecoveryInputSchema.parse(request.body),
42
+ })));
43
+ server.post(`${prefix}/rename`, (request, reply) => run(reply, () => recovery.rename({
44
+ ...target.parse(request.params),
45
+ ...nexusCommandRecoveryRenameInputSchema.parse(request.body),
46
+ })));
47
+ }
48
+ //# sourceMappingURL=nexus-command-recovery-control-routes.js.map
@@ -0,0 +1,6 @@
1
+ import { type ServiceAccess } from "@helyx/sdk";
2
+ import type { DashboardModuleDefinition } from "./dashboard-module-projection.js";
3
+ export declare function nexusObservedRoot(services: ServiceAccess, guildId: string): Promise<string | null>;
4
+ /** Relabel the guild DTO only; permissions, canonical identities and handlers stay unchanged. */
5
+ export declare function nexusModuleLabels(modules: readonly DashboardModuleDefinition[], services: ServiceAccess, guildId: string): Promise<DashboardModuleDefinition[]>;
6
+ //# sourceMappingURL=nexus-command-references.d.ts.map
@@ -0,0 +1,33 @@
1
+ import { HELYX_SERVICE_NAMES, formatNexusCommandReference, observedNexusCommandRoot, } from "@helyx/sdk";
2
+ export async function nexusObservedRoot(services, guildId) {
3
+ try {
4
+ if (!services.has(HELYX_SERVICE_NAMES.nexusCore))
5
+ return "nexus";
6
+ return await observedNexusCommandRoot(services.get(HELYX_SERVICE_NAMES.nexusCore), guildId);
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ }
12
+ /** Relabel the guild DTO only; permissions, canonical identities and handlers stay unchanged. */
13
+ export async function nexusModuleLabels(modules, services, guildId) {
14
+ const copy = structuredClone(modules);
15
+ if (!copy.some((module) => module.commands.some((command) => command.name.startsWith("/nexus "))))
16
+ return [...copy];
17
+ const root = await nexusObservedRoot(services, guildId);
18
+ return copy.map((module) => ({
19
+ ...module,
20
+ commands: module.commands.map((command) => {
21
+ if (!command.id.startsWith("nexus.") ||
22
+ !command.name.startsWith("/nexus "))
23
+ return command;
24
+ const path = command.name.slice("/nexus ".length).replaceAll(" ", ".");
25
+ return {
26
+ ...command,
27
+ name: formatNexusCommandReference(root, path) ??
28
+ `Nexus ${path.replaceAll(".", " ")} (command unavailable)`,
29
+ };
30
+ }),
31
+ }));
32
+ }
33
+ //# sourceMappingURL=nexus-command-references.js.map
@@ -1,7 +1,8 @@
1
1
  import { CORE_RECORD_RETENTION_TASK, MODULE_ACTIVATION_RECOVERY_TASK, ScheduledTaskRepository, } from "@helyx/database";
2
- import { getModuleScheduledTaskContribution, HELYX_SERVICE_NAMES, MODERATION_CASE_RETENTION_TASK, } from "@helyx/sdk";
2
+ import { getModuleScheduledTaskContribution, HELYX_SERVICE_NAMES, NEXUS_COMMAND_LOG_TASK, MODERATION_CASE_RETENTION_TASK, } from "@helyx/sdk";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { canAccessModule } from "./premium-access.js";
5
+ import { isInviteRollupMaintenanceTask } from "./invite-rollup-maintenance.js";
5
6
  const DEFAULT_POLL_INTERVAL_MS = 1_000;
6
7
  const DEFAULT_LEASE_MS = 45_000;
7
8
  const DEFAULT_CLAIM_LIMIT = 8;
@@ -295,6 +296,18 @@ export function createScheduledTaskRunner(input) {
295
296
  taskKind: contribution.kind,
296
297
  taskVersion: contribution.version,
297
298
  delivery: contribution.delivery,
299
+ ...((module.manifest.id === NEXUS_COMMAND_LOG_TASK.moduleId &&
300
+ contribution.kind === NEXUS_COMMAND_LOG_TASK.taskKind &&
301
+ contribution.version === NEXUS_COMMAND_LOG_TASK.taskVersion &&
302
+ contribution.delivery === "one-shot") ||
303
+ isInviteRollupMaintenanceTask({
304
+ moduleId: module.manifest.id,
305
+ taskKind: contribution.kind,
306
+ taskVersion: contribution.version,
307
+ delivery: contribution.delivery,
308
+ }, module)
309
+ ? { runWhenDisabled: true }
310
+ : {}),
298
311
  }))),
299
312
  MODERATION_CASE_RETENTION_TASK,
300
313
  ],
@@ -398,9 +411,15 @@ export function createLocalScheduledTaskRoute(input) {
398
411
  return deferred("module_globally_disabled", DEFAULT_POLL_INTERVAL_MS * 30);
399
412
  }
400
413
  if (task.guildId) {
401
- const enabled = await input.services
402
- .get(HELYX_SERVICE_NAMES.installations)
403
- .isModuleEnabled(task.guildId, task.moduleId);
414
+ const trustedCommandLog = task.moduleId === NEXUS_COMMAND_LOG_TASK.moduleId &&
415
+ task.taskKind === NEXUS_COMMAND_LOG_TASK.taskKind &&
416
+ task.taskVersion === NEXUS_COMMAND_LOG_TASK.taskVersion &&
417
+ task.delivery === "one-shot";
418
+ const enabled = trustedCommandLog ||
419
+ isInviteRollupMaintenanceTask(task, module) ||
420
+ (await input.services
421
+ .get(HELYX_SERVICE_NAMES.installations)
422
+ .isModuleEnabled(task.guildId, task.moduleId));
404
423
  if (!enabled)
405
424
  return deferred("module_disabled", DEFAULT_POLL_INTERVAL_MS * 30);
406
425
  if (!(await canAccessModule(input.services, task.guildId, module)))
@@ -0,0 +1,13 @@
1
+ export interface StartupCommandCatalogue {
2
+ revision: number;
3
+ fingerprint: string;
4
+ }
5
+ /** Publication failures or ownership loss must never advertise follower readiness. */
6
+ export declare function completeShardCommandStartup(input: {
7
+ assertOwnership(): void;
8
+ publishCatalogue(): Promise<void>;
9
+ synchronise(): Promise<void>;
10
+ markReady(): Promise<void>;
11
+ }): Promise<void>;
12
+ export declare function shardStartupCatalogueReady(value: unknown, expected: StartupCommandCatalogue | null): boolean;
13
+ //# sourceMappingURL=shard-command-startup.d.ts.map
@@ -0,0 +1,27 @@
1
+ /** Publication failures or ownership loss must never advertise follower readiness. */
2
+ export async function completeShardCommandStartup(input) {
3
+ input.assertOwnership();
4
+ await input.publishCatalogue();
5
+ input.assertOwnership();
6
+ await input.synchronise();
7
+ input.assertOwnership();
8
+ await input.markReady();
9
+ }
10
+ export function shardStartupCatalogueReady(value, expected) {
11
+ if (!value ||
12
+ typeof value !== "object" ||
13
+ !("ready" in value) ||
14
+ value.ready !== true ||
15
+ !("commandCatalogue" in value))
16
+ return false;
17
+ const actual = value.commandCatalogue;
18
+ if (expected === null)
19
+ return actual === null;
20
+ return (actual !== null &&
21
+ typeof actual === "object" &&
22
+ "revision" in actual &&
23
+ "fingerprint" in actual &&
24
+ actual.revision === expected.revision &&
25
+ actual.fingerprint === expected.fingerprint);
26
+ }
27
+ //# sourceMappingURL=shard-command-startup.js.map
@@ -239,6 +239,10 @@ export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.Zod
239
239
  }, z.core.$strict>, z.ZodObject<{
240
240
  kind: z.ZodLiteral<"guild.state.get">;
241
241
  guildId: z.ZodString;
242
+ }, z.core.$strict>, z.ZodObject<{
243
+ guildId: z.ZodString;
244
+ userIds: z.ZodArray<z.ZodString>;
245
+ kind: z.ZodLiteral<"guild.user-identities.read">;
242
246
  }, z.core.$strict>, z.ZodObject<{
243
247
  kind: z.ZodLiteral<"guild.dashboard.access">;
244
248
  guildId: z.ZodString;
@@ -307,12 +311,19 @@ export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.Zod
307
311
  assumptions: z.ZodObject<{
308
312
  entryChannelId: z.ZodString;
309
313
  beforeRoleIds: z.ZodArray<z.ZodString>;
314
+ removedRoleIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
310
315
  afterRoleId: z.ZodString;
311
316
  entrance: z.ZodEnum<{
312
317
  public: "public";
313
318
  restricted: "restricted";
314
319
  }>;
320
+ entryAfter: z.ZodOptional<z.ZodEnum<{
321
+ hidden: "hidden";
322
+ visible: "visible";
323
+ either: "either";
324
+ }>>;
315
325
  allowedChannelIds: z.ZodArray<z.ZodString>;
326
+ requiredAfterChannelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
316
327
  reviewChannelId: z.ZodOptional<z.ZodString>;
317
328
  }, z.core.$strict>;
318
329
  }, z.core.$strict>, z.ZodObject<{
@@ -460,6 +471,13 @@ export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.Zod
460
471
  readonly publish: "publish";
461
472
  }>;
462
473
  value: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
474
+ }, z.core.$strict>, z.ZodObject<{
475
+ actorUserId: z.ZodString;
476
+ correlationId: z.ZodString;
477
+ kind: z.ZodLiteral<"guild.module.resource.create-defaults">;
478
+ guildId: z.ZodString;
479
+ moduleId: z.ZodString;
480
+ resourceType: z.ZodString;
463
481
  }, z.core.$strict>, z.ZodObject<{
464
482
  actorUserId: z.ZodString;
465
483
  correlationId: z.ZodString;
@@ -724,6 +742,10 @@ export declare const shardControlRequestSchema: z.ZodObject<{
724
742
  }, z.core.$strict>, z.ZodObject<{
725
743
  kind: z.ZodLiteral<"guild.state.get">;
726
744
  guildId: z.ZodString;
745
+ }, z.core.$strict>, z.ZodObject<{
746
+ guildId: z.ZodString;
747
+ userIds: z.ZodArray<z.ZodString>;
748
+ kind: z.ZodLiteral<"guild.user-identities.read">;
727
749
  }, z.core.$strict>, z.ZodObject<{
728
750
  kind: z.ZodLiteral<"guild.dashboard.access">;
729
751
  guildId: z.ZodString;
@@ -792,12 +814,19 @@ export declare const shardControlRequestSchema: z.ZodObject<{
792
814
  assumptions: z.ZodObject<{
793
815
  entryChannelId: z.ZodString;
794
816
  beforeRoleIds: z.ZodArray<z.ZodString>;
817
+ removedRoleIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
795
818
  afterRoleId: z.ZodString;
796
819
  entrance: z.ZodEnum<{
797
820
  public: "public";
798
821
  restricted: "restricted";
799
822
  }>;
823
+ entryAfter: z.ZodOptional<z.ZodEnum<{
824
+ hidden: "hidden";
825
+ visible: "visible";
826
+ either: "either";
827
+ }>>;
800
828
  allowedChannelIds: z.ZodArray<z.ZodString>;
829
+ requiredAfterChannelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
801
830
  reviewChannelId: z.ZodOptional<z.ZodString>;
802
831
  }, z.core.$strict>;
803
832
  }, z.core.$strict>, z.ZodObject<{
@@ -945,6 +974,13 @@ export declare const shardControlRequestSchema: z.ZodObject<{
945
974
  readonly publish: "publish";
946
975
  }>;
947
976
  value: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
977
+ }, z.core.$strict>, z.ZodObject<{
978
+ actorUserId: z.ZodString;
979
+ correlationId: z.ZodString;
980
+ kind: z.ZodLiteral<"guild.module.resource.create-defaults">;
981
+ guildId: z.ZodString;
982
+ moduleId: z.ZodString;
983
+ resourceType: z.ZodString;
948
984
  }, z.core.$strict>, z.ZodObject<{
949
985
  actorUserId: z.ZodString;
950
986
  correlationId: z.ZodString;
@@ -1143,6 +1179,21 @@ export declare const shardControlResponseSchema: z.ZodDiscriminatedUnion<[z.ZodO
1143
1179
  ok: z.ZodLiteral<false>;
1144
1180
  status: z.ZodNumber;
1145
1181
  message: z.ZodString;
1182
+ fieldError: z.ZodCatch<z.ZodOptional<z.ZodObject<{
1183
+ fieldName: z.ZodLiteral<"slashCommandName">;
1184
+ code: z.ZodEnum<{
1185
+ invalid_input: "invalid_input";
1186
+ revision_conflict: "revision_conflict";
1187
+ command_rename_unavailable: "command_rename_unavailable";
1188
+ command_name_policy_unavailable: "command_name_policy_unavailable";
1189
+ command_name_blocked: "command_name_blocked";
1190
+ command_name_reserved: "command_name_reserved";
1191
+ command_rename_cooldown: "command_rename_cooldown";
1192
+ command_sync_unresolved: "command_sync_unresolved";
1193
+ }>;
1194
+ availableAt: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
1195
+ serverTime: z.ZodOptional<z.ZodISODateTime>;
1196
+ }, z.core.$strict>>>;
1146
1197
  }, z.core.$strict>], "ok">;
1147
1198
  export type ShardControlResponse = z.infer<typeof shardControlResponseSchema>;
1148
1199
  declare const shardCloudOperationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -1714,6 +1765,10 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
1714
1765
  }, z.core.$strict>, z.ZodObject<{
1715
1766
  kind: z.ZodLiteral<"guild.state.get">;
1716
1767
  guildId: z.ZodString;
1768
+ }, z.core.$strict>, z.ZodObject<{
1769
+ guildId: z.ZodString;
1770
+ userIds: z.ZodArray<z.ZodString>;
1771
+ kind: z.ZodLiteral<"guild.user-identities.read">;
1717
1772
  }, z.core.$strict>, z.ZodObject<{
1718
1773
  kind: z.ZodLiteral<"guild.dashboard.access">;
1719
1774
  guildId: z.ZodString;
@@ -1782,12 +1837,19 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
1782
1837
  assumptions: z.ZodObject<{
1783
1838
  entryChannelId: z.ZodString;
1784
1839
  beforeRoleIds: z.ZodArray<z.ZodString>;
1840
+ removedRoleIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1785
1841
  afterRoleId: z.ZodString;
1786
1842
  entrance: z.ZodEnum<{
1787
1843
  public: "public";
1788
1844
  restricted: "restricted";
1789
1845
  }>;
1846
+ entryAfter: z.ZodOptional<z.ZodEnum<{
1847
+ hidden: "hidden";
1848
+ visible: "visible";
1849
+ either: "either";
1850
+ }>>;
1790
1851
  allowedChannelIds: z.ZodArray<z.ZodString>;
1852
+ requiredAfterChannelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1791
1853
  reviewChannelId: z.ZodOptional<z.ZodString>;
1792
1854
  }, z.core.$strict>;
1793
1855
  }, z.core.$strict>, z.ZodObject<{
@@ -1935,6 +1997,13 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
1935
1997
  readonly publish: "publish";
1936
1998
  }>;
1937
1999
  value: z.ZodRecord<z.ZodString, z.ZodCustom<ManagedResourceValue, ManagedResourceValue>>;
2000
+ }, z.core.$strict>, z.ZodObject<{
2001
+ actorUserId: z.ZodString;
2002
+ correlationId: z.ZodString;
2003
+ kind: z.ZodLiteral<"guild.module.resource.create-defaults">;
2004
+ guildId: z.ZodString;
2005
+ moduleId: z.ZodString;
2006
+ resourceType: z.ZodString;
1938
2007
  }, z.core.$strict>, z.ZodObject<{
1939
2008
  actorUserId: z.ZodString;
1940
2009
  correlationId: z.ZodString;
@@ -2340,6 +2409,21 @@ export declare const workerMessageSchema: z.ZodDiscriminatedUnion<[z.ZodDiscrimi
2340
2409
  ok: z.ZodLiteral<false>;
2341
2410
  status: z.ZodNumber;
2342
2411
  message: z.ZodString;
2412
+ fieldError: z.ZodCatch<z.ZodOptional<z.ZodObject<{
2413
+ fieldName: z.ZodLiteral<"slashCommandName">;
2414
+ code: z.ZodEnum<{
2415
+ invalid_input: "invalid_input";
2416
+ revision_conflict: "revision_conflict";
2417
+ command_rename_unavailable: "command_rename_unavailable";
2418
+ command_name_policy_unavailable: "command_name_policy_unavailable";
2419
+ command_name_blocked: "command_name_blocked";
2420
+ command_name_reserved: "command_name_reserved";
2421
+ command_rename_cooldown: "command_rename_cooldown";
2422
+ command_sync_unresolved: "command_sync_unresolved";
2423
+ }>;
2424
+ availableAt: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
2425
+ serverTime: z.ZodOptional<z.ZodISODateTime>;
2426
+ }, z.core.$strict>>>;
2343
2427
  }, z.core.$strict>], "ok">, z.ZodObject<{
2344
2428
  version: z.ZodLiteral<1>;
2345
2429
  type: z.ZodLiteral<"helyx.cloud.request">;
@@ -1,4 +1,6 @@
1
1
  import { z } from "zod";
2
+ import { discordUserIdentityRequestSchema } from "@helyx/control-protocol/discord-user-identities";
3
+ import { dashboardFieldValidationSchema } from "@helyx/control-protocol/field-validation";
2
4
  import { channelAuditModuleIdSchema, channelAuditInputSchema, channelAuditConfigurationSchema, channelAuditReportSchema, } from "@helyx/control-protocol/channel-audit";
3
5
  import { CLOUD_MAX_RESOURCE_IMPORT_BYTES, creatorOnboardingRequestSchema, } from "@helyx/control-protocol";
4
6
  import { AUTOMOD_SCANNER_LIMITS } from "@helyx/sdk";
@@ -297,6 +299,9 @@ export const shardControlOperationSchema = z.discriminatedUnion("kind", [
297
299
  })
298
300
  .strict(),
299
301
  z.object({ kind: z.literal("guild.state.get"), guildId: snowflake }).strict(),
302
+ discordUserIdentityRequestSchema.extend({
303
+ kind: z.literal("guild.user-identities.read"),
304
+ }),
300
305
  z
301
306
  .object({
302
307
  kind: z.literal("guild.dashboard.access"),
@@ -514,6 +519,15 @@ export const shardControlOperationSchema = z.discriminatedUnion("kind", [
514
519
  ...mutationContext.shape,
515
520
  })
516
521
  .strict(),
522
+ z
523
+ .object({
524
+ kind: z.literal("guild.module.resource.create-defaults"),
525
+ guildId: snowflake,
526
+ moduleId,
527
+ resourceType,
528
+ ...mutationContext.shape,
529
+ })
530
+ .strict(),
517
531
  z
518
532
  .object({
519
533
  kind: z.literal("guild.module.resource.update"),
@@ -652,6 +666,7 @@ export const shardControlResponseSchema = z.discriminatedUnion("ok", [
652
666
  ok: z.literal(false),
653
667
  status: z.number().int().min(400).max(599),
654
668
  message: z.string().min(1).max(300),
669
+ fieldError: dashboardFieldValidationSchema.optional().catch(undefined),
655
670
  })
656
671
  .strict(),
657
672
  ]);
@@ -1092,6 +1107,14 @@ export async function executeShardControlOperation(handler, operation) {
1092
1107
  });
1093
1108
  case "guild.state.get":
1094
1109
  return handler.getGuildState(operation.guildId);
1110
+ case "guild.user-identities.read": {
1111
+ if (!handler.resolveDiscordUserIdentities)
1112
+ throw new Error("Discord identity lookup is unavailable");
1113
+ return handler.resolveDiscordUserIdentities({
1114
+ guildId: operation.guildId,
1115
+ userIds: operation.userIds,
1116
+ });
1117
+ }
1095
1118
  case "guild.dashboard.access":
1096
1119
  return handler.canAccessDashboard(operation);
1097
1120
  case "guild.access-policy.get":
@@ -1284,6 +1307,16 @@ export async function executeShardControlOperation(handler, operation) {
1284
1307
  actorUserId: operation.actorUserId,
1285
1308
  correlationId: operation.correlationId,
1286
1309
  });
1310
+ case "guild.module.resource.create-defaults":
1311
+ if (!handler.getManagedResourceCreateDefaults)
1312
+ throw new Error("Creation defaults are unavailable");
1313
+ return handler.getManagedResourceCreateDefaults({
1314
+ guildId: operation.guildId,
1315
+ moduleId: operation.moduleId,
1316
+ resourceType: operation.resourceType,
1317
+ actorUserId: operation.actorUserId,
1318
+ correlationId: operation.correlationId,
1319
+ });
1287
1320
  case "guild.module.resource.update":
1288
1321
  return handler.updateManagedResource({
1289
1322
  guildId: operation.guildId,
@@ -0,0 +1,5 @@
1
+ import { type DatabasePool } from "@helyx/database";
2
+ /** No provisional order: schema readiness precedes the first coordinator tuple. */
3
+ export declare function prepareShardDeploymentOrder(database: DatabasePool, mode: "apply" | "inspect"): Promise<number>;
4
+ export declare function allocateShardDeploymentOrder(database: DatabasePool): Promise<number>;
5
+ //# sourceMappingURL=shard-core-readiness.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { inspectCoreMigrations, runCoreMigrations, RuntimeStateRepository, } from "@helyx/database";
2
+ /** No provisional order: schema readiness precedes the first coordinator tuple. */
3
+ export async function prepareShardDeploymentOrder(database, mode) {
4
+ if (mode === "inspect") {
5
+ const result = await inspectCoreMigrations(database);
6
+ if (result.pending.length)
7
+ throw new Error(`Core migrations must be applied before shard admission: ${result.pending.join(", ")}`);
8
+ }
9
+ else
10
+ await runCoreMigrations(database);
11
+ return allocateShardDeploymentOrder(database);
12
+ }
13
+ export async function allocateShardDeploymentOrder(database) {
14
+ const value = await new RuntimeStateRepository(database).nextShardDeploymentOrder();
15
+ if (value < 1n || value > BigInt(Number.MAX_SAFE_INTEGER))
16
+ throw new Error("Shard deployment order is outside the safe runtime range");
17
+ return Number(value);
18
+ }
19
+ //# sourceMappingURL=shard-core-readiness.js.map
@@ -1,3 +1,4 @@
1
+ import type { DiscordUserIdentityRequest, DiscordUserIdentityResponse } from "@helyx/control-protocol/discord-user-identities";
1
2
  import { type AutoModerationEnhancedResultOutcome, type CreatorOnboardingRequest, type CreatorOnboardingResponse } from "@helyx/sdk";
2
3
  import { type BotControlHandler } from "./control-server.js";
3
4
  import { type ShardControlRequest, type ShardControlResponse } from "./shard-contracts.js";
@@ -39,6 +40,7 @@ export declare class ShardControlRouter implements BotControlHandler {
39
40
  limit: number;
40
41
  knownFingerprint?: string;
41
42
  }): ReturnType<AutoModerationScannerProviderRegistryService["getConfigurationPage"]>;
43
+ resolveDiscordUserIdentities(input: DiscordUserIdentityRequest): Promise<DiscordUserIdentityResponse>;
42
44
  getGuildState(guildId: string): ReturnType<BotControlHandler["getGuildState"]>;
43
45
  canAccessDashboard(input: Parameters<BotControlHandler["canAccessDashboard"]>[0]): ReturnType<BotControlHandler["canAccessDashboard"]>;
44
46
  getGuildAccessPolicy(input: Parameters<BotControlHandler["getGuildAccessPolicy"]>[0]): ReturnType<BotControlHandler["getGuildAccessPolicy"]>;
@@ -62,6 +64,7 @@ export declare class ShardControlRouter implements BotControlHandler {
62
64
  previewManagedResource(input: Parameters<BotControlHandler["previewManagedResource"]>[0]): ReturnType<BotControlHandler["previewManagedResource"]>;
63
65
  importManagedResource(input: Parameters<BotControlHandler["importManagedResource"]>[0]): ReturnType<BotControlHandler["importManagedResource"]>;
64
66
  createManagedResource(input: Parameters<BotControlHandler["createManagedResource"]>[0]): ReturnType<BotControlHandler["createManagedResource"]>;
67
+ getManagedResourceCreateDefaults(input: Parameters<NonNullable<BotControlHandler["getManagedResourceCreateDefaults"]>>[0]): ReturnType<NonNullable<BotControlHandler["getManagedResourceCreateDefaults"]>>;
65
68
  updateManagedResource(input: Parameters<BotControlHandler["updateManagedResource"]>[0]): ReturnType<BotControlHandler["updateManagedResource"]>;
66
69
  deleteManagedResource(input: Parameters<BotControlHandler["deleteManagedResource"]>[0]): ReturnType<BotControlHandler["deleteManagedResource"]>;
67
70
  executeManagedResourceAction(input: Parameters<BotControlHandler["executeManagedResourceAction"]>[0]): ReturnType<BotControlHandler["executeManagedResourceAction"]>;
@@ -46,6 +46,9 @@ export class ShardControlRouter {
46
46
  ...input,
47
47
  });
48
48
  }
49
+ resolveDiscordUserIdentities(input) {
50
+ return this.#route({ kind: "guild.user-identities.read", ...input });
51
+ }
49
52
  getGuildState(guildId) {
50
53
  return this.#route({ kind: "guild.state.get", guildId });
51
54
  }
@@ -189,6 +192,12 @@ export class ShardControlRouter {
189
192
  ...input,
190
193
  }));
191
194
  }
195
+ getManagedResourceCreateDefaults(input) {
196
+ return this.#route(shardControlOperationSchema.parse({
197
+ kind: "guild.module.resource.create-defaults",
198
+ ...input,
199
+ }));
200
+ }
192
201
  updateManagedResource(input) {
193
202
  return this.#route(shardControlOperationSchema.parse({
194
203
  kind: "guild.module.resource.update",
@@ -391,7 +400,7 @@ function unwrapResponse(response) {
391
400
  ? accepted.status
392
401
  : accepted.status >= 500
393
402
  ? 503
394
- : 502, accepted.message);
403
+ : 502, accepted.message, accepted.fieldError);
395
404
  return accepted.result;
396
405
  }
397
406
  function sameShardLease(left, right) {
@@ -30,7 +30,7 @@ export declare function shardHostedControlCallbacks(router: Pick<ShardControlRou
30
30
  };
31
31
  export declare function splitNumericCommittedBatch(batch: NumericWriteBehindCommittedBatch, index: number): NumericWriteBehindCommittedBatch;
32
32
  export declare function buildShardWorkerEnvironment(source: NodeJS.ProcessEnv, identity: ShardIdentity, restartCount: number): NodeJS.ProcessEnv;
33
- export declare function shardRuntimeCompositionHash(modules: readonly ModuleDefinition[], internalGuildId?: string, globalCommandMode?: Parameters<typeof buildApplicationCommandDefinitions>[2]): string;
33
+ export declare function shardRuntimeCompositionHash(modules: readonly ModuleDefinition[], internalGuildId?: string, globalCommandMode?: Parameters<typeof buildApplicationCommandDefinitions>[2], commandCatalogueFingerprint?: string): string;
34
34
  export declare function coordinatedFollowerReady(input: {
35
35
  health: ShardHealthSnapshot;
36
36
  activeLeader: ShardLeaderLease | undefined;