@gitsense/gsc-utils 0.2.21 → 0.2.24

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/README.md ADDED
@@ -0,0 +1,432 @@
1
+ # GitSense Chat Utils (gsc-utils)
2
+
3
+ A comprehensive JavaScript library providing utilities for processing, manipulating, and managing various elements within GitSense Chat messages, including code blocks, patches, analyzers, and context data.
4
+
5
+ ## Code Structure
6
+
7
+ ```txt
8
+ .
9
+ ├── LICENSE
10
+ ├── README.md
11
+ ├── package-lock.json
12
+ ├── package.json
13
+ ├── rollup.config.js
14
+ ├── src
15
+ │   ├── AnalysisBlockUtils.js
16
+ │   ├── AnalyzerUtils
17
+ │   │   ├── constants.js
18
+ │   │   ├── contextMapper.js
19
+ │   │   ├── dataValidator.js
20
+ │   │   ├── defaultPromptLoader.js
21
+ │   │   ├── discovery.js
22
+ │   │   ├── index.js
23
+ │   │   ├── instructionLoader.js
24
+ │   │   ├── management.js
25
+ │   │   ├── responseProcessor.js
26
+ │   │   ├── saver.js
27
+ │   │   └── schemaLoader.js
28
+ │   ├── ChatUtils.js
29
+ │   ├── CodeBlockUtils
30
+ │   │   ├── blockExtractor.js
31
+ │   │   ├── blockProcessor.js
32
+ │   │   ├── constants.js
33
+ │   │   ├── continuationUtils.js
34
+ │   │   ├── headerParser.js
35
+ │   │   ├── headerUtils.js
36
+ │   │   ├── index.js
37
+ │   │   ├── lineNumberFormatter.js
38
+ │   │   ├── markerRemover.js
39
+ │   │   ├── patchIntegration.js
40
+ │   │   ├── relationshipUtils.js
41
+ │   │   ├── updateCodeBlock.js
42
+ │   │   └── uuidUtils.js
43
+ │   ├── ConfigUtils.js
44
+ │   ├── ContextUtils.js
45
+ │   ├── EnvUtils.js
46
+ │   ├── GSToolBlockUtils.js
47
+ │   ├── GitSenseChatUtils.js
48
+ │   ├── JsonUtils.js
49
+ │   ├── LLMUtils.js
50
+ │   ├── MessageUtils.js
51
+ │   ├── PatchUtils
52
+ │   │   ├── constants.js
53
+ │   │   ├── diagnosticReporter.js
54
+ │   │   ├── enhancedPatchProcessor.js
55
+ │   │   ├── fuzzyMatcher.js
56
+ │   │   ├── hunkCorrector.js
57
+ │   │   ├── hunkValidator.js
58
+ │   │   ├── index.js
59
+ │   │   ├── patchExtractor.js
60
+ │   │   ├── patchHeaderFormatter.js
61
+ │   │   ├── patchParser.js
62
+ │   │   ├── patchProcessor.js
63
+ │   │   └── patchVerifier
64
+ │   │   ├── constants.js
65
+ │   │   ├── detectAndFixOverlappingHunks.js
66
+ │   │   ├── detectAndFixRedundantChanges.js
67
+ │   │   ├── formatAndAddLineNumbers.js
68
+ │   │   ├── index.js
69
+ │   │   ├── verifyAndCorrectHunkHeaders.js
70
+ │   │   └── verifyAndCorrectLineNumbers.js
71
+ │   └── SharedUtils
72
+ │   ├── timestampUtils.js
73
+ │   └── versionUtils.js
74
+ ```
75
+
76
+ ## Core Modules
77
+
78
+ ### GitSenseChatUtils (Main Interface)
79
+
80
+ This is the primary class exported by the library, offering a unified API for interacting with the various utility modules. It aggregates functionalities from `CodeBlockUtils`, `PatchUtils`, `AnalyzerUtils`, `MessageUtils`, `LLMUtils`, `ConfigUtils`, and `EnvUtils`.
81
+
82
+ ### CodeBlockUtils
83
+
84
+ Provides a comprehensive suite of utilities for processing, manipulating, and managing code blocks within GitSense Chat messages. These utilities handle various aspects of the code block lifecycle, including extraction, header parsing, UUID management, patch detection, and continuation handling.
85
+
86
+ #### Core Functions
87
+
88
+ * **`processCodeBlocks(text, options)`**: The primary function for processing code blocks. It identifies code blocks within text using markdown fences, parses their headers or content, detects block types (code, patch, gs-tool, gitsense-search-flow, analysis), and extracts relevant metadata. It returns detailed information about each block, including any warnings encountered during processing.
89
+ * **`extractCodeBlocks(text, options)`**: A simplified API wrapper around `processCodeBlocks` that returns only the extracted blocks and warnings, suitable for basic code block identification needs.
90
+ * **`fixTextCodeBlocks(text)`**: Scans text for code blocks with invalid UUIDs and automatically corrects them by generating new valid UUID v4 strings.
91
+
92
+ #### Block Extraction
93
+
94
+ * **`findAllCodeFences(text)`**: Identifies the positions of all opening and closing markdown code fences (\`\`\`) within a given text.
95
+ * **`matchFencesAndExtractBlocks(text, openingPositions, closingPositions)`**: Matches identified opening and closing fences to determine complete and incomplete code blocks, providing warnings for potentially malformed structures.
96
+ * **`extractCodeBlocksWithUUIDs(messageText)`**: Finds all code blocks in a message and attempts to extract their `Block-UUID` from the content.
97
+ * **`findCodeBlockByUUID(messageText, blockUUID)`**: Locates a specific code block within a message by its `Block-UUID`.
98
+
99
+ #### Header Utilities
100
+
101
+ * **`parseHeader(header, language)`**: Parses the metadata header from a code block's content based on its programming language, extracting fields like `Component`, `Block-UUID`, `Version`, `Description`, `Language`, `Created-at`, and `Authors`.
102
+ * **`isValidISOTimestamp(timestamp)`**: Validates if a string conforms to the ISO 8601 timestamp format.
103
+ * **`getHeaderLineCount(headerText, language)`**: Calculates the total number of lines a code block's header occupies, including comment delimiters and the two mandatory blank lines that follow it.
104
+
105
+ #### UUID Utilities
106
+
107
+ * **`generateUUID()`**: Generates a new valid RFC 4122 UUID v4 string.
108
+ * **`validateUUID(uuid)`**: Validates a UUID string and returns an object indicating its validity and a corrected UUID if the original was invalid.
109
+
110
+ #### Patch Integration
111
+
112
+ * **`containsPatch(content)`**: Checks if the provided text content contains at least one patch block.
113
+
114
+ #### Relationship & Context Utilities
115
+
116
+ * **`detectCodeBlockRelationships(content, codeBlockService, options)`**: Detects special relationships between code blocks, such as patches or parent-child links, using an optional `codeBlockService` to verify parent UUID existence.
117
+ * **`detectIncompleteCodeBlock(content, options)`**: Identifies if a message contains an incomplete code block and returns information about the last one found.
118
+ * **`extractFilePaths(messageText)`**: Extracts file paths from specially formatted lines in a message (e.g., `#### File: \`path/to/file.ext\``).
119
+
120
+ #### Continuation Utilities
121
+
122
+ * **`extractContinuationInfo(content, partNumber, language, header)`**: Extracts context information from an incomplete block's content to assist in generating prompts for continuation.
123
+ * **`generateContinuationPrompt(incompleteBlock, isLastPart)`**: Generates a structured prompt for continuing an incomplete code block, including instructions for metadata preservation and format.
124
+
125
+ #### Comment-Delimited Header Parsing
126
+
127
+ * **`parseCommentDelimitedBlocks(input)`**: Parses code blocks where metadata headers are enclosed in language-specific comment delimiters (e.g., `/** ... */`, `""" ... """`) rather than markdown fences.
128
+
129
+ #### Marker Removal
130
+
131
+ * **`removeCodeBlockMarkers(markdownText)`**: Removes custom `--- CODE BLOCK START ---` and `--- CODE BLOCK COMPLETE ---` markers surrounding markdown code blocks, but only when both markers are present for a given block.
132
+
133
+ #### Code Block Updating
134
+
135
+ * **`updateCodeBlock(messageContent, identifier, newCodeContent, language)`**: A generic router function to update a code block's content by either its index or `Block-UUID`.
136
+ * **`updateCodeBlockByIndex(messageContent, blockIndex, newCodeContent, language)`**: Replaces the content of a code block specified by its index within a message.
137
+ * **`updateCodeBlockByUUID(messageContent, blockUUID, newCodeContent, language)`**: Replaces the content of a code block specified by its `Block-UUID`.
138
+ * **`updateCodeBlockInMessage(messageText, blockUUID, newCode, language)`**: Updates a code block in message text identified by UUID (moved from original PatchUtils).
139
+ * **`deleteCodeBlock(messageContent, identifier)`**: A generic router function to delete a code block by either its index or `Block-UUID`.
140
+ * **`deleteCodeBlockByIndex(messageContent, blockIndex)`**: Deletes a code block specified by its index within a message.
141
+ * **`deleteCodeBlockByUUID(messageContent, blockUUID)`**: Deletes a code block specified by its `Block-UUID`.
142
+
143
+ #### Line Number Formatting
144
+
145
+ * **`formatWithLineNumbers(codeContent, startLine, paddingWidth)`**: Formats raw code content by adding padded line numbers to each line.
146
+ * **`formatBlockWithLineNumbers(block, startLine, paddingWidth)`**: Formats a processed code block object by adding line numbers to its content.
147
+ * **`formatBlocksWithLineNumbers(blocks, startLine, paddingWidth)`**: Formats an array of processed code block objects with line numbers.
148
+ * **`removeLineNumbers(formattedContent)`**: Removes line number prefixes from formatted code content.
149
+
150
+ #### Constants
151
+
152
+ * **`COMMENT_STYLES`**: Defines comment styles for various programming languages, used by `parseHeader` to correctly interpret header delimiters.
153
+
154
+ ### PatchUtils
155
+
156
+ Provides a comprehensive suite of utilities for handling, validating, applying, and correcting patches within GitSense Chat. These utilities are designed to work with the traditional unified diff format and offer enhanced diagnostics and fuzzy matching capabilities to improve patch reliability.
157
+
158
+ #### Core Patch Processing
159
+
160
+ * **`applyPatch(sourceText, patchText)`**: Applies a traditional unified diff patch to source code. It cleans line numbers from the patch content before using the `jsdiff` library for application.
161
+ * **`createPatch(sourceText, targetCode, metadata, filename)`**: Generates a patch in traditional unified diff format between two versions of code, incorporating the specified metadata and adding line number prefixes to the diff content lines.
162
+ * **`createPatchFromCodeBlocks(sourceCodeBlockText, targetCodeBlockText, patchMetadata)`**: Creates a patch between two full code block strings (including their metadata headers), adjusting hunk line numbers to account for the original code block's header.
163
+
164
+ #### Enhanced Patch Processing & Validation
165
+
166
+ * **`applyPatchWithDiagnostics(sourceText, patchText)`**: Applies a patch with detailed per-hunk diagnostics, including validation, fuzzy matching for misplaced hunks, and correction suggestions. Returns a comprehensive result object with success status, patched text, and diagnostic reports.
167
+ * **`validatePatch(sourceText, patchText)`**: Validates a patch without applying it, providing detailed diagnostics and identifying if invalid hunks can be corrected using fuzzy matching.
168
+ * **`applyHunk(sourceText, hunkText)`**: Applies a single hunk to source code, including validation and optional fuzzy matching for correction.
169
+
170
+ #### Patch Parsing & Metadata Handling
171
+
172
+ * **`determinePatchFormat(patchText)`**: Determines the patch format (e.g., 'traditional') based on the presence of specific markers.
173
+ * **`extractPatchMetadata(patchText)`**: Extracts metadata fields from a patch block's header.
174
+ * **`validatePatchMetadata(metadata)`**: Validates patch metadata for required fields (`Source-Block-UUID`, `Target-Block-UUID`, `Source-Version`, `Target-Version`, `Description`, `Authors`) and correct version/UUID formats.
175
+ * **`extractPatchContent(patchText, format)`**: Extracts the raw unified diff content from between the patch start and end markers.
176
+ * **`isPatchBlock(codeBlockContent)`**: Determines if a code block's content represents a patch by checking for the mandatory `# Patch Metadata` header.
177
+ * **`detectPatch(messageText)`**: Finds the first valid patch block within a larger message text.
178
+ * **`findAllPatches(messageText)`**: Finds all valid patch blocks within a message text.
179
+
180
+ #### Header Formatting
181
+
182
+ * **`formatCodeBlockHeader(sourceBlockInfo, patchBlock)`**: Formats the metadata header for a new code block based on source information and patch metadata, following GitSense Chat's inheritance rules.
183
+
184
+ #### Hunk Validation
185
+
186
+ * **`parseHunk(hunkText)`**: Parses a hunk into its components (header, context lines, added lines, removed lines).
187
+ * **`parseHunkHeader(header)`**: Parses a hunk header (`@@ ... @@`) into its constituent parts (old start/count, new start/count).
188
+ * **`validateHunk(sourceCode, hunkText)`**: Validates a single hunk against source code, attempting direct application and fuzzy matching for corrections.
189
+ * **`validateHunks(sourceCode, hunks)`**: Validates all hunks in a patch against the source code.
190
+
191
+ #### Fuzzy Matching
192
+
193
+ * **`findBestContextMatch(contextLines, sourceCode, options)`**: Finds the best match for context lines within source code using similarity scoring.
194
+ * **`findExactLineMatches(contextLine, sourceCode)`**: Finds exact matches for a single context line within the source code.
195
+ * **`findBestMatchWithSlidingWindow(contextLines, sourceCode, windowSize)`**: Finds the best match using a sliding window approach for longer context blocks.
196
+
197
+ #### Hunk Correction
198
+
199
+ * **`recalculateHunkHeader(matchPosition, contextLines, addedLines, removedLines)`**: Recalculates a hunk header based on the matched position and content.
200
+ * **`reconstructHunk(header, contextLines, addedLines, removedLines)`**: Reconstructs a hunk with the corrected header.
201
+ * **`generateCorrectedHunk(originalHunk, matchResult)`**: Generates a corrected hunk based on fuzzy matching results.
202
+ * **`preserveHunkStructure(originalHunkText, correctedHeader)`**: Preserves the original structure of a hunk while updating its header.
203
+ * **`generateHunkCorrection(hunkValidation, matchResult)`**: Generates a corrected version of a problematic hunk with an explanation.
204
+
205
+ #### Diagnostic Reporting
206
+
207
+ * **`generateHumanReadableDiagnostics(hunkResults)`**: Generates a human-readable diagnostic report summarizing the validation status of all hunks in a patch.
208
+ * **`generateLLMFeedback(hunkResults)`**: Generates structured feedback about patch validation for consumption by LLMs.
209
+ * **`describeHunkResult(hunkResult)`**: Generates a human-readable description of a single hunk's validation result.
210
+ * **`formatHunkResultForLLM(hunkResult)`**: Formats a single hunk's validation result for LLM consumption.
211
+ * **`formatDiagnosticSummary(patchResult)`**: Formats a diagnostic summary for the entire patch application or validation result.
212
+ * **`generateErrorMessage(patchResult)`**: Generates a concise error message for a failed patch application or validation.
213
+
214
+ #### Patch Verification
215
+
216
+ * **`verifyAndCorrectLineNumbers(patchText, sourceText, windowSize)`**: Verifies and corrects the `NNN:` line number prefixes on context and deletion lines within a patch by comparing their content against the original source code within a sliding window.
217
+ * **`verifyAndCorrectHunkHeaders(patchText)`**: Verifies and corrects the hunk headers (`@@ -old,count +new,count @@`) within a patch based on the line number prefixes found in the hunk's content lines.
218
+ * **`formatAndAddLineNumbers(patchText, sourceText)`**: Ensures patch content lines have `NNN:` line number prefixes with consistent padding, adding them if missing.
219
+ * **`detectAndFixRedundantChanges(patchText, autoFix)`**: Detects and optionally fixes redundant changes in a patch where content is deleted and re-added identically.
220
+ * **`detectAndFixOverlappingHunks(patchText, autoFix)`**: Detects and optionally fixes overlapping hunks in a patch file by merging them.
221
+
222
+ #### Constants
223
+
224
+ * **`CONTENT_LINE_REGEX`**: Regex to parse context/deletion/addition lines with line numbers.
225
+ * **`HUNK_HEADER_REGEX`**: Regex to parse hunk headers.
226
+ * **`LINE_NUMBER_PREFIX_REGEX`**: Regex to detect line number prefixes.
227
+ * **`FUZZY_MATCH_THRESHOLD`**: Minimum confidence threshold for fuzzy matching.
228
+ * **`MAX_ALTERNATIVE_MATCHES`**: Maximum number of alternative matches to consider.
229
+ * **`DEFAULT_SLIDING_WINDOW_SIZE`**: Default sliding window size for fuzzy matching.
230
+ * **`MAX_CONTEXT_LINES_FOR_DIRECT_MATCH`**: Maximum context lines to use for direct matching before switching to sliding window.
231
+ * **`PATCH_START_MARKER`**: The start marker for patch content (`# --- PATCH START MARKER ---`).
232
+ * **`PATCH_END_MARKER`**: The end marker for patch content (`# --- PATCH END MARKER ---`).
233
+ * **`PATCH_METADATA_HEADER`**: The patch metadata header (`# Patch Metadata`).
234
+ * **`REQUIRED_METADATA_FIELDS`**: List of required metadata fields for a patch.
235
+ * **`ORIGINAL_FILE_HEADER`**: The header for the original file in the diff (`--- Original`).
236
+ * **`MODIFIED_FILE_HEADER`**: The header for the modified file in the diff (`+++ Modified`).
237
+
238
+ ### AnalyzerUtils
239
+
240
+ Provides a suite of utilities for managing and interacting with GitSense Chat analyzers. Analyzers are specialized message templates used by the GitSense Chat system to process and analyze code context.
241
+
242
+ #### Core Functions
243
+
244
+ * **`getAnalyzers(basePath, options)`**: Discovers and lists all available analyzers by traversing the directory structure under `basePath`. An analyzer is considered valid if its corresponding `1.md` instruction file exists. The `options` parameter can include `includeDescription` to optionally load the analyzer's description from its JSON metadata.
245
+ * **`getAnalyzerSchema(basePath, analyzerId)`**: Retrieves the JSON schema for a specific analyzer identified by `analyzerId`. It reads the corresponding `1.md` file, extracts the JSON block, and deduces schema types from the metadata fields.
246
+ * **`getAnalyzerInstructionsContent(basePath, analyzerId)`**: Loads the raw Markdown content of a specific analyzer's `1.md` instruction file based on its `analyzerId`.
247
+ * **`saveConfiguration(basePath, analyzerId, instructionsContent, options)`**: Saves or updates an analyzer configuration. It parses the `analyzerId` to determine the directory structure, creates directories if necessary, and saves the `instructionsContent` to `1.md`. It can optionally ensure `config.json` files exist in the analyzer, content, and instructions directories.
248
+ * **`deleteAnalyzer(basePath, analyzerId)`**: Deletes a specific analyzer configuration and intelligently cleans up empty directories. It checks for protection at all levels (analyzer, content type, instructions type) before deletion.
249
+ * **`buildChatIdToPathMap(allMessages)`**: Builds a map of chat IDs to file paths from the context messages within a chat, which is crucial for validating LLM-generated analysis metadata.
250
+ * **`processLLMAnalysisResponse(messageContent, stoppedStreaming)`**: Extracts code blocks from LLM message content, identifies analysis and metadata blocks, and performs initial validation.
251
+
252
+ #### Default Prompt Loading
253
+
254
+ * **`getSystemMessageContent(basePath)`**: Retrieves the raw Markdown content of the shared system message (`_shared/system/1.md`).
255
+ * **`getStartMessageContent(basePath)`**: Retrieves the raw Markdown content of the shared start message (`_shared/start/1.md`).
256
+
257
+ #### Helper Functions
258
+
259
+ * **`readConfig(dirPath)`**: Reads and parses the `config.json` file in a directory.
260
+ * **`isValidDirName(name)`**: Checks if a directory name is valid according to GitSense Chat rules.
261
+ * **`ensureConfigJson(dirPath, label)`**: Ensures a `config.json` file exists in the given directory with a specified label.
262
+
263
+ #### Constants
264
+
265
+ * **`ANALYZE_HEADER_PREFIX`**: Defines the standard header prefix used in analysis blocks (`# GitSense Chat Analysis`).
266
+
267
+ ### MessageUtils
268
+
269
+ Provides utility functions for processing message files, including context message detection and chat tree navigation.
270
+
271
+ #### Core Functions
272
+
273
+ * **`getChatTemplateMessages(dirname, messageType)`**: Gets template messages from a specific message type directory (e.g., 'notes', 'draft'), parsing metadata to determine message role and content.
274
+ * **`getMessagesBeforeId(model, message, stopId, messages)`**: Gets a list of messages in a chat tree up to a specific message ID.
275
+ * **`getMessageById(chatOrMessage, id)`**: Gets a specific message by its ID from a chat tree using an iterative approach to avoid deep recursion.
276
+ * **`getLastMessage(message)`**: Gets the last message in a specific conversation thread (follows the first child path).
277
+ * **`findMessages(rootNode, filterFn)`**: Recursively finds all messages in a chat tree that match a given filter function, using an iterative approach with a stack.
278
+ * **`deleteMessagesByIds(rootNode, idsToDeleteArray)`**: Deletes messages by their IDs from a nested chat structure, re-parenting their children.
279
+ * **`getMessageContentType(messageContent)`**: Determines the type of message content based on specific prefixes (overview, file content, analyze, regular).
280
+ * **`isContextMessage(messageContent)`**: Checks if a message is a context message (overview or file content).
281
+ * **`isContextItemsOverviewMessage(messageContent)`**: Checks if a message is a context items overview message.
282
+ * **`isAnalyzeMessage(messageContent)`**: Checks if a message is an analyze message.
283
+ * **`isNewAnalyzerInstructionsMessage(messageContent, strict)`**: Checks if a message is the final "New Analyzer Instructions" message.
284
+ * **`parseAnalyzeMessage(messageContent)`**: Parses the unique analyzer ID from an analyze message.
285
+
286
+ ### ConfigUtils
287
+
288
+ Provides utility functions for loading and accessing application configuration from `data/chats.json`.
289
+
290
+ #### Core Functions
291
+
292
+ * **`loadConfig(filePath)`**: Asynchronously loads and parses the application configuration from the specified JSON file path, handling errors appropriately.
293
+ * **`getProviderConfig(config, providerName)`**: Retrieves the configuration object for a specific LLM provider (e.g., "Google", "Anthropic") from the loaded configuration data.
294
+ * **`getModelProviderDetails(config, modelName, providerName)`**: Finds the specific details (like `modelId` and `maxOutputTokens`) for a given user-friendly `modelName` associated with a specific `providerName` within the configuration.
295
+ * **`getApiKeyName(config, providerName)`**: Retrieves the name of the environment variable (e.g., "GEMINI_API_KEY") designated to hold the API key for a specified provider from the configuration.
296
+ * **`getProviderForModel(config, modelName)`**: Retrieves the first provider configuration listed for a given `modelName` in the configuration data.
297
+
298
+ ### EnvUtils
299
+
300
+ Provides utility functions for loading and accessing environment variables from a `.env` file.
301
+
302
+ #### Core Functions
303
+
304
+ * **`loadEnv(filePath)`**: Asynchronously loads environment variables from the specified `.env` file path into `process.env`. It ensures the file is only loaded once per process and handles cases where the file might not exist.
305
+ * **`getApiKey(keyName)`**: Retrieves the value of a specific API key environment variable by its name (e.g., "GEMINI_API_KEY"). It assumes `loadEnv` has been called previously and returns `null` if the variable is not set.
306
+
307
+ ### LLMUtils
308
+
309
+ Provides utility functions related to interactions with Large Language Models (LLMs).
310
+
311
+ #### Core Functions
312
+
313
+ * **`estimateTokens(text)`**: Estimates the number of tokens in a given text string using a basic heuristic (approximately 4 characters per token). Note that this is a rough estimate.
314
+
315
+ ### JsonUtils
316
+
317
+ Provides utility functions for working with JSON data.
318
+
319
+ #### Core Functions
320
+
321
+ * **`detectJsonComments(jsonString)`**: Scans a string for C-style block (`/* ... */`) and single-line (`// ...`) comments, correctly ignoring comments inside JSON string literals.
322
+
323
+ ### GSToolBlockUtils
324
+
325
+ Provides utility functions for identifying, parsing, formatting, and manipulating GitSense Chat Tool Blocks within markdown content.
326
+
327
+ #### Core Functions
328
+
329
+ * **`isToolBlock(content)`**: Checks if the provided code block content represents a GitSense Chat Tool Block by verifying the presence of the marker line `# GitSense Chat Tool`.
330
+ * **`parseToolBlock(content)`**: Parses the content of a verified GitSense Chat Tool Block to extract the JSON payload, stripping initial marker and comment lines.
331
+ * **`formatToolBlock(toolData)`**: Formats a tool data object into the standard string representation used inside a GitSense Chat Tool Block.
332
+ * **`replaceToolBlock(markdownContent, toolName, newToolData, CodeBlockUtils)`**: Replaces the content of the first GitSense Chat Tool Block matching a specific `toolName` within a larger markdown string.
333
+ * **`detectAndFormatUnfencedToolBlock(messageContent)`**: Detects an unfenced GitSense Chat Tool block within a message, validates its JSON content, and returns a properly formatted fenced block.
334
+
335
+ ### ContextUtils
336
+
337
+ Provides utility functions for parsing and formatting context message sections.
338
+
339
+ #### Core Functions
340
+
341
+ * **`parseContextSection(sectionText)`**: Parses the details (name, path, chat ID, etc.) and code content from a single context message section.
342
+ * **`extractContextSections(messageContent)`**: Extracts and parses all context sections from a full context message string.
343
+ * **`extractContextItemsOverviewTableRows(messageContent)`**: Parses the table rows from a Context Items Overview message.
344
+ * **`formatContextContent(items, contentType, contentOption)`**: Formats an array of loaded items into a structured context message string suitable for LLM consumption.
345
+
346
+ ### AnalysisBlockUtils
347
+
348
+ Provides utilities for identifying, parsing, and validating structured analysis blocks within GitSense Chat messages.
349
+
350
+ #### Core Functions
351
+
352
+ * **`isAnalysisBlock(content)`**: Checks if the provided content string starts with the standard analysis block header (`# GitSense Chat Analysis`).
353
+ * **`getAnalysisBlockType(content)`**: Determines the specific type of analysis block based on its initial header lines.
354
+ * **`parseOverviewMetadata(content)`**: Parses the metadata fields from an analysis block's content, assuming a Markdown list format.
355
+ * **`validateAnalysisMetadata(metadata)`**: Validates the parsed analysis metadata object, checking for required fields like 'Chat ID'.
356
+
357
+ ## Usage
358
+
359
+ To use the GitSense Chat Utils library in your project, you can import the main interface class or individual modules/functions as needed.
360
+
361
+ ### Main Interface Class
362
+
363
+ The primary way to interact with the library is through the `GitSenseChatUtils` class:
364
+
365
+ ```javascript
366
+ const { GitSenseChatUtils } = require('@gitsense/gsc-utils');
367
+
368
+ const utils = new GitSenseChatUtils();
369
+
370
+ // Example: Extract code blocks from markdown text
371
+ const markdownText = '...'; // Your markdown content
372
+ const { blocks, warnings } = utils.extractCodeBlocks(markdownText);
373
+
374
+ // Example: Fix invalid UUIDs in text
375
+ const { text: fixedText, modified } = utils.fixTextCodeBlocks(markdownText);
376
+
377
+ // Example: Check if a code block is a patch
378
+ const isPatch = utils.isPatchBlock(codeBlockContentString);
379
+ ```
380
+
381
+ ### Individual Modules
382
+
383
+ You can also import and use individual utility modules directly:
384
+
385
+ ```javascript
386
+ const { CodeBlockUtils } = require('@gitsense/gsc-utils');
387
+ const { PatchUtils } = require('@gitsense/gsc-utils');
388
+ const { AnalyzerUtils } = require('@gitsense/gsc-utils');
389
+ const { MessageUtils } = require('@gitsense/gsc-utils');
390
+ const { ConfigUtils } = require('@gitsense/gsc-utils');
391
+ const { EnvUtils } = require('@gitsense/gsc-utils');
392
+ const { LLMUtils } = require('@gitsense/gsc-utils');
393
+ const { JsonUtils } = require('@gitsense/gsc-utils');
394
+ const { GSToolBlockUtils } = require('@gitsense/gsc-utils');
395
+ const { ContextUtils } = require('@gitsense/gsc-utils');
396
+ const { AnalysisBlockUtils } = require('@gitsense/gsc-utils');
397
+ const { ChatUtils } = require('@gitsense/gsc-utils');
398
+
399
+ // Example: Using CodeBlockUtils directly
400
+ const { blocks, warnings } = CodeBlockUtils.extractCodeBlocks(markdownText);
401
+
402
+ // Example: Using PatchUtils directly
403
+ const patchResult = PatchUtils.applyPatchWithDiagnostics(sourceCodeString, patchString);
404
+
405
+ // Example: Using AnalyzerUtils directly
406
+ const analyzers = AnalyzerUtils.getAnalyzers('/path/to/analyzers');
407
+
408
+ // Example: Using MessageUtils directly
409
+ const messages = MessageUtils.getChatTemplateMessages('/path/to/messages', 'draft');
410
+ ```
411
+
412
+ ### Individual Functions
413
+
414
+ Many core functions are also exported individually for convenience:
415
+
416
+ ```javascript
417
+ const {
418
+ extractCodeBlocks,
419
+ fixTextCodeBlocks,
420
+ isPatchBlock,
421
+ getAnalyzers,
422
+ getChatTemplateMessages,
423
+ applyPatchWithDiagnostics,
424
+ estimateTokens
425
+ } = require('@gitsense/gsc-utils');
426
+
427
+ // Example: Extract code blocks
428
+ const { blocks, warnings } = extractCodeBlocks(markdownText);
429
+
430
+ // Example: Estimate tokens
431
+ const tokenCount = estimateTokens("Sample text for token estimation.");
432
+ ```