lazy-gravity 0.2.0 → 0.3.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 (56) hide show
  1. package/README.md +76 -15
  2. package/dist/bin/commands/doctor.js +19 -2
  3. package/dist/bin/commands/setup.js +286 -70
  4. package/dist/bot/eventRouter.js +70 -0
  5. package/dist/bot/index.js +353 -147
  6. package/dist/bot/telegramCommands.js +428 -0
  7. package/dist/bot/telegramMessageHandler.js +304 -0
  8. package/dist/bot/telegramProjectCommand.js +137 -0
  9. package/dist/bot/workspaceQueue.js +61 -0
  10. package/dist/commands/joinCommandHandler.js +4 -1
  11. package/dist/database/telegramBindingRepository.js +97 -0
  12. package/dist/database/userPreferenceRepository.js +46 -1
  13. package/dist/events/interactionCreateHandler.js +36 -0
  14. package/dist/events/messageCreateHandler.js +11 -7
  15. package/dist/handlers/approvalButtonAction.js +99 -0
  16. package/dist/handlers/autoAcceptButtonAction.js +43 -0
  17. package/dist/handlers/buttonHandler.js +55 -0
  18. package/dist/handlers/commandHandler.js +44 -0
  19. package/dist/handlers/errorPopupButtonAction.js +137 -0
  20. package/dist/handlers/messageHandler.js +70 -0
  21. package/dist/handlers/modeSelectAction.js +63 -0
  22. package/dist/handlers/modelButtonAction.js +102 -0
  23. package/dist/handlers/planningButtonAction.js +118 -0
  24. package/dist/handlers/selectHandler.js +41 -0
  25. package/dist/handlers/templateButtonAction.js +54 -0
  26. package/dist/platform/adapter.js +8 -0
  27. package/dist/platform/discord/discordAdapter.js +99 -0
  28. package/dist/platform/discord/index.js +15 -0
  29. package/dist/platform/discord/wrappers.js +331 -0
  30. package/dist/platform/index.js +18 -0
  31. package/dist/platform/richContentBuilder.js +76 -0
  32. package/dist/platform/telegram/index.js +16 -0
  33. package/dist/platform/telegram/telegramAdapter.js +195 -0
  34. package/dist/platform/telegram/telegramFormatter.js +134 -0
  35. package/dist/platform/telegram/wrappers.js +329 -0
  36. package/dist/platform/types.js +28 -0
  37. package/dist/services/approvalDetector.js +15 -2
  38. package/dist/services/cdpBridgeManager.js +91 -146
  39. package/dist/services/defaultModelApplicator.js +54 -0
  40. package/dist/services/modeService.js +16 -1
  41. package/dist/services/modelService.js +57 -16
  42. package/dist/services/notificationSender.js +149 -0
  43. package/dist/services/responseMonitor.js +1 -2
  44. package/dist/ui/autoAcceptUi.js +37 -0
  45. package/dist/ui/modeUi.js +38 -1
  46. package/dist/ui/modelsUi.js +96 -0
  47. package/dist/ui/outputUi.js +32 -0
  48. package/dist/ui/projectListUi.js +55 -0
  49. package/dist/ui/screenshotUi.js +26 -0
  50. package/dist/ui/sessionPickerUi.js +35 -1
  51. package/dist/ui/templateUi.js +41 -0
  52. package/dist/utils/configLoader.js +63 -12
  53. package/dist/utils/lockfile.js +5 -5
  54. package/dist/utils/logger.js +7 -0
  55. package/dist/utils/telegramImageHandler.js +127 -0
  56. package/package.json +4 -2
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ /**
3
+ * Platform-agnostic SelectAction for mode_select interactions.
4
+ *
5
+ * When a user selects a mode from the inline dropdown, this action:
6
+ * 1. Updates the ModeService
7
+ * 2. Syncs the mode change to Antigravity via CDP
8
+ * 3. Refreshes the mode selection UI
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.createModeSelectAction = createModeSelectAction;
12
+ const cdpBridgeManager_1 = require("../services/cdpBridgeManager");
13
+ const modeService_1 = require("../services/modeService");
14
+ const modeUi_1 = require("../ui/modeUi");
15
+ const logger_1 = require("../utils/logger");
16
+ function createModeSelectAction(deps) {
17
+ return {
18
+ match(customId) {
19
+ return customId === 'mode_select';
20
+ },
21
+ async execute(interaction, values) {
22
+ const selectedMode = values[0];
23
+ if (!selectedMode)
24
+ return;
25
+ // Validate mode name before any side effects
26
+ const normalized = selectedMode.trim().toLowerCase();
27
+ if (!['fast', 'plan'].includes(normalized)) {
28
+ await interaction.followUp({ text: `Invalid mode: ${selectedMode}` }).catch(() => { });
29
+ return;
30
+ }
31
+ await interaction.deferUpdate();
32
+ // CDP-first: try to sync to Antigravity immediately
33
+ const cdp = (0, cdpBridgeManager_1.getCurrentCdp)(deps.bridge);
34
+ const displayName = modeService_1.MODE_DISPLAY_NAMES[selectedMode] || selectedMode;
35
+ if (cdp) {
36
+ const res = await cdp.setUiMode(selectedMode);
37
+ if (!res.ok) {
38
+ logger_1.logger.warn(`[ModeSelect] UI mode switch failed: ${res.error}`);
39
+ await interaction.followUp({
40
+ text: `Failed to switch mode in Antigravity: ${res.error}`,
41
+ }).catch(() => { });
42
+ return;
43
+ }
44
+ // CDP sync succeeded — update local cache as synced
45
+ deps.modeService.setMode(selectedMode, true);
46
+ const payload = (0, modeUi_1.buildModePayload)(deps.modeService.getCurrentMode());
47
+ await interaction.update(payload);
48
+ await interaction.followUp({
49
+ text: `Mode changed to ${displayName}.`,
50
+ }).catch(() => { });
51
+ }
52
+ else {
53
+ // No CDP — set locally as pending
54
+ deps.modeService.setMode(selectedMode, false);
55
+ const payload = (0, modeUi_1.buildModePayload)(deps.modeService.getCurrentMode(), true);
56
+ await interaction.update(payload);
57
+ await interaction.followUp({
58
+ text: `Mode set to ${displayName}. Will sync when connected to Antigravity.`,
59
+ }).catch(() => { });
60
+ }
61
+ },
62
+ };
63
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * Platform-agnostic ButtonAction for model selection interactions.
4
+ *
5
+ * Handles:
6
+ * model_btn_<name> — Switch to the specified model
7
+ * model_refresh_btn — Refresh the model list UI
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.createModelButtonAction = createModelButtonAction;
11
+ const cdpBridgeManager_1 = require("../services/cdpBridgeManager");
12
+ const modelsUi_1 = require("../ui/modelsUi");
13
+ const logger_1 = require("../utils/logger");
14
+ function createModelButtonAction(deps) {
15
+ return {
16
+ match(customId) {
17
+ if (customId === 'model_refresh_btn') {
18
+ return { action: 'refresh' };
19
+ }
20
+ if (customId === 'model_set_default_btn') {
21
+ return { action: 'set_default' };
22
+ }
23
+ if (customId === 'model_clear_default_btn') {
24
+ return { action: 'clear_default' };
25
+ }
26
+ if (customId.startsWith('model_btn_')) {
27
+ return { action: 'select', modelName: customId.slice('model_btn_'.length) };
28
+ }
29
+ return null;
30
+ },
31
+ async execute(interaction, params) {
32
+ await interaction.deferUpdate();
33
+ const cdp = (0, cdpBridgeManager_1.getCurrentCdp)(deps.bridge);
34
+ if (!cdp) {
35
+ await interaction.followUp({ text: 'Not connected to CDP.' }).catch(() => { });
36
+ return;
37
+ }
38
+ if (params.action === 'set_default') {
39
+ const currentModel = await cdp.getCurrentModel();
40
+ if (!currentModel) {
41
+ await interaction.followUp({ text: 'No current model detected.' }).catch(() => { });
42
+ return;
43
+ }
44
+ if (deps.modelService) {
45
+ deps.modelService.setDefaultModel(currentModel);
46
+ }
47
+ if (deps.userPrefRepo) {
48
+ deps.userPrefRepo.setDefaultModel(interaction.user.id, currentModel);
49
+ }
50
+ await refreshModelsUI(cdp, deps, interaction);
51
+ await interaction.followUp({
52
+ text: `Default model set to ${currentModel}.`,
53
+ }).catch(() => { });
54
+ }
55
+ else if (params.action === 'clear_default') {
56
+ if (deps.modelService) {
57
+ deps.modelService.setDefaultModel(null);
58
+ }
59
+ if (deps.userPrefRepo) {
60
+ deps.userPrefRepo.setDefaultModel(interaction.user.id, null);
61
+ }
62
+ await refreshModelsUI(cdp, deps, interaction);
63
+ await interaction.followUp({
64
+ text: 'Default model cleared.',
65
+ }).catch(() => { });
66
+ }
67
+ else if (params.action === 'select') {
68
+ const res = await cdp.setUiModel(params.modelName);
69
+ if (!res.ok) {
70
+ await interaction.followUp({
71
+ text: res.error || 'Failed to change model.',
72
+ }).catch(() => { });
73
+ return;
74
+ }
75
+ // Refresh UI after model change
76
+ await refreshModelsUI(cdp, deps, interaction);
77
+ await interaction.followUp({
78
+ text: `Model changed to ${res.model}.`,
79
+ }).catch(() => { });
80
+ }
81
+ else {
82
+ // refresh
83
+ await refreshModelsUI(cdp, deps, interaction);
84
+ }
85
+ },
86
+ };
87
+ }
88
+ async function refreshModelsUI(cdp, actionDeps, interaction) {
89
+ try {
90
+ const models = await cdp.getUiModels();
91
+ const currentModel = await cdp.getCurrentModel();
92
+ const quotaData = await actionDeps.fetchQuota();
93
+ const defaultModel = actionDeps.modelService?.getDefaultModel() ?? null;
94
+ const payload = (0, modelsUi_1.buildModelsPayload)(models, currentModel, quotaData, defaultModel);
95
+ if (payload) {
96
+ await interaction.update(payload);
97
+ }
98
+ }
99
+ catch (err) {
100
+ logger_1.logger.warn('[ModelButton] Failed to refresh models UI:', err?.message || err);
101
+ }
102
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ /**
3
+ * Platform-agnostic planning button action.
4
+ *
5
+ * Handles Open / Proceed button presses for the planning mode dialog
6
+ * from both Discord and Telegram using the ButtonAction interface.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createPlanningButtonAction = createPlanningButtonAction;
10
+ const cdpBridgeManager_1 = require("../services/cdpBridgeManager");
11
+ const logger_1 = require("../utils/logger");
12
+ const MAX_PLAN_CONTENT = 4096;
13
+ function createPlanningButtonAction(deps) {
14
+ return {
15
+ match(customId) {
16
+ const parsed = (0, cdpBridgeManager_1.parsePlanningCustomId)(customId);
17
+ if (!parsed)
18
+ return null;
19
+ return {
20
+ action: parsed.action,
21
+ projectName: parsed.projectName ?? '',
22
+ channelId: parsed.channelId ?? '',
23
+ };
24
+ },
25
+ async execute(interaction, params) {
26
+ const { action, channelId } = params;
27
+ // Acknowledge immediately so Telegram doesn't time out
28
+ await interaction.deferUpdate().catch(() => { });
29
+ if (channelId && channelId !== interaction.channel.id) {
30
+ await interaction
31
+ .reply({ text: 'This planning action is linked to a different session channel.' })
32
+ .catch(() => { });
33
+ return;
34
+ }
35
+ const projectName = params.projectName || deps.bridge.lastActiveWorkspace;
36
+ const detector = projectName
37
+ ? deps.bridge.pool.getPlanningDetector(projectName)
38
+ : undefined;
39
+ if (!detector) {
40
+ await interaction
41
+ .reply({ text: 'Planning detector not found.' })
42
+ .catch(() => { });
43
+ return;
44
+ }
45
+ if (action === 'open') {
46
+ const clicked = await detector.clickOpenButton();
47
+ if (!clicked) {
48
+ await interaction
49
+ .reply({ text: 'Open button not found.' })
50
+ .catch(() => { });
51
+ return;
52
+ }
53
+ // Wait for DOM to update after Open click
54
+ await new Promise((resolve) => setTimeout(resolve, 500));
55
+ // Extract plan content with retry
56
+ let planContent = null;
57
+ for (let attempt = 0; attempt < 3; attempt++) {
58
+ planContent = await detector.extractPlanContent();
59
+ if (planContent)
60
+ break;
61
+ await new Promise((resolve) => setTimeout(resolve, 500));
62
+ }
63
+ await interaction
64
+ .update({
65
+ text: '📋 Plan opened',
66
+ components: [],
67
+ })
68
+ .catch((err) => {
69
+ logger_1.logger.warn('[PlanningAction] update failed:', err);
70
+ });
71
+ if (planContent) {
72
+ const truncated = planContent.length > MAX_PLAN_CONTENT
73
+ ? planContent.substring(0, MAX_PLAN_CONTENT - 15) + '\n\n(truncated)'
74
+ : planContent;
75
+ await interaction
76
+ .followUp({ text: truncated })
77
+ .catch((err) => {
78
+ logger_1.logger.warn('[PlanningAction] followUp failed:', err);
79
+ });
80
+ }
81
+ else {
82
+ await interaction
83
+ .followUp({ text: 'Could not extract plan content from the editor.' })
84
+ .catch(() => { });
85
+ }
86
+ }
87
+ else {
88
+ // Proceed action
89
+ await interaction.deferUpdate().catch(() => { });
90
+ let clicked = false;
91
+ try {
92
+ clicked = await detector.clickProceedButton();
93
+ }
94
+ catch (err) {
95
+ const msg = err instanceof Error ? err.message : String(err);
96
+ logger_1.logger.error(`[PlanningAction] CDP click failed: ${msg}`);
97
+ await interaction.reply({ text: `Proceed failed: ${msg}` }).catch(() => { });
98
+ return;
99
+ }
100
+ if (clicked) {
101
+ await interaction
102
+ .update({
103
+ text: '▶️ Proceed started',
104
+ components: [],
105
+ })
106
+ .catch((err) => {
107
+ logger_1.logger.warn('[PlanningAction] update failed:', err);
108
+ });
109
+ }
110
+ else {
111
+ await interaction
112
+ .reply({ text: 'Proceed button not found.' })
113
+ .catch(() => { });
114
+ }
115
+ }
116
+ },
117
+ };
118
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * Platform-agnostic select menu interaction handler.
4
+ *
5
+ * Uses a registry pattern similar to buttonHandler: each select type
6
+ * registers a match+execute pair.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createPlatformSelectHandler = createPlatformSelectHandler;
10
+ const logger_1 = require("../utils/logger");
11
+ // ---------------------------------------------------------------------------
12
+ // Factory
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * Create a platform-agnostic select menu handler.
16
+ * Returns an async function that processes PlatformSelectInteraction events.
17
+ */
18
+ function createPlatformSelectHandler(deps) {
19
+ return async (interaction) => {
20
+ for (const action of deps.actions) {
21
+ try {
22
+ if (!action.match(interaction.customId))
23
+ continue;
24
+ await action.execute(interaction, interaction.values);
25
+ return;
26
+ }
27
+ catch (err) {
28
+ const errorMessage = err instanceof Error ? err.message : String(err);
29
+ logger_1.logger.error('[SelectHandler] Action error:', errorMessage);
30
+ await interaction
31
+ .reply({
32
+ text: 'An error occurred while processing the selection.',
33
+ ephemeral: true,
34
+ })
35
+ .catch(() => { });
36
+ return;
37
+ }
38
+ }
39
+ logger_1.logger.warn(`[SelectHandler] No handler for customId: ${interaction.customId}`);
40
+ };
41
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * Platform-agnostic ButtonAction for template execution interactions.
4
+ *
5
+ * When a template button is clicked, the template prompt is injected into
6
+ * Antigravity via CDP. The user receives a confirmation message.
7
+ *
8
+ * Handles: template_btn_<id>
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.createTemplateButtonAction = createTemplateButtonAction;
12
+ const cdpBridgeManager_1 = require("../services/cdpBridgeManager");
13
+ const templateUi_1 = require("../ui/templateUi");
14
+ const logger_1 = require("../utils/logger");
15
+ function createTemplateButtonAction(deps) {
16
+ return {
17
+ match(customId) {
18
+ if (!customId.startsWith(templateUi_1.TEMPLATE_BTN_PREFIX))
19
+ return null;
20
+ const id = (0, templateUi_1.parseTemplateButtonId)(customId);
21
+ if (isNaN(id))
22
+ return null;
23
+ return { templateId: String(id) };
24
+ },
25
+ async execute(interaction, params) {
26
+ const templateId = parseInt(params.templateId, 10);
27
+ const template = deps.templateRepo.findById(templateId);
28
+ if (!template) {
29
+ await interaction.reply({ text: 'Template not found. It may have been deleted.' }).catch(() => { });
30
+ return;
31
+ }
32
+ await interaction.deferUpdate();
33
+ const cdp = (0, cdpBridgeManager_1.getCurrentCdp)(deps.bridge);
34
+ if (!cdp) {
35
+ await interaction.followUp({
36
+ text: 'Not connected to Antigravity. Send the prompt as a message instead.',
37
+ }).catch(() => { });
38
+ return;
39
+ }
40
+ // Inject the template prompt
41
+ logger_1.logger.info(`[TemplateButton] Executing template "${template.name}" (id=${template.id})`);
42
+ const result = await cdp.injectMessage(template.prompt);
43
+ if (!result.ok) {
44
+ await interaction.followUp({
45
+ text: `Failed to execute template: ${result.error}`,
46
+ }).catch(() => { });
47
+ return;
48
+ }
49
+ await interaction.followUp({
50
+ text: `Executing template: ${template.name}`,
51
+ }).catch(() => { });
52
+ },
53
+ };
54
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Platform adapter interface.
4
+ *
5
+ * Each messaging platform (Discord, Telegram, etc.) implements this interface
6
+ * to provide a unified event-driven API for the bot core.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ /**
3
+ * Discord adapter implementing the PlatformAdapter interface.
4
+ *
5
+ * Bridges discord.js Client events into platform-agnostic callbacks,
6
+ * allowing the bot core to operate independently of Discord specifics.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DiscordAdapter = void 0;
10
+ const discord_js_1 = require("discord.js");
11
+ const wrappers_1 = require("./wrappers");
12
+ class DiscordAdapter {
13
+ platform = 'discord';
14
+ client;
15
+ botUserId = '';
16
+ constructor(client) {
17
+ this.client = client;
18
+ }
19
+ /**
20
+ * Start listening for Discord events and forward them
21
+ * through the platform-agnostic event callbacks.
22
+ */
23
+ async start(events) {
24
+ // Ready event: capture bot user ID and notify
25
+ this.client.once(discord_js_1.Events.ClientReady, (readyClient) => {
26
+ this.botUserId = readyClient.user.id;
27
+ events.onReady?.();
28
+ });
29
+ // Message create
30
+ if (events.onMessage) {
31
+ const onMessage = events.onMessage;
32
+ this.client.on(discord_js_1.Events.MessageCreate, async (message) => {
33
+ try {
34
+ const wrapped = (0, wrappers_1.wrapDiscordMessage)(message);
35
+ await onMessage(wrapped);
36
+ }
37
+ catch (error) {
38
+ events.onError?.(error instanceof Error ? error : new Error(String(error)));
39
+ }
40
+ });
41
+ }
42
+ // Interaction create (buttons, selects, commands)
43
+ if (events.onButtonInteraction || events.onSelectInteraction || events.onCommandInteraction) {
44
+ this.client.on(discord_js_1.Events.InteractionCreate, async (interaction) => {
45
+ try {
46
+ if (interaction.isButton() && events.onButtonInteraction) {
47
+ const wrapped = (0, wrappers_1.wrapDiscordButton)(interaction);
48
+ await events.onButtonInteraction(wrapped);
49
+ }
50
+ else if (interaction.isStringSelectMenu() && events.onSelectInteraction) {
51
+ const wrapped = (0, wrappers_1.wrapDiscordSelect)(interaction);
52
+ await events.onSelectInteraction(wrapped);
53
+ }
54
+ else if (interaction.isChatInputCommand() && events.onCommandInteraction) {
55
+ const wrapped = (0, wrappers_1.wrapDiscordCommand)(interaction);
56
+ await events.onCommandInteraction(wrapped);
57
+ }
58
+ }
59
+ catch (error) {
60
+ events.onError?.(error instanceof Error ? error : new Error(String(error)));
61
+ }
62
+ });
63
+ }
64
+ // Client error forwarding
65
+ this.client.on(discord_js_1.Events.Error, (error) => {
66
+ events.onError?.(error);
67
+ });
68
+ }
69
+ /** Stop the adapter by destroying the discord.js Client. */
70
+ async stop() {
71
+ this.client.destroy();
72
+ }
73
+ /**
74
+ * Retrieve a channel by its Discord snowflake ID.
75
+ * Returns null if the channel is not found, not fetchable, or not text-based.
76
+ */
77
+ async getChannel(channelId) {
78
+ try {
79
+ const channel = await this.client.channels.fetch(channelId);
80
+ if (!channel)
81
+ return null;
82
+ if (!channel.isTextBased())
83
+ return null;
84
+ return (0, wrappers_1.wrapDiscordChannel)(channel);
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ }
90
+ /** Return the bot's own user ID. Empty string before start() completes. */
91
+ getBotUserId() {
92
+ return this.botUserId;
93
+ }
94
+ /** Access the raw discord.js Client for platform-specific features. */
95
+ getRawClient() {
96
+ return this.client;
97
+ }
98
+ }
99
+ exports.DiscordAdapter = DiscordAdapter;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toDiscordButtonStyle = exports.toDiscordPayload = exports.wrapDiscordSentMessage = exports.wrapDiscordCommand = exports.wrapDiscordSelect = exports.wrapDiscordButton = exports.wrapDiscordMessage = exports.wrapDiscordChannel = exports.wrapDiscordUser = exports.DiscordAdapter = void 0;
4
+ var discordAdapter_1 = require("./discordAdapter");
5
+ Object.defineProperty(exports, "DiscordAdapter", { enumerable: true, get: function () { return discordAdapter_1.DiscordAdapter; } });
6
+ var wrappers_1 = require("./wrappers");
7
+ Object.defineProperty(exports, "wrapDiscordUser", { enumerable: true, get: function () { return wrappers_1.wrapDiscordUser; } });
8
+ Object.defineProperty(exports, "wrapDiscordChannel", { enumerable: true, get: function () { return wrappers_1.wrapDiscordChannel; } });
9
+ Object.defineProperty(exports, "wrapDiscordMessage", { enumerable: true, get: function () { return wrappers_1.wrapDiscordMessage; } });
10
+ Object.defineProperty(exports, "wrapDiscordButton", { enumerable: true, get: function () { return wrappers_1.wrapDiscordButton; } });
11
+ Object.defineProperty(exports, "wrapDiscordSelect", { enumerable: true, get: function () { return wrappers_1.wrapDiscordSelect; } });
12
+ Object.defineProperty(exports, "wrapDiscordCommand", { enumerable: true, get: function () { return wrappers_1.wrapDiscordCommand; } });
13
+ Object.defineProperty(exports, "wrapDiscordSentMessage", { enumerable: true, get: function () { return wrappers_1.wrapDiscordSentMessage; } });
14
+ Object.defineProperty(exports, "toDiscordPayload", { enumerable: true, get: function () { return wrappers_1.toDiscordPayload; } });
15
+ Object.defineProperty(exports, "toDiscordButtonStyle", { enumerable: true, get: function () { return wrappers_1.toDiscordButtonStyle; } });