@gitsense/gsc-utils 0.2.23 → 0.2.25

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: GitSenseChatUtils
3
- * Block-UUID: d7cdbb94-f335-4f85-bdc4-0dd3ae95127e
4
- * Parent-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
5
- * Version: 2.1.5
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 and EnvUtils.
3
+ * Block-UUID: 1793b3a8-4881-4306-bfdf-673eef503679
4
+ * Parent-UUID: eaeabebb-04b6-4881-9b29-88798c7f21b6
5
+ * Version: 2.4.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, and ObjectUtils.
7
7
  * Language: JavaScript
8
- * Created-at: 2025-04-15T16:04:26.780Z
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)
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)
10
10
  */
11
11
 
12
12
 
@@ -22,15 +22,34 @@ const LLMUtils = require('./LLMUtils');
22
22
  const JsonUtils = require('./JsonUtils');
23
23
  const DateUtils = require('./DateUtils');
24
24
  const FormatterUtils = require('./FormatterUtils');
25
+ const MarkdownUtils = require('./MarkdownUtils');
25
26
  const ConfigUtils = require('./ConfigUtils');
26
27
  const EnvUtils = require('./EnvUtils');
28
+ const DomUtils = require('./DomUtils');
29
+ const ObjectUtils = require('./ObjectUtils');
30
+ const SVGUtils = require('./SVGUtils');
31
+ const LanguageNameUtils = require('./LanguageNameUtils');
27
32
 
28
33
  const {
29
- estimateTokens
34
+ normalizeLanguageName,
35
+ isKnownLanguage,
36
+ } = LanguageNameUtils;
37
+
38
+ const {
39
+ formatAge,
40
+ isValidDateString,
41
+ compareDates,
42
+ normalizeDateTime,
43
+ getTimeDifference,
44
+ formatTimeDifference,
45
+ } = DateUtils;
46
+
47
+ const {
48
+ estimateTokens,
30
49
  } = LLMUtils;
31
50
 
32
51
  const {
33
- detectJsonComments
52
+ detectJsonComments,
34
53
  } = JsonUtils;
35
54
 
