@link-assistant/hive-mind 1.7.0 → 1.7.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - d86ba79: Prevent duplicate URLs from being added to the /solve queue (Issue #1080)
8
+ - Added `findByUrl()` method to SolveQueue to detect existing items by URL
9
+ - Updated /solve command handler to check for duplicates before queueing
10
+ - Uses normalized URLs for consistent comparison
11
+ - Returns informative error message when duplicate is detected
12
+
3
13
  ## 1.7.0
4
14
 
5
15
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -1069,18 +1069,32 @@ bot.command(/^solve$/i, async ctx => {
1069
1069
  return;
1070
1070
  }
1071
1071
 
1072
+ // Use normalized URL from validation to ensure consistent duplicate detection
1073
+ // See: https://github.com/link-assistant/hive-mind/issues/1080
1074
+ const normalizedUrl = validation.parsed.normalized;
1075
+
1072
1076
  const requester = buildUserMention({ user: ctx.from, parseMode: 'Markdown' });
1073
1077
  const optionsText = args.slice(1).join(' ') || 'none';
1074
- let infoBlock = `Requested by: ${requester}\nURL: ${escapeMarkdown(args[0])}\nOptions: ${optionsText}`;
1078
+ let infoBlock = `Requested by: ${requester}\nURL: ${escapeMarkdown(normalizedUrl)}\nOptions: ${optionsText}`;
1075
1079
  if (solveOverrides.length > 0) infoBlock += `\nšŸ”’ Locked options: ${solveOverrides.join(' ')}`;
1076
1080
  const solveQueue = getSolveQueue({ verbose: VERBOSE });
1081
+
1082
+ // Check for duplicate URL in queue
1083
+ // See: https://github.com/link-assistant/hive-mind/issues/1080
1084
+ const existingItem = solveQueue.findByUrl(normalizedUrl);
1085
+ if (existingItem) {
1086
+ const statusText = existingItem.status === 'starting' || existingItem.status === 'started' ? 'being processed' : 'already in the queue';
1087
+ await ctx.reply(`āŒ This URL is ${statusText}.\n\nURL: ${escapeMarkdown(normalizedUrl)}\nStatus: ${existingItem.status}\n\nšŸ’” Use /solve-queue to check the queue status.`, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id });
1088
+ return;
1089
+ }
1090
+
1077
1091
  const check = await solveQueue.canStartCommand();
1078
1092
  const queueStats = solveQueue.getStats();
1079
1093
  if (check.canStart && queueStats.queued === 0) {
1080
1094
  const startingMessage = await ctx.reply(`šŸš€ Starting solve command...\n\n${infoBlock}`, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id });
1081
1095
  await executeAndUpdateMessage(ctx, startingMessage, 'solve', args, infoBlock);
1082
1096
  } else {
1083
- const queueItem = solveQueue.enqueue({ url: args[0], args, ctx, requester, infoBlock, tool: solveTool });
1097
+ const queueItem = solveQueue.enqueue({ url: normalizedUrl, args, ctx, requester, infoBlock, tool: solveTool });
1084
1098
  let queueMessage = `šŸ“‹ Solve command queued (position #${queueStats.queued + 1})\n\n${infoBlock}`;
1085
1099
  if (check.reason) queueMessage += `\n\nā³ Waiting: ${check.reason}`;
1086
1100
  const queuedMessage = await ctx.reply(queueMessage, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id });
@@ -303,6 +303,30 @@ export class SolveQueue {
303
303
  return item;
304
304
  }
305
305
 
306
+ /**
307
+ * Find an item by URL in the queue or processing items
308
+ * Used to prevent duplicate URLs from being added to the queue
309
+ * @param {string} url - The URL to search for
310
+ * @returns {SolveQueueItem|null} The found item or null
311
+ * @see https://github.com/link-assistant/hive-mind/issues/1080
312
+ */
313
+ findByUrl(url) {
314
+ // Check queued items
315
+ const queuedItem = this.queue.find(item => item.url === url);
316
+ if (queuedItem) {
317
+ return queuedItem;
318
+ }
319
+
320
+ // Check processing items
321
+ for (const item of this.processing.values()) {
322
+ if (item.url === url) {
323
+ return item;
324
+ }
325
+ }
326
+
327
+ return null;
328
+ }
329
+
306
330
  /**
307
331
  * Cancel a queued item by ID
308
332
  * @param {string} id - Item ID