@gitsense/gsc-utils 0.2.19 → 0.2.20

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.
@@ -8845,11 +8845,120 @@ function replaceToolBlock(markdownContent, toolName, newToolData, CodeBlockUtils
8845
8845
  return updatedMarkdown;
8846
8846
  }
8847
8847
 
8848
+ /**
8849
+ * Detects an unfenced GitSense Chat Tool block within a given message string,
8850
+ * validates its JSON content, and returns a properly formatted fenced block
8851
+ * along with its original position.
8852
+ *
8853
+ * This function is designed to be forgiving, looking for the marker line
8854
+ * "# GitSense Chat Tool" followed by JSON content, even if not enclosed
8855
+ * in Markdown code fences.
8856
+ *
8857
+ * @param {string} messageContent - The full message content string.
8858
+ * @returns {{
8859
+ * found: boolean,
8860
+ * formattedToolBlock?: string,
8861
+ * originalUnfencedContent?: string,
8862
+ * startIndex?: number,
8863
+ * endIndex?: number,
8864
+ * parsedToolData?: object
8865
+ * }} An object indicating if an unfenced tool block was found, its formatted version,
8866
+ * its original content, start/end indices, and the parsed tool data.
8867
+ */
8868
+ function detectAndFormatUnfencedToolBlock(messageContent) {
8869
+ const marker = '# GitSense Chat Tool';
8870
+ const lines = messageContent.split('\n');
8871
+ let markerLineIndex = -1;
8872
+
8873
+ // 1. Find the marker line
8874
+ for (let i = 0; i < lines.length; i++) {
8875
+ if (lines[i].trim().startsWith(marker)) {
8876
+ markerLineIndex = i;
8877
+ break;
8878
+ }
8879
+ }
8880
+
8881
+ if (markerLineIndex === -1) {
8882
+ return { found: false };
8883
+ }
8884
+
8885
+ // 2. Extract potential JSON content following the marker
8886
+ let jsonStartLineIndex = -1;
8887
+ let jsonEndLineIndex = -1;
8888
+ let braceCount = 0;
8889
+ let inJsonBlock = false;
8890
+
8891
+ for (let i = markerLineIndex + 1; i < lines.length; i++) {
8892
+ const trimmedLine = lines[i].trim();
8893
+
8894
+ if (!inJsonBlock) {
8895
+ if (trimmedLine.length === 0 || trimmedLine.startsWith('#')) { // Skip empty lines or comments
8896
+ continue;
8897
+ }
8898
+ if (trimmedLine.startsWith('{')) {
8899
+ jsonStartLineIndex = i;
8900
+ inJsonBlock = true;
8901
+ } else {
8902
+ return { found: false }; // Found something after marker but not JSON
8903
+ }
8904
+ }
8905
+
8906
+ if (inJsonBlock) {
8907
+ for (const char of trimmedLine) {
8908
+ if (char === '{') braceCount++;
8909
+ else if (char === '}') braceCount--;
8910
+ }
8911
+ if (braceCount === 0 && trimmedLine.endsWith('}')) {
8912
+ jsonEndLineIndex = i;
8913
+ break; // Found the end of the JSON block
8914
+ }
8915
+ }
8916
+ }
8917
+
8918
+ if (jsonStartLineIndex === -1 || jsonEndLineIndex === -1) {
8919
+ return { found: false }; // JSON block not properly formed or not found
8920
+ }
8921
+
8922
+ // Extract the raw unfenced content including the marker and JSON
8923
+ const originalUnfencedContentLines = lines.slice(markerLineIndex, jsonEndLineIndex + 1);
8924
+ const originalUnfencedContent = originalUnfencedContentLines.join('\n');
8925
+
8926
+ // 3. Validate the extracted content using parseToolBlock
8927
+ let parsedToolData = null;
8928
+ try {
8929
+ parsedToolData = parseToolBlock$1(originalUnfencedContent);
8930
+ } catch (error) {
8931
+ console.warn("detectAndFormatUnfencedToolBlock: Failed to parse unfenced tool block JSON:", error.message);
8932
+ return { found: false }; // Invalid JSON structure
8933
+ }
8934
+
8935
+ if (!parsedToolData) {
8936
+ return { found: false };
8937
+ }
8938
+
8939
+ // 4. Format the validated tool data into a fenced block
8940
+ const formattedToolBlock = `\`\`\`txt\n${formatToolBlock(parsedToolData)}\n\`\`\``;
8941
+
8942
+ // Calculate start and end indices in the original message string
8943
+ const startIndex = messageContent.indexOf(originalUnfencedContent);
8944
+ const endIndex = startIndex + originalUnfencedContent.length;
8945
+
8946
+ return {
8947
+ found: true,
8948
+ formattedToolBlock,
8949
+ originalUnfencedContent,
8950
+ startIndex,
8951
+ endIndex,
8952
+ parsedToolData
8953
+ };
8954
+ }
8955
+
8848
8956
  var GSToolBlockUtils$3 = {
8849
8957
  isToolBlock: isToolBlock$1,
8850
8958
  parseToolBlock: parseToolBlock$1,
8851
8959
  formatToolBlock,
8852
8960
  replaceToolBlock,
8961
+ detectAndFormatUnfencedToolBlock,
8853
8962
  };
