@gitsense/gsc-utils 0.2.34 → 0.2.36

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.
@@ -1426,7 +1426,10 @@ function parseOverviewMetadata$1(content) {
1426
1426
  const lines = content.split('\n');
1427
1427
 
1428
1428
  // Regex to capture "Field Name" and "Value" from lines like '* **Field Name: ** Value'
1429
- const fieldRegex = /^\*\s+\*\*([\w\s.-]+):\*\*\s+(.*)$/;
1429
+ const fieldRegex1 = /^\*\s+\*\*([\w\s.-]+):\*\*\s+(.*)$/;
1430
+ const fieldRegex2 = /^\*\s+\*\*([\w\s.-]+)\*\*:\s+(.*)$/;
1431
+ const fieldRegex3 = /^.*?(Chat ID|Path).*:\s*(\d+)$/m;
1432
+
1430
1433
  let foundList = false;
1431
1434
  let currentKey = null; // For potential multi-line handling in the future
1432
1435
 
@@ -1442,7 +1445,7 @@ function parseOverviewMetadata$1(content) {
1442
1445
  break;
1443
1446
  }
1444
1447
 
1445
- const match = trimmedLine.match(fieldRegex);
1448
+ const match = trimmedLine.match(fieldRegex1) || trimmedLine.match(fieldRegex2) || trimmedLine.match(fieldRegex3);
1446
1449
 
1447
1450
  if (match) {
1448
1451
  foundList = true;
@@ -9961,7 +9964,7 @@ function fixTextCodeBlocks$2(text) {
9961
9964
  const [fieldPart, valuePart] = line.split(':').map(p => p.trim());
9962
9965
 
9963
9966
  // Skip if N/A or contains unexpected characters
9964
- if (valuePart === 'N/A' || valuePart.match(/\(/)) {
9967
+ if (valuePart === 'N/A' || !valuePart.match(/\w-/)) {
9965
9968
  return line;
9966
9969
  }
9967
9970
  // Validate UUID
@@ -11000,7 +11003,7 @@ const { formatWithLineNumbers: formatWithLineNumbers$1, formatBlockWithLineNumbe
11000
11003
  const { getLineage: getLineage$1 } = lineageTracer;
11001
11004
 
11002
11005
  // Export all imported items
11003
- var CodeBlockUtils$7 = {
11006
+ var CodeBlockUtils$8 = {
11004
11007
  // Constants
11005
11008
  COMMENT_STYLES: COMMENT_STYLES$1,
11006
11009
 
@@ -11060,6 +11063,302 @@ var CodeBlockUtils$7 = {
11060
11063
  removeLineNumbers: removeLineNumbers$1,
11061
11064
  };
11062
11065
 
11066
+ /**
11067
+ * Component: Date Utilities
11068
+ * Block-UUID: fef3b0f4-8055-4690-9336-e68a9cc33a61
11069
+ * Parent-UUID: 716e5ce9-84df-4f12-89e7-4a28e4a39a81
11070
+ * Version: 1.0.0
11071
+ * Description: Date formatting and manipulation utilities for GitSense Chat
11072
+ * Language: JavaScript
11073
+ * Created-at: 2025-10-11T23:26:20.815Z
11074
+ * Authors: Claude-3.5-Sonnet (v1.0.0), Qwen 3 Coder 480B - Cerebras (v1.0.0)
11075
+ */
11076
+
11077
+ /**
11078
+ * Ensures a date string has a timezone indicator
11079
+ * @param {string} dateString - Date string in format "YYYY-MM-DD(T| )HH:mm:ss.SSS"
11080
+ * @returns {string} Date string with 'Z' timezone indicator if not present
11081
+ */
11082
+ function normalizeDateTime$1(dateString) {
11083
+ return dateString.includes('Z') ? dateString : dateString + 'Z';
11084
+ }
11085
+
11086
+ /**
11087
+ * Calculates the time difference between now and a given date
11088
+ * @param {string} dateString - Date string to compare against current time
11089
+ * @returns {number} Difference in seconds
11090
+ */
11091
+ function getTimeDifference$1(dateString) {
11092
+ const now = new Date();
11093
+ const date = new Date(normalizeDateTime$1(dateString));
11094
+ return Math.floor((now - date) / 1000);
11095
+ }
11096
+
11097
+ /**
11098
+ * Formats a time difference in seconds to a human-readable string
11099
+ * @param {number} diff - Time difference in seconds
11100
+ * @returns {string} Formatted string (e.g., "5s ago", "2m ago", "3h ago", "2d ago")
11101
+ */
11102
+ function formatTimeDifference$1(diff) {
11103
+ if (diff < 60) {
11104
+ return `${diff}s ago`;
11105
+ } else if (diff < 3600) {
11106
+ const minutes = Math.floor(diff / 60);
11107
+ return `${minutes}m ago`;
11108
+ } else if (diff < 86400) {
11109
+ const hours = Math.floor(diff / 3600);
11110
+ return `${hours}h ago`;
11111
+ } else {
11112
+ const days = Math.floor(diff / 86400);
11113
+ return `${days}d ago`;
11114
+ }
11115
+ }
11116
+
11117
+ /**
11118
+ * Formats a date string into a relative time string
11119
+ * @param {string} dateString - Date string to format
11120
+ * @returns {string} Formatted relative time string
11121
+ */
11122
+ function formatAge$1(dateString) {
11123
+ if (!dateString) {
11124
+ return 'N/A';
11125
+ }
11126
+
11127
+ try {
11128
+ const diff = getTimeDifference$1(dateString);
11129
+ return formatTimeDifference$1(diff);
11130
+ } catch (error) {
11131
+ console.error('Error formatting date:', error);
11132
+ return 'Invalid date';
11133
+ }
11134
+ }
11135
+
11136
+ /**
11137
+ * Validates a date string format
11138
+ * @param {string} dateString - Date string to validate
11139
+ * @returns {boolean} True if date string is valid
11140
+ */
11141
+ function isValidDateString$1(dateString) {
11142
+ if (!dateString) return false;
11143
+
11144
+ const pattern = /^\d{4}-\d{2}-\d{2}(T| )\d{2}:\d{2}:\d{2}\.\d{3}Z?$/;
11145
+ if (!pattern.test(dateString)) return false;
11146
+
11147
+ const date = new Date(normalizeDateTime$1(dateString));
11148
+ return date instanceof Date && !isNaN(date);
11149
+ }
11150
+
11151
+ /**
11152
+ * Compares two date strings
11153
+ * @param {string} dateA - First date string
11154
+ * @param {string} dateB - Second date string
11155
+ * @returns {number} -1 if dateA is earlier, 0 if equal, 1 if dateA is later
11156
+ */
11157
+ function compareDates$1(dateA, dateB) {
11158
+ if (!isValidDateString$1(dateA) || !isValidDateString$1(dateB)) {
11159
+ throw new Error(`Invalid date string format. A: ${dateA} B: ${dateB})`);
11160
+ }
11161
+
11162
+ const timeA = new Date(normalizeDateTime$1(dateA)).getTime();
11163
+ const timeB = new Date(normalizeDateTime$1(dateB)).getTime();
11164
+
11165
+ if (timeA < timeB) return -1;
11166
+ if (timeA > timeB) return 1;
11167
+ return 0;
11168
+ }
11169
+
11170
+ var DateUtils$1 = {
11171
+ formatAge: formatAge$1,
11172
+ isValidDateString: isValidDateString$1,
11173
+ compareDates: compareDates$1,
11174
+ normalizeDateTime: normalizeDateTime$1,
11175
+ getTimeDifference: getTimeDifference$1,
11176
+ formatTimeDifference: formatTimeDifference$1
11177
+ };
11178
+
11179
+ /**
11180
+ * Component: CLI Contract Utilities
11181
+ * Block-UUID: a57b72a0-0d95-44a2-8f3f-ab6ee84b3197
11182
+ * Parent-UUID: 9050e244-793a-4dc6-8571-b96f38927f69
11183
+ * Version: 1.1.0
11184
+ * Description: Utilities for parsing GitSense Chat CLI contract messages and determining save modes for code blocks.
11185
+ * Language: JavaScript
11186
+ * Created-at: 2026-02-27T02:26:15.078Z
11187
+ * Authors: GLM-4.7 (v1.0.0), GLM-4.7 (v1.1.0)
11188
+ */
11189
+
11190
+ const CodeBlockUtils$7 = CodeBlockUtils$8;
11191
+
11192
+ /**
11193
+ * Parses a contract message object to extract the contract data.
11194
+ * Handles cases where data might be in 'content' (as JSON string) or 'metadata'.
11195
+ *
11196
+ * @param {Object} message - The chat message object.
11197
+ * @returns {Object|null} The parsed contract data object or null if invalid.
11198
+ */
11199
+ function parseContractMessage(message) {
11200
+ if (!message) {
11201
+ return null;
11202
+ }
11203
+
11204
+ // We expect the message type to be 'gsc-cli-contract'
11205
+ if (message.type !== 'gsc-cli-contract') {
11206
+ return null;
11207
+ }
11208
+
11209
+ const content = message.message || '';
11210
+ const lines = content.split('\n');
11211
+
11212
+ const contractData = {};
11213
+ let inTable = false;
11214
+ let foundHeader = false;
11215
+
11216
+ for (let i = 0; i < lines.length; i++) {
11217
+ const line = lines[i].trim();
11218
+
11219
+ // Check for the CLI Contract header
11220
+ if (line.startsWith('### CLI Contract')) {
11221
+ foundHeader = true;
11222
+ continue;
11223
+ }
11224
+
11225
+ // If we haven't found the header yet, keep looking
11226
+ if (!foundHeader) {
11227
+ continue;
11228
+ }
11229
+
11230
+ // Check for table separator (e.g., | :--- | :--- |)
11231
+ if (line.includes('---')) {
11232
+ inTable = true;
11233
+ continue;
11234
+ }
11235
+
11236
+ // Parse table rows
11237
+ if (inTable && line.startsWith('|')) {
11238
+ // Remove leading/trailing pipes and split by pipe
11239
+ const parts = line.substring(1, line.length - 1).split('|').map(p => p.trim());
11240
+
11241
+ if (parts.length >= 2) {
11242
+ const key = parts[0].replace(/\*\*/g, '').toLowerCase(); // Remove bold markdown and normalize
11243
+ const value = parts[1];
11244
+
11245
+ if (key === 'uuid') contractData.uuid = value;
11246
+ else if (key === 'expires at') contractData.expiresAt = value;
11247
+ else if (key === 'status') contractData.status = value;
11248
+ else if (key === 'description') contractData.description = value;
11249
+ }
11250
+ }
11251
+ }
11252
+
11253
+ return contractData;
11254
+ }
11255
+
11256
+ /**
11257
+ * Checks if a message is a contract message.
11258
+ *
11259
+ * @param {Object} message - The chat message object.
11260
+ * @returns {boolean} True if the message is a contract message.
11261
+ */
11262
+ function isContractMessage(message) {
11263
+ return message && message.type === 'gsc-cli-contract';
11264
+ }
11265
+
11266
+ /**
11267
+ * Determines if a contract is currently active based on its expiration time.
11268
+ *
11269
+ * @param {Object} contractData - The contract data object (must contain expiresAt).
11270
+ * @returns {boolean} True if the contract is active, false otherwise.
11271
+ */
11272
+ function isContractActive(contractData) {
11273
+ if (!contractData || !contractData.expiresAt) {
11274
+ return false;
11275
+ }
11276
+
11277
+ const now = Date.now();
11278
+ const expiresAt = new Date(contractData.expiresAt).getTime();
11279
+
11280
+ return now < expiresAt;
11281
+ }
11282
+
11283
+ /**
11284
+ * Determines the save mode (update vs new-file) based on the code content.
11285
+ * Parses the code block header to check for a Parent-UUID.
11286
+ *
11287
+ * @param {string} rawCodeContent - The full content of the code block (including header).
11288
+ * @returns {Object} An object { mode: 'update'|'new-file', metadata: Object }.
11289
+ */
11290
+ function determineSaveMode(rawCodeContent) {
11291
+ const { blocks } = CodeBlockUtils$7.processCodeBlocks(rawCodeContent, { silent: true });
11292
+
11293
+ if (!blocks || blocks.length === 0) {
11294
+ return { mode: 'unknown', metadata: null };
11295
+ }
11296
+
11297
+ const block = blocks[0];
11298
+ const header = block.header || {};
11299
+ const parentUUID = header['Parent-UUID'];
11300
+
11301
+ let mode = 'new-file';
11302
+
11303
+ // If Parent-UUID exists and is not N/A, it's an update
11304
+ if (parentUUID && parentUUID !== 'N/A') {
11305
+ mode = 'update';
11306
+ }
11307
+
11308
+ return {
11309
+ mode,
11310
+ metadata: {
11311
+ blockUUID: header['Block-UUID'],
11312
+ parentUUID: parentUUID,
11313
+ language: block.language
11314
+ }
11315
+ };
11316
+ }
11317
+
11318
+ /**
11319
+ * Extracts key metadata from a code block content.
11320
+ *
11321
+ * @param {string} rawCodeContent - The full content of the code block.
11322
+ * @returns {Object|null} Metadata object or null if parsing fails.
11323
+ */
11324
+ function extractCodeMetadata(rawCodeContent) {
11325
+ const result = determineSaveMode(rawCodeContent);
11326
+ return result.metadata;
11327
+ }
11328
+
11329
+ /**
11330
+ * Formats the remaining time until expiration.
11331
+ *
11332
+ * @param {string|Date} expiresAt - The expiration timestamp.
11333
+ * @returns {string} Formatted string (e.g., "45m", "2h", "1d").
11334
+ */
11335
+ function formatTimeRemaining(expiresAt) {
11336
+ const now = Date.now();
11337
+ const expiry = new Date(expiresAt).getTime();
11338
+ const diffMs = expiry - now;
11339
+
11340
+ if (diffMs <= 0) return 'Expired';
11341
+
11342
+ const diffMins = Math.floor(diffMs / 60000);
11343
+
11344
+ if (diffMins < 60) return `${diffMins}m`;
11345
+
11346
+ const diffHours = Math.floor(diffMins / 60);
11347
+ if (diffHours < 24) return `${diffHours}h`;
11348
+
11349
+ const diffDays = Math.floor(diffHours / 24);
11350
+ return `${diffDays}d`;
11351
+ }
11352
+
11353
+ var CLIContractUtils$1 = {
11354
+ parseContractMessage,
11355
+ isContractMessage,
11356
+ isContractActive,
11357
+ determineSaveMode,
11358
+ extractCodeMetadata,
11359
+ formatTimeRemaining
11360
+ };
11361
+
11063
11362
  /*
11064
11363
  * Component: ContextUtils
11065
11364
  * Block-UUID: 534c348d-a11f-4de6-ad15-f33068d51fb8
@@ -11071,7 +11370,7 @@ var CodeBlockUtils$7 = {
11071
11370
  * 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), Qwen 3 Coder 480B - Cerebras (v1.4.0)
11072
11371
  */
11073
11372
 
11074
- const CodeBlockUtils$6 = CodeBlockUtils$7;
11373
+ const CodeBlockUtils$6 = CodeBlockUtils$8;
11075
11374
  const MessageUtils$2 = MessageUtils$3;
11076
11375
 
11077
11376
  /**
@@ -11531,7 +11830,7 @@ var constants = {
11531
11830
  * Authors: Gemini 2.5 Flash (v1.0.0)
11532
11831
  */
11533
11832
 
11534
- const CodeBlockUtils$5 = CodeBlockUtils$7;
11833
+ const CodeBlockUtils$5 = CodeBlockUtils$8;
11535
11834
  const GSToolBlockUtils$1 = GSToolBlockUtils$3;
11536
11835
  const JsonUtils$1 = JsonUtils$2;
11537
11836
  const { ANALYZE_HEADER_PREFIX } = constants;
@@ -11841,7 +12140,7 @@ const fs$7 = require$$0.promises;
11841
12140
  const path$5 = require$$1;
11842
12141
  const { getAnalyzerInstructionsContent: getAnalyzerInstructionsContent$2 } = instructionLoader;
11843
12142
  const { preprocessJsonForValidation: preprocessJsonForValidation$4 } = jsonParser;
11844
- const CodeBlockUtils$4 = CodeBlockUtils$7;
12143
+ const CodeBlockUtils$4 = CodeBlockUtils$8;
11845
12144
 
11846
12145
  /**
11847
12146
  * Reads and parses the config.json file in a directory.
@@ -12137,18 +12436,18 @@ var saver = {
12137
12436
 
12138
12437
  /**
12139
12438
  * Component: AnalyzerUtils Schema Loader
12140
- * Block-UUID: bf25c501-f9e1-4e5b-ad22-9ed24ba50787
12141
- * Parent-UUID: 66208fdc-2c80-4264-8500-06d5f4db103a
12142
- * Version: 1.4.1
12439
+ * Block-UUID: 20ac37ba-6ff7-462e-9e08-3204df118b03
12440
+ * Parent-UUID: bf25c501-f9e1-4e5b-ad22-9ed24ba50787
12441
+ * Version: 1.5.0
12143
12442
  * Description: Provides utility functions for retrieving and deducing JSON schemas for analyzers.
12144
12443
  * Language: JavaScript
12145
- * Created-at: 2025-11-23T05:40:43.016Z
12146
- * Authors: Gemini 2.5 Flash (v1.0.0), Gemini 2.5 Pro (v1.1.0), Claude Haiku 4.5 (v1.2.0), Claude Haiku 4.5 (v1.3.0), Qwen 3 Coder 480B - Cerebras (v1.4.0), GLM-4.6 (v1.4.1)
12444
+ * Created-at: 2026-02-15T06:21:20.089Z
12445
+ * Authors: Gemini 2.5 Flash (v1.0.0), Gemini 2.5 Pro (v1.1.0), Claude Haiku 4.5 (v1.2.0), Claude Haiku 4.5 (v1.3.0), Qwen 3 Coder 480B - Cerebras (v1.4.0), GLM-4.6 (v1.4.1), GLM-4.7 (v1.5.0)
12147
12446
  */
12148
12447
 
12149
12448
  const fs$5 = require$$0.promises;
12150
12449
  const path$3 = require$$1;
12151
- const CodeBlockUtils$3 = CodeBlockUtils$7;
12450
+ const CodeBlockUtils$3 = CodeBlockUtils$8;
12152
12451
  const { preprocessJsonForValidation: preprocessJsonForValidation$3 } = jsonParser;
12153
12452
 
12154
12453
  /**
@@ -12163,35 +12462,39 @@ const { preprocessJsonForValidation: preprocessJsonForValidation$3 } = jsonParse
12163
12462
  function parseMetadataDefinitions(markdownContent) {
12164
12463
  const definitions = new Map();
12165
12464
 
12166
- // Match the "### Custom Metadata Definitions" section until the next code block or section
12167
- const sectionRegex = /### Custom Metadata Definitions\s*([\s\S]*?)(?=```|\n##|\n---)/;
12168
- const match = markdownContent.match(sectionRegex);
12169
-
12170
- if (!match || !match[1]) {
12171
- return definitions;
12172
- }
12173
-
12174
- const definitionBlock = match[1];
12465
+ // Match both "### Fixed Metadata Definitions" and "### Custom Metadata Definitions" sections
12466
+ const sectionHeaders = ['### Fixed Metadata Definitions', '### Custom Metadata Definitions'];
12175
12467
 
12176
- // Regex to match both formats:
12177
- // Format 1: * `fieldName` (type): description
12178
- // Format 2: * fieldName (type): description
12179
- // Capture groups:
12180
- // Group 1: backtick-wrapped field name (if present)
12181
- // Group 2: non-backtick field name (if present)
12182
- // Group 3: field type
12183
- // Group 4: description
12184
- const lineRegex = /^\s*\*\s+(?:`([^`]+)`|([a-zA-Z0-9_-]+))\s+\(([^)]+)\):\s*(.+)/gm;
12468
+ for (const sectionHeader of sectionHeaders) {
12469
+ const sectionRegex = new RegExp(`${sectionHeader}\\s*([\\s\\S]*?)(?=\`\`\\|\\n##|\\n---)`);
12470
+ const match = markdownContent.match(sectionRegex);
12185
12471
 
12186
- let lineMatch;
12187
- while ((lineMatch = lineRegex.exec(definitionBlock)) !== null) {
12188
- // Extract field name from either group 1 (backtick-wrapped) or group 2 (plain)
12189
- const fieldName = (lineMatch[1] || lineMatch[2]).trim();
12190
- const fieldType = lineMatch[3].trim();
12191
- const description = lineMatch[4].trim();
12472
+ if (!match || !match[1]) {
12473
+ continue;
12474
+ }
12192
12475
 
12193
- if (fieldName && fieldType && description) {
12194
- definitions.set(fieldName, { type: fieldType, description });
12476
+ const definitionBlock = match[1];
12477
+
12478
+ // Regex to match both formats:
12479
+ // Format 1: * `fieldName` (type): description
12480
+ // Format 2: * fieldName (type): description
12481
+ // Capture groups:
12482
+ // Group 1: backtick-wrapped field name (if present)
12483
+ // Group 2: non-backtick field name (if present)
12484
+ // Group 3: field type
12485
+ // Group 4: description
12486
+ const lineRegex = /^\s*\*\s+(?:`([^`]+)`|([a-zA-Z0-9_-]+))\s+\(([^)]+)\):\s*(.+)/gm;
12487
+
12488
+ let lineMatch;
12489
+ while ((lineMatch = lineRegex.exec(definitionBlock)) !== null) {
12490
+ // Extract field name from either group 1 (backtick-wrapped) or group 2 (plain)
12491
+ const fieldName = (lineMatch[1] || lineMatch[2]).trim();
12492
+ const fieldType = lineMatch[3].trim();
12493
+ const description = lineMatch[4].trim();
12494
+
12495
+ if (fieldName && fieldType && description) {
12496
+ definitions.set(fieldName, { type: fieldType, description });
12497
+ }
12195
12498
  }
12196
12499
  }
12197
12500
 
@@ -12622,7 +12925,7 @@ var defaultPromptLoader = {
12622
12925
 
12623
12926
  const fs$2 = require$$0.promises;
12624
12927
  const path = require$$1;
12625
- const CodeBlockUtils$2 = CodeBlockUtils$7;
12928
+ const CodeBlockUtils$2 = CodeBlockUtils$8;
12626
12929
  const { preprocessJsonForValidation: preprocessJsonForValidation$2 } = jsonParser;
12627
12930
  const { isValidDirName: isValidDirName$1 } = discovery;
12628
12931
  const { readConfig } = discovery;
@@ -12808,7 +13111,7 @@ var updater = {
12808
13111
  */
12809
13112
 
12810
13113
  require$$0.promises;
12811
- const CodeBlockUtils$1 = CodeBlockUtils$7;
13114
+ const CodeBlockUtils$1 = CodeBlockUtils$8;
12812
13115
  const { preprocessJsonForValidation: preprocessJsonForValidation$1 } = jsonParser;
12813
13116
  const { isValidDirName } = discovery;
12814
13117
  const { saveConfiguration: saveConfiguration$1 } = saver;
@@ -13015,119 +13318,6 @@ var LLMUtils$1 = {
13015
13318
  estimateTokens: estimateTokens$1,
13016
13319
  };
13017
13320
 
13018
- /**
13019
- * Component: Date Utilities
13020
- * Block-UUID: fef3b0f4-8055-4690-9336-e68a9cc33a61
13021
- * Parent-UUID: 716e5ce9-84df-4f12-89e7-4a28e4a39a81
13022
- * Version: 1.0.0
13023
- * Description: Date formatting and manipulation utilities for GitSense Chat
13024
- * Language: JavaScript
13025
- * Created-at: 2025-10-11T23:26:20.815Z
13026
- * Authors: Claude-3.5-Sonnet (v1.0.0), Qwen 3 Coder 480B - Cerebras (v1.0.0)
13027
- */
13028
-
13029
- /**
13030
- * Ensures a date string has a timezone indicator
13031
- * @param {string} dateString - Date string in format "YYYY-MM-DD(T| )HH:mm:ss.SSS"
13032
- * @returns {string} Date string with 'Z' timezone indicator if not present
13033
- */
13034
- function normalizeDateTime$1(dateString) {
13035
- return dateString.includes('Z') ? dateString : dateString + 'Z';
13036
- }
13037
-
13038
- /**
13039
- * Calculates the time difference between now and a given date
13040
- * @param {string} dateString - Date string to compare against current time
13041
- * @returns {number} Difference in seconds
13042
- */
13043
- function getTimeDifference$1(dateString) {
13044
- const now = new Date();
13045
- const date = new Date(normalizeDateTime$1(dateString));
13046
- return Math.floor((now - date) / 1000);
13047
- }
13048
-
13049
- /**
13050
- * Formats a time difference in seconds to a human-readable string
13051
- * @param {number} diff - Time difference in seconds
13052
- * @returns {string} Formatted string (e.g., "5s ago", "2m ago", "3h ago", "2d ago")
13053
- */
13054
- function formatTimeDifference$1(diff) {
13055
- if (diff < 60) {
13056
- return `${diff}s ago`;
13057
- } else if (diff < 3600) {
13058
- const minutes = Math.floor(diff / 60);
13059
- return `${minutes}m ago`;
13060
- } else if (diff < 86400) {
13061
- const hours = Math.floor(diff / 3600);
13062
- return `${hours}h ago`;
13063
- } else {
13064
- const days = Math.floor(diff / 86400);
13065
- return `${days}d ago`;
13066
- }
13067
- }
13068
-
13069
- /**
13070
- * Formats a date string into a relative time string
13071
- * @param {string} dateString - Date string to format
13072
- * @returns {string} Formatted relative time string
13073
- */
13074
- function formatAge$1(dateString) {
13075
- if (!dateString) {
13076
- return 'N/A';
13077
- }
13078
-
13079
- try {
13080
- const diff = getTimeDifference$1(dateString);
13081
- return formatTimeDifference$1(diff);
13082
- } catch (error) {
13083
- console.error('Error formatting date:', error);
13084
- return 'Invalid date';
13085
- }
13086
- }
13087
-
13088
- /**
13089
- * Validates a date string format
13090
- * @param {string} dateString - Date string to validate
13091
- * @returns {boolean} True if date string is valid
13092
- */
13093
- function isValidDateString$1(dateString) {
13094
- if (!dateString) return false;
13095
-
13096
- const pattern = /^\d{4}-\d{2}-\d{2}(T| )\d{2}:\d{2}:\d{2}\.\d{3}Z?$/;
13097
- if (!pattern.test(dateString)) return false;
13098
-
13099
- const date = new Date(normalizeDateTime$1(dateString));
13100
- return date instanceof Date && !isNaN(date);
13101
- }
13102
-
13103
- /**
13104
- * Compares two date strings
13105
- * @param {string} dateA - First date string
13106
- * @param {string} dateB - Second date string
13107
- * @returns {number} -1 if dateA is earlier, 0 if equal, 1 if dateA is later
13108
- */
13109
- function compareDates$1(dateA, dateB) {
13110
- if (!isValidDateString$1(dateA) || !isValidDateString$1(dateB)) {
13111
- throw new Error(`Invalid date string format. A: ${dateA} B: ${dateB})`);
13112
- }
13113
-
13114
- const timeA = new Date(normalizeDateTime$1(dateA)).getTime();
13115
- const timeB = new Date(normalizeDateTime$1(dateB)).getTime();
13116
-
13117
- if (timeA < timeB) return -1;
13118
- if (timeA > timeB) return 1;
13119
- return 0;
13120
- }
13121
-
13122
- var DateUtils$1 = {
13123
- formatAge: formatAge$1,
13124
- isValidDateString: isValidDateString$1,
13125
- compareDates: compareDates$1,
13126
- normalizeDateTime: normalizeDateTime$1,
13127
- getTimeDifference: getTimeDifference$1,
13128
- formatTimeDifference: formatTimeDifference$1
13129
- };
13130
-
13131
13321
  /**
13132
13322
  * Component: Formatter Utilities
13133
13323
  * Block-UUID: 8512c809-87b0-4f90-af9d-b3dca204c4de
@@ -13338,6 +13528,9 @@ const h$1 = {
13338
13528
  createArticle: (params) => {
13339
13529
  return createElement("article", params);
13340
13530
  },
13531
+ createBlockquote: (params) => {
13532
+ return createElement("blockquote", params);
13533
+ },
13341
13534
  createBr: () => {
13342
13535
  return createElement("br");
13343
13536
  },
@@ -26370,15 +26563,16 @@ var CompactChatUtils$1 = {
26370
26563
  * Component: GitSenseChatUtils
26371
26564
  * Block-UUID: c1b6c4d3-7959-4eb6-8022-6cd7aa59240d
26372
26565
  * Parent-UUID: 1793b3a8-4881-4306-bfdf-673eef503679
26373
- * Version: 2.7.0
26374
- * 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, EnvUtils, ObjectUtils, MetaRawResultUtils, and CompactChatUtils.
26566
+ * Version: 2.8.0
26567
+ * 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, EnvUtils, ObjectUtils, MetaRawResultUtils, CompactChatUtils, and CLIContractUtils.
26375
26568
  * Language: JavaScript
26376
26569
  * Created-at: 2025-10-17T17:13:04.663Z
26377
- * 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), Qwen 3 Coder 480B - Cerebras (v2.2.0), Qwen 3 Coder 480B - Cerebras (v2.2.1), Claude Haiku 4.5 (v2.3.0), Qwen 3 Coder 480B - Cerebras (v2.4.0), Qwen 3 Coder 480B - Cerebras (v2.5.0), GLM-4.6 (v2.6.0), GLM-4.6 (v2.7.0)
26570
+ * 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), Qwen 3 Coder 480B - Cerebras (v2.2.0), Qwen 3 Coder 480B - Cerebras (v2.2.1), Claude Haiku 4.5 (v2.3.0), Qwen 3 Coder 480B - Cerebras (v2.4.0), Qwen 3 Coder 480B - Cerebras (v2.5.0), GLM-4.6 (v2.6.0), GLM-4.6 (v2.7.0), GLM-4.7 (v2.8.0)
26378
26571
  */
26379
26572
 
26380
26573
  const ChatUtils = ChatUtils$2;
26381
- const CodeBlockUtils = CodeBlockUtils$7;
26574
+ const CLIContractUtils = CLIContractUtils$1;
26575
+ const CodeBlockUtils = CodeBlockUtils$8;
26382
26576
  const ContextUtils = ContextUtils$2;
26383
26577
  const MessageUtils = MessageUtils$3;
26384
26578
  const AnalysisBlockUtils = AnalysisBlockUtils$3;
@@ -26794,6 +26988,7 @@ var GitSenseChatUtils_1 = {
26794
26988
  GSToolBlockUtils,
26795
26989
  JsonUtils,
26796
26990
  ConfigUtils,
26991
+ CLIContractUtils,
26797
26992
  DateUtils,
26798
26993
  LanguageNameUtils,
26799
26994
  FormatterUtils,
@@ -26944,6 +27139,14 @@ var GitSenseChatUtils_1 = {
26944
27139
  parseTableRow,
26945
27140
  parseSize,
26946
27141
  parseTokens,
27142
+
27143
+ // Contract Utilities (from CLIContractUtils)
27144
+ parseContractMessage: CLIContractUtils.parseContractMessage,
27145
+ isContractMessage: CLIContractUtils.isContractMessage,
27146
+ isContractActive: CLIContractUtils.isContractActive,
27147
+ determineSaveMode: CLIContractUtils.determineSaveMode,
27148
+ extractCodeMetadata: CLIContractUtils.extractCodeMetadata,
27149
+ formatTimeRemaining: CLIContractUtils.formatTimeRemaining,
26947
27150
  };
26948
27151
 
26949
27152
  var GitSenseChatUtils$1 = /*@__PURE__*/getDefaultExportFromCjs(GitSenseChatUtils_1);