@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.
@@ -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,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
- 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
  }