@gitsense/gsc-utils 0.2.25 → 0.2.27

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 (35) hide show
  1. package/README.md +380 -62
  2. package/dist/gsc-utils.cjs.js +2203 -331
  3. package/dist/gsc-utils.esm.js +2203 -331
  4. package/package.json +1 -1
  5. package/src/AnalyzerUtils/cloner.js +149 -0
  6. package/src/AnalyzerUtils/constants.js +1 -1
  7. package/src/AnalyzerUtils/defaultPromptLoader.js +10 -10
  8. package/src/AnalyzerUtils/discovery.js +48 -39
  9. package/src/AnalyzerUtils/index.js +13 -7
  10. package/src/AnalyzerUtils/instructionLoader.js +6 -6
  11. package/src/AnalyzerUtils/jsonParser.js +35 -0
  12. package/src/AnalyzerUtils/management.js +6 -6
  13. package/src/AnalyzerUtils/saver.js +5 -5
  14. package/src/AnalyzerUtils/schemaLoader.js +194 -26
  15. package/src/AnalyzerUtils/updater.js +187 -0
  16. package/src/CodeBlockUtils/blockProcessor.js +14 -32
  17. package/src/CodeBlockUtils/index.js +7 -6
  18. package/src/CodeBlockUtils/lineageTracer.js +95 -0
  19. package/src/CompactChatUtils/CompactedMessageUtils.js +224 -0
  20. package/src/CompactChatUtils/README.md +321 -0
  21. package/src/CompactChatUtils/ReferenceMessageUtils.js +143 -0
  22. package/src/CompactChatUtils/index.js +40 -0
  23. package/src/ContextUtils.js +40 -4
  24. package/src/DomUtils.js +86 -12
  25. package/src/GSToolBlockUtils.js +66 -1
  26. package/src/GitSenseChatUtils.js +58 -5
  27. package/src/MarkdownUtils.js +4 -1
  28. package/src/MessageUtils.js +1 -1
  29. package/src/MetaRawResultUtils.js +244 -0
  30. package/src/PatchUtils/constants.js +9 -3
  31. package/src/PatchUtils/patchParser.js +60 -36
  32. package/src/PatchUtils/patchVerifier/detectAndFixOverlappingHunks.js +1 -1
  33. package/src/SVGUtils.js +57 -0
  34. package/src/SharedUtils/stringUtils.js +303 -0
  35. package/src/CodeBlockUtils/blockProcessor.js.rej +0 -8
@@ -363,7 +363,7 @@ function getMessageContentType(messageContent) {
363
363
  return 'regular'; // Handle non-string input gracefully
364
364
  }
365
365
  const trimmedContent = messageContent.trimStart(); // Check from the beginning, ignoring leading whitespace
