@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.
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Component: AnalyzerUtils Schema Loader
3
- * Block-UUID: bf25c501-f9e1-4e5b-ad22-9ed24ba50787
4
- * Parent-UUID: 66208fdc-2c80-4264-8500-06d5f4db103a
5
- * Version: 1.4.1
3
+ * Block-UUID: 20ac37ba-6ff7-462e-9e08-3204df118b03
4
+ * Parent-UUID: bf25c501-f9e1-4e5b-ad22-9ed24ba50787
5
+ * Version: 1.5.0
6
6
  * Description: Provides utility functions for retrieving and deducing JSON schemas for analyzers.
7
7
  * Language: JavaScript
8
- * Created-at: 2025-11-23T05:40:43.016Z
9
- * 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)
8
+ * Created-at: 2026-02-15T06:21:20.089Z
9
+ * 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)
10
10
  */
11
11
 
12
12
 
@@ -27,35 +27,39 @@ const { preprocessJsonForValidation } = require('./jsonParser');
27
27
  function parseMetadataDefinitions(markdownContent) {
28
28
  const definitions = new Map();
29
29
 
30
- // Match the "### Custom Metadata Definitions" section until the next code block or section
31
- const sectionRegex = /### Custom Metadata Definitions\s*([\s\S]*?)(?=```|\n##|\n---)/;
32
- const match = markdownContent.match(sectionRegex);
30
+ // Match both "### Fixed Metadata Definitions" and "### Custom Metadata Definitions" sections
31
+ const sectionHeaders = ['### Fixed Metadata Definitions', '### Custom Metadata Definitions'];
32
+
33
+ for (const sectionHeader of sectionHeaders) {
34
+ const sectionRegex = new RegExp(`${sectionHeader}\\s*([\\s\\S]*?)(?=\`\`\\|\\n##|\\n---)`);
35
+ const match = markdownContent.match(sectionRegex);
33
36
 
34
- if (!match || !match[1]) {
35
- return definitions;
36
- }
37
+ if (!match || !match[1]) {
38
+ continue;
39
+ }
37
40
 
38
- const definitionBlock = match[1];
39
-
40
- // Regex to match both formats:
41
- // Format 1: * `fieldName` (type): description
42
- // Format 2: * fieldName (type): description
43
- // Capture groups:
44
- // Group 1: backtick-wrapped field name (if present)
45
- // Group 2: non-backtick field name (if present)
46
- // Group 3: field type
47
- // Group 4: description
48
- const lineRegex = /^\s*\*\s+(?:`([^`]+)`|([a-zA-Z0-9_-]+))\s+\(([^)]+)\):\s*(.+)/gm;
49
-
50
- let lineMatch;
51
- while ((lineMatch = lineRegex.exec(definitionBlock)) !== null) {
52
- // Extract field name from either group 1 (backtick-wrapped) or group 2 (plain)
53
- const fieldName = (lineMatch[1] || lineMatch[2]).trim();
54
- const fieldType = lineMatch[3].trim();
55
- const description = lineMatch[4].trim();
56
-
57
- if (fieldName && fieldType && description) {
58
- definitions.set(fieldName, { type: fieldType, description });
41
+ const definitionBlock = match[1];
42
+
43
+ // Regex to match both formats:
44
+ // Format 1: * `fieldName` (type): description
45
+ // Format 2: * fieldName (type): description
46
+ // Capture groups:
47
+ // Group 1: backtick-wrapped field name (if present)
48
+ // Group 2: non-backtick field name (if present)
49
+ // Group 3: field type
50
+ // Group 4: description
51
+ const lineRegex = /^\s*\*\s+(?:`([^`]+)`|([a-zA-Z0-9_-]+))\s+\(([^)]+)\):\s*(.+)/gm;
52
+
53
+ let lineMatch;
54
+ while ((lineMatch = lineRegex.exec(definitionBlock)) !== null) {
55
+ // Extract field name from either group 1 (backtick-wrapped) or group 2 (plain)
56
+ const fieldName = (lineMatch[1] || lineMatch[2]).trim();
57
+ const fieldType = lineMatch[3].trim();
58
+ const description = lineMatch[4].trim();
59
+
60
+ if (fieldName && fieldType && description) {
61
+ definitions.set(fieldName, { type: fieldType, description });
62
+ }
59
63
  }
60
64
  }
