@gitsense/gsc-utils 0.1.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.
- package/LICENSE +21 -0
- package/dist/gitsense-chat-utils.cjs.js +10977 -0
- package/dist/gitsense-chat-utils.esm.js +10975 -0
- package/dist/gsc-utils.cjs.js +11043 -0
- package/dist/gsc-utils.esm.js +11041 -0
- package/package.json +37 -0
- package/src/AnalysisBlockUtils.js +151 -0
- package/src/ChatUtils.js +126 -0
- package/src/CodeBlockUtils/blockExtractor.js +277 -0
- package/src/CodeBlockUtils/blockProcessor.js +559 -0
- package/src/CodeBlockUtils/blockProcessor.js.rej +8 -0
- package/src/CodeBlockUtils/constants.js +62 -0
- package/src/CodeBlockUtils/continuationUtils.js +191 -0
- package/src/CodeBlockUtils/headerParser.js +175 -0
- package/src/CodeBlockUtils/headerUtils.js +236 -0
- package/src/CodeBlockUtils/index.js +83 -0
- package/src/CodeBlockUtils/lineNumberFormatter.js +117 -0
- package/src/CodeBlockUtils/markerRemover.js +89 -0
- package/src/CodeBlockUtils/patchIntegration.js +38 -0
- package/src/CodeBlockUtils/relationshipUtils.js +159 -0
- package/src/CodeBlockUtils/updateCodeBlock.js +372 -0
- package/src/CodeBlockUtils/uuidUtils.js +48 -0
- package/src/ContextUtils.js +180 -0
- package/src/GSToolBlockUtils.js +108 -0
- package/src/GitSenseChatUtils.js +386 -0
- package/src/JsonUtils.js +101 -0
- package/src/LLMUtils.js +31 -0
- package/src/MessageUtils.js +460 -0
- package/src/PatchUtils/constants.js +72 -0
- package/src/PatchUtils/diagnosticReporter.js +213 -0
- package/src/PatchUtils/enhancedPatchProcessor.js +390 -0
- package/src/PatchUtils/fuzzyMatcher.js +252 -0
- package/src/PatchUtils/hunkCorrector.js +204 -0
- package/src/PatchUtils/hunkValidator.js +305 -0
- package/src/PatchUtils/index.js +135 -0
- package/src/PatchUtils/patchExtractor.js +175 -0
- package/src/PatchUtils/patchHeaderFormatter.js +143 -0
- package/src/PatchUtils/patchParser.js +289 -0
- package/src/PatchUtils/patchProcessor.js +389 -0
- package/src/PatchUtils/patchVerifier/constants.js +23 -0
- package/src/PatchUtils/patchVerifier/detectAndFixOverlappingHunks.js +281 -0
- package/src/PatchUtils/patchVerifier/detectAndFixRedundantChanges.js +404 -0
- package/src/PatchUtils/patchVerifier/formatAndAddLineNumbers.js +165 -0
- package/src/PatchUtils/patchVerifier/index.js +25 -0
- package/src/PatchUtils/patchVerifier/verifyAndCorrectHunkHeaders.js +202 -0
- package/src/PatchUtils/patchVerifier/verifyAndCorrectLineNumbers.js +254 -0
- package/src/SharedUtils/timestampUtils.js +41 -0
- package/src/SharedUtils/versionUtils.js +58 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: PatchUtils Header Formatter
|
|
3
|
+
* Block-UUID: 87821582-84d4-46c1-ba5f-ea2591fba1bb
|
|
4
|
+
* Parent-UUID: 1a8f5d2e-c7b9-4e0a-8d1f-9c3b0a4e2f1a
|
|
5
|
+
* Version: 1.0.0
|
|
6
|
+
* Description: Formats the metadata header for a new code block created after applying a patch.
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-04-18T02:59:04.322Z
|
|
9
|
+
* Authors: Gemini 2.5 Pro (v1.0.0)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Formats the metadata header for a new code block based on source info and patch metadata.
|
|
15
|
+
* Follows the rules specified in the System Prompt for metadata inheritance and updates.
|
|
16
|
+
*
|
|
17
|
+
* @param {object} sourceBlockInfo - The block info object for the source code block (from CodeBlockService).
|
|
18
|
+
* Expected to have a `header` property with source metadata.
|
|
19
|
+
* @param {object} patchBlock - The parsed patch block object (e.g., from patchParser.findAllPatches).
|
|
20
|
+
* Expected to have a `metadata` property with patch metadata.
|
|
21
|
+
* @returns {string} The formatted code block header string with appropriate comment syntax.
|
|
22
|
+
* @throws {Error} If required source or patch metadata is missing.
|
|
23
|
+
*/
|
|
24
|
+
function formatCodeBlockHeader(sourceBlockInfo, patchBlock) {
|
|
25
|
+
// --- Function body from original PatchUtils.formatCodeBlockHeader ---
|
|
26
|
+
// --- (Copied Verbatim) ---
|
|
27
|
+
if (!sourceBlockInfo || !sourceBlockInfo.header) {
|
|
28
|
+
throw new Error("formatCodeBlockHeader: Missing sourceBlockInfo or sourceBlockInfo.header.");
|
|
29
|
+
}
|
|
30
|
+
if (!patchBlock || !patchBlock.metadata) {
|
|
31
|
+
throw new Error("formatCodeBlockHeader: Missing patchBlock or patchBlock.metadata.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const sourceHeader = sourceBlockInfo.header;
|
|
35
|
+
const patchMetadata = patchBlock.metadata;
|
|
36
|
+
|
|
37
|
+
// --- Validate required fields ---
|
|
38
|
+
const requiredSource = ['Component', 'Language', 'Description', 'Block-UUID', 'Version', 'Authors'];
|
|
39
|
+
const requiredPatch = ['Source-Block-UUID', 'Target-Block-UUID', 'Source-Version', 'Target-Version', 'Authors'];
|
|
40
|
+
|
|
41
|
+
requiredSource.forEach(key => {
|
|
42
|
+
if (!sourceHeader[key]) throw new Error(`formatCodeBlockHeader: Missing required source metadata key: ${key}`);
|
|
43
|
+
});
|
|
44
|
+
requiredPatch.forEach(key => {
|
|
45
|
+
if (!patchMetadata[key]) throw new Error(`formatCodeBlockHeader: Missing required patch metadata key: ${key}`);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// --- Construct New Metadata Object ---
|
|
49
|
+
const newMetadata = {
|
|
50
|
+
'Component': sourceHeader['Component'], // Preserve from source
|
|
51
|
+
'Block-UUID': patchMetadata['Target-Block-UUID'], // Use Target UUID from patch
|
|
52
|
+
'Parent-UUID': patchMetadata['Source-Block-UUID'], // Use Source UUID from patch as Parent
|
|
53
|
+
'Version': patchMetadata['Target-Version'], // Use Target Version from patch
|
|
54
|
+
'Description': sourceHeader['Description'], // Preserve Description from source
|
|
55
|
+
'Language': sourceHeader['Language'], // Preserve Language from source
|
|
56
|
+
'Created-at': new Date().toISOString(), // New timestamp
|
|
57
|
+
'Authors': patchMetadata['Authors'] // Use Authors list from patch
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const language = newMetadata['Language'].toLowerCase();
|
|
61
|
+
let headerLines = [];
|
|
62
|
+
let commentStart = '';
|
|
63
|
+
let commentEnd = '';
|
|
64
|
+
let linePrefix = '';
|
|
65
|
+
|
|
66
|
+
// --- Determine Comment Style ---
|
|
67
|
+
// Based on Code Block Header Format Rules in System Prompt
|
|
68
|
+
switch (language) {
|
|
69
|
+
case 'python':
|
|
70
|
+
case 'py':
|
|
71
|
+
commentStart = '"""';
|
|
72
|
+
commentEnd = '"""';
|
|
73
|
+
break;
|
|
74
|
+
case 'javascript':
|
|
75
|
+
case 'js':
|
|
76
|
+
case 'typescript':
|
|
77
|
+
case 'ts':
|
|
78
|
+
case 'java':
|
|
79
|
+
case 'c':
|
|
80
|
+
case 'cpp':
|
|
81
|
+
case 'csharp':
|
|
82
|
+
case 'cs':
|
|
83
|
+
case 'go':
|
|
84
|
+
case 'php':
|
|
85
|
+
case 'swift':
|
|
86
|
+
case 'kotlin':
|
|
87
|
+
case 'rust':
|
|
88
|
+
case 'css':
|
|
89
|
+
case 'scss':
|
|
90
|
+
case 'less':
|
|
91
|
+
commentStart = '/**';
|
|
92
|
+
linePrefix = ' * ';
|
|
93
|
+
commentEnd = ' */';
|
|
94
|
+
break;
|
|
95
|
+
case 'ruby':
|
|
96
|
+
case 'rb':
|
|
97
|
+
commentStart = '=begin';
|
|
98
|
+
commentEnd = '=end';
|
|
99
|
+
break;
|
|
100
|
+
case 'html':
|
|
101
|
+
case 'xml':
|
|
102
|
+
case 'svg':
|
|
103
|
+
commentStart = '<!--';
|
|
104
|
+
linePrefix = ' '; // Optional: Add space for readability inside comment
|
|
105
|
+
commentEnd = '-->';
|
|
106
|
+
break;
|
|
107
|
+
case 'bash':
|
|
108
|
+
case 'sh':
|
|
109
|
+
case 'shell':
|
|
110
|
+
case 'yaml':
|
|
111
|
+
case 'yml':
|
|
112
|
+
case 'perl':
|
|
113
|
+
case 'powershell':
|
|
114
|
+
case 'ps1':
|
|
115
|
+
// Add other languages using # for single-line comments
|
|
116
|
+
default: // Default to # for unknown or simple languages
|
|
117
|
+
linePrefix = '# ';
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// --- Format Metadata Lines ---
|
|
122
|
+
const metadataOrder = [
|
|
123
|
+
'Component', 'Block-UUID', 'Parent-UUID', 'Version',
|
|
124
|
+
'Description', 'Language', 'Created-at', 'Authors'
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
if (commentStart) headerLines.push(commentStart);
|
|
128
|
+
|
|
129
|
+
metadataOrder.forEach(key => {
|
|
130
|
+
if (newMetadata[key]) {
|
|
131
|
+
headerLines.push(`${linePrefix}${key}: ${newMetadata[key]}`);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if (commentEnd) headerLines.push(commentEnd);
|
|
136
|
+
|
|
137
|
+
return headerLines.join('\n');
|
|
138
|
+
// --- End of Function Body ---
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
module.exports = {
|
|
142
|
+
formatCodeBlockHeader
|
|
143
|
+
};
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: PatchUtils Parser
|
|
3
|
+
* Block-UUID: ce634df9-ff99-482a-a261-56ab34a2546e
|
|
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.
|
|
7
|
+
* Language: JavaScript
|
|
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)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const { isValidVersion } = require('../SharedUtils/versionUtils'); // Assuming SharedUtils is one level up
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Determines the type of patch format used based on markers.
|
|
17
|
+
* Primarily looks for traditional unified diff markers after metadata.
|
|
18
|
+
* @param {string} patchText - The patch text
|
|
19
|
+
* @returns {string} 'traditional', or 'unknown'
|
|
20
|
+
*/
|
|
21
|
+
function determinePatchFormat(patchText) {
|
|
22
|
+
if (!patchText || typeof patchText !== 'string') {
|
|
23
|
+
return 'unknown';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check for required metadata header first
|
|
27
|
+
if (!patchText.includes('# Patch Metadata')) {
|
|
28
|
+
return 'unknown'; // Must have metadata header
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Check for traditional unified diff markers *after* potential metadata and start marker
|
|
32
|
+
// 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
|
+
}
|
|
37
|
+
|
|
38
|
+
const contentAfterMarker = patchText.substring(startMarkerIndex);
|
|
39
|
+
|
|
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;
|
|
42
|
+
|
|
43
|
+
if (traditionalMarkers.test(contentAfterMarker)) {
|
|
44
|
+
return 'traditional';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Removed check for obsolete '@=' context marker
|
|
48
|
+
|
|
49
|
+
return 'unknown'; // Format doesn't match expected traditional structure after markers
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Extracts metadata from a patch block.
|
|
54
|
+
* Stops at the first sign of patch content (---, +++, @@, start marker).
|
|
55
|
+
* @param {string} patchText - The patch text including metadata.
|
|
56
|
+
* @returns {Object} Extracted metadata object.
|
|
57
|
+
*/
|
|
58
|
+
function extractPatchMetadata(patchText) {
|
|
59
|
+
if (!patchText) {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const metadata = {};
|
|
64
|
+
const lines = patchText.split('\n');
|
|
65
|
+
let inMetadata = true;
|
|
66
|
+
|
|
67
|
+
for (const line of lines) {
|
|
68
|
+
const trimmedLine = line.trim();
|
|
69
|
+
|
|
70
|
+
// Stop processing metadata if we hit content markers or the start marker
|
|
71
|
+
if (trimmedLine === '# --- PATCH START MARKER ---' ||
|
|
72
|
+
line.startsWith('--- ') || // Standard diff header start
|
|
73
|
+
line.startsWith('+++ ') || // Standard diff header start
|
|
74
|
+
line.startsWith('@@ ')) // Standard diff hunk header start
|
|
75
|
+
{
|
|
76
|
+
inMetadata = false;
|
|
77
|
+
break; // Stop reading metadata
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Parse metadata lines (format: # Key: Value)
|
|
81
|
+
if (trimmedLine.startsWith('# ')) {
|
|
82
|
+
const metaLine = line.substring(line.indexOf('# ') + 2); // Get content after '# '
|
|
83
|
+
const colonIndex = metaLine.indexOf(':');
|
|
84
|
+
|
|
85
|
+
if (colonIndex > 0) {
|
|
86
|
+
const key = metaLine.substring(0, colonIndex).trim();
|
|
87
|
+
const value = metaLine.substring(colonIndex + 1).trim();
|
|
88
|
+
// Only add if key is not empty
|
|
89
|
+
if (key) {
|
|
90
|
+
metadata[key] = value;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Allow lines that are just comments (e.g., # Description continued)
|
|
94
|
+
} else if (trimmedLine !== '' && !trimmedLine.startsWith('# Patch Metadata')) {
|
|
95
|
+
// If we encounter non-empty, non-comment lines before the start marker,
|
|
96
|
+
// it's likely malformed, stop metadata parsing.
|
|
97
|
+
inMetadata = false;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return metadata;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Validates patch metadata for required fields and version format.
|
|
107
|
+
* @param {Object} metadata - Patch metadata object extracted by extractPatchMetadata.
|
|
108
|
+
* @returns {Array<string>} Array of error messages, empty if valid.
|
|
109
|
+
*/
|
|
110
|
+
function validatePatchMetadata(metadata) {
|
|
111
|
+
const errors = [];
|
|
112
|
+
const requiredFields = [
|
|
113
|
+
'Source-Block-UUID',
|
|
114
|
+
'Target-Block-UUID',
|
|
115
|
+
'Source-Version',
|
|
116
|
+
'Target-Version',
|
|
117
|
+
'Description',
|
|
118
|
+
'Authors'
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
for (const field of requiredFields) {
|
|
122
|
+
// Check for presence and non-empty string value
|
|
123
|
+
if (!metadata[field] || typeof metadata[field] !== 'string' || metadata[field].trim() === '') {
|
|
124
|
+
errors.push(`Missing or empty required metadata field: ${field}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Validate version format if present
|
|
129
|
+
if (metadata['Source-Version'] && !isValidVersion(metadata['Source-Version'])) { // Use imported validator
|
|
130
|
+
errors.push(`Invalid Source-Version format: "${metadata['Source-Version']}". Expected X.Y.Z`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (metadata['Target-Version'] && !isValidVersion(metadata['Target-Version'])) { // Use imported validator
|
|
134
|
+
errors.push(`Invalid Target-Version format: "${metadata['Target-Version']}". Expected X.Y.Z`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 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".');
|
|
140
|
+
}
|
|
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".');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return errors;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Extracts the raw unified diff content between the start and end markers.
|
|
150
|
+
* Includes lines with 'NNN: ' prefixes. Excludes the markers themselves.
|
|
151
|
+
* @param {string} patchText - Full patch text with metadata and markers.
|
|
152
|
+
* @param {string} format - Expected format (should be 'traditional').
|
|
153
|
+
* @returns {string} Raw unified diff content, or empty string if not found/invalid.
|
|
154
|
+
*/
|
|
155
|
+
function extractPatchContent(patchText, format) {
|
|
156
|
+
if (!patchText || format !== 'traditional') {
|
|
157
|
+
return "";
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const lines = patchText.split('\n');
|
|
161
|
+
let contentLines = [];
|
|
162
|
+
let inContentBlock = false;
|
|
163
|
+
|
|
164
|
+
for (const line of lines) {
|
|
165
|
+
if (line.trim() === '# --- PATCH START MARKER ---') {
|
|
166
|
+
inContentBlock = true;
|
|
167
|
+
continue; // Skip the marker line itself
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (line.trim() === '# --- PATCH END MARKER ---') {
|
|
171
|
+
inContentBlock = false;
|
|
172
|
+
break; // Stop processing once end marker is found
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (inContentBlock) {
|
|
176
|
+
contentLines.push(line);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return contentLines.join('\n');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Removed extractContextPatches function (obsolete context format)
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Determines if a code block's content represents a patch block
|
|
187
|
+
* by checking for the mandatory metadata header.
|
|
188
|
+
* @param {string} codeBlockContent - The content of the code block (between fences).
|
|
189
|
+
* @returns {boolean} True if the code block is a patch.
|
|
190
|
+
*/
|
|
191
|
+
function isPatchBlock(codeBlockContent) {
|
|
192
|
+
if (!codeBlockContent || typeof codeBlockContent !== 'string') {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
// Check for the mandatory metadata header using a regex for robustness
|
|
196
|
+
// Allows for potential whitespace variations
|
|
197
|
+
return /^\s*#\s*Patch Metadata\s*\n/.test(codeBlockContent);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Detects the first valid patch block within a larger message text.
|
|
202
|
+
* @param {string} messageText - The message text to analyze.
|
|
203
|
+
* @returns {Object|null} Patch information object { patchText, metadata, sourceBlockUUID, targetBlockUUID, startIndex, endIndex } or null if no valid patch found.
|
|
204
|
+
*/
|
|
205
|
+
function detectPatch(messageText) {
|
|
206
|
+
if (!messageText || typeof messageText !== 'string') {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Find the first code block that contains patch metadata
|
|
211
|
+
// Regex looks for ``` optionally followed by 'diff' language hint
|
|
212
|
+
const codeBlockRegex = /```(?:diff)?\s*\n([\s\S]*?)```/g;
|
|
213
|
+
let match;
|
|
214
|
+
while ((match = codeBlockRegex.exec(messageText)) !== null) {
|
|
215
|
+
const blockContent = match[1];
|
|
216
|
+
if (isPatchBlock(blockContent)) { // Use isPatchBlock for check
|
|
217
|
+
const metadata = extractPatchMetadata(blockContent); // Use extractPatchMetadata
|
|
218
|
+
// Basic validation: Check for essential UUIDs
|
|
219
|
+
if (metadata['Source-Block-UUID'] && metadata['Target-Block-UUID'] &&
|
|
220
|
+
metadata['Source-Block-UUID'] !== '26f930c9-2bc8-4906-bdf5-469700b2f857' && // Check placeholders
|
|
221
|
+
metadata['Target-Block-UUID'] !== '48a957eb-dd72-44bb-84a2-0df3c7cb16ed')
|
|
222
|
+
{
|
|
223
|
+
return {
|
|
224
|
+
patchText: blockContent, // Return the content inside the fence
|
|
225
|
+
metadata,
|
|
226
|
+
sourceBlockUUID: metadata['Source-Block-UUID'],
|
|
227
|
+
targetBlockUUID: metadata['Target-Block-UUID'],
|
|
228
|
+
startIndex: match.index, // Store block position if needed
|
|
229
|
+
endIndex: match.index + match[0].length
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return null; // No valid patch block found
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Finds all valid patch blocks within a message text.
|
|
240
|
+
* @param {string} messageText - The message text to analyze.
|
|
241
|
+
* @returns {Array<Object>} Array of patch information objects.
|
|
242
|
+
*/
|
|
243
|
+
function findAllPatches(messageText) {
|
|
244
|
+
if (!messageText || typeof messageText !== 'string') {
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const patches = [];
|
|
249
|
+
const codeBlockRegex = /```(?:diff)?\s*\n([\s\S]*?)```/g;
|
|
250
|
+
|
|
251
|
+
let match;
|
|
252
|
+
while ((match = codeBlockRegex.exec(messageText)) !== null) {
|
|
253
|
+
const blockContent = match[1];
|
|
254
|
+
|
|
255
|
+
if (isPatchBlock(blockContent)) {
|
|
256
|
+
const metadata = extractPatchMetadata(blockContent);
|
|
257
|
+
|
|
258
|
+
// Basic validation: Check for essential UUIDs and non-placeholder values
|
|
259
|
+
if (metadata['Source-Block-UUID'] && metadata['Target-Block-UUID'] &&
|
|
260
|
+
metadata['Source-Block-UUID'] !== 'e898f14f-14f6-4710-b35b-1cf3478fb5da' &&
|
|
261
|
+
metadata['Target-Block-UUID'] !== '0093be2a-fd84-4925-a0c1-13f8a8260cbf')
|
|
262
|
+
{
|
|
263
|
+
patches.push({
|
|
264
|
+
patchText: blockContent,
|
|
265
|
+
metadata,
|
|
266
|
+
sourceBlockUUID: metadata['Source-Block-UUID'],
|
|
267
|
+
targetBlockUUID: metadata['Target-Block-UUID'],
|
|
268
|
+
startIndex: match.index,
|
|
269
|
+
endIndex: match.index + match[0].length
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return patches;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
module.exports = {
|
|
280
|
+
// Removed validateAndParseContextPatch
|
|
281
|
+
determinePatchFormat,
|
|
282
|
+
extractPatchMetadata,
|
|
283
|
+
validatePatchMetadata,
|
|
284
|
+
extractPatchContent,
|
|
285
|
+
// Removed extractContextPatches
|
|
286
|
+
isPatchBlock,
|
|
287
|
+
detectPatch,
|
|
288
|
+
findAllPatches,
|
|
289
|
+
};
|