36
55
  const {
@@ -131,6 +150,11 @@ const {
131
150
  formatTokens,
132
151
  } = FormatterUtils;
133
152
 
153
+ const {
154
+ createMarkdownRenderer,
155
+ removeSignature,
156
+ } = MarkdownUtils;
157
+
134
158
  const {
135
159
  parseContextSection,
136
160
  extractContextSections,
@@ -138,6 +162,10 @@ const {
138
162
  formatContextContent,
139
163
  } = ContextUtils;
140
164
 
165
+ const {
166
+ trimObjectStrings
167
+ } = ObjectUtils;
168
+
141
169
 
142
170
  /**
143
171
  * GitSenseChatUtils class provides a unified interface to code block and patch utilities.
@@ -340,20 +368,22 @@ class GitSenseChatUtils {
340
368
  // Uses function from CodeBlockUtils
341
369
  return CodeBlockUtils.isValidISOTimestamp(timestamp);
342
370
  }
371
+
372
+ /**
373
+ * Creates a configured markdown-it renderer instance.
374
+ * @param {Object} hljs - An instance of highlight.js.
375
+ * @param {Object} [hstyle={}] - Optional styles for highlighted code blocks.
376
+ * @param {Object} [nhstyle={}] - Optional styles for non-highlighted code blocks.
377
+ * @returns {Object} A configured markdown-it instance.
378
+ */
379
+ createMarkdownRenderer(hljs, hstyle, nhstyle) {
380
+ return MarkdownUtils.createMarkdownRenderer(hljs, hstyle, nhstyle);
381
+ }
343
382
  }
344
383
 
345
384
  // Export the main class, the aggregated CodeBlockUtils, PatchUtils,
346
385
  // and individual functions for backward compatibility or direct use.
347
386
  module.exports = {
348
- // New Utility Modules
349
- DateUtils,
350
- FormatterUtils,
351
-
352
- // Date Utility Functions
353
- formatAge: DateUtils.formatAge,
354
- compareDates: DateUtils.compareDates,
355
- isValidDateString: DateUtils.isValidDateString,
356
-
357
387
  // Main class
358
388
  GitSenseChatUtils,
359
389
 
@@ -370,9 +400,13 @@ module.exports = {
370
400
  JsonUtils,
371
401
  ConfigUtils,
372
402
  DateUtils,
403
+ LanguageNameUtils,
373
404
  FormatterUtils,
374
-
405
+ MarkdownUtils,
375
406
  EnvUtils,
407
+ DomUtils,
408
+ ObjectUtils,
409
+ SVGUtils,
376
410
 
377
411
  // --- Individual Function Exports (sourced correctly) ---
378
412
 
@@ -390,6 +424,10 @@ module.exports = {
390
424
  // Timestamp (from CodeBlockUtils)
391
425
  isValidISOTimestamp,
392
426
 
427
+ // Language Name Utilities (from LanguageNameUtils)
428
+ normalizeLanguageName,
429
+ isKnownLanguage,
430
+
393
431
  // Patch Detection/Integration (from CodeBlockUtils)
394
432
  containsPatch,
395
433
 
@@ -448,13 +486,22 @@ module.exports = {
448
486
 
449
487
  // Date Utils
450
488
  formatAge,
451
- compareDates,
452
489
  isValidDateString,
490
+ compareDates,
491
+ normalizeDateTime,
492
+ getTimeDifference,
493
+ formatTimeDifference,
453
494
 
454
495
  // Formatter Utils
455
496
  formatBytes,
456
497
  formatTokens,
457
- formatOverviewTable,
498
+
499
+ // Object Utils
500
+ trimObjectStrings,
501
+
502
+ // Markdown Utils
503
+ createMarkdownRenderer,
504
+ removeSignature,
458
505
 
459
506
  // GS Tool Block
460
507
  isToolBlock,
@@ -0,0 +1,171 @@
1
+ /*
2
+ * Component: Language Name Utils
3
+ * Block-UUID: 313abeab-2bb3-49d1-8693-e9e88aa97113
4
+ * Parent-UUID: N/A
5
+ * Version: 1.0.0
6
+ * Description: Utility for converting common lowercase language names and aliases to their proper capitalization
7
+ * Language: JavaScript
8
+ * Created-at: 2025-10-19T23:25:09.231Z
9
+ * Authors: Qwen 3 Coder 480B - Cerebras (v1.0.0)
10
+ */
11
+
12
+
13
+ /**
14
+ * A mapping of language aliases to their properly capitalized names
15
+ */
16
+ const LANGUAGE_NAME_MAP = {
17
+ // Core Programming Languages
18
+ 'javascript': 'JavaScript',
19
+ 'js': 'JavaScript',
20
+ 'typescript': 'TypeScript',
21
+ 'ts': 'TypeScript',
22
+ 'python': 'Python',
23
+ 'py': 'Python',
24
+ 'java': 'Java',
25
+ 'c': 'C',
26
+ 'c++': 'C++',
27
+ 'cpp': 'C++',
28
+ 'c#': 'C#',
29
+ 'csharp': 'C#',
30
+ 'go': 'Go',
31
+ 'rust': 'Rust',
32
+ 'rs': 'Rust',
33
+ 'swift': 'Swift',
34
+ 'kotlin': 'Kotlin',
35
+ 'ruby': 'Ruby',
36
+ 'rb': 'Ruby',
37
+ 'php': 'PHP',
38
+ 'perl': 'Perl',
39
+ 'scala': 'Scala',
40
+ 'r': 'R',
41
+ 'matlab': 'MATLAB',
42
+
43
+ // Web Development & Templating
44
+ 'html': 'HTML',
45
+ 'css': 'CSS',
46
+ 'xml': 'XML',
47
+ 'json': 'JSON',
48
+ 'yaml': 'YAML',
49
+ 'yml': 'YAML',
50
+ 'markdown': 'Markdown',
51
+ 'md': 'Markdown',
52
+ 'jsx': 'JSX',
53
+ 'tsx': 'TSX',
54
+ 'sass': 'Sass',
55
+ 'scss': 'SCSS',
56
+ 'less': 'Less',
57
+ 'vue': 'Vue',
58
+ 'svelte': 'Svelte',
59
+
60
+ // Infrastructure & DevOps
61
+ 'dockerfile': 'Dockerfile',
62
+ 'terraform': 'Terraform',
63
+ 'hcl': 'HCL',
64
+ 'groovy': 'Groovy',
65
+ 'gradle': 'Gradle',
66
+ 'cmake': 'CMake',
67
+ 'make': 'Make',
68
+
69
+ // Shell/Scripting Languages
70
+ 'bash': 'Bash',
71
+ 'shell': 'Shell',
72
+ 'powershell': 'PowerShell',
73
+ 'ps': 'PowerShell',
74
+
75
+ // Database/Query Languages
76
+ 'sql': 'SQL',
77
+ 'mysql': 'MySQL',
78
+ 'postgresql': 'PostgreSQL',
79
+ 'postgres': 'PostgreSQL',
80
+ 'mongodb': 'MongoDB',
81
+ 'redis': 'Redis',
82
+
83
+ // Data & Configuration Formats
84
+ 'toml': 'TOML',
85
+ 'ini': 'INI',
86
+ 'protobuf': 'Protocol Buffers',
87
+ 'proto': 'Protocol Buffers',
88
+ 'avro': 'Avro',
89
+
90
+ // Documentation & Markup
91
+ 'rst': 'reStructuredText',
92
+ 'asciidoc': 'AsciiDoc',
93
+ 'tex': 'TeX',
94
+ 'latex': 'LaTeX',
95
+
96
+ // Specialized & Niche Languages
97
+ 'dart': 'Dart',
98
+ 'lua': 'Lua',
99
+ 'haskell': 'Haskell',
100
+ 'elixir': 'Elixir',
101
+ 'erlang': 'Erlang',
102
+ 'clojure': 'Clojure',
103
+ 'f#': 'F#',
104
+ 'fortran': 'Fortran',
105
+ 'cobol': 'COBOL',
106
+ 'pascal': 'Pascal',
107
+ 'delphi': 'Delphi',
108
+ 'objective-c': 'Objective-C',
109
+ 'objc': 'Objective-C',
110
+ 'assembly': 'Assembly',
111
+ 'asm': 'Assembly',
112
+ 'solidity': 'Solidity',
113
+ 'julia': 'Julia',
114
+ 'zig': 'Zig',
115
+ 'ocaml': 'OCaml',
116
+ 'gdscript': 'GDScript',
117
+ 'lisp': 'Lisp',
118
+ 'move': 'Move',
119
+ 'cairo': 'Cairo',
120
+ 'vyper': 'Vyper',
121
+
122
+ // Legacy & Foundational
123
+ 'vb.net': 'VB.NET',
124
+ 'vbnet': 'VB.NET'
125
+ };
126
+
127
+ /**
128
+ * Normalizes a language name or alias to its proper capitalization
129
+ * @param {string} language - The language name or alias to normalize
130
+ * @returns {string} The properly capitalized language name, or the original input if not found
131
+ */
132
+ function normalizeLanguageName(language) {
133
+ if (!language) return language;
134
+
135
+ const lowerLanguage = language.toLowerCase();
136
+ return LANGUAGE_NAME_MAP[lowerLanguage] || language;
137
+ }
138
+
139
+ /**
140
+ * Checks if a language name or alias is known to the normalizer
141
+ * @param {string} language - The language name or alias to check
142
+ * @returns {boolean} True if the language is known, false otherwise
143
+ */
144
+ function isKnownLanguage(language) {
145
+ if (!language) return false;
146
+
147
+ return LANGUAGE_NAME_MAP.hasOwnProperty(language.toLowerCase());
148
+ }
149
+
150
+ /**
151
+ * Gets all known language aliases
152
+ * @returns {string[]} Array of all known language aliases
153
+ */
154
+ function getKnownLanguageAliases() {
155
+ return Object.keys(LANGUAGE_NAME_MAP);
156
+ }
157
+
158
+ /**
159
+ * Gets the mapping of language aliases to their normalized names
160
+ * @returns {Object} The language name mapping object
161
+ */
162
+ function getLanguageNameMap() {
163
+ return { ...LANGUAGE_NAME_MAP };
164
+ }
165
+
166
+ module.exports = {
167
+ normalizeLanguageName,
168
+ isKnownLanguage,
169
+ getKnownLanguageAliases,
170
+ getLanguageNameMap
171
+ };
@@ -0,0 +1,124 @@
1
+ /*
2
+ * Component: Markdown Utilities
3
+ * Block-UUID: 1e1b9db3-c1c6-45a7-80d8-7f7bc093e433
4
+ * Parent-UUID: N/A
5
+ * Version: 1.0.0
6
+ * Description: Provides utilities for configuring and using markdown-it with highlight.js for rendering Markdown content with syntax highlighting. Designed for use within GitSense Chat UI components.
7
+ * Language: JavaScript
8
+ * Created-at: 2025-10-15T23:48:15.318Z
9
+ * Authors: Qwen 3 Coder 480B - Cerebras (v1.0.0)
10
+ */
11
+
12
+
13
+ const { h } = require('./DomUtils');
14
+
15
+ /**
16
+ * Creates a configured markdown renderer instance.
17
+ * This renderer integrates markdown-it for Markdown processing and highlight.js for syntax highlighting
18
+ * within code blocks, replicating the style used in the main GitSense Chat conversation view.
19
+ *
20
+ * @param {Object} hljs - An instance of highlight.js.
21
+ * @param {Object} [hstyle={}] - Optional custom styles for highlighted code blocks. Merged with defaults.
22
+ * @param {Object} [nhstyle={}] - Optional custom styles for non-highlighted code blocks. Merged with defaults.
23
+ * @returns {Object} A configured markdown-it instance.
24
+ */
25
+ function createMarkdownRenderer(hljs, hstyle = {}, nhstyle = {}) {
26
+ const MarkDownIt = require("markdown-it");
27
+
28
+ const defaultHighlightStyle = {
29
+ backgroundColor: '#fafafa',
30
+ border: '1px solid #ddd',
31
+ marginTop: '5px',
32
+ overflow: 'auto',
33
+ maxHeight: '500px'
34
+ };
35
+
36
+ const defaultNoHighlightStyle = {
37
+ marginTop: '5px',
38
+ overflow: 'auto',
39
+ maxHeight: '800px'
40
+ };
41
+
42
+ // Merge default and custom styles
43
+ const highlightStyle = { ...defaultHighlightStyle, ...hstyle };
44
+ const noHighlightStyle = { ...defaultNoHighlightStyle, ...nhstyle };
45
+
46
+ // Configure markdown-it with a custom highlight function
47
+ const md = new MarkDownIt({
48
+ html: false, // Can be overridden if needed
49
+ highlight: function (str, lang) {
50
+ // Attempt to highlight if the language is supported
51
+ if (lang && hljs.getLanguage(lang)) {
52
+ try {
53
+ // Use highlight.js to generate the highlighted code HTML
54
+ const highlightedCode = hljs.highlight(str, { language: lang, ignoreIllegals: true }).value;
55
+
56
+ // Create the inner code element with the highlighted content
57
+ // and the language label prepended.
58
+ const codeElement = h.createCode({
59
+ html: `<span class='gs-chat-lang'>${lang}</span>\n\n${highlightedCode}`
60
+ });
61
+
62
+ // Wrap the code element in a pre tag with styling
63
+ const preElement = h.createPre({
64
+ cls: 'hljs', // Standard class for highlight.js containers
65
+ style: highlightStyle,
66
+ append: [codeElement]
67
+ });
68
+
69
+ // Return the outer HTML of the pre element to be injected into the Markdown output
70
+ return preElement.outerHTML;
71
+ } catch (error) {
72
+ // Gracefully handle highlight.js errors
73
+ console.warn("Syntax highlighting failed for language:", lang, error);
74
+ }
75
+ }
76
+
77
+ // Fallback for unsupported languages or highlighting errors
78
+ const escapedCode = md.utils.escapeHtml(str);
79
+ const codeElement = h.createCode({
80
+ html: escapedCode
81
+ });
82
+
83
+ const preElement = h.createPre({
84
+ cls: 'hljs',
85
+ style: noHighlightStyle,
86
+ append: [codeElement]
87
+ });
88
+
89
+ return preElement.outerHTML;
90
+ }
91
+ });
92
+
93
+ // --- Register Common markdown-it Plugins ---
94
+ // These are commonly used in GitSense Chat and should be included by default.
95
+ // The integrator can choose to disable them or add more via md.disable() or md.use() after creation.
96
+ md.use(require('markdown-it-anchor'), { level: 1 }); // Add anchors to headings
97
+ md.use(require('markdown-it-attrs'), { allowedAttributes: ['id'] }); // Allow custom attributes like {#custom-id}
98
+
99
+ return md;
100
+ }
101
+
102
+ /**
103
+ * This function removes any existing LLM author signature. After streaming, the backend will
104
+ * add the LLM author signature as a regular Markdown line, which is why we are matching for
105
+ * a paragraph. The signature is important for processing, but we don't want the user to see
106
+ * it.
107
+ *
108
+ * @param {HTMLElement} body - The DOM element containing the rendered markdown HTML.
109
+ * @param {string} model - The name of the model to include in the signature.
110
+ */
111
+ function removeSignature(body) {
112
+ if (!body) {
113
+ console.warn('MarkdownUtils.removeSignature: Invalid body.');
114
+ return;
115
+ }
116
+
117
+ const llmSignatureRegex = new RegExp(`<p>Authored by [^<]+</p>$`, 'i');
118
+ body.innerHTML = body.innerHTML.replace(llmSignatureRegex, '');
119
+ }
120
+
121
+ module.exports = {
122
+ createMarkdownRenderer,
123
+ removeSignature,
124
+ };
@@ -0,0 +1,54 @@
1
+ /*
2
+ * Component: ObjectUtils
3
+ * Block-UUID: 6f3c6c7a-1c5a-40c4-be26-332703b68d31
4
+ * Parent-UUID: N/A
5
+ * Version: 1.0.0
6
+ * Description: Utility functions for processing and manipulating JavaScript objects, including string property trimming for LLM token optimization
7
+ * Language: JavaScript
8
+ * Created-at: 2025-10-17T17:02:12.153Z
9
+ * Authors: Qwen 3 Coder 480B - Cerebras (v1.0.0)
10
+ */
11
+
12
+
13
+ /**
14
+ * Recursively trims string properties in an object to a maximum length
15
+ * @param {Object|Array} obj - The object or array to process
16
+ * @param {number} maxLength - Maximum length for strings (default: 100)
17
+ * @param {string} suffix - Suffix to append to trimmed strings (default: '...')
18
+ * @returns {Object|Array} - New object with trimmed strings
19
+ */
20
+ function trimObjectStrings(obj, maxLength = 100, suffix = '...') {
21
+ // Handle null or undefined
22
+ if (obj === null || obj === undefined) {
23
+ return obj;
24
+ }
25
+
26
+ // Handle strings
27
+ if (typeof obj === 'string') {
28
+ if (obj.length <= maxLength) {
29
+ return obj;
30
+ }
31
+ return obj.substring(0, maxLength - suffix.length) + suffix;
32
+ }
33
+
34
+ // Handle arrays
35
+ if (Array.isArray(obj)) {
36
+ return obj.map(item => trimObjectStrings(item, maxLength, suffix));
37
+ }
38
+
39
+ // Handle objects
40
+ if (typeof obj === 'object') {
41
+ const trimmedObj = {};
42
+ for (const key in obj) {
43
+ if (obj.hasOwnProperty(key)) {
44
+ trimmedObj[key] = trimObjectStrings(obj[key], maxLength, suffix);
45
+ }
46
+ }
47
+ return trimmedObj;
48
+ }
49
+
50
+ // Return other types unchanged
51
+ return obj;
52
+ }
53
+
54
+ module.exports = { trimObjectStrings };
@@ -158,6 +158,7 @@ function extractPatchContent(patchText, format) {
158
158
  }
159
159
 
160
160
  const lines = patchText.split('\n');
161
+
161
162
  let contentLines = [];
162
163
  let inContentBlock = false;
163
164
 
@@ -180,8 +181,6 @@ function extractPatchContent(patchText, format) {
180
181
  return contentLines.join('\n');
181
182
  }
182
183
 
183
- // Removed extractContextPatches function (obsolete context format)
184
-
185
184
  /**
186
185
  * Determines if a code block's content represents a patch block
187
186
  * by checking for the mandatory metadata header.
@@ -113,7 +113,7 @@ function applyPatch(sourceText, patchText) {
113
113
  }
114
114
 
115
115
  // 4. Apply the patch
116
- const patchedResult = jsdiff.applyPatch(sourceText, rawDiffContent, { fuzzFactor: 0 });
116
+ const patchedResult = jsdiff.applyPatch(sourceText, rawDiffContent, { fuzzFactor: 20 });
117
117
 
118
118
  if (patchedResult === false) {
119
119
  // jsdiff.applyPatch returns false on failure
@@ -276,11 +276,13 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
276
276
  const [ sourceHeaderText ] = sourceCodeBlockText.split('\n\n\n');
277
277
  const [ targetHeaderText ] = targetCodeBlockText.split('\n\n\n');
278
278
 
279
- const sourceContentTemp = sourceCodeBlockText.split('\n\n\n'); sourceContentTemp.shift();
280
- const sourceContent = sourceContentTemp.join('\n\n');
279
+ const sourceContentTemp = sourceCodeBlockText.split('\n\n\n');
280
+ sourceContentTemp.shift();
281
+ const sourceContent = sourceContentTemp.join('\n\n\n');
281
282
 
282
- const targetContentTemp = targetCodeBlockText.split('\n\n\n'); targetContentTemp.shift();
283
- const targetContent = targetContentTemp.join('\n\n');
283
+ const targetContentTemp = targetCodeBlockText.split('\n\n\n');
284
+ targetContentTemp.shift();
285
+ const targetContent = targetContentTemp.join('\n\n\n');
284
286
 
285
287
  // Get the number of lines in the header + two blank lines
286
288
  // Note, before the code block header format was solidified, we use to include 'Updated-at' but no more so
@@ -346,6 +348,7 @@ function createPatchFromCodeBlocks(CodeBlockUtils, sourceCodeBlockText, targetCo
346
348
  `# --- PATCH START MARKER ---\n`+
347
349
  `${adjustedDiffPatch}\n`+
348
350
  `# --- PATCH END MARKER ---`;
351
+
349
352
  return {
350
353
  formatted,
351
354
  formattedMetadata,