@gitsense/gsc-utils 0.2.25 → 0.2.28

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.
Files changed (39) hide show
  1. package/README.md +380 -62
  2. package/dist/gsc-utils.cjs.js +2290 -326
  3. package/dist/gsc-utils.esm.js +2290 -326
  4. package/package.json +1 -1
  5. package/src/AnalyzerUtils/cloner.js +149 -0
  6. package/src/AnalyzerUtils/constants.js +1 -1
  7. package/src/AnalyzerUtils/defaultPromptLoader.js +10 -10
  8. package/src/AnalyzerUtils/discovery.js +48 -39
  9. package/src/AnalyzerUtils/index.js +13 -7
  10. package/src/AnalyzerUtils/instructionLoader.js +6 -6
  11. package/src/AnalyzerUtils/jsonParser.js +35 -0
  12. package/src/AnalyzerUtils/management.js +6 -6
  13. package/src/AnalyzerUtils/saver.js +5 -5
  14. package/src/AnalyzerUtils/schemaLoader.js +194 -26
  15. package/src/AnalyzerUtils/updater.js +187 -0
  16. package/src/CodeBlockUtils/blockProcessor.js +14 -32
  17. package/src/CodeBlockUtils/index.js +7 -6
  18. package/src/CodeBlockUtils/lineageTracer.js +95 -0
  19. package/src/CompactChatUtils/CompactedMessageUtils.js +224 -0
  20. package/src/CompactChatUtils/README.md +321 -0
  21. package/src/CompactChatUtils/ReferenceMessageUtils.js +143 -0
  22. package/src/CompactChatUtils/index.js +40 -0
  23. package/src/ContextUtils.js +40 -4
  24. package/src/DomUtils.js +102 -14
  25. package/src/FormatterUtils.js +1 -1
  26. package/src/GSToolBlockUtils.js +66 -1
  27. package/src/GitSenseChatUtils.js +58 -5
  28. package/src/LLMUtils.js +1 -1
  29. package/src/MarkdownUtils.js +4 -1
  30. package/src/MessageUtils.js +1 -1
  31. package/src/MetaRawResultUtils.js +244 -0
  32. package/src/PatchUtils/constants.js +9 -3
  33. package/src/PatchUtils/patchParser.js +60 -36
  34. package/src/PatchUtils/patchVerifier/detectAndFixOverlappingHunks.js +1 -1
  35. package/src/PatchUtils/patchVerifier/detectAndFixRedundantChanges.js +1 -1
  36. package/src/PatchUtils/patchVerifier/verifyAndCorrectHunkHeaders.js +1 -1
  37. package/src/SVGUtils.js +137 -2
  38. package/src/SharedUtils/stringUtils.js +303 -0
  39. package/src/CodeBlockUtils/blockProcessor.js.rej +0 -8
