@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.
- package/dist/gsc-utils.cjs.js +361 -158
- package/dist/gsc-utils.esm.js +361 -158
- package/package.json +1 -1
- package/src/AnalysisBlockUtils.js +5 -2
- package/src/AnalyzerUtils/schemaLoader.js +36 -32
- package/src/CLIContractUtils.js +184 -0
- package/src/CodeBlockUtils/blockProcessor.js +1 -1
- package/src/DomUtils.js +3 -0
- package/src/GitSenseChatUtils.js +13 -3
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Component: AnalyzerUtils Schema Loader
|
|
3
|
-
* Block-UUID:
|
|
4
|
-
* Parent-UUID:
|
|
5
|
-
* Version: 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:
|
|
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
|
|
31
|
-
const
|
|
32
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
if (!match || !match[1]) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
package/src/GitSenseChatUtils.js
CHANGED
|
@@ -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.
|
|
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
|
|
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
|
};
|