@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 +432 -0
- package/dist/gsc-utils.cjs.js +232 -10
- package/dist/gsc-utils.esm.js +232 -10
- package/package.json +1 -1
- package/src/ContextUtils.js +19 -5
- package/src/DateUtils.js +113 -0
- package/src/FormatterUtils.js +55 -0
- package/src/GitSenseChatUtils.js +41 -4
- package/src/PatchUtils/patchProcessor.js +4 -2
package/src/ContextUtils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Component: ContextUtils
|
|
3
|
-
* Block-UUID:
|
|
4
|
-
* Parent-UUID:
|
|
5
|
-
* Version: 1.
|
|
3
|
+
* Block-UUID: a0b71292-b1cc-401a-8ce2-544a047b0fef
|
|
4
|
+
* Parent-UUID: c018b1f9-2291-4bc9-9c4b-ab53a5db745e
|
|
5
|
+
* Version: 1.3.0
|
|
6
6
|
* Description: Provides utility functions for parsing context message sections to extract file details and code blocks, and for formatting content for LLM context.
|
|
7
7
|
* Language: JavaScript
|
|
8
8
|
* Created-at: 2025-05-09T01:36:20.107Z
|
|
9
|
-
* Authors: Gemini 2.5 Flash Thinking (v1.0.0), Gemini 2.5 Flash (v1.1.0), Qwen 3 Coder 480B - Cerebras (v1.2.0)
|
|
9
|
+
* Authors: Gemini 2.5 Flash Thinking (v1.0.0), Gemini 2.5 Flash (v1.1.0), Qwen 3 Coder 480B - Cerebras (v1.2.0), Qwen 3 Coder 480B - Cerebras (v1.3.0)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
@@ -188,12 +188,26 @@ function extractContextSections(messageContent) {
|
|
|
188
188
|
const [summary, items] = messageContent.split(/\n---Start of Context---\n\n/);
|
|
189
189
|
const sections = items.split(/\n---End of Item---\n/);
|
|
190
190
|
|
|
191
|
+
// Determine the origin of the context based on the message header
|
|
192
|
+
let contextOrigin = 'unknown'; // Default value if not determinable
|
|
193
|
+
if (messageContent.includes("## FILE CONTENT - WORKING DIRECTORY")) {
|
|
194
|
+
contextOrigin = 'working-directory';
|
|
195
|
+
} else if (messageContent.includes("## FILE CONTENT - IMPORTED")) {
|
|
196
|
+
contextOrigin = 'imported';
|
|
197
|
+
} else if (messageContent.includes("## OVERVIEW - IMPORTED")) {
|
|
198
|
+
// Handle the overview case as well, though it uses 'file content' type
|
|
199
|
+
contextOrigin = 'imported';
|
|
200
|
+
}
|
|
201
|
+
|
|
191
202
|
// Process sections starting from the first potential path delimiter.
|
|
192
203
|
for (let i = 0; i < sections.length; i++) {
|
|
193
204
|
const contextSection = parseContextSection(sections[i]);
|
|
194
205
|
|
|
195
206
|
if (contextSection) {
|
|
196
207
|
contextSections.push(contextSection);
|
|
208
|
+
// Attach the determined context origin to the section
|
|
209
|
+
// This provides information on how the context was introduced
|
|
210
|
+
contextSection.contextOrigin = contextOrigin;
|
|
197
211
|
}
|
|
198
212
|
}
|
|
199
213
|
|
|
@@ -214,6 +228,7 @@ function extractContextItemsOverviewTableRows(messageContent) {
|
|
|
214
228
|
return null;
|
|
215
229
|
}
|
|
216
230
|
|
|
231
|
+
// Map the column number to the type
|
|
217
232
|
const col2Field = {
|
|
218
233
|
1: 'chatId',
|
|
219
234
|
2: 'type', // file, tree, etc.
|
|
@@ -339,4 +354,3 @@ module.exports = {
|
|
|
339
354
|
extractContextItemsOverviewTableRows,
|
|
340
355
|
formatContextContent,
|
|
341
356
|
};
|
|
342
|
-
|
package/src/DateUtils.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: Date Utilities
|
|
3
|
+
* Block-UUID: fef3b0f4-8055-4690-9336-e68a9cc33a61
|
|
4
|
+
* Parent-UUID: 716e5ce9-84df-4f12-89e7-4a28e4a39a81
|
|
5
|
+
* Version: 1.0.0
|
|
6
|
+
* Description: Date formatting and manipulation utilities for GitSense Chat
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-10-11T23:26:20.815Z
|
|
9
|
+
* Authors: Claude-3.5-Sonnet (v1.0.0), Qwen 3 Coder 480B - Cerebras (v1.0.0)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Ensures a date string has a timezone indicator
|
|
15
|
+
* @param {string} dateString - Date string in format "YYYY-MM-DD(T| )HH:mm:ss.SSS"
|
|
16
|
+
* @returns {string} Date string with 'Z' timezone indicator if not present
|
|
17
|
+
*/
|
|
18
|
+
function normalizeDateTime(dateString) {
|
|
19
|
+
return dateString.includes('Z') ? dateString : dateString + 'Z';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Calculates the time difference between now and a given date
|
|
24
|
+
* @param {string} dateString - Date string to compare against current time
|
|
25
|
+
* @returns {number} Difference in seconds
|
|
26
|
+
*/
|
|
27
|
+
function getTimeDifference(dateString) {
|
|
28
|
+
const now = new Date();
|
|
29
|
+
const date = new Date(normalizeDateTime(dateString));
|
|
30
|
+
return Math.floor((now - date) / 1000);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Formats a time difference in seconds to a human-readable string
|
|
35
|
+
* @param {number} diff - Time difference in seconds
|
|
36
|
+
* @returns {string} Formatted string (e.g., "5s ago", "2m ago", "3h ago", "2d ago")
|
|
37
|
+
*/
|
|
38
|
+
function formatTimeDifference(diff) {
|
|
39
|
+
if (diff < 60) {
|
|
40
|
+
return `${diff}s ago`;
|
|
41
|
+
} else if (diff < 3600) {
|
|
42
|
+
const minutes = Math.floor(diff / 60);
|
|
43
|
+
return `${minutes}m ago`;
|
|
44
|
+
} else if (diff < 86400) {
|
|
45
|
+
const hours = Math.floor(diff / 3600);
|
|
46
|
+
return `${hours}h ago`;
|
|
47
|
+
} else {
|
|
48
|
+
const days = Math.floor(diff / 86400);
|
|
49
|
+
return `${days}d ago`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Formats a date string into a relative time string
|
|
55
|
+
* @param {string} dateString - Date string to format
|
|
56
|
+
* @returns {string} Formatted relative time string
|
|
57
|
+
*/
|
|
58
|
+
function formatAge(dateString) {
|
|
59
|
+
if (!dateString) {
|
|
60
|
+
return 'N/A';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const diff = getTimeDifference(dateString);
|
|
65
|
+
return formatTimeDifference(diff);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error('Error formatting date:', error);
|
|
68
|
+
return 'Invalid date';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Validates a date string format
|
|
74
|
+
* @param {string} dateString - Date string to validate
|
|
75
|
+
* @returns {boolean} True if date string is valid
|
|
76
|
+
*/
|
|
77
|
+
function isValidDateString(dateString) {
|
|
78
|
+
if (!dateString) return false;
|
|
79
|
+
|
|
80
|
+
const pattern = /^\d{4}-\d{2}-\d{2}(T| )\d{2}:\d{2}:\d{2}\.\d{3}Z?$/;
|
|
81
|
+
if (!pattern.test(dateString)) return false;
|
|
82
|
+
|
|
83
|
+
const date = new Date(normalizeDateTime(dateString));
|
|
84
|
+
return date instanceof Date && !isNaN(date);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Compares two date strings
|
|
89
|
+
* @param {string} dateA - First date string
|
|
90
|
+
* @param {string} dateB - Second date string
|
|
91
|
+
* @returns {number} -1 if dateA is earlier, 0 if equal, 1 if dateA is later
|
|
92
|
+
*/
|
|
93
|
+
function compareDates(dateA, dateB) {
|
|
94
|
+
if (!isValidDateString(dateA) || !isValidDateString(dateB)) {
|
|
95
|
+
throw new Error(`Invalid date string format. A: ${dateA} B: ${dateB})`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const timeA = new Date(normalizeDateTime(dateA)).getTime();
|
|
99
|
+
const timeB = new Date(normalizeDateTime(dateB)).getTime();
|
|
100
|
+
|
|
101
|
+
if (timeA < timeB) return -1;
|
|
102
|
+
if (timeA > timeB) return 1;
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
formatAge,
|
|
108
|
+
isValidDateString,
|
|
109
|
+
compareDates,
|
|
110
|
+
normalizeDateTime,
|
|
111
|
+
getTimeDifference,
|
|
112
|
+
formatTimeDifference
|
|
113
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: Formatter Utilities
|
|
3
|
+
* Block-UUID: 9b1e07bf-e92c-43c1-9ac0-5dacdb7ae618
|
|
4
|
+
* Parent-UUID: 9c07d12f-5a05-4402-99d2-85d872d7b2f7
|
|
5
|
+
* Version: 1.0.0
|
|
6
|
+
* Description: Utility functions for formatting content in GitSense Chat
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-10-11T23:27:15.420Z
|
|
9
|
+
* Authors: Claude 3.7 Sonnet (v1.0.0), Claude 3.7 Sonnet (v1.1.0), Gemini 2.5 Flash Thinking (v1.2.0), Gemini 2.5 Flash Thinking (v1.3.0), Qwen 3 Coder 480B - Cerebras (v1.4.0), Qwen 3 Coder 480B - Cerebras (v1.5.0), Qwen 3 Coder 480B - Cerebras (v1.0.0)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Formats bytes into human-readable string (KB, MB, GB)
|
|
15
|
+
* @param {number} bytes - Number of bytes
|
|
16
|
+
* @returns {string} Formatted size string
|
|
17
|
+
*/
|
|
18
|
+
function formatBytes(bytes) {
|
|
19
|
+
if (typeof bytes !== 'number' || isNaN(bytes)) return '0 bytes';
|
|
20
|
+
if (bytes === 0) return '0 bytes';
|
|
21
|
+
|
|
22
|
+
const k = 1024;
|
|
23
|
+
const sizes = ['bytes', 'KB', 'MB', 'GB'];
|
|
24
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
25
|
+
|
|
26
|
+
// Special case for bytes (no decimal)
|
|
27
|
+
if (i === 0) return `${bytes} ${sizes[i]}`;
|
|
28
|
+
|
|
29
|
+
const value = bytes / Math.pow(k, i);
|
|
30
|
+
// Show no decimal if whole number
|
|
31
|
+
const decimalPlaces = value % 1 === 0 ? 0 : 1;
|
|
32
|
+
return `${value.toFixed(decimalPlaces)} ${sizes[i]}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Formats token count into human-readable string (k, m, b)
|
|
37
|
+
* @param {number} count - Number of tokens
|
|
38
|
+
* @returns {string} Formatted token string
|
|
39
|
+
*/
|
|
40
|
+
function formatTokens(count) {
|
|
41
|
+
if (typeof count !== 'number' || isNaN(count)) return '0';
|
|
42
|
+
if (count === 0) return '0';
|
|
43
|
+
|
|
44
|
+
if (count < 1000) return `${count}`;
|
|
45
|
+
if (count < 1000000) return `${(count/1000).toFixed(count >= 10000 ? 1 : 0)}k`;
|
|
46
|
+
if (count < 1000000000) return `${(count/1000000).toFixed(1)}m`;
|
|
47
|
+
|
|
48
|
+
// For billions
|
|
49
|
+
return `${(count/1000000000).toFixed(1)}b`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
formatBytes,
|
|
54
|
+
formatTokens
|
|
55
|
+
};
|
package/src/GitSenseChatUtils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Component: GitSenseChatUtils
|
|
3
|
-
* Block-UUID:
|
|
4
|
-
* Parent-UUID:
|
|
5
|
-
* Version: 2.1.
|
|
3
|
+
* Block-UUID: d7cdbb94-f335-4f85-bdc4-0dd3ae95127e
|
|
4
|
+
* Parent-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
|
|
5
|
+
* Version: 2.1.5
|
|
6
6
|
* Description: Interface class for GitSense Chat utilities providing a unified API for code block parsing (markdown), extraction, and patch operations. Integrates functionalities from CodeBlockUtils and PatchUtils modules, and now includes ConfigUtils and EnvUtils.
|
|
7
7
|
* Language: JavaScript
|
|
8
8
|
* Created-at: 2025-04-15T16:04:26.780Z
|
|
9
|
-
* Authors: Claude 3.7 Sonnet (v1.0.0), Gemini 2.5 Pro (v2.0.0), Gemini 2.5 Pro (v2.1.0), Gemini 2.5 Pro (v2.1.1), Gemini 2.5 Flash (v2.1.2), Gemini 2.5 Flash (v2.1.3), Gemini 2.5 Flash (v2.1.4)
|
|
9
|
+
* Authors: Claude 3.7 Sonnet (v1.0.0), Gemini 2.5 Pro (v2.0.0), Gemini 2.5 Pro (v2.1.0), Gemini 2.5 Pro (v2.1.1), Gemini 2.5 Flash (v2.1.2), Gemini 2.5 Flash (v2.1.3), Gemini 2.5 Flash (v2.1.4), Qwen 3 Coder 480B - Cerebras (v2.1.5)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
@@ -20,9 +20,20 @@ const PatchUtils = require('./PatchUtils');
|
|
|
20
20
|
const GSToolBlockUtils = require('./GSToolBlockUtils');
|
|
21
21
|
const LLMUtils = require('./LLMUtils');
|
|
22
22
|
const JsonUtils = require('./JsonUtils');
|
|
23
|
+
const DateUtils = require('./DateUtils');
|
|
24
|
+
const FormatterUtils = require('./FormatterUtils');
|
|
23
25
|
const ConfigUtils = require('./ConfigUtils');
|
|
24
26
|
const EnvUtils = require('./EnvUtils');
|
|
25
27
|
|
|
28
|
+
const {
|
|
29
|
+
formatAge,
|
|
30
|
+
isValidDateString,
|
|
31
|
+
compareDates,
|
|
32
|
+
normalizeDateTime,
|
|
33
|
+
getTimeDifference,
|
|
34
|
+
formatTimeDifference
|
|
35
|
+
} = DateUtils;
|
|
36
|
+
|
|
26
37
|
const {
|
|
27
38
|
estimateTokens
|
|
28
39
|
} = LLMUtils;
|
|
@@ -124,6 +135,11 @@ const {
|
|
|
124
135
|
getApiKey
|
|
125
136
|
} = EnvUtils;
|
|
126
137
|
|
|
138
|
+
const {
|
|
139
|
+
formatBytes,
|
|
140
|
+
formatTokens,
|
|
141
|
+
} = FormatterUtils;
|
|
142
|
+
|
|
127
143
|
const {
|
|
128
144
|
parseContextSection,
|
|
129
145
|
extractContextSections,
|
|
@@ -338,6 +354,12 @@ class GitSenseChatUtils {
|
|
|
338
354
|
// Export the main class, the aggregated CodeBlockUtils, PatchUtils,
|
|
339
355
|
// and individual functions for backward compatibility or direct use.
|
|
340
356
|
module.exports = {
|
|
357
|
+
// New Utility Modules
|
|
358
|
+
DateUtils,
|
|
359
|
+
FormatterUtils,
|
|
360
|
+
|
|
361
|
+
// Date Utility Functions
|
|
362
|
+
|
|
341
363
|
// Main class
|
|
342
364
|
GitSenseChatUtils,
|
|
343
365
|
|
|
@@ -353,6 +375,9 @@ module.exports = {
|
|
|
353
375
|
GSToolBlockUtils,
|
|
354
376
|
JsonUtils,
|
|
355
377
|
ConfigUtils,
|
|
378
|
+
DateUtils,
|
|
379
|
+
FormatterUtils,
|
|
380
|
+
|
|
356
381
|
EnvUtils,
|
|
357
382
|
|
|
358
383
|
// --- Individual Function Exports (sourced correctly) ---
|
|
@@ -427,6 +452,18 @@ module.exports = {
|
|
|
427
452
|
// LLM Utils
|
|
428
453
|
estimateTokens,
|
|
429
454
|
|
|
455
|
+
// Date Utils
|
|
456
|
+
formatAge,
|
|
457
|
+
isValidDateString,
|
|
458
|
+
compareDates,
|
|
459
|
+
normalizeDateTime,
|
|
460
|
+
getTimeDifference,
|
|
461
|
+
formatTimeDifference,
|
|
462
|
+
|
|
463
|
+
// Formatter Utils
|
|
464
|
+
formatBytes,
|
|
465
|
+
formatTokens,
|
|
466
|
+
|
|
430
467
|
// GS Tool Block
|
|
431
468
|
isToolBlock,
|
|
432
469
|
parseToolBlock,
|
|
@@ -283,7 +283,9 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
|
|
|
283
283
|
const targetContent = targetContentTemp.join('\n\n');
|
|
284
284
|
|
|
285
285
|
// Get the number of lines in the header + two blank lines
|
|
286
|
-
|
|
286
|
+
// Note, before the code block header format was solidified, we use to include 'Updated-at' but no more so
|
|
287
|
+
// we need to filter it out from the source header
|
|
288
|
+
const sourceHeaderLineCount = sourceHeaderText.split('\n').filter(line => !line.includes('Updated-at')).length;
|
|
287
289
|
const targetHeaderLineCount = targetHeaderText.split('\n').length;
|
|
288
290
|
|
|
289
291
|
// To keep things simple we are going to require the source and target header line count to be the same.
|
|
@@ -291,7 +293,7 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
|
|
|
291
293
|
if (sourceHeaderLineCount !== targetHeaderLineCount) {
|
|
292
294
|
// Some LLMs will not generate a Parent-UUID for the first version so we won't make this
|
|
293
295
|
// fatal if the sourceHeader does not have a Parent-UUID
|
|
294
|
-
if (
|
|
296
|
+
if (sourceHeaderText.includes('Parent-UUID')) {
|
|
295
297
|
throw new Error('Source and target header line count must be the same');
|
|
296
298
|
}
|
|
297
299
|
}
|