366
- if (trimmedContent.startsWith('## FILE CONTENT')) {
366
+ if (trimmedContent.startsWith('## FILE CONTENT') || trimmedContent.startsWith('## REFERENCE FILE CONTENT')) {
367
367
  return 'file-content-context';
368
368
  } else if (trimmedContent.startsWith('## OVERVIEW')) {
369
369
  return 'overview-context';
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Component: MetaRawResultUtils
3
+ * Block-UUID: 8a4d235b-a9d3-44b8-9c08-47b3678ba1c0
4
+ * Parent-UUID: N/A
5
+ * Version: 1.0.0
6
+ * Description: Utility for parsing and extracting mappings from meta-raw-result messages
7
+ * Language: JavaScript
8
+ * Created-at: 2025-11-15T19:15:00.000Z
9
+ * Authors: GLM-4.6 (v1.0.0)
10
+ */
11
+
12
+
13
+ const ChatUtils = require('./ChatUtils');
14
+
15
+ /**
16
+ * Extracts and parses all meta-raw-result messages from a chat
17
+ * @param {Object} chat - The chat object containing messages
18
+ * @param {string} model - The model name (optional, for message filtering)
19
+ * @returns {Map<number, Object>} Map of chatId to file metadata
20
+ */
21
+ function extractMetaRawResultMappings(chat, model = null) {
22
+ const mappings = new Map();
23
+
24
+ try {
25
+ // Get all messages from the chat
26
+ const allMessages = ChatUtils.getChatMessages(chat, model);
27
+
28
+ // Filter for meta-raw-result messages
29
+ const metaRawMessages = allMessages.filter(msg => isMetaRawResultMessage(msg));
30
+
31
+ // Parse each meta-raw-result message
32
+ for (const message of metaRawMessages) {
33
+ const messageMappings = parseMetaRawResultContent(message.message);
34
+
35
+ // Merge mappings into the main map
36
+ for (const [chatId, fileInfo] of messageMappings) {
37
+ mappings.set(chatId, fileInfo);
38
+ }
39
+ }
40
+
41
+ return mappings;
42
+ } catch (error) {
43
+ console.error('Error extracting meta-raw-result mappings:', error);
44
+ return mappings;
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Validates if a message is a meta-raw-result message
50
+ * @param {Object} message - The message object to validate
51
+ * @returns {boolean} True if message is meta-raw-result type
52
+ */
53
+ function isMetaRawResultMessage(message) {
54
+ if (!message || !message.message) {
55
+ return false;
56
+ }
57
+
58
+ // Check if message type is meta-raw-result
59
+ if (message.type === 'meta-raw-result') {
60
+ return true;
61
+ }
62
+
63
+ return false;
64
+ }
65
+
66
+ /**
67
+ * Parses a single meta-raw-result message content
68
+ * @param {string} messageContent - The message content to parse
69
+ * @returns {Map<number, Object>} Map of chatId to file metadata
70
+ */
71
+ function parseMetaRawResultContent(messageContent) {
72
+ const mappings = new Map();
73
+
74
+ try {
75
+ // Split content into lines
76
+ const lines = messageContent.split('\n');
77
+
78
+ // Find the data section
79
+ let dataSectionStart = -1;
80
+ for (let i = 0; i < lines.length; i++) {
81
+ if (lines[i].trimStart().startsWith('## Data ')) {
82
+ dataSectionStart = i;
83
+ break;
84
+ }
85
+ }
86
+
87
+ if (dataSectionStart === -1) {
88
+ return mappings; // No data section found
89
+ }
90
+
91
+ // Find the table header (line with |)
92
+ let headerLine = -1;
93
+ for (let i = dataSectionStart; i < lines.length; i++) {
94
+ if (lines[i].includes('|') && lines[i].includes('Chat ID')) {
95
+ headerLine = i;
96
+ break;
97
+ }
98
+ }
99
+
100
+ if (headerLine === -1) {
101
+ return mappings; // No table header found
102
+ }
103
+
104
+ // Find the separator line (|---|---|...)
105
+ let separatorLine = -1;
106
+ for (let i = headerLine + 1; i < lines.length; i++) {
107
+ if (lines[i].match(/^\|[\s\-\|]*\|$/)) {
108
+ separatorLine = i;
109
+ break;
110
+ }
111
+ }
112
+
113
+ if (separatorLine === -1) {
114
+ return mappings; // No separator found
115
+ }
116
+
117
+ // Parse data rows (everything after the separator)
118
+ for (let i = separatorLine + 1; i < lines.length; i++) {
119
+ const line = lines[i].trim();
120
+
121
+ // Skip empty lines or separator lines
122
+ if (!line || line.match(/^\|[\s\-\|]*\|$/) || !line.includes('|')) {
123
+ continue;
124
+ }
125
+
126
+ // Parse the table row
127
+ const fileInfo = parseTableRow(line);
128
+ if (fileInfo && fileInfo.id) {
129
+ mappings.set(fileInfo.id, fileInfo);
130
+ }
131
+ }
132
+
133
+ return mappings;
134
+ } catch (error) {
135
+ console.error('Error parsing meta-raw-result content:', error);
136
+ return mappings;
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Parses a single table row from meta-raw-result content
142
+ * @param {string} rowLine - The table row line to parse
143
+ * @returns {Object|null} Parsed file information object or null if parsing failed
144
+ */
145
+ function parseTableRow(rowLine) {
146
+ try {
147
+ // Split the row by | and clean up
148
+ const cells = rowLine.split('|').map(cell => cell.trim()).filter(cell => cell);
149
+
150
+ if (cells.length < 6) {
151
+ return null; // Not enough columns
152
+ }
153
+
154
+ // Extract basic information from the table cells
155
+ const repo = cells[0];
156
+ const branch = cells[1];
157
+ const filePath = cells[2];
158
+ const language = cells[3];
159
+ const chatId = parseInt(cells[4], 10);
160
+
161
+ // Parse file path to extract name and path
162
+ const pathParts = filePath.split('/');
163
+ const name = pathParts[pathParts.length - 1];
164
+ const path = filePath;
165
+
166
+ // Create full path
167
+ const fullPath = `${repo}/${path}`;
168
+
169
+ return {
170
+ id: chatId,
171
+ name: name,
172
+ path: path,
173
+ repo: repo,
174
+ branch: branch,
175
+ language: language,
176
+ fullPath: fullPath
177
+ };
178
+ } catch (error) {
179
+ console.error('Error parsing table row:', error);
180
+ return null;
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Parses size string to bytes
186
+ * @param {string} sizeStr - Size string (e.g., "1.2 KB", "500 B")
187
+ * @returns {number} Size in bytes
188
+ */
189
+ function parseSize(sizeStr) {
190
+ if (!sizeStr || sizeStr === 'N/A') {
191
+ return 0;
192
+ }
193
+
194
+ const match = sizeStr.match(/^([\d.]+)\s*(B|KB|MB|GB)?$/i);
195
+ if (!match) {
196
+ return 0;
197
+ }
198
+
199
+ const value = parseFloat(match[1]);
200
+ const unit = (match[2] || 'B').toUpperCase();
201
+
202
+ switch (unit) {
203
+ case 'B': return Math.round(value);
204
+ case 'KB': return Math.round(value * 1024);
205
+ case 'MB': return Math.round(value * 1024 * 1024);
206
+ case 'GB': return Math.round(value * 1024 * 1024 * 1024);
207
+ default: return 0;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Parses tokens string to number
213
+ * @param {string} tokensStr - Tokens string (e.g., "1.2k", "500")
214
+ * @returns {number} Token count
215
+ */
216
+ function parseTokens(tokensStr) {
217
+ if (!tokensStr || tokensStr === 'N/A') {
218
+ return 0;
219
+ }
220
+
221
+ const match = tokensStr.match(/^([\d.]+)(k|m|b)?$/i);
222
+ if (!match) {
223
+ return 0;
224
+ }
225
+
226
+ const value = parseFloat(match[1]);
227
+ const suffix = (match[2] || '').toLowerCase();
228
+
229
+ switch (suffix) {
230
+ case 'k': return Math.round(value * 1000);
231
+ case 'm': return Math.round(value * 1000000);
232
+ case 'b': return Math.round(value * 1000000000);
233
+ default: return Math.round(value);
234
+ }
235
+ }
236
+
237
+ module.exports = {
238
+ extractMetaRawResultMappings,
239
+ isMetaRawResultMessage,
240
+ parseMetaRawResultContent,
241
+ parseTableRow,
242
+ parseSize,
243
+ parseTokens
244
+ };
@@ -2,11 +2,11 @@
2
2
  * Component: PatchUtils Constants
3
3
  * Block-UUID: c6747054-2c8b-461f-910d-0fd725d9a350
4
4
  * Parent-UUID: 32adc00e-7509-4219-8e40-6c1319371db9
5
- * Version: 2.0.0
5
+ * Version: 2.1.0
6
6
  * Description: Contains shared constants and regular expressions used by the enhanced patch utilities.
7
7
  * Language: JavaScript
8
8
  * Created-at: 2025-05-14T16:55:00.000Z
9
- * Authors: Gemini 2.5 Flash Thinking (v1.0.0), Claude 3.7 Sonnet (v2.0.0)
9
+ * Authors: Gemini 2.5 Flash Thinking (v1.0.0), Claude 3.7 Sonnet (v2.0.0), Qwen 3 Coder 480B - Cerebras (v2.1.0)
10
10
  */
11
11
 
12
12
 
@@ -34,10 +34,14 @@ const DEFAULT_SLIDING_WINDOW_SIZE = 3;
34
34
  // If context is longer than this, we'll use a sliding window approach
35
35
  const MAX_CONTEXT_LINES_FOR_DIRECT_MATCH = 10;
36
36
 
37
- // Patch markers
37
+ // Traditional patch markers
38
38
  const PATCH_START_MARKER = '# --- PATCH START MARKER ---';
39
39
  const PATCH_END_MARKER = '# --- PATCH END MARKER ---';
40
40
 
41
+ // Abbreviated patch markers
42
+ const ABBREVIATED_PATCH_START_MARKER = '# --- ABBREVIATED PATCH START MARKER ---';
43
+ const ABBREVIATED_PATCH_END_MARKER = '# --- ABBREVIATED PATCH END MARKER ---';
44
+
41
45
  // Patch metadata header
42
46
  const PATCH_METADATA_HEADER = '# Patch Metadata';
43
47
 
@@ -65,6 +69,8 @@ module.exports = {
65
69
  MAX_CONTEXT_LINES_FOR_DIRECT_MATCH,
66
70
  PATCH_START_MARKER,
67
71
  PATCH_END_MARKER,
72
+ ABBREVIATED_PATCH_START_MARKER,
73
+ ABBREVIATED_PATCH_END_MARKER,
68
74
  PATCH_METADATA_HEADER,
69
75
  REQUIRED_METADATA_FIELDS,
70
76
  ORIGINAL_FILE_HEADER,
@@ -2,21 +2,24 @@
2
2
  * Component: PatchUtils Parser
3
3
  * Block-UUID: ce634df9-ff99-482a-a261-56ab34a2546e
4
4
  * Parent-UUID: fcc85ec1-0146-40bf-a937-6f7928258cbf
5
- * Version: 1.1.0
6
- * Description: Handles parsing, validation, extraction, and detection of traditional unified diff patches. Extracts metadata and raw diff content.
5
+ * Version: 1.2.0
6
+ * Description: Handles parsing, validation, extraction, and detection of traditional unified diff patches and abbreviated patches. Extracts metadata and raw diff content.
7
7
  * Language: JavaScript
8
8
  * Created-at: 2025-04-18T02:59:04.322Z
9
- * Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0)
9
+ * Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0), Qwen 3 Coder 480B - Cerebras (v1.2.0)
10
10
  */
11
11
 
12
12
 
13
13
  const { isValidVersion } = require('../SharedUtils/versionUtils'); // Assuming SharedUtils is one level up
14
+ const { PATCH_START_MARKER, PATCH_END_MARKER, PATCH_METADATA_HEADER,
15
+ ORIGINAL_FILE_HEADER, MODIFIED_FILE_HEADER, ABBREVIATED_PATCH_START_MARKER,
16
+ ABBREVIATED_PATCH_END_MARKER } = require('./constants');
14
17
 
15
18
  /**
16
19
  * Determines the type of patch format used based on markers.
17
- * Primarily looks for traditional unified diff markers after metadata.
20
+ * Looks for traditional unified diff markers or abbreviated patch markers.
18
21
  * @param {string} patchText - The patch text
19
- * @returns {string} 'traditional', or 'unknown'
22
+ * @returns {string} 'traditional', 'abbreviated', or 'unknown'
20
23
  */
21
24
  function determinePatchFormat(patchText) {
22
25
  if (!patchText || typeof patchText !== 'string') {
@@ -24,29 +27,33 @@ function determinePatchFormat(patchText) {
24
27
  }
25
28
 
26
29
  // Check for required metadata header first
27
- if (!patchText.includes('# Patch Metadata')) {
30
+ if (!patchText.includes(PATCH_METADATA_HEADER)) {
28
31
  return 'unknown'; // Must have metadata header
29
32
  }
30
33
 
31
34
  // Check for traditional unified diff markers *after* potential metadata and start marker
32
35
  // Look for ---, +++, @@ after the start marker
33
- const startMarkerIndex = patchText.indexOf('# --- PATCH START MARKER ---');
34
- if (startMarkerIndex === -1) {
35
- return 'unknown'; // Must have start marker
36
- }
36
+ const traditionalStartMarkerIndex = patchText.indexOf(PATCH_START_MARKER);
37
+ if (traditionalStartMarkerIndex !== -1) {
38
+ const contentAfterMarker = patchText.substring(traditionalStartMarkerIndex);
37
39
 
38
- const contentAfterMarker = patchText.substring(startMarkerIndex);
40
+ // Use regex for more reliable detection within the content part
41
+ const traditionalMarkers = /^\s*--- Original\s*\n\s*\+\+\+ Modified\s*\n\s*@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@/m;
39
42
 
40
- // Use regex for more reliable detection within the content part
41
- const traditionalMarkers = /^\s*--- Original\s*\n\s*\+\+\+ Modified\s*\n\s*@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@/m;
43
+ if (traditionalMarkers.test(contentAfterMarker)) {
44
+ return 'traditional';
45
+ }
46
+ }
42
47
 
43
- if (traditionalMarkers.test(contentAfterMarker)) {
44
- return 'traditional';
48
+ // Check for abbreviated patch markers
49
+ const abbreviatedStartMarkerIndex = patchText.indexOf(ABBREVIATED_PATCH_START_MARKER);
50
+ if (abbreviatedStartMarkerIndex !== -1) {
51
+ return 'abbreviated';
45
52
  }
46
53
 
47
54
  // Removed check for obsolete '@=' context marker
48
55
 
49
- return 'unknown'; // Format doesn't match expected traditional structure after markers
56
+ return 'unknown'; // Format doesn't match expected structures after markers
50
57
  }
51
58
 
52
59
  /**
@@ -68,7 +75,8 @@ function extractPatchMetadata(patchText) {
68
75
  const trimmedLine = line.trim();
69
76
 
70
77
  // Stop processing metadata if we hit content markers or the start marker
71
- if (trimmedLine === '# --- PATCH START MARKER ---' ||
78
+ if (trimmedLine === PATCH_START_MARKER ||
79
+ trimmedLine === ABBREVIATED_PATCH_START_MARKER ||
72
80
  line.startsWith('--- ') || // Standard diff header start
73
81
  line.startsWith('+++ ') || // Standard diff header start
74
82
  line.startsWith('@@ ')) // Standard diff hunk header start
@@ -91,7 +99,7 @@ function extractPatchMetadata(patchText) {
91
99
  }
92
100
  }
93
101
  // Allow lines that are just comments (e.g., # Description continued)
94
- } else if (trimmedLine !== '' && !trimmedLine.startsWith('# Patch Metadata')) {
102
+ } else if (trimmedLine !== '' && !trimmedLine.startsWith(PATCH_METADATA_HEADER)) {
95
103
  // If we encounter non-empty, non-comment lines before the start marker,
96
104
  // it's likely malformed, stop metadata parsing.
97
105
  inMetadata = false;
@@ -135,11 +143,11 @@ function validatePatchMetadata(metadata) {
135
143
  }
136
144
 
137
145
  // Validate UUIDs are not the template string
138
- if (metadata['Source-Block-UUID'] === '12d8a596-0620-4725-ba49-ae6fccdfa2ad') {
139
- errors.push('Source-Block-UUID contains placeholder value "f016e2e4-f97f-4ffe-9f46-ea48f59a3eea".');
146
+ if (metadata['Source-Block-UUID'] === '{{GS-UUID}}') {
147
+ errors.push('Source-Block-UUID contains placeholder value "{{GS-UUID}}".');
140
148
  }
141
- if (metadata['Target-Block-UUID'] === '5bfb717c-aaec-462e-a50e-d096aba0d63f') {
142
- errors.push('Target-Block-UUID contains placeholder value "12e76392-f0ac-4c9d-a5be-c98401487352".');
149
+ if (metadata['Target-Block-UUID'] === '{{GS-UUID}}') {
150
+ errors.push('Target-Block-UUID contains placeholder value "{{GS-UUID}}".');
143
151
  }
144
152
 
145
153
  return errors;
@@ -152,23 +160,34 @@ function validatePatchMetadata(metadata) {
152
160
  * @param {string} format - Expected format (should be 'traditional').
153
161
  * @returns {string} Raw unified diff content, or empty string if not found/invalid.
154
162
  */
155
- function extractPatchContent(patchText, format) {
156
- if (!patchText || format !== 'traditional') {
163
+ function extractPatchContent(patchText, format = 'traditional') {
164
+ if (!patchText) {
157
165
  return "";
158
166
  }
159
167
 
160
168
  const lines = patchText.split('\n');
161
-
162
169
  let contentLines = [];
163
170
  let inContentBlock = false;
171
+ let startMarker, endMarker;
172
+
173
+ // Determine which markers to look for based on format
174
+ if (format === 'traditional') {
175
+ startMarker = PATCH_START_MARKER;
176
+ endMarker = PATCH_END_MARKER;
177
+ } else if (format === 'abbreviated') {
178
+ startMarker = ABBREVIATED_PATCH_START_MARKER;
179
+ endMarker = ABBREVIATED_PATCH_END_MARKER;
180
+ } else {
181
+ return ""; // Unsupported format
182
+ }
164
183
 
165
184
  for (const line of lines) {
166
- if (line.trim() === '# --- PATCH START MARKER ---') {
185
+ if (line.trim() === startMarker) {
167
186
  inContentBlock = true;
168
187
  continue; // Skip the marker line itself
169
188
  }
170
189
 
171
- if (line.trim() === '# --- PATCH END MARKER ---') {
190
+ if (line.trim() === endMarker) {
172
191
  inContentBlock = false;
173
192
  break; // Stop processing once end marker is found
174
193
  }
@@ -207,23 +226,25 @@ function detectPatch(messageText) {
207
226
  }
208
227
 
209
228
  // Find the first code block that contains patch metadata
210
- // Regex looks for ``` optionally followed by 'diff' language hint
211
- const codeBlockRegex = /```(?:diff)?\s*\n([\s\S]*?)```/g;
229
+ // Regex looks for ``` optionally followed by language hint
230
+ const codeBlockRegex = /```([a-zA-Z0-9#+_-]*)?\s*\n([\s\S]*?)```/g;
212
231
  let match;
213
232
  while ((match = codeBlockRegex.exec(messageText)) !== null) {
214
- const blockContent = match[1];
233
+ const language = match[1] || '';
234
+ const blockContent = match[2];
215
235
  if (isPatchBlock(blockContent)) { // Use isPatchBlock for check
216
236
  const metadata = extractPatchMetadata(blockContent); // Use extractPatchMetadata
217
237
  // Basic validation: Check for essential UUIDs
218
238
  if (metadata['Source-Block-UUID'] && metadata['Target-Block-UUID'] &&
219
- metadata['Source-Block-UUID'] !== '26f930c9-2bc8-4906-bdf5-469700b2f857' && // Check placeholders
220
- metadata['Target-Block-UUID'] !== '48a957eb-dd72-44bb-84a2-0df3c7cb16ed')
239
+ metadata['Source-Block-UUID'] !== '{{GS-UUID}}' && // Check placeholders
240
+ metadata['Target-Block-UUID'] !== '{{GS-UUID}}')
221
241
  {
222
242
  return {
223
243
  patchText: blockContent, // Return the content inside the fence
224
244
  metadata,
225
245
  sourceBlockUUID: metadata['Source-Block-UUID'],
226
246
  targetBlockUUID: metadata['Target-Block-UUID'],
247
+ language: language,
227
248
  startIndex: match.index, // Store block position if needed
228
249
  endIndex: match.index + match[0].length
229
250
  };
@@ -245,25 +266,28 @@ function findAllPatches(messageText) {
245
266
  }
246
267
 
247
268
  const patches = [];
248
- const codeBlockRegex = /```(?:diff)?\s*\n([\s\S]*?)```/g;
269
+ // Find code blocks with any language identifier
270
+ const codeBlockRegex = /```([a-zA-Z0-9#+_-]*)?\s*\n([\s\S]*?)```/g;
249
271
 
250
272
  let match;
251
273
  while ((match = codeBlockRegex.exec(messageText)) !== null) {
252
- const blockContent = match[1];
274
+ const language = match[1] || '';
275
+ const blockContent = match[2];
253
276
 
254
277
  if (isPatchBlock(blockContent)) {
255
278
  const metadata = extractPatchMetadata(blockContent);
256
279
 
257
280
  // Basic validation: Check for essential UUIDs and non-placeholder values
258
281
  if (metadata['Source-Block-UUID'] && metadata['Target-Block-UUID'] &&
259
- metadata['Source-Block-UUID'] !== 'e898f14f-14f6-4710-b35b-1cf3478fb5da' &&
260
- metadata['Target-Block-UUID'] !== '0093be2a-fd84-4925-a0c1-13f8a8260cbf')
282
+ metadata['Source-Block-UUID'] !== '{{GS-UUID}}' &&
283
+ metadata['Target-Block-UUID'] !== '{{GS-UUID}}')
261
284
  {
262
285
  patches.push({
263
286
  patchText: blockContent,
264
287
  metadata,
265
288
  sourceBlockUUID: metadata['Source-Block-UUID'],
266
289
  targetBlockUUID: metadata['Target-Block-UUID'],
290
+ language: language,
267
291
  startIndex: match.index,
268
292
  endIndex: match.index + match[0].length
269
293
  });
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Component: PatchUtils Detect and Fix Overlapping Hunks
3
- * Block-UUID: 0e1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d
3
+ * Block-UUID: 7324dab8-24ae-4a42-9dc3-766e69104ef6
4
4
  * Parent-UUID: 2308ed72-91ff-48ba-bc80-310c23c01ff1
5
5
  * Version: 1.0.0
6
6
  * Description: Detects and optionally fixes overlapping hunks in a patch file by merging them.
package/src/SVGUtils.js CHANGED
@@ -490,6 +490,18 @@ class SVGUtils {
490
490
  return this.create(xml, params);
491
491
  }
492
492
 
493
+ /**
494
+ * Generate dropZone SVG icon
495
+ * @param {Object} params - Configuration parameters
496
+ * @returns {Element} SVG element
497
+ */
498
+ static dropZone(params) {
499
+ const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='64' height='64'><path d="M7 18C4.23858 18 2 15.7614 2 13C2 10.2386 4.23858 8 7 8C7.55228 8 8 8.44772 8 9C8 9.55228 7.55228 10 7 10C5.34315 10 4 11.3431 4 13C4 14.6569 5.34315 16 7 16H17C18.6569 16 20 14.6569 20 13C20 11.3431 18.6569 10 17 10C16.4477 10 16 9.55228 16 9C16 8.44772 16.4477 8 17 8C19.7614 8 22 10.2386 22 13C22 15.7614 19.7614 18 17 18H7Z" fill="currentColor"/><path d="M12 2L12 14M12 14L9 11M12 14L15 11" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
500
+ return this.create(xml, params);
501
+ }
502
+
503
+
504
+
493
505
  /**
494
506
  * Generate dot SVG icon
495
507
  * @param {Object} params - Configuration parameters
@@ -530,6 +542,26 @@ class SVGUtils {
530
542
  return this.create(xml, params);
531
543
  }
532
544
 
545
+ /**
546
+ * Generate eye SVG icon
547
+ * @param {Object} params - Configuration parameters
548
+ * @returns {Element} SVG element
549
+ */
550
+ static eye(params) {
551
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 2c1.981 0 3.671.992 4.933 2.078 1.27 1.091 2.187 2.345 2.637 3.023a1.62 1.62 0 0 1 0 1.798c-.45.678-1.367 1.932-2.637 3.023C11.67 13.008 9.981 14 8 14c-1.981 0-3.671-.992-4.933-2.078C1.797 10.83.88 9.576.43 8.898a1.62 1.62 0 0 1 0-1.798c.45-.677 1.367-1.931 2.637-3.022C4.33 2.992 6.019 2 8 2ZM1.679 7.932a.12.12 0 0 0 0 .136c.411.622 1.241 1.75 2.366 2.717C5.176 11.758 6.527 12.5 8 12.5c1.473 0 2.825-.742 3.955-1.715 1.124-.967 1.954-2.096 2.366-2.717a.12.12 0 0 0 0-.136c-.412-.621-1.242-1.75-2.366-2.717C10.824 4.242 9.473 3.5 8 3.5c-1.473 0-2.825.742-3.955 1.715-1.124.967-1.954 2.096-2.366 2.717ZM8 10a2 2 0 1 1-.001-3.999A2 2 0 0 1 8 10Z"></path></svg>`;
552
+ return this.create(xml, params);
553
+ }
554
+
555
+ /**
556
+ * Generate eye closed SVG icon
557
+ * @param {Object} params - Configuration parameters
558
+ * @returns {Element} SVG element
559
+ */
560
+ static eyeClosed(params) {
561
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M.143 2.31a.75.75 0 0 1 1.047-.167l14.5 10.5a.75.75 0 1 1-.88 1.214l-2.248-1.628C11.346 13.19 9.792 14 8 14c-1.981 0-3.67-.992-4.933-2.078C1.797 10.832.88 9.577.43 8.9a1.619 1.619 0 0 1 0-1.797c.353-.533.995-1.42 1.868-2.305L.31 3.357A.75.75 0 0 1 .143 2.31Zm1.536 5.622A.12.12 0 0 0 1.657 8c0 .021.006.045.022.068.412.621 1.242 1.75 2.366 2.717C5.175 11.758 6.527 12.5 8 12.5c1.195 0 2.31-.488 3.29-1.191L9.063 9.695A2 2 0 0 1 6.058 7.52L3.529 5.688a14.207 14.207 0 0 0-1.85 2.244ZM8 3.5c-.516 0-1.017.09-1.499.251a.75.75 0 1 1-.473-1.423A6.207 6.207 0 0 1 8 2c1.981 0 3.67.992 4.933 2.078 1.27 1.091 2.187 2.345 2.637 3.023a1.62 1.62 0 0 1 0 1.798c-.11.166-.248.365-.41.587a.75.75 0 1 1-1.21-.887c.148-.201.272-.382.371-.53a.119.119 0 0 0 0-.137c-.412-.621-1.242-1.75-2.366-2.717C10.825 4.242 9.473 3.5 8 3.5Z"></path></svg>`;
562
+ return this.create(xml, params);
563
+ }
564
+
533
565
  /**
534
566
  * Generate file SVG icon
535
567
  * @param {Object} params - Configuration parameters
@@ -1086,6 +1118,16 @@ class SVGUtils {
1086
1118
  return this.create(xml, params);
1087
1119
  }
1088
1120
 
1121
+ /**
1122
+ * Generate squarCircle SVG icon
1123
+ * @param {Object} params - Configuration parameters
1124
+ * @returns {Element} SVG element
1125
+ */
1126
+ static squareCircle(params) {
1127
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16Zm0-1.5a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13Z"></path><path d="M5 5.75A.75.75 0 0 1 5.75 5h4.5a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-.75.75h-4.5a.75.75 0 0 1-.75-.75Z"></path></svg>`;
1128
+ return this.create(xml, params);
1129
+ }
1130
+
1089
1131
  /**
1090
1132
  * Generate stack SVG icon
1091
1133
  * @param {Object} params - Configuration parameters
@@ -1376,6 +1418,16 @@ class SVGUtils {
1376
1418
  return this.create(xml, params);
1377
1419
  }
1378
1420
 
1421
+ /**
1422
+ * Generate verticalEllipsis SVG icon
1423
+ * @param {Object} params - Configuration parameters
1424
+ * @returns {Element} SVG element
1425
+ */
1426
+ static verticalEllipsis(params) {
1427
+ const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16' transform='rotate(90)'><path d='M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z'></path></svg>`;
1428
+ return this.create(xml, params);
1429
+ }
1430
+
1379
1431
  /**
1380
1432
  * Generate x SVG icon
1381
1433
  * @param {Object} params - Configuration parameters
@@ -1405,6 +1457,11 @@ class SVGUtils {
1405
1457
  const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M2.343 13.657A8 8 0 1113.657 2.343 8 8 0 012.343 13.657zM6.03 4.97a.75.75 0 00-1.06 1.06L6.94 8 4.97 9.97a.75.75 0 101.06 1.06L8 9.06l1.97 1.97a.75.75 0 101.06-1.06L9.06 8l1.97-1.97a.75.75 0 10-1.06-1.06L8 6.94 6.03 4.97z'></path></svg>`;
1406
1458
  return this.create(xml, params);
1407
1459
  }
1460
+
1461
+ static zai(params) {
1462
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em"><title>Z.ai</title><path d="M12.105 2L9.927 4.953H.653L2.83 2h9.276zM23.254 19.048L21.078 22h-9.242l2.174-2.952h9.244zM24 2L9.264 22H0L14.736 2H24z"/></svg>`;
1463
+ return this.create(xml, params);
1464
+ }
1408
1465
  }
1409
1466
 
1410
1467
  module.exports = SVGUtils;