lazy-gravity 0.9.2 → 0.11.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 (41) hide show
  1. package/dist/bin/commands/doctor.js +45 -7
  2. package/dist/bot/index.js +401 -41
  3. package/dist/bot/telegramMessageHandler.js +1 -0
  4. package/dist/commands/chatCommandHandler.js +43 -3
  5. package/dist/commands/registerSlashCommands.js +13 -1
  6. package/dist/events/interactionCreateHandler.js +456 -27
  7. package/dist/events/messageCreateHandler.js +66 -7
  8. package/dist/handlers/__tests__/fileChangeButtonAction.test.js +85 -0
  9. package/dist/handlers/approvalButtonAction.js +2 -1
  10. package/dist/handlers/errorPopupButtonAction.js +2 -1
  11. package/dist/handlers/fileChangeButtonAction.js +57 -0
  12. package/dist/handlers/genericActionButtonAction.js +72 -0
  13. package/dist/handlers/planningButtonAction.js +126 -23
  14. package/dist/handlers/planningModalSubmitAction.js +38 -0
  15. package/dist/handlers/questionSelectAction.js +70 -0
  16. package/dist/handlers/questionSkipAction.js +68 -0
  17. package/dist/handlers/runCommandButtonAction.js +2 -1
  18. package/dist/platform/discord/discordResponseRenderer.js +164 -0
  19. package/dist/platform/discord/wrappers.js +76 -0
  20. package/dist/services/approvalDetector.js +110 -35
  21. package/dist/services/artifactService.js +103 -37
  22. package/dist/services/assistantDomExtractor.js +194 -3
  23. package/dist/services/cdpBridgeManager.js +149 -8
  24. package/dist/services/cdpConnectionPool.js +22 -2
  25. package/dist/services/cdpService.js +134 -15
  26. package/dist/services/chatSessionService.js +147 -40
  27. package/dist/services/errorPopupDetector.js +23 -11
  28. package/dist/services/notificationSender.js +80 -3
  29. package/dist/services/planningDetector.js +69 -25
  30. package/dist/services/promptDispatcher.js +27 -1
  31. package/dist/services/questionDetector.js +428 -0
  32. package/dist/services/responseMonitor.js +45 -3
  33. package/dist/services/runCommandDetector.js +14 -7
  34. package/dist/ui/artifactsUi.js +4 -3
  35. package/dist/utils/consecutiveEmptyPollGate.js +21 -0
  36. package/dist/utils/fileOpenCache.js +29 -0
  37. package/dist/utils/htmlToDiscordMarkdown.js +5 -2
  38. package/dist/utils/pathUtils.js +12 -0
  39. package/dist/utils/projectResolver.js +10 -0
  40. package/dist/utils/questionActionUtils.js +47 -0
  41. package/package.json +1 -1
