@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.
@@ -6810,7 +6810,9 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
6810
6810
  const targetContent = targetContentTemp.join('\n\n');
6811
6811
 
6812
6812
  // Get the number of lines in the header + two blank lines
6813
- const sourceHeaderLineCount = sourceHeaderText.split('\n').length;
6813
+ // Note, before the code block header format was solidified, we use to include 'Updated-at' but no more so
6814
+ // we need to filter it out from the source header
6815
+ const sourceHeaderLineCount = sourceHeaderText.split('\n').filter(line => !line.includes('Updated-at')).length;
6814
6816
  const targetHeaderLineCount = targetHeaderText.split('\n').length;
6815
6817
 
6816
6818
  // To keep things simple we are going to require the source and target header line count to be the same.
@@ -6818,7 +6820,7 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
6818
6820
  if (sourceHeaderLineCount !== targetHeaderLineCount) {
6819
6821
  // Some LLMs will not generate a Parent-UUID for the first version so we won't make this
6820
6822
  // fatal if the sourceHeader does not have a Parent-UUID
6821
- if (sourceHeaderLineCount.includes('Parent-UUID')) {
6823
+ if (sourceHeaderText.includes('Parent-UUID')) {
6822
6824
  throw new Error('Source and target header line count must be the same');
6823
6825
  }
6824
6826
  }
@@ -10628,13 +10630,13 @@ var CodeBlockUtils$5 = {
10628
10630
 
10629
10631
  /*
10630
10632
  * Component: ContextUtils
10631
- * Block-UUID: c018b1f9-2291-4bc9-9c4b-ab53a5db745e
10632
- * Parent-UUID: c199efe3-003c-4226-af3c-d460392a6569
10633
- * Version: 1.2.0
10633
+ * Block-UUID: a0b71292-b1cc-401a-8ce2-544a047b0fef
10634
+ * Parent-UUID: c018b1f9-2291-4bc9-9c4b-ab53a5db745e
10635
+ * Version: 1.3.0
10634
10636
  * Description: Provides utility functions for parsing context message sections to extract file details and code blocks, and for formatting content for LLM context.
10635
10637
  * Language: JavaScript
10636
10638
  * Created-at: 2025-05-09T01:36:20.107Z
10637
- * Authors: Gemini 2.5 Flash Thinking (v1.0.0), Gemini 2.5 Flash (v1.1.0), Qwen 3 Coder 480B - Cerebras (v1.2.0)
10639
+ * 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)
10638
10640
  */
10639
10641
 
10640
10642
  const CodeBlockUtils$4 = CodeBlockUtils$5;
@@ -10815,12 +10817,26 @@ function extractContextSections$1(messageContent) {
10815
10817
  const [summary, items] = messageContent.split(/\n---Start of Context---\n\n/);
10816
10818
  const sections = items.split(/\n---End of Item---\n/);
10817
10819
 
10820
+ // Determine the origin of the context based on the message header
10821
+ let contextOrigin = 'unknown'; // Default value if not determinable
10822
+ if (messageContent.includes("## FILE CONTENT - WORKING DIRECTORY")) {
10823
+ contextOrigin = 'working-directory';
10824
+ } else if (messageContent.includes("## FILE CONTENT - IMPORTED")) {
10825
+ contextOrigin = 'imported';
10826
+ } else if (messageContent.includes("## OVERVIEW - IMPORTED")) {
10827
+ // Handle the overview case as well, though it uses 'file content' type
10828
+ contextOrigin = 'imported';
10829
+ }
10830
+
10818
10831
  // Process sections starting from the first potential path delimiter.
10819
10832
  for (let i = 0; i < sections.length; i++) {
10820
10833
  const contextSection = parseContextSection$1(sections[i]);
10821
10834
 
10822
10835
  if (contextSection) {
10823
10836
  contextSections.push(contextSection);
10837
+ // Attach the determined context origin to the section
10838
+ // This provides information on how the context was introduced
10839
+ contextSection.contextOrigin = contextOrigin;
10824
10840
  }
10825
10841
  }
10826
10842
 
@@ -10841,6 +10857,7 @@ function extractContextItemsOverviewTableRows$1(messageContent) {
10841
10857
  return null;
10842
10858
  }
10843
10859
 
10860
+ // Map the column number to the type
10844
10861
  const col2Field = {
10845
10862
  1: 'chatId',
10846
10863
  2: 'type', // file, tree, etc.
@@ -12038,6 +12055,174 @@ var LLMUtils$1 = {
12038
12055
  estimateTokens: estimateTokens$1,
12039
12056
  };
12040
12057
 
12058
+ /**
12059
+ * Component: Date Utilities
12060
+ * Block-UUID: fef3b0f4-8055-4690-9336-e68a9cc33a61
12061
+ * Parent-UUID: 716e5ce9-84df-4f12-89e7-4a28e4a39a81
12062
+ * Version: 1.0.0
12063
+ * Description: Date formatting and manipulation utilities for GitSense Chat
12064
+ * Language: JavaScript
12065
+ * Created-at: 2025-10-11T23:26:20.815Z
12066
+ * Authors: Claude-3.5-Sonnet (v1.0.0), Qwen 3 Coder 480B - Cerebras (v1.0.0)
12067
+ */
12068
+
12069
+ /**
12070
+ * Ensures a date string has a timezone indicator
12071
+ * @param {string} dateString - Date string in format "YYYY-MM-DD(T| )HH:mm:ss.SSS"
12072
+ * @returns {string} Date string with 'Z' timezone indicator if not present
12073
+ */
12074
+ function normalizeDateTime$1(dateString) {
12075
+ return dateString.includes('Z') ? dateString : dateString + 'Z';
12076
+ }
12077
+
12078
+ /**
12079
+ * Calculates the time difference between now and a given date
12080
+ * @param {string} dateString - Date string to compare against current time
12081
+ * @returns {number} Difference in seconds
12082
+ */
12083
+ function getTimeDifference$1(dateString) {
12084
+ const now = new Date();
12085
+ const date = new Date(normalizeDateTime$1(dateString));
12086
+ return Math.floor((now - date) / 1000);
12087
+ }
12088
+
12089
+ /**
12090
+ * Formats a time difference in seconds to a human-readable string
12091
+ * @param {number} diff - Time difference in seconds
12092
+ * @returns {string} Formatted string (e.g., "5s ago", "2m ago", "3h ago", "2d ago")
12093
+ */
12094
+ function formatTimeDifference$1(diff) {
12095
+ if (diff < 60) {
12096
+ return `${diff}s ago`;
12097
+ } else if (diff < 3600) {
12098
+ const minutes = Math.floor(diff / 60);
12099
+ return `${minutes}m ago`;
12100
+ } else if (diff < 86400) {
12101
+ const hours = Math.floor(diff / 3600);
12102
+ return `${hours}h ago`;
12103
+ } else {
12104
+ const days = Math.floor(diff / 86400);
12105
+ return `${days}d ago`;
12106
+ }
12107
+ }
12108
+
12109
+ /**
12110
+ * Formats a date string into a relative time string
12111
+ * @param {string} dateString - Date string to format
12112
+ * @returns {string} Formatted relative time string
12113
+ */
12114
+ function formatAge$1(dateString) {
12115
+ if (!dateString) {
12116
+ return 'N/A';
12117
+ }
12118
+
12119
+ try {
12120
+ const diff = getTimeDifference$1(dateString);
12121
+ return formatTimeDifference$1(diff);
12122
+ } catch (error) {
12123
+ console.error('Error formatting date:', error);
12124
+ return 'Invalid date';
12125
+ }
12126
+ }
12127
+
12128
+ /**
12129
+ * Validates a date string format
12130
+ * @param {string} dateString - Date string to validate
12131
+ * @returns {boolean} True if date string is valid
12132
+ */
12133
+ function isValidDateString$1(dateString) {
12134
+ if (!dateString) return false;
12135
+
12136
+ const pattern = /^\d{4}-\d{2}-\d{2}(T| )\d{2}:\d{2}:\d{2}\.\d{3}Z?$/;
12137
+ if (!pattern.test(dateString)) return false;
12138
+
12139
+ const date = new Date(normalizeDateTime$1(dateString));
12140
+ return date instanceof Date && !isNaN(date);
12141
+ }
12142
+
12143
+ /**
12144
+ * Compares two date strings
12145
+ * @param {string} dateA - First date string
12146
+ * @param {string} dateB - Second date string
12147
+ * @returns {number} -1 if dateA is earlier, 0 if equal, 1 if dateA is later
12148
+ */
12149
+ function compareDates$1(dateA, dateB) {
12150
+ if (!isValidDateString$1(dateA) || !isValidDateString$1(dateB)) {
12151
+ throw new Error(`Invalid date string format. A: ${dateA} B: ${dateB})`);
12152
+ }
12153
+
12154
+ const timeA = new Date(normalizeDateTime$1(dateA)).getTime();
12155
+ const timeB = new Date(normalizeDateTime$1(dateB)).getTime();
12156
+
12157
+ if (timeA < timeB) return -1;
12158
+ if (timeA > timeB) return 1;
12159
+ return 0;
12160
+ }
12161
+
12162
+ var DateUtils$1 = {
12163
+ formatAge: formatAge$1,
12164
+ isValidDateString: isValidDateString$1,
12165
+ compareDates: compareDates$1,
12166
+ normalizeDateTime: normalizeDateTime$1,
12167
+ getTimeDifference: getTimeDifference$1,
12168
+ formatTimeDifference: formatTimeDifference$1
12169
+ };
12170
+
12171
+ /**
12172
+ * Component: Formatter Utilities
12173
+ * Block-UUID: 9b1e07bf-e92c-43c1-9ac0-5dacdb7ae618
12174
+ * Parent-UUID: 9c07d12f-5a05-4402-99d2-85d872d7b2f7
12175
+ * Version: 1.0.0
12176
+ * Description: Utility functions for formatting content in GitSense Chat
12177
+ * Language: JavaScript
12178
+ * Created-at: 2025-10-11T23:27:15.420Z
12179
+ * 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)
12180
+ */
12181
+
12182
+ /**
12183
+ * Formats bytes into human-readable string (KB, MB, GB)
12184
+ * @param {number} bytes - Number of bytes
12185
+ * @returns {string} Formatted size string
12186
+ */
12187
+ function formatBytes$1(bytes) {
12188
+ if (typeof bytes !== 'number' || isNaN(bytes)) return '0 bytes';
12189
+ if (bytes === 0) return '0 bytes';
12190
+
12191
+ const k = 1024;
12192
+ const sizes = ['bytes', 'KB', 'MB', 'GB'];
12193
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
12194
+
12195
+ // Special case for bytes (no decimal)
12196
+ if (i === 0) return `${bytes} ${sizes[i]}`;
12197
+
12198
+ const value = bytes / Math.pow(k, i);
12199
+ // Show no decimal if whole number
12200
+ const decimalPlaces = value % 1 === 0 ? 0 : 1;
12201
+ return `${value.toFixed(decimalPlaces)} ${sizes[i]}`;
12202
+ }
12203
+
12204
+ /**
12205
+ * Formats token count into human-readable string (k, m, b)
12206
+ * @param {number} count - Number of tokens
12207
+ * @returns {string} Formatted token string
12208
+ */
12209
+ function formatTokens$1(count) {
12210
+ if (typeof count !== 'number' || isNaN(count)) return '0';
12211
+ if (count === 0) return '0';
12212
+
12213
+ if (count < 1000) return `${count}`;
12214
+ if (count < 1000000) return `${(count/1000).toFixed(count >= 10000 ? 1 : 0)}k`;
12215
+ if (count < 1000000000) return `${(count/1000000).toFixed(1)}m`;
12216
+
12217
+ // For billions
12218
+ return `${(count/1000000000).toFixed(1)}b`;
12219
+ }
12220
+
12221
+ var FormatterUtils$1 = {
12222
+ formatBytes: formatBytes$1,
12223
+ formatTokens: formatTokens$1
12224
+ };
12225
+
12041
12226
  /*
12042
12227
  * Component: Config Utilities
12043
12228
  * Block-UUID: 65b39008-da68-462e-bcac-27db873c9ddc
@@ -12236,13 +12421,13 @@ var EnvUtils$1 = {
12236
12421
 
12237
12422
  /*
12238
12423
  * Component: GitSenseChatUtils
12239
- * Block-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
12240
- * Parent-UUID: 7a9b1c8e-f1a4-4b2d-9e8f-6f7a0b1c2d3f
12241
- * Version: 2.1.4
12424
+ * Block-UUID: d7cdbb94-f335-4f85-bdc4-0dd3ae95127e
12425
+ * Parent-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
12426
+ * Version: 2.1.5
12242
12427
  * 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.
12243
12428
  * Language: JavaScript
12244
12429
  * Created-at: 2025-04-15T16:04:26.780Z
12245
- * 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)
12430
+ * 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)
12246
12431
  */
12247
12432
 
12248
12433
  const ChatUtils = ChatUtils$1;
@@ -12255,9 +12440,20 @@ const PatchUtils = PatchUtils$2;
12255
12440
  const GSToolBlockUtils = GSToolBlockUtils$3;
12256
12441
  const LLMUtils = LLMUtils$1;
12257
12442
  const JsonUtils = JsonUtils$2;
12443
+ const DateUtils = DateUtils$1;
12444
+ const FormatterUtils = FormatterUtils$1;
12258
12445
  const ConfigUtils = ConfigUtils$1;
12259
12446
  const EnvUtils = EnvUtils$1;
12260
12447
 
12448
+ const {
12449
+ formatAge,
12450
+ isValidDateString,
12451
+ compareDates,
12452
+ normalizeDateTime,
12453
+ getTimeDifference,
12454
+ formatTimeDifference
12455
+ } = DateUtils;
12456
+
12261
12457
  const {
12262
12458
  estimateTokens
12263
12459
  } = LLMUtils;
@@ -12359,6 +12555,11 @@ const {
12359
12555
  getApiKey
12360
12556
  } = EnvUtils;
12361
12557
 
12558
+ const {
12559
+ formatBytes,
12560
+ formatTokens,
12561
+ } = FormatterUtils;
12562
+
12362
12563
  const {
12363
12564
  parseContextSection,
12364
12565
  extractContextSections,
@@ -12573,6 +12774,12 @@ class GitSenseChatUtils {
12573
12774
  // Export the main class, the aggregated CodeBlockUtils, PatchUtils,
12574
12775
  // and individual functions for backward compatibility or direct use.
12575
12776
  var GitSenseChatUtils_1 = {
12777
+ // New Utility Modules
12778
+ DateUtils,
12779
+ FormatterUtils,
12780
+
12781
+ // Date Utility Functions
12782
+
12576
12783
  // Main class
12577
12784
  GitSenseChatUtils,
12578
12785
 
@@ -12588,6 +12795,9 @@ var GitSenseChatUtils_1 = {
12588
12795
  GSToolBlockUtils,
12589
12796
  JsonUtils,
12590
12797
  ConfigUtils,
12798
+ DateUtils,
12799
+ FormatterUtils,
12800
+
12591
12801
  EnvUtils,
12592
12802
 
12593
12803
  // --- Individual Function Exports (sourced correctly) ---
@@ -12662,6 +12872,18 @@ var GitSenseChatUtils_1 = {
12662
12872
  // LLM Utils
12663
12873
  estimateTokens,
12664
12874
 
12875
+ // Date Utils
12876
+ formatAge,
12877
+ isValidDateString,
12878
+ compareDates,
12879
+ normalizeDateTime,
12880
+ getTimeDifference,
12881
+ formatTimeDifference,
12882
+
12883
+ // Formatter Utils
12884
+ formatBytes,
12885
+ formatTokens,
12886
+
12665
12887
  // GS Tool Block
12666
12888
  isToolBlock,
12667
12889
  parseToolBlock,
@@ -6808,7 +6808,9 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
6808
6808
  const targetContent = targetContentTemp.join('\n\n');
6809
6809
 
6810
6810
  // Get the number of lines in the header + two blank lines
6811
- const sourceHeaderLineCount = sourceHeaderText.split('\n').length;
6811
+ // Note, before the code block header format was solidified, we use to include 'Updated-at' but no more so
6812
+ // we need to filter it out from the source header
6813
+ const sourceHeaderLineCount = sourceHeaderText.split('\n').filter(line => !line.includes('Updated-at')).length;
6812
6814
  const targetHeaderLineCount = targetHeaderText.split('\n').length;
6813
6815
 
6814
6816
  // To keep things simple we are going to require the source and target header line count to be the same.
@@ -6816,7 +6818,7 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
6816
6818
  if (sourceHeaderLineCount !== targetHeaderLineCount) {
6817
6819
  // Some LLMs will not generate a Parent-UUID for the first version so we won't make this
6818
6820
  // fatal if the sourceHeader does not have a Parent-UUID
6819
- if (sourceHeaderLineCount.includes('Parent-UUID')) {
6821
+ if (sourceHeaderText.includes('Parent-UUID')) {
6820
6822
  throw new Error('Source and target header line count must be the same');
6821
6823
  }
6822
6824
  }
@@ -10626,13 +10628,13 @@ var CodeBlockUtils$5 = {
10626
10628
 
10627
10629
  /*
10628
10630
  * Component: ContextUtils
10629
- * Block-UUID: c018b1f9-2291-4bc9-9c4b-ab53a5db745e
10630
- * Parent-UUID: c199efe3-003c-4226-af3c-d460392a6569
10631
- * Version: 1.2.0
10631
+ * Block-UUID: a0b71292-b1cc-401a-8ce2-544a047b0fef
10632
+ * Parent-UUID: c018b1f9-2291-4bc9-9c4b-ab53a5db745e
10633
+ * Version: 1.3.0
10632
10634
  * Description: Provides utility functions for parsing context message sections to extract file details and code blocks, and for formatting content for LLM context.
10633
10635
  * Language: JavaScript
10634
10636
  * Created-at: 2025-05-09T01:36:20.107Z
10635
- * Authors: Gemini 2.5 Flash Thinking (v1.0.0), Gemini 2.5 Flash (v1.1.0), Qwen 3 Coder 480B - Cerebras (v1.2.0)
10637
+ * 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)
10636
10638
  */
10637
10639
 
10638
10640
  const CodeBlockUtils$4 = CodeBlockUtils$5;
@@ -10813,12 +10815,26 @@ function extractContextSections$1(messageContent) {
10813
10815
  const [summary, items] = messageContent.split(/\n---Start of Context---\n\n/);
10814
10816
  const sections = items.split(/\n---End of Item---\n/);
10815
10817
 
10818
+ // Determine the origin of the context based on the message header
10819
+ let contextOrigin = 'unknown'; // Default value if not determinable
10820
+ if (messageContent.includes("## FILE CONTENT - WORKING DIRECTORY")) {
10821
+ contextOrigin = 'working-directory';
10822
+ } else if (messageContent.includes("## FILE CONTENT - IMPORTED")) {
10823
+ contextOrigin = 'imported';
10824
+ } else if (messageContent.includes("## OVERVIEW - IMPORTED")) {
10825
+ // Handle the overview case as well, though it uses 'file content' type
10826
+ contextOrigin = 'imported';
10827
+ }
10828
+
10816
10829
  // Process sections starting from the first potential path delimiter.
10817
10830
  for (let i = 0; i < sections.length; i++) {
10818
10831
  const contextSection = parseContextSection$1(sections[i]);
10819
10832
 
10820
10833
  if (contextSection) {
10821
10834
  contextSections.push(contextSection);
10835
+ // Attach the determined context origin to the section
10836
+ // This provides information on how the context was introduced
10837
+ contextSection.contextOrigin = contextOrigin;
10822
10838
  }
10823
10839
  }
10824
10840
 
@@ -10839,6 +10855,7 @@ function extractContextItemsOverviewTableRows$1(messageContent) {
10839
10855
  return null;
10840
10856
  }
10841
10857
 
10858
+ // Map the column number to the type
10842
10859
  const col2Field = {
10843
10860
  1: 'chatId',
10844
10861
  2: 'type', // file, tree, etc.
@@ -12036,6 +12053,174 @@ var LLMUtils$1 = {
12036
12053
  estimateTokens: estimateTokens$1,
12037
12054
  };
12038
12055
 
12056
+ /**
12057
+ * Component: Date Utilities
12058
+ * Block-UUID: fef3b0f4-8055-4690-9336-e68a9cc33a61
12059
+ * Parent-UUID: 716e5ce9-84df-4f12-89e7-4a28e4a39a81
12060
+ * Version: 1.0.0
12061
+ * Description: Date formatting and manipulation utilities for GitSense Chat
12062
+ * Language: JavaScript
12063
+ * Created-at: 2025-10-11T23:26:20.815Z
12064
+ * Authors: Claude-3.5-Sonnet (v1.0.0), Qwen 3 Coder 480B - Cerebras (v1.0.0)
12065
+ */
12066
+
12067
+ /**
12068
+ * Ensures a date string has a timezone indicator
12069
+ * @param {string} dateString - Date string in format "YYYY-MM-DD(T| )HH:mm:ss.SSS"
12070
+ * @returns {string} Date string with 'Z' timezone indicator if not present
12071
+ */
12072
+ function normalizeDateTime$1(dateString) {
12073
+ return dateString.includes('Z') ? dateString : dateString + 'Z';
12074
+ }
12075
+
12076
+ /**
12077
+ * Calculates the time difference between now and a given date
12078
+ * @param {string} dateString - Date string to compare against current time
12079
+ * @returns {number} Difference in seconds
12080
+ */
12081
+ function getTimeDifference$1(dateString) {
12082
+ const now = new Date();
12083
+ const date = new Date(normalizeDateTime$1(dateString));
12084
+ return Math.floor((now - date) / 1000);
12085
+ }
12086
+
12087
+ /**
12088
+ * Formats a time difference in seconds to a human-readable string
12089
+ * @param {number} diff - Time difference in seconds
12090
+ * @returns {string} Formatted string (e.g., "5s ago", "2m ago", "3h ago", "2d ago")
12091
+ */
12092
+ function formatTimeDifference$1(diff) {
12093
+ if (diff < 60) {
12094
+ return `${diff}s ago`;
12095
+ } else if (diff < 3600) {
12096
+ const minutes = Math.floor(diff / 60);
12097
+ return `${minutes}m ago`;
12098
+ } else if (diff < 86400) {
12099
+ const hours = Math.floor(diff / 3600);
12100
+ return `${hours}h ago`;
12101
+ } else {
12102
+ const days = Math.floor(diff / 86400);
12103
+ return `${days}d ago`;
12104
+ }
12105
+ }
12106
+
12107
+ /**
12108
+ * Formats a date string into a relative time string
12109
+ * @param {string} dateString - Date string to format
12110
+ * @returns {string} Formatted relative time string
12111
+ */
12112
+ function formatAge$1(dateString) {
12113
+ if (!dateString) {
12114
+ return 'N/A';
12115
+ }
12116
+
12117
+ try {
12118
+ const diff = getTimeDifference$1(dateString);
12119
+ return formatTimeDifference$1(diff);
12120
+ } catch (error) {
12121
+ console.error('Error formatting date:', error);
12122
+ return 'Invalid date';
12123
+ }
12124
+ }
12125
+
12126
+ /**
12127
+ * Validates a date string format
12128
+ * @param {string} dateString - Date string to validate
12129
+ * @returns {boolean} True if date string is valid
12130
+ */
12131
+ function isValidDateString$1(dateString) {
12132
+ if (!dateString) return false;
12133
+
12134
+ const pattern = /^\d{4}-\d{2}-\d{2}(T| )\d{2}:\d{2}:\d{2}\.\d{3}Z?$/;
12135
+ if (!pattern.test(dateString)) return false;
12136
+
12137
+ const date = new Date(normalizeDateTime$1(dateString));
12138
+ return date instanceof Date && !isNaN(date);
12139
+ }
12140
+
12141
+ /**
12142
+ * Compares two date strings
12143
+ * @param {string} dateA - First date string
12144
+ * @param {string} dateB - Second date string
12145
+ * @returns {number} -1 if dateA is earlier, 0 if equal, 1 if dateA is later
12146
+ */
12147
+ function compareDates$1(dateA, dateB) {
12148
+ if (!isValidDateString$1(dateA) || !isValidDateString$1(dateB)) {
12149
+ throw new Error(`Invalid date string format. A: ${dateA} B: ${dateB})`);
12150
+ }
12151
+
12152
+ const timeA = new Date(normalizeDateTime$1(dateA)).getTime();
12153
+ const timeB = new Date(normalizeDateTime$1(dateB)).getTime();
12154
+
12155
+ if (timeA < timeB) return -1;
12156
+ if (timeA > timeB) return 1;
12157
+ return 0;
12158
+ }
12159
+
12160
+ var DateUtils$1 = {
12161
+ formatAge: formatAge$1,
12162
+ isValidDateString: isValidDateString$1,
12163
+ compareDates: compareDates$1,
12164
+ normalizeDateTime: normalizeDateTime$1,
12165
+ getTimeDifference: getTimeDifference$1,
12166
+ formatTimeDifference: formatTimeDifference$1
12167
+ };
12168
+
12169
+ /**
12170
+ * Component: Formatter Utilities
12171
+ * Block-UUID: 9b1e07bf-e92c-43c1-9ac0-5dacdb7ae618
12172
+ * Parent-UUID: 9c07d12f-5a05-4402-99d2-85d872d7b2f7
12173
+ * Version: 1.0.0
12174
+ * Description: Utility functions for formatting content in GitSense Chat
12175
+ * Language: JavaScript
12176
+ * Created-at: 2025-10-11T23:27:15.420Z
12177
+ * 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)
12178
+ */
12179
+
12180
+ /**
12181
+ * Formats bytes into human-readable string (KB, MB, GB)
12182
+ * @param {number} bytes - Number of bytes
12183
+ * @returns {string} Formatted size string
12184
+ */
12185
+ function formatBytes$1(bytes) {
12186
+ if (typeof bytes !== 'number' || isNaN(bytes)) return '0 bytes';
12187
+ if (bytes === 0) return '0 bytes';
12188
+
12189
+ const k = 1024;
12190
+ const sizes = ['bytes', 'KB', 'MB', 'GB'];
12191
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
12192
+
12193
+ // Special case for bytes (no decimal)
12194
+ if (i === 0) return `${bytes} ${sizes[i]}`;
12195
+
12196
+ const value = bytes / Math.pow(k, i);
12197
+ // Show no decimal if whole number
12198
+ const decimalPlaces = value % 1 === 0 ? 0 : 1;
12199
+ return `${value.toFixed(decimalPlaces)} ${sizes[i]}`;
12200
+ }
12201
+
12202
+ /**
12203
+ * Formats token count into human-readable string (k, m, b)
12204
+ * @param {number} count - Number of tokens
12205
+ * @returns {string} Formatted token string
12206
+ */
12207
+ function formatTokens$1(count) {
12208
+ if (typeof count !== 'number' || isNaN(count)) return '0';
12209
+ if (count === 0) return '0';
12210
+
12211
+ if (count < 1000) return `${count}`;
12212
+ if (count < 1000000) return `${(count/1000).toFixed(count >= 10000 ? 1 : 0)}k`;
12213
+ if (count < 1000000000) return `${(count/1000000).toFixed(1)}m`;
12214
+
12215
+ // For billions
12216
+ return `${(count/1000000000).toFixed(1)}b`;
12217
+ }
12218
+
12219
+ var FormatterUtils$1 = {
12220
+ formatBytes: formatBytes$1,
12221
+ formatTokens: formatTokens$1
12222
+ };
12223
+
12039
12224
  /*
12040
12225
  * Component: Config Utilities
12041
12226
  * Block-UUID: 65b39008-da68-462e-bcac-27db873c9ddc
@@ -12234,13 +12419,13 @@ var EnvUtils$1 = {
12234
12419
 
12235
12420
  /*
12236
12421
  * Component: GitSenseChatUtils
12237
- * Block-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
12238
- * Parent-UUID: 7a9b1c8e-f1a4-4b2d-9e8f-6f7a0b1c2d3f
12239
- * Version: 2.1.4
12422
+ * Block-UUID: d7cdbb94-f335-4f85-bdc4-0dd3ae95127e
12423
+ * Parent-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
12424
+ * Version: 2.1.5
12240
12425
  * 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.
12241
12426
  * Language: JavaScript
12242
12427
  * Created-at: 2025-04-15T16:04:26.780Z
12243
- * 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)
12428
+ * 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)
12244
12429
  */
12245
12430
 
12246
12431
  const ChatUtils = ChatUtils$1;
@@ -12253,9 +12438,20 @@ const PatchUtils = PatchUtils$2;
12253
12438
  const GSToolBlockUtils = GSToolBlockUtils$3;
12254
12439
  const LLMUtils = LLMUtils$1;
12255
12440
  const JsonUtils = JsonUtils$2;
12441
+ const DateUtils = DateUtils$1;
12442
+ const FormatterUtils = FormatterUtils$1;
12256
12443
  const ConfigUtils = ConfigUtils$1;
12257
12444
  const EnvUtils = EnvUtils$1;
12258
12445
 
12446
+ const {
12447
+ formatAge,
12448
+ isValidDateString,
12449
+ compareDates,
12450
+ normalizeDateTime,
12451
+ getTimeDifference,
12452
+ formatTimeDifference
12453
+ } = DateUtils;
12454
+
12259
12455
  const {
12260
12456
  estimateTokens
12261
12457
  } = LLMUtils;
@@ -12357,6 +12553,11 @@ const {
12357
12553
  getApiKey
12358
12554
  } = EnvUtils;
12359
12555
 
12556
+ const {
12557
+ formatBytes,
12558
+ formatTokens,
12559
+ } = FormatterUtils;
12560
+
12360
12561
  const {
12361
12562
  parseContextSection,
12362
12563
  extractContextSections,
@@ -12571,6 +12772,12 @@ class GitSenseChatUtils {
12571
12772
  // Export the main class, the aggregated CodeBlockUtils, PatchUtils,
12572
12773
  // and individual functions for backward compatibility or direct use.
12573
12774
  var GitSenseChatUtils_1 = {
12775
+ // New Utility Modules
12776
+ DateUtils,
12777
+ FormatterUtils,
12778
+
12779
+ // Date Utility Functions
12780
+
12574
12781
  // Main class
12575
12782
  GitSenseChatUtils,
12576
12783
 
@@ -12586,6 +12793,9 @@ var GitSenseChatUtils_1 = {
12586
12793
  GSToolBlockUtils,
12587
12794
  JsonUtils,
12588
12795
  ConfigUtils,
12796
+ DateUtils,
12797
+ FormatterUtils,
12798
+
12589
12799
  EnvUtils,
12590
12800
 
12591
12801
  // --- Individual Function Exports (sourced correctly) ---
@@ -12660,6 +12870,18 @@ var GitSenseChatUtils_1 = {
12660
12870
  // LLM Utils
12661
12871
  estimateTokens,
12662
12872
 
12873
+ // Date Utils
12874
+ formatAge,
12875
+ isValidDateString,
12876
+ compareDates,
12877
+ normalizeDateTime,
12878
+ getTimeDifference,
12879
+ formatTimeDifference,
12880
+
12881
+ // Formatter Utils
12882
+ formatBytes,
12883
+ formatTokens,
12884
+
12663
12885
  // GS Tool Block
12664
12886
  isToolBlock,
12665
12887
  parseToolBlock,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitsense/gsc-utils",
3
- "version": "0.2.21",
3
+ "version": "0.2.24",
4
4
  "description": "Utilities for GitSense Chat (GSC)",
5
5
  "main": "dist/gsc-utils.cjs.js",
6
6
  "module": "dist/gsc-utils.esm.js",