@gitsense/gsc-utils 0.2.14 → 0.2.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitsense/gsc-utils",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "Utilities for GitSense Chat (GSC)",
5
5
  "main": "dist/gsc-utils.cjs.js",
6
6
  "module": "dist/gsc-utils.esm.js",
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Component: AnalyzerUtils Default Prompt Loader
3
- * Block-UUID: 0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5f
3
+ * Block-UUID: be863744-6461-4b94-97ce-b1d177e9e881
4
4
  * Parent-UUID: N/A
5
5
  * Version: 1.0.0
6
6
  * Description: Provides utility functions for loading shared, default prompt components (system and start messages).
@@ -1,17 +1,18 @@
1
1
  /*
2
2
  * Component: AnalyzerUtils Discovery
3
- * Block-UUID: 0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5f
4
- * Parent-UUID: N/A
5
- * Version: 1.0.0
3
+ * Block-UUID: a87a86c4-69fc-4cbb-80a8-857f56122395
4
+ * Parent-UUID: 0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5f
5
+ * Version: 1.1.0
6
6
  * Description: Provides utility functions for discovering available analyzers.
7
7
  * Language: JavaScript
8
8
  * Created-at: 2025-08-28T23:48:00.000Z
9
- * Authors: Gemini 2.5 Flash (v1.0.0)
9
+ * Authors: Gemini 2.5 Flash (v1.0.0), Gemini 2.5 Flash (v1.1.0)
10
10
  */
11
11
 
12
12
 
13
13
  const fs = require('fs').promises;
14
14
  const path = require('path');
15
+ const { getAnalyzerInstructionsContent } = require('./instructionLoader');
15
16
 
16
17
  /**
17
18
  * Reads and parses the config.json file in a directory.
@@ -53,9 +54,12 @@ function isValidDirName(name) {
53
54
  * An analyzer is considered valid if a '1.md' file exists in the instructions directory.
54
55
  *
55
56
  * @param {string} analyzeMessagesBasePath - The absolute or relative path to the base directory containing the analyzer message files (e.g., 'messages/analyze').
56
- * @returns {Promise<Array<{id: string, label: string}>>} A promise that resolves to an array of analyzer objects.
57
+ * @param {object} [options={}] - Optional configuration.
58
+ * @param {boolean} [options.includeDescription=false] - Whether to include the description of the analyzer.
59
+ * @returns {Promise<Array<{id: string, label: string, name: string, protected: boolean, description?: string}>>} A promise that resolves to an array of analyzer objects.
57
60
  */
