@gitsense/gsc-utils 0.2.25 → 0.2.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +380 -62
  2. package/dist/gsc-utils.cjs.js +2203 -331
  3. package/dist/gsc-utils.esm.js +2203 -331
  4. package/package.json +1 -1
  5. package/src/AnalyzerUtils/cloner.js +149 -0
  6. package/src/AnalyzerUtils/constants.js +1 -1
  7. package/src/AnalyzerUtils/defaultPromptLoader.js +10 -10
  8. package/src/AnalyzerUtils/discovery.js +48 -39
  9. package/src/AnalyzerUtils/index.js +13 -7
  10. package/src/AnalyzerUtils/instructionLoader.js +6 -6
  11. package/src/AnalyzerUtils/jsonParser.js +35 -0
  12. package/src/AnalyzerUtils/management.js +6 -6
  13. package/src/AnalyzerUtils/saver.js +5 -5
  14. package/src/AnalyzerUtils/schemaLoader.js +194 -26
  15. package/src/AnalyzerUtils/updater.js +187 -0
  16. package/src/CodeBlockUtils/blockProcessor.js +14 -32
  17. package/src/CodeBlockUtils/index.js +7 -6
  18. package/src/CodeBlockUtils/lineageTracer.js +95 -0
  19. package/src/CompactChatUtils/CompactedMessageUtils.js +224 -0
  20. package/src/CompactChatUtils/README.md +321 -0
  21. package/src/CompactChatUtils/ReferenceMessageUtils.js +143 -0
  22. package/src/CompactChatUtils/index.js +40 -0
  23. package/src/ContextUtils.js +40 -4
  24. package/src/DomUtils.js +86 -12
  25. package/src/GSToolBlockUtils.js +66 -1
  26. package/src/GitSenseChatUtils.js +58 -5
  27. package/src/MarkdownUtils.js +4 -1
  28. package/src/MessageUtils.js +1 -1
  29. package/src/MetaRawResultUtils.js +244 -0
  30. package/src/PatchUtils/constants.js +9 -3
  31. package/src/PatchUtils/patchParser.js +60 -36
  32. package/src/PatchUtils/patchVerifier/detectAndFixOverlappingHunks.js +1 -1
  33. package/src/SVGUtils.js +57 -0
  34. package/src/SharedUtils/stringUtils.js +303 -0
  35. package/src/CodeBlockUtils/blockProcessor.js.rej +0 -8
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Component: CodeBlockUtils Lineage Tracer
3
+ * Block-UUID: 13b08cce-6fd1-4ec9-a915-240714ee89b9
4
+ * Parent-UUID: df1a629b-2cc0-4677-b410-3172ee0e0f9f
5
+ * Version: 1.1.0
6
+ * Description: Provides a utility function to trace the full lineage (patch-based and parent-based) of code blocks within a chat, including loop detection.
7
+ * Language: JavaScript
8
+ * Created-at: 2025-10-23T01:28:10.456Z
9
+ * Authors: Qwen 3 Coder 480B - Cerebras (v1.0.0), Qwen 3 Coder 480B - Cerebras (v1.1.0)
10
+ */
11
+
12
+
13
+ /**
14
+ * Traces the full lineage of a code block or patch identified by a UUID.
15
+ * The lineage includes the block itself and all its ancestors, tracing backwards
16
+ * first through patch relationships (Source-Block-UUID -> Target-Block-UUID)
17
+ * and then through Parent-UUID relationships.
18
+ * Loop detection is included to prevent infinite tracing.
19
+ *
20
+ * @param {string} uuid - The UUID of the target code block or patch.
21
+ * @param {Map<string, object>} blockMap - A map where keys are UUIDs (for code blocks)
22
+ * or patch UUIDs (source:target) and values
23
+ * are the corresponding block objects.
24
+ * Block objects are expected to have
25
+ * properties like `isPatch`, `metadata`, and `header`.
26
+ * @returns {Array<object>} An array of block objects representing the lineage.
27
+ * The first element is the block for the provided `uuid`.
28
+ * Subsequent elements are its ancestors.
29
+ * Returns an empty array if the initial uuid is not found.
30
+ * If a loop is detected, the last element will have a property `loopDetected: true`.
31
+ */
32
+ function getLineage(uuid, blockMap) {
33
+ if (!uuid || !blockMap) {
34
+ return [];
35
+ }
36
+
37
+ const lineage = [];
38
+ const visitedUuids = new Set();
39
+ let currentUuid = uuid;
40
+
41
+ while (currentUuid) {
42
+ // --- Loop Detection ---
43
+ if (visitedUuids.has(currentUuid)) {
44
+ // Add a marker or the block itself to indicate the loop
45
+ const loopBlock = blockMap.get(currentUuid) || { uuid: currentUuid, loopDetected: true, type: 'loop-marker' };
46
+ loopBlock.loopDetected = true; // Ensure the property is set
47
+ lineage.push(loopBlock);
48
+ break; // Stop the trace
49
+ }
50
+ visitedUuids.add(currentUuid);
51
+
52
+ // --- 1. Try to find the block directly by its UUID ---
53
+ let block = blockMap.get(currentUuid);
54
+
55
+ // --- 2. If not found directly, search patch keys ---
56
+ if (!block) {
57
+ for (const [key, value] of blockMap) {
58
+ // Check if the map key is a patch key (contains ':') and ends with our target UUID
59
+ if (key.includes(':') && key.endsWith(`:${currentUuid}`)) {
60
+ block = value;
61
+ break;
62
+ }
63
+ }
64
+ }
65
+
66
+ // --- 3. If a block was found, add it to the lineage ---
67
+ if (block) {
68
+ lineage.push(block);
69
+
70
+ let nextUuid = null;
71
+
72
+ // --- 3a. If it's a patch, move to its source UUID ---
73
+ if (block.isPatch && block.metadata && block.metadata['Source-Block-UUID']) {
74
+ nextUuid = block.metadata['Source-Block-UUID'];
75
+ }
76
+ // --- 3b. If it's a code block, move to its Parent-UUID (if valid) ---
77
+ else if (!block.isPatch && block.header && block.header['Parent-UUID'] && block.header['Parent-UUID'] !== 'N/A') {
78
+ nextUuid = block.header['Parent-UUID'];
79
+ }
80
+ // If it's a code block with Parent-UUID: 0c104865-260a-4942-8cb6-93bebf40c450
81
+
82
+ currentUuid = nextUuid;
83
+ } else {
84
+ // If no block is found for currentUuid, the lineage is incomplete.
85
+ // We could add a placeholder here if needed, but for now, we just stop.
86
+ currentUuid = null;
87
+ }
88
+ }
89
+
90
+ return lineage;
91
+ }
92
+
93
+ module.exports = {
94
+ getLineage
95
+ };
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Component: CompactedMessageUtils
3
+ * Block-UUID: b4111118-ec11-49d6-9a6e-402ca0b6df5b
4
+ * Parent-UUID: N/A
5
+ * Version: 1.0.1
6
+ * Description: Utility for formatting, parsing, and validating compacted messages with standardized metadata headers.
7
+ * Language: JavaScript
8
+ * Created-at: 2025-12-07T00:09:15.842Z
9
+ * Authors: GLM-4.6 (v1.0.0), GLM-4.6 (v1.0.1)
10
+ */
11
+
12
+
13
+ class CompactedMessageUtils {
14
+ /**
15
+ * Formats a compacted message with standardized metadata headers
16
+ * @param {string} content - The compacted message content
17
+ * @param {string} originalChatUuid - UUID of the original chat
18
+ * @param {string} messageRange - Message range that was compacted (e.g., "3-6")
19
+ * @param {Object} options - Additional options
20
+ * @param {Date} options.compactedAt - Custom timestamp for when the message was compacted
21
+ * @returns {string} Formatted compacted message with metadata
22
+ */
23
+ static formatCompactedMessage(content, originalChatUuid, messageRange, options = {}) {
24
+ if (!content) {
25
+ throw new Error('Content is required for formatting a compacted message');
26
+ }
27
+
28
+ if (!originalChatUuid) {
29
+ throw new Error('Original chat UUID is required for formatting a compacted message');
30
+ }
31
+
32
+ if (!messageRange) {
33
+ throw new Error('Message range is required for formatting a compacted message');
34
+ }
35
+
36
+ // Use provided timestamp or generate current one
37
+ const compactedAt = options.compactedAt || new Date().toISOString();
38
+
39
+ return `## Compacted Message
40
+
41
+ - **Original Chat:** [${originalChatUuid}](/?chat=${originalChatUuid})
42
+ - **Message Range:** ${messageRange}
43
+ - **Compacted At:** ${compactedAt}
44
+
45
+ ${content}`;
46
+ }
47
+
48
+ /**
49
+ * Extracts metadata from a compacted message
50
+ * @param {string} compactedMessage - The compacted message to parse
51
+ * @returns {Object|null} Metadata object or null if format is invalid
52
+ */
53
+ static extractCompactedMessageMetadata(compactedMessage) {
54
+ if (!this.isCompactedMessage(compactedMessage)) {
55
+ return null;
56
+ }
57
+
58
+ // Extract Original Chat UUID
59
+ const originalChatMatch = compactedMessage.match(/\*\*Original Chat:\*\*\s*([a-f0-9-]+)/i);
60
+ const originalChatUuid = originalChatMatch ? originalChatMatch[1] : null;
61
+
62
+ // Extract Message Range
63
+ const rangeMatch = compactedMessage.match(/\*\*Message Range:\*\*\s*(\d+-\d+)/i);
64
+ const messageRange = rangeMatch ? rangeMatch[1] : null;
65
+
66
+ // Extract Compacted At timestamp
67
+ const compactedAtMatch = compactedMessage.match(/\*\*Compacted At:\*\*\s*([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z)/i);
68
+ const compactedAt = compactedAtMatch ? compactedAtMatch[1] : null;
69
+
70
+ return {
71
+ originalChatUuid,
72
+ messageRange,
73
+ compactedAt
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Extracts just the content portion from a compacted message (without metadata)
79
+ * @param {string} compactedMessage - The compacted message to parse
80
+ * @returns {string|null} Content portion or null if format is invalid
81
+ */
82
+ static extractCompactedMessageContent(compactedMessage) {
83
+ if (!this.isCompactedMessage(compactedMessage)) {
84
+ return null;
85
+ }
86
+
87
+ // Find the start and end boundaries
88
+ const startMarker = "## Compacted Message";
89
+ const endMarker = "## End Compacted Message";
90
+
91
+ const startIndex = compactedMessage.indexOf(startMarker);
92
+ const endIndex = compactedMessage.indexOf(endMarker);
93
+
94
+ // If start marker is not found, return null
95
+ if (startIndex === -1) {
96
+ return null;
97
+ }
98
+
99
+ // If end marker is not found, extract everything after start marker
100
+ if (endIndex === -1) {
101
+ return compactedMessage.substring(startIndex + startMarker.length).trim();
102
+ }
103
+
104
+ // Extract content between the markers
105
+ const contentStart = startIndex + startMarker.length;
106
+ return compactedMessage.substring(contentStart, endIndex).trim();
107
+ }
108
+
109
+ /**
110
+ * Validates that a compacted message follows the expected format
111
+ * @param {string} compactedMessage - The compacted message to validate
112
+ * @returns {Object} Validation result with isValid flag and any errors/warnings
113
+ */
114
+ static validateCompactedMessageFormat(compactedMessage) {
115
+ const result = {
116
+ isValid: true,
117
+ errors: [],
118
+ warnings: []
119
+ };
120
+
121
+ if (!compactedMessage) {
122
+ result.isValid = false;
123
+ result.errors.push('Compacted message is empty or null');
124
+ return result;
125
+ }
126
+
127
+ // Check for required header
128
+ if (!compactedMessage.includes('## Compacted Message')) {
129
+ result.isValid = false;
130
+ result.errors.push('Missing required "## Compacted Message" header');
131
+ }
132
+
133
+ // Check for required metadata fields
134
+ const metadata = this.extractCompactedMessageMetadata(compactedMessage);
135
+
136
+ if (!metadata) {
137
+ result.isValid = false;
138
+ result.errors.push('Could not extract metadata from compacted message');
139
+ return result;
140
+ }
141
+
142
+ if (!metadata.originalChatUuid) {
143
+ result.isValid = false;
144
+ result.errors.push('Missing or invalid Original Chat UUID');
145
+ }
146
+
147
+ if (!metadata.messageRange) {
148
+ result.isValid = false;
149
+ result.errors.push('Missing or invalid Message Range');
150
+ }
151
+
152
+ if (!metadata.compactedAt) {
153
+ result.warnings.push('Missing or invalid Compacted At timestamp');
154
+ }
155
+
156
+ // Validate UUID format
157
+ if (metadata.originalChatUuid && !this.isValidUUID(metadata.originalChatUuid)) {
158
+ result.isValid = false;
159
+ result.errors.push('Original Chat UUID is not in valid UUID format');
160
+ }
161
+
162
+ // Validate message range format
163
+ if (metadata.messageRange && !this.isValidMessageRange(metadata.messageRange)) {
164
+ result.isValid = false;
165
+ result.errors.push('Message Range is not in valid format (expected "X-Y")');
166
+ }
167
+
168
+ // Validate timestamp format
169
+ if (metadata.compactedAt && !this.isValidISOTimestamp(metadata.compactedAt)) {
170
+ result.warnings.push('Compacted At timestamp is not in valid ISO 8601 format');
171
+ }
172
+
173
+ return result;
174
+ }
175
+
176
+ /**
177
+ * Checks if a message is a compacted message
178
+ * @param {string} message - The message content to check
179
+ * @returns {boolean} True if the message is a compacted message
180
+ */
181
+ static isCompactedMessage(message) {
182
+ if (!message) return false;
183
+
184
+ // Check for the compacted message header
185
+ return message.includes('## Compacted Message');
186
+ }
187
+
188
+ /**
189
+ * Validates if a string is a valid UUID v4
190
+ * @param {string} uuid - The UUID string to validate
191
+ * @returns {boolean} True if valid UUID v4
192
+ */
193
+ static isValidUUID(uuid) {
194
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
195
+ return uuidRegex.test(uuid);
196
+ }
197
+
198
+ /**
199
+ * Validates if a string is a valid message range (e.g., "3-6")
200
+ * @param {string} range - The range string to validate
201
+ * @returns {boolean} True if valid range format
202
+ */
203
+ static isValidMessageRange(range) {
204
+ const rangeRegex = /^\d+-\d+$/;
205
+ if (!rangeRegex.test(range)) return false;
206
+
207
+ const [from, to] = range.split('-').map(Number);
208
+ return !isNaN(from) && !isNaN(to) && from <= to;
209
+ }
210
+
211
+ /**
212
+ * Validates if a string is a valid ISO 8601 timestamp
213
+ * @param {string} timestamp - The timestamp string to validate
214
+ * @returns {boolean} True if valid ISO 8601 timestamp
215
+ */
216
+ static isValidISOTimestamp(timestamp) {
217
+ if (!timestamp) return false;
218
+
219
+ const date = new Date(timestamp);
220
+ return !isNaN(date.getTime()) && timestamp === date.toISOString();
221
+ }
222
+ }
223
+
224
+ module.exports = { CompactedMessageUtils };
@@ -0,0 +1,321 @@
1
+ # CompactChatUtils
2
+
3
+ A utility module for working with compacted messages in GitSense Chat. This module provides functionality for parsing reference messages, formatting compacted messages, and validating message formats.
4
+
5
+ ## Overview
6
+
7
+ CompactChatUtils is designed to handle the compact message workflow in GitSense Chat, which allows for efficient storage and retrieval of chat messages by compacting older messages while preserving context. The module consists of two main utility classes:
8
+
9
+ - **ReferenceMessageUtils**: Parses reference messages that contain information about which messages to compact and which to keep as context
10
+ - **CompactedMessageUtils**: Formats, parses, and validates compacted messages with standardized metadata headers
11
+
12
+ ## Installation
13
+
14
+ ```javascript
15
+ const { CompactChatUtils } = require('@gitsense/gsc-utils');
16
+ ```
17
+
18
+ Or import individual utilities:
19
+
20
+ ```javascript
21
+ const { ReferenceMessageUtils } = require('@gitsense/gsc-utils');
22
+ const { CompactedMessageUtils } = require('@gitsense/gsc-utils');
23
+ ```
24
+
25
+ ## API Reference
26
+
27
+ ### ReferenceMessageUtils
28
+
29
+ #### `extractReferenceMessageData(referenceMessage)`
30
+
31
+ Extracts all data from a reference message including session data, metadata, and message sections.
32
+
33
+ **Parameters:**
34
+ - `referenceMessage` (string): The reference message content to parse
35
+
36
+ **Returns:**
37
+ - Object: Parsed data with messages to compact and keep, metadata, and session information
38
+
39
+ **Example:**
40
+ ```javascript
41
+ const data = ReferenceMessageUtils.extractReferenceMessageData(referenceMessage);
42
+ console.log(data.messagesToCompact);
43
+ console.log(data.originalChatUuid);
44
+ ```
45
+
46
+ #### `parseMessageSection(section)`
47
+
48
+ Parses a message section to extract individual messages.
49
+
50
+ **Parameters:**
51
+ - `section` (string): The section content to parse
52
+
53
+ **Returns:**
54
+ - Array: Array of parsed message objects
55
+
56
+ **Example:**
57
+ ```javascript
58
+ const messages = ReferenceMessageUtils.parseMessageSection(section);
59
+ ```
60
+
61
+ #### `extractReferenceMessageMetadata(referenceMessage)`
62
+
63
+ Extracts just the metadata from a reference message without the message sections.
64
+
65
+ **Parameters:**
66
+ - `referenceMessage` (string): The reference message content to parse
67
+
68
+ **Returns:**
69
+ - Object: Metadata object with original chat UUID, validation hash, session ID, and range information
70
+
71
+ **Example:**
72
+ ```javascript
73
+ const metadata = ReferenceMessageUtils.extractReferenceMessageMetadata(referenceMessage);
74
+ console.log(metadata.originalChatUuid);
75
+ ```
76
+
77
+ #### `isReferenceMessage(message)`
78
+
79
+ Checks if a message is a reference message.
80
+
81
+ **Parameters:**
82
+ - `message` (string): The message content to check
83
+
84
+ **Returns:**
85
+ - boolean: True if the message is a reference message
86
+
87
+ **Example:**
88
+ ```javascript
89
+ if (ReferenceMessageUtils.isReferenceMessage(message)) {
90
+ // Handle reference message
91
+ }
92
+ ```
93
+
94
+ ### CompactedMessageUtils
95
+
96
+ #### `formatCompactedMessage(content, originalChatUuid, messageRange, options)`
97
+
98
+ Formats a compacted message with standardized metadata headers.
99
+
100
+ **Parameters:**
101
+ - `content` (string): The compacted message content
102
+ - `originalChatUuid` (string): UUID of the original chat
103
+ - `messageRange` (string): Message range that was compacted (e.g., "3-6")
104
+ - `options` (Object, optional): Additional options
105
+ - `compactedAt` (Date): Custom timestamp for when the message was compacted
106
+
107
+ **Returns:**
108
+ - string: Formatted compacted message with metadata
109
+
110
+ **Example:**
111
+ ```javascript
112
+ const compactedMessage = CompactedMessageUtils.formatCompactedMessage(
113
+ content,
114
+ '123e4567-e89b-12d3-a456-426614174000',
115
+ '3-6'
116
+ );
117
+ ```
118
+
119
+ #### `extractCompactedMessageMetadata(compactedMessage)`
120
+
121
+ Extracts metadata from a compacted message.
122
+
123
+ **Parameters:**
124
+ - `compactedMessage` (string): The compacted message to parse
125
+
126
+ **Returns:**
127
+ - Object|null: Metadata object or null if format is invalid
128
+
129
+ **Example:**
130
+ ```javascript
131
+ const metadata = CompactedMessageUtils.extractCompactedMessageMetadata(compactedMessage);
132
+ console.log(metadata.originalChatUuid);
133
+ ```
134
+
135
+ #### `extractCompactedMessageContent(compactedMessage)`
136
+
137
+ Extracts just the content portion from a compacted message (without metadata).
138
+
139
+ **Parameters:**
140
+ - `compactedMessage` (string): The compacted message to parse
141
+
142
+ **Returns:**
143
+ - string|null: Content portion or null if format is invalid
144
+
145
+ **Example:**
146
+ ```javascript
147
+ const content = CompactedMessageUtils.extractCompactedMessageContent(compactedMessage);
148
+ ```
149
+
150
+ #### `validateCompactedMessageFormat(compactedMessage)`
151
+
152
+ Validates that a compacted message follows the expected format.
153
+
154
+ **Parameters:**
155
+ - `compactedMessage` (string): The compacted message to validate
156
+
157
+ **Returns:**
158
+ - Object: Validation result with isValid flag and any errors/warnings
159
+
160
+ **Example:**
161
+ ```javascript
162
+ const validation = CompactedMessageUtils.validateCompactedMessageFormat(compactedMessage);
163
+ if (validation.isValid) {
164
+ // Process valid compacted message
165
+ } else {
166
+ console.error(validation.errors);
167
+ }
168
+ ```
169
+
170
+ #### `isCompactedMessage(message)`
171
+
172
+ Checks if a message is a compacted message.
173
+
174
+ **Parameters:**
175
+ - `message` (string): The message content to check
176
+
177
+ **Returns:**
178
+ - boolean: True if the message is a compacted message
179
+
180
+ **Example:**
181
+ ```javascript
182
+ if (CompactedMessageUtils.isCompactedMessage(message)) {
183
+ // Handle compacted message
184
+ }
185
+ ```
186
+
187
+ #### `isValidUUID(uuid)`
188
+
189
+ Validates if a string is a valid UUID v4.
190
+
191
+ **Parameters:**
192
+ - `uuid` (string): The UUID string to validate
193
+
194
+ **Returns:**
195
+ - boolean: True if valid UUID v4
196
+
197
+ **Example:**
198
+ ```javascript
199
+ if (CompactedMessageUtils.isValidUUID(uuid)) {
200
+ // Process valid UUID
201
+ }
202
+ ```
203
+
204
+ #### `isValidMessageRange(range)`
205
+
206
+ Validates if a string is a valid message range (e.g., "3-6").
207
+
208
+ **Parameters:**
209
+ - `range` (string): The range string to validate
210
+
211
+ **Returns:**
212
+ - boolean: True if valid range format
213
+
214
+ **Example:**
215
+ ```javascript
216
+ if (CompactedMessageUtils.isValidMessageRange(range)) {
217
+ // Process valid range
218
+ }
219
+ ```
220
+
221
+ #### `isValidISOTimestamp(timestamp)`
222
+
223
+ Validates if a string is a valid ISO 8601 timestamp.
224
+
225
+ **Parameters:**
226
+ - `timestamp` (string): The timestamp string to validate
227
+
228
+ **Returns:**
229
+ - boolean: True if valid ISO 8601 timestamp
230
+
231
+ **Example:**
232
+ ```javascript
233
+ if (CompactedMessageUtils.isValidISOTimestamp(timestamp)) {
234
+ // Process valid timestamp
235
+ }
236
+ ```
237
+
238
+ ## Usage Examples
239
+
240
+ ### Parsing a Reference Message
241
+
242
+ ```javascript
243
+ const { ReferenceMessageUtils } = require('@gitsense/gsc-utils');
244
+
245
+ // Parse a reference message to extract data
246
+ const referenceData = ReferenceMessageUtils.extractReferenceMessageData(referenceMessage);
247
+
248
+ // Access the extracted data
249
+ const { messagesToCompact, messagesToKeep, originalChatUuid, range } = referenceData;
250
+
251
+ console.log(`Original Chat UUID: ${originalChatUuid}`);
252
+ console.log(`Messages to compact: ${messagesToCompact.length}`);
253
+ console.log(`Messages to keep: ${messagesToKeep.length}`);
254
+ ```
255
+
256
+ ### Formatting a Compacted Message
257
+
258
+ ```javascript
259
+ const { CompactedMessageUtils } = require('@gitsense/gsc-utils');
260
+
261
+ // Format a compacted message with metadata
262
+ const compactedMessage = CompactedMessageUtils.formatCompactedMessage(
263
+ "This is the compacted content...",
264
+ "123e4567-e89b-12d3-a456-426614174000",
265
+ "3-6",
266
+ { compactedAt: new Date() }
267
+ );
268
+
269
+ console.log(compactedMessage);
270
+ ```
271
+
272
+ ### Validating a Compacted Message
273
+
274
+ ```javascript
275
+ const { CompactedMessageUtils } = require('@gitsense/gsc-utils');
276
+
277
+ // Validate a compacted message
278
+ const validation = CompactedMessageUtils.validateCompactedMessageFormat(compactedMessage);
279
+
280
+ if (!validation.isValid) {
281
+ console.error("Validation errors:");
282
+ validation.errors.forEach(error => console.error(`- ${error}`));
283
+
284
+ if (validation.warnings.length > 0) {
285
+ console.warn("Validation warnings:");
286
+ validation.warnings.forEach(warning => console.warn(`- ${warning}`));
287
+ }
288
+ }
289
+ ```
290
+
291
+ ### Using the Combined Interface
292
+
293
+ ```javascript
294
+ const { CompactChatUtils } = require('@gitsense/gsc-utils');
295
+
296
+ // Check if a message is a reference message
297
+ if (CompactChatUtils.isReferenceMessage(message)) {
298
+ const data = CompactChatUtils.extractReferenceMessageData(message);
299
+ // Process reference message data
300
+ }
301
+
302
+ // Check if a message is a compacted message
303
+ if (CompactChatUtils.isCompactedMessage(message)) {
304
+ const metadata = CompactChatUtils.extractCompactedMessageMetadata(message);
305
+ // Process compacted message metadata
306
+ }
307
+ ```
308
+
309
+ ## File Structure
310
+
311
+ ```
312
+ src/CompactChatUtils/
313
+ ├── index.js # Main entry point that exports all utilities
314
+ ├── ReferenceMessageUtils.js # Utilities for parsing reference messages
315
+ ├── CompactedMessageUtils.js # Utilities for compacted messages
316
+ └── README.md # This documentation
317
+ ```
318
+
319
+ ## Dependencies
320
+
321
+ The CompactChatUtils module has no external dependencies and is part of the larger `@gitsense/gsc-utils` package.