package/src/SVGUtils.js CHANGED
@@ -83,7 +83,7 @@ class SVGUtils {
83
83
  * @returns {Element} SVG element
84
84
  */
85
85
  static archive(params) {
86
- const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M1.75 2.5a.25.25 0 00-.25.25v1.5c0 .138.112.25.25.25h12.5a.25.25 0 00.25-.25v-1.5a.25.25 0 00-.25-.25H1.75zM0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v1.5A1.75 1.75 0 0114.25 6H1.75A1.75 1.75 0 010 4.25v-1.5zM1.75 7a.75.75 0 01.75.75v5.5c0 .138.112.25.25.25h10.5a.25.25 0 00.25-.25v-5.5a.75.75 0 111.5 0v5.5A1.75 1.75 0 0113.25 15H2.75A1.75 1.75 0 011 13.25v-5.5A.75.75 0 011.75 7zm4.5 1a.75.75 0 000 1.5h3.5a.75.75 0 100-1.5h-3.5z'></path></svg>`;
86
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v1.5A1.75 1.75 0 0 1 14.25 6H1.75A1.75 1.75 0 0 1 0 4.25ZM1.75 7a.75.75 0 0 1 .75.75v5.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-5.5a.75.75 0 0 1 1.5 0v5.5A1.75 1.75 0 0 1 13.25 15H2.75A1.75 1.75 0 0 1 1 13.25v-5.5A.75.75 0 0 1 1.75 7Zm0-4.5a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25ZM6.25 8h3.5a.75.75 0 0 1 0 1.5h-3.5a.75.75 0 0 1 0-1.5Z"></path></svg>`;
87
87
  return this.create(xml, params);
88
88
  }
89
89
 
@@ -409,6 +409,16 @@ class SVGUtils {
409
409
  return this.create(xml, params);
410
410
  }
411
411
 
412
+ /**
413
+ * Generate commentDiscussions24 SVG icon
414
+ * @param {Object} params - Configuration parameters
415
+ * @returns {Element} SVG element
416
+ */
417
+ static commentDiscussions24(params) {
418
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path></svg>`;
419
+ return this.create(xml, params);
420
+ }
421
+
412
422
  /**
413
423
  * Generate commit SVG icon
414
424
  * @param {Object} params - Configuration parameters
@@ -419,6 +429,16 @@ class SVGUtils {
419
429
  return this.create(xml, params);
420
430
  }
421
431
 
432
+ /**
433
+ * Generate commit SVG icon
434
+ * @param {Object} params - Configuration parameters
435
+ * @returns {Element} SVG element
436
+ */
437
+ static compose24(params) {
438
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M1 21.25V4a1.75 1.75 0 0 1 1.75-1.75h7.51a.75.75 0 0 1 0 1.5H2.75A.25.25 0 0 0 2.5 4v17.25a.25.25 0 0 0 .25.25H20a.25.25 0 0 0 .25-.25V13a.75.75 0 0 1 1.5 0v8.25c0 .464-.184.909-.513 1.237A1.746 1.746 0 0 1 20 23H2.75A1.75 1.75 0 0 1 1 21.25Z"></path><path d="M19.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.25.929a.751.751 0 0 1-.928-.927l.929-3.25c.082-.287.235-.547.445-.758l8.61-8.61Zm-7.55 9.67a.241.241 0 0 0-.063.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064L19.19 6.25l-1.44-1.44Zm8.964-8.61a.245.245 0 0 0-.177-.073.245.245 0 0 0-.177.073L18.811 3.75l1.439 1.44 1.263-1.263a.245.245 0 0 0 .073-.177.245.245 0 0 0-.073-.177Z"></path></svg>`;
439
+ return this.create(xml, params);
440
+ }
441
+
422
442
  /**
423
443
  * Generate container SVG icon
424
444
  * @param {Object} params - Configuration parameters
@@ -449,6 +469,16 @@ class SVGUtils {
449
469
  return this.create(xml, params);
450
470
  }
451
471
 
472
+ /**
473
+ * Generate crosshairs SVG icon
474
+ * @param {Object} params - Configuration parameters
475
+ * @returns {Element} SVG element
476
+ */
477
+ static crosshairs(params) {
478
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M14 8A6 6 0 1 1 2 8a6 6 0 0 1 12 0Zm-1.5 0a4.5 4.5 0 1 0-9 0 4.5 4.5 0 0 0 9 0Z"></path><path d="M5 7.25a.75.75 0 0 1 0 1.5H1a.75.75 0 0 1 0-1.5Zm3-7a.75.75 0 0 1 .75.75v4a.75.75 0 0 1-1.5 0V1A.75.75 0 0 1 8 .25Zm7 7a.75.75 0 0 1 0 1.5h-4a.75.75 0 0 1 0-1.5Zm-7 3a.75.75 0 0 1 .75.75v4a.75.75 0 0 1-1.5 0v-4a.75.75 0 0 1 .75-.75Z"></path></svg>`;
479
+ return this.create(xml, params);
480
+ }
481
+
452
482
  /**
453
483
  * Generate deepSeek SVG icon
454
484
  * @param {Object} params - Configuration parameters
@@ -490,6 +520,16 @@ class SVGUtils {
490
520
  return this.create(xml, params);
491
521
  }
492
522
 
523
+ /**
524
+ * Generate dropZone SVG icon
525
+ * @param {Object} params - Configuration parameters
526
+ * @returns {Element} SVG element
527
+ */
528
+ static dropZone(params) {
529
+ const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='64' height='64'><path d="M7 18C4.23858 18 2 15.7614 2 13C2 10.2386 4.23858 8 7 8C7.55228 8 8 8.44772 8 9C8 9.55228 7.55228 10 7 10C5.34315 10 4 11.3431 4 13C4 14.6569 5.34315 16 7 16H17C18.6569 16 20 14.6569 20 13C20 11.3431 18.6569 10 17 10C16.4477 10 16 9.55228 16 9C16 8.44772 16.4477 8 17 8C19.7614 8 22 10.2386 22 13C22 15.7614 19.7614 18 17 18H7Z" fill="currentColor"/><path d="M12 2L12 14M12 14L9 11M12 14L15 11" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
530
+ return this.create(xml, params);
531
+ }
532
+
493
533
  /**
494
534
  * Generate dot SVG icon
495
535
  * @param {Object} params - Configuration parameters
@@ -530,6 +570,26 @@ class SVGUtils {
530
570
  return this.create(xml, params);
531
571
  }
532
572
 
573
+ /**
574
+ * Generate eye SVG icon
575
+ * @param {Object} params - Configuration parameters
576
+ * @returns {Element} SVG element
577
+ */
578
+ static eye(params) {
579
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 2c1.981 0 3.671.992 4.933 2.078 1.27 1.091 2.187 2.345 2.637 3.023a1.62 1.62 0 0 1 0 1.798c-.45.678-1.367 1.932-2.637 3.023C11.67 13.008 9.981 14 8 14c-1.981 0-3.671-.992-4.933-2.078C1.797 10.83.88 9.576.43 8.898a1.62 1.62 0 0 1 0-1.798c.45-.677 1.367-1.931 2.637-3.022C4.33 2.992 6.019 2 8 2ZM1.679 7.932a.12.12 0 0 0 0 .136c.411.622 1.241 1.75 2.366 2.717C5.176 11.758 6.527 12.5 8 12.5c1.473 0 2.825-.742 3.955-1.715 1.124-.967 1.954-2.096 2.366-2.717a.12.12 0 0 0 0-.136c-.412-.621-1.242-1.75-2.366-2.717C10.824 4.242 9.473 3.5 8 3.5c-1.473 0-2.825.742-3.955 1.715-1.124.967-1.954 2.096-2.366 2.717ZM8 10a2 2 0 1 1-.001-3.999A2 2 0 0 1 8 10Z"></path></svg>`;
580
+ return this.create(xml, params);
581
+ }
582
+
583
+ /**
584
+ * Generate eye closed SVG icon
585
+ * @param {Object} params - Configuration parameters
586
+ * @returns {Element} SVG element
587
+ */
588
+ static eyeClosed(params) {
589
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M.143 2.31a.75.75 0 0 1 1.047-.167l14.5 10.5a.75.75 0 1 1-.88 1.214l-2.248-1.628C11.346 13.19 9.792 14 8 14c-1.981 0-3.67-.992-4.933-2.078C1.797 10.832.88 9.577.43 8.9a1.619 1.619 0 0 1 0-1.797c.353-.533.995-1.42 1.868-2.305L.31 3.357A.75.75 0 0 1 .143 2.31Zm1.536 5.622A.12.12 0 0 0 1.657 8c0 .021.006.045.022.068.412.621 1.242 1.75 2.366 2.717C5.175 11.758 6.527 12.5 8 12.5c1.195 0 2.31-.488 3.29-1.191L9.063 9.695A2 2 0 0 1 6.058 7.52L3.529 5.688a14.207 14.207 0 0 0-1.85 2.244ZM8 3.5c-.516 0-1.017.09-1.499.251a.75.75 0 1 1-.473-1.423A6.207 6.207 0 0 1 8 2c1.981 0 3.67.992 4.933 2.078 1.27 1.091 2.187 2.345 2.637 3.023a1.62 1.62 0 0 1 0 1.798c-.11.166-.248.365-.41.587a.75.75 0 1 1-1.21-.887c.148-.201.272-.382.371-.53a.119.119 0 0 0 0-.137c-.412-.621-1.242-1.75-2.366-2.717C10.825 4.242 9.473 3.5 8 3.5Z"></path></svg>`;
590
+ return this.create(xml, params);
591
+ }
592
+
533
593
  /**
534
594
  * Generate file SVG icon
535
595
  * @param {Object} params - Configuration parameters
@@ -822,6 +882,16 @@ class SVGUtils {
822
882
  return this.create(xml, params);
823
883
  }
824
884
 
885
+ /**
886
+ * Generate lock SVG icon
887
+ * @param {Object} params - Configuration parameters
888
+ * @returns {Element} SVG element
889
+ */
890
+ static lock(params) {
891
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>`;
892
+ return this.create(xml, params);
893
+ }
894
+
825
895
  /**
826
896
  * Generate lightBulb SVG icon
827
897
  * @param {Object} params - Configuration parameters
@@ -874,6 +944,16 @@ class SVGUtils {
874
944
  return this.create(xml, params);
875
945
  }
876
946
 
947
+ /**
948
+ * Generate moveToEnd SVG icon
949
+ * @param {Object} params - Configuration parameters
950
+ * @returns {Element} SVG element
951
+ */
952
+ static moveToEnd(params) {
953
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m10.78 8.53-3.75 3.75a.749.749 0 1 1-1.06-1.06l2.469-2.47H1.75a.75.75 0 0 1 0-1.5h6.689L5.97 4.78a.749.749 0 1 1 1.06-1.06l3.75 3.75a.749.749 0 0 1 0 1.06ZM13 12.25v-8.5a.75.75 0 0 1 1.5 0v8.5a.75.75 0 0 1-1.5 0Z"></path></svg>`;
954
+ return this.create(xml, params);
955
+ }
956
+
877
957
  /**
878
958
  * Generate northStar SVG icon
879
959
  * @param {Object} params - Configuration parameters
@@ -894,6 +974,16 @@ class SVGUtils {
894
974
  return this.create(xml, params);
895
975
  }
896
976
 
977
+ /**
978
+ * Generate note24 SVG icon
979
+ * @param {Object} params - Configuration parameters
980
+ * @returns {Element} SVG element
981
+ */
982
+ static note24(params) {
983
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M0 4.75C0 3.784.784 3 1.75 3h20.5c.966 0 1.75.784 1.75 1.75v14.5A1.75 1.75 0 0 1 22.25 21H1.75A1.75 1.75 0 0 1 0 19.25Zm1.75-.25a.25.25 0 0 0-.25.25v14.5c0 .138.112.25.25.25h20.5a.25.25 0 0 0 .25-.25V4.75a.25.25 0 0 0-.25-.25Z"></path><path d="M5 8.75A.75.75 0 0 1 5.75 8h11.5a.75.75 0 0 1 0 1.5H5.75A.75.75 0 0 1 5 8.75Zm0 4a.75.75 0 0 1 .75-.75h5.5a.75.75 0 0 1 0 1.5h-5.5a.75.75 0 0 1-.75-.75Z"></path></svg>`;
984
+ return this.create(xml, params);
985
+ }
986
+
897
987
  /**
898
988
  * Generate openAI SVG icon
899
989
  * @param {Object} params - Configuration parameters
@@ -960,7 +1050,17 @@ class SVGUtils {
960
1050
  * @returns {Element} SVG element
961
1051
  */
962
1052
  static pin(params) {
963
- const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M4.456.734a1.75 1.75 0 012.826.504l.613 1.327a3.081 3.081 0 002.084 1.707l2.454.584c1.332.317 1.8 1.972.832 2.94L11.06 10l3.72 3.72a.75.75 0 11-1.061 1.06L10 11.06l-2.204 2.205c-.968.968-2.623.5-2.94-.832l-.584-2.454a3.081 3.081 0 00-1.707-2.084l-1.327-.613a1.75 1.75 0 01-.504-2.826L4.456.734zM5.92 1.866a.25.25 0 00-.404-.072L1.794 5.516a.25.25 0 00.072.404l1.328.613A4.582 4.582 0 015.73 9.63l.584 2.454a.25.25 0 00.42.12l5.47-5.47a.25.25 0 00-.12-.42L9.63 5.73a4.581 4.581 0 01-3.098-2.537L5.92 1.866z'></path></svg>`;
1053
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="m11.294.984 3.722 3.722a1.75 1.75 0 0 1-.504 2.826l-1.327.613a3.089 3.089 0 0 0-1.707 2.084l-.584 2.454c-.317 1.332-1.972 1.8-2.94.832L5.75 11.311 1.78 15.28a.749.749 0 1 1-1.06-1.06l3.969-3.97-2.204-2.204c-.968-.968-.5-2.623.832-2.94l2.454-.584a3.08 3.08 0 0 0 2.084-1.707l.613-1.327a1.75 1.75 0 0 1 2.826-.504ZM6.283 9.723l2.732 2.731a.25.25 0 0 0 .42-.119l.584-2.454a4.586 4.586 0 0 1 2.537-3.098l1.328-.613a.25.25 0 0 0 .072-.404l-3.722-3.722a.25.25 0 0 0-.404.072l-.613 1.328a4.584 4.584 0 0 1-3.098 2.537l-2.454.584a.25.25 0 0 0-.119.42l2.731 2.732Z"></path></svg>`;
1054
+ return this.create(xml, params);
1055
+ }
1056
+
1057
+ /**
1058
+ * Generate pin24 SVG icon
1059
+ * @param {Object} params - Configuration parameters
1060
+ * @returns {Element} SVG element
1061
+ */
1062
+ static pin24(params) {
1063
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="m16.114 1.553 6.333 6.333a1.75 1.75 0 0 1-.603 2.869l-1.63.633a5.67 5.67 0 0 0-3.395 3.725l-1.131 3.959a1.75 1.75 0 0 1-2.92.757L9 16.061l-5.595 5.594a.749.749 0 1 1-1.06-1.06L7.939 15l-3.768-3.768a1.75 1.75 0 0 1 .757-2.92l3.959-1.131a5.666 5.666 0 0 0 3.725-3.395l.633-1.63a1.75 1.75 0 0 1 2.869-.603ZM5.232 10.171l8.597 8.597a.25.25 0 0 0 .417-.108l1.131-3.959A7.17 7.17 0 0 1 19.67 9.99l1.63-.634a.25.25 0 0 0 .086-.409l-6.333-6.333a.25.25 0 0 0-.409.086l-.634 1.63a7.17 7.17 0 0 1-4.711 4.293L5.34 9.754a.25.25 0 0 0-.108.417Z"></path></svg>`;
964
1064
  return this.create(xml, params);
965
1065
  }
966
1066
 
@@ -1076,6 +1176,16 @@ class SVGUtils {
1076
1176
  return this.create(xml, params);
1077
1177
  }
1078
1178
 
1179
+ /**
1180
+ * Generate sparkle SVG icon
1181
+ * @param {Object} params - Configuration parameters
1182
+ * @returns {Element} SVG element
1183
+ */
1184
+ static sparkle(params) {
1185
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M7.198.57c.275-.752 1.34-.752 1.615 0l.849 2.317a5.819 5.819 0 0 0 3.462 3.463l2.317.848c.753.275.753 1.34 0 1.615l-2.317.849a5.815 5.815 0 0 0-3.462 3.462l-.849 2.317c-.275.753-1.34.753-1.615 0l-.848-2.317a5.819 5.819 0 0 0-3.463-3.462L.57 8.813c-.752-.275-.752-1.34 0-1.615l2.317-.848A5.823 5.823 0 0 0 6.35 2.887L7.198.57Zm.562 2.833A7.323 7.323 0 0 1 3.403 7.76l-.673.246.673.246a7.324 7.324 0 0 1 4.357 4.356l.246.673.246-.673a7.322 7.322 0 0 1 4.356-4.356l.673-.246-.673-.246a7.324 7.324 0 0 1-4.356-4.357l-.246-.673-.246.673Z"></path></svg>`;
1186
+ return this.create(xml, params);
1187
+ }
1188
+
1079
1189
  /**
1080
1190
  * Generate square SVG icon
1081
1191
  * @param {Object} params - Configuration parameters
@@ -1086,6 +1196,16 @@ class SVGUtils {
1086
1196
  return this.create(xml, params);
1087
1197
  }
1088
1198
 
1199
+ /**
1200
+ * Generate squarCircle SVG icon
1201
+ * @param {Object} params - Configuration parameters
1202
+ * @returns {Element} SVG element
1203
+ */
1204
+ static squareCircle(params) {
1205
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16Zm0-1.5a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13Z"></path><path d="M5 5.75A.75.75 0 0 1 5.75 5h4.5a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-.75.75h-4.5a.75.75 0 0 1-.75-.75Z"></path></svg>`;
1206
+ return this.create(xml, params);
1207
+ }
1208
+
1089
1209
  /**
1090
1210
  * Generate stack SVG icon
1091
1211
  * @param {Object} params - Configuration parameters
@@ -1376,6 +1496,16 @@ class SVGUtils {
1376
1496
  return this.create(xml, params);
1377
1497
  }
1378
1498
 
1499
+ /**
1500
+ * Generate verticalEllipsis SVG icon
1501
+ * @param {Object} params - Configuration parameters
1502
+ * @returns {Element} SVG element
1503
+ */
1504
+ static verticalEllipsis(params) {
1505
+ const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16' transform='rotate(90)'><path d='M8 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zM1.5 9a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm13 0a1.5 1.5 0 100-3 1.5 1.5 0 000 3z'></path></svg>`;
1506
+ return this.create(xml, params);
1507
+ }
1508
+
1379
1509
  /**
1380
1510
  * Generate x SVG icon
1381
1511
  * @param {Object} params - Configuration parameters
@@ -1405,6 +1535,11 @@ class SVGUtils {
1405
1535
  const xml = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16'><path fill-rule='evenodd' d='M2.343 13.657A8 8 0 1113.657 2.343 8 8 0 012.343 13.657zM6.03 4.97a.75.75 0 00-1.06 1.06L6.94 8 4.97 9.97a.75.75 0 101.06 1.06L8 9.06l1.97 1.97a.75.75 0 101.06-1.06L9.06 8l1.97-1.97a.75.75 0 10-1.06-1.06L8 6.94 6.03 4.97z'></path></svg>`;
1406
1536
  return this.create(xml, params);
1407
1537
  }
1538
+
1539
+ static zai(params) {
1540
+ const xml = `<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em"><title>Z.ai</title><path d="M12.105 2L9.927 4.953H.653L2.83 2h9.276zM23.254 19.048L21.078 22h-9.242l2.174-2.952h9.244zM24 2L9.264 22H0L14.736 2H24z"/></svg>`;
1541
+ return this.create(xml, params);
1542
+ }
1408
1543
  }
1409
1544
 
1410
1545
  module.exports = SVGUtils;
@@ -0,0 +1,303 @@
1
+ /*
2
+ * Component: StringUtils
3
+ * Block-UUID: 7069f2b4-f0b3-4dcd-9eae-5cecaddcdd66
4
+ * Version: 1.0.0
5
+ * Description: A collection of utility functions for common string manipulation and processing tasks within GitSense Chat.
6
+ * Language: JavaScript
7
+ * Created-at: 2025-10-30T22:06:47.000Z
8
+ * Authors: Qwen 3 Coder 480B - Cerebras (v1.0.0)
9
+ */
10
+
11
+
12
+ /**
13
+ * Splits a string into an array of substrings based on a delimiter, up to a specified limit.
14
+ * This mimics behavior similar to Python's `str.split(sep, maxsplit)` or Java's `String.split(regex, limit)`.
15
+ *
16
+ * @param {string} text - The string to split.
17
+ * @param {string|RegExp} delimiter - The delimiter to split the string by.
18
+ * @param {number} [limit=Infinity] - The maximum number of parts to return. The final part will contain the remainder of the string.
19
+ * @returns {string[]} An array of substrings.
20
+ */
21
+ function splitWithLimit(text, delimiter, limit = Infinity) {
22
+ if (limit === 0) {
23
+ return [];
24
+ }
25
+ if (limit === 1) {
26
+ return [text];
27
+ }
28
+
29
+ const parts = [];
30
+ let remainingText = text;
31
+ let count = 0;
32
+
33
+ // Handle RegExp delimiter
34
+ if (delimiter instanceof RegExp) {
35
+ // For RegExp, we need to manually find matches and slice the string
36
+ // This is a simplified approach and might not cover all edge cases of global regex matching
37
+ // especially with capture groups or zero-width matches.
38
+ const flags = delimiter.flags.includes('g') ? delimiter.flags : delimiter.flags + 'g';
39
+ const globalDelimiter = new RegExp(delimiter.source, flags);
40
+ let match;
41
+ let lastIndex = 0;
42
+ let matchCount = 0;
43
+
44
+ // We need (limit - 1) matches to create `limit` parts
45
+ while ((match = globalDelimiter.exec(remainingText)) !== null && matchCount < limit - 1) {
46
+ // Add the part before the match
47
+ parts.push(remainingText.substring(lastIndex, match.index));
48
+ // Add the matched delimiter part itself if it's non-empty (important for zero-width matches)
49
+ // This part is tricky; typically, the delimiter itself is not part of the returned array.
50
+ // The logic below follows the standard split behavior where the delimiter is not included.
51
+ lastIndex = match.index + match[0].length;
52
+ matchCount++;
53
+ // Avoid infinite loop for zero-length matches
54
+ if (match.index === globalDelimiter.lastIndex) {
55
+ globalDelimiter.lastIndex++;
56
+ }
57
+ }
58
+ // Add the final part
59
+ parts.push(remainingText.substring(lastIndex));
60
+ } else {
61
+ // Handle string delimiter
62
+ const delimLength = delimiter.length;
63
+ if (delimLength === 0) {
64
+ // If delimiter is an empty string, split by characters
65
+ // This is consistent with JS String.split('')
66
+ return text.split('').slice(0, limit);
67
+ }
68
+ let index;
69
+ while (count < limit - 1 && (index = remainingText.indexOf(delimiter)) !== -1) {
70
+ parts.push(remainingText.substring(0, index));
71
+ remainingText = remainingText.substring(index + delimLength);
72
+ count++;
73
+ }
74
+ // Add the final part (the rest of the string)
75
+ parts.push(remainingText);
76
+ }
77
+
78
+ return parts;
79
+ }
80
+
81
+ /**
82
+ * Capitalizes the first character of a string.
83
+ *
84
+ * @param {string} text - The string to capitalize.
85
+ * @returns {string} The string with its first character capitalized.
86
+ */
87
+ function capitalize(text) {
88
+ if (!text || typeof text !== 'string') {
89
+ return text;
90
+ }
91
+ return text.charAt(0).toUpperCase() + text.slice(1);
92
+ }
93
+
94
+ /**
95
+ * Converts a string to title case (capitalizing the first letter of each word).
96
+ * Words are sequences of characters separated by space, tab, or newline.
97
+ *
98
+ * @param {string} text - The string to convert.
99
+ * @returns {string} The string in title case.
100
+ */
101
+ function titleCase(text) {
102
+ if (!text || typeof text !== 'string') {
103
+ return text;
104
+ }
105
+ // Split by one or more whitespace characters
106
+ return text.split(/\s+/).map(word => capitalize(word)).join(' ');
107
+ }
108
+
109
+ /**
110
+ * Converts a string to camelCase.
111
+ *
112
+ * @param {string} text - The string to convert.
113
+ * @returns {string} The string in camelCase.
114
+ */
115
+ function camelCase(text) {
116
+ if (!text || typeof text !== 'string') {
117
+ return text;
118
+ }
119
+ return text
120
+ .split(/\W+/) // Split on non-word characters
121
+ .map((word, index) => {
122
+ if (index === 0) {
123
+ // First word is lowercase
124
+ return word.toLowerCase();
125
+ }
126
+ // Subsequent words have their first letter capitalized
127
+ return capitalize(word.toLowerCase());
128
+ })
129
+ .join('');
130
+ }
131
+
132
+ /**
133
+ * Converts a string to PascalCase.
134
+ *
135
+ * @param {string} text - The string to convert.
136
+ * @returns {string} The string in PascalCase.
137
+ */
138
+ function pascalCase(text) {
139
+ if (!text || typeof text !== 'string') {
140
+ return text;
141
+ }
142
+ return text
143
+ .split(/\W+/) // Split on non-word characters
144
+ .map(word => capitalize(word.toLowerCase()))
145
+ .join('');
146
+ }
147
+
148
+ /**
149
+ * Converts a string to kebab-case.
150
+ *
151
+ * @param {string} text - The string to convert.
152
+ * @returns {string} The string in kebab-case.
153
+ */
154
+ function kebabCase(text) {
155
+ if (!text || typeof text !== 'string') {
156
+ return text;
157
+ }
158
+ return text
159
+ .split(/\W+/) // Split on non-word characters
160
+ .map(word => word.toLowerCase())
161
+ .filter(word => word.length > 0) // Remove empty strings from split
162
+ .join('-');
163
+ }
164
+
165
+ /**
166
+ * Converts a string to snake_case.
167
+ *
168
+ * @param {string} text - The string to convert.
169
+ * @returns {string} The string in snake_case.
170
+ */
171
+ function snakeCase(text) {
172
+ if (!text || typeof text !== 'string') {
173
+ return text;
174
+ }
175
+ return text
176
+ .split(/\W+/) // Split on non-word characters
177
+ .map(word => word.toLowerCase())
178
+ .filter(word => word.length > 0) // Remove empty strings from split
179
+ .join('_');
180
+ }
181
+
182
+ /**
183
+ * Converts a string to CONSTANT_CASE.
184
+ *
185
+ * @param {string} text - The string to convert.
186
+ * @returns {string} The string in CONSTANT_CASE.
187
+ */
188
+ function constantCase(text) {
189
+ if (!text || typeof text !== 'string') {
190
+ return text;
191
+ }
192
+ return text
193
+ .split(/\W+/) // Split on non-word characters
194
+ .map(word => word.toUpperCase())
195
+ .filter(word => word.length > 0) // Remove empty strings from split
196
+ .join('_');
197
+ }
198
+
199
+ /**
200
+ * Trims leading and trailing whitespace and normalizes internal whitespace
201
+ * (replacing sequences of whitespace characters with a single space).
202
+ *
203
+ * @param {string} text - The string to trim and normalize.
204
+ * @returns {string} The trimmed and normalized string.
205
+ */
206
+ function trimWhitespace(text) {
207
+ if (!text || typeof text !== 'string') {
208
+ return text;
209
+ }
210
+ return text.trim().replace(/\s+/g, ' ');
211
+ }
212
+
213
+ /**
214
+ * Truncates a string to a specified maximum length and appends a suffix if truncated.
215
+ *
216
+ * @param {string} text - The string to truncate.
217
+ * @param {number} maxLength - The maximum length of the string.
218
+ * @param {string} [suffix='...'] - The suffix to append if the string is truncated.
219
+ * @returns {string} The truncated string with suffix, or the original string if not truncated.
220
+ */
221
+ function truncate(text, maxLength, suffix = '...') {
222
+ if (!text || typeof text !== 'string' || maxLength <= 0) {
223
+ return '';
224
+ }
225
+ if (text.length <= maxLength) {
226
+ return text;
227
+ }
228
+ // Ensure we don't cut the suffix itself if maxLength is very small
229
+ const suffixLength = suffix.length;
230
+ if (maxLength <= suffixLength) {
231
+ // If max length is less than or equal to suffix, return a truncated suffix
232
+ // This is a bit of an edge case, but handles it gracefully.
233
+ return suffix.substring(0, maxLength);
234
+ }
235
+ return text.substring(0, maxLength - suffixLength) + suffix;
236
+ }
237
+
238
+ /**
239
+ * Escapes HTML characters in a string to prevent them from being interpreted as HTML.
240
+ *
241
+ * @param {string} text - The string to escape.
242
+ * @returns {string} The escaped string.
243
+ */
244
+ function escapeHtml(text) {
245
+ if (!text || typeof text !== 'string') {
246
+ return text;
247
+ }
248
+ const htmlEscapes = {
249
+ '&': '&amp;',
250
+ '<': '&lt;',
251
+ '>': '&gt;',
252
+ '"': '&quot;',
253
+ "'": '&#39;',
254
+ };
255
+ return text.replace(/[&<>"']/g, match => htmlEscapes[match]);
256
+ }
257
+
258
+ /**
259
+ * Removes HTML tags from a string.
260
+ *
261
+ * @param {string} text - The string to strip tags from.
262
+ * @returns {string} The string without HTML tags.
263
+ */
264
+ function stripHtml(text) {
265
+ if (!text || typeof text !== 'string') {
266
+ return text;
267
+ }
268
+ return text.replace(/<[^>]*>/g, '');
269
+ }
270
+
271
+ /**
272
+ * Performs a basic check to see if a string looks like a valid email address.
273
+ * This is a simple validation and should not be used for robust security checks.
274
+ *
275
+ * @param {string} email - The email string to validate.
276
+ * @returns {boolean} True if the string looks like a valid email, false otherwise.
277
+ */
278
+ function isValidEmail(email) {
279
+ if (!email || typeof email !== 'string') {
280
+ return false;
281
+ }
282
+ // A basic regex for email validation. Note: Fully validating email addresses
283
+ // is extremely complex. This covers common cases.
284
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
285
+ return emailRegex.test(email);
286
+ }
287
+
288
+
289
+ module.exports = {
290
+ splitWithLimit,
291
+ capitalize,
292
+ titleCase,
293
+ camelCase,
294
+ kebabCase,
295
+ snakeCase,
296
+ constantCase,
297
+ pascalCase,
298
+ trimWhitespace,
299
+ truncate,
300
+ escapeHtml,
301
+ stripHtml,
302
+ isValidEmail,
303
+ };
@@ -1,8 +0,0 @@
1
- @@ -262,6 +283,7 @@
2
- function processCodeBlocks(text, options = { silent: false, validatePatches: false }) {
3
- if (typeof text !== "string") { // Allow empty strings
4
- console.warn("Warning: Input must be a string.");
5
- + return { blocks: [], warnings: [{ type: 'invalid_input', message: 'Input must be a string.' }], hasIncompleteBlocks: false, lastIncompleteBlock: null };
6
- }
7
- if (text.trim() === "") {
8
- return { blocks: [], warnings: [], hasIncompleteBlocks: false, lastIncompleteBlock: null };