@open-everywhere/provider-discord 0.6.0 → 0.8.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 (72) hide show
  1. package/agent/approvals/discord-admin.ts +121 -0
  2. package/agent/approvals/discord-card.ts +32 -38
  3. package/agent/approvals/discord-flow.ts +18 -6
  4. package/agent/channels/discord-channel-info.ts +43 -15
  5. package/agent/channels/discord-dispatch-target.ts +36 -1
  6. package/agent/channels/discord-events.ts +3 -2
  7. package/agent/channels/discord-friendly-names.ts +28 -0
  8. package/agent/channels/discord-front.ts +7 -3
  9. package/agent/channels/discord-gateway.ts +88 -35
  10. package/agent/channels/discord-invite.ts +46 -0
  11. package/agent/channels/discord-origin-codec.ts +11 -0
  12. package/agent/channels/discord-rest.ts +35 -2
  13. package/agent/commands/discord-commands.ts +64 -12
  14. package/agent/docs-generated.ts +506 -2
  15. package/agent/register.ts +21 -1
  16. package/agent/surface-parity.ts +3 -0
  17. package/dist/agent/approvals/discord-admin.d.ts +31 -0
  18. package/dist/agent/approvals/discord-admin.d.ts.map +1 -1
  19. package/dist/agent/approvals/discord-admin.js +107 -0
  20. package/dist/agent/approvals/discord-admin.js.map +1 -1
  21. package/dist/agent/approvals/discord-card.d.ts +13 -14
  22. package/dist/agent/approvals/discord-card.d.ts.map +1 -1
  23. package/dist/agent/approvals/discord-card.js +23 -36
  24. package/dist/agent/approvals/discord-card.js.map +1 -1
  25. package/dist/agent/approvals/discord-flow.d.ts.map +1 -1
  26. package/dist/agent/approvals/discord-flow.js +18 -7
  27. package/dist/agent/approvals/discord-flow.js.map +1 -1
  28. package/dist/agent/channels/discord-channel-info.d.ts +3 -1
  29. package/dist/agent/channels/discord-channel-info.d.ts.map +1 -1
  30. package/dist/agent/channels/discord-channel-info.js +40 -13
  31. package/dist/agent/channels/discord-channel-info.js.map +1 -1
  32. package/dist/agent/channels/discord-dispatch-target.d.ts +17 -1
  33. package/dist/agent/channels/discord-dispatch-target.d.ts.map +1 -1
  34. package/dist/agent/channels/discord-dispatch-target.js +35 -1
  35. package/dist/agent/channels/discord-dispatch-target.js.map +1 -1
  36. package/dist/agent/channels/discord-events.d.ts +3 -2
  37. package/dist/agent/channels/discord-events.d.ts.map +1 -1
  38. package/dist/agent/channels/discord-events.js.map +1 -1
  39. package/dist/agent/channels/discord-friendly-names.d.ts +7 -0
  40. package/dist/agent/channels/discord-friendly-names.d.ts.map +1 -0
  41. package/dist/agent/channels/discord-friendly-names.js +27 -0
  42. package/dist/agent/channels/discord-friendly-names.js.map +1 -0
  43. package/dist/agent/channels/discord-front.d.ts.map +1 -1
  44. package/dist/agent/channels/discord-front.js +7 -3
  45. package/dist/agent/channels/discord-front.js.map +1 -1
  46. package/dist/agent/channels/discord-gateway.d.ts +6 -0
  47. package/dist/agent/channels/discord-gateway.d.ts.map +1 -1
  48. package/dist/agent/channels/discord-gateway.js +61 -8
  49. package/dist/agent/channels/discord-gateway.js.map +1 -1
  50. package/dist/agent/channels/discord-invite.d.ts +10 -0
  51. package/dist/agent/channels/discord-invite.d.ts.map +1 -0
  52. package/dist/agent/channels/discord-invite.js +42 -0
  53. package/dist/agent/channels/discord-invite.js.map +1 -0
  54. package/dist/agent/channels/discord-origin-codec.d.ts.map +1 -1
  55. package/dist/agent/channels/discord-origin-codec.js +12 -0
  56. package/dist/agent/channels/discord-origin-codec.js.map +1 -1
  57. package/dist/agent/channels/discord-rest.d.ts.map +1 -1
  58. package/dist/agent/channels/discord-rest.js +39 -2
  59. package/dist/agent/channels/discord-rest.js.map +1 -1
  60. package/dist/agent/commands/discord-commands.d.ts.map +1 -1
  61. package/dist/agent/commands/discord-commands.js +62 -13
  62. package/dist/agent/commands/discord-commands.js.map +1 -1
  63. package/dist/agent/docs-generated.d.ts.map +1 -1
  64. package/dist/agent/docs-generated.js +506 -2
  65. package/dist/agent/docs-generated.js.map +1 -1
  66. package/dist/agent/register.d.ts.map +1 -1
  67. package/dist/agent/register.js +19 -2
  68. package/dist/agent/register.js.map +1 -1
  69. package/dist/agent/surface-parity.d.ts.map +1 -1
  70. package/dist/agent/surface-parity.js +3 -0
  71. package/dist/agent/surface-parity.js.map +1 -1
  72. package/package.json +10 -2
package/agent/register.ts CHANGED
@@ -45,16 +45,21 @@ import {
45
45
  registerNativeAdminCheck,
46
46
  registerNativeMemberCheck,
47
47
  registerScopeLabelResolver,
48
+ registerMeetingInviteResolver,
48
49
  registerBotDisplayName,
49
50
  registerAccountDirectory,
50
51
  registerProviderDocs,
51
52
  registerSurfaceCommandReconciler,
53
+ registerFriendlyNameResolver,
54
+ registerAccountDisplayName,
52
55
  } from "@open-everywhere/core/agent/adapter-api.js";
