@gitsense/gsc-utils 0.2.7 → 0.2.9
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/dist/gsc-utils.cjs.js +316 -67
- package/dist/gsc-utils.esm.js +316 -67
- package/package.json +1 -1
- package/src/AnalyzerUtils/defaultPromptLoader.js +75 -0
- package/src/AnalyzerUtils/index.js +5 -2
- package/src/ContextUtils.js +163 -5
- package/src/GitSenseChatUtils.js +18 -4
package/dist/gsc-utils.esm.js
CHANGED
|
@@ -16,8 +16,8 @@ function getDefaultExportFromCjs (x) {
|
|
|
16
16
|
* Authors: Claude 3.7 Sonnet (v1.0.0), Gemini 2.5 Pro (v1.1.0), Gemini 2.5 Flash Thinking (v1.2.0)
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
const fs$
|
|
20
|
-
const path$
|
|
19
|
+
const fs$8 = require$$0;
|
|
20
|
+
const path$6 = require$$1;
|
|
21
21
|
const ANALYZE_MESSAGE_REGEXP = /^# Analyze - `([^`]+)`\n/;
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -51,12 +51,12 @@ function unescapeCodeBlocks(content) {
|
|
|
51
51
|
* @returns {Array} An array of message objects with role and content properties
|
|
52
52
|
*/
|
|
53
53
|
function getChatTemplateMessages$1(dirname, messageType) {
|
|
54
|
-
const messagesDir = path$
|
|
54
|
+
const messagesDir = path$6.join(dirname, messageType);
|
|
55
55
|
const messages = [];
|
|
56
56
|
|
|
57
57
|
try {
|
|
58
58
|
// Read all files in the directory
|
|
59
|
-
const files = fs$
|
|
59
|
+
const files = fs$8.readdirSync(messagesDir);
|
|
60
60
|
|
|
61
61
|
// Sort files numerically (1.md, 2.md, etc.)
|
|
62
62
|
const sortedFiles = files.sort((a, b) => {
|
|
@@ -67,9 +67,9 @@ function getChatTemplateMessages$1(dirname, messageType) {
|
|
|
67
67
|
|
|
68
68
|
// Process each file
|
|
69
69
|
for (const file of sortedFiles) {
|
|
70
|
-
if (path$
|
|
71
|
-
const filePath = path$
|
|
72
|
-
const fileContent = fs$
|
|
70
|
+
if (path$6.extname(file) === '.md') {
|
|
71
|
+
const filePath = path$6.join(messagesDir, file);
|
|
72
|
+
const fileContent = fs$8.readFileSync(filePath, 'utf8');
|
|
73
73
|
|
|
74
74
|
// Split by triple newline to separate metadata from content
|
|
75
75
|
const parts = fileContent.split('\n\n\n');
|
|
@@ -10453,26 +10453,108 @@ var CodeBlockUtils$4 = {
|
|
|
10453
10453
|
removeLineNumbers: removeLineNumbers$1,
|
|
10454
10454
|
};
|
|
10455
10455
|
|
|
10456
|
-
|
|
10456
|
+
/*
|
|
10457
10457
|
* Component: ContextUtils
|
|
10458
10458
|
* Block-UUID: c199efe3-003c-4226-af3c-d460392a6569
|
|
10459
10459
|
* Parent-UUID: N/A
|
|
10460
|
-
* Version: 1.
|
|
10461
|
-
* Description: Provides utility functions for parsing context message sections to extract file details and code blocks.
|
|
10460
|
+
* Version: 1.1.0
|
|
10461
|
+
* Description: Provides utility functions for parsing context message sections to extract file details and code blocks, and for formatting content for LLM context.
|
|
10462
10462
|
* Language: JavaScript
|
|
10463
10463
|
* Created-at: 2025-05-09T01:36:20.107Z
|
|
10464
|
-
* Authors: Gemini 2.5 Flash Thinking (v1.0.0)
|
|
10464
|
+
* Authors: Gemini 2.5 Flash Thinking (v1.0.0), Gemini 2.5 Flash (v1.1.0)
|
|
10465
10465
|
*/
|
|
10466
10466
|
|
|
10467
10467
|
const CodeBlockUtils$3 = CodeBlockUtils$4;
|
|
10468
10468
|
const MessageUtils$2 = MessageUtils$3;
|
|
10469
10469
|
|
|
10470
|
+
/**
|
|
10471
|
+
* Formats bytes into human-readable string (KB, MB, GB)
|
|
10472
|
+
* @param {number} bytes - Number of bytes
|
|
10473
|
+
* @returns {string} Formatted size string
|
|
10474
|
+
*/
|
|
10475
|
+
function _formatBytes(bytes) {
|
|
10476
|
+
if (typeof bytes !== 'number' || isNaN(bytes)) return '0 bytes';
|
|
10477
|
+
if (bytes === 0) return '0 bytes';
|
|
10478
|
+
|
|
10479
|
+
const k = 1024;
|
|
10480
|
+
const sizes = ['bytes', 'KB', 'MB', 'GB'];
|
|
10481
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
10482
|
+
|
|
10483
|
+
// Special case for bytes (no decimal)
|
|
10484
|
+
if (i === 0) return `${bytes} ${sizes[i]}`;
|
|
10485
|
+
|
|
10486
|
+
const value = bytes / Math.pow(k, i);
|
|
10487
|
+
// Show no decimal if whole number
|
|
10488
|
+
const decimalPlaces = value % 1 === 0 ? 0 : 1;
|
|
10489
|
+
return `${value.toFixed(decimalPlaces)} ${sizes[i]}`;
|
|
10490
|
+
}
|
|
10491
|
+
|
|
10492
|
+
/**
|
|
10493
|
+
* Creates a summary of items for human readers
|
|
10494
|
+
* @param {Array} items - Array of loaded items
|
|
10495
|
+
* @param {string} contentType - Content type
|
|
10496
|
+
* @returns {string} Human-readable summary
|
|
10497
|
+
*/
|
|
10498
|
+
function _createContextSummary(items, contentType) {
|
|
10499
|
+
if (items.length === 0) return '';
|
|
10500
|
+
|
|
10501
|
+
// Group by files and trees
|
|
10502
|
+
const files = items.filter(item => item.metadata?.type === 'git-blob');
|
|
10503
|
+
const trees = items.filter(item => item.metadata?.type === 'git-tree' || item.metadata?.type === 'git-ref');
|
|
10504
|
+
|
|
10505
|
+
// Calculate total size and tokens
|
|
10506
|
+
const totalSize = items.reduce((sum, item) => sum + (item.size || 0), 0);
|
|
10507
|
+
const totalTokens = items.reduce((sum, item) => sum + (item.tokenCount || 0), 0);
|
|
10508
|
+
|
|
10509
|
+
let summary = contentType === 'file content'
|
|
10510
|
+
? `\n**Summary:** ${items.length} file${items.length === 1 ? '' : 's'} (${_formatBytes(totalSize)}, ${totalTokens.toLocaleString()} tokens)\n\n`
|
|
10511
|
+
: `\n**Summary:** ${files.length} file${files.length === 1 ? '' : 's'} - ${trees.length} tree${trees.length === 1 ? '' : 's'}\n\n`;
|
|
10512
|
+
|
|
10513
|
+
// Add brief description of first X files
|
|
10514
|
+
const maxFiles = 10;
|
|
10515
|
+
const displayItems = items.slice(0, maxFiles);
|
|
10516
|
+
if (displayItems.length > 0) {
|
|
10517
|
+
displayItems.forEach(item => {
|
|
10518
|
+
if (item.tokenCount) {
|
|
10519
|
+
summary += `- ${item.name} - ${_formatBytes(item.size)}, ${item.tokenCount.toLocaleString()} tokens\n`;
|
|
10520
|
+
} else {
|
|
10521
|
+
summary += `- ${item.name} - Not analyzed\n`;
|
|
10522
|
+
}
|
|
10523
|
+
});
|
|
10524
|
+
|
|
10525
|
+
// Add note if there are more files
|
|
10526
|
+
if (items.length > maxFiles) {
|
|
10527
|
+
summary += `- ... and ${items.length - maxFiles} more\n`;
|
|
10528
|
+
}
|
|
10529
|
+
}
|
|
10530
|
+
|
|
10531
|
+
return summary + "\n";
|
|
10532
|
+
}
|
|
10533
|
+
|
|
10534
|
+
/**
|
|
10535
|
+
* Escapes backticks in code blocks to prevent premature termination of LLM-generated code blocks.
|
|
10536
|
+
* @param {string} content - The content string to escape.
|
|
10537
|
+
* @returns {{escapedContent: string, escapedLineNums: Array<number>}} Object with escaped content and line numbers of escaped lines.
|
|
10538
|
+
*/
|
|
10539
|
+
function _escapeCodeBlocks(content) {
|
|
10540
|
+
const escapedLineNums = [];
|
|
10541
|
+
const escapedLines = content.replace(/\n$/, '').split('\n').map((line, i) => {
|
|
10542
|
+
if (line.trimStart().startsWith('```')) {
|
|
10543
|
+
line = '\\' + line.trimStart();
|
|
10544
|
+
escapedLineNums.push(i + 1);
|
|
10545
|
+
}
|
|
10546
|
+
return line;
|
|
10547
|
+
});
|
|
10548
|
+
return { escapedContent: escapedLines.join('\n'), escapedLineNums };
|
|
10549
|
+
}
|
|
10550
|
+
|
|
10551
|
+
|
|
10470
10552
|
/**
|
|
10471
10553
|
* Parses context details from a context message section.
|
|
10472
10554
|
* @param {string} sectionText - The text content of a single context section (starting from the file header).
|
|
10473
10555
|
* @returns {Object|null} An object with file details (name, path, meta, content) or null if parsing fails.
|
|
10474
10556
|
*/
|
|
10475
|
-
function parseContextSection(sectionText) {
|
|
10557
|
+
function parseContextSection$1(sectionText) {
|
|
10476
10558
|
const contextSection = {
|
|
10477
10559
|
name: 'Unknown File',
|
|
10478
10560
|
content: null,
|
|
@@ -10548,7 +10630,7 @@ function parseContextSection(sectionText) {
|
|
|
10548
10630
|
* @returns {Array<Object>} An array of parsed context section objects.
|
|
10549
10631
|
* @throws {Error} If the message content is not a valid context message.
|
|
10550
10632
|
*/
|
|
10551
|
-
function extractContextSections(messageContent) {
|
|
10633
|
+
function extractContextSections$1(messageContent) {
|
|
10552
10634
|
// Use the utility function to validate the message type
|
|
10553
10635
|
if (!MessageUtils$2.isContextMessage(messageContent)) {
|
|
10554
10636
|
throw new Error("Invalid message type: Content is not a context message.");
|
|
@@ -10562,7 +10644,7 @@ function extractContextSections(messageContent) {
|
|
|
10562
10644
|
|
|
10563
10645
|
// Process sections starting from the first potential path delimiter.
|
|
10564
10646
|
for (let i = 0; i < sections.length; i++) {
|
|
10565
|
-
const contextSection = parseContextSection(sections[i]);
|
|
10647
|
+
const contextSection = parseContextSection$1(sections[i]);
|
|
10566
10648
|
|
|
10567
10649
|
if (contextSection) {
|
|
10568
10650
|
contextSections.push(contextSection);
|
|
@@ -10577,7 +10659,7 @@ function extractContextSections(messageContent) {
|
|
|
10577
10659
|
return contextSections;
|
|
10578
10660
|
}
|
|
10579
10661
|
|
|
10580
|
-
function extractContextItemsOverviewTableRows(messageContent) {
|
|
10662
|
+
function extractContextItemsOverviewTableRows$1(messageContent) {
|
|
10581
10663
|
const lines = messageContent.trim().split('\n');
|
|
10582
10664
|
const startIndex = lines.findIndex(line => line.startsWith('---Start of Overview Items---')) + 4;
|
|
10583
10665
|
|
|
@@ -10627,10 +10709,85 @@ function extractContextItemsOverviewTableRows(messageContent) {
|
|
|
10627
10709
|
return rows;
|
|
10628
10710
|
}
|
|
10629
10711
|
|
|
10712
|
+
/**
|
|
10713
|
+
* Formats content for context based on content type.
|
|
10714
|
+
* This function is adapted from the original `formatContentForContext` in `formatterUtils.js`.
|
|
10715
|
+
*
|
|
10716
|
+
* @param {Array<Object>} items - Array of loaded items, each with `chatId`, `name`, `content`, `meta`, `repo` (from chatsApi.getBlobDetailsByChatIds).
|
|
10717
|
+
* @param {string} contentType - Type of content ('file content' or 'overview'). For batch analysis, always 'file content'.
|
|
10718
|
+
* @param {string} contentOption - Option for the content type. For batch analysis, always 'imported'.
|
|
10719
|
+
* @returns {string} Formatted text for context.
|
|
10720
|
+
*/
|
|
10721
|
+
function formatContextContent$1(items, contentType, contentOption) {
|
|
10722
|
+
if (items.length === 0) {
|
|
10723
|
+
return 'No content loaded';
|
|
10724
|
+
}
|
|
10725
|
+
|
|
10726
|
+
let result = '';
|
|
10727
|
+
|
|
10728
|
+
// Header based on content type
|
|
10729
|
+
if (contentType === 'overview') {
|
|
10730
|
+
result += `## OVERVIEW - ${contentOption.toUpperCase()}\n`;
|
|
10731
|
+
} else {
|
|
10732
|
+
result += `## FILE CONTENT - ${contentOption.toUpperCase()}\n`;
|
|
10733
|
+
}
|
|
10734
|
+
|
|
10735
|
+
// Summary of items
|
|
10736
|
+
result += _createContextSummary(items, contentType);
|
|
10737
|
+
result += "\n---Start of Context---\n\n";
|
|
10738
|
+
|
|
10739
|
+
items.forEach((item, index) => {
|
|
10740
|
+
// Ensure item has necessary properties, especially meta and repo
|
|
10741
|
+
const itemMeta = item.meta || {};
|
|
10742
|
+
const itemRepo = item.repo || {};
|
|
10743
|
+
|
|
10744
|
+
result += "#### `"+item.name+"`\n";
|
|
10745
|
+
|
|
10746
|
+
const { escapedContent, escapedLineNums } = _escapeCodeBlocks(item.content);
|
|
10747
|
+
|
|
10748
|
+
// Always include metadata for batch analysis context
|
|
10749
|
+
result +=
|
|
10750
|
+
`- Repo: ${itemRepo.fullName || 'N/A'}\n`+
|
|
10751
|
+
`- Path: ${itemMeta.path || 'N/A'}\n`;
|
|
10752
|
+
|
|
10753
|
+
// Size and Tokens are specific to 'file content'
|
|
10754
|
+
if (contentType === 'file content') {
|
|
10755
|
+
result += `- Size: ${_formatBytes(itemMeta.size)}\n`;
|
|
10756
|
+
result += `- Tokens: ${itemMeta.tokens?.content?.estimate || 'N/A'}\n`;
|
|
10757
|
+
} else {
|
|
10758
|
+
const type = itemMeta.type || 'unknown';
|
|
10759
|
+
result += `- Type: ${type === 'git-blob' ? 'file' : type === 'git-tree' || type === 'git-ref' ? 'directory' : type }\n`;
|
|
10760
|
+
result += `- Tokens: ${itemMeta.tokens?.analysis?.[contentOption.toLowerCase()]?.estimate || 'N/A'}\n`;
|
|
10761
|
+
}
|
|
10762
|
+
|
|
10763
|
+
result += `- Chat ID: ${item.chatId}\n`;
|
|
10764
|
+
|
|
10765
|
+
if (escapedLineNums.length) {
|
|
10766
|
+
result += `- Escaped Lines: ${escapedLineNums.join(',')}\n`;
|
|
10767
|
+
}
|
|
10768
|
+
|
|
10769
|
+
result += '\n';
|
|
10770
|
+
|
|
10771
|
+
// The original formatterUtils had a special summary handling.
|
|
10772
|
+
// For batch analysis, we want the full file content.
|
|
10773
|
+
// The `if (!escapedContent.includes('Component: New Analyzer Chat') && escapedContent.match(summary))`
|
|
10774
|
+
// logic is specific to the frontend's overview builder and should not be applied here.
|
|
10775
|
+
result += "```"+(itemMeta.highlight || '')+"\n"+escapedContent+"\n```";
|
|
10776
|
+
|
|
10777
|
+
if (index !== items.length - 1) {
|
|
10778
|
+
result += '\n---End of Item---\n';
|
|
10779
|
+
}
|
|
10780
|
+
});
|
|
10781
|
+
|
|
10782
|
+
return result;
|
|
10783
|
+
}
|
|
10784
|
+
|
|
10785
|
+
|
|
10630
10786
|
var ContextUtils$2 = {
|
|
10631
|
-
parseContextSection,
|
|
10632
|
-
extractContextSections,
|
|
10633
|
-
extractContextItemsOverviewTableRows
|
|
10787
|
+
parseContextSection: parseContextSection$1,
|
|
10788
|
+
extractContextSections: extractContextSections$1,
|
|
10789
|
+
extractContextItemsOverviewTableRows: extractContextItemsOverviewTableRows$1,
|
|
10790
|
+
formatContextContent: formatContextContent$1, // Export the new method
|
|
10634
10791
|
};
|
|
10635
10792
|
|
|
10636
10793
|
/*
|
|
@@ -10923,8 +11080,8 @@ var dataValidator = {
|
|
|
10923
11080
|
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10924
11081
|
*/
|
|
10925
11082
|
|
|
10926
|
-
const fs$
|
|
10927
|
-
const path$
|
|
11083
|
+
const fs$7 = require$$0.promises;
|
|
11084
|
+
const path$5 = require$$1;
|
|
10928
11085
|
|
|
10929
11086
|
/**
|
|
10930
11087
|
* Reads and parses the config.json file in a directory.
|
|
@@ -10933,9 +11090,9 @@ const path$4 = require$$1;
|
|
|
10933
11090
|
* or null if the file doesn't exist or is invalid.
|
|
10934
11091
|
*/
|
|
10935
11092
|
async function readConfig$1(dirPath) {
|
|
10936
|
-
const configPath = path$
|
|
11093
|
+
const configPath = path$5.join(dirPath, 'config.json');
|
|
10937
11094
|
try {
|
|
10938
|
-
const fileContent = await fs$
|
|
11095
|
+
const fileContent = await fs$7.readFile(configPath, 'utf8');
|
|
10939
11096
|
return JSON.parse(fileContent);
|
|
10940
11097
|
} catch (error) {
|
|
10941
11098
|
if (error.code !== 'ENOENT') {
|
|
@@ -10972,41 +11129,41 @@ async function getAnalyzers$2(analyzeMessagesBasePath) {
|
|
|
10972
11129
|
const analyzers = [];
|
|
10973
11130
|
|
|
10974
11131
|
try {
|
|
10975
|
-
const analyzerEntries = await fs$
|
|
11132
|
+
const analyzerEntries = await fs$7.readdir(analyzeMessagesBasePath, { withFileTypes: true });
|
|
10976
11133
|
|
|
10977
11134
|
for (const analyzerEntry of analyzerEntries) {
|
|
10978
11135
|
if (analyzerEntry.isDirectory() && isValidDirName(analyzerEntry.name)) {
|
|
10979
11136
|
const analyzerName = analyzerEntry.name;
|
|
10980
|
-
const analyzerPath = path$
|
|
11137
|
+
const analyzerPath = path$5.join(analyzeMessagesBasePath, analyzerName);
|
|
10981
11138
|
const analyzerConfig = await readConfig$1(analyzerPath);
|
|
10982
11139
|
const analyzerLabel = analyzerConfig?.label || analyzerName;
|
|
10983
11140
|
|
|
10984
|
-
const contentEntries = await fs$
|
|
11141
|
+
const contentEntries = await fs$7.readdir(analyzerPath, { withFileTypes: true });
|
|
10985
11142
|
|
|
10986
11143
|
for (const contentEntry of contentEntries) {
|
|
10987
11144
|
if (contentEntry.isDirectory() && isValidDirName(contentEntry.name)) {
|
|
10988
11145
|
const contentType = contentEntry.name;
|
|
10989
|
-
const contentPath = path$
|
|
11146
|
+
const contentPath = path$5.join(analyzerPath, contentType);
|
|
10990
11147
|
const contentConfig = await readConfig$1(contentPath);
|
|
10991
11148
|
const contentLabel = contentConfig?.label || contentType;
|
|
10992
11149
|
|
|
10993
|
-
const instructionsEntries = await fs$
|
|
11150
|
+
const instructionsEntries = await fs$7.readdir(contentPath, { withFileTypes: true });
|
|
10994
11151
|
|
|
10995
11152
|
for (const instructionsEntry of instructionsEntries) {
|
|
10996
11153
|
if (instructionsEntry.isDirectory() && isValidDirName(instructionsEntry.name)) {
|
|
10997
11154
|
const instructionsType = instructionsEntry.name;
|
|
10998
|
-
const instructionsPath = path$
|
|
11155
|
+
const instructionsPath = path$5.join(contentPath, instructionsType);
|
|
10999
11156
|
const instructionsConfig = await readConfig$1(instructionsPath);
|
|
11000
11157
|
const instructionsLabel = instructionsConfig?.label || instructionsType;
|
|
11001
11158
|
|
|
11002
11159
|
// Check for the existence of 1.md to confirm a valid analyzer configuration
|
|
11003
|
-
const instructionsFilePath = path$
|
|
11160
|
+
const instructionsFilePath = path$5.join(instructionsPath, '1.md');
|
|
11004
11161
|
try {
|
|
11005
|
-
await fs$
|
|
11162
|
+
await fs$7.access(instructionsFilePath); // Check if file exists and is accessible
|
|
11006
11163
|
|
|
11007
11164
|
// If analyzerName starts with 'tutorial-', check its last modified time.
|
|
11008
11165
|
if (analyzerName.startsWith('tutorial-')) {
|
|
11009
|
-
const stats = await fs$
|
|
11166
|
+
const stats = await fs$7.stat(instructionsFilePath);
|
|
11010
11167
|
const lastModified = stats.mtime.getTime(); // Get timestamp in milliseconds
|
|
11011
11168
|
const sixtyMinutesAgo = Date.now() - (60 * 60 * 1000); // Current time - 60 minutes in ms
|
|
11012
11169
|
|
|
@@ -11060,8 +11217,8 @@ var discovery = {
|
|
|
11060
11217
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0), Gemini 2.5 Flash Thinking (v1.1.0)
|
|
11061
11218
|
*/
|
|
11062
11219
|
|
|
11063
|
-
const fs$
|
|
11064
|
-
const path$
|
|
11220
|
+
const fs$6 = require$$0.promises;
|
|
11221
|
+
const path$4 = require$$1;
|
|
11065
11222
|
|
|
11066
11223
|
/**
|
|
11067
11224
|
* Saves or updates an analyzer configuration.
|
|
@@ -11116,18 +11273,18 @@ async function saveConfiguration$1(analyzeMessagesBasePath, analyzerId, instruct
|
|
|
11116
11273
|
}
|
|
11117
11274
|
|
|
11118
11275
|
// 3. Construct directory paths
|
|
11119
|
-
const analyzerDir = path$
|
|
11120
|
-
const contentDir = path$
|
|
11121
|
-
const instructionsDir = path$
|
|
11122
|
-
const instructionsFilePath = path$
|
|
11276
|
+
const analyzerDir = path$4.join(analyzeMessagesBasePath, analyzerName);
|
|
11277
|
+
const contentDir = path$4.join(analyzerDir, contentType);
|
|
11278
|
+
const instructionsDir = path$4.join(contentDir, instructionsType);
|
|
11279
|
+
const instructionsFilePath = path$4.join(instructionsDir, '1.md');
|
|
11123
11280
|
|
|
11124
11281
|
try {
|
|
11125
11282
|
// 4. Create directories recursively
|
|
11126
|
-
await fs$
|
|
11283
|
+
await fs$6.mkdir(instructionsDir, { recursive: true });
|
|
11127
11284
|
|
|
11128
11285
|
// 5. Save instructions content to 1.md
|
|
11129
11286
|
const finalContent = `; role: assistant\n\n\n${instructionsContent}`;
|
|
11130
|
-
await fs$
|
|
11287
|
+
await fs$6.writeFile(instructionsFilePath, finalContent, 'utf8');
|
|
11131
11288
|
|
|
11132
11289
|
// 6. Optionally create/Update config.json files
|
|
11133
11290
|
if (ensureConfigs) {
|
|
@@ -11153,11 +11310,11 @@ async function saveConfiguration$1(analyzeMessagesBasePath, analyzerId, instruct
|
|
|
11153
11310
|
* @param {string} label - The label to ensure is in the config.json.
|
|
11154
11311
|
*/
|
|
11155
11312
|
async function ensureConfigJson(dirPath, label) {
|
|
11156
|
-
const configPath = path$
|
|
11313
|
+
const configPath = path$4.join(dirPath, 'config.json');
|
|
11157
11314
|
let config = {};
|
|
11158
11315
|
|
|
11159
11316
|
try {
|
|
11160
|
-
const fileContent = await fs$
|
|
11317
|
+
const fileContent = await fs$6.readFile(configPath, 'utf8');
|
|
11161
11318
|
config = JSON.parse(fileContent);
|
|
11162
11319
|
} catch (error) {
|
|
11163
11320
|
// If file doesn't exist or parsing fails, start with an empty config
|
|
@@ -11174,7 +11331,7 @@ async function ensureConfigJson(dirPath, label) {
|
|
|
11174
11331
|
}
|
|
11175
11332
|
|
|
11176
11333
|
// Write the updated config back to the file
|
|
11177
|
-
await fs$
|
|
11334
|
+
await fs$6.writeFile(configPath, JSON.stringify(config, null, 4), 'utf8');
|
|
11178
11335
|
}
|
|
11179
11336
|
|
|
11180
11337
|
|
|
@@ -11193,8 +11350,8 @@ var saver = {
|
|
|
11193
11350
|
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
11194
11351
|
*/
|
|
11195
11352
|
|
|
11196
|
-
const fs$
|
|
11197
|
-
const path$
|
|
11353
|
+
const fs$5 = require$$0.promises;
|
|
11354
|
+
const path$3 = require$$1;
|
|
11198
11355
|
const CodeBlockUtils$1 = CodeBlockUtils$4;
|
|
11199
11356
|
|
|
11200
11357
|
/**
|
|
@@ -11280,10 +11437,10 @@ async function getAnalyzerSchema$2(analyzeMessagesBasePath, analyzerId) {
|
|
|
11280
11437
|
}
|
|
11281
11438
|
const [analyzerName, contentType, instructionsType] = parts;
|
|
11282
11439
|
|
|
11283
|
-
const instructionsFilePath = path$
|
|
11440
|
+
const instructionsFilePath = path$3.join(analyzeMessagesBasePath, analyzerName, contentType, instructionsType, '1.md');
|
|
11284
11441
|
|
|
11285
11442
|
try {
|
|
11286
|
-
const fileContent = await fs$
|
|
11443
|
+
const fileContent = await fs$5.readFile(instructionsFilePath, 'utf8');
|
|
11287
11444
|
const { blocks } = CodeBlockUtils$1.extractCodeBlocks(fileContent, { silent: true });
|
|
11288
11445
|
const jsonBlocks = blocks.filter(block => block.type === 'code' && block.language === 'json');
|
|
11289
11446
|
|
|
@@ -11354,8 +11511,8 @@ var schemaLoader = {
|
|
|
11354
11511
|
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
11355
11512
|
*/
|
|
11356
11513
|
|
|
11357
|
-
const fs$
|
|
11358
|
-
const path$
|
|
11514
|
+
const fs$4 = require$$0.promises;
|
|
11515
|
+
const path$2 = require$$1;
|
|
11359
11516
|
const { readConfig } = discovery; // Import helper from discovery
|
|
11360
11517
|
|
|
11361
11518
|
/**
|
|
@@ -11365,7 +11522,7 @@ const { readConfig } = discovery; // Import helper from discovery
|
|
|
11365
11522
|
*/
|
|
11366
11523
|
async function isDirectoryEmpty(dirPath) {
|
|
11367
11524
|
try {
|
|
11368
|
-
const files = await fs$
|
|
11525
|
+
const files = await fs$4.readdir(dirPath);
|
|
11369
11526
|
return files.length === 0 || (files.length === 1 && files[0] === 'config.json');
|
|
11370
11527
|
} catch (error) {
|
|
11371
11528
|
if (error.code === 'ENOENT') {
|
|
@@ -11396,10 +11553,10 @@ async function deleteAnalyzer$2(analyzeMessagesBasePath, analyzerId) {
|
|
|
11396
11553
|
}
|
|
11397
11554
|
const [analyzerName, contentType, instructionsType] = parts;
|
|
11398
11555
|
|
|
11399
|
-
const analyzerDir = path$
|
|
11400
|
-
const contentDir = path$
|
|
11401
|
-
const instructionsDir = path$
|
|
11402
|
-
const instructionsFilePath = path$
|
|
11556
|
+
const analyzerDir = path$2.join(analyzeMessagesBasePath, analyzerName);
|
|
11557
|
+
const contentDir = path$2.join(analyzerDir, contentType);
|
|
11558
|
+
const instructionsDir = path$2.join(contentDir, instructionsType);
|
|
11559
|
+
const instructionsFilePath = path$2.join(instructionsDir, '1.md');
|
|
11403
11560
|
|
|
11404
11561
|
try {
|
|
11405
11562
|
// 1. Check for protection at all levels
|
|
@@ -11420,7 +11577,7 @@ async function deleteAnalyzer$2(analyzeMessagesBasePath, analyzerId) {
|
|
|
11420
11577
|
|
|
11421
11578
|
// 2. Delete the 1.md file
|
|
11422
11579
|
try {
|
|
11423
|
-
await fs$
|
|
11580
|
+
await fs$4.unlink(instructionsFilePath);
|
|
11424
11581
|
} catch (error) {
|
|
11425
11582
|
if (error.code === 'ENOENT') {
|
|
11426
11583
|
return { success: false, message: `Analyzer instructions file not found: ${instructionsFilePath}. It may have already been deleted.` };
|
|
@@ -11434,7 +11591,7 @@ async function deleteAnalyzer$2(analyzeMessagesBasePath, analyzerId) {
|
|
|
11434
11591
|
// Check and delete instructions directory
|
|
11435
11592
|
if (await isDirectoryEmpty(instructionsDir)) {
|
|
11436
11593
|
try {
|
|
11437
|
-
await fs$
|
|
11594
|
+
await fs$4.rmdir(instructionsDir);
|
|
11438
11595
|
deletedDirs.push(instructionsDir);
|
|
11439
11596
|
} catch (error) {
|
|
11440
11597
|
console.warn(`Warning: Could not remove empty instructions directory ${instructionsDir}: ${error.message}`);
|
|
@@ -11444,7 +11601,7 @@ async function deleteAnalyzer$2(analyzeMessagesBasePath, analyzerId) {
|
|
|
11444
11601
|
// Check and delete content directory
|
|
11445
11602
|
if (await isDirectoryEmpty(contentDir)) {
|
|
11446
11603
|
try {
|
|
11447
|
-
await fs$
|
|
11604
|
+
await fs$4.rmdir(contentDir);
|
|
11448
11605
|
deletedDirs.push(contentDir);
|
|
11449
11606
|
} catch (error) {
|
|
11450
11607
|
console.warn(`Warning: Could not remove empty content directory ${contentDir}: ${error.message}`);
|
|
@@ -11454,7 +11611,7 @@ async function deleteAnalyzer$2(analyzeMessagesBasePath, analyzerId) {
|
|
|
11454
11611
|
// Check and delete analyzer directory
|
|
11455
11612
|
if (await isDirectoryEmpty(analyzerDir)) {
|
|
11456
11613
|
try {
|
|
11457
|
-
await fs$
|
|
11614
|
+
await fs$4.rmdir(analyzerDir);
|
|
11458
11615
|
deletedDirs.push(analyzerDir);
|
|
11459
11616
|
} catch (error) {
|
|
11460
11617
|
console.warn(`Warning: Could not remove empty analyzer directory ${analyzerDir}: ${error.message}`);
|
|
@@ -11483,8 +11640,8 @@ var management = {
|
|
|
11483
11640
|
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
11484
11641
|
*/
|
|
11485
11642
|
|
|
11486
|
-
const fs$
|
|
11487
|
-
const path = require$$1;
|
|
11643
|
+
const fs$3 = require$$0.promises;
|
|
11644
|
+
const path$1 = require$$1;
|
|
11488
11645
|
|
|
11489
11646
|
/**
|
|
11490
11647
|
* Retrieves the raw Markdown content of the analyzer's '1.md' instruction file.
|
|
@@ -11510,10 +11667,10 @@ async function getAnalyzerInstructionsContent$2(analyzeMessagesBasePath, analyze
|
|
|
11510
11667
|
}
|
|
11511
11668
|
const [analyzerName, contentType, instructionsType] = parts;
|
|
11512
11669
|
|
|
11513
|
-
const instructionsFilePath = path.join(analyzeMessagesBasePath, analyzerName, contentType, instructionsType, '1.md');
|
|
11670
|
+
const instructionsFilePath = path$1.join(analyzeMessagesBasePath, analyzerName, contentType, instructionsType, '1.md');
|
|
11514
11671
|
|
|
11515
11672
|
try {
|
|
11516
|
-
const fileContent = await fs$
|
|
11673
|
+
const fileContent = await fs$3.readFile(instructionsFilePath, 'utf8');
|
|
11517
11674
|
return fileContent;
|
|
11518
11675
|
} catch (error) {
|
|
11519
11676
|
if (error.code === 'ENOENT') {
|
|
@@ -11530,15 +11687,90 @@ var instructionLoader = {
|
|
|
11530
11687
|
getAnalyzerInstructionsContent: getAnalyzerInstructionsContent$2
|
|
11531
11688
|
};
|
|
11532
11689
|
|
|
11690
|
+
/*
|
|
11691
|
+
* Component: AnalyzerUtils Default Prompt Loader
|
|
11692
|
+
* Block-UUID: 0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5f
|
|
11693
|
+
* Parent-UUID: N/A
|
|
11694
|
+
* Version: 1.0.0
|
|
11695
|
+
* Description: Provides utility functions for loading shared, default prompt components (system and start messages).
|
|
11696
|
+
* Language: JavaScript
|
|
11697
|
+
* Created-at: 2025-08-29T03:30:28.771Z
|
|
11698
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
11699
|
+
*/
|
|
11700
|
+
|
|
11701
|
+
const fs$2 = require$$0.promises;
|
|
11702
|
+
const path = require$$1;
|
|
11703
|
+
|
|
11704
|
+
/**
|
|
11705
|
+
* Retrieves the raw Markdown content of the shared system message ('_shared/system/1.md').
|
|
11706
|
+
*
|
|
11707
|
+
* @param {string} analyzeMessagesBasePath - The absolute path to the base directory containing analyzer message files (e.g., 'messages/analyze').
|
|
11708
|
+
* @returns {Promise<string|null>} A promise that resolves with the full Markdown content, or null if not found/invalid.
|
|
11709
|
+
*/
|
|
11710
|
+
async function getSystemMessageContent$2(analyzeMessagesBasePath) {
|
|
11711
|
+
if (typeof analyzeMessagesBasePath !== 'string' || analyzeMessagesBasePath.trim() === '') {
|
|
11712
|
+
console.error('Error: analyzeMessagesBasePath is required for getSystemMessageContent.');
|
|
11713
|
+
return null;
|
|
11714
|
+
}
|
|
11715
|
+
|
|
11716
|
+
const systemMessageFilePath = path.join(analyzeMessagesBasePath, '_shared', 'system', '1.md');
|
|
11717
|
+
|
|
11718
|
+
try {
|
|
11719
|
+
const fileContent = await fs$2.readFile(systemMessageFilePath, 'utf8');
|
|
11720
|
+
return fileContent;
|
|
11721
|
+
} catch (error) {
|
|
11722
|
+
if (error.code === 'ENOENT') {
|
|
11723
|
+
console.warn(`Default system message file not found: ${systemMessageFilePath}.`);
|
|
11724
|
+
return null;
|
|
11725
|
+
} else {
|
|
11726
|
+
console.error(`Error reading default system message file ${systemMessageFilePath}: ${error.message}`);
|
|
11727
|
+
throw error;
|
|
11728
|
+
}
|
|
11729
|
+
}
|
|
11730
|
+
}
|
|
11731
|
+
|
|
11732
|
+
/**
|
|
11733
|
+
* Retrieves the raw Markdown content of the shared start message ('_shared/start/1.md').
|
|
11734
|
+
*
|
|
11735
|
+
* @param {string} analyzeMessagesBasePath - The absolute path to the base directory containing analyzer message files (e.g., 'messages/analyze').
|
|
11736
|
+
* @returns {Promise<string|null>} A promise that resolves with the full Markdown content, or null if not found/invalid.
|
|
11737
|
+
*/
|
|
11738
|
+
async function getStartMessageContent$2(analyzeMessagesBasePath) {
|
|
11739
|
+
if (typeof analyzeMessagesBasePath !== 'string' || analyzeMessagesBasePath.trim() === '') {
|
|
11740
|
+
console.error('Error: analyzeMessagesBasePath is required for getStartMessageContent.');
|
|
11741
|
+
return null;
|
|
11742
|
+
}
|
|
11743
|
+
|
|
11744
|
+
const startMessageFilePath = path.join(analyzeMessagesBasePath, '_shared', 'start', '1.md');
|
|
11745
|
+
|
|
11746
|
+
try {
|
|
11747
|
+
const fileContent = await fs$2.readFile(startMessageFilePath, 'utf8');
|
|
11748
|
+
return fileContent;
|
|
11749
|
+
} catch (error) {
|
|
11750
|
+
if (error.code === 'ENOENT') {
|
|
11751
|
+
console.warn(`Default start message file not found: ${startMessageFilePath}.`);
|
|
11752
|
+
return null;
|
|
11753
|
+
} else {
|
|
11754
|
+
console.error(`Error reading default start message file ${startMessageFilePath}: ${error.message}`);
|
|
11755
|
+
throw error;
|
|
11756
|
+
}
|
|
11757
|
+
}
|
|
11758
|
+
}
|
|
11759
|
+
|
|
11760
|
+
var defaultPromptLoader = {
|
|
11761
|
+
getSystemMessageContent: getSystemMessageContent$2,
|
|
11762
|
+
getStartMessageContent: getStartMessageContent$2
|
|
11763
|
+
};
|
|
11764
|
+
|
|
11533
11765
|
/*
|
|
11534
11766
|
* Component: AnalyzerUtils Index
|
|
11535
11767
|
* Block-UUID: b403b6a1-230b-4247-8cd6-2a3d068f4bbf
|
|
11536
11768
|
* Parent-UUID: N/A
|
|
11537
|
-
* Version: 1.
|
|
11769
|
+
* Version: 1.2.0
|
|
11538
11770
|
* Description: Aggregates and exports all utility functions from the AnalyzerUtils module.
|
|
11539
11771
|
* Language: JavaScript
|
|
11540
11772
|
* Created-at: 2025-08-28T15:56:40.319Z
|
|
11541
|
-
* Authors: Gemini 2.5 Flash (v1.0.0), Gemini 2.5 Flash (v1.1.0)
|
|
11773
|
+
* Authors: Gemini 2.5 Flash (v1.0.0), Gemini 2.5 Flash (v1.1.0), Gemini 2.5 Flash (v1.2.0)
|
|
11542
11774
|
*/
|
|
11543
11775
|
|
|
11544
11776
|
const { buildChatIdToPathMap: buildChatIdToPathMap$1 } = contextMapper;
|
|
@@ -11549,6 +11781,7 @@ const { saveConfiguration } = saver;
|
|
|
11549
11781
|
const { getAnalyzerSchema: getAnalyzerSchema$1 } = schemaLoader;
|
|
11550
11782
|
const { deleteAnalyzer: deleteAnalyzer$1 } = management;
|
|
11551
11783
|
const { getAnalyzerInstructionsContent: getAnalyzerInstructionsContent$1 } = instructionLoader;
|
|
11784
|
+
const { getSystemMessageContent: getSystemMessageContent$1, getStartMessageContent: getStartMessageContent$1 } = defaultPromptLoader; // NEW: Import default prompt loaders
|
|
11552
11785
|
|
|
11553
11786
|
var AnalyzerUtils$1 = {
|
|
11554
11787
|
buildChatIdToPathMap: buildChatIdToPathMap$1,
|
|
@@ -11559,6 +11792,8 @@ var AnalyzerUtils$1 = {
|
|
|
11559
11792
|
deleteAnalyzer: deleteAnalyzer$1,
|
|
11560
11793
|
getAnalyzerInstructionsContent: getAnalyzerInstructionsContent$1,
|
|
11561
11794
|
saveConfiguration,
|
|
11795
|
+
getSystemMessageContent: getSystemMessageContent$1,
|
|
11796
|
+
getStartMessageContent: getStartMessageContent$1
|
|
11562
11797
|
};
|
|
11563
11798
|
|
|
11564
11799
|
/**
|
|
@@ -11769,11 +12004,11 @@ var EnvUtils$1 = {
|
|
|
11769
12004
|
* Component: GitSenseChatUtils
|
|
11770
12005
|
* Block-UUID: 5e8d1a9c-0b3f-4e1a-8c7d-9f0b2e1d3a4b
|
|
11771
12006
|
* Parent-UUID: 7a9b1c8e-f1a4-4b2d-9e8f-6f7a0b1c2d3f
|
|
11772
|
-
* Version: 2.1.
|
|
12007
|
+
* Version: 2.1.4
|
|
11773
12008
|
* 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.
|
|
11774
12009
|
* Language: JavaScript
|
|
11775
12010
|
* Created-at: 2025-04-15T16:04:26.780Z
|
|
11776
|
-
* 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)
|
|
12011
|
+
* 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)
|
|
11777
12012
|
*/
|
|
11778
12013
|
|
|
11779
12014
|
const ChatUtils = ChatUtils$1;
|
|
@@ -11829,6 +12064,8 @@ const {
|
|
|
11829
12064
|
getAnalyzerSchema,
|
|
11830
12065
|
deleteAnalyzer,
|
|
11831
12066
|
getAnalyzerInstructionsContent,
|
|
12067
|
+
getSystemMessageContent,
|
|
12068
|
+
getStartMessageContent,
|
|
11832
12069
|
saveAnalyzerConfiguration,
|
|
11833
12070
|
} = AnalyzerUtils;
|
|
11834
12071
|
|
|
@@ -11888,6 +12125,13 @@ const {
|
|
|
11888
12125
|
getApiKey
|
|
11889
12126
|
} = EnvUtils;
|
|
11890
12127
|
|
|
12128
|
+
const {
|
|
12129
|
+
parseContextSection,
|
|
12130
|
+
extractContextSections,
|
|
12131
|
+
extractContextItemsOverviewTableRows,
|
|
12132
|
+
formatContextContent,
|
|
12133
|
+
} = ContextUtils;
|
|
12134
|
+
|
|
11891
12135
|
|
|
11892
12136
|
/**
|
|
11893
12137
|
* GitSenseChatUtils class provides a unified interface to code block and patch utilities.
|
|
@@ -12164,6 +12408,8 @@ var GitSenseChatUtils_1 = {
|
|
|
12164
12408
|
getAnalyzerSchema,
|
|
12165
12409
|
deleteAnalyzer,
|
|
12166
12410
|
getAnalyzerInstructionsContent,
|
|
12411
|
+
getSystemMessageContent,
|
|
12412
|
+
getStartMessageContent,
|
|
12167
12413
|
|
|
12168
12414
|
// ChatUtils
|
|
12169
12415
|
getChatMessages,
|
|
@@ -12196,8 +12442,11 @@ var GitSenseChatUtils_1 = {
|
|
|
12196
12442
|
loadEnv,
|
|
12197
12443
|
getApiKey,
|
|
12198
12444
|
|
|
12199
|
-
//
|
|
12200
|
-
|
|
12445
|
+
// Context Utils
|
|
12446
|
+
parseContextSection,
|
|
12447
|
+
extractContextSections,
|
|
12448
|
+
extractContextItemsOverviewTableRows,
|
|
12449
|
+
formatContextContent,
|
|
12201
12450
|
};
|
|
12202
12451
|
|
|
12203
12452
|
var GitSenseChatUtils$1 = /*@__PURE__*/getDefaultExportFromCjs(GitSenseChatUtils_1);
|