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