56
+ import { fetchDiscordInfo } from "./channels/discord-channel-info.js";
57
+ import { discordFriendlyNameResolver } from "./channels/discord-friendly-names.js";
53
58
  import { PROVIDER_DOCS } from "./docs-generated.js";
54
59
  import { DISCORD_SURFACE_PARITY } from "./surface-parity.js";
55
60
  import { DISCORD_PROVIDER_EVENTS } from "./provider-events.js";
56
61
  import { registerDiscordOps } from "./ops.js";
57
- import { resolveDiscordTarget, discordReportTargetFor, resolveDiscordDeclaredTarget } from "./channels/discord-dispatch-target.js";
62
+ import { resolveDiscordTarget, discordReportTargetFor, resolveDiscordDeclaredTarget, discordTestRunArm } from "./channels/discord-dispatch-target.js";
58
63
  import { bindDiscord } from "./channels/discord-identity.js";
59
64
  import { discordPostArm } from "./channels/discord-post-arm.js";
60
65
  import { discordWakeOriginCodec } from "./channels/discord-origin-codec.js";
@@ -65,6 +70,7 @@ import { discordBotDisplayName } from "./channels/discord-bot-name.js";
65
70
  import { fetchGuildDirectory } from "./channels/discord-directory.js";
66
71
  import { postDiscordApprovalCard, postDiscordJudgeLiftNotice } from "./approvals/discord-flow.js";
67
72
  import { discordScopeLabelResolver } from "./approvals/discord-scope-label.js";
73
+ import { discordInviteResolver } from "./channels/discord-invite.js";
68
74
  import { guildIdFromScopeKey, isGuildAdminViaRest, isGuildMemberViaRest } from "./approvals/discord-admin.js";
69
75
  import { reconcileDiscordCommands } from "./commands/discord-command-sync.js";
70
76
 
@@ -88,6 +94,15 @@ export function registerDiscordProvider(): void {
88
94
  // the manual's inventory table is generated from it.
89
95
  registerProviderEvents("discord", DISCORD_PROVIDER_EVENTS);
90
96
  registerPostArm(discordPostArm);
97
+ // The friendly-names guard's Discord resolver (OPE-2482): a raw snowflake in text a person reads
98
+ // renders as the channel, server or person it names.
99
+ registerFriendlyNameResolver("discord", discordFriendlyNameResolver());
100
+ // The account profile (OPE-2482): a person's display name and the username Discord keeps unique, so
101
+ // an identity-link ask names the account by name and handle, never by its number.
102
+ registerAccountDisplayName("discord", async (nativeId) => {
103
+ const info = await fetchDiscordInfo("users", nativeId);
104
+ return info ? { name: info.name, ...(info.handle ? { handle: info.handle } : {}) } : undefined;
105
+ });
91
106
  registerWakeOriginCodec("discord", discordWakeOriginCodec);
92
107
  registerReadAdapter(discordReadAdapter);
93
108
  // THE SEAT CATCH-UP FETCH (OPE-1726): the seat's own channel (or thread) history since its
@@ -108,6 +123,8 @@ export function registerDiscordProvider(): void {
108
123
  reportTargetFor: discordReportTargetFor,
109
124
  // OPE-2419 — a webhook target on Discord: a guild channel, or a person's DM opened at fire time.
110
125
  resolveDeclaredTarget: (spec) => resolveDiscordDeclaredTarget(spec),
126
+ // OPE-2540 — a routine test run on Discord, anchored on its own opening post.
127
+ testRun: discordTestRunArm,
111
128
  });
112
129
  // Native admin leg for the spend-cap bypass (spend/bypass.ts): a guild ADMINISTRATOR, REST-verified.
