@gitsense/gsc-utils 0.2.25 → 0.2.27
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/README.md +380 -62
- package/dist/gsc-utils.cjs.js +2203 -331
- package/dist/gsc-utils.esm.js +2203 -331
- package/package.json +1 -1
- package/src/AnalyzerUtils/cloner.js +149 -0
- package/src/AnalyzerUtils/constants.js +1 -1
- package/src/AnalyzerUtils/defaultPromptLoader.js +10 -10
- package/src/AnalyzerUtils/discovery.js +48 -39
- package/src/AnalyzerUtils/index.js +13 -7
- package/src/AnalyzerUtils/instructionLoader.js +6 -6
- package/src/AnalyzerUtils/jsonParser.js +35 -0
- package/src/AnalyzerUtils/management.js +6 -6
- package/src/AnalyzerUtils/saver.js +5 -5
- package/src/AnalyzerUtils/schemaLoader.js +194 -26
- package/src/AnalyzerUtils/updater.js +187 -0
- package/src/CodeBlockUtils/blockProcessor.js +14 -32
- package/src/CodeBlockUtils/index.js +7 -6
- package/src/CodeBlockUtils/lineageTracer.js +95 -0
- package/src/CompactChatUtils/CompactedMessageUtils.js +224 -0
- package/src/CompactChatUtils/README.md +321 -0
- package/src/CompactChatUtils/ReferenceMessageUtils.js +143 -0
- package/src/CompactChatUtils/index.js +40 -0
- package/src/ContextUtils.js +40 -4
- package/src/DomUtils.js +86 -12
- package/src/GSToolBlockUtils.js +66 -1
- package/src/GitSenseChatUtils.js +58 -5
- package/src/MarkdownUtils.js +4 -1
- package/src/MessageUtils.js +1 -1
- package/src/MetaRawResultUtils.js +244 -0
- package/src/PatchUtils/constants.js +9 -3
- package/src/PatchUtils/patchParser.js +60 -36
- package/src/PatchUtils/patchVerifier/detectAndFixOverlappingHunks.js +1 -1
- package/src/SVGUtils.js +57 -0
- package/src/SharedUtils/stringUtils.js +303 -0
- package/src/CodeBlockUtils/blockProcessor.js.rej +0 -8
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: ReferenceMessageUtils
|
|
3
|
+
* Block-UUID: 2870551a-4311-4d64-9491-c9cc62f276e8
|
|
4
|
+
* Parent-UUID: N/A
|
|
5
|
+
* Description: Utility for parsing reference messages in the compact message workflow, extracting session data, metadata, and message sections.
|
|
6
|
+
* Language: JavaScript
|
|
7
|
+
* Created-at: 2025-12-07T00:08:42.573Z
|
|
8
|
+
* Authors: GLM-4.6 (v1.0.0)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ReferenceMessageUtils {
|
|
13
|
+
/**
|
|
14
|
+
* Extracts all data from a reference message including session data, metadata, and message sections
|
|
15
|
+
* @param {string} referenceMessage - The reference message content to parse
|
|
16
|
+
* @returns {Object} Parsed data with messages to compact and keep, metadata, and session information
|
|
17
|
+
*/
|
|
18
|
+
static extractReferenceMessageData(referenceMessage) {
|
|
19
|
+
if (!referenceMessage) {
|
|
20
|
+
return {
|
|
21
|
+
messagesToCompact: [],
|
|
22
|
+
messagesToKeep: [],
|
|
23
|
+
originalChatUuid: null,
|
|
24
|
+
validationHash: null,
|
|
25
|
+
sessionId: null,
|
|
26
|
+
range: null,
|
|
27
|
+
from: null,
|
|
28
|
+
to: null
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Extract Original Chat UUID
|
|
33
|
+
const originalChatUuidMatch = referenceMessage.match(/Original Chat UUID:\s*([a-f0-9-]+)/i);
|
|
34
|
+
const originalChatUuid = originalChatUuidMatch ? originalChatUuidMatch[1] : null;
|
|
35
|
+
|
|
36
|
+
// Extract Validation Hash
|
|
37
|
+
const validationHashMatch = referenceMessage.match(/Validation Hash:\s*([a-f0-9]+)/i);
|
|
38
|
+
const validationHash = validationHashMatch ? validationHashMatch[1] : null;
|
|
39
|
+
|
|
40
|
+
// Extract Session ID
|
|
41
|
+
const sessionIdMatch = referenceMessage.match(/Session ID:\s*(\d+)/i);
|
|
42
|
+
const sessionId = sessionIdMatch ? sessionIdMatch[1] : null;
|
|
43
|
+
|
|
44
|
+
// Extract Range
|
|
45
|
+
const rangeMatch = referenceMessage.match(/Range:\s*(\d+-\d+)/i);
|
|
46
|
+
const range = rangeMatch ? rangeMatch[1] : null;
|
|
47
|
+
|
|
48
|
+
// Extract From and To values
|
|
49
|
+
const fromMatch = referenceMessage.match(/From:\s*(\d+)/i);
|
|
50
|
+
const from = fromMatch ? parseInt(fromMatch[1], 10) : null;
|
|
51
|
+
|
|
52
|
+
const toMatch = referenceMessage.match(/To:\s*(\d+)/i);
|
|
53
|
+
const to = toMatch ? parseInt(toMatch[1], 10) : null;
|
|
54
|
+
|
|
55
|
+
// If range is not found but from and to are available, construct the range
|
|
56
|
+
if (!range && from !== null && to !== null) {
|
|
57
|
+
range = `${from}-${to}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Extract Messages to Compact section
|
|
61
|
+
const compactSectionMatch = referenceMessage.match(/# Messages to Compact\n([\s\S]*?)(?=\n# |\n$|$)/);
|
|
62
|
+
const compactSection = compactSectionMatch ? compactSectionMatch[1] : '';
|
|
63
|
+
|
|
64
|
+
// Extract Messages to Keep section
|
|
65
|
+
const keepSectionMatch = referenceMessage.match(/# Messages to Keep \(Context\)\n([\s\S]*?)(?=\n# |\n$|$)/);
|
|
66
|
+
const keepSection = keepSectionMatch ? keepSectionMatch[1] : '';
|
|
67
|
+
|
|
68
|
+
// Parse messages from each section
|
|
69
|
+
const messagesToCompact = this.parseMessageSection(compactSection);
|
|
70
|
+
const messagesToKeep = this.parseMessageSection(keepSection);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
messagesToCompact,
|
|
74
|
+
messagesToKeep,
|
|
75
|
+
originalChatUuid,
|
|
76
|
+
validationHash,
|
|
77
|
+
sessionId,
|
|
78
|
+
range,
|
|
79
|
+
from,
|
|
80
|
+
to
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Parses a message section to extract individual messages
|
|
86
|
+
* @param {string} section - The section content to parse
|
|
87
|
+
* @returns {Array} Array of parsed message objects
|
|
88
|
+
*/
|
|
89
|
+
static parseMessageSection(section) {
|
|
90
|
+
if (!section) return [];
|
|
91
|
+
|
|
92
|
+
const messages = [];
|
|
93
|
+
const messageRegex = /<(\w+) message number (\d+)>\n([\s\S]*?)\n<\/\1 message number \2>/g;
|
|
94
|
+
let match;
|
|
95
|
+
|
|
96
|
+
while ((match = messageRegex.exec(section)) !== null) {
|
|
97
|
+
const [, role, positionStr, content] = match;
|
|
98
|
+
const position = parseInt(positionStr, 10);
|
|
99
|
+
|
|
100
|
+
messages.push({
|
|
101
|
+
role,
|
|
102
|
+
position,
|
|
103
|
+
content: content.trim()
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return messages;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Extracts just the metadata from a reference message without the message sections
|
|
112
|
+
* @param {string} referenceMessage - The reference message content to parse
|
|
113
|
+
* @returns {Object} Metadata object with original chat UUID, validation hash, session ID, and range information
|
|
114
|
+
*/
|
|
115
|
+
static extractReferenceMessageMetadata(referenceMessage) {
|
|
116
|
+
const data = this.extractReferenceMessageData(referenceMessage);
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
originalChatUuid: data.originalChatUuid,
|
|
120
|
+
validationHash: data.validationHash,
|
|
121
|
+
sessionId: data.sessionId,
|
|
122
|
+
range: data.range,
|
|
123
|
+
from: data.from,
|
|
124
|
+
to: data.to
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Checks if a message is a reference message
|
|
130
|
+
* @param {string} message - The message content to check
|
|
131
|
+
* @returns {boolean} True if the message is a reference message
|
|
132
|
+
*/
|
|
133
|
+
static isReferenceMessage(message) {
|
|
134
|
+
if (!message) return false;
|
|
135
|
+
|
|
136
|
+
// Check for key indicators of a reference message
|
|
137
|
+
return message.includes('# Compact Messages Reference') &&
|
|
138
|
+
message.includes('Original Chat UUID:') &&
|
|
139
|
+
message.includes('Session ID:');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = { ReferenceMessageUtils };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: CompactChatUtils Index
|
|
3
|
+
* Block-UUID: cd0a6091-edb6-4e92-9439-63dd8f6a6796
|
|
4
|
+
* Parent-UUID: 5ffa0338-b4fb-4968-908c-f23a26d4923b
|
|
5
|
+
* Version: 2.0.0
|
|
6
|
+
* Description: Entry point for CompactChatUtils that exports both ReferenceMessageUtils and CompactedMessageUtils methods directly for easier access.
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-12-07T00:10:05.123Z
|
|
9
|
+
* Authors: GLM-4.6 (v1.0.0), GLM-4.6 (v2.0.0)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const { ReferenceMessageUtils } = require('./ReferenceMessageUtils');
|
|
14
|
+
const { CompactedMessageUtils } = require('./CompactedMessageUtils');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* CompactChatUtils provides utilities for working with compacted messages in GitSense Chat.
|
|
18
|
+
* It includes functionality for parsing reference messages and formatting/parsing compacted messages.
|
|
19
|
+
*/
|
|
20
|
+
module.exports = {
|
|
21
|
+
// Export the classes for those who want to access them directly
|
|
22
|
+
ReferenceMessageUtils,
|
|
23
|
+
CompactedMessageUtils,
|
|
24
|
+
|
|
25
|
+
// Export all methods from ReferenceMessageUtils directly
|
|
26
|
+
extractReferenceMessageData: ReferenceMessageUtils.extractReferenceMessageData,
|
|
27
|
+
parseMessageSection: ReferenceMessageUtils.parseMessageSection,
|
|
28
|
+
extractReferenceMessageMetadata: ReferenceMessageUtils.extractReferenceMessageMetadata,
|
|
29
|
+
isReferenceMessage: ReferenceMessageUtils.isReferenceMessage,
|
|
30
|
+
|
|
31
|
+
// Export all methods from CompactedMessageUtils directly
|
|
32
|
+
formatCompactedMessage: CompactedMessageUtils.formatCompactedMessage,
|
|
33
|
+
extractCompactedMessageMetadata: CompactedMessageUtils.extractCompactedMessageMetadata,
|
|
34
|
+
extractCompactedMessageContent: CompactedMessageUtils.extractCompactedMessageContent,
|
|
35
|
+
validateCompactedMessageFormat: CompactedMessageUtils.validateCompactedMessageFormat,
|
|
36
|
+
isCompactedMessage: CompactedMessageUtils.isCompactedMessage,
|
|
37
|
+
isValidUUID: CompactedMessageUtils.isValidUUID,
|
|
38
|
+
isValidMessageRange: CompactedMessageUtils.isValidMessageRange,
|
|
39
|
+
isValidISOTimestamp: CompactedMessageUtils.isValidISOTimestamp
|
|
40
|
+
};
|
package/src/ContextUtils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Component: ContextUtils
|
|
3
|
-
* Block-UUID:
|
|
4
|
-
* Parent-UUID:
|
|
5
|
-
* Version: 1.
|
|
3
|
+
* Block-UUID: 534c348d-a11f-4de6-ad15-f33068d51fb8
|
|
4
|
+
* Parent-UUID: a0b71292-b1cc-401a-8ce2-544a047b0fef
|
|
5
|
+
* Version: 1.4.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), Qwen 3 Coder 480B - Cerebras (v1.3.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), Qwen 3 Coder 480B - Cerebras (v1.4.0)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
@@ -77,6 +77,41 @@ function _createContextSummary(items, contentType) {
|
|
|
77
77
|
return summary + "\n";
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Extracts all context files from a given chat object.
|
|
82
|
+
* Iterates through chat messages, identifies context loader outputs,
|
|
83
|
+
* and parses them into individual file objects.
|
|
84
|
+
*
|
|
85
|
+
* @param {object} chat - The GitSense chat object.
|
|
86
|
+
* @returns {Array<object>} An array of parsed context file objects.
|
|
87
|
+
* Returns an empty array if no context files are found or on error.
|
|
88
|
+
*/
|
|
89
|
+
function getContextFiles(chat) {
|
|
90
|
+
const ChatUtils = require('./ChatUtils');
|
|
91
|
+
const contextFiles = [];
|
|
92
|
+
const messages = ChatUtils.getChatMessages(chat);
|
|
93
|
+
|
|
94
|
+
if (!Array.isArray(messages)) {
|
|
95
|
+
console.warn("getContextFiles: Provided chat object does not contain a valid messages array.");
|
|
96
|
+
return contextFiles;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
messages.forEach(message => {
|
|
100
|
+
// Check if the message content is a context message
|
|
101
|
+
if (MessageUtils.isContextMessage(message.message)) {
|
|
102
|
+
try {
|
|
103
|
+
// Extract all context sections from the message content
|
|
104
|
+
const extractedFiles = extractContextSections(message.message);
|
|
105
|
+
contextFiles.push(...extractedFiles);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.warn(`getContextFiles: Failed to extract context sections from message ID ${message.id}:`, error);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
return contextFiles;
|
|
113
|
+
}
|
|
114
|
+
|
|
80
115
|
/**
|
|
81
116
|
* Escapes backticks in code blocks to prevent premature termination of LLM-generated code blocks.
|
|
82
117
|
* @param {string} content - The content string to escape.
|
|
@@ -351,6 +386,7 @@ function formatContextContent(items, contentType, contentOption) {
|
|
|
351
386
|
module.exports = {
|
|
352
387
|
parseContextSection,
|
|
353
388
|
extractContextSections,
|
|
389
|
+
getContextFiles,
|
|
354
390
|
extractContextItemsOverviewTableRows,
|
|
355
391
|
formatContextContent,
|
|
356
392
|
};
|
package/src/DomUtils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Component: DomUtils Helper Functions
|
|
3
|
-
* Block-UUID:
|
|
4
|
-
* Parent-UUID:
|
|
5
|
-
* Version: 1.
|
|
3
|
+
* Block-UUID: 9a8e8e8e-8b15-4346-bbfa-740e6a5d2d79
|
|
4
|
+
* Parent-UUID: 8a528728-ce54-4445-946d-1743fb4b16be
|
|
5
|
+
* Version: 1.3.0
|
|
6
6
|
* Description: Provides helper functions for creating and manipulating DOM elements.
|
|
7
7
|
* Language: JavaScript
|
|
8
|
-
* Created-at: 2025-
|
|
9
|
-
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Flash (v1.1.0)
|
|
8
|
+
* Created-at: 2025-12-14T04:18:40.180Z
|
|
9
|
+
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Flash (v1.1.0), Qwen 3 Coder 480B - Cerebras (v1.2.0), GLM-4.6 (v1.2.1), GLM-4.6 (v1.3.0)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
@@ -19,6 +19,7 @@ function createElement(type, params) {
|
|
|
19
19
|
let {
|
|
20
20
|
id,
|
|
21
21
|
ariaLabel,
|
|
22
|
+
xmlns,
|
|
22
23
|
role,
|
|
23
24
|
html,
|
|
24
25
|
text,
|
|
@@ -41,11 +42,15 @@ function createElement(type, params) {
|
|
|
41
42
|
"data-message-role": dmr,
|
|
42
43
|
attrs = {},
|
|
43
44
|
dataset,
|
|
45
|
+
rows
|
|
44
46
|
} = params;
|
|
45
47
|
|
|
46
48
|
// Set standard attributes
|
|
47
49
|
if (id != null) elem.id = id;
|
|
48
50
|
if (ariaLabel) elem.setAttribute("aria-label", ariaLabel);
|
|
51
|
+
if (xmlns) elem.setAttribute("xmlns", xmlns);
|
|
52
|
+
if (params.viewBox) elem.setAttribute("viewBox", params.viewBox);
|
|
53
|
+
if (params.fill) elem.setAttribute("fill", params.fill);
|
|
49
54
|
if (role) elem.setAttribute("role", role);
|
|
50
55
|
if (placeholder) elem.setAttribute("placeholder", placeholder);
|
|
51
56
|
if (cls || className) elem.setAttribute("class", cls || className);
|
|
@@ -53,6 +58,9 @@ function createElement(type, params) {
|
|
|
53
58
|
if (title != null) elem.setAttribute("title", title);
|
|
54
59
|
if (inputType) elem.setAttribute("type", inputType);
|
|
55
60
|
if (name != null) elem.setAttribute("name", name);
|
|
61
|
+
if (params.width) elem.setAttribute("width", params.width);
|
|
62
|
+
if (params.height) elem.setAttribute("height", params.height);
|
|
63
|
+
if (params.stroke) elem.setAttribute("stroke", params.stroke);
|
|
56
64
|
if (value != null) elem.value = value;
|
|
57
65
|
if (checked != null && checked) elem.checked = true; // Use property for checked
|
|
58
66
|
if (selected != null && selected) elem.selected = true; // Use property for selected
|
|
@@ -60,13 +68,21 @@ function createElement(type, params) {
|
|
|
60
68
|
if (dmi != null) elem.setAttribute("data-message-id", dmi);
|
|
61
69
|
if (dmr != null) elem.setAttribute("data-message-role", dmr);
|
|
62
70
|
if (_for != null ) elem.setAttribute("for", _for);
|
|
71
|
+
if (params.strokeWidth) elem.setAttribute("stroke-width", params.strokeWidth);
|
|
72
|
+
if (params.strokeLinecap) elem.setAttribute("stroke-linecap", params.strokeLinecap);
|
|
73
|
+
if (params.strokeLinejoin) elem.setAttribute("stroke-linejoin", params.strokeLinejoin);
|
|
63
74
|
if (colSpan != null) elem.colSpan = colSpan;
|
|
75
|
+
if (rows) elem.setAttribute("rows", params.rows);
|
|
64
76
|
|
|
65
77
|
// Set content
|
|
66
78
|
if (html != null) {
|
|
67
79
|
if (typeof html === "object" && html instanceof Node) { // Ensure html is a Node
|
|
68
80
|
elem.appendChild(html);
|
|
69
81
|
} else if (typeof html === "string") {
|
|
82
|
+
// For SVG elements, use innerHTML to support path elements
|
|
83
|
+
if (type === 'svg' && params.innerHTML) {
|
|
84
|
+
elem.innerHTML = params.innerHTML;
|
|
85
|
+
}
|
|
70
86
|
elem.innerHTML = html;
|
|
71
87
|
}
|
|
72
88
|
} else if (text != null) {
|
|
@@ -92,12 +108,12 @@ function createElement(type, params) {
|
|
|
92
108
|
});
|
|
93
109
|
}
|
|
94
110
|
|
|
95
|
-
//
|
|
111
|
+
// Set additional attributes from attrs object
|
|
96
112
|
if (attrs && typeof attrs === 'object') {
|
|
97
113
|
for (const [key, value] of Object.entries(attrs)) {
|
|
98
114
|
if (value !== undefined && value !== null) {
|
|
99
115
|
// Skip if already set by standard properties or handled directly
|
|
100
|
-
if (!['id', 'class', 'role', 'aria-label', 'title', 'style', '
|
|
116
|
+
if (!['id', 'class', 'role', 'aria-label', 'title', 'style', 'selected', 'disabled', 'value', 'name', 'type', 'for'].includes(key) && !key.startsWith('data-')) {
|
|
101
117
|
elem.setAttribute(key, value);
|
|
102
118
|
}
|
|
103
119
|
}
|
|
@@ -210,14 +226,17 @@ const h = {
|
|
|
210
226
|
},
|
|
211
227
|
createLink: (params) => {
|
|
212
228
|
const link = createElement("a", params);
|
|
213
|
-
|
|
214
|
-
if (params?.
|
|
229
|
+
if (params?.href) link.href = params.href;
|
|
230
|
+
if (params?.target) link.target = params.target;
|
|
215
231
|
return link;
|
|
216
232
|
},
|
|
217
233
|
createNav: (params) => {
|
|
218
234
|
return createElement("nav", params);
|
|
219
235
|
},
|
|
220
|
-
|
|
236
|
+
createOl: (params) => {
|
|
237
|
+
return createElement("ol", params);
|
|
238
|
+
},
|
|
239
|
+
createOL: (params) => {
|
|
221
240
|
return createElement("ol", params);
|
|
222
241
|
},
|
|
223
242
|
createOption: (params) => { // Added
|
|
@@ -235,11 +254,33 @@ const h = {
|
|
|
235
254
|
},
|
|
236
255
|
createSelect: (params) => { // Added
|
|
237
256
|
// name, disabled etc handled by createElement
|
|
238
|
-
|
|
257
|
+
const select = createElement("select", params);
|
|
258
|
+
|
|
259
|
+
// Handle options array if provided
|
|
260
|
+
if (params && params.options && Array.isArray(params.options)) {
|
|
261
|
+
params.options.forEach(option => {
|
|
262
|
+
if (option && typeof option === 'object') {
|
|
263
|
+
const optionElement = createElement("option", {
|
|
264
|
+
value: option.value,
|
|
265
|
+
text: option.text,
|
|
266
|
+
selected: option.selected
|
|
267
|
+
});
|
|
268
|
+
select.appendChild(optionElement);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return select;
|
|
239
274
|
},
|
|
240
275
|
createSpan: (params) => {
|
|
241
276
|
return createElement("span", params);
|
|
242
277
|
},
|
|
278
|
+
createSvg: (params) => {
|
|
279
|
+
// Create SVG element with xmlns attribute
|
|
280
|
+
const svgParams = { ...params, xmlns: "http://www.w3.org/2000/svg" };
|
|
281
|
+
const svg = createElement("svg", svgParams);
|
|
282
|
+
return svg;
|
|
283
|
+
},
|
|
243
284
|
createStrong: (params) => { // Added
|
|
244
285
|
return createElement("strong", params);
|
|
245
286
|
},
|
|
@@ -252,6 +293,10 @@ const h = {
|
|
|
252
293
|
createText: (text) => {
|
|
253
294
|
return document.createTextNode(text);
|
|
254
295
|
},
|
|
296
|
+
createTextarea: (params) => {
|
|
297
|
+
const textArea = createElement("textarea", params);
|
|
298
|
+
return textArea;
|
|
299
|
+
},
|
|
255
300
|
createTextArea: (params) => {
|
|
256
301
|
const textArea = createElement("textarea", params);
|
|
257
302
|
return textArea;
|
|
@@ -450,6 +495,35 @@ const h = {
|
|
|
450
495
|
})
|
|
451
496
|
.join('');
|
|
452
497
|
},
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Injects CSS styles into the document head.
|
|
501
|
+
* @param {string} cssString - The CSS string to inject.
|
|
502
|
+
* @param {string} [id] - Optional ID for the style element to prevent duplicates.
|
|
503
|
+
* @returns {HTMLStyleElement} The created or existing style element.
|
|
504
|
+
*/
|
|
505
|
+
injectStyles: (cssString, id) => {
|
|
506
|
+
// If an ID is provided, check if styles with this ID already exist
|
|
507
|
+
if (id) {
|
|
508
|
+
const existingStyle = document.getElementById(id);
|
|
509
|
+
if (existingStyle) {
|
|
510
|
+
// Styles already injected, return the existing element
|
|
511
|
+
return existingStyle;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Create a new style element
|
|
516
|
+
const styleElement = document.createElement('style');
|
|
517
|
+
if (id) {
|
|
518
|
+
styleElement.id = id;
|
|
519
|
+
}
|
|
520
|
+
styleElement.textContent = cssString;
|
|
521
|
+
|
|
522
|
+
// Append to the document head
|
|
523
|
+
document.head.appendChild(styleElement);
|
|
524
|
+
|
|
525
|
+
return styleElement;
|
|
526
|
+
},
|
|
453
527
|
|
|
454
528
|
/**
|
|
455
529
|
* Calculates the distance between an element's edge and the viewport's corresponding edge
|
|
@@ -480,6 +554,6 @@ const h = {
|
|
|
480
554
|
return rect.left;
|
|
481
555
|
}
|
|
482
556
|
}
|
|
483
|
-
}
|
|
557
|
+
};
|
|
484
558
|
|
|
485
559
|
module.exports = { h };
|
package/src/GSToolBlockUtils.js
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
const GS_TOOL_BLOCK_TYPE = 'gs-tool';
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* Checks if a given code block content represents a GitSense Chat Tool Block.
|
|
15
17
|
* It verifies if the first non-empty line starts with "# GitSense Chat Tool".
|
|
@@ -28,6 +30,65 @@ function isToolBlock(content) {
|
|
|
28
30
|
return false;
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
|
|
34
|
+
// TODO: Add JSDocs
|
|
35
|
+
function getToolBlocksByTool(content, tool, CodeBlockUtils) {
|
|
36
|
+
const { blocks, warnings } = CodeBlockUtils.extractCodeBlocks(content, { silent: true });
|
|
37
|
+
|
|
38
|
+
return blocks.filter((block, index) => {
|
|
39
|
+
if (block.type !== GS_TOOL_BLOCK_TYPE)
|
|
40
|
+
return;
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const data = parseToolBlock(block.content);
|
|
44
|
+
|
|
45
|
+
if (data.tool === tool) {
|
|
46
|
+
block.index = index;
|
|
47
|
+
return block;
|
|
48
|
+
}
|
|
49
|
+
} catch(error) {
|
|
50
|
+
// FIXME: We need a more elegant way to identify examples.
|
|
51
|
+
if (!content.includes(/Internal INTEGER IDs/)) {
|
|
52
|
+
console.warn(`Invalid tool block JSON: ${error.message}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// TODO: Add JSDocs
|
|
59
|
+
function getToolBlockElemsByTool(dom, tool) {
|
|
60
|
+
const elems = dom.querySelectorAll('pre');
|
|
61
|
+
const toolBockElems = [];
|
|
62
|
+
|
|
63
|
+
for ( let i = 0; i < elems.length; i++ ) {
|
|
64
|
+
const elem = elems[i];
|
|
65
|
+
let content = elem.textContent;
|
|
66
|
+
|
|
67
|
+
// We need to strip out the first two lines since this is not part of the actual code
|
|
68
|
+
// block. These two lines are designed to make it easy to identify the language
|
|
69
|
+
content = content.split('\n').slice(2).join('\n');
|
|
70
|
+
|
|
71
|
+
if (!isToolBlock(content))
|
|
72
|
+
continue;
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const data = parseToolBlock(content, { silent: true });
|
|
76
|
+
|
|
77
|
+
if (data.tool === tool)
|
|
78
|
+
toolBockElems.push(elem);
|
|
79
|
+
} catch(error) {
|
|
80
|
+
// FIXME: We need a more elegant way to identify examples.
|
|
81
|
+
if (!content.match(/Internal INTEGER IDs/)) {
|
|
82
|
+
console.warn("getToolBlockElemsByTool: ",error.message);
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return toolBockElems;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
31
92
|
/**
|
|
32
93
|
* Parses the content of a GitSense Chat Tool Block to extract the JSON payload.
|
|
33
94
|
* It strips the marker line and any subsequent lines starting with '#' (comments)
|
|
@@ -136,7 +197,7 @@ function replaceToolBlock(markdownContent, toolName, newToolData, CodeBlockUtils
|
|
|
136
197
|
// 2. Iterate through the processed blocks to find the target GitSense Chat Tool Block
|
|
137
198
|
for (let i = 0; i < blocks.length; i++) {
|
|
138
199
|
const block = blocks[i];
|
|
139
|
-
if (block.type ===
|
|
200
|
+
if (block.type === GS_TOOL_BLOCK_TYPE && block.toolData && block.toolData.tool === toolName) {
|
|
140
201
|
targetBlockIndex = i;
|
|
141
202
|
break; // Found the first matching tool block
|
|
142
203
|
}
|
|
@@ -270,10 +331,14 @@ function detectAndFormatUnfencedToolBlock(messageContent) {
|
|
|
270
331
|
};
|
|
271
332
|
}
|
|
272
333
|
|
|
334
|
+
|
|
335
|
+
|
|
273
336
|
module.exports = {
|
|
274
337
|
isToolBlock,
|
|
275
338
|
parseToolBlock,
|
|
276
339
|
formatToolBlock,
|
|
277
340
|
replaceToolBlock,
|
|
341
|
+
getToolBlocksByTool,
|
|
342
|
+
getToolBlockElemsByTool,
|
|
278
343
|
detectAndFormatUnfencedToolBlock,
|
|
279
344
|
}
|
package/src/GitSenseChatUtils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Component: GitSenseChatUtils
|
|
3
|
-
* Block-UUID:
|
|
4
|
-
* Parent-UUID:
|
|
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, and
|
|
3
|
+
* Block-UUID: c1b6c4d3-7959-4eb6-8022-6cd7aa59240d
|
|
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.
|
|
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)
|
|
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)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
@@ -28,7 +28,10 @@ const EnvUtils = require('./EnvUtils');
|
|
|
28
28
|
const DomUtils = require('./DomUtils');
|
|
29
29
|
const ObjectUtils = require('./ObjectUtils');
|
|
30
30
|
const SVGUtils = require('./SVGUtils');
|
|
31
|
+
const StringUtils = require('./SharedUtils/stringUtils');
|
|
31
32
|
const LanguageNameUtils = require('./LanguageNameUtils');
|
|
33
|
+
const MetaRawResultUtils = require('./MetaRawResultUtils');
|
|
34
|
+
const CompactChatUtils = require('./CompactChatUtils');
|
|
32
35
|
|
|
33
36
|
const {
|
|
34
37
|
normalizeLanguageName,
|
|
@@ -114,6 +117,7 @@ const {
|
|
|
114
117
|
removeCodeBlockMarkers,
|
|
115
118
|
updateCodeBlockByIndex,
|
|
116
119
|
deleteCodeBlockByIndex,
|
|
120
|
+
getLineage,
|
|
117
121
|
} = CodeBlockUtils;
|
|
118
122
|
|
|
119
123
|
const {
|
|
@@ -159,6 +163,7 @@ const {
|
|
|
159
163
|
parseContextSection,
|
|
160
164
|
extractContextSections,
|
|
161
165
|
extractContextItemsOverviewTableRows,
|
|
166
|
+
getContextFiles,
|
|
162
167
|
formatContextContent,
|
|
163
168
|
} = ContextUtils;
|
|
164
169
|
|
|
@@ -166,6 +171,28 @@ const {
|
|
|
166
171
|
trimObjectStrings
|
|
167
172
|
} = ObjectUtils;
|
|
168
173
|
|
|
174
|
+
const {
|
|
175
|
+
splitWithLimit,
|
|
176
|
+
capitalize,
|
|
177
|
+
titleCase,
|
|
178
|
+
camelCase,
|
|
179
|
+
kebabCase,
|
|
180
|
+
snakeCase,
|
|
181
|
+
constantCase,
|
|
182
|
+
pascalCase,
|
|
183
|
+
trimWhitespace,
|
|
184
|
+
truncate,
|
|
185
|
+
} = StringUtils;
|
|
186
|
+
|
|
187
|
+
const {
|
|
188
|
+
extractMetaRawResultMappings,
|
|
189
|
+
isMetaRawResultMessage,
|
|
190
|
+
parseMetaRawResultContent,
|
|
191
|
+
parseTableRow,
|
|
192
|
+
parseSize,
|
|
193
|
+
parseTokens
|
|
194
|
+
} = MetaRawResultUtils;
|
|
195
|
+
|
|
169
196
|
|
|
170
197
|
/**
|
|
171
198
|
* GitSenseChatUtils class provides a unified interface to code block and patch utilities.
|
|
@@ -406,7 +433,12 @@ module.exports = {
|
|
|
406
433
|
EnvUtils,
|
|
407
434
|
DomUtils,
|
|
408
435
|
ObjectUtils,
|
|
436
|
+
StringUtils,
|
|
409
437
|
SVGUtils,
|
|
438
|
+
MetaRawResultUtils,
|
|
439
|
+
CompactChatUtils,
|
|
440
|
+
ReferenceMessageUtils: CompactChatUtils.ReferenceMessageUtils,
|
|
441
|
+
CompactedMessageUtils: CompactChatUtils.CompactedMessageUtils,
|
|
410
442
|
|
|
411
443
|
// --- Individual Function Exports (sourced correctly) ---
|
|
412
444
|
|
|
@@ -499,6 +531,18 @@ module.exports = {
|
|
|
499
531
|
// Object Utils
|
|
500
532
|
trimObjectStrings,
|
|
501
533
|
|
|
534
|
+
// String Utils
|
|
535
|
+
splitWithLimit,
|
|
536
|
+
capitalize,
|
|
537
|
+
titleCase,
|
|
538
|
+
camelCase,
|
|
539
|
+
kebabCase,
|
|
540
|
+
snakeCase,
|
|
541
|
+
constantCase,
|
|
542
|
+
pascalCase,
|
|
543
|
+
trimWhitespace,
|
|
544
|
+
truncate,
|
|
545
|
+
|
|
502
546
|
// Markdown Utils
|
|
503
547
|
createMarkdownRenderer,
|
|
504
548
|
removeSignature,
|
|
@@ -518,8 +562,17 @@ module.exports = {
|
|
|
518
562
|
getApiKey,
|
|
519
563
|
|
|
520
564
|
// Context Utils
|
|
565
|
+
getContextFiles,
|
|
521
566
|
parseContextSection,
|
|
522
567
|
extractContextSections,
|
|
523
568
|
extractContextItemsOverviewTableRows,
|
|
524
569
|
formatContextContent,
|
|
570
|
+
|
|
571
|
+
// MetaRawResult Utils
|
|
572
|
+
extractMetaRawResultMappings,
|
|
573
|
+
isMetaRawResultMessage,
|
|
574
|
+
parseMetaRawResultContent,
|
|
575
|
+
parseTableRow,
|
|
576
|
+
parseSize,
|
|
577
|
+
parseTokens,
|
|
525
578
|
};
|
package/src/MarkdownUtils.js
CHANGED
|
@@ -56,7 +56,10 @@ function createMarkdownRenderer(hljs, hstyle = {}, nhstyle = {}) {
|
|
|
56
56
|
// Create the inner code element with the highlighted content
|
|
57
57
|
// and the language label prepended.
|
|
58
58
|
const codeElement = h.createCode({
|
|
59
|
-
html: `<span class='gs-chat-lang'>${lang}</span>\n\n${highlightedCode}
|
|
59
|
+
html: `<span class='gs-chat-lang'>${lang}</span>\n\n${highlightedCode}`,
|
|
60
|
+
style: {
|
|
61
|
+
fontSize: '13px'
|
|
62
|
+
}
|
|
60
63
|
});
|
|
61
64
|
|
|
62
65
|
// Wrap the code element in a pre tag with styling
|