@link-assistant/hive-mind 0.41.3 → 0.41.5

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,22 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 0.41.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 27bbc44: Add backslash detection and validation in GitHub URLs
8
+
9
+ When users provide URLs with backslashes (e.g., `https://github.com/owner/repo/issues/123\`), the system now properly validates them and provides helpful error messages with auto-corrected URL suggestions. According to RFC 3986, backslash is not a valid character in URL paths.
10
+
11
+ **Changes:**
12
+
13
+ - Enhanced `parseGitHubUrl()` function to detect backslashes in URL paths
14
+ - Updated all validation points (Telegram bot `/solve` and `/hive` commands, CLI `hive` and `solve` commands)
15
+ - Provides user-friendly error messages with corrected URL suggestions
16
+ - Comprehensive test suite for backslash validation scenarios
17
+
18
+ Fixes #923
19
+
3
20
  ## 0.41.3
4
21
 
5
22
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "0.41.3",
3
+ "version": "0.41.5",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -1107,6 +1107,22 @@ export function parseGitHubUrl(url) {
1107
1107
  if (normalizedUrl.startsWith('http://')) {
1108
1108
  normalizedUrl = normalizedUrl.replace(/^http:\/\//, 'https://');
1109
1109
  }
1110
+
1111
+ // Check for backslashes in the URL path (excluding query params and hash)
1112
+ // According to RFC 3986, backslash is not a valid character in URL paths
1113
+ const urlBeforeQueryAndHash = normalizedUrl.split('?')[0].split('#')[0];
1114
+ if (urlBeforeQueryAndHash.includes('\\')) {
1115
+ // Generate suggested URL by replacing backslashes with forward slashes
1116
+ const suggestedUrl = urlBeforeQueryAndHash.replace(/\\/g, '/');
1117
+ const urlAfterPath = normalizedUrl.substring(urlBeforeQueryAndHash.length);
1118
+
1119
+ return {
1120
+ valid: false,
1121
+ error: 'Invalid character in URL: backslash (\\) is not allowed in URL paths',
1122
+ suggestion: suggestedUrl + urlAfterPath
1123
+ };
1124
+ }
1125
+
1110
1126
  // Parse the URL
1111
1127
  let urlObj;
1112
1128
  try {
package/src/hive.mjs CHANGED
@@ -337,10 +337,9 @@ if (githubUrl) {
337
337
 
338
338
  if (!parsedUrl.valid) {
339
339
  console.error('Error: Invalid GitHub URL format');
340
- if (parsedUrl.error) {
341
- console.error(` ${parsedUrl.error}`);
342
- }
343
- console.error('Expected: https://github.com/owner or https://github.com/owner/repo');
340
+ if (parsedUrl.error) console.error(` ${parsedUrl.error}`);
341
+ if (parsedUrl.suggestion) console.error(`\nšŸ’” Did you mean: ${parsedUrl.suggestion}`);
342
+ console.error('\nExpected: https://github.com/owner or https://github.com/owner/repo');
344
343
  console.error('You can use any of these formats:');
345
344
  console.error(' - https://github.com/owner');
346
345
  console.error(' - https://github.com/owner/repo');
@@ -66,10 +66,9 @@ export const validateGitHubUrl = (issueUrl) => {
66
66
 
67
67
  if (!parsedUrl.valid) {
68
68
  console.error('Error: Invalid GitHub URL format');
69
- if (parsedUrl.error) {
70
- console.error(` ${parsedUrl.error}`);
71
- }
72
- console.error(' Please provide a valid GitHub issue or pull request URL');
69
+ if (parsedUrl.error) console.error(` ${parsedUrl.error}`);
70
+ if (parsedUrl.suggestion) console.error(`\nšŸ’” Did you mean: ${parsedUrl.suggestion}`);
71
+ console.error('\n Please provide a valid GitHub issue or pull request URL');
73
72
  console.error(' Examples:');
74
73
  console.error(' https://github.com/owner/repo/issues/123 (issue)');
75
74
  console.error(' https://github.com/owner/repo/pull/456 (pull request)');
@@ -638,7 +638,8 @@ function validateGitHubUrl(args, options = {}) {
638
638
  if (!parsed.valid) {
639
639
  return {
640
640
  valid: false,
641
- error: parsed.error || 'Invalid GitHub URL'
641
+ error: parsed.error || 'Invalid GitHub URL',
642
+ suggestion: parsed.suggestion
642
643
  };
643
644
  }
644
645
 
@@ -987,7 +988,12 @@ bot.command(/^solve$/i, async (ctx) => {
987
988
 
988
989
  const validation = validateGitHubUrl(userArgs);
989
990
  if (!validation.valid) {
990
- await ctx.reply(`āŒ ${validation.error}\n\nExample: \`/solve https://github.com/owner/repo/issues/123\`\n\nOr reply to a message containing a GitHub link with \`/solve\``, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id });
991
+ let errorMsg = `āŒ ${validation.error}`;
992
+ if (validation.suggestion) {
993
+ errorMsg += `\n\nšŸ’” Did you mean: \`${validation.suggestion}\``;
994
+ }
995
+ errorMsg += '\n\nExample: `/solve https://github.com/owner/repo/issues/123`\n\nOr reply to a message containing a GitHub link with `/solve`';
996
+ await ctx.reply(errorMsg, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id });
991
997
  return;
992
998
  }
993
999
 
@@ -1136,7 +1142,12 @@ bot.command(/^hive$/i, async (ctx) => {
1136
1142
  exampleUrl: 'https://github.com/owner/repo'
1137
1143
  });
1138
1144
  if (!validation.valid) {
1139
- await ctx.reply(`āŒ ${validation.error}\n\nExample: \`/hive https://github.com/owner/repo\``, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id });
1145
+ let errorMsg = `āŒ ${validation.error}`;
1146
+ if (validation.suggestion) {
1147
+ errorMsg += `\n\nšŸ’” Did you mean: \`${validation.suggestion}\``;
1148
+ }
1149
+ errorMsg += '\n\nExample: `/hive https://github.com/owner/repo`';
1150
+ await ctx.reply(errorMsg, { parse_mode: 'Markdown', reply_to_message_id: ctx.message.message_id });
1140
1151
  return;
1141
1152
  }
1142
1153