58
- async function getAnalyzers(analyzeMessagesBasePath) {
61
+ async function getAnalyzers(analyzeMessagesBasePath, options = {}) {
62
+ const { includeDescription = false } = options;
59
63
  const analyzers = [];
60
64
 
61
65
  try {
@@ -106,11 +110,23 @@ async function getAnalyzers(analyzeMessagesBasePath) {
106
110
  const analyzerId = `${analyzerName}::${contentType}::${instructionsType}`;
107
111
  const analyzerFullLabel = `${analyzerLabel} (${contentLabel} - ${instructionsLabel})`;
108
112
 
113
+ let descriptionContent = null;
114
+ if (includeDescription) {
115
+ try {
116
+ descriptionContent = await getAnalyzerInstructionsContent(analyzeMessagesBasePath, analyzerId);
117
+ } catch (descError) {
118
+ console.warn(`Warning: Could not load description for ${analyzerId}: ${descError.message}`);
119
+ descriptionContent = null;
120
+ }
121
+ }
122
+
109
123
  analyzers.push({
110
124
  id: analyzerId,
111
125
  label: analyzerFullLabel,
112
- protected: analyzerConfig?.protected || false
113
- });
126
+ name: analyzerName,
127
+ protected: analyzerConfig?.protected || false,
128
+ ...(descriptionContent && { description: descriptionContent })
129
+ });
114
130
  } catch (error) {
115
131
  // If 1.md doesn't exist, this is not a complete analyzer configuration, skip.
116
132
  if (error.code !== 'ENOENT') {
@@ -41,7 +41,9 @@ async function getAnalyzerInstructionsContent(analyzeMessagesBasePath, analyzerI
41
41
 
42
42
  try {
43
43
  const fileContent = await fs.readFile(instructionsFilePath, 'utf8');
44
- return fileContent;
44
+ const parts = fileContent.split('\n\n\n');
45
+ parts.shift();
46
+ return parts.join('\n\n\n');
45
47
  } catch (error) {
46
48
  if (error.code === 'ENOENT') {
47
49
  console.warn(`Analyzer instructions file not found: ${instructionsFilePath}`);
@@ -1,15 +1,18 @@
1
1
  /**
2
2
  * Component: GitSense Tool Block Utilities
3
- * Block-UUID: 72db6a5f-3b09-49e8-8f39-d4e3d37b510a
4
- * Parent-UUID: N/A
5
- * Version: 1.0.0
6
- * Description: Provides utility functions for identifying and parsing GitSense Chat Tool Blocks.
3
+ * Block-UUID: 8e1f7b4e-7e30-48b4-a7fc-643bf647661f
4
+ * Parent-UUID: 72db6a5f-3b09-49e8-8f39-d4e3d37b510a
5
+ * Version: 1.1.0
6
+ * Description: Provides utility functions for identifying and parsing GitSense Chat Tool Blocks, and now for replacing them within markdown.
7
7
  * Language: JavaScript
8
- * Created-at: 2025-04-27T01:29:53.576Z
9
- * Authors: Gemini 2.5 Pro (v1.0.0)
8
+ * Created-at: 2025-09-12T17:23:34.779Z
9
+ * Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Flash (v1.1.0)
10
10
  */
11
11
 
12
12
 
13
+ const { updateCodeBlockByIndex } = require('./CodeBlockUtils/updateCodeBlock');
14
+ const { processCodeBlocks } = require('./CodeBlockUtils/blockProcessor');
15
+
13
16
  /**
14
17
  * Checks if a given code block content represents a GitSense Chat Tool Block.
15
18
  * It verifies if the first non-empty line starts with "# GitSense Chat Tool".
@@ -97,12 +100,68 @@ function parseToolBlock(content) {
97
100
  }
98
101
  }
99
102
 
103
+ /**
104
+ * Formats tool data into a GitSense Chat Tool Block string.
105
+ *
106
+ * @param {object} toolData - The tool data object to format.
107
+ * @returns {string} The formatted GitSense Chat Tool Block string.
108
+ */
100
109
  function formatToolBlock(toolData) {
101
110
  return `# GitSense Chat Tool\n\n${JSON.stringify(toolData, null, 2)}`;
102
111
  }
103
112
 
113
+ /**
114
+ * Replaces a specific GitSense Chat Tool Block within a markdown string with updated tool data.
115
+ * This function leverages CodeBlockUtils for robust parsing and updating.
116
+ *
117
+ * @param {string} markdownContent - The original markdown string containing code blocks.
118
+ * @param {string} toolName - The 'tool' property value of the target GitSense Chat Tool Block to replace.
119
+ * @param {Object} newToolData - The new tool data object to insert into the block.
120
+ * @returns {string} The markdown content with the specified tool block updated.
121
+ * @throws {Error} If the target tool block is not found or if CodeBlockUtils encounters an error.
122
+ */
123
+ function replaceToolBlock(markdownContent, toolName, newToolData) {
124
+ if (typeof markdownContent !== 'string' || !toolName || !newToolData) {
125
+ throw new Error("Missing required parameters for replaceToolBlock.");
126
+ }
127
+
128
+ // 1. Process the markdown content to find all code blocks
129
+ const { blocks, warnings } = processCodeBlocks(markdownContent, { silent: true });
130
+
131
+ let targetBlockIndex = -1;
132
+
133
+ // 2. Iterate through the processed blocks to find the target GitSense Chat Tool Block
134
+ for (let i = 0; i < blocks.length; i++) {
135
+ const block = blocks[i];
136
+ if (block.type === 'gs-tool' && block.toolData && block.toolData.tool === toolName) {
137
+ targetBlockIndex = i;
138
+ break; // Found the first matching tool block
139
+ }
140
+ }
141
+
142
+ if (targetBlockIndex === -1) {
143
+ console.warn(`replaceToolBlock: No GitSense Chat Tool Block with name "${toolName}" found to replace.`);
144
+ return markdownContent; // Return original content if no replacement occurred
145
+ }
146
+
147
+ // 3. Format the new tool data into the content that goes *inside* the fences
148
+ const newContentBetweenFences = formatToolBlock(newToolData);
149
+
150
+ // 4. Use CodeBlockUtils.updateCodeBlockByIndex to perform the replacement
151
+ // The language for GitSense Tool Blocks is always 'txt'
152
+ const updatedMarkdown = updateCodeBlockByIndex(
153
+ markdownContent,
154
+ targetBlockIndex,
155
+ newContentBetweenFences,
156
+ 'txt'
157
+ );
158
+
159
+ return updatedMarkdown;
160
+ }
161
+
104
162
  module.exports = {
105
163
  isToolBlock,
106
164
  parseToolBlock,
107
- formatToolBlock
165
+ formatToolBlock,
166
+ replaceToolBlock,
108
167
  }