113
130
  registerNativeAdminCheck("discord", async (scopeKey, principalId) => {
@@ -122,6 +139,9 @@ export function registerDiscordProvider(): void {
122
139
  return guildId ? isGuildMemberViaRest(guildId, principalId) : false;
123
140
  });
124
141
  registerScopeLabelResolver("discord", discordScopeLabelResolver);
142
+ // The meeting invite lookup (OPE-2473): a `discord.gg/<code>` link from "Invite to voice channel" resolves to its
143
+ // server and voice channel, and core runs every usual meeting check on that channel.
144
+ registerMeetingInviteResolver("discord", discordInviteResolver);
125
145
  // The bot's own Discord handle (OPE-610) — the arm the instruction assembler renders as a HANDLE
126
146
  // line on a Discord-pinned session ("your mention/handle here appears as X"), never as identity —
127
147
  // see channels/discord-bot-name.ts's header for the naming-model split. `discordBotDisplayName`
@@ -61,6 +61,9 @@ export const DISCORD_SURFACE_PARITY: SurfaceParityDeclaration = {
61
61
  // as this surface's own card with the overrule button, and the tap comes back the same route the
62
62
  // Approve/Reject taps take.
63
63
  "judge-lift-notice": "supported",
64
+ // OPE-2534: the unified-window divert asks core on every guild channel wake (discord-gateway.ts). A wake on the
65
+ // native per-channel path carries no wake id, so it takes no note, as a Slack room with no window takes none.
66
+ "out-of-office-cover": "supported",
64
67
  "name-drop-mention": "supported",
65
68
  // 🔴 THE EVENT NEVER LEAVES THE RELAY. `deploy/discord-relay/index.js` subscribes to
66
69
  // `Events.MessageCreate` (plus the two reaction events) and nothing else, so an edit — Discord's
@@ -60,4 +60,35 @@ export declare function isGuildMemberViaRest(guildId: string, userId: string, de
60
60
  export declare function discordAuthorRoles(guildId: string, userId: string, deps?: DiscordAdminDeps): Promise<readonly string[] | undefined>;
61
61
  /** Reset the cached role-evidence verdicts (tests only). */
62
62
  export declare function _resetDiscordAuthorRolesCache(): void;
63
+ /** One permission overwrite on a channel. `type` 0 is a role (the @everyone role's id is the guild id), 1 a member. */
64
+ export interface DiscordOverwrite {
65
+ readonly id: string;
66
+ readonly type: number;
67
+ readonly allow: string;
68
+ readonly deny: string;
69
+ }
70
+ /** The facts Discord's permission rule reads. */
71
+ export interface DiscordViewFacts {
72
+ readonly guildId: string;
73
+ readonly ownerId?: string;
74
+ /** Role id → permission bits, as the guild's role table spells them (a decimal string). */
75
+ readonly rolePermissions: ReadonlyMap<string, string>;
76
+ readonly userId: string;
77
+ readonly memberRoleIds: readonly string[];
78
+ readonly overwrites: readonly DiscordOverwrite[];
79
+ }
80
+ /**
81
+ * Discord's documented permission rule for VIEW_CHANNEL (developer docs, "Permissions" → "Permission Overwrites"),
82
+ * in its order. The owner and ADMINISTRATOR see everything. Else the base is the @everyone role's bits OR the
83
+ * member's roles' bits. Then the @everyone overwrite, then the member's role overwrites together, then the member's
84
+ * own overwrite, each as "deny, then allow". Pure.
85
+ */
86
+ export declare function discordCanView(f: DiscordViewFacts): boolean;
87
+ /**
88
+ * Can `userId` read `channelId` in `guildId`, per Discord's own rule ({@link discordCanView})? A public thread reads
89
+ * as its parent channel. Each of these answers FALSE: a private thread, a channel in another guild, a person who is
90
+ * not a member (404), a bot account (cover is for people), and every failure. NEVER throws. Not cached: cover asks
91
+ * only about a person with live cover.
92
+ */
93
+ export declare function discordMemberCanViewChannel(guildId: string, channelId: string, userId: string, deps?: DiscordAdminDeps): Promise<boolean>;
63
94
  //# sourceMappingURL=discord-admin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discord-admin.d.ts","sourceRoot":"","sources":["../../../agent/approvals/discord-admin.ts"],"names":[],"mappings":"AA+BA;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxE;AAED,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAiBD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0CxH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CA+BzH;AAOD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CA+B7I;AAED,4DAA4D;AAC5D,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD"}
1
+ {"version":3,"file":"discord-admin.d.ts","sourceRoot":"","sources":["../../../agent/approvals/discord-admin.ts"],"names":[],"mappings":"AA+BA;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxE;AAED,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAiBD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0CxH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CA+BzH;AAOD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CA+B7I;AAED,4DAA4D;AAC5D,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD;AAgBD,uHAAuH;AACvH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2FAA2F;IAC3F,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAClD;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAmB3D;AAWD;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwCnJ"}
@@ -216,4 +216,111 @@ export async function discordAuthorRoles(guildId, userId, deps = {}) {
216
216
  export function _resetDiscordAuthorRolesCache() {
217
217
  roleEvidenceCache.clear();
218
218
  }
219
+ // --- CAN THIS PERSON READ THIS CHANNEL? (OPE-2534, out-of-office cover) --------------------------------------------
220
+ //
221
+ // The cover recap shows a question only where the covered person could already read it. A relay message carries no
222
+ // permission data, so the answer is Discord's own permission rule over three REST reads: the channel (its overwrites,
223
+ // and its parent for a thread), the guild (its owner and role table) and the member (their roles). FAIL-CLOSED like
224
+ // every check in this file: any failure is "cannot read", so the recap counts the question and shows nothing of it.
225
+ /** Discord's `VIEW_CHANNEL` and `ADMINISTRATOR` permission bits. */
226
+ const VIEW_CHANNEL = 1n << 10n;
227
+ const ADMINISTRATOR = 1n << 3n;
228
+ /** A public thread (10 announcement, 11 public) reads as its parent channel. A private thread (12) does not. */
229
+ const PUBLIC_THREAD_TYPES = new Set([10, 11]);
230
+ const PRIVATE_THREAD_TYPE = 12;
231
+ function permissionBits(v) {
232
+ return v !== undefined && /^\d+$/.test(v) ? BigInt(v) : 0n;
233
+ }
234
+ /**
235
+ * Discord's documented permission rule for VIEW_CHANNEL (developer docs, "Permissions" → "Permission Overwrites"),
236
+ * in its order. The owner and ADMINISTRATOR see everything. Else the base is the @everyone role's bits OR the
237
+ * member's roles' bits. Then the @everyone overwrite, then the member's role overwrites together, then the member's
238
+ * own overwrite, each as "deny, then allow". Pure.
239
+ */
240
+ export function discordCanView(f) {
241
+ if (f.ownerId !== undefined && f.ownerId === f.userId)
242
+ return true;
243
+ let base = permissionBits(f.rolePermissions.get(f.guildId));
244
+ for (const r of f.memberRoleIds)
245
+ base |= permissionBits(f.rolePermissions.get(r));
246
+ if ((base & ADMINISTRATOR) !== 0n)
247
+ return true;
248
+ const everyone = f.overwrites.find((o) => o.type === 0 && o.id === f.guildId);
249
+ if (everyone)
250
+ base = (base & ~permissionBits(everyone.deny)) | permissionBits(everyone.allow);
251
+ let allow = 0n;
252
+ let deny = 0n;
253
+ for (const o of f.overwrites) {
254
+ if (o.type === 0 && o.id !== f.guildId && f.memberRoleIds.includes(o.id)) {
255
+ allow |= permissionBits(o.allow);
256
+ deny |= permissionBits(o.deny);
257
+ }
258
+ }
259
+ base = (base & ~deny) | allow;
260
+ const own = f.overwrites.find((o) => o.type === 1 && o.id === f.userId);
261
+ if (own)
262
+ base = (base & ~permissionBits(own.deny)) | permissionBits(own.allow);
263
+ return (base & VIEW_CHANNEL) !== 0n;
264
+ }
265
+ function overwritesOf(channel) {
266
+ const raw = Array.isArray(channel["permission_overwrites"]) ? channel["permission_overwrites"] : [];
267
+ return raw.flatMap((o) => isObject(o) && typeof o["id"] === "string" && typeof o["type"] === "number"
268
+ ? [{ id: o["id"], type: o["type"], allow: String(o["allow"] ?? "0"), deny: String(o["deny"] ?? "0") }]
269
+ : []);
270
+ }
271
+ /**
272
+ * Can `userId` read `channelId` in `guildId`, per Discord's own rule ({@link discordCanView})? A public thread reads
273
+ * as its parent channel. Each of these answers FALSE: a private thread, a channel in another guild, a person who is
274
+ * not a member (404), a bot account (cover is for people), and every failure. NEVER throws. Not cached: cover asks
275
+ * only about a person with live cover.
276
+ */
277
+ export async function discordMemberCanViewChannel(guildId, channelId, userId, deps = {}) {
278
+ const token = deps.token ?? process.env.DISCORD_BOT_TOKEN;
279
+ if (!token || !guildId || !channelId || !userId)
280
+ return false;
281
+ const doFetch = deps.fetchFn ?? fetch;
282
+ const headers = { authorization: `Bot ${token}` };
283
+ const read = async (path) => {
284
+ const res = await doFetch(`https://discord.com/api/v10/${path}`, { headers });
285
+ if (!res.ok)
286
+ return undefined;
287
+ const body = (await res.json());
288
+ return isObject(body) ? body : undefined;
289
+ };
290
+ try {
291
+ let channel = await read(`channels/${encodeURIComponent(channelId)}`);
292
+ if (!channel || channel["guild_id"] !== guildId || channel["type"] === PRIVATE_THREAD_TYPE)
293
+ return false;
294
+ if (typeof channel["type"] === "number" && PUBLIC_THREAD_TYPES.has(channel["type"])) {
295
+ const parentId = channel["parent_id"];
296
+ channel = typeof parentId === "string" ? await read(`channels/${encodeURIComponent(parentId)}`) : undefined;
297
+ if (!channel || channel["guild_id"] !== guildId)
298
+ return false;
299
+ }
300
+ const guild = await read(`guilds/${encodeURIComponent(guildId)}`);
301
+ if (!guild)
302
+ return false;
303
+ const member = await read(`guilds/${encodeURIComponent(guildId)}/members/${encodeURIComponent(userId)}`);
304
+ const user = member?.["user"];
305
+ if (!member || !isObject(user) || user["id"] !== userId || user["bot"] === true)
306
+ return false;
307
+ const rolePermissions = new Map();
308
+ for (const r of Array.isArray(guild["roles"]) ? guild["roles"] : []) {
309
+ if (isObject(r) && typeof r["id"] === "string")
310
+ rolePermissions.set(r["id"], String(r["permissions"] ?? "0"));
311
+ }
312
+ return discordCanView({
313
+ guildId,
314
+ ...(typeof guild["owner_id"] === "string" ? { ownerId: guild["owner_id"] } : {}),
315
+ rolePermissions,
316
+ userId,
317
+ memberRoleIds: Array.isArray(member["roles"]) ? member["roles"].filter((r) => typeof r === "string") : [],
318
+ overwrites: overwritesOf(channel),
319
+ });
320
+ }
321
+ catch (err) {
322
+ log(`view check error for guild ${guildId}: ${err?.message ?? String(err)}`);
323
+ return false;
324
+ }
325
+ }
219
326
  //# sourceMappingURL=discord-admin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"discord-admin.js","sourceRoot":"","sources":["../../../agent/approvals/discord-admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discord-admin.js","sourceRoot":"","sources":["../../../agent/approvals/discord-admin.ts"],"names":[],"mappings":"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"}
@@ -51,8 +51,9 @@ export declare function parseDiscordApprovalCustomId(customId: string): {
51
51
  org: string;
52
52
  } | null;
53
53
  /**
54
- * The card for a still-pending action: the plain sentence, the summary, "requested by / expires", and one button per layout option, each carrying the pending id + org in its custom_id (see the file header for why the org rides the custom_id on Discord). Mirrors card.ts's pendingCardBlocks.
54
+ * The card for a still-pending action (OPE-2481): the headline in bold, at most one consequence line, a warning when the proposal was tainted, the small footer, and one button per layout option, each carrying the pending id + org in its custom_id (see the file header for why the org rides the custom_id on Discord). The kind never appears: Discord has no hidden metadata slot, so the kind lives on the row the custom_id names. Mirrors card.ts's pendingCardBlocks.
55
55
  * The OPTIONS come from core's card layout (OPE-53, OPE-2363: only a ROUTINE's card gets the middle grant button), so Slack, Teams and Discord can never disagree. OPE-2456's rule option needs a confirmation before the click, which a Discord button cannot show, so it is left out.
56
+ * The headline and the consequence went through core's `plainValue`, so they carry no markdown of their own. `<@id>` is Discord's user-mention syntax too, so the footer reads as the Slack card's does.
56
57
  */
57
58
  export declare function pendingDiscordCard(row: PendingActionRow, summaryLines: readonly string[]): DiscordCardMessage;
58
59
  /**
@@ -66,23 +67,21 @@ export declare function pendingDiscordCard(row: PendingActionRow, summaryLines:
66
67
  * `approval.judge.contradicted` row the contradiction breaker counts.
67
68
  *
68
69
  * NOT AN APPROVAL CARD, and the render says so: no Approve, no Reject, no expiry line. The act is
69
- * already done, so this is a review surface, not a decision surface. It deliberately does NOT reuse
70
- * `cardBody` — that helper's header reads "Approval requested", which is the one thing this message
71
- * must never say.
70
+ * already done, so this is a review surface, not a decision surface.
72
71
  *
73
- * THE COPY IS THE SLACK COPY, word for word (the header, the ⚡ line, the button label). Two rooms
74
- * on two platforms must not be told different things about the same mechanism; only the envelope
75
- * differs — Markdown `content` + a components row, rather than blocks.
72
+ * THE COPY IS THE SLACK COPY, word for word (core's `judgeLiftHeadline`, `judgeLiftOutcome` and
73
+ * `JUDGE_LIFT_BUTTON`). Two rooms on two platforms must not be told different things about the same
74
+ * mechanism; only the envelope differs — Markdown `content` + a components row, rather than blocks.
75
+ * Two lines and the button (OPE-2481): the headline names the act in plain words, never its kind.
76
76
  */
77
- export declare function judgeLiftNoticeDiscordCard(row: PendingActionRow, summaryLines: readonly string[], outcomeLine: string): DiscordCardMessage;
77
+ export declare function judgeLiftNoticeDiscordCard(row: PendingActionRow, _summaryLines: readonly string[], outcomeLine: string): DiscordCardMessage;
78
78
  /**
79
- * The card once a decision has landed: SAME summary, buttons GONE (`components: []` — the
80
- * type-7 UPDATE_MESSAGE response replaces the whole message, so an empty row strips them),
81
- * plus a context line naming who decided + the outcome. Renders whatever the caller already
82
- * CAS-decided — this function never decides anything (mirrors card.ts's decidedCardBlocks,
83
- * including the same three status lines).
79
+ * The card once a decision has landed: ONE line (OPE-2481), buttons GONE (`components: []` — the
80
+ * type-7 UPDATE_MESSAGE response replaces the whole message, so an empty row strips them). The line is
81
+ * core's `decidedCardLine`, so it reads exactly as the Slack card's does, including a durable
82
+ * decline's line. Renders whatever the caller already CAS-decided — this function never decides anything.
84
83
  */
85
- export declare function decidedDiscordCard(row: PendingActionRow, summaryLines: readonly string[], outcomeLine: string): DiscordCardMessage;
84
+ export declare function decidedDiscordCard(row: PendingActionRow, _summaryLines: readonly string[], outcomeLine: string): DiscordCardMessage;
86
85
  /**
87
86
  * Does a Discord interaction's `member.permissions` bitfield carry ADMINISTRATOR? The field
88
87
  * is a STRINGIFIED integer (Discord serializes the 64-bit+ field as a decimal string).
@@ -1 +1 @@
1
- {"version":3,"file":"discord-card.d.ts","sourceRoot":"","sources":["../../../agent/approvals/discord-card.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAGnG;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,iBAAiB,CAAC;AAEzD,uHAAuH;AACvH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAYzC;4FAC4F;AAC5F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAClD;AAED;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,QAAQ,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAM9F;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,uBAAuB,GAAG,MAAM,CAQ7G;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,uBAAuB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAcpI;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,kBAAkB,CAW7G;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,kBAAkB,CAkB1I;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,kBAAkB,CAalI;AAKD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAOlE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGvF"}
1
+ {"version":3,"file":"discord-card.d.ts","sourceRoot":"","sources":["../../../agent/approvals/discord-card.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAYnG;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,iBAAiB,CAAC;AAEzD,uHAAuH;AACvH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAYzC;4FAC4F;AAC5F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAClD;AAED;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,QAAQ,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAM9F;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,uBAAuB,GAAG,MAAM,CAQ7G;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,uBAAuB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAcpI;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,kBAAkB,CAY7G;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,kBAAkB,CAmB3I;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,kBAAkB,CAEnI;AAKD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAOlE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGvF"}
@@ -6,8 +6,8 @@
6
6
  //
7
7
  // Discord's card idiom differs from Slack's in three load-bearing ways, all handled here:
8
8
  // - No blocks: the card body is one Markdown `content` string; buttons ride a components
9
- // ACTION_ROW. (Discord caps `content` at 2000 chars — summary lines are short
10
- // code-rendered fragments, far under it.)
9
+ // ACTION_ROW. (Discord caps `content` at 2000 chars — a card is a few short lines
10
+ // of short code-rendered text, far under it.)
11
11
  // - No per-button `value` slot: Slack carries the org in the button's `value`; Discord's
12
12
  // ONLY payload carrier is the `custom_id`, so the org rides there too (same frozen-org
13
13
  // doctrine, different envelope). custom_id is capped at 100 chars — enforced below.
@@ -17,7 +17,7 @@
17
17
  // THREE renders live here, and only the first two are a card: the PENDING card (Approve/Reject), the
18
18
  // DECIDED card (no buttons), and the JUDGE-LIFT NOTICE (OPE-1103) — a review surface for an action
19
19
  // that already ran, carrying the one "This should not have run" button and never a decision one.
20
- import { approvalLabel, optionsWithoutConfirm, pendingCardLayout, plainSummaryForRow } from "@open-everywhere/core/agent/adapter-api.js";
20
+ import { cardFooter, decidedCardLine, footerRequester, JUDGE_LIFT_BUTTON, judgeLiftLines, optionsWithoutConfirm, pendingCardLayout, pendingCardLines, } from "@open-everywhere/core/agent/adapter-api.js";
21
21
  /**
22
22
  * Every approval button custom_id this feature owns starts with this. Deliberately distinct
23
23
  * from BOTH the Slack action_id prefix ("oe_approval:" — a different wire format, keeping
@@ -83,18 +83,16 @@ export function parseDiscordApprovalCustomId(customId) {
83
83
  return null;
84
84
  return { id, decision: decision, org };
85
85
  }
86
- /** The shared card body: the plain sentence first (OPE-2434), then the `Approval requested: <kind>` label, the summary and the provenance. `<@id>` is Discord's user-mention syntax too, so the requester line reads identically to the Slack card. The sentence went through core's `plainValue`, so it carries no markdown of its own. */
87
- function cardBody(row, summaryLines, footer) {
88
- return [`**${plainSummaryForRow(row)}**`, `-# ${approvalLabel(row.kind)}`, ...summaryLines, footer].join("\n");
89
- }
90
86
  const OPTION_STYLE = { primary: BUTTON_STYLE_SUCCESS, danger: BUTTON_STYLE_DANGER, neutral: BUTTON_STYLE_SECONDARY };
91
87
  /**
92
- * The card for a still-pending action: the plain sentence, the summary, "requested by / expires", and one button per layout option, each carrying the pending id + org in its custom_id (see the file header for why the org rides the custom_id on Discord). Mirrors card.ts's pendingCardBlocks.
88
+ * The card for a still-pending action (OPE-2481): the headline in bold, at most one consequence line, a warning when the proposal was tainted, the small footer, and one button per layout option, each carrying the pending id + org in its custom_id (see the file header for why the org rides the custom_id on Discord). The kind never appears: Discord has no hidden metadata slot, so the kind lives on the row the custom_id names. Mirrors card.ts's pendingCardBlocks.
93
89
  * The OPTIONS come from core's card layout (OPE-53, OPE-2363: only a ROUTINE's card gets the middle grant button), so Slack, Teams and Discord can never disagree. OPE-2456's rule option needs a confirmation before the click, which a Discord button cannot show, so it is left out.
90
+ * The headline and the consequence went through core's `plainValue`, so they carry no markdown of their own. `<@id>` is Discord's user-mention syntax too, so the footer reads as the Slack card's does.
94
91
  */
95
92
  export function pendingDiscordCard(row, summaryLines) {
96
93
  const layout = pendingCardLayout(row, summaryLines);
97
- const content = cardBody(row, summaryLines, `-# Requested by <@${layout.requestedBy}> · ${layout.expiry}`);
94
+ const [headline, ...rest] = pendingCardLines(layout);
95
+ const content = [`**${headline}**`, ...rest, `-# ${cardFooter(footerRequester(row, "discord"), layout.expiry)}`].join("\n");
98
96
  // A Discord button sends its click with no confirmation first, so the rule option (OPE-2456) is left out here.
99
97
  const buttons = optionsWithoutConfirm(layout.options).map((o) => ({
100
98
  type: COMPONENT_BUTTON,
@@ -115,18 +113,18 @@ export function pendingDiscordCard(row, summaryLines) {
115
113
  * `approval.judge.contradicted` row the contradiction breaker counts.
116
114
  *
117
115
  * NOT AN APPROVAL CARD, and the render says so: no Approve, no Reject, no expiry line. The act is
118
- * already done, so this is a review surface, not a decision surface. It deliberately does NOT reuse
119
- * `cardBody` — that helper's header reads "Approval requested", which is the one thing this message
120
- * must never say.
116
+ * already done, so this is a review surface, not a decision surface.
121
117
  *
122
- * THE COPY IS THE SLACK COPY, word for word (the header, the ⚡ line, the button label). Two rooms
123
- * on two platforms must not be told different things about the same mechanism; only the envelope
124
- * differs — Markdown `content` + a components row, rather than blocks.
118
+ * THE COPY IS THE SLACK COPY, word for word (core's `judgeLiftHeadline`, `judgeLiftOutcome` and
119
+ * `JUDGE_LIFT_BUTTON`). Two rooms on two platforms must not be told different things about the same
120
+ * mechanism; only the envelope differs — Markdown `content` + a components row, rather than blocks.
121
+ * Two lines and the button (OPE-2481): the headline names the act in plain words, never its kind.
125
122
  */
126
- export function judgeLiftNoticeDiscordCard(row, summaryLines, outcomeLine) {
127
- const context = `-# ⚡ Auto-approved by the approval judge — no card was posted and this has already run · ${outcomeLine}`;
123
+ export function judgeLiftNoticeDiscordCard(row, _summaryLines, outcomeLine) {
128
124
  return {
129
- content: [`**Ran without asking: ${row.kind}**`, ...summaryLines, context].join("\n"),
125
+ content: judgeLiftLines(row, outcomeLine)
126
+ .map((line, i, all) => (i === 0 ? `**${line}**` : i === all.length - 1 ? `-# ${line}` : line))
127
+ .join("\n"),
130
128
  components: [
131
129
  {
132
130
  type: COMPONENT_ACTION_ROW,
@@ -134,7 +132,7 @@ export function judgeLiftNoticeDiscordCard(row, summaryLines, outcomeLine) {
134
132
  {
135
133
  type: COMPONENT_BUTTON,
136
134
  style: BUTTON_STYLE_DANGER,
137
- label: "This should not have run",
135
+ label: JUDGE_LIFT_BUTTON,
138
136
  custom_id: buildDiscordApprovalCustomId(row, "contradict"),
139
137
  },
140
138
  ],
@@ -143,24 +141,13 @@ export function judgeLiftNoticeDiscordCard(row, summaryLines, outcomeLine) {
143
141
  };
144
142
  }
145
143
  /**
146
- * The card once a decision has landed: SAME summary, buttons GONE (`components: []` — the
147
- * type-7 UPDATE_MESSAGE response replaces the whole message, so an empty row strips them),
148
- * plus a context line naming who decided + the outcome. Renders whatever the caller already
149
- * CAS-decided — this function never decides anything (mirrors card.ts's decidedCardBlocks,
150
- * including the same three status lines).
144
+ * The card once a decision has landed: ONE line (OPE-2481), buttons GONE (`components: []` — the
145
+ * type-7 UPDATE_MESSAGE response replaces the whole message, so an empty row strips them). The line is
146
+ * core's `decidedCardLine`, so it reads exactly as the Slack card's does, including a durable
147
+ * decline's line. Renders whatever the caller already CAS-decided — this function never decides anything.
151
148
  */
152
- export function decidedDiscordCard(row, summaryLines, outcomeLine) {
153
- const decidedContext = row.status === "approved"
154
- ? `✅ Approved by <@${row.decidedBy}> · ${outcomeLine}`
155
- : row.status === "rejected"
156
- ? // A kind whose DECLINE is itself durable returns a line saying what the decline recorded
157
- // (approvals/types.ts ActionKind.declined). Every other kind's reject passes the literal
158
- // "rejected" and renders byte-for-byte what it always did. Kept in step with card.ts's
159
- // decidedCardBlocks by hand, exactly like the three status lines above it — a Discord card
160
- // that dropped the line would leave a clicker believing a decline was remembered.
161
- `❌ Rejected by <@${row.decidedBy}>${outcomeLine === "rejected" ? "" : ` · ${outcomeLine}`}`
162
- : "⏰ Expired";
163
- return { content: cardBody(row, summaryLines, decidedContext), components: [] };
149
+ export function decidedDiscordCard(row, _summaryLines, outcomeLine) {
150
+ return { content: decidedCardLine(row, outcomeLine, `<@${row.decidedBy}>`), components: [] };
164
151
  }
165
152
  /** Discord's ADMINISTRATOR permission bit (0x8). https://discord.com/developers/docs/topics/permissions */
166
153
  const ADMINISTRATOR_BIT = 1n << 3n;
@@ -1 +1 @@
1
- {"version":3,"file":"discord-card.js","sourceRoot":"","sources":["../../../agent/approvals/discord-card.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discord-card.js","sourceRoot":"","sources":["../../../agent/approvals/discord-card.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"discord-flow.d.ts","sourceRoot":"","sources":["../../../agent/approvals/discord-flow.ts"],"names":[],"mappings":"AAyDA,OAAO,EAOL,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EACtB,MAAM,4CAA4C,CAAC;AAyBpD,oFAAoF;AACpF,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjE,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE7B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CAEf;AAkDD;;;0DAG0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;oEACgE;IAChE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AASD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI,CAcpF;AAMD,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IAClC,gGAAgG;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IACzC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;CACpD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,uBAAuB,GAAG,0BAA0B,CAuD3F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gCAAgC,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAyH/I"}
1
+ {"version":3,"file":"discord-flow.d.ts","sourceRoot":"","sources":["../../../agent/approvals/discord-flow.ts"],"names":[],"mappings":"AAyDA,OAAO,EAOL,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EAEtB,MAAM,4CAA4C,CAAC;AAyBpD,oFAAoF;AACpF,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjE,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE7B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CAEf;AAkDD;;;0DAG0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;oEACgE;IAChE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AASD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI,CAcpF;AAMD,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IAClC,gGAAgG;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IACzC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;CACpD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,uBAAuB,GAAG,0BAA0B,CAuD3F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gCAAgC,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAoI/I"}
@@ -54,7 +54,7 @@
54
54
  // (`POST /webhooks/{app}/{token}` with `flags 64`) rather than the `@original` edit this package
55
55
  // has, and that behaviour cannot be measured offline. It is a separate change, and OPE-1407's
56
56
  // definition-of-done comment records it as open.
57
- import { resolveApprovalClick, deliverDecisionFeedback, discordDecisionWakeTarget, postDiscordDecisionNotice, clickerFloorRefusalNotice, judgeContradictionNotice, } from "@open-everywhere/core/agent/adapter-api.js";
57
+ import { resolveApprovalClick, deliverDecisionFeedback, discordDecisionWakeTarget, postDiscordDecisionNotice, clickerFloorRefusalNotice, judgeContradictionNotice, CLICK_NOTICE, } from "@open-everywhere/core/agent/adapter-api.js";
58
58
  import { OE_DISCORD_APPROVAL_PREFIX, parseDiscordApprovalCustomId, pendingDiscordCard, decidedDiscordCard, judgeLiftNoticeDiscordCard, isGuildAdministrator, scopeWithinGuild, } from "./discord-card.js";
59
59
  import { guildIdFromScopeKey, isGuildAdminViaRest } from "./discord-admin.js";
60
60
  function log(msg) {
@@ -190,7 +190,7 @@ function ephemeral(content) {
190
190
  export function discordResponseFor(res) {
191
191
  switch (res.outcome) {
192
192
  case "unknown":
193
- return ephemeral("This approval request is no longer known (it may have already been decided or has aged out).");
193
+ return ephemeral(CLICK_NOTICE.unknown);
194
194
  case "not-pending":
195
195
  case "expired-race":
196
196
  case "unregistered-kind":
@@ -201,7 +201,7 @@ export function discordResponseFor(res) {
201
201
  return { type: RESPONSE_UPDATE_MESSAGE, data: { content: card.content, components: card.components } };
202
202
  }
203
203
  case "denied":
204
- return ephemeral("Only a domain/org admin — or a server administrator, for this server's own scopes — can decide this request.");
204
+ return ephemeral(CLICK_NOTICE.deniedDiscord);
205
205
  case "clicker-denied":
206
206
  // The clicker gate (OPE-185, core approvals/clicker-floor.ts) — same UX as `denied`: an
207
207
  // ephemeral to the clicker alone, card untouched, row still pending.
@@ -269,7 +269,7 @@ export async function handleDiscordApprovalInteraction(raw, deps = {}) {
269
269
  if (!click.clickerId) {
270
270
  // It WAS ours; fail soft on the click rather than forward a half-understood payload.
271
271
  console.error(`[open-everywhere:discord-approvals] component click "${click.customId}" carries no user id — ignoring the click`);
272
- return ephemeral("Couldn't read who clicked — this decision was not applied.");
272
+ return ephemeral(CLICK_NOTICE.noClicker);
273
273
  }
274
274
  const clickerId = click.clickerId;
275
275
  const res = await resolveApprovalClick({
@@ -307,8 +307,11 @@ export async function handleDiscordApprovalInteraction(raw, deps = {}) {
307
307
  return rowGuild ? isGuildAdminViaRest(rowGuild, clickerId) : false;
308
308
  },
309
309
  });
310
- // Decision FEEDBACK (task #106 — Slack click-path parity): a fresh notice beside the card (the
311
- // UPDATE_MESSAGE response is an EDIT, invisible to backscroll) + the cross-thread window wake.
310
+ // Decision FEEDBACK (task #106 — Slack click-path parity): the cross-thread window wake, and a
311
+ // fresh notice beside the card that states the outcome only when no seat took the wake or a thread
312
+ // seat or a worker owns the card's channel (the UPDATE_MESSAGE response is an EDIT, invisible to
313
+ // backscroll; the room never reads the decided line twice, OPE-2473). Otherwise only an asker whom
314
+ // somebody else answered, or whose request expired, gets one short line (OPE-2490).
312
315
  // The wake's guild id comes from the SIGNED interaction (Slack's team.id analogue — the frozen
313
316
  // scopeKey can name a different workspace under an explicit-scope override). A DM-context
314
317
  // interaction has none, so the core takes the card's mint-frozen DM `postedTo` as the DM seat's
@@ -330,6 +333,10 @@ export async function handleDiscordApprovalInteraction(raw, deps = {}) {
330
333
  outcomeLine: "expired",
331
334
  executed: "none",
332
335
  target: discordDecisionWakeTarget(res.row, click.guildId),
336
+ // The interaction answer (UPDATE_MESSAGE) edits the card to its decided line.
337
+ cardShowsOutcome: true,
338
+ // The notice posts into the card's own channel; a Discord thread IS its channel id.
339
+ noticeThread: discordDecisionWakeTarget(res.row, click.guildId)?.origin ?? null,
333
340
  postNotice: (text) => (deps.postNotice ?? postDiscordDecisionNotice)(res.row, text),
334
341
  }, deps.decisionWake);
335
342
  }
@@ -342,6 +349,10 @@ export async function handleDiscordApprovalInteraction(raw, deps = {}) {
342
349
  executed: res.executed,
343
350
  clickerId,
344
351
  target: discordDecisionWakeTarget(res.row, click.guildId),
352
+ // The interaction answer (UPDATE_MESSAGE) edits the card to its decided line.
353
+ cardShowsOutcome: true,
354
+ // The notice posts into the card's own channel; a Discord thread IS its channel id.
355
+ noticeThread: discordDecisionWakeTarget(res.row, click.guildId)?.origin ?? null,
345
356
  postNotice: (text) => (deps.postNotice ?? postDiscordDecisionNotice)(res.row, text),
346
357
  }, deps.decisionWake);
347
358
  }
@@ -370,7 +381,7 @@ export async function handleDiscordApprovalInteraction(raw, deps = {}) {
370
381
  // Genuinely unexpected (store outage, …) after we'd established this WAS our click —
371
382
  // fail soft with an honest ephemeral note; never throw out of the interactions path.
372
383
  console.error(`[open-everywhere:discord-approvals] click handling failed softly for "${click.customId}": ${String(err)}`);
373
- return ephemeral("Something went wrong handling this click — the decision was not applied.");
384
+ return ephemeral(CLICK_NOTICE.failed);
374
385
  }
375
386
  }
376
387
  //# sourceMappingURL=discord-flow.js.map