@gitsense/gsc-utils 0.2.21 → 0.2.23

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.
@@ -1,12 +1,12 @@
1
1
  /*
2
2
  * Component: ContextUtils
3
- * Block-UUID: c018b1f9-2291-4bc9-9c4b-ab53a5db745e
4
- * Parent-UUID: c199efe3-003c-4226-af3c-d460392a6569
5
- * Version: 1.2.0
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
-
@@ -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
+ };
@@ -1,12 +1,12 @@
1
1
  /*
2
2
  * Component: GitSenseChatUtils
3
- * Block-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
4
- * Parent-UUID: 7a9b1c8e-f1a4-4b2d-9e8f-6f7a0b1c2d3f
5
- * Version: 2.1.4
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,6 +20,8 @@ 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
 
@@ -124,6 +126,11 @@ const {
124
126
  getApiKey
125
127
  } = EnvUtils;
126
128
 
129
+ const {
130
+ formatBytes,
131
+ formatTokens,
132
+ } = FormatterUtils;
133
+
127
134
  const {
128
135
  parseContextSection,
129
136
  extractContextSections,
@@ -338,6 +345,15 @@ class GitSenseChatUtils {
338
345
  // Export the main class, the aggregated CodeBlockUtils, PatchUtils,
339
346
  // and individual functions for backward compatibility or direct use.
340
347
  module.exports = {
348
+ // New Utility Modules
349
+ DateUtils,
350
+ FormatterUtils,
351
+
352
+ // Date Utility Functions
353
+ formatAge: DateUtils.formatAge,
354
+ compareDates: DateUtils.compareDates,
355
+ isValidDateString: DateUtils.isValidDateString,
356
+
341
357
  // Main class
342
358
  GitSenseChatUtils,
343
359
 
@@ -353,6 +369,9 @@ module.exports = {
353
369
  GSToolBlockUtils,
354
370
  JsonUtils,
355
371
  ConfigUtils,
372
+ DateUtils,
373
+ FormatterUtils,
374
+
356
375
  EnvUtils,
357
376
 
358
377
  // --- Individual Function Exports (sourced correctly) ---
@@ -427,6 +446,16 @@ module.exports = {
427
446
  // LLM Utils
428
447
  estimateTokens,
429
448
 
449
+ // Date Utils
450
+ formatAge,
451
+ compareDates,
452
+ isValidDateString,
453
+
454
+ // Formatter Utils
455
+ formatBytes,
456
+ formatTokens,
457
+ formatOverviewTable,
458
+
430
459
  // GS Tool Block
431
460
  isToolBlock,
432
461
  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
- const sourceHeaderLineCount = sourceHeaderText.split('\n').length;
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 (sourceHeaderLineCount.includes('Parent-UUID')) {
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
  }