61
65
 
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Component: CLI Contract Utilities
3
+ * Block-UUID: a57b72a0-0d95-44a2-8f3f-ab6ee84b3197
4
+ * Parent-UUID: 9050e244-793a-4dc6-8571-b96f38927f69
5
+ * Version: 1.1.0
6
+ * Description: Utilities for parsing GitSense Chat CLI contract messages and determining save modes for code blocks.
7
+ * Language: JavaScript
8
+ * Created-at: 2026-02-27T02:26:15.078Z
9
+ * Authors: GLM-4.7 (v1.0.0), GLM-4.7 (v1.1.0)
10
+ */
11
+
12
+
13
+ const CodeBlockUtils = require('./CodeBlockUtils');
14
+ const DateUtils = require('./DateUtils');
15
+
16
+ /**
17
+ * Parses a contract message object to extract the contract data.
18
+ * Handles cases where data might be in 'content' (as JSON string) or 'metadata'.
19
+ *
20
+ * @param {Object} message - The chat message object.
21
+ * @returns {Object|null} The parsed contract data object or null if invalid.
22
+ */
23
+ function parseContractMessage(message) {
24
+ if (!message) {
25
+ return null;
26
+ }
27
+
28
+ // We expect the message type to be 'gsc-cli-contract'
29
+ if (message.type !== 'gsc-cli-contract') {
30
+ return null;
31
+ }
32
+
33
+ const content = message.message || '';
34
+ const lines = content.split('\n');
35
+
36
+ const contractData = {};
37
+ let inTable = false;
38
+ let foundHeader = false;
39
+
40
+ for (let i = 0; i < lines.length; i++) {
41
+ const line = lines[i].trim();
42
+
43
+ // Check for the CLI Contract header
44
+ if (line.startsWith('### CLI Contract')) {
45
+ foundHeader = true;
46
+ continue;
47
+ }
48
+
49
+ // If we haven't found the header yet, keep looking
50
+ if (!foundHeader) {
51
+ continue;
52
+ }
53
+
54
+ // Check for table separator (e.g., | :--- | :--- |)
55
+ if (line.includes('---')) {
56
+ inTable = true;
57
+ continue;
58
+ }
59
+
60
+ // Parse table rows
61
+ if (inTable && line.startsWith('|')) {
62
+ // Remove leading/trailing pipes and split by pipe
63
+ const parts = line.substring(1, line.length - 1).split('|').map(p => p.trim());
64
+
65
+ if (parts.length >= 2) {
66
+ const key = parts[0].replace(/\*\*/g, '').toLowerCase(); // Remove bold markdown and normalize
67
+ const value = parts[1];
68
+
69
+ if (key === 'uuid') contractData.uuid = value;
70
+ else if (key === 'expires at') contractData.expiresAt = value;
71
+ else if (key === 'status') contractData.status = value;
72
+ else if (key === 'description') contractData.description = value;
73
+ }
74
+ }
75
+ }
76
+
77
+ return contractData;
78
+ }
79
+
80
+ /**
81
+ * Checks if a message is a contract message.
82
+ *
83
+ * @param {Object} message - The chat message object.
84
+ * @returns {boolean} True if the message is a contract message.
85
+ */
86
+ function isContractMessage(message) {
87
+ return message && message.type === 'gsc-cli-contract';
88
+ }
89
+
90
+ /**
91
+ * Determines if a contract is currently active based on its expiration time.
92
+ *
93
+ * @param {Object} contractData - The contract data object (must contain expiresAt).
94
+ * @returns {boolean} True if the contract is active, false otherwise.
95
+ */
96
+ function isContractActive(contractData) {
97
+ if (!contractData || !contractData.expiresAt) {
98
+ return false;
99
+ }
100
+
101
+ const now = Date.now();
102
+ const expiresAt = new Date(contractData.expiresAt).getTime();
103
+
104
+ return now < expiresAt;
105
+ }
106
+
107
+ /**
108
+ * Determines the save mode (update vs new-file) based on the code content.
109
+ * Parses the code block header to check for a Parent-UUID.
110
+ *
111
+ * @param {string} rawCodeContent - The full content of the code block (including header).
112
+ * @returns {Object} An object { mode: 'update'|'new-file', metadata: Object }.
113
+ */
114
+ function determineSaveMode(rawCodeContent) {
115
+ const { blocks } = CodeBlockUtils.processCodeBlocks(rawCodeContent, { silent: true });
116
+
117
+ if (!blocks || blocks.length === 0) {
118
+ return { mode: 'unknown', metadata: null };
119
+ }
120
+
121
+ const block = blocks[0];
122
+ const header = block.header || {};
123
+ const parentUUID = header['Parent-UUID'];
124
+
125
+ let mode = 'new-file';
126
+
127
+ // If Parent-UUID exists and is not N/A, it's an update
128
+ if (parentUUID && parentUUID !== 'N/A') {
129
+ mode = 'update';
130
+ }
131
+
132
+ return {
133
+ mode,
134
+ metadata: {
135
+ blockUUID: header['Block-UUID'],
136
+ parentUUID: parentUUID,
137
+ language: block.language
138
+ }
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Extracts key metadata from a code block content.
144
+ *
145
+ * @param {string} rawCodeContent - The full content of the code block.
146
+ * @returns {Object|null} Metadata object or null if parsing fails.
147
+ */
148
+ function extractCodeMetadata(rawCodeContent) {
149
+ const result = determineSaveMode(rawCodeContent);
150
+ return result.metadata;
151
+ }
152
+
153
+ /**
154
+ * Formats the remaining time until expiration.
155
+ *
156
+ * @param {string|Date} expiresAt - The expiration timestamp.
157
+ * @returns {string} Formatted string (e.g., "45m", "2h", "1d").
158
+ */
159
+ function formatTimeRemaining(expiresAt) {
160
+ const now = Date.now();
161
+ const expiry = new Date(expiresAt).getTime();
162
+ const diffMs = expiry - now;
163
+
164
+ if (diffMs <= 0) return 'Expired';
165
+
166
+ const diffMins = Math.floor(diffMs / 60000);
167
+
168
+ if (diffMins < 60) return `${diffMins}m`;
169
+
170
+ const diffHours = Math.floor(diffMins / 60);
171
+ if (diffHours < 24) return `${diffHours}h`;
172
+
173
+ const diffDays = Math.floor(diffHours / 24);
174
+ return `${diffDays}d`;
175
+ }
176
+
177
+ module.exports = {
178
+ parseContractMessage,
179
+ isContractMessage,
180
+ isContractActive,
181
+ determineSaveMode,
182
+ extractCodeMetadata,
183
+ formatTimeRemaining
184
+ };
@@ -502,7 +502,7 @@ function fixTextCodeBlocks(text) {
502
502
  const [fieldPart, valuePart] = line.split(':').map(p => p.trim());
503
503
 
504
504
  // Skip if N/A or contains unexpected characters
505
- if (valuePart === 'N/A' || valuePart.match(/\(/)) {
505
+ if (valuePart === 'N/A' || !valuePart.match(/\w-/)) {
506
506
  return line;
507
507
  }
508
508
  // Validate UUID
package/src/DomUtils.js CHANGED
@@ -154,6 +154,9 @@ const h = {
154
154
  createArticle: (params) => {
155
155
  return createElement("article", params);
156
156
  },
157
+ createBlockquote: (params) => {
158
+ return createElement("blockquote", params);
159
+ },
157
160
  createBr: () => {
158
161
  return createElement("br");
159
162
  },
@@ -2,15 +2,16 @@
2
2
  * Component: GitSenseChatUtils
3
3
  * Block-UUID: c1b6c4d3-7959-4eb6-8022-6cd7aa59240d
4
4
  * Parent-UUID: 1793b3a8-4881-4306-bfdf-673eef503679
5
- * Version: 2.7.0
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, EnvUtils, ObjectUtils, MetaRawResultUtils, and CompactChatUtils.
5
+ * Version: 2.8.0
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, EnvUtils, ObjectUtils, MetaRawResultUtils, CompactChatUtils, and CLIContractUtils.
7
7
  * Language: JavaScript
8
8
  * Created-at: 2025-10-17T17:13:04.663Z
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), 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)
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), 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)
10
10
  */
11
11
 
12
12
 
13
13
  const ChatUtils = require('./ChatUtils');
14
+ const CLIContractUtils = require('./CLIContractUtils');
14
15
  const CodeBlockUtils = require('./CodeBlockUtils');
15
16
  const ContextUtils = require('./ContextUtils');
16
17
  const MessageUtils = require('./MessageUtils');
@@ -427,6 +428,7 @@ module.exports = {
427
428
  GSToolBlockUtils,
428
429
  JsonUtils,
429
430
  ConfigUtils,
431
+ CLIContractUtils,
430
432
  DateUtils,
431
433
  LanguageNameUtils,
432
434
  FormatterUtils,
@@ -577,4 +579,12 @@ module.exports = {
577
579
  parseTableRow,
578
580
  parseSize,
579
581
  parseTokens,
582
+
583
+ // Contract Utilities (from CLIContractUtils)
584
+ parseContractMessage: CLIContractUtils.parseContractMessage,
585
+ isContractMessage: CLIContractUtils.isContractMessage,
586
+ isContractActive: CLIContractUtils.isContractActive,
587
+ determineSaveMode: CLIContractUtils.determineSaveMode,
588
+ extractCodeMetadata: CLIContractUtils.extractCodeMetadata,
589
+ formatTimeRemaining: CLIContractUtils.formatTimeRemaining,
580
590
  };