8854
8963
 
8855
8964
  /*
@@ -8843,11 +8843,120 @@ function replaceToolBlock(markdownContent, toolName, newToolData, CodeBlockUtils
8843
8843
  return updatedMarkdown;
8844
8844
  }
8845
8845
 
8846
+ /**
8847
+ * Detects an unfenced GitSense Chat Tool block within a given message string,
8848
+ * validates its JSON content, and returns a properly formatted fenced block
8849
+ * along with its original position.
8850
+ *
8851
+ * This function is designed to be forgiving, looking for the marker line
8852
+ * "# GitSense Chat Tool" followed by JSON content, even if not enclosed
8853
+ * in Markdown code fences.
8854
+ *
8855
+ * @param {string} messageContent - The full message content string.
8856
+ * @returns {{
8857
+ * found: boolean,
8858
+ * formattedToolBlock?: string,
8859
+ * originalUnfencedContent?: string,
8860
+ * startIndex?: number,
8861
+ * endIndex?: number,
8862
+ * parsedToolData?: object
8863
+ * }} An object indicating if an unfenced tool block was found, its formatted version,
8864
+ * its original content, start/end indices, and the parsed tool data.
8865
+ */
8866
+ function detectAndFormatUnfencedToolBlock(messageContent) {
8867
+ const marker = '# GitSense Chat Tool';
8868
+ const lines = messageContent.split('\n');
8869
+ let markerLineIndex = -1;
8870
+
8871
+ // 1. Find the marker line
8872
+ for (let i = 0; i < lines.length; i++) {
8873
+ if (lines[i].trim().startsWith(marker)) {
8874
+ markerLineIndex = i;
8875
+ break;
8876
+ }
8877
+ }
8878
+
8879
+ if (markerLineIndex === -1) {
8880
+ return { found: false };
8881
+ }
8882
+
8883
+ // 2. Extract potential JSON content following the marker
8884
+ let jsonStartLineIndex = -1;
8885
+ let jsonEndLineIndex = -1;
8886
+ let braceCount = 0;
8887
+ let inJsonBlock = false;
8888
+
8889
+ for (let i = markerLineIndex + 1; i < lines.length; i++) {
8890
+ const trimmedLine = lines[i].trim();
8891
+
8892
+ if (!inJsonBlock) {
8893
+ if (trimmedLine.length === 0 || trimmedLine.startsWith('#')) { // Skip empty lines or comments
8894
+ continue;
8895
+ }
8896
+ if (trimmedLine.startsWith('{')) {
8897
+ jsonStartLineIndex = i;
8898
+ inJsonBlock = true;
8899
+ } else {
8900
+ return { found: false }; // Found something after marker but not JSON
8901
+ }
8902
+ }
8903
+
8904
+ if (inJsonBlock) {
8905
+ for (const char of trimmedLine) {
8906
+ if (char === '{') braceCount++;
8907
+ else if (char === '}') braceCount--;
8908
+ }
8909
+ if (braceCount === 0 && trimmedLine.endsWith('}')) {
8910
+ jsonEndLineIndex = i;
8911
+ break; // Found the end of the JSON block
8912
+ }
8913
+ }
8914
+ }
8915
+
8916
+ if (jsonStartLineIndex === -1 || jsonEndLineIndex === -1) {
8917
+ return { found: false }; // JSON block not properly formed or not found
8918
+ }
8919
+
8920
+ // Extract the raw unfenced content including the marker and JSON
8921
+ const originalUnfencedContentLines = lines.slice(markerLineIndex, jsonEndLineIndex + 1);
8922
+ const originalUnfencedContent = originalUnfencedContentLines.join('\n');
8923
+
8924
+ // 3. Validate the extracted content using parseToolBlock
8925
+ let parsedToolData = null;
8926
+ try {
8927
+ parsedToolData = parseToolBlock$1(originalUnfencedContent);
8928
+ } catch (error) {
8929
+ console.warn("detectAndFormatUnfencedToolBlock: Failed to parse unfenced tool block JSON:", error.message);
8930
+ return { found: false }; // Invalid JSON structure
8931
+ }
8932
+
8933
+ if (!parsedToolData) {
8934
+ return { found: false };
8935
+ }
8936
+
8937
+ // 4. Format the validated tool data into a fenced block
8938
+ const formattedToolBlock = `\`\`\`txt\n${formatToolBlock(parsedToolData)}\n\`\`\``;
8939
+
8940
+ // Calculate start and end indices in the original message string
8941
+ const startIndex = messageContent.indexOf(originalUnfencedContent);
8942
+ const endIndex = startIndex + originalUnfencedContent.length;
8943
+
8944
+ return {
8945
+ found: true,
8946
+ formattedToolBlock,
8947
+ originalUnfencedContent,
8948
+ startIndex,
8949
+ endIndex,
8950
+ parsedToolData
8951
+ };
8952
+ }
8953
+
8846
8954
  var GSToolBlockUtils$3 = {
8847
8955
  isToolBlock: isToolBlock$1,
8848
8956
  parseToolBlock: parseToolBlock$1,
8849
8957
  formatToolBlock,
8850
8958
  replaceToolBlock,
8959
+ detectAndFormatUnfencedToolBlock,
8851
8960
  };