@@ -152,6 +152,7 @@ function createTelegramMessageHandler(deps) {
152
152
  (0, cdpBridgeManager_1.ensureErrorPopupDetector)(deps.bridge, cdp, projectName, selectedAccount);
153
153
  (0, cdpBridgeManager_1.ensurePlanningDetector)(deps.bridge, cdp, projectName, selectedAccount);
154
154
  (0, cdpBridgeManager_1.ensureRunCommandDetector)(deps.bridge, cdp, projectName, selectedAccount);
155
+ (0, cdpBridgeManager_1.ensureQuestionDetector)(deps.bridge, cdp, projectName, selectedAccount);
155
156
  // Acknowledge receipt
156
157
  await message.react('\u{1F440}').catch(() => { });
157
158
  // Download image attachments if present
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ChatCommandHandler = void 0;
4
4
  const i18n_1 = require("../utils/i18n");
5
+ const logger_1 = require("../utils/logger");
5
6
  const discord_js_1 = require("discord.js");
6
7
  /**
7
8
  * Handler for chat session related commands
@@ -73,9 +74,31 @@ class ChatCommandHandler {
73
74
  });
74
75
  return;
75
76
  }
77
+ // Start a new chat in the IDE
78
+ const newChatResult = await this.chatSessionService.startNewChat(workspaceCdp);
79
+ if (!newChatResult.ok) {
80
+ // Log but don't fail the command, as the channel still needs to be created
81
+ // and the user might just have to click it manually if the IDE state is strange.
82
+ logger_1.logger.warn(`[/new] Could not start new chat in IDE automatically: ${newChatResult.error}`);
83
+ }
84
+ const customNameRaw = interaction.options.getString('name');
85
+ let safeCustomName = null;
86
+ if (customNameRaw) {
87
+ // Import TitleGeneratorService to sanitize the channel name if needed,
88
+ // or just do basic sanitization inline.
89
+ safeCustomName = customNameRaw
90
+ .toLowerCase()
91
+ .replace(/\s+/g, '-')
92
+ .replace(/[^a-z0-9\-_\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uff00-\uff9f\u4e00-\u9faf]/g, '-')
93
+ .replace(/-{2,}/g, '-')
94
+ .replace(/^-+|-+$/g, '')
95
+ .substring(0, 80);
96
+ if (!safeCustomName)
97
+ safeCustomName = null;
98
+ }
76
99
  // Create a new session channel
77
100
  const sessionNumber = this.chatSessionRepo.getNextSessionNumber(parentId);
78
- const channelName = `session-${sessionNumber}`;
101
+ const channelName = safeCustomName ? `${sessionNumber}-${safeCustomName}` : `session-${sessionNumber}`;
79
102
  const sessionResult = await this.channelManager.createSessionChannel(guild, parentId, channelName);
80
103
  const newChannelId = sessionResult.channelId;
81
104
  // Register binding and session
@@ -92,6 +115,17 @@ class ChatCommandHandler {
92
115
  activeAccountName: selectedAccount,
93
116
  guildId: guild.id,
94
117
  });
118
+ if (safeCustomName) {
119
+ // Set the display name and mark it as renamed so autoRenameChannel skips it
120
+ this.chatSessionRepo.updateDisplayName(newChannelId, safeCustomName);
121
+ // Try to make the IDE's DOM match the Discord channel
122
+ if (workspaceCdp) {
123
+ const renameResult = await this.chatSessionService.renameCurrentChatInUI(workspaceCdp, safeCustomName);
124
+ if (!renameResult.ok) {
125
+ logger_1.logger.warn(`[/new] Could not rename chat in IDE automatically: ${renameResult.error}`);
126
+ }
127
+ }
128
+ }
95
129
  const embed = new discord_js_1.EmbedBuilder()
96
130
  .setTitle((0, i18n_1.t)('šŸ’¬ Started a new session'))
97
131
  .setDescription((0, i18n_1.t)(`Created a new chat session\n→ <#${newChannelId}>`))
@@ -115,8 +149,14 @@ class ChatCommandHandler {
115
149
  const embed = new discord_js_1.EmbedBuilder()
116
150
  .setTitle((0, i18n_1.t)('šŸ’¬ Chat Session Info'))
117
151
  .setColor(info.hasActiveChat ? 0x00CC88 : 0x888888)
118
- .addFields({ name: (0, i18n_1.t)('Title'), value: info.title, inline: true }, { name: (0, i18n_1.t)('Status'), value: info.hasActiveChat ? (0, i18n_1.t)('🟢 Active') : (0, i18n_1.t)('⚪ Inactive'), inline: true })
119
- .setDescription((0, i18n_1.t)('※ Non-session channel.\nUse `/project` to create a project first.'))
152
+ .addFields({ name: (0, i18n_1.t)('Title'), value: info.title, inline: true }, { name: (0, i18n_1.t)('Status'), value: info.hasActiveChat ? (0, i18n_1.t)('🟢 Active') : (0, i18n_1.t)('⚪ Inactive'), inline: true });
153
+ const channel = await interaction.client.channels.fetch(interaction.channelId).catch(() => null);
154
+ const categoryId = channel?.parentId;
155
+ const isProjectChannel = categoryId ? !!this.bindingRepo.findByChannelId(categoryId) : false;
156
+ const desc = isProjectChannel
157
+ ? (0, i18n_1.t)('※ No active session is bound to this channel.\n\nšŸ’” **Tip**: If you recently deleted a session in the IDE, this channel was automatically unbound. Send a prompt or use `/new` to start a fresh chat.')
158
+ : (0, i18n_1.t)('※ Non-session channel.\nUse `/project` to create a project first.');
159
+ embed.setDescription(desc)
120
160
  .setTimestamp();
121
161
  await interaction.editReply({ embeds: [embed] });
122
162
  return;
@@ -95,7 +95,10 @@ const projectCommand = new discord_js_1.SlashCommandBuilder()
95
95
  /** /new command definition (formerly /chat new, made into a standalone command) */
96
96
  const newCommand = new discord_js_1.SlashCommandBuilder()
97
97
  .setName('new')
98
- .setDescription((0, i18n_1.t)('Start a new chat session in the current project'));
98
+ .setDescription((0, i18n_1.t)('Start a new chat session in the current project'))
99
+ .addStringOption(option => option.setName('name')
100
+ .setDescription((0, i18n_1.t)('Name of the new chat session'))
101
+ .setRequired(false));
99
102
  /** /chat command definition (merged status + list) */
100
103
  const chatCommand = new discord_js_1.SlashCommandBuilder()
101
104
  .setName('chat')
@@ -157,6 +160,14 @@ const pingCommand = new discord_js_1.SlashCommandBuilder()
157
160
  const artifactsCommand = new discord_js_1.SlashCommandBuilder()
158
161
  .setName('artifacts')
159
162
  .setDescription((0, i18n_1.t)('Browse and view generated artifacts from the active session'));
163
+ /** /open command definition */
164
+ const openCommand = new discord_js_1.SlashCommandBuilder()
165
+ .setName('open')
166
+ .setDescription((0, i18n_1.t)('Open and read a file from the workspace'))
167
+ .addStringOption((option) => option
168
+ .setName('filepath')
169
+ .setDescription((0, i18n_1.t)('Absolute or relative path to the file'))
170
+ .setRequired(true));
160
171
  /** Array of commands to register */
161
172
  exports.slashCommands = [
162
173
  helpCommand,
@@ -179,6 +190,7 @@ exports.slashCommands = [
179
190
  pingCommand,
180
191
  logsCommand,
181
192
  artifactsCommand,
193
+ openCommand,
182
194
  ];
183
195
  /**
184
196
  * Register slash commands with Discord