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