8852
8961
 
8853
8962
  /*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitsense/gsc-utils",
3
- "version": "0.2.19",
3
+ "version": "0.2.20",
4
4
  "description": "Utilities for GitSense Chat (GSC)",
5
5
  "main": "dist/gsc-utils.cjs.js",
6
6
  "module": "dist/gsc-utils.esm.js",
@@ -162,9 +162,118 @@ function replaceToolBlock(markdownContent, toolName, newToolData, CodeBlockUtils
162
162
  return updatedMarkdown;
163
163
  }
164
164
 
165
+ /**
166
+ * Detects an unfenced GitSense Chat Tool block within a given message string,
167
+ * validates its JSON content, and returns a properly formatted fenced block
168
+ * along with its original position.
169
+ *
170
+ * This function is designed to be forgiving, looking for the marker line
171
+ * "# GitSense Chat Tool" followed by JSON content, even if not enclosed
172
+ * in Markdown code fences.
173
+ *
174
+ * @param {string} messageContent - The full message content string.
175
+ * @returns {{
176
+ * found: boolean,
177
+ * formattedToolBlock?: string,
178
+ * originalUnfencedContent?: string,
179
+ * startIndex?: number,
180
+ * endIndex?: number,
181
+ * parsedToolData?: object
182
+ * }} An object indicating if an unfenced tool block was found, its formatted version,
183
+ * its original content, start/end indices, and the parsed tool data.
184
+ */
185
+ function detectAndFormatUnfencedToolBlock(messageContent) {
186
+ const marker = '# GitSense Chat Tool';
187
+ const lines = messageContent.split('\n');
188
+ let markerLineIndex = -1;
189
+
190
+ // 1. Find the marker line
191
+ for (let i = 0; i < lines.length; i++) {
192
+ if (lines[i].trim().startsWith(marker)) {
193
+ markerLineIndex = i;
194
+ break;
195
+ }
196
+ }
197
+
198
+ if (markerLineIndex === -1) {
199
+ return { found: false };
200
+ }
201
+
202
+ // 2. Extract potential JSON content following the marker
203
+ let jsonStartLineIndex = -1;
204
+ let jsonEndLineIndex = -1;
205
+ let braceCount = 0;
206
+ let inJsonBlock = false;
207
+
208
+ for (let i = markerLineIndex + 1; i < lines.length; i++) {
209
+ const trimmedLine = lines[i].trim();
210
+
211
+ if (!inJsonBlock) {
212
+ if (trimmedLine.length === 0 || trimmedLine.startsWith('#')) { // Skip empty lines or comments
213
+ continue;
214
+ }
215
+ if (trimmedLine.startsWith('{')) {
216
+ jsonStartLineIndex = i;
217
+ inJsonBlock = true;
218
+ } else {
219
+ return { found: false }; // Found something after marker but not JSON
220
+ }
221
+ }
222
+
223
+ if (inJsonBlock) {
224
+ for (const char of trimmedLine) {
225
+ if (char === '{') braceCount++;
226
+ else if (char === '}') braceCount--;
227
+ }
228
+ if (braceCount === 0 && trimmedLine.endsWith('}')) {
229
+ jsonEndLineIndex = i;
230
+ break; // Found the end of the JSON block
231
+ }
232
+ }
233
+ }
234
+
235
+ if (jsonStartLineIndex === -1 || jsonEndLineIndex === -1) {
236
+ return { found: false }; // JSON block not properly formed or not found
237
+ }
238
+
239
+ // Extract the raw unfenced content including the marker and JSON
240
+ const originalUnfencedContentLines = lines.slice(markerLineIndex, jsonEndLineIndex + 1);
241
+ const originalUnfencedContent = originalUnfencedContentLines.join('\n');
242
+
243
+ // 3. Validate the extracted content using parseToolBlock
244
+ let parsedToolData = null;
245
+ try {
246
+ parsedToolData = parseToolBlock(originalUnfencedContent);
247
+ } catch (error) {
248
+ console.warn("detectAndFormatUnfencedToolBlock: Failed to parse unfenced tool block JSON:", error.message);
249
+ return { found: false }; // Invalid JSON structure
250
+ }
251
+
252
+ if (!parsedToolData) {
253
+ return { found: false };
254
+ }
255
+
256
+ // 4. Format the validated tool data into a fenced block
257
+ const formattedToolBlock = `\`\`\`txt\n${formatToolBlock(parsedToolData)}\n\`\`\``;
258
+
259
+ // Calculate start and end indices in the original message string
260
+ const startIndex = messageContent.indexOf(originalUnfencedContent);
261
+ const endIndex = startIndex + originalUnfencedContent.length;
262
+
263
+ return {
264
+ found: true,
265
+ formattedToolBlock,
266
+ originalUnfencedContent,
267
+ startIndex,
268
+ endIndex,
269
+ parsedToolData
270
+ };
271
+ }
272
+
165
273
  module.exports = {
166
274
  isToolBlock,
167
275
  parseToolBlock,
168
276
  formatToolBlock,
169
277
  replaceToolBlock,
278
+ detectAndFormatUnfencedToolBlock,
170
279
  }