@gitsense/gsc-utils 0.2.16 → 0.2.18
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/dist/gsc-utils.cjs.js +995 -1097
- package/dist/gsc-utils.esm.js +995 -1097
- package/package.json +1 -1
- package/src/AnalyzerUtils/discovery.js +15 -3
- package/src/GSToolBlockUtils.js +6 -4
package/dist/gsc-utils.esm.js
CHANGED
|
@@ -675,7 +675,7 @@ var constants$2 = {
|
|
|
675
675
|
* Generates a valid RFC 4122 UUID v4
|
|
676
676
|
* @returns {string} A valid UUID v4
|
|
677
677
|
*/
|
|
678
|
-
function generateUUID$
|
|
678
|
+
function generateUUID$3() {
|
|
679
679
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
680
680
|
const r = Math.random() * 16 | 0;
|
|
681
681
|
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
@@ -688,13 +688,13 @@ function generateUUID$2() {
|
|
|
688
688
|
* @param {string} uuid - The UUID string to validate
|
|
689
689
|
* @returns {Object} Object containing validation results and replacement UUID if needed
|
|
690
690
|
*/
|
|
691
|
-
function validateUUID$
|
|
691
|
+
function validateUUID$4(uuid) {
|
|
692
692
|
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
693
693
|
|
|
694
694
|
if (!uuidPattern.test(uuid)) {
|
|
695
695
|
return {
|
|
696
696
|
"Block-UUID": "INVALID UUID",
|
|
697
|
-
"Correct Block-UUID": generateUUID$
|
|
697
|
+
"Correct Block-UUID": generateUUID$3()
|
|
698
698
|
};
|
|
699
699
|
}
|
|
700
700
|
|
|
@@ -704,8 +704,8 @@ function validateUUID$3(uuid) {
|
|
|
704
704
|
}
|
|
705
705
|
|
|
706
706
|
var uuidUtils = {
|
|
707
|
-
generateUUID: generateUUID$
|
|
708
|
-
validateUUID: validateUUID$
|
|
707
|
+
generateUUID: generateUUID$3,
|
|
708
|
+
validateUUID: validateUUID$4
|
|
709
709
|
};
|
|
710
710
|
|
|
711
711
|
/**
|
|
@@ -797,7 +797,7 @@ function formatBlocksWithLineNumbers$2(blocks, startLine = 1, paddingWidth = 0)
|
|
|
797
797
|
* @param {string} formattedContent - The code content with line numbers
|
|
798
798
|
* @returns {string} The original code content without line numbers
|
|
799
799
|
*/
|
|
800
|
-
function removeLineNumbers$
|
|
800
|
+
function removeLineNumbers$a(formattedContent) {
|
|
801
801
|
if (typeof formattedContent !== 'string') {
|
|
802
802
|
throw new Error("formattedContent must be a string");
|
|
803
803
|
}
|
|
@@ -821,7 +821,7 @@ var lineNumberFormatter = {
|
|
|
821
821
|
formatWithLineNumbers: formatWithLineNumbers$2,
|
|
822
822
|
formatBlockWithLineNumbers: formatBlockWithLineNumbers$2,
|
|
823
823
|
formatBlocksWithLineNumbers: formatBlocksWithLineNumbers$2,
|
|
824
|
-
removeLineNumbers: removeLineNumbers$
|
|
824
|
+
removeLineNumbers: removeLineNumbers$a
|
|
825
825
|
};
|
|
826
826
|
|
|
827
827
|
/**
|
|
@@ -837,8 +837,8 @@ var lineNumberFormatter = {
|
|
|
837
837
|
|
|
838
838
|
// Dependencies from other modules within CodeBlockUtils
|
|
839
839
|
const { COMMENT_STYLES: COMMENT_STYLES$2 } = constants$2;
|
|
840
|
-
const { removeLineNumbers: removeLineNumbers$
|
|
841
|
-
const { validateUUID: validateUUID$
|
|
840
|
+
const { removeLineNumbers: removeLineNumbers$9 } = lineNumberFormatter; // Assuming this utility exists
|
|
841
|
+
const { validateUUID: validateUUID$3 } = uuidUtils; // Assuming uuidUtils.js is in the same directory
|
|
842
842
|
|
|
843
843
|
const MAX_HEADER_LINES = 12; // Maximum allowed non-empty lines for a header
|
|
844
844
|
/**
|
|
@@ -863,7 +863,7 @@ function isValidISOTimestamp$2(timestamp) {
|
|
|
863
863
|
* @returns {Object} - The parsed header object.
|
|
864
864
|
* @throws {Error} If header parsing fails (e.g., missing fields, invalid format).
|
|
865
865
|
*/
|
|
866
|
-
function parseHeader$
|
|
866
|
+
function parseHeader$3(header, language) {
|
|
867
867
|
const headerObject = {};
|
|
868
868
|
|
|
869
869
|
// Get comment style for the language
|
|
@@ -972,7 +972,7 @@ function parseHeader$2(header, language) {
|
|
|
972
972
|
// Special handling for Block-UUID and Parent-UUID
|
|
973
973
|
if (key === "Block-UUID" || key === "Parent-UUID") {
|
|
974
974
|
if (value !== 'N/A') {
|
|
975
|
-
const uuidValidation = validateUUID$
|
|
975
|
+
const uuidValidation = validateUUID$3(value); // Use imported function
|
|
976
976
|
if (uuidValidation["Block-UUID"] === "INVALID UUID") {
|
|
977
977
|
// Store invalid status and the suggested correction
|
|
978
978
|
headerObject[key] = "INVALID UUID";
|
|
@@ -1054,7 +1054,7 @@ function getHeaderLineCount$1(headerText, language) {
|
|
|
1054
1054
|
|
|
1055
1055
|
var headerUtils = {
|
|
1056
1056
|
isValidISOTimestamp: isValidISOTimestamp$2,
|
|
1057
|
-
parseHeader: parseHeader$
|
|
1057
|
+
parseHeader: parseHeader$3,
|
|
1058
1058
|
getHeaderLineCount: getHeaderLineCount$1 // Export the new function
|
|
1059
1059
|
};
|
|
1060
1060
|
|
|
@@ -1074,7 +1074,7 @@ var headerUtils = {
|
|
|
1074
1074
|
* @param {string} text - The input text
|
|
1075
1075
|
* @returns {Object} Object containing arrays of opening and closing fence positions: { openingPositions: Array, closingPositions: Array }
|
|
1076
1076
|
*/
|
|
1077
|
-
function findAllCodeFences$
|
|
1077
|
+
function findAllCodeFences$4(text) {
|
|
1078
1078
|
const openingPositions = [];
|
|
1079
1079
|
const closingPositions = [];
|
|
1080
1080
|
|
|
@@ -1139,7 +1139,7 @@ function findAllCodeFences$2(text) {
|
|
|
1139
1139
|
* @param {Array} closingPositions - Array of closing fence objects { position, length }
|
|
1140
1140
|
* @returns {Object} Object containing: { completeBlocks: Array, incompleteBlocks: Array, warnings: Array }
|
|
1141
1141
|
*/
|
|
1142
|
-
function matchFencesAndExtractBlocks$
|
|
1142
|
+
function matchFencesAndExtractBlocks$4(text, openingPositions, closingPositions) {
|
|
1143
1143
|
const completeBlocks = [];
|
|
1144
1144
|
const incompleteBlocks = [];
|
|
1145
1145
|
const warnings = [];
|
|
@@ -1298,7 +1298,7 @@ function extractCodeBlocksWithUUIDs$1(messageText) {
|
|
|
1298
1298
|
* @param {string} blockUUID - The Block-UUID to find
|
|
1299
1299
|
* @returns {Object|null} Code block object or null if not found
|
|
1300
1300
|
*/
|
|
1301
|
-
function findCodeBlockByUUID$
|
|
1301
|
+
function findCodeBlockByUUID$2(messageText, blockUUID) {
|
|
1302
1302
|
if (!messageText || !blockUUID) {
|
|
1303
1303
|
return null;
|
|
1304
1304
|
}
|
|
@@ -1308,10 +1308,10 @@ function findCodeBlockByUUID$1(messageText, blockUUID) {
|
|
|
1308
1308
|
}
|
|
1309
1309
|
|
|
1310
1310
|
var blockExtractor = {
|
|
1311
|
-
findAllCodeFences: findAllCodeFences$
|
|
1312
|
-
matchFencesAndExtractBlocks: matchFencesAndExtractBlocks$
|
|
1311
|
+
findAllCodeFences: findAllCodeFences$4,
|
|
1312
|
+
matchFencesAndExtractBlocks: matchFencesAndExtractBlocks$4,
|
|
1313
1313
|
extractCodeBlocksWithUUIDs: extractCodeBlocksWithUUIDs$1,
|
|
1314
|
-
findCodeBlockByUUID: findCodeBlockByUUID$
|
|
1314
|
+
findCodeBlockByUUID: findCodeBlockByUUID$2
|
|
1315
1315
|
};
|
|
1316
1316
|
|
|
1317
1317
|
/**
|
|
@@ -1458,7 +1458,7 @@ function validateAnalysisMetadata(metadata) {
|
|
|
1458
1458
|
}
|
|
1459
1459
|
|
|
1460
1460
|
|
|
1461
|
-
var AnalysisBlockUtils$
|
|
1461
|
+
var AnalysisBlockUtils$3 = {
|
|
1462
1462
|
isAnalysisBlock,
|
|
1463
1463
|
getAnalysisBlockType,
|
|
1464
1464
|
parseOverviewMetadata: parseOverviewMetadata$1,
|
|
@@ -1807,7 +1807,7 @@ var constants$1 = {
|
|
|
1807
1807
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0)
|
|
1808
1808
|
*/
|
|
1809
1809
|
|
|
1810
|
-
const { removeLineNumbers: removeLineNumbers$
|
|
1810
|
+
const { removeLineNumbers: removeLineNumbers$8 } = lineNumberFormatter; // Assuming this utility exists
|
|
1811
1811
|
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$4, HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$3 } = constants$1;
|
|
1812
1812
|
|
|
1813
1813
|
|
|
@@ -1972,7 +1972,7 @@ var formatAndAddLineNumbers_1 = {
|
|
|
1972
1972
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0), Claude 3.7 Sonnet (v1.1.0, v1.2.0)
|
|
1973
1973
|
*/
|
|
1974
1974
|
|
|
1975
|
-
const { removeLineNumbers: removeLineNumbers$
|
|
1975
|
+
const { removeLineNumbers: removeLineNumbers$7 } = lineNumberFormatter; // Assuming this utility exists
|
|
1976
1976
|
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$3 } = constants$1;
|
|
1977
1977
|
const { formatAndAddLineNumbers: formatAndAddLineNumbers$1 } = formatAndAddLineNumbers_1; // Import the helper
|
|
1978
1978
|
|
|
@@ -2020,7 +2020,7 @@ function verifyAndCorrectLineNumbers$2(patchText, sourceText, windowSize = 251)
|
|
|
2020
2020
|
const formatResult = formatAndAddLineNumbers$1(patchText, sourceText);
|
|
2021
2021
|
const patchLines = formatResult.formattedPatchText.split('\n');
|
|
2022
2022
|
// Ensure source is clean (defensive check, though caller should provide clean source)
|
|
2023
|
-
const sourceLines = removeLineNumbers$
|
|
2023
|
+
const sourceLines = removeLineNumbers$7(sourceText).split('\n');
|
|
2024
2024
|
const outputLines = [];
|
|
2025
2025
|
const errors = [];
|
|
2026
2026
|
let correctionsMade = formatResult.correctionsMade; // Inherit corrections made by formatter
|
|
@@ -6578,7 +6578,7 @@ function escapeHTML(s) {
|
|
|
6578
6578
|
|
|
6579
6579
|
const parser$1 = patchParser;
|
|
6580
6580
|
const jsdiff$1 = lib;
|
|
6581
|
-
const { removeLineNumbers: removeLineNumbers$
|
|
6581
|
+
const { removeLineNumbers: removeLineNumbers$6 } = lineNumberFormatter;
|
|
6582
6582
|
|
|
6583
6583
|
/**
|
|
6584
6584
|
* Apply patch against source code. Expects traditional unified diff format.
|
|
@@ -6620,7 +6620,7 @@ function applyPatch(sourceText, patchText) {
|
|
|
6620
6620
|
}
|
|
6621
6621
|
|
|
6622
6622
|
// 1.1. Play it safe and clean sourceText by removing potential line numbers
|
|
6623
|
-
sourceText = removeLineNumbers$
|
|
6623
|
+
sourceText = removeLineNumbers$6(sourceText);
|
|
6624
6624
|
|
|
6625
6625
|
// 2. Extract metadata (optional for applying, but good practice)
|
|
6626
6626
|
const metadata = parser$1.extractPatchMetadata(patchText);
|
|
@@ -6685,8 +6685,8 @@ function createPatch(sourceText, targetCode, metadata = {}, filename = 'Original
|
|
|
6685
6685
|
|
|
6686
6686
|
try {
|
|
6687
6687
|
// --- CRITICAL: jsdiff needs CLEAN text ---
|
|
6688
|
-
const cleanSource = removeLineNumbers$
|
|
6689
|
-
const cleanTarget = removeLineNumbers$
|
|
6688
|
+
const cleanSource = removeLineNumbers$6(sourceText);
|
|
6689
|
+
const cleanTarget = removeLineNumbers$6(targetCode);
|
|
6690
6690
|
|
|
6691
6691
|
// --- Generate standard diff ---
|
|
6692
6692
|
// Provide filenames for standard diff headers (--- filename \n +++ filename)
|
|
@@ -7320,7 +7320,7 @@ var fuzzyMatcher$1 = {
|
|
|
7320
7320
|
* Authors: Claude 3.7 Sonnet (v1.0.0), Claude 3.5 Sonnet (v1.1.0, v1.2.0), Claude 3.5 Sonnet (v1.3.0), Gemini 2.5 Flash (v1.3.0)
|
|
7321
7321
|
*/
|
|
7322
7322
|
const { findBestContextMatch: findBestContextMatch$1, findBestMatchWithSlidingWindow: findBestMatchWithSlidingWindow$1 } = fuzzyMatcher$1;
|
|
7323
|
-
const { removeLineNumbers: removeLineNumbers$
|
|
7323
|
+
const { removeLineNumbers: removeLineNumbers$5 } = lineNumberFormatter;
|
|
7324
7324
|
|
|
7325
7325
|
/**
|
|
7326
7326
|
* Parses a hunk into its components
|
|
@@ -7340,7 +7340,7 @@ function parseHunk(hunkText) {
|
|
|
7340
7340
|
|
|
7341
7341
|
for (const line of contentLines) {
|
|
7342
7342
|
// Clean line numbers from the content
|
|
7343
|
-
const cleanLine = removeLineNumbers$
|
|
7343
|
+
const cleanLine = removeLineNumbers$5(line.substring(1));
|
|
7344
7344
|
|
|
7345
7345
|
if (line.startsWith(' ')) {
|
|
7346
7346
|
// Regular context line - add to both context arrays
|
|
@@ -7991,7 +7991,7 @@ var diagnosticReporter$1 = {
|
|
|
7991
7991
|
* Authors: Claude 3.7 Sonnet (v1.0.0)
|
|
7992
7992
|
*/
|
|
7993
7993
|
|
|
7994
|
-
const { removeLineNumbers: removeLineNumbers$
|
|
7994
|
+
const { removeLineNumbers: removeLineNumbers$4 } = lineNumberFormatter;
|
|
7995
7995
|
|
|
7996
7996
|
/**
|
|
7997
7997
|
* Extracts individual hunks from a patch
|
|
@@ -8098,7 +8098,7 @@ function cleanHunkLineNumbers$1(hunkText) {
|
|
|
8098
8098
|
|
|
8099
8099
|
if (line.startsWith(' ') || line.startsWith('+') || line.startsWith('-')) {
|
|
8100
8100
|
const prefix = line[0];
|
|
8101
|
-
const content = removeLineNumbers$
|
|
8101
|
+
const content = removeLineNumbers$4(line.substring(1));
|
|
8102
8102
|
cleanedLines.push(`${prefix}${content}`);
|
|
8103
8103
|
} else {
|
|
8104
8104
|
// Non-content line, keep as is
|
|
@@ -8167,7 +8167,7 @@ var patchExtractor$1 = {
|
|
|
8167
8167
|
*/
|
|
8168
8168
|
|
|
8169
8169
|
const jsdiff = lib;
|
|
8170
|
-
const { removeLineNumbers: removeLineNumbers$
|
|
8170
|
+
const { removeLineNumbers: removeLineNumbers$3 } = lineNumberFormatter;
|
|
8171
8171
|
const { extractAndCleanHunks, reconstructPatch } = patchExtractor$1;
|
|
8172
8172
|
const { validateHunk, validateHunks } = hunkValidator$1;
|
|
8173
8173
|
const { findBestContextMatch, findBestMatchWithSlidingWindow } = fuzzyMatcher$1;
|
|
@@ -8220,7 +8220,7 @@ function applyPatchWithDiagnostics(sourceText, patchText) {
|
|
|
8220
8220
|
}
|
|
8221
8221
|
|
|
8222
8222
|
// Clean source text (remove any line numbers)
|
|
8223
|
-
const cleanSourceText = removeLineNumbers$
|
|
8223
|
+
const cleanSourceText = removeLineNumbers$3(sourceText);
|
|
8224
8224
|
|
|
8225
8225
|
// First, clean up redundant changes
|
|
8226
8226
|
const redundantFixResult = detectAndFixRedundantChanges(patchText, true);
|
|
@@ -8388,7 +8388,7 @@ function validatePatch(sourceText, patchText) {
|
|
|
8388
8388
|
}
|
|
8389
8389
|
|
|
8390
8390
|
// Clean source text
|
|
8391
|
-
const cleanSourceText = removeLineNumbers$
|
|
8391
|
+
const cleanSourceText = removeLineNumbers$3(sourceText);
|
|
8392
8392
|
|
|
8393
8393
|
// Clean up redundant changes
|
|
8394
8394
|
const redundantFixResult = detectAndFixRedundantChanges(patchText, true);
|
|
@@ -8465,7 +8465,7 @@ function applyHunk(sourceText, hunkText) {
|
|
|
8465
8465
|
}
|
|
8466
8466
|
|
|
8467
8467
|
// Clean source text
|
|
8468
|
-
const cleanSourceText = removeLineNumbers$
|
|
8468
|
+
const cleanSourceText = removeLineNumbers$3(sourceText);
|
|
8469
8469
|
|
|
8470
8470
|
// Clean hunk line numbers
|
|
8471
8471
|
const cleanHunk = cleanHunkLineNumbers(hunkText);
|
|
@@ -8599,7 +8599,7 @@ const enhancedProcessor = enhancedPatchProcessor;
|
|
|
8599
8599
|
*/
|
|
8600
8600
|
|
|
8601
8601
|
// Export all modules
|
|
8602
|
-
var PatchUtils$
|
|
8602
|
+
var PatchUtils$2 = {
|
|
8603
8603
|
// Original exports (for backward compatibility)
|
|
8604
8604
|
validateAndParseContextPatch: parser.validateAndParseContextPatch,
|
|
8605
8605
|
determinePatchFormat: parser.determinePatchFormat,
|
|
@@ -8680,381 +8680,6 @@ var PatchUtils$1 = {
|
|
|
8680
8680
|
applyHunk: enhancedProcessor.applyHunk
|
|
8681
8681
|
};
|
|
8682
8682
|
|
|
8683
|
-
/**
|
|
8684
|
-
* Component: CodeBlockUtils Update Code Block
|
|
8685
|
-
* Block-UUID: 6a7b8c9d-0e1f-42a3-b4c5-d6e7f8a9b0c1
|
|
8686
|
-
* Parent-UUID: 5f9c1e3a-7b2d-4e8f-a1d0-9c4b2e1f8a0b
|
|
8687
|
-
* Version: 1.4.0
|
|
8688
|
-
* Description: Provides functions to update the content of a specific code block within a string, identified by index, UUID, or direct reference.
|
|
8689
|
-
* Language: JavaScript
|
|
8690
|
-
* Created-at: 2025-04-16T00:56:57.352Z
|
|
8691
|
-
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0), Gemini 2.5 Pro (v1.2.0), Gemini 2.5 Pro (v1.3.0), Gemini 2.5 Flash Thinking (v1.4.0)
|
|
8692
|
-
*/
|
|
8693
|
-
|
|
8694
|
-
var updateCodeBlock_1;
|
|
8695
|
-
var hasRequiredUpdateCodeBlock;
|
|
8696
|
-
|
|
8697
|
-
function requireUpdateCodeBlock () {
|
|
8698
|
-
if (hasRequiredUpdateCodeBlock) return updateCodeBlock_1;
|
|
8699
|
-
hasRequiredUpdateCodeBlock = 1;
|
|
8700
|
-
// Dependencies from other modules within CodeBlockUtils
|
|
8701
|
-
const { findAllCodeFences, matchFencesAndExtractBlocks, findCodeBlockByUUID } = blockExtractor; // Added findCodeBlockByUUID
|
|
8702
|
-
const { processCodeBlocks } = requireBlockProcessor(); // To get parsed block info
|
|
8703
|
-
|
|
8704
|
-
/**
|
|
8705
|
-
* Replaces the content of a code block specified by its index within a message string.
|
|
8706
|
-
*
|
|
8707
|
-
* @param {string} messageContent - The original message string containing code blocks.
|
|
8708
|
-
* @param {number} blockIndex - The 0-based index of the code block to replace.
|
|
8709
|
-
* @param {string} newCodeContent - The new raw content (code, potentially including header) to insert into the block.
|
|
8710
|
-
* @param {string} [language] - Optional: The language identifier for the updated code block fence. If omitted, the original language is preserved.
|
|
8711
|
-
* @returns {string} The message content with the specified code block updated.
|
|
8712
|
-
* @throws {Error} If the blockIndex is out of bounds or if block boundaries cannot be determined.
|
|
8713
|
-
*/
|
|
8714
|
-
function updateCodeBlockByIndex(messageContent, blockIndex, newCodeContent, language = undefined) {
|
|
8715
|
-
if (typeof messageContent !== 'string') {
|
|
8716
|
-
throw new Error("messageContent must be a string.");
|
|
8717
|
-
}
|
|
8718
|
-
if (typeof blockIndex !== 'number' || blockIndex < 0) {
|
|
8719
|
-
throw new Error("blockIndex must be a non-negative number.");
|
|
8720
|
-
}
|
|
8721
|
-
if (typeof newCodeContent !== 'string') {
|
|
8722
|
-
// Allow empty string replacement, but not other types
|
|
8723
|
-
throw new Error("newCodeContent must be a string.");
|
|
8724
|
-
}
|
|
8725
|
-
|
|
8726
|
-
// Step 1: Find all fence positions to get accurate start/end of the full block
|
|
8727
|
-
const { openingPositions, closingPositions } = findAllCodeFences(messageContent);
|
|
8728
|
-
const { completeBlocks, incompleteBlocks, warnings: extractorWarnings } = matchFencesAndExtractBlocks(
|
|
8729
|
-
messageContent, openingPositions, closingPositions
|
|
8730
|
-
);
|
|
8731
|
-
|
|
8732
|
-
// Combine complete and incomplete for indexing, assuming we might want to update an incomplete one too
|
|
8733
|
-
// Note: Replacing content in an incomplete block might be unusual, but technically possible.
|
|
8734
|
-
const allBlocks = [...completeBlocks, ...incompleteBlocks];
|
|
8735
|
-
|
|
8736
|
-
// Step 2: Validate index
|
|
8737
|
-
if (blockIndex >= allBlocks.length) {
|
|
8738
|
-
throw new Error(`blockIndex ${blockIndex} is out of bounds. Found ${allBlocks.length} blocks.`);
|
|
8739
|
-
}
|
|
8740
|
-
|
|
8741
|
-
// Step 3: Get the target block's boundary information
|
|
8742
|
-
const targetBlockBoundaries = allBlocks[blockIndex];
|
|
8743
|
-
const openingFence = targetBlockBoundaries.opening;
|
|
8744
|
-
const closingFence = targetBlockBoundaries.closing; // Will be undefined for incomplete blocks
|
|
8745
|
-
|
|
8746
|
-
if (!openingFence) {
|
|
8747
|
-
// Should not happen if index is valid, but good practice to check
|
|
8748
|
-
throw new Error(`Could not find opening fence for block at index ${blockIndex}.`);
|
|
8749
|
-
}
|
|
8750
|
-
|
|
8751
|
-
// Determine the exact start and end of the full markdown block
|
|
8752
|
-
const blockStartPos = openingFence.position;
|
|
8753
|
-
// If the block is incomplete, the end is the end of the messageContent
|
|
8754
|
-
const blockEndPos = closingFence
|
|
8755
|
-
? closingFence.position + closingFence.length
|
|
8756
|
-
: messageContent.length;
|
|
8757
|
-
|
|
8758
|
-
// Step 4: Construct the replacement block string
|
|
8759
|
-
const targetLanguage = language !== undefined ? language : (openingFence.language || ''); // Use provided language or original/empty
|
|
8760
|
-
const newBlockString = `\`\`\`${targetLanguage}\n${newCodeContent}\n\`\`\``;
|
|
8761
|
-
|
|
8762
|
-
// Step 5: Perform the replacement
|
|
8763
|
-
const updatedMessageContent =
|
|
8764
|
-
messageContent.substring(0, blockStartPos) +
|
|
8765
|
-
newBlockString +
|
|
8766
|
-
messageContent.substring(blockEndPos);
|
|
8767
|
-
|
|
8768
|
-
return updatedMessageContent;
|
|
8769
|
-
}
|
|
8770
|
-
|
|
8771
|
-
/**
|
|
8772
|
-
* Replaces the content of a code block specified by its Block-UUID within a message string.
|
|
8773
|
-
*
|
|
8774
|
-
* @param {string} messageContent - The original message string containing code blocks.
|
|
8775
|
-
* @param {string} blockUUID - The Block-UUID of the code block to replace.
|
|
8776
|
-
* @param {string} newCodeContent - The new raw content (code, potentially including header) to insert into the block.
|
|
8777
|
-
* @param {string} [language] - Optional: The language identifier for the updated code block fence. If omitted, the original language is preserved.
|
|
8778
|
-
* @returns {string} The message content with the specified code block updated.
|
|
8779
|
-
* @throws {Error} If no block with the specified UUID is found, or if multiple blocks have the same UUID.
|
|
8780
|
-
*/
|
|
8781
|
-
function updateCodeBlockByUUID(messageContent, blockUUID, newCodeContent, language = undefined) {
|
|
8782
|
-
if (typeof messageContent !== 'string') {
|
|
8783
|
-
throw new Error("messageContent must be a string.");
|
|
8784
|
-
}
|
|
8785
|
-
if (typeof blockUUID !== 'string' || !blockUUID) {
|
|
8786
|
-
throw new Error("blockUUID must be a non-empty string.");
|
|
8787
|
-
}
|
|
8788
|
-
if (typeof newCodeContent !== 'string') {
|
|
8789
|
-
throw new Error("newCodeContent must be a string.");
|
|
8790
|
-
}
|
|
8791
|
-
|
|
8792
|
-
// Step 1: Process blocks to get headers and find the target index
|
|
8793
|
-
const { blocks: processedBlocks, warnings } = processCodeBlocks(messageContent, { silent: true });
|
|
8794
|
-
|
|
8795
|
-
let targetIndex = -1;
|
|
8796
|
-
|
|
8797
|
-
for (let i = 0; i < processedBlocks.length; i++) {
|
|
8798
|
-
const block = processedBlocks[i];
|
|
8799
|
-
let match = false;
|
|
8800
|
-
|
|
8801
|
-
// Check standard code blocks by Block-UUID
|
|
8802
|
-
if ((block.type === 'code') && block.header && block.header['Block-UUID'] === blockUUID) {
|
|
8803
|
-
match = true;
|
|
8804
|
-
}
|
|
8805
|
-
// Check patch blocks by Target-Block-UUID
|
|
8806
|
-
else if (block.type === 'patch' && block.metadata && block.metadata['Target-Block-UUID'] === blockUUID) {
|
|
8807
|
-
match = true;
|
|
8808
|
-
}
|
|
8809
|
-
|
|
8810
|
-
if (match) {
|
|
8811
|
-
// If we've already found one, log a warning but still update the first one found.
|
|
8812
|
-
if (targetIndex !== -1) {
|
|
8813
|
-
console.warn(`Multiple blocks found matching UUID: ${blockUUID} (could be Block-UUID or Target-Block-UUID). Updating the first occurrence.`);
|
|
8814
|
-
} else {
|
|
8815
|
-
targetIndex = i;
|
|
8816
|
-
}
|
|
8817
|
-
}
|
|
8818
|
-
}
|
|
8819
|
-
|
|
8820
|
-
// Step 2: Handle findings
|
|
8821
|
-
if (targetIndex === -1) { // Use targetIndex to check if *any* valid match was set
|
|
8822
|
-
throw new Error(`No code or patch block found matching UUID: ${blockUUID} (checked Block-UUID and Target-Block-UUID).`);
|
|
8823
|
-
}
|
|
8824
|
-
// Warning for multiple matches is handled inside the loop now.
|
|
8825
|
-
|
|
8826
|
-
// Step 3: Call the index-based function
|
|
8827
|
-
// We need the index relative to *all* blocks (complete and incomplete), not just processed ones.
|
|
8828
|
-
// Re-extract boundaries to get the correct index mapping.
|
|
8829
|
-
const { openingPositions, closingPositions } = findAllCodeFences(messageContent);
|
|
8830
|
-
const { completeBlocks, incompleteBlocks } = matchFencesAndExtractBlocks(
|
|
8831
|
-
messageContent, openingPositions, closingPositions
|
|
8832
|
-
);
|
|
8833
|
-
const allBlocks = [...completeBlocks, ...incompleteBlocks];
|
|
8834
|
-
|
|
8835
|
-
// Find the index in the combined list that corresponds to the processed block's position
|
|
8836
|
-
const targetProcessedBlock = processedBlocks[targetIndex];
|
|
8837
|
-
const actualIndex = allBlocks.findIndex(b => b.opening.position === targetProcessedBlock.position);
|
|
8838
|
-
|
|
8839
|
-
if (actualIndex === -1) {
|
|
8840
|
-
// This indicates a discrepancy between blockProcessor and blockExtractor results, which shouldn't happen.
|
|
8841
|
-
throw new Error(`Internal error: Could not map processed block at index ${targetIndex} (matching UUID: ${blockUUID}) back to extracted block boundaries.`);
|
|
8842
|
-
}
|
|
8843
|
-
|
|
8844
|
-
// Pass the optional language parameter down
|
|
8845
|
-
return updateCodeBlockByIndex(messageContent, actualIndex, newCodeContent, language);
|
|
8846
|
-
}
|
|
8847
|
-
|
|
8848
|
-
/**
|
|
8849
|
-
* Updates a code block in message text identified by UUID.
|
|
8850
|
-
* (Moved from original PatchUtils)
|
|
8851
|
-
* @param {string} messageText - The original message text
|
|
8852
|
-
* @param {string} blockUUID - The Block-UUID to update
|
|
8853
|
-
* @param {string} newCode - The new code content (raw content, including header if applicable)
|
|
8854
|
-
* @param {string} language - The code language for the fence
|
|
8855
|
-
* @returns {string} Updated message text
|
|
8856
|
-
* @throws {Error} If block not found or parameters missing.
|
|
8857
|
-
*/
|
|
8858
|
-
function updateCodeBlockInMessage(messageText, blockUUID, newCode, language) {
|
|
8859
|
-
if (!messageText || !blockUUID || newCode === null || newCode === undefined) { // Allow empty string for newCode
|
|
8860
|
-
throw new Error("Missing required parameters for updating code block (messageText, blockUUID, newCode)");
|
|
8861
|
-
}
|
|
8862
|
-
|
|
8863
|
-
// Use findCodeBlockByUUID from blockExtractor
|
|
8864
|
-
const block = findCodeBlockByUUID(messageText, blockUUID);
|
|
8865
|
-
|
|
8866
|
-
if (!block) {
|
|
8867
|
-
throw new Error(`Code block with UUID ${blockUUID} not found`);
|
|
8868
|
-
}
|
|
8869
|
-
|
|
8870
|
-
// Construct the new full block string
|
|
8871
|
-
const newBlockString = '```' + (language || block.language) + '\n' + newCode + '\n```';
|
|
8872
|
-
|
|
8873
|
-
// Replace the old block with the new one using precise indices
|
|
8874
|
-
return messageText.substring(0, block.startIndex) +
|
|
8875
|
-
newBlockString +
|
|
8876
|
-
messageText.substring(block.endIndex);
|
|
8877
|
-
}
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
/**
|
|
8881
|
-
* Generic router function to update a code block by index or UUID.
|
|
8882
|
-
*
|
|
8883
|
-
* @param {string} messageContent - The original message string.
|
|
8884
|
-
* @param {number|string} identifier - The block index (number) or Block-UUID (string).
|
|
8885
|
-
* @param {string} newCodeContent - The new raw content for the block.
|
|
8886
|
-
* @param {string} [language] - Optional: The language identifier for the updated code block fence.
|
|
8887
|
-
* @returns {string} The updated message content.
|
|
8888
|
-
* @throws {Error} If the identifier type is invalid or if the underlying update function fails.
|
|
8889
|
-
*/
|
|
8890
|
-
function updateCodeBlock(messageContent, identifier, newCodeContent, language = undefined) {
|
|
8891
|
-
if (typeof identifier === 'number') {
|
|
8892
|
-
// Pass language to index-based function
|
|
8893
|
-
return updateCodeBlockByIndex(messageContent, identifier, newCodeContent, language);
|
|
8894
|
-
} else if (typeof identifier === 'string') {
|
|
8895
|
-
// Pass language to UUID-based function
|
|
8896
|
-
return updateCodeBlockByUUID(messageContent, identifier, newCodeContent, language);
|
|
8897
|
-
} else {
|
|
8898
|
-
throw new Error("Invalid identifier type. Must be a number (index) or a string (UUID).");
|
|
8899
|
-
}
|
|
8900
|
-
}
|
|
8901
|
-
|
|
8902
|
-
/**
|
|
8903
|
-
* Deletes a code block specified by its index within a message string.
|
|
8904
|
-
*
|
|
8905
|
-
* @param {string} messageContent - The original message string containing code blocks.
|
|
8906
|
-
* @param {number} blockIndex - The 0-based index of the code block to delete.
|
|
8907
|
-
* @returns {string} The message content with the specified code block deleted.
|
|
8908
|
-
* @throws {Error} If the blockIndex is out of bounds or if block boundaries cannot be determined.
|
|
8909
|
-
*/
|
|
8910
|
-
function deleteCodeBlockByIndex(messageContent, blockIndex) {
|
|
8911
|
-
if (typeof messageContent !== 'string') {
|
|
8912
|
-
throw new Error("messageContent must be a string.");
|
|
8913
|
-
}
|
|
8914
|
-
if (typeof blockIndex !== 'number' || blockIndex < 0) {
|
|
8915
|
-
throw new Error("blockIndex must be a non-negative number.");
|
|
8916
|
-
}
|
|
8917
|
-
|
|
8918
|
-
// Step 1: Find all fence positions to get accurate start/end of the full block
|
|
8919
|
-
const { openingPositions, closingPositions } = findAllCodeFences(messageContent);
|
|
8920
|
-
const { completeBlocks, incompleteBlocks } = matchFencesAndExtractBlocks(
|
|
8921
|
-
messageContent, openingPositions, closingPositions
|
|
8922
|
-
);
|
|
8923
|
-
|
|
8924
|
-
// Combine complete and incomplete for indexing
|
|
8925
|
-
const allBlocks = [...completeBlocks, ...incompleteBlocks];
|
|
8926
|
-
|
|
8927
|
-
// Step 2: Validate index
|
|
8928
|
-
if (blockIndex >= allBlocks.length) {
|
|
8929
|
-
throw new Error(`blockIndex ${blockIndex} is out of bounds. Found ${allBlocks.length} blocks.`);
|
|
8930
|
-
}
|
|
8931
|
-
|
|
8932
|
-
// Step 3: Get the target block's boundary information
|
|
8933
|
-
const targetBlockBoundaries = allBlocks[blockIndex];
|
|
8934
|
-
const openingFence = targetBlockBoundaries.opening;
|
|
8935
|
-
const closingFence = targetBlockBoundaries.closing; // Will be undefined for incomplete blocks
|
|
8936
|
-
|
|
8937
|
-
if (!openingFence) {
|
|
8938
|
-
// Should not happen if index is valid, but good practice to check
|
|
8939
|
-
throw new Error(`Could not find opening fence for block at index ${blockIndex}.`);
|
|
8940
|
-
}
|
|
8941
|
-
|
|
8942
|
-
// Determine the exact start and end of the full markdown block
|
|
8943
|
-
const blockStartPos = openingFence.position;
|
|
8944
|
-
// If the block is incomplete, the end is the end of the messageContent
|
|
8945
|
-
const blockEndPos = closingFence
|
|
8946
|
-
? closingFence.position + closingFence.length
|
|
8947
|
-
: messageContent.length;
|
|
8948
|
-
|
|
8949
|
-
// Step 4: Perform the deletion
|
|
8950
|
-
const updatedMessageContent =
|
|
8951
|
-
messageContent.substring(0, blockStartPos) +
|
|
8952
|
-
messageContent.substring(blockEndPos);
|
|
8953
|
-
|
|
8954
|
-
return updatedMessageContent;
|
|
8955
|
-
}
|
|
8956
|
-
|
|
8957
|
-
/**
|
|
8958
|
-
* Deletes a code block specified by its Block-UUID within a message string.
|
|
8959
|
-
*
|
|
8960
|
-
* @param {string} messageContent - The original message string containing code blocks.
|
|
8961
|
-
* @param {string} blockUUID - The Block-UUID of the code block to delete.
|
|
8962
|
-
* @returns {string} The message content with the specified code block deleted.
|
|
8963
|
-
* @throws {Error} If no block with the specified UUID is found, or if multiple blocks have the same UUID.
|
|
8964
|
-
*/
|
|
8965
|
-
function deleteCodeBlockByUUID(messageContent, blockUUID) {
|
|
8966
|
-
if (typeof messageContent !== 'string') {
|
|
8967
|
-
throw new Error("messageContent must be a string.");
|
|
8968
|
-
}
|
|
8969
|
-
if (typeof blockUUID !== 'string' || !blockUUID) {
|
|
8970
|
-
throw new Error("blockUUID must be a non-empty string.");
|
|
8971
|
-
}
|
|
8972
|
-
|
|
8973
|
-
// Step 1: Process blocks to get headers and find the target index
|
|
8974
|
-
const { blocks: processedBlocks, warnings } = processCodeBlocks(messageContent, { silent: true });
|
|
8975
|
-
|
|
8976
|
-
let targetIndex = -1;
|
|
8977
|
-
|
|
8978
|
-
for (let i = 0; i < processedBlocks.length; i++) {
|
|
8979
|
-
const block = processedBlocks[i];
|
|
8980
|
-
let match = false;
|
|
8981
|
-
|
|
8982
|
-
// Check standard code blocks by Block-UUID
|
|
8983
|
-
if (block.type === 'code' && block.header && block.header['Block-UUID'] === blockUUID) {
|
|
8984
|
-
match = true;
|
|
8985
|
-
}
|
|
8986
|
-
// Check patch blocks by Target-Block-UUID
|
|
8987
|
-
else if (block.type === 'patch' && block.metadata && block.metadata['Target-Block-UUID'] === blockUUID) {
|
|
8988
|
-
match = true;
|
|
8989
|
-
}
|
|
8990
|
-
|
|
8991
|
-
if (match) {
|
|
8992
|
-
// If we've already found one, log a warning but still target the first one found.
|
|
8993
|
-
if (targetIndex !== -1) {
|
|
8994
|
-
console.warn(`Multiple blocks found matching UUID: ${blockUUID} (could be Block-UUID or Target-Block-UUID). Deleting the first occurrence.`);
|
|
8995
|
-
} else {
|
|
8996
|
-
targetIndex = i;
|
|
8997
|
-
}
|
|
8998
|
-
}
|
|
8999
|
-
}
|
|
9000
|
-
|
|
9001
|
-
// Step 2: Handle findings
|
|
9002
|
-
if (targetIndex === -1) { // Use targetIndex to check if *any* valid match was set
|
|
9003
|
-
throw new Error(`No code or patch block found matching UUID: ${blockUUID} (checked Block-UUID and Target-Block-UUID).`);
|
|
9004
|
-
}
|
|
9005
|
-
// Warning for multiple matches is handled inside the loop now.
|
|
9006
|
-
|
|
9007
|
-
// Step 3: Call the index-based function
|
|
9008
|
-
// We need the index relative to *all* blocks (complete and incomplete), not just processed ones.
|
|
9009
|
-
// Re-extract boundaries to get the correct index mapping.
|
|
9010
|
-
const { openingPositions, closingPositions } = findAllCodeFences(messageContent);
|
|
9011
|
-
const { completeBlocks, incompleteBlocks } = matchFencesAndExtractBlocks(
|
|
9012
|
-
messageContent, openingPositions, closingPositions
|
|
9013
|
-
);
|
|
9014
|
-
const allBlocks = [...completeBlocks, ...incompleteBlocks];
|
|
9015
|
-
|
|
9016
|
-
// Find the index in the combined list that corresponds to the processed block's position
|
|
9017
|
-
const targetProcessedBlock = processedBlocks[targetIndex];
|
|
9018
|
-
const actualIndex = allBlocks.findIndex(b => b.opening.position === targetProcessedBlock.position);
|
|
9019
|
-
|
|
9020
|
-
if (actualIndex === -1) {
|
|
9021
|
-
// This indicates a discrepancy between blockProcessor and blockExtractor results, which shouldn't happen.
|
|
9022
|
-
throw new Error(`Internal error: Could not map processed block at index ${targetIndex} (matching UUID: ${blockUUID}) back to extracted block boundaries.`);
|
|
9023
|
-
}
|
|
9024
|
-
|
|
9025
|
-
return deleteCodeBlockByIndex(messageContent, actualIndex);
|
|
9026
|
-
}
|
|
9027
|
-
|
|
9028
|
-
/**
|
|
9029
|
-
* Generic router function to delete a code block by index or UUID.
|
|
9030
|
-
*
|
|
9031
|
-
* @param {string} messageContent - The original message string.
|
|
9032
|
-
* @param {number|string} identifier - The block index (number) or Block-UUID (string).
|
|
9033
|
-
* @returns {string} The updated message content.
|
|
9034
|
-
* @throws {Error} If the identifier type is invalid or if the underlying delete function fails.
|
|
9035
|
-
*/
|
|
9036
|
-
function deleteCodeBlock(messageContent, identifier) {
|
|
9037
|
-
if (typeof identifier === 'number') {
|
|
9038
|
-
return deleteCodeBlockByIndex(messageContent, identifier);
|
|
9039
|
-
} else if (typeof identifier === 'string') {
|
|
9040
|
-
return deleteCodeBlockByUUID(messageContent, identifier);
|
|
9041
|
-
} else {
|
|
9042
|
-
throw new Error("Invalid identifier type. Must be a number (index) or a string (UUID).");
|
|
9043
|
-
}
|
|
9044
|
-
}
|
|
9045
|
-
|
|
9046
|
-
updateCodeBlock_1 = {
|
|
9047
|
-
updateCodeBlockByIndex,
|
|
9048
|
-
updateCodeBlockByUUID,
|
|
9049
|
-
updateCodeBlock,
|
|
9050
|
-
updateCodeBlockInMessage,
|
|
9051
|
-
deleteCodeBlockByIndex,
|
|
9052
|
-
deleteCodeBlockByUUID,
|
|
9053
|
-
deleteCodeBlock,
|
|
9054
|
-
};
|
|
9055
|
-
return updateCodeBlock_1;
|
|
9056
|
-
}
|
|
9057
|
-
|
|
9058
8683
|
/**
|
|
9059
8684
|
* Component: GitSense Tool Block Utilities
|
|
9060
8685
|
* Block-UUID: 8e1f7b4e-7e30-48b4-a7fc-643bf647661f
|
|
@@ -9066,170 +8691,164 @@ function requireUpdateCodeBlock () {
|
|
|
9066
8691
|
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Flash (v1.1.0)
|
|
9067
8692
|
*/
|
|
9068
8693
|
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
* It verifies if the first non-empty line starts with "# GitSense Chat Tool".
|
|
9081
|
-
*
|
|
9082
|
-
* @param {string} content - The raw content of the code block (within the fences).
|
|
9083
|
-
* @returns {boolean} True if it's a GitSense Chat Tool Block, false otherwise.
|
|
9084
|
-
*/
|
|
9085
|
-
function isToolBlock(content) {
|
|
9086
|
-
if (!content || typeof content !== 'string') {
|
|
9087
|
-
return false;
|
|
9088
|
-
}
|
|
8694
|
+
/**
|
|
8695
|
+
* Checks if a given code block content represents a GitSense Chat Tool Block.
|
|
8696
|
+
* It verifies if the first non-empty line starts with "# GitSense Chat Tool".
|
|
8697
|
+
*
|
|
8698
|
+
* @param {string} content - The raw content of the code block (within the fences).
|
|
8699
|
+
* @returns {boolean} True if it's a GitSense Chat Tool Block, false otherwise.
|
|
8700
|
+
*/
|
|
8701
|
+
function isToolBlock$1(content) {
|
|
8702
|
+
if (!content || typeof content !== 'string') {
|
|
8703
|
+
return false;
|
|
8704
|
+
}
|
|
9089
8705
|
|
|
9090
|
-
|
|
9091
|
-
|
|
8706
|
+
if (content.match(/^\s*# GitSense Chat Tool\n\s*{/))
|
|
8707
|
+
return true;
|
|
9092
8708
|
|
|
9093
|
-
|
|
9094
|
-
|
|
8709
|
+
return false;
|
|
8710
|
+
}
|
|
9095
8711
|
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
8712
|
+
/**
|
|
8713
|
+
* Parses the content of a GitSense Chat Tool Block to extract the JSON payload.
|
|
8714
|
+
* It strips the marker line and any subsequent lines starting with '#' (comments)
|
|
8715
|
+
* or empty lines before attempting to parse the remaining content as JSON.
|
|
8716
|
+
*
|
|
8717
|
+
* @param {string} content - The raw content of the code block, verified by isToolBlock.
|
|
8718
|
+
* @returns {{ tool: string, config: object, data: object } | null} The parsed JSON object { tool, config, data } or null if parsing fails or format is invalid.
|
|
8719
|
+
* @throws {Error} If JSON parsing fails.
|
|
8720
|
+
*/
|
|
8721
|
+
function parseToolBlock$1(content) {
|
|
8722
|
+
if (!isToolBlock$1(content)) {
|
|
8723
|
+
return null; // Should already be verified, but double-check
|
|
8724
|
+
}
|
|
9109
8725
|
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
8726
|
+
const lines = content.split('\n');
|
|
8727
|
+
const jsonLines = [];
|
|
8728
|
+
let markerFound = false;
|
|
9113
8729
|
|
|
9114
|
-
|
|
9115
|
-
|
|
8730
|
+
for (const line of lines) {
|
|
8731
|
+
const trimmedLine = line.trim();
|
|
9116
8732
|
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
8733
|
+
if (!markerFound) {
|
|
8734
|
+
if (trimmedLine.startsWith('# GitSense Chat Tool')) {
|
|
8735
|
+
markerFound = true; // Skip the marker line itself
|
|
8736
|
+
}
|
|
8737
|
+
continue; // Skip lines before the marker (shouldn't be any non-empty ones based on isToolBlock)
|
|
8738
|
+
}
|
|
9123
8739
|
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
8740
|
+
// After the marker, skip empty lines and comment lines
|
|
8741
|
+
if (trimmedLine.length === 0 || /^\s*#/.test(line)) {
|
|
8742
|
+
continue;
|
|
8743
|
+
}
|
|
9128
8744
|
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
8745
|
+
// Keep lines that are part of the JSON
|
|
8746
|
+
jsonLines.push(line);
|
|
8747
|
+
}
|
|
9132
8748
|
|
|
9133
|
-
|
|
8749
|
+
const jsonString = jsonLines.join('\n');
|
|
9134
8750
|
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
|
|
9138
|
-
|
|
8751
|
+
if (!jsonString) {
|
|
8752
|
+
// No JSON content found after stripping comments/marker
|
|
8753
|
+
throw new Error("No JSON content found in the tool block after stripping marker and comments.");
|
|
8754
|
+
}
|
|
9139
8755
|
|
|
9140
|
-
|
|
9141
|
-
|
|
8756
|
+
try {
|
|
8757
|
+
const parsed = JSON.parse(jsonString);
|
|
9142
8758
|
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
8759
|
+
// Basic validation of the parsed structure
|
|
8760
|
+
// The properties tool and config are required. Tool cannot be null or undefined but
|
|
8761
|
+
// config can't. The reason for requiring config to be declared is to reserve the
|
|
8762
|
+
// property name.
|
|
8763
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
8764
|
+
throw new Error("Parsed content is not a valid JSON object.");
|
|
8765
|
+
}
|
|
8766
|
+
if (typeof parsed.tool !== 'string' || !parsed.tool) {
|
|
8767
|
+
throw new Error("Parsed JSON object is missing the required 'tool' string property.");
|
|
8768
|
+
}
|
|
9153
8769
|
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
8770
|
+
if (typeof parsed.config === 'undefined') {
|
|
8771
|
+
throw new Error("Parsed JSON object is missing the required 'config' property.");
|
|
8772
|
+
}
|
|
9157
8773
|
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
8774
|
+
return parsed;
|
|
8775
|
+
} catch (error) {
|
|
8776
|
+
// Re-throw JSON parsing errors with more context
|
|
8777
|
+
throw new Error(`Failed to parse tool block JSON: ${error.message}\nContent after stripping comments:\n${jsonString}`);
|
|
8778
|
+
}
|
|
8779
|
+
}
|
|
9164
8780
|
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
8781
|
+
/**
|
|
8782
|
+
* Formats tool data into a GitSense Chat Tool Block string.
|
|
8783
|
+
*
|
|
8784
|
+
* @param {object} toolData - The tool data object to format.
|
|
8785
|
+
* @returns {string} The formatted GitSense Chat Tool Block string.
|
|
8786
|
+
*/
|
|
8787
|
+
function formatToolBlock(toolData) {
|
|
8788
|
+
return `# GitSense Chat Tool\n\n${JSON.stringify(toolData, null, 2)}`;
|
|
8789
|
+
}
|
|
9174
8790
|
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
8791
|
+
/**
|
|
8792
|
+
* Replaces a specific GitSense Chat Tool Block within a markdown string with updated tool data.
|
|
8793
|
+
* This function leverages CodeBlockUtils for robust parsing and updating.
|
|
8794
|
+
*
|
|
8795
|
+
* @param {string} markdownContent - The original markdown string containing code blocks.
|
|
8796
|
+
* @param {string} toolName - The 'tool' property value of the target GitSense Chat Tool Block to replace.
|
|
8797
|
+
* @param {Object} newToolData - The new tool data object to insert into the block.
|
|
8798
|
+
* @returns {string} The markdown content with the specified tool block updated.
|
|
8799
|
+
* @throws {Error} If the target tool block is not found or if CodeBlockUtils encounters an error.
|
|
8800
|
+
*/
|
|
8801
|
+
function replaceToolBlock(markdownContent, toolName, newToolData, processCodeBlocks, updateCodeBlockByIndex) {
|
|
8802
|
+
if (typeof markdownContent !== 'string' || !toolName || !newToolData) {
|
|
8803
|
+
throw new Error("Missing required parameters for replaceToolBlock.");
|
|
8804
|
+
}
|
|
9189
8805
|
|
|
9190
|
-
|
|
9191
|
-
|
|
8806
|
+
// We can't require them as this will create a circular dependency
|
|
8807
|
+
if (!processCodeBlocks || !updateCodeBlockByIndex) {
|
|
8808
|
+
throw new Error("Missing required dependencies processCodeBlocks and/or updateCodeBlockByIndex.");
|
|
8809
|
+
}
|
|
9192
8810
|
|
|
9193
|
-
|
|
8811
|
+
// 1. Process the markdown content to find all code blocks
|
|
8812
|
+
const { blocks, warnings } = processCodeBlocks(markdownContent, { silent: true });
|
|
9194
8813
|
|
|
9195
|
-
|
|
9196
|
-
for (let i = 0; i < blocks.length; i++) {
|
|
9197
|
-
const block = blocks[i];
|
|
9198
|
-
if (block.type === 'gs-tool' && block.toolData && block.toolData.tool === toolName) {
|
|
9199
|
-
targetBlockIndex = i;
|
|
9200
|
-
break; // Found the first matching tool block
|
|
9201
|
-
}
|
|
9202
|
-
}
|
|
8814
|
+
let targetBlockIndex = -1;
|
|
9203
8815
|
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
8816
|
+
// 2. Iterate through the processed blocks to find the target GitSense Chat Tool Block
|
|
8817
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
8818
|
+
const block = blocks[i];
|
|
8819
|
+
if (block.type === 'gs-tool' && block.toolData && block.toolData.tool === toolName) {
|
|
8820
|
+
targetBlockIndex = i;
|
|
8821
|
+
break; // Found the first matching tool block
|
|
8822
|
+
}
|
|
8823
|
+
}
|
|
9208
8824
|
|
|
9209
|
-
|
|
9210
|
-
|
|
8825
|
+
if (targetBlockIndex === -1) {
|
|
8826
|
+
console.warn(`replaceToolBlock: No GitSense Chat Tool Block with name "${toolName}" found to replace.`);
|
|
8827
|
+
return markdownContent; // Return original content if no replacement occurred
|
|
8828
|
+
}
|
|
9211
8829
|
|
|
9212
|
-
|
|
9213
|
-
|
|
9214
|
-
const updatedMarkdown = updateCodeBlockByIndex(
|
|
9215
|
-
markdownContent,
|
|
9216
|
-
targetBlockIndex,
|
|
9217
|
-
newContentBetweenFences,
|
|
9218
|
-
'txt'
|
|
9219
|
-
);
|
|
8830
|
+
// 3. Format the new tool data into the content that goes *inside* the fences
|
|
8831
|
+
const newContentBetweenFences = formatToolBlock(newToolData);
|
|
9220
8832
|
|
|
9221
|
-
|
|
9222
|
-
|
|
8833
|
+
// 4. Use CodeBlockUtils.updateCodeBlockByIndex to perform the replacement
|
|
8834
|
+
// The language for GitSense Tool Blocks is always 'txt'
|
|
8835
|
+
const updatedMarkdown = updateCodeBlockByIndex(
|
|
8836
|
+
markdownContent,
|
|
8837
|
+
targetBlockIndex,
|
|
8838
|
+
newContentBetweenFences,
|
|
8839
|
+
'txt'
|
|
8840
|
+
);
|
|
9223
8841
|
|
|
9224
|
-
|
|
9225
|
-
isToolBlock,
|
|
9226
|
-
parseToolBlock,
|
|
9227
|
-
formatToolBlock,
|
|
9228
|
-
replaceToolBlock,
|
|
9229
|
-
};
|
|
9230
|
-
return GSToolBlockUtils$2;
|
|
8842
|
+
return updatedMarkdown;
|
|
9231
8843
|
}
|
|
9232
8844
|
|
|
8845
|
+
var GSToolBlockUtils$3 = {
|
|
8846
|
+
isToolBlock: isToolBlock$1,
|
|
8847
|
+
parseToolBlock: parseToolBlock$1,
|
|
8848
|
+
formatToolBlock,
|
|
8849
|
+
replaceToolBlock,
|
|
8850
|
+
};
|
|
8851
|
+
|
|
9233
8852
|
/*
|
|
9234
8853
|
* Component: CodeBlockUtils Continuation Utilities
|
|
9235
8854
|
* Block-UUID: 6fdf5c7d-4def-42a1-bc88-0312f6002cfc
|
|
@@ -9249,7 +8868,7 @@ function requireGSToolBlockUtils () {
|
|
|
9249
8868
|
* @param {Object} header - The parsed header object from the incomplete block (if available).
|
|
9250
8869
|
* @returns {Object} Continuation information { lastLines: Array<string>, blockUUID: string|null, partNumber: number, language: string, metadata: Object }
|
|
9251
8870
|
*/
|
|
9252
|
-
function extractContinuationInfo$
|
|
8871
|
+
function extractContinuationInfo$3(content, partNumber, language, header = {}) {
|
|
9253
8872
|
// Extract Block-UUID directly from the parsed header if available and valid
|
|
9254
8873
|
let blockUUID = (header && header['Block-UUID'] && header['Block-UUID'] !== 'INVALID UUID')
|
|
9255
8874
|
? header['Block-UUID']
|
|
@@ -9417,7 +9036,7 @@ Contribute code starting from the line immediately following the repeated code b
|
|
|
9417
9036
|
|
|
9418
9037
|
|
|
9419
9038
|
var continuationUtils = {
|
|
9420
|
-
extractContinuationInfo: extractContinuationInfo$
|
|
9039
|
+
extractContinuationInfo: extractContinuationInfo$3,
|
|
9421
9040
|
generateContinuationPrompt: generateContinuationPrompt$2
|
|
9422
9041
|
};
|
|
9423
9042
|
|
|
@@ -9440,7 +9059,7 @@ var continuationUtils = {
|
|
|
9440
9059
|
* @param {string} jsonString The string potentially containing JSON and comments.
|
|
9441
9060
|
* @returns {string[]} An array of detected comment strings (including their markers).
|
|
9442
9061
|
*/
|
|
9443
|
-
function detectJsonComments$
|
|
9062
|
+
function detectJsonComments$2(jsonString) {
|
|
9444
9063
|
const comments = [];
|
|
9445
9064
|
let inString = false;
|
|
9446
9065
|
let inBlockComment = false;
|
|
@@ -9519,7 +9138,7 @@ function detectJsonComments$1(jsonString) {
|
|
|
9519
9138
|
}
|
|
9520
9139
|
|
|
9521
9140
|
var JsonUtils$2 = {
|
|
9522
|
-
detectJsonComments: detectJsonComments$
|
|
9141
|
+
detectJsonComments: detectJsonComments$2
|
|
9523
9142
|
};
|
|
9524
9143
|
|
|
9525
9144
|
/**
|
|
@@ -9533,558 +9152,550 @@ var JsonUtils$2 = {
|
|
|
9533
9152
|
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0), Gemini 2.5 Pro (v1.2.0), Gemini 2.5 Flash Thinking (v1.3.0), Gemini 2.5 Flash Thinking (v1.4.0)
|
|
9534
9153
|
*/
|
|
9535
9154
|
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
-
|
|
9563
|
-
|
|
9564
|
-
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
try {
|
|
9576
|
-
toolData = GSToolBlockUtils.parseToolBlock(content);
|
|
9577
|
-
} catch (error) {
|
|
9578
|
-
// When chatting about the tool block, the LLM may add
|
|
9579
|
-
// add comments in it so let's test for this
|
|
9580
|
-
const comments = detectJsonComments(content);
|
|
9581
|
-
|
|
9582
|
-
if (comments.length) {
|
|
9583
|
-
ignoreDueToComments = true;
|
|
9584
|
-
} else {
|
|
9585
|
-
toolParseError = error.message;
|
|
9586
|
-
warnings.push({
|
|
9587
|
-
position: position,
|
|
9588
|
-
type: 'gs_tool_block_parse_error',
|
|
9589
|
-
message: `Invalid GitSense tool block: ${error.message}`,
|
|
9590
|
-
content: content
|
|
9591
|
-
});
|
|
9592
|
-
}
|
|
9593
|
-
}
|
|
9155
|
+
const { findAllCodeFences: findAllCodeFences$3, matchFencesAndExtractBlocks: matchFencesAndExtractBlocks$3 } = blockExtractor;
|
|
9156
|
+
const { parseHeader: parseHeader$2 } = headerUtils;
|
|
9157
|
+
const { validateUUID: validateUUID$2, generateUUID: generateUUID$2 } = uuidUtils;
|
|
9158
|
+
const AnalysisBlockUtils$2 = AnalysisBlockUtils$3;
|
|
9159
|
+
const PatchUtils$1 = PatchUtils$2;
|
|
9160
|
+
const GSToolBlockUtils$2 = GSToolBlockUtils$3;
|
|
9161
|
+
const { extractContinuationInfo: extractContinuationInfo$2 } = continuationUtils;
|
|
9162
|
+
const { removeLineNumbers: removeLineNumbers$2 } = lineNumberFormatter;
|
|
9163
|
+
const { detectJsonComments: detectJsonComments$1 } = JsonUtils$2;
|
|
9164
|
+
|
|
9165
|
+
/**
|
|
9166
|
+
* Processes a single block's content (internal helper)
|
|
9167
|
+
* @param {string} content - The block content
|
|
9168
|
+
* @param {string} language - The language of the block
|
|
9169
|
+
* @param {number} position - The position in the original text
|
|
9170
|
+
* @param {boolean} incomplete - Whether the block is incomplete
|
|
9171
|
+
* @param {Object} options - Processing options (e.g., silent, validatePatches)
|
|
9172
|
+
* @returns {Object} Processed block object
|
|
9173
|
+
*/
|
|
9174
|
+
function processBlockContent(content, language, position, incomplete, options = { silent: true, validatePatches: false }) {
|
|
9175
|
+
const { silent, validatePatches } = options;
|
|
9176
|
+
let warnings = []; // Collect warnings specific to this block
|
|
9177
|
+
let header = {};
|
|
9178
|
+
let headerText = ''; // Raw header text including comments
|
|
9179
|
+
let headerParseError = null;
|
|
9180
|
+
let headerDelimiterType = null; // 'triple' or 'double'
|
|
9181
|
+
let codeText = content; // Default to all content being code
|
|
9182
|
+
|
|
9183
|
+
// Check if this is a GitSense Tool Block *first*
|
|
9184
|
+
if (GSToolBlockUtils$2.isToolBlock(content)) {
|
|
9185
|
+
let ignoreDueToComments = false;
|
|
9186
|
+
let toolData = null;
|
|
9187
|
+
let toolParseError = null;
|
|
9188
|
+
try {
|
|
9189
|
+
toolData = GSToolBlockUtils$2.parseToolBlock(content);
|
|
9190
|
+
} catch (error) {
|
|
9191
|
+
// When chatting about the tool block, the LLM may add
|
|
9192
|
+
// add comments in it so let's test for this
|
|
9193
|
+
const comments = detectJsonComments$1(content);
|
|
9594
9194
|
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
|
|
9606
|
-
|
|
9607
|
-
}
|
|
9195
|
+
if (comments.length) {
|
|
9196
|
+
ignoreDueToComments = true;
|
|
9197
|
+
} else {
|
|
9198
|
+
toolParseError = error.message;
|
|
9199
|
+
warnings.push({
|
|
9200
|
+
position: position,
|
|
9201
|
+
type: 'gs_tool_block_parse_error',
|
|
9202
|
+
message: `Invalid GitSense tool block: ${error.message}`,
|
|
9203
|
+
content: content
|
|
9204
|
+
});
|
|
9205
|
+
}
|
|
9206
|
+
}
|
|
9608
9207
|
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
|
|
9612
|
-
|
|
9613
|
-
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
type: 'analysis_metadata_error',
|
|
9623
|
-
message: `Invalid analysis metadata: ${validationResult.errors.join(', ')}`,
|
|
9624
|
-
content: content,
|
|
9625
|
-
});
|
|
9626
|
-
}
|
|
9627
|
-
}
|
|
9208
|
+
if (ignoreDueToComments) ; else {
|
|
9209
|
+
return {
|
|
9210
|
+
type: 'gs-tool',
|
|
9211
|
+
language: language,
|
|
9212
|
+
content: content,
|
|
9213
|
+
position: position,
|
|
9214
|
+
incomplete: incomplete,
|
|
9215
|
+
toolData: toolData,
|
|
9216
|
+
toolParseError: toolParseError,
|
|
9217
|
+
warnings: warnings,
|
|
9218
|
+
};
|
|
9219
|
+
}
|
|
9220
|
+
}
|
|
9628
9221
|
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
position: position,
|
|
9634
|
-
incomplete: incomplete,
|
|
9635
|
-
analysisMetadata: analysisMetadata,
|
|
9636
|
-
analysisValidation: validationResult,
|
|
9637
|
-
warnings: warnings,
|
|
9638
|
-
};
|
|
9639
|
-
}
|
|
9222
|
+
// Check if this is an analysis block *next*
|
|
9223
|
+
if (AnalysisBlockUtils$2.isAnalysisBlock(content)) {
|
|
9224
|
+
const analysisType = AnalysisBlockUtils$2.getAnalysisBlockType(content);
|
|
9225
|
+
const analysisMetadata = AnalysisBlockUtils$2.parseOverviewMetadata(content);
|
|
9640
9226
|
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
return {
|
|
9646
|
-
type: 'gitsense-search-flow',
|
|
9647
|
-
language: language,
|
|
9648
|
-
content: content, // Keep raw content for now
|
|
9649
|
-
position: position,
|
|
9650
|
-
incomplete: incomplete,
|
|
9651
|
-
// Add parsedData: {} or similar if parsing is implemented later
|
|
9652
|
-
warnings: warnings, // Include any warnings collected so far
|
|
9653
|
-
};
|
|
9654
|
-
}
|
|
9227
|
+
// Validate the metadata if it was successfully parsed
|
|
9228
|
+
let validationResult = { isValid: false, errors: ['Failed to parse analysis metadata'] };
|
|
9229
|
+
if (analysisMetadata) {
|
|
9230
|
+
validationResult = AnalysisBlockUtils$2.validateAnalysisMetadata(analysisMetadata);
|
|
9655
9231
|
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
const errors = PatchUtils.validatePatchMetadata(metadata);
|
|
9666
|
-
if (errors.length) {
|
|
9667
|
-
warnings.push({
|
|
9668
|
-
position: position,
|
|
9669
|
-
type: 'patch_metadata_error',
|
|
9670
|
-
message: `Invalid patch metadata: ${errors.join(', ')}`,
|
|
9671
|
-
content: content,
|
|
9672
|
-
});
|
|
9673
|
-
// Decide if invalid metadata makes the whole block invalid or just adds a warning
|
|
9674
|
-
// For now, just warn, but return the extracted (potentially invalid) metadata.
|
|
9675
|
-
}
|
|
9232
|
+
if (!validationResult.isValid) {
|
|
9233
|
+
warnings.push({
|
|
9234
|
+
position: position,
|
|
9235
|
+
type: 'analysis_metadata_error',
|
|
9236
|
+
message: `Invalid analysis metadata: ${validationResult.errors.join(', ')}`,
|
|
9237
|
+
content: content,
|
|
9238
|
+
});
|
|
9239
|
+
}
|
|
9240
|
+
}
|
|
9676
9241
|
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
});
|
|
9689
|
-
} else {
|
|
9690
|
-
// Basic validation passed (structure was parsable)
|
|
9691
|
-
patchValidationResult = { valid: true, errors: [], patches: patches };
|
|
9692
|
-
}
|
|
9693
|
-
} catch (error) {
|
|
9694
|
-
patchValidationResult = { valid: false, errors: [error.message], patches: null };
|
|
9695
|
-
warnings.push({
|
|
9696
|
-
position: position,
|
|
9697
|
-
type: 'patch_parse_error',
|
|
9698
|
-
message: `Error parsing context patch: ${error.message}`,
|
|
9699
|
-
content: content,
|
|
9700
|
-
});
|
|
9701
|
-
}
|
|
9702
|
-
}
|
|
9242
|
+
return {
|
|
9243
|
+
type: analysisType,
|
|
9244
|
+
language: language,
|
|
9245
|
+
content: content,
|
|
9246
|
+
position: position,
|
|
9247
|
+
incomplete: incomplete,
|
|
9248
|
+
analysisMetadata: analysisMetadata,
|
|
9249
|
+
analysisValidation: validationResult,
|
|
9250
|
+
warnings: warnings,
|
|
9251
|
+
};
|
|
9252
|
+
}
|
|
9703
9253
|
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
content = removeLineNumbers(content); // This is the "cleaned" content
|
|
9719
|
-
}
|
|
9254
|
+
// Check if this is a gitsense-search-flow block *next*
|
|
9255
|
+
if (language === 'gitsense-search-flow') {
|
|
9256
|
+
// Future parsing logic for gitsense-search-flow content would go here.
|
|
9257
|
+
// For now, we just identify the type and keep the raw content.
|
|
9258
|
+
return {
|
|
9259
|
+
type: 'gitsense-search-flow',
|
|
9260
|
+
language: language,
|
|
9261
|
+
content: content, // Keep raw content for now
|
|
9262
|
+
position: position,
|
|
9263
|
+
incomplete: incomplete,
|
|
9264
|
+
// Add parsedData: {} or similar if parsing is implemented later
|
|
9265
|
+
warnings: warnings, // Include any warnings collected so far
|
|
9266
|
+
};
|
|
9267
|
+
}
|
|
9720
9268
|
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
if (tripleNewlineIndex !== -1) {
|
|
9727
|
-
const potentialHeaderText = content.substring(0, tripleNewlineIndex); // No trim here
|
|
9728
|
-
|
|
9729
|
-
try {
|
|
9730
|
-
header = parseHeader(potentialHeaderText, language);
|
|
9731
|
-
headerText = potentialHeaderText;
|
|
9732
|
-
codeText = content.substring(tripleNewlineIndex + tripleNewlineSeparator.length);
|
|
9733
|
-
headerDelimiterType = 'triple';
|
|
9734
|
-
} catch (error) {
|
|
9735
|
-
// If parsing fails, it's not a valid header, log warning and try double newline
|
|
9736
|
-
headerParseError = error.message;
|
|
9737
|
-
warnings.push({
|
|
9738
|
-
position: position,
|
|
9739
|
-
type: 'header_parse_error',
|
|
9740
|
-
message: `Invalid header (triple newline attempt): ${error.message}. Attempting double newline.`,
|
|
9741
|
-
content: potentialHeaderText // Show the problematic header text
|
|
9742
|
-
});
|
|
9743
|
-
// Do not set header, headerText, codeText, or headerDelimiterType yet.
|
|
9744
|
-
// Fall through to the next attempt.
|
|
9745
|
-
}
|
|
9746
|
-
}
|
|
9269
|
+
// Then check if this is a patch block
|
|
9270
|
+
if (PatchUtils$1.isPatchBlock(content)) {
|
|
9271
|
+
const patchFormat = PatchUtils$1.determinePatchFormat(content);
|
|
9272
|
+
const metadata = PatchUtils$1.extractPatchMetadata(content); // Extract metadata regardless of validation
|
|
9273
|
+
const patchContent = PatchUtils$1.extractPatchContent(content); // Extract raw patch content
|
|
9747
9274
|
|
|
9748
|
-
|
|
9749
|
-
// Only if a valid header wasn't found in the triple newline attempt
|
|
9750
|
-
if (!headerDelimiterType) {
|
|
9751
|
-
const doubleNewlineSeparator = '\n\n';
|
|
9752
|
-
const doubleNewlineIndex = content.indexOf(doubleNewlineSeparator);
|
|
9753
|
-
|
|
9754
|
-
if (doubleNewlineIndex !== -1) {
|
|
9755
|
-
const potentialHeaderText = content.substring(0, doubleNewlineIndex); // No trim here
|
|
9756
|
-
|
|
9757
|
-
try {
|
|
9758
|
-
header = parseHeader(potentialHeaderText, language);
|
|
9759
|
-
headerText = potentialHeaderText;
|
|
9760
|
-
codeText = content.substring(doubleNewlineIndex + doubleNewlineSeparator.length);
|
|
9761
|
-
headerDelimiterType = 'double';
|
|
9762
|
-
} catch (error) {
|
|
9763
|
-
// If parsing fails, it's not a valid header, log warning and default to no header
|
|
9764
|
-
headerParseError = error.message;
|
|
9765
|
-
warnings.push({
|
|
9766
|
-
position: position,
|
|
9767
|
-
type: 'header_parse_error',
|
|
9768
|
-
message: `Invalid header (double newline attempt): ${error.message}. Treating block as code only.`,
|
|
9769
|
-
content: potentialHeaderText // Show the problematic header text
|
|
9770
|
-
});
|
|
9771
|
-
// Fall through to default case (no header)
|
|
9772
|
-
}
|
|
9773
|
-
}
|
|
9774
|
-
}
|
|
9275
|
+
let patchValidationResult = { valid: true, errors: [], patches: null }; // Default valid state
|
|
9775
9276
|
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9277
|
+
// Validate metadata (always useful)
|
|
9278
|
+
const errors = PatchUtils$1.validatePatchMetadata(metadata);
|
|
9279
|
+
if (errors.length) {
|
|
9280
|
+
warnings.push({
|
|
9281
|
+
position: position,
|
|
9282
|
+
type: 'patch_metadata_error',
|
|
9283
|
+
message: `Invalid patch metadata: ${errors.join(', ')}`,
|
|
9284
|
+
content: content,
|
|
9285
|
+
});
|
|
9286
|
+
// Decide if invalid metadata makes the whole block invalid or just adds a warning
|
|
9287
|
+
// For now, just warn, but return the extracted (potentially invalid) metadata.
|
|
9288
|
+
}
|
|
9785
9289
|
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9290
|
+
// Optionally validate context patch structure if requested
|
|
9291
|
+
if (patchFormat === 'context' && validatePatches) {
|
|
9292
|
+
try {
|
|
9293
|
+
const patches = PatchUtils$1.extractContextPatches(content);
|
|
9294
|
+
if (!patches || patches.length === 0) {
|
|
9295
|
+
patchValidationResult = { valid: false, errors: ['No valid context patch content found.'], patches: null };
|
|
9296
|
+
warnings.push({
|
|
9297
|
+
position: position,
|
|
9298
|
+
type: 'patch_content_error',
|
|
9299
|
+
message: 'No valid context patch content found.',
|
|
9300
|
+
content: content,
|
|
9301
|
+
});
|
|
9302
|
+
} else {
|
|
9303
|
+
// Basic validation passed (structure was parsable)
|
|
9304
|
+
patchValidationResult = { valid: true, errors: [], patches: patches };
|
|
9305
|
+
}
|
|
9306
|
+
} catch (error) {
|
|
9307
|
+
patchValidationResult = { valid: false, errors: [error.message], patches: null };
|
|
9308
|
+
warnings.push({
|
|
9309
|
+
position: position,
|
|
9310
|
+
type: 'patch_parse_error',
|
|
9311
|
+
message: `Error parsing context patch: ${error.message}`,
|
|
9312
|
+
content: content,
|
|
9313
|
+
});
|
|
9314
|
+
}
|
|
9315
|
+
}
|
|
9799
9316
|
|
|
9317
|
+
return {
|
|
9318
|
+
type: 'patch',
|
|
9319
|
+
language: language === 'diff' ? 'diff' : language, // Use 'diff' if specified, else keep original
|
|
9320
|
+
content: content, // Full original content within fences
|
|
9321
|
+
position: position,
|
|
9322
|
+
incomplete: incomplete,
|
|
9323
|
+
metadata: metadata,
|
|
9324
|
+
patch: patchContent, // Raw patch content after metadata
|
|
9325
|
+
patchFormat: patchFormat,
|
|
9326
|
+
patchValidation: validatePatches ? patchValidationResult : undefined, // Include validation only if requested
|
|
9327
|
+
warnings: warnings,
|
|
9328
|
+
};
|
|
9329
|
+
} else {
|
|
9330
|
+
// For non-patch blocks, remove display line numbers before processing content
|
|
9331
|
+
content = removeLineNumbers$2(content); // This is the "cleaned" content
|
|
9332
|
+
}
|
|
9800
9333
|
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
* @param {Array} incompleteBlocks - Array of incomplete block objects from extractor
|
|
9806
|
-
* @param {Object} options - Processing options
|
|
9807
|
-
* @returns {Array} Array of processed block objects
|
|
9808
|
-
*/
|
|
9809
|
-
function processBlockContents(text, completeBlocks, incompleteBlocks, options) {
|
|
9810
|
-
const processedBlocks = [];
|
|
9811
|
-
const allWarnings = []; // Collect warnings from all blocks
|
|
9812
|
-
|
|
9813
|
-
// Process complete blocks
|
|
9814
|
-
for (const block of completeBlocks) {
|
|
9815
|
-
try {
|
|
9816
|
-
const startPos = block.opening.position + block.opening.length;
|
|
9817
|
-
const endPos = block.closing.position;
|
|
9818
|
-
// Get content, including the newlines immediately after opening and before closing fence
|
|
9819
|
-
const contentWithNewlines = text.substring(startPos, endPos);
|
|
9820
|
-
const content = contentWithNewlines; //.replace(/^\s*\n|\n\s*$/g, '');
|
|
9821
|
-
|
|
9822
|
-
const language = block.opening.language;
|
|
9823
|
-
|
|
9824
|
-
// Process block content
|
|
9825
|
-
const processedBlock = processBlockContent(content, language, block.opening.position, false, options);
|
|
9826
|
-
processedBlocks.push(processedBlock);
|
|
9827
|
-
if (processedBlock.warnings) {
|
|
9828
|
-
allWarnings.push(...processedBlock.warnings);
|
|
9829
|
-
}
|
|
9830
|
-
} catch (error) {
|
|
9831
|
-
// Catch errors during the processing of a single block
|
|
9832
|
-
allWarnings.push({
|
|
9833
|
-
position: block.opening?.position || -1,
|
|
9834
|
-
type: 'block_processing_error',
|
|
9835
|
-
message: `Error processing complete block: ${error.message}`,
|
|
9836
|
-
content: text.substring(block.opening?.position, block.closing?.position + block.closing?.length) || "Error retrieving block content"
|
|
9837
|
-
});
|
|
9838
|
-
}
|
|
9839
|
-
}
|
|
9334
|
+
// --- Process as a regular code block ---
|
|
9335
|
+
// Attempt 1: Look for triple newline separator (our standard)
|
|
9336
|
+
const tripleNewlineSeparator = '\n\n\n';
|
|
9337
|
+
const tripleNewlineIndex = content.indexOf(tripleNewlineSeparator);
|
|
9840
9338
|
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
try {
|
|
9844
|
-
const startPos = block.opening.position + block.opening.length;
|
|
9845
|
-
// Get content from opening fence to end of text
|
|
9846
|
-
const contentWithNewline = text.substring(startPos);
|
|
9847
|
-
// Trim only leading whitespace line
|
|
9848
|
-
const content = contentWithNewline.replace(/^\s*\n/, '');
|
|
9849
|
-
|
|
9850
|
-
const language = block.opening.language;
|
|
9851
|
-
|
|
9852
|
-
// Process block content - it's expected to be incomplete
|
|
9853
|
-
const processedBlock = processBlockContent(content, language, block.opening.position, true, options);
|
|
9854
|
-
|
|
9855
|
-
// Extract continuation info for incomplete blocks
|
|
9856
|
-
// Requires extractContinuationInfo from continuationUtils
|
|
9857
|
-
try {
|
|
9858
|
-
// Pass the *processed* header info to continuation utils
|
|
9859
|
-
let { 'Continuation-Part': partNumber } = processedBlock?.header || {};
|
|
9860
|
-
partNumber = partNumber ? parseInt(partNumber) + 1 : 2; // Default to part 2 if not specified
|
|
9861
|
-
processedBlock.continuationInfo = extractContinuationInfo(processedBlock.content, partNumber, language, processedBlock.header);
|
|
9862
|
-
} catch (continuationError) {
|
|
9863
|
-
allWarnings.push({
|
|
9864
|
-
position: block.opening?.position || -1,
|
|
9865
|
-
type: 'continuation_info_error',
|
|
9866
|
-
message: `Error extracting continuation info: ${continuationError.message}`,
|
|
9867
|
-
content: content
|
|
9868
|
-
});
|
|
9869
|
-
}
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
processedBlocks.push(processedBlock);
|
|
9873
|
-
if (processedBlock.warnings) {
|
|
9874
|
-
allWarnings.push(...processedBlock.warnings);
|
|
9875
|
-
}
|
|
9876
|
-
} catch (error) {
|
|
9877
|
-
// Catch errors during the processing of a single incomplete block
|
|
9878
|
-
allWarnings.push({
|
|
9879
|
-
position: block.opening?.position || -1,
|
|
9880
|
-
type: 'incomplete_block_processing_error',
|
|
9881
|
-
message: `Error processing incomplete block: ${error.message}`,
|
|
9882
|
-
content: text.substring(block.opening?.position) || "Error retrieving block content"
|
|
9883
|
-
});
|
|
9884
|
-
}
|
|
9885
|
-
}
|
|
9339
|
+
if (tripleNewlineIndex !== -1) {
|
|
9340
|
+
const potentialHeaderText = content.substring(0, tripleNewlineIndex); // No trim here
|
|
9886
9341
|
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9342
|
+
try {
|
|
9343
|
+
header = parseHeader$2(potentialHeaderText, language);
|
|
9344
|
+
headerText = potentialHeaderText;
|
|
9345
|
+
codeText = content.substring(tripleNewlineIndex + tripleNewlineSeparator.length);
|
|
9346
|
+
headerDelimiterType = 'triple';
|
|
9347
|
+
} catch (error) {
|
|
9348
|
+
// If parsing fails, it's not a valid header, log warning and try double newline
|
|
9349
|
+
headerParseError = error.message;
|
|
9350
|
+
warnings.push({
|
|
9351
|
+
position: position,
|
|
9352
|
+
type: 'header_parse_error',
|
|
9353
|
+
message: `Invalid header (triple newline attempt): ${error.message}. Attempting double newline.`,
|
|
9354
|
+
content: potentialHeaderText // Show the problematic header text
|
|
9355
|
+
});
|
|
9356
|
+
// Do not set header, headerText, codeText, or headerDelimiterType yet.
|
|
9357
|
+
// Fall through to the next attempt.
|
|
9358
|
+
}
|
|
9359
|
+
}
|
|
9891
9360
|
|
|
9361
|
+
// Attempt 2: Look for double newline separator (fallback)
|
|
9362
|
+
// Only if a valid header wasn't found in the triple newline attempt
|
|
9363
|
+
if (!headerDelimiterType) {
|
|
9364
|
+
const doubleNewlineSeparator = '\n\n';
|
|
9365
|
+
const doubleNewlineIndex = content.indexOf(doubleNewlineSeparator);
|
|
9892
9366
|
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
* @param {string} text - The input text containing code blocks
|
|
9896
|
-
* @param {Object} options - Processing options (e.g., silent, validatePatches)
|
|
9897
|
-
* @returns {Object} { blocks: Array, warnings: Array, hasIncompleteBlocks: boolean, lastIncompleteBlock: Object|null }
|
|
9898
|
-
*/
|
|
9899
|
-
function processCodeBlocks(text, options = { silent: false, validatePatches: false }) {
|
|
9900
|
-
if (typeof text !== "string") { // Allow empty strings
|
|
9901
|
-
console.warn("Warning: Input must be a string.");
|
|
9902
|
-
return {
|
|
9903
|
-
blocks: [],
|
|
9904
|
-
warnings: [{ type: 'invalid_input', message: 'Input must be a string.' }],
|
|
9905
|
-
hasIncompleteBlocks: false,
|
|
9906
|
-
lastIncompleteBlock: null }
|
|
9907
|
-
;
|
|
9908
|
-
}
|
|
9367
|
+
if (doubleNewlineIndex !== -1) {
|
|
9368
|
+
const potentialHeaderText = content.substring(0, doubleNewlineIndex); // No trim here
|
|
9909
9369
|
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
9370
|
+
try {
|
|
9371
|
+
header = parseHeader$2(potentialHeaderText, language);
|
|
9372
|
+
headerText = potentialHeaderText;
|
|
9373
|
+
codeText = content.substring(doubleNewlineIndex + doubleNewlineSeparator.length);
|
|
9374
|
+
headerDelimiterType = 'double';
|
|
9375
|
+
} catch (error) {
|
|
9376
|
+
// If parsing fails, it's not a valid header, log warning and default to no header
|
|
9377
|
+
headerParseError = error.message;
|
|
9378
|
+
warnings.push({
|
|
9379
|
+
position: position,
|
|
9380
|
+
type: 'header_parse_error',
|
|
9381
|
+
message: `Invalid header (double newline attempt): ${error.message}. Treating block as code only.`,
|
|
9382
|
+
content: potentialHeaderText // Show the problematic header text
|
|
9383
|
+
});
|
|
9384
|
+
// Fall through to default case (no header)
|
|
9385
|
+
}
|
|
9386
|
+
}
|
|
9387
|
+
}
|
|
9913
9388
|
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
|
|
9922
|
-
|
|
9923
|
-
const { processedBlocks, allWarnings: processorWarnings } = processBlockContents(
|
|
9924
|
-
text, completeBlocks, incompleteBlocks, options
|
|
9925
|
-
);
|
|
9926
|
-
|
|
9927
|
-
// Combine warnings from extractor and processor
|
|
9928
|
-
const allWarnings = [...extractorWarnings, ...processorWarnings];
|
|
9929
|
-
|
|
9930
|
-
// Log warnings if not silent
|
|
9931
|
-
if (!options.silent && allWarnings.length > 0) {
|
|
9932
|
-
console.warn('\nCode Block Processing Warnings:');
|
|
9933
|
-
allWarnings.forEach((warning, index) => {
|
|
9934
|
-
console.warn(`\nWarning ${index + 1}:`);
|
|
9935
|
-
console.warn(`Type: ${warning.type}`);
|
|
9936
|
-
console.warn(`Message: ${warning.message}`);
|
|
9937
|
-
console.warn(`Position: ${warning.position}`);
|
|
9938
|
-
if (warning.content) {
|
|
9939
|
-
// Limit logged content length
|
|
9940
|
-
const maxLogLength = 200;
|
|
9941
|
-
const loggedContent = warning.content.length > maxLogLength
|
|
9942
|
-
? warning.content.substring(0, maxLogLength) + '...'
|
|
9943
|
-
: warning.content;
|
|
9944
|
-
console.warn(`Content Hint: ${loggedContent}`);
|
|
9945
|
-
}
|
|
9946
|
-
});
|
|
9947
|
-
}
|
|
9389
|
+
// Default: If no valid header was found after both attempts
|
|
9390
|
+
if (!headerDelimiterType && !incomplete) { // Only warn about missing header if the block is complete
|
|
9391
|
+
warnings.push({
|
|
9392
|
+
position: position,
|
|
9393
|
+
type: 'missing_header',
|
|
9394
|
+
message: `No distinct header found or parsed as valid. Treating block as code only.`,
|
|
9395
|
+
content: content.substring(0, 100) + '...' // Show beginning of content
|
|
9396
|
+
});
|
|
9397
|
+
}
|
|
9948
9398
|
|
|
9949
|
-
|
|
9950
|
-
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9399
|
+
return {
|
|
9400
|
+
type: 'code',
|
|
9401
|
+
language: language,
|
|
9402
|
+
header: header,
|
|
9403
|
+
headerText: headerText.trim(), // Include the raw header text if successfully parsed
|
|
9404
|
+
content: codeText, // The code part after the header (or full content if no header)
|
|
9405
|
+
position: position, // Position of the opening fence
|
|
9406
|
+
headerDelimiterType: headerDelimiterType, // 'triple', 'double', or null
|
|
9407
|
+
incomplete: incomplete,
|
|
9408
|
+
warnings: warnings,
|
|
9409
|
+
headerParseError: headerParseError // Include error message if parsing failed
|
|
9410
|
+
};
|
|
9411
|
+
}
|
|
9961
9412
|
|
|
9962
|
-
/**
|
|
9963
|
-
* Public API function - maintains backward compatibility for simple extraction.
|
|
9964
|
-
* Use processCodeBlocks for more detailed results (warnings, incomplete status).
|
|
9965
|
-
* @param {string} text - The input text containing code blocks
|
|
9966
|
-
* @param {Object} options - Options for extraction (e.g., { silent: true })
|
|
9967
|
-
* @returns {Object} - Object containing extracted blocks and warnings { blocks: Array, warnings: Array }
|
|
9968
|
-
*/
|
|
9969
|
-
function extractCodeBlocks(text, options = { silent: false, validatePatches: false, debug: false }) {
|
|
9970
|
-
const { blocks, warnings } = processCodeBlocks(text, options);
|
|
9971
|
-
return { blocks, warnings };
|
|
9972
|
-
}
|
|
9973
9413
|
|
|
9414
|
+
/**
|
|
9415
|
+
* Processes the content of complete and incomplete blocks (internal helper)
|
|
9416
|
+
* @param {string} text - The input text
|
|
9417
|
+
* @param {Array} completeBlocks - Array of complete block objects from extractor
|
|
9418
|
+
* @param {Array} incompleteBlocks - Array of incomplete block objects from extractor
|
|
9419
|
+
* @param {Object} options - Processing options
|
|
9420
|
+
* @returns {Array} Array of processed block objects
|
|
9421
|
+
*/
|
|
9422
|
+
function processBlockContents(text, completeBlocks, incompleteBlocks, options) {
|
|
9423
|
+
const processedBlocks = [];
|
|
9424
|
+
const allWarnings = []; // Collect warnings from all blocks
|
|
9974
9425
|
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
|
|
9426
|
+
// Process complete blocks
|
|
9427
|
+
for (const block of completeBlocks) {
|
|
9428
|
+
try {
|
|
9429
|
+
const startPos = block.opening.position + block.opening.length;
|
|
9430
|
+
const endPos = block.closing.position;
|
|
9431
|
+
// Get content, including the newlines immediately after opening and before closing fence
|
|
9432
|
+
const contentWithNewlines = text.substring(startPos, endPos);
|
|
9433
|
+
const content = contentWithNewlines; //.replace(/^\s*\n|\n\s*$/g, '');
|
|
9434
|
+
|
|
9435
|
+
const language = block.opening.language;
|
|
9436
|
+
|
|
9437
|
+
// Process block content
|
|
9438
|
+
const processedBlock = processBlockContent(content, language, block.opening.position, false, options);
|
|
9439
|
+
processedBlocks.push(processedBlock);
|
|
9440
|
+
if (processedBlock.warnings) {
|
|
9441
|
+
allWarnings.push(...processedBlock.warnings);
|
|
9442
|
+
}
|
|
9443
|
+
} catch (error) {
|
|
9444
|
+
// Catch errors during the processing of a single block
|
|
9445
|
+
allWarnings.push({
|
|
9446
|
+
position: block.opening?.position || -1,
|
|
9447
|
+
type: 'block_processing_error',
|
|
9448
|
+
message: `Error processing complete block: ${error.message}`,
|
|
9449
|
+
content: text.substring(block.opening?.position, block.closing?.position + block.closing?.length) || "Error retrieving block content"
|
|
9450
|
+
});
|
|
9451
|
+
}
|
|
9452
|
+
}
|
|
9987
9453
|
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
// Process matches in reverse to maintain correct positions
|
|
9998
|
-
for (let i = matches.length - 1; i >= 0; i--) {
|
|
9999
|
-
const match = matches[i];
|
|
10000
|
-
const fullMatch = match[0];
|
|
10001
|
-
const language = match[1];
|
|
10002
|
-
const blockContent = match[2];
|
|
10003
|
-
|
|
10004
|
-
// Check if this is a patch block or a gitsense-search-flow block (if they contain UUIDs)
|
|
10005
|
-
if (PatchUtils.isPatchBlock(blockContent)) {
|
|
10006
|
-
// Process patch block UUIDs
|
|
10007
|
-
const lines = blockContent.split('\n');
|
|
10008
|
-
let blockModified = false;
|
|
10009
|
-
|
|
10010
|
-
const newLines = lines.map(line => {
|
|
10011
|
-
// Check for UUID fields in patch metadata
|
|
10012
|
-
if ((line.includes('# Source-Block-UUID:') || line.includes('# Target-Block-UUID:')) &&
|
|
10013
|
-
!line.includes('{{GS-UUID}')) {
|
|
10014
|
-
|
|
10015
|
-
const [fieldPart, valuePart] = line.split(':').map(p => p.trim());
|
|
10016
|
-
|
|
10017
|
-
// Validate UUID
|
|
10018
|
-
const validation = validateUUID(valuePart);
|
|
10019
|
-
if (validation["Block-UUID"] === "INVALID UUID") {
|
|
10020
|
-
blockModified = true;
|
|
10021
|
-
modified = true;
|
|
10022
|
-
return `${fieldPart}: ${validation["Correct Block-UUID"]}`;
|
|
10023
|
-
}
|
|
10024
|
-
}
|
|
10025
|
-
return line;
|
|
10026
|
-
});
|
|
10027
|
-
|
|
10028
|
-
// If this block was modified, replace it in the text
|
|
10029
|
-
if (blockModified) {
|
|
10030
|
-
const newBlock = `\`\`\`${language}\n${newLines.join('\n')}\n\`\`\``;
|
|
10031
|
-
fixedText = fixedText.substring(0, match.index) +
|
|
10032
|
-
newBlock +
|
|
10033
|
-
fixedText.substring(match.index + fullMatch.length);
|
|
10034
|
-
}
|
|
10035
|
-
} else {
|
|
10036
|
-
// Process regular code block or gitsense-search-flow block for UUIDs
|
|
10037
|
-
// Split block content into lines to check for header/UUIDs
|
|
10038
|
-
const lines = blockContent.split('\n');
|
|
10039
|
-
let blockModified = false;
|
|
10040
|
-
|
|
10041
|
-
// Process each line
|
|
10042
|
-
const newLines = lines.map(line => {
|
|
10043
|
-
// Check for UUID fields
|
|
10044
|
-
if (line.includes(' Block-UUID: ') || line.includes(' Parent-UUID: ')) {
|
|
10045
|
-
const [fieldPart, valuePart] = line.split(':').map(p => p.trim());
|
|
10046
|
-
|
|
10047
|
-
// Skip if N/A or contains unexpected characters
|
|
10048
|
-
if (valuePart === 'N/A' || valuePart.match(/\(/)) {
|
|
10049
|
-
return line;
|
|
10050
|
-
}
|
|
10051
|
-
// Validate UUID
|
|
10052
|
-
const validation = validateUUID(valuePart);
|
|
10053
|
-
|
|
10054
|
-
if (validation["Block-UUID"] === "INVALID UUID") {
|
|
10055
|
-
blockModified = true;
|
|
10056
|
-
modified = true;
|
|
10057
|
-
return `${fieldPart}: ${validation["Correct Block-UUID"]}`;
|
|
10058
|
-
}
|
|
10059
|
-
}
|
|
10060
|
-
return line;
|
|
10061
|
-
});
|
|
10062
|
-
|
|
10063
|
-
// If this block was modified, replace it in the text
|
|
10064
|
-
if (blockModified) {
|
|
10065
|
-
const newBlock = `\`\`\`${language}\n${newLines.join('\n')}\n\`\`\``;
|
|
10066
|
-
fixedText = fixedText.substring(0, match.index) +
|
|
10067
|
-
newBlock +
|
|
10068
|
-
fixedText.substring(match.index + fullMatch.length);
|
|
10069
|
-
}
|
|
10070
|
-
}
|
|
10071
|
-
}
|
|
9454
|
+
// Process incomplete blocks
|
|
9455
|
+
for (const block of incompleteBlocks) {
|
|
9456
|
+
try {
|
|
9457
|
+
const startPos = block.opening.position + block.opening.length;
|
|
9458
|
+
// Get content from opening fence to end of text
|
|
9459
|
+
const contentWithNewline = text.substring(startPos);
|
|
9460
|
+
// Trim only leading whitespace line
|
|
9461
|
+
const content = contentWithNewline.replace(/^\s*\n/, '');
|
|
10072
9462
|
|
|
10073
|
-
|
|
10074
|
-
text: fixedText,
|
|
10075
|
-
modified: modified
|
|
10076
|
-
};
|
|
10077
|
-
}
|
|
9463
|
+
const language = block.opening.language;
|
|
10078
9464
|
|
|
9465
|
+
// Process block content - it's expected to be incomplete
|
|
9466
|
+
const processedBlock = processBlockContent(content, language, block.opening.position, true, options);
|
|
10079
9467
|
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
9468
|
+
// Extract continuation info for incomplete blocks
|
|
9469
|
+
// Requires extractContinuationInfo from continuationUtils
|
|
9470
|
+
try {
|
|
9471
|
+
// Pass the *processed* header info to continuation utils
|
|
9472
|
+
let { 'Continuation-Part': partNumber } = processedBlock?.header || {};
|
|
9473
|
+
partNumber = partNumber ? parseInt(partNumber) + 1 : 2; // Default to part 2 if not specified
|
|
9474
|
+
processedBlock.continuationInfo = extractContinuationInfo$2(processedBlock.content, partNumber, language, processedBlock.header);
|
|
9475
|
+
} catch (continuationError) {
|
|
9476
|
+
allWarnings.push({
|
|
9477
|
+
position: block.opening?.position || -1,
|
|
9478
|
+
type: 'continuation_info_error',
|
|
9479
|
+
message: `Error extracting continuation info: ${continuationError.message}`,
|
|
9480
|
+
content: content
|
|
9481
|
+
});
|
|
9482
|
+
}
|
|
9483
|
+
|
|
9484
|
+
|
|
9485
|
+
processedBlocks.push(processedBlock);
|
|
9486
|
+
if (processedBlock.warnings) {
|
|
9487
|
+
allWarnings.push(...processedBlock.warnings);
|
|
9488
|
+
}
|
|
9489
|
+
} catch (error) {
|
|
9490
|
+
// Catch errors during the processing of a single incomplete block
|
|
9491
|
+
allWarnings.push({
|
|
9492
|
+
position: block.opening?.position || -1,
|
|
9493
|
+
type: 'incomplete_block_processing_error',
|
|
9494
|
+
message: `Error processing incomplete block: ${error.message}`,
|
|
9495
|
+
content: text.substring(block.opening?.position) || "Error retrieving block content"
|
|
9496
|
+
});
|
|
9497
|
+
}
|
|
9498
|
+
}
|
|
9499
|
+
|
|
9500
|
+
// Return processed blocks and collected warnings
|
|
9501
|
+
// Note: The caller (processCodeBlocks) will handle adding these warnings to its own return object.
|
|
9502
|
+
return { processedBlocks, allWarnings };
|
|
9503
|
+
}
|
|
9504
|
+
|
|
9505
|
+
|
|
9506
|
+
/**
|
|
9507
|
+
* Core function to process code blocks with shared logic
|
|
9508
|
+
* @param {string} text - The input text containing code blocks
|
|
9509
|
+
* @param {Object} options - Processing options (e.g., silent, validatePatches)
|
|
9510
|
+
* @returns {Object} { blocks: Array, warnings: Array, hasIncompleteBlocks: boolean, lastIncompleteBlock: Object|null }
|
|
9511
|
+
*/
|
|
9512
|
+
function processCodeBlocks$5(text, options = { silent: false, validatePatches: false }) {
|
|
9513
|
+
if (typeof text !== "string") { // Allow empty strings
|
|
9514
|
+
console.warn("Warning: Input must be a string.");
|
|
9515
|
+
return {
|
|
9516
|
+
blocks: [],
|
|
9517
|
+
warnings: [{ type: 'invalid_input', message: 'Input must be a string.' }],
|
|
9518
|
+
hasIncompleteBlocks: false,
|
|
9519
|
+
lastIncompleteBlock: null }
|
|
9520
|
+
;
|
|
9521
|
+
}
|
|
9522
|
+
|
|
9523
|
+
if (text.trim() === "") {
|
|
9524
|
+
return { blocks: [], warnings: [], hasIncompleteBlocks: false, lastIncompleteBlock: null };
|
|
9525
|
+
}
|
|
9526
|
+
|
|
9527
|
+
// Step 1: Find all fence positions
|
|
9528
|
+
const { openingPositions, closingPositions } = findAllCodeFences$3(text);
|
|
9529
|
+
|
|
9530
|
+
// Step 2: Match fences to get potential block boundaries
|
|
9531
|
+
const { completeBlocks, incompleteBlocks, warnings: extractorWarnings } = matchFencesAndExtractBlocks$3(
|
|
9532
|
+
text, openingPositions, closingPositions
|
|
9533
|
+
);
|
|
9534
|
+
|
|
9535
|
+
// Step 3: Process the content of these potential blocks
|
|
9536
|
+
const { processedBlocks, allWarnings: processorWarnings } = processBlockContents(
|
|
9537
|
+
text, completeBlocks, incompleteBlocks, options
|
|
9538
|
+
);
|
|
9539
|
+
|
|
9540
|
+
// Combine warnings from extractor and processor
|
|
9541
|
+
const allWarnings = [...extractorWarnings, ...processorWarnings];
|
|
9542
|
+
|
|
9543
|
+
// Log warnings if not silent
|
|
9544
|
+
if (!options.silent && allWarnings.length > 0) {
|
|
9545
|
+
console.warn('\nCode Block Processing Warnings:');
|
|
9546
|
+
allWarnings.forEach((warning, index) => {
|
|
9547
|
+
console.warn(`\nWarning ${index + 1}:`);
|
|
9548
|
+
console.warn(`Type: ${warning.type}`);
|
|
9549
|
+
console.warn(`Message: ${warning.message}`);
|
|
9550
|
+
console.warn(`Position: ${warning.position}`);
|
|
9551
|
+
if (warning.content) {
|
|
9552
|
+
// Limit logged content length
|
|
9553
|
+
const maxLogLength = 200;
|
|
9554
|
+
const loggedContent = warning.content.length > maxLogLength
|
|
9555
|
+
? warning.content.substring(0, maxLogLength) + '...'
|
|
9556
|
+
: warning.content;
|
|
9557
|
+
console.warn(`Content Hint: ${loggedContent}`);
|
|
9558
|
+
}
|
|
9559
|
+
});
|
|
9560
|
+
}
|
|
9561
|
+
|
|
9562
|
+
const hasIncompleteBlocks = incompleteBlocks.length > 0;
|
|
9563
|
+
const lastIncompleteBlock = hasIncompleteBlocks
|
|
9564
|
+
? processedBlocks.find(block => block.incomplete) // Find the corresponding processed block
|
|
9565
|
+
: null;
|
|
9566
|
+
|
|
9567
|
+
return {
|
|
9568
|
+
blocks: processedBlocks,
|
|
9569
|
+
warnings: allWarnings,
|
|
9570
|
+
hasIncompleteBlocks: hasIncompleteBlocks,
|
|
9571
|
+
lastIncompleteBlock: lastIncompleteBlock
|
|
9572
|
+
};
|
|
9573
|
+
}
|
|
9574
|
+
|
|
9575
|
+
/**
|
|
9576
|
+
* Public API function - maintains backward compatibility for simple extraction.
|
|
9577
|
+
* Use processCodeBlocks for more detailed results (warnings, incomplete status).
|
|
9578
|
+
* @param {string} text - The input text containing code blocks
|
|
9579
|
+
* @param {Object} options - Options for extraction (e.g., { silent: true })
|
|
9580
|
+
* @returns {Object} - Object containing extracted blocks and warnings { blocks: Array, warnings: Array }
|
|
9581
|
+
*/
|
|
9582
|
+
function extractCodeBlocks$2(text, options = { silent: false, validatePatches: false, debug: false }) {
|
|
9583
|
+
const { blocks, warnings } = processCodeBlocks$5(text, options);
|
|
9584
|
+
return { blocks, warnings };
|
|
10086
9585
|
}
|
|
10087
9586
|
|
|
9587
|
+
|
|
9588
|
+
/**
|
|
9589
|
+
* Fixes invalid UUIDs in code blocks within text
|
|
9590
|
+
* @param {string} text - The input text containing code blocks
|
|
9591
|
+
* @returns {Object} - Object containing fixed text and whether changes were made { text: string, modified: boolean }
|
|
9592
|
+
*/
|
|
9593
|
+
function fixTextCodeBlocks$2(text) {
|
|
9594
|
+
if (typeof text !== "string" || text.trim() === "") {
|
|
9595
|
+
return {
|
|
9596
|
+
text: text,
|
|
9597
|
+
modified: false
|
|
9598
|
+
};
|
|
9599
|
+
}
|
|
9600
|
+
|
|
9601
|
+
let modified = false;
|
|
9602
|
+
let fixedText = text;
|
|
9603
|
+
|
|
9604
|
+
// Regex to match code blocks with their language
|
|
9605
|
+
const codeBlockRegex = /```([a-zA-Z-]*)\n([\s\S]*?)\n```/g;
|
|
9606
|
+
|
|
9607
|
+
// Store all matches to process in reverse
|
|
9608
|
+
const matches = Array.from(text.matchAll(codeBlockRegex));
|
|
9609
|
+
|
|
9610
|
+
// Process matches in reverse to maintain correct positions
|
|
9611
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
9612
|
+
const match = matches[i];
|
|
9613
|
+
const fullMatch = match[0];
|
|
9614
|
+
const language = match[1];
|
|
9615
|
+
const blockContent = match[2];
|
|
9616
|
+
|
|
9617
|
+
// Check if this is a patch block or a gitsense-search-flow block (if they contain UUIDs)
|
|
9618
|
+
if (PatchUtils$1.isPatchBlock(blockContent)) {
|
|
9619
|
+
// Process patch block UUIDs
|
|
9620
|
+
const lines = blockContent.split('\n');
|
|
9621
|
+
let blockModified = false;
|
|
9622
|
+
|
|
9623
|
+
const newLines = lines.map(line => {
|
|
9624
|
+
// Check for UUID fields in patch metadata
|
|
9625
|
+
if ((line.includes('# Source-Block-UUID:') || line.includes('# Target-Block-UUID:')) &&
|
|
9626
|
+
!line.includes('{{GS-UUID}')) {
|
|
9627
|
+
|
|
9628
|
+
const [fieldPart, valuePart] = line.split(':').map(p => p.trim());
|
|
9629
|
+
|
|
9630
|
+
// Validate UUID
|
|
9631
|
+
const validation = validateUUID$2(valuePart);
|
|
9632
|
+
if (validation["Block-UUID"] === "INVALID UUID") {
|
|
9633
|
+
blockModified = true;
|
|
9634
|
+
modified = true;
|
|
9635
|
+
return `${fieldPart}: ${validation["Correct Block-UUID"]}`;
|
|
9636
|
+
}
|
|
9637
|
+
}
|
|
9638
|
+
return line;
|
|
9639
|
+
});
|
|
9640
|
+
|
|
9641
|
+
// If this block was modified, replace it in the text
|
|
9642
|
+
if (blockModified) {
|
|
9643
|
+
const newBlock = `\`\`\`${language}\n${newLines.join('\n')}\n\`\`\``;
|
|
9644
|
+
fixedText = fixedText.substring(0, match.index) +
|
|
9645
|
+
newBlock +
|
|
9646
|
+
fixedText.substring(match.index + fullMatch.length);
|
|
9647
|
+
}
|
|
9648
|
+
} else {
|
|
9649
|
+
// Process regular code block or gitsense-search-flow block for UUIDs
|
|
9650
|
+
// Split block content into lines to check for header/UUIDs
|
|
9651
|
+
const lines = blockContent.split('\n');
|
|
9652
|
+
let blockModified = false;
|
|
9653
|
+
|
|
9654
|
+
// Process each line
|
|
9655
|
+
const newLines = lines.map(line => {
|
|
9656
|
+
// Check for UUID fields
|
|
9657
|
+
if (line.includes(' Block-UUID: ') || line.includes(' Parent-UUID: ')) {
|
|
9658
|
+
const [fieldPart, valuePart] = line.split(':').map(p => p.trim());
|
|
9659
|
+
|
|
9660
|
+
// Skip if N/A or contains unexpected characters
|
|
9661
|
+
if (valuePart === 'N/A' || valuePart.match(/\(/)) {
|
|
9662
|
+
return line;
|
|
9663
|
+
}
|
|
9664
|
+
// Validate UUID
|
|
9665
|
+
const validation = validateUUID$2(valuePart);
|
|
9666
|
+
|
|
9667
|
+
if (validation["Block-UUID"] === "INVALID UUID") {
|
|
9668
|
+
blockModified = true;
|
|
9669
|
+
modified = true;
|
|
9670
|
+
return `${fieldPart}: ${validation["Correct Block-UUID"]}`;
|
|
9671
|
+
}
|
|
9672
|
+
}
|
|
9673
|
+
return line;
|
|
9674
|
+
});
|
|
9675
|
+
|
|
9676
|
+
// If this block was modified, replace it in the text
|
|
9677
|
+
if (blockModified) {
|
|
9678
|
+
const newBlock = `\`\`\`${language}\n${newLines.join('\n')}\n\`\`\``;
|
|
9679
|
+
fixedText = fixedText.substring(0, match.index) +
|
|
9680
|
+
newBlock +
|
|
9681
|
+
fixedText.substring(match.index + fullMatch.length);
|
|
9682
|
+
}
|
|
9683
|
+
}
|
|
9684
|
+
}
|
|
9685
|
+
|
|
9686
|
+
return {
|
|
9687
|
+
text: fixedText,
|
|
9688
|
+
modified: modified
|
|
9689
|
+
};
|
|
9690
|
+
}
|
|
9691
|
+
|
|
9692
|
+
|
|
9693
|
+
var blockProcessor = {
|
|
9694
|
+
processCodeBlocks: processCodeBlocks$5,
|
|
9695
|
+
extractCodeBlocks: extractCodeBlocks$2,
|
|
9696
|
+
fixTextCodeBlocks: fixTextCodeBlocks$2,
|
|
9697
|
+
};
|
|
9698
|
+
|
|
10088
9699
|
/**
|
|
10089
9700
|
* Component: CodeBlockUtils Patch Integration
|
|
10090
9701
|
* Block-UUID: 9f7395ef-e213-4841-a95d-f263e422288a
|
|
@@ -10097,7 +9708,7 @@ function requireBlockProcessor () {
|
|
|
10097
9708
|
*/
|
|
10098
9709
|
|
|
10099
9710
|
// Dependency on the core block processor
|
|
10100
|
-
const { processCodeBlocks: processCodeBlocks$
|
|
9711
|
+
const { processCodeBlocks: processCodeBlocks$4 } = blockProcessor;
|
|
10101
9712
|
|
|
10102
9713
|
/**
|
|
10103
9714
|
* Checks if the provided text content contains at least one patch block.
|
|
@@ -10107,7 +9718,7 @@ const { processCodeBlocks: processCodeBlocks$3 } = requireBlockProcessor();
|
|
|
10107
9718
|
*/
|
|
10108
9719
|
function containsPatch$2(content, options = { silent: true }) {
|
|
10109
9720
|
// Use the core processor to get all blocks
|
|
10110
|
-
const { blocks } = processCodeBlocks$
|
|
9721
|
+
const { blocks } = processCodeBlocks$4(content, options);
|
|
10111
9722
|
|
|
10112
9723
|
// Check if any processed block is of type 'patch'
|
|
10113
9724
|
for (let i = 0; i < blocks.length; i++) {
|
|
@@ -10135,7 +9746,7 @@ var patchIntegration = {
|
|
|
10135
9746
|
*/
|
|
10136
9747
|
|
|
10137
9748
|
// Dependency on the core block processor
|
|
10138
|
-
const { processCodeBlocks: processCodeBlocks$
|
|
9749
|
+
const { processCodeBlocks: processCodeBlocks$3 } = blockProcessor;
|
|
10139
9750
|
|
|
10140
9751
|
/**
|
|
10141
9752
|
* Detects special code block relationships in a message, such as patches or parent-child links.
|
|
@@ -10169,7 +9780,7 @@ function detectCodeBlockRelationships$2(content, codeBlockService, options = { s
|
|
|
10169
9780
|
|
|
10170
9781
|
|
|
10171
9782
|
// Extract all code blocks using the core processor
|
|
10172
|
-
const { blocks, warnings } = processCodeBlocks$
|
|
9783
|
+
const { blocks, warnings } = processCodeBlocks$3(content, options);
|
|
10173
9784
|
|
|
10174
9785
|
let hasPatch = false;
|
|
10175
9786
|
let hasParentChildRelationship = false;
|
|
@@ -10243,7 +9854,7 @@ function detectIncompleteCodeBlock$2(content, options = { silent: true }) {
|
|
|
10243
9854
|
}
|
|
10244
9855
|
|
|
10245
9856
|
// Use the core processor which already identifies incomplete blocks
|
|
10246
|
-
const { hasIncompleteBlocks, lastIncompleteBlock } = processCodeBlocks$
|
|
9857
|
+
const { hasIncompleteBlocks, lastIncompleteBlock } = processCodeBlocks$3(content, options);
|
|
10247
9858
|
|
|
10248
9859
|
return {
|
|
10249
9860
|
hasIncompleteBlocks,
|
|
@@ -10546,6 +10157,281 @@ Plain text block.
|
|
|
10546
10157
|
// (Removed the check `if (typeof module !== 'undefined' && module.exports)` as it's standard in Node)
|
|
10547
10158
|
var markerRemover = { removeCodeBlockMarkers: removeCodeBlockMarkers$2 };
|
|
10548
10159
|
|
|
10160
|
+
/**
|
|
10161
|
+
* Component: CodeBlockUtils Update Code Block
|
|
10162
|
+
* Block-UUID: 6a7b8c9d-0e1f-42a3-b4c5-d6e7f8a9b0c1
|
|
10163
|
+
* Parent-UUID: 5f9c1e3a-7b2d-4e8f-a1d0-9c4b2e1f8a0b
|
|
10164
|
+
* Version: 1.4.0
|
|
10165
|
+
* Description: Provides functions to update the content of a specific code block within a string, identified by index, UUID, or direct reference.
|
|
10166
|
+
* Language: JavaScript
|
|
10167
|
+
* Created-at: 2025-04-16T00:56:57.352Z
|
|
10168
|
+
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0), Gemini 2.5 Pro (v1.2.0), Gemini 2.5 Pro (v1.3.0), Gemini 2.5 Flash Thinking (v1.4.0)
|
|
10169
|
+
*/
|
|
10170
|
+
|
|
10171
|
+
// Dependencies from other modules within CodeBlockUtils
|
|
10172
|
+
const { findAllCodeFences: findAllCodeFences$2, matchFencesAndExtractBlocks: matchFencesAndExtractBlocks$2, findCodeBlockByUUID: findCodeBlockByUUID$1 } = blockExtractor; // Added findCodeBlockByUUID
|
|
10173
|
+
const { processCodeBlocks: processCodeBlocks$2 } = blockProcessor; // To get parsed block info
|
|
10174
|
+
|
|
10175
|
+
/**
|
|
10176
|
+
* Replaces the content of a code block specified by its index within a message string.
|
|
10177
|
+
*
|
|
10178
|
+
* @param {string} messageContent - The original message string containing code blocks.
|
|
10179
|
+
* @param {number} blockIndex - The 0-based index of the code block to replace.
|
|
10180
|
+
* @param {string} newCodeContent - The new raw content (code, potentially including header) to insert into the block.
|
|
10181
|
+
* @param {string} [language] - Optional: The language identifier for the updated code block fence. If omitted, the original language is preserved.
|
|
10182
|
+
* @returns {string} The message content with the specified code block updated.
|
|
10183
|
+
* @throws {Error} If the blockIndex is out of bounds or if block boundaries cannot be determined.
|
|
10184
|
+
*/
|
|
10185
|
+
function updateCodeBlockByIndex$2(messageContent, blockIndex, newCodeContent, language = undefined) {
|
|
10186
|
+
if (typeof messageContent !== 'string') {
|
|
10187
|
+
throw new Error("messageContent must be a string.");
|
|
10188
|
+
}
|
|
10189
|
+
if (typeof blockIndex !== 'number' || blockIndex < 0) {
|
|
10190
|
+
throw new Error("blockIndex must be a non-negative number.");
|
|
10191
|
+
}
|
|
10192
|
+
if (typeof newCodeContent !== 'string') {
|
|
10193
|
+
// Allow empty string replacement, but not other types
|
|
10194
|
+
throw new Error("newCodeContent must be a string.");
|
|
10195
|
+
}
|
|
10196
|
+
|
|
10197
|
+
// Step 1: Find all fence positions to get accurate start/end of the full block
|
|
10198
|
+
const { openingPositions, closingPositions } = findAllCodeFences$2(messageContent);
|
|
10199
|
+
const { completeBlocks, incompleteBlocks, warnings: extractorWarnings } = matchFencesAndExtractBlocks$2(
|
|
10200
|
+
messageContent, openingPositions, closingPositions
|
|
10201
|
+
);
|
|
10202
|
+
|
|
10203
|
+
// Combine complete and incomplete for indexing, assuming we might want to update an incomplete one too
|
|
10204
|
+
// Note: Replacing content in an incomplete block might be unusual, but technically possible.
|
|
10205
|
+
const allBlocks = [...completeBlocks, ...incompleteBlocks];
|
|
10206
|
+
|
|
10207
|
+
// Step 2: Validate index
|
|
10208
|
+
if (blockIndex >= allBlocks.length) {
|
|
10209
|
+
throw new Error(`blockIndex ${blockIndex} is out of bounds. Found ${allBlocks.length} blocks.`);
|
|
10210
|
+
}
|
|
10211
|
+
|
|
10212
|
+
// Step 3: Get the target block's boundary information
|
|
10213
|
+
const targetBlockBoundaries = allBlocks[blockIndex];
|
|
10214
|
+
const openingFence = targetBlockBoundaries.opening;
|
|
10215
|
+
const closingFence = targetBlockBoundaries.closing; // Will be undefined for incomplete blocks
|
|
10216
|
+
|
|
10217
|
+
if (!openingFence) {
|
|
10218
|
+
// Should not happen if index is valid, but good practice to check
|
|
10219
|
+
throw new Error(`Could not find opening fence for block at index ${blockIndex}.`);
|
|
10220
|
+
}
|
|
10221
|
+
|
|
10222
|
+
// Determine the exact start and end of the full markdown block
|
|
10223
|
+
const blockStartPos = openingFence.position;
|
|
10224
|
+
// If the block is incomplete, the end is the end of the messageContent
|
|
10225
|
+
const blockEndPos = closingFence
|
|
10226
|
+
? closingFence.position + closingFence.length
|
|
10227
|
+
: messageContent.length;
|
|
10228
|
+
|
|
10229
|
+
// Step 4: Construct the replacement block string
|
|
10230
|
+
const targetLanguage = language !== undefined ? language : (openingFence.language || ''); // Use provided language or original/empty
|
|
10231
|
+
const newBlockString = `\`\`\`${targetLanguage}\n${newCodeContent}\n\`\`\``;
|
|
10232
|
+
|
|
10233
|
+
// Step 5: Perform the replacement
|
|
10234
|
+
const updatedMessageContent =
|
|
10235
|
+
messageContent.substring(0, blockStartPos) +
|
|
10236
|
+
newBlockString +
|
|
10237
|
+
messageContent.substring(blockEndPos);
|
|
10238
|
+
|
|
10239
|
+
return updatedMessageContent;
|
|
10240
|
+
}
|
|
10241
|
+
|
|
10242
|
+
/**
|
|
10243
|
+
* Replaces the content of a code block specified by its Block-UUID within a message string.
|
|
10244
|
+
*
|
|
10245
|
+
* @param {string} messageContent - The original message string containing code blocks.
|
|
10246
|
+
* @param {string} blockUUID - The Block-UUID of the code block to replace.
|
|
10247
|
+
* @param {string} newCodeContent - The new raw content (code, potentially including header) to insert into the block.
|
|
10248
|
+
* @param {string} [language] - Optional: The language identifier for the updated code block fence. If omitted, the original language is preserved.
|
|
10249
|
+
* @returns {string} The message content with the specified code block updated.
|
|
10250
|
+
* @throws {Error} If no block with the specified UUID is found, or if multiple blocks have the same UUID.
|
|
10251
|
+
*/
|
|
10252
|
+
function updateCodeBlockByUUID$1(messageContent, blockUUID, newCodeContent, language = undefined) {
|
|
10253
|
+
if (typeof messageContent !== 'string') {
|
|
10254
|
+
throw new Error("messageContent must be a string.");
|
|
10255
|
+
}
|
|
10256
|
+
if (typeof blockUUID !== 'string' || !blockUUID) {
|
|
10257
|
+
throw new Error("blockUUID must be a non-empty string.");
|
|
10258
|
+
}
|
|
10259
|
+
if (typeof newCodeContent !== 'string') {
|
|
10260
|
+
throw new Error("newCodeContent must be a string.");
|
|
10261
|
+
}
|
|
10262
|
+
|
|
10263
|
+
// Step 1: Process blocks to get headers and find the target index
|
|
10264
|
+
const { blocks: processedBlocks, warnings } = processCodeBlocks$2(messageContent, { silent: true });
|
|
10265
|
+
|
|
10266
|
+
let targetIndex = -1;
|
|
10267
|
+
|
|
10268
|
+
for (let i = 0; i < processedBlocks.length; i++) {
|
|
10269
|
+
const block = processedBlocks[i];
|
|
10270
|
+
let match = false;
|
|
10271
|
+
|
|
10272
|
+
// Check standard code blocks by Block-UUID
|
|
10273
|
+
if ((block.type === 'code') && block.header && block.header['Block-UUID'] === blockUUID) {
|
|
10274
|
+
match = true;
|
|
10275
|
+
}
|
|
10276
|
+
// Check patch blocks by Target-Block-UUID
|
|
10277
|
+
else if (block.type === 'patch' && block.metadata && block.metadata['Target-Block-UUID'] === blockUUID) {
|
|
10278
|
+
match = true;
|
|
10279
|
+
}
|
|
10280
|
+
|
|
10281
|
+
if (match) {
|
|
10282
|
+
// If we've already found one, log a warning but still update the first one found.
|
|
10283
|
+
if (targetIndex !== -1) {
|
|
10284
|
+
console.warn(`Multiple blocks found matching UUID: ${blockUUID} (could be Block-UUID or Target-Block-UUID). Updating the first occurrence.`);
|
|
10285
|
+
} else {
|
|
10286
|
+
targetIndex = i;
|
|
10287
|
+
}
|
|
10288
|
+
}
|
|
10289
|
+
}
|
|
10290
|
+
|
|
10291
|
+
// Step 2: Handle findings
|
|
10292
|
+
if (targetIndex === -1) { // Use targetIndex to check if *any* valid match was set
|
|
10293
|
+
throw new Error(`No code or patch block found matching UUID: ${blockUUID} (checked Block-UUID and Target-Block-UUID).`);
|
|
10294
|
+
}
|
|
10295
|
+
// Warning for multiple matches is handled inside the loop now.
|
|
10296
|
+
|
|
10297
|
+
// Step 3: Call the index-based function
|
|
10298
|
+
// We need the index relative to *all* blocks (complete and incomplete), not just processed ones.
|
|
10299
|
+
// Re-extract boundaries to get the correct index mapping.
|
|
10300
|
+
const { openingPositions, closingPositions } = findAllCodeFences$2(messageContent);
|
|
10301
|
+
const { completeBlocks, incompleteBlocks } = matchFencesAndExtractBlocks$2(
|
|
10302
|
+
messageContent, openingPositions, closingPositions
|
|
10303
|
+
);
|
|
10304
|
+
const allBlocks = [...completeBlocks, ...incompleteBlocks];
|
|
10305
|
+
|
|
10306
|
+
// Find the index in the combined list that corresponds to the processed block's position
|
|
10307
|
+
const targetProcessedBlock = processedBlocks[targetIndex];
|
|
10308
|
+
const actualIndex = allBlocks.findIndex(b => b.opening.position === targetProcessedBlock.position);
|
|
10309
|
+
|
|
10310
|
+
if (actualIndex === -1) {
|
|
10311
|
+
// This indicates a discrepancy between blockProcessor and blockExtractor results, which shouldn't happen.
|
|
10312
|
+
throw new Error(`Internal error: Could not map processed block at index ${targetIndex} (matching UUID: ${blockUUID}) back to extracted block boundaries.`);
|
|
10313
|
+
}
|
|
10314
|
+
|
|
10315
|
+
// Pass the optional language parameter down
|
|
10316
|
+
return updateCodeBlockByIndex$2(messageContent, actualIndex, newCodeContent, language);
|
|
10317
|
+
}
|
|
10318
|
+
|
|
10319
|
+
/**
|
|
10320
|
+
* Updates a code block in message text identified by UUID.
|
|
10321
|
+
* (Moved from original PatchUtils)
|
|
10322
|
+
* @param {string} messageText - The original message text
|
|
10323
|
+
* @param {string} blockUUID - The Block-UUID to update
|
|
10324
|
+
* @param {string} newCode - The new code content (raw content, including header if applicable)
|
|
10325
|
+
* @param {string} language - The code language for the fence
|
|
10326
|
+
* @returns {string} Updated message text
|
|
10327
|
+
* @throws {Error} If block not found or parameters missing.
|
|
10328
|
+
*/
|
|
10329
|
+
function updateCodeBlockInMessage$1(messageText, blockUUID, newCode, language) {
|
|
10330
|
+
if (!messageText || !blockUUID || newCode === null || newCode === undefined) { // Allow empty string for newCode
|
|
10331
|
+
throw new Error("Missing required parameters for updating code block (messageText, blockUUID, newCode)");
|
|
10332
|
+
}
|
|
10333
|
+
|
|
10334
|
+
// Use findCodeBlockByUUID from blockExtractor
|
|
10335
|
+
const block = findCodeBlockByUUID$1(messageText, blockUUID);
|
|
10336
|
+
|
|
10337
|
+
if (!block) {
|
|
10338
|
+
throw new Error(`Code block with UUID ${blockUUID} not found`);
|
|
10339
|
+
}
|
|
10340
|
+
|
|
10341
|
+
// Construct the new full block string
|
|
10342
|
+
const newBlockString = '```' + (language || block.language) + '\n' + newCode + '\n```';
|
|
10343
|
+
|
|
10344
|
+
// Replace the old block with the new one using precise indices
|
|
10345
|
+
return messageText.substring(0, block.startIndex) +
|
|
10346
|
+
newBlockString +
|
|
10347
|
+
messageText.substring(block.endIndex);
|
|
10348
|
+
}
|
|
10349
|
+
|
|
10350
|
+
|
|
10351
|
+
/**
|
|
10352
|
+
* Generic router function to update a code block by index or UUID.
|
|
10353
|
+
*
|
|
10354
|
+
* @param {string} messageContent - The original message string.
|
|
10355
|
+
* @param {number|string} identifier - The block index (number) or Block-UUID (string).
|
|
10356
|
+
* @param {string} newCodeContent - The new raw content for the block.
|
|
10357
|
+
* @param {string} [language] - Optional: The language identifier for the updated code block fence.
|
|
10358
|
+
* @returns {string} The updated message content.
|
|
10359
|
+
* @throws {Error} If the identifier type is invalid or if the underlying update function fails.
|
|
10360
|
+
*/
|
|
10361
|
+
function updateCodeBlock$1(messageContent, identifier, newCodeContent, language = undefined) {
|
|
10362
|
+
if (typeof identifier === 'number') {
|
|
10363
|
+
// Pass language to index-based function
|
|
10364
|
+
return updateCodeBlockByIndex$2(messageContent, identifier, newCodeContent, language);
|
|
10365
|
+
} else if (typeof identifier === 'string') {
|
|
10366
|
+
// Pass language to UUID-based function
|
|
10367
|
+
return updateCodeBlockByUUID$1(messageContent, identifier, newCodeContent, language);
|
|
10368
|
+
} else {
|
|
10369
|
+
throw new Error("Invalid identifier type. Must be a number (index) or a string (UUID).");
|
|
10370
|
+
}
|
|
10371
|
+
}
|
|
10372
|
+
|
|
10373
|
+
/**
|
|
10374
|
+
* Deletes a code block specified by its index within a message string.
|
|
10375
|
+
*
|
|
10376
|
+
* @param {string} messageContent - The original message string containing code blocks.
|
|
10377
|
+
* @param {number} blockIndex - The 0-based index of the code block to delete.
|
|
10378
|
+
* @returns {string} The message content with the specified code block deleted.
|
|
10379
|
+
* @throws {Error} If the blockIndex is out of bounds or if block boundaries cannot be determined.
|
|
10380
|
+
*/
|
|
10381
|
+
function deleteCodeBlockByIndex$2(messageContent, blockIndex) {
|
|
10382
|
+
if (typeof messageContent !== 'string') {
|
|
10383
|
+
throw new Error("messageContent must be a string.");
|
|
10384
|
+
}
|
|
10385
|
+
if (typeof blockIndex !== 'number' || blockIndex < 0) {
|
|
10386
|
+
throw new Error("blockIndex must be a non-negative number.");
|
|
10387
|
+
}
|
|
10388
|
+
|
|
10389
|
+
// Step 1: Find all fence positions to get accurate start/end of the full block
|
|
10390
|
+
const { openingPositions, closingPositions } = findAllCodeFences$2(messageContent);
|
|
10391
|
+
const { completeBlocks, incompleteBlocks } = matchFencesAndExtractBlocks$2(
|
|
10392
|
+
messageContent, openingPositions, closingPositions
|
|
10393
|
+
);
|
|
10394
|
+
|
|
10395
|
+
// Combine complete and incomplete for indexing
|
|
10396
|
+
const allBlocks = [...completeBlocks, ...incompleteBlocks];
|
|
10397
|
+
|
|
10398
|
+
// Step 2: Validate index
|
|
10399
|
+
if (blockIndex >= allBlocks.length) {
|
|
10400
|
+
throw new Error(`blockIndex ${blockIndex} is out of bounds. Found ${allBlocks.length} blocks.`);
|
|
10401
|
+
}
|
|
10402
|
+
|
|
10403
|
+
// Step 3: Get the target block's boundary information
|
|
10404
|
+
const targetBlockBoundaries = allBlocks[blockIndex];
|
|
10405
|
+
const openingFence = targetBlockBoundaries.opening;
|
|
10406
|
+
const closingFence = targetBlockBoundaries.closing; // Will be undefined for incomplete blocks
|
|
10407
|
+
|
|
10408
|
+
if (!openingFence) {
|
|
10409
|
+
// Should not happen if index is valid, but good practice to check
|
|
10410
|
+
throw new Error(`Could not find opening fence for block at index ${blockIndex}.`);
|
|
10411
|
+
}
|
|
10412
|
+
|
|
10413
|
+
// Determine the exact start and end of the full markdown block
|
|
10414
|
+
const blockStartPos = openingFence.position;
|
|
10415
|
+
// If the block is incomplete, the end is the end of the messageContent
|
|
10416
|
+
const blockEndPos = closingFence
|
|
10417
|
+
? closingFence.position + closingFence.length
|
|
10418
|
+
: messageContent.length;
|
|
10419
|
+
|
|
10420
|
+
// Step 4: Perform the deletion
|
|
10421
|
+
const updatedMessageContent =
|
|
10422
|
+
messageContent.substring(0, blockStartPos) +
|
|
10423
|
+
messageContent.substring(blockEndPos);
|
|
10424
|
+
|
|
10425
|
+
return updatedMessageContent;
|
|
10426
|
+
}
|
|
10427
|
+
|
|
10428
|
+
var updateCodeBlock_1 = {
|
|
10429
|
+
updateCodeBlockByIndex: updateCodeBlockByIndex$2,
|
|
10430
|
+
updateCodeBlockByUUID: updateCodeBlockByUUID$1,
|
|
10431
|
+
updateCodeBlock: updateCodeBlock$1,
|
|
10432
|
+
updateCodeBlockInMessage: updateCodeBlockInMessage$1,
|
|
10433
|
+
deleteCodeBlockByIndex: deleteCodeBlockByIndex$2};
|
|
10434
|
+
|
|
10549
10435
|
/**
|
|
10550
10436
|
* Component: CodeBlockUtils Index
|
|
10551
10437
|
* Block-UUID: 7e9d3f8a-1b2c-4d5e-8f9a-0123456789ab
|
|
@@ -10562,17 +10448,17 @@ const { COMMENT_STYLES: COMMENT_STYLES$1 } = constants$2;
|
|
|
10562
10448
|
const { generateUUID: generateUUID$1, validateUUID: validateUUID$1 } = uuidUtils;
|
|
10563
10449
|
const { isValidISOTimestamp: isValidISOTimestamp$1, parseHeader: parseHeader$1, getHeaderLineCount } = headerUtils;
|
|
10564
10450
|
const { findAllCodeFences: findAllCodeFences$1, matchFencesAndExtractBlocks: matchFencesAndExtractBlocks$1, extractCodeBlocksWithUUIDs, findCodeBlockByUUID } = blockExtractor;
|
|
10565
|
-
const { processCodeBlocks: processCodeBlocks$1, extractCodeBlocks: extractCodeBlocks$1, fixTextCodeBlocks: fixTextCodeBlocks$1 } =
|
|
10451
|
+
const { processCodeBlocks: processCodeBlocks$1, extractCodeBlocks: extractCodeBlocks$1, fixTextCodeBlocks: fixTextCodeBlocks$1 } = blockProcessor;
|
|
10566
10452
|
const { containsPatch: containsPatch$1 } = patchIntegration;
|
|
10567
10453
|
const { detectCodeBlockRelationships: detectCodeBlockRelationships$1, detectIncompleteCodeBlock: detectIncompleteCodeBlock$1, extractFilePaths: extractFilePaths$1 } = relationshipUtils;
|
|
10568
10454
|
const { extractContinuationInfo: extractContinuationInfo$1, generateContinuationPrompt: generateContinuationPrompt$1 } = continuationUtils;
|
|
10569
10455
|
const { parseCodeBlocks: parseCommentDelimitedBlocks$1 } = headerParser;
|
|
10570
10456
|
const { removeCodeBlockMarkers: removeCodeBlockMarkers$1 } = markerRemover;
|
|
10571
|
-
const { updateCodeBlockByIndex: updateCodeBlockByIndex$1, updateCodeBlockByUUID, updateCodeBlock, updateCodeBlockInMessage, deleteCodeBlockByIndex: deleteCodeBlockByIndex$1 } =
|
|
10457
|
+
const { updateCodeBlockByIndex: updateCodeBlockByIndex$1, updateCodeBlockByUUID, updateCodeBlock, updateCodeBlockInMessage, deleteCodeBlockByIndex: deleteCodeBlockByIndex$1 } = updateCodeBlock_1;
|
|
10572
10458
|
const { formatWithLineNumbers: formatWithLineNumbers$1, formatBlockWithLineNumbers: formatBlockWithLineNumbers$1, formatBlocksWithLineNumbers: formatBlocksWithLineNumbers$1, removeLineNumbers: removeLineNumbers$1 } = lineNumberFormatter;
|
|
10573
10459
|
|
|
10574
10460
|
// Export all imported items
|
|
10575
|
-
var CodeBlockUtils$
|
|
10461
|
+
var CodeBlockUtils$5 = {
|
|
10576
10462
|
// Constants
|
|
10577
10463
|
COMMENT_STYLES: COMMENT_STYLES$1,
|
|
10578
10464
|
|
|
@@ -10639,7 +10525,7 @@ var CodeBlockUtils$4 = {
|
|
|
10639
10525
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0), Gemini 2.5 Flash (v1.1.0)
|
|
10640
10526
|
*/
|
|
10641
10527
|
|
|
10642
|
-
const CodeBlockUtils$
|
|
10528
|
+
const CodeBlockUtils$4 = CodeBlockUtils$5;
|
|
10643
10529
|
const MessageUtils$2 = MessageUtils$3;
|
|
10644
10530
|
|
|
10645
10531
|
/**
|
|
@@ -10778,7 +10664,7 @@ function parseContextSection$1(sectionText) {
|
|
|
10778
10664
|
}
|
|
10779
10665
|
});
|
|
10780
10666
|
|
|
10781
|
-
const { blocks, warnings } = CodeBlockUtils$
|
|
10667
|
+
const { blocks, warnings } = CodeBlockUtils$4.extractCodeBlocks(sectionText, { silent: true });
|
|
10782
10668
|
const codeBlocks = blocks.filter(block => block.type === 'code');
|
|
10783
10669
|
|
|
10784
10670
|
if (codeBlocks.length === 0) {
|
|
@@ -11044,8 +10930,8 @@ var constants = {
|
|
|
11044
10930
|
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
11045
10931
|
*/
|
|
11046
10932
|
|
|
11047
|
-
const CodeBlockUtils$
|
|
11048
|
-
const GSToolBlockUtils$1 =
|
|
10933
|
+
const CodeBlockUtils$3 = CodeBlockUtils$5;
|
|
10934
|
+
const GSToolBlockUtils$1 = GSToolBlockUtils$3;
|
|
11049
10935
|
const JsonUtils$1 = JsonUtils$2;
|
|
11050
10936
|
const { ANALYZE_HEADER_PREFIX } = constants;
|
|
11051
10937
|
|
|
@@ -11061,7 +10947,7 @@ const { ANALYZE_HEADER_PREFIX } = constants;
|
|
|
11061
10947
|
*/
|
|
11062
10948
|
function processLLMAnalysisResponse$2(messageContent, stoppedStreaming) {
|
|
11063
10949
|
const silent = { silent: true };
|
|
11064
|
-
const { blocks, warnings } = CodeBlockUtils$
|
|
10950
|
+
const { blocks, warnings } = CodeBlockUtils$3.extractCodeBlocks(messageContent, silent);
|
|
11065
10951
|
|
|
11066
10952
|
const analysisBlocks = [];
|
|
11067
10953
|
const analysisMetadataBlocks = [];
|
|
@@ -11174,7 +11060,7 @@ var responseProcessor = {
|
|
|
11174
11060
|
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
11175
11061
|
*/
|
|
11176
11062
|
|
|
11177
|
-
const AnalysisBlockUtils$1 = AnalysisBlockUtils$
|
|
11063
|
+
const AnalysisBlockUtils$1 = AnalysisBlockUtils$3;
|
|
11178
11064
|
|
|
11179
11065
|
/**
|
|
11180
11066
|
* Validates the extracted analysis blocks and their metadata.
|
|
@@ -11318,6 +11204,7 @@ var instructionLoader = {
|
|
|
11318
11204
|
const fs$6 = require$$0.promises;
|
|
11319
11205
|
const path$4 = require$$1;
|
|
11320
11206
|
const { getAnalyzerInstructionsContent: getAnalyzerInstructionsContent$2 } = instructionLoader;
|
|
11207
|
+
const CodeBlockUtils$2 = CodeBlockUtils$5;
|
|
11321
11208
|
|
|
11322
11209
|
/**
|
|
11323
11210
|
* Reads and parses the config.json file in a directory.
|
|
@@ -11415,10 +11302,21 @@ async function getAnalyzers$2(analyzeMessagesBasePath, options = {}) {
|
|
|
11415
11302
|
const analyzerId = `${analyzerName}::${contentType}::${instructionsType}`;
|
|
11416
11303
|
const analyzerFullLabel = `${analyzerLabel} (${contentLabel} - ${instructionsLabel})`;
|
|
11417
11304
|
|
|
11418
|
-
let
|
|
11305
|
+
let description = null;
|
|
11419
11306
|
if (includeDescription) {
|
|
11420
11307
|
try {
|
|
11421
|
-
|
|
11308
|
+
const content = await getAnalyzerInstructionsContent$2(analyzeMessagesBasePath, analyzerId);
|
|
11309
|
+
const { blocks, warnings } = CodeBlockUtils$2.extractCodeBlocks(content, { silent: true });
|
|
11310
|
+
const jsonBlock = blocks.find(block => block.language === 'json');
|
|
11311
|
+
|
|
11312
|
+
if (jsonBlock && jsonBlock.content) {
|
|
11313
|
+
try {
|
|
11314
|
+
const json = JSON.parse(jsonBlock.content);
|
|
11315
|
+
description = json.description;
|
|
11316
|
+
} catch(error) {
|
|
11317
|
+
console.warn(`${analyzerId} contains an invalid JSON`);
|
|
11318
|
+
}
|
|
11319
|
+
}
|
|
11422
11320
|
} catch (descError) {
|
|
11423
11321
|
console.warn(`Warning: Could not load description for ${analyzerId}: ${descError.message}`);
|
|
11424
11322
|
descriptionContent = null;
|
|
@@ -11430,7 +11328,7 @@ async function getAnalyzers$2(analyzeMessagesBasePath, options = {}) {
|
|
|
11430
11328
|
label: analyzerFullLabel,
|
|
11431
11329
|
name: analyzerName,
|
|
11432
11330
|
protected: analyzerConfig?.protected || false,
|
|
11433
|
-
|
|
11331
|
+
description
|
|
11434
11332
|
});
|
|
11435
11333
|
} catch (error) {
|
|
11436
11334
|
// If 1.md doesn't exist, this is not a complete analyzer configuration, skip.
|
|
@@ -11603,7 +11501,7 @@ var saver = {
|
|
|
11603
11501
|
|
|
11604
11502
|
const fs$4 = require$$0.promises;
|
|
11605
11503
|
const path$2 = require$$1;
|
|
11606
|
-
const CodeBlockUtils$1 = CodeBlockUtils$
|
|
11504
|
+
const CodeBlockUtils$1 = CodeBlockUtils$5;
|
|
11607
11505
|
|
|
11608
11506
|
/**
|
|
11609
11507
|
* Deduces the JSON schema type and format/items from a string value pattern.
|
|
@@ -12232,13 +12130,13 @@ var EnvUtils$1 = {
|
|
|
12232
12130
|
*/
|
|
12233
12131
|
|
|
12234
12132
|
const ChatUtils = ChatUtils$1;
|
|
12235
|
-
const CodeBlockUtils = CodeBlockUtils$
|
|
12133
|
+
const CodeBlockUtils = CodeBlockUtils$5;
|
|
12236
12134
|
const ContextUtils = ContextUtils$2;
|
|
12237
12135
|
const MessageUtils = MessageUtils$3;
|
|
12238
|
-
const AnalysisBlockUtils = AnalysisBlockUtils$
|
|
12136
|
+
const AnalysisBlockUtils = AnalysisBlockUtils$3;
|
|
12239
12137
|
const AnalyzerUtils = AnalyzerUtils$1;
|
|
12240
|
-
const PatchUtils = PatchUtils$
|
|
12241
|
-
const GSToolBlockUtils =
|
|
12138
|
+
const PatchUtils = PatchUtils$2;
|
|
12139
|
+
const GSToolBlockUtils = GSToolBlockUtils$3;
|
|
12242
12140
|
const LLMUtils = LLMUtils$1;
|
|
12243
12141
|
const JsonUtils = JsonUtils$2;
|
|
12244
12142
|
const ConfigUtils = ConfigUtils$1;
|