@link-assistant/hive-mind 0.43.0 → 0.45.0
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/CHANGELOG.md +38 -0
- package/package.json +1 -1
- package/src/claude.budget-stats.lib.mjs +50 -0
- package/src/claude.lib.mjs +5 -0
- package/src/hive.config.lib.mjs +5 -0
- package/src/solve.config.lib.mjs +5 -0
- package/src/telegram-bot.mjs +17 -7
- package/src/version-info.lib.mjs +319 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 0.45.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 81f8da0: Add `--tokens-budget-stats` option for detailed token usage analysis. This experimental feature shows context window usage and output token usage in absolute values and ratios when using `--tool claude`. Disabled by default.
|
|
8
|
+
|
|
9
|
+
## 0.44.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- b72136f: Add /version command to hive-telegram-bot
|
|
14
|
+
|
|
15
|
+
Implements a new /version command that displays comprehensive version information including:
|
|
16
|
+
|
|
17
|
+
- Bot version (package version with git commit SHA in development)
|
|
18
|
+
- solve and hive command versions
|
|
19
|
+
- Node.js runtime version
|
|
20
|
+
- Platform information (OS and architecture)
|
|
21
|
+
|
|
22
|
+
This helps users and administrators quickly check version information without accessing logs or the server directly.
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- 445091b: Fix Perl version detection in ubuntu-24-server-install.sh
|
|
27
|
+
|
|
28
|
+
The `perlbrew available` command output was not being parsed correctly, causing the installation script to skip Perl installation with the message "Could not determine latest Perl version."
|
|
29
|
+
|
|
30
|
+
**Changes:**
|
|
31
|
+
|
|
32
|
+
- Use `grep -oE` to robustly extract Perl version strings regardless of line formatting
|
|
33
|
+
- Capture stderr from `perlbrew available` for better debugging
|
|
34
|
+
- Add debug output showing `perlbrew available` response when version detection fails
|
|
35
|
+
- Works with 'i' markers for already-installed versions and variable indentation
|
|
36
|
+
|
|
37
|
+
This ensures the latest Perl version is properly detected and installed via perlbrew.
|
|
38
|
+
|
|
39
|
+
Fixes #948
|
|
40
|
+
|
|
3
41
|
## 0.43.0
|
|
4
42
|
|
|
5
43
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Token budget statistics display module
|
|
3
|
+
// Extracted from claude.lib.mjs to maintain file line limits
|
|
4
|
+
|
|
5
|
+
import { formatNumber } from './claude.lib.mjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Display token budget statistics (context window usage and ratios)
|
|
9
|
+
* @param {Object} usage - Usage data for a model
|
|
10
|
+
* @param {Function} log - Logging function
|
|
11
|
+
*/
|
|
12
|
+
export const displayBudgetStats = async (usage, log) => {
|
|
13
|
+
const modelInfo = usage.modelInfo;
|
|
14
|
+
if (!modelInfo?.limit) {
|
|
15
|
+
await log('\n ⚠️ Budget stats not available (no model limits found)');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
await log('\n 📊 Token Budget Statistics:');
|
|
20
|
+
|
|
21
|
+
// Context window usage
|
|
22
|
+
if (modelInfo.limit.context) {
|
|
23
|
+
const contextLimit = modelInfo.limit.context;
|
|
24
|
+
// Input tokens include regular input + cache creation + cache read
|
|
25
|
+
const totalInputUsed = usage.inputTokens + usage.cacheCreationTokens + usage.cacheReadTokens;
|
|
26
|
+
const contextUsageRatio = totalInputUsed / contextLimit;
|
|
27
|
+
const contextUsagePercent = (contextUsageRatio * 100).toFixed(2);
|
|
28
|
+
|
|
29
|
+
await log(' Context window:');
|
|
30
|
+
await log(` Used: ${formatNumber(totalInputUsed)} tokens`);
|
|
31
|
+
await log(` Limit: ${formatNumber(contextLimit)} tokens`);
|
|
32
|
+
await log(` Ratio: ${contextUsageRatio.toFixed(4)} (${contextUsagePercent}%)`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Output tokens usage
|
|
36
|
+
if (modelInfo.limit.output) {
|
|
37
|
+
const outputLimit = modelInfo.limit.output;
|
|
38
|
+
const outputUsageRatio = usage.outputTokens / outputLimit;
|
|
39
|
+
const outputUsagePercent = (outputUsageRatio * 100).toFixed(2);
|
|
40
|
+
|
|
41
|
+
await log(' Output tokens:');
|
|
42
|
+
await log(` Used: ${formatNumber(usage.outputTokens)} tokens`);
|
|
43
|
+
await log(` Limit: ${formatNumber(outputLimit)} tokens`);
|
|
44
|
+
await log(` Ratio: ${outputUsageRatio.toFixed(4)} (${outputUsagePercent}%)`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Total session tokens (input + cache_creation + output)
|
|
48
|
+
const totalSessionTokens = usage.inputTokens + usage.cacheCreationTokens + usage.outputTokens;
|
|
49
|
+
await log(` Total session tokens: ${formatNumber(totalSessionTokens)}`);
|
|
50
|
+
};
|
package/src/claude.lib.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import { reportError } from './sentry.lib.mjs';
|
|
|
13
13
|
import { timeouts, retryLimits } from './config.lib.mjs';
|
|
14
14
|
import { detectUsageLimit, formatUsageLimitMessage } from './usage-limit.lib.mjs';
|
|
15
15
|
import { createInteractiveHandler } from './interactive-mode.lib.mjs';
|
|
16
|
+
import { displayBudgetStats } from './claude.budget-stats.lib.mjs';
|
|
16
17
|
/**
|
|
17
18
|
* Format numbers with spaces as thousands separator (no commas)
|
|
18
19
|
* Per issue #667: Use spaces for thousands, . for decimals
|
|
@@ -1279,6 +1280,10 @@ export const executeClaudeCommand = async (params) => {
|
|
|
1279
1280
|
const usage = tokenUsage.modelUsage[modelId];
|
|
1280
1281
|
await log(`\n 📊 ${usage.modelName || modelId}:`);
|
|
1281
1282
|
await displayModelUsage(usage, log);
|
|
1283
|
+
// Display budget stats if flag is enabled
|
|
1284
|
+
if (argv.tokensBudgetStats && usage.modelInfo?.limit) {
|
|
1285
|
+
await displayBudgetStats(usage, log);
|
|
1286
|
+
}
|
|
1282
1287
|
}
|
|
1283
1288
|
// Show totals if multiple models were used
|
|
1284
1289
|
if (modelIds.length > 1) {
|
package/src/hive.config.lib.mjs
CHANGED
|
@@ -251,6 +251,11 @@ export const createYargsConfig = (yargsInstance) => {
|
|
|
251
251
|
description: 'Prompt AI to use general-purpose sub agents for processing large tasks with multiple files/folders. Only supported for --tool claude.',
|
|
252
252
|
default: false
|
|
253
253
|
})
|
|
254
|
+
.option('tokens-budget-stats', {
|
|
255
|
+
type: 'boolean',
|
|
256
|
+
description: '[EXPERIMENTAL] Show detailed token budget statistics including context window usage and ratios. Only supported for --tool claude.',
|
|
257
|
+
default: false
|
|
258
|
+
})
|
|
254
259
|
.option('prompt-issue-reporting', {
|
|
255
260
|
type: 'boolean',
|
|
256
261
|
description: 'Enable automatic issue creation for spotted bugs/errors not related to main task. Issues will include reproducible examples, workarounds, and fix suggestions. Works for both current and third-party repositories. Only supported for --tool claude.',
|
package/src/solve.config.lib.mjs
CHANGED
|
@@ -255,6 +255,11 @@ export const createYargsConfig = (yargsInstance) => {
|
|
|
255
255
|
description: 'Prompt AI to use general-purpose sub agents for processing large tasks with multiple files/folders. Only supported for --tool claude.',
|
|
256
256
|
default: false
|
|
257
257
|
})
|
|
258
|
+
.option('tokens-budget-stats', {
|
|
259
|
+
type: 'boolean',
|
|
260
|
+
description: '[EXPERIMENTAL] Show detailed token budget statistics including context window usage and ratios. Only supported for --tool claude.',
|
|
261
|
+
default: false
|
|
262
|
+
})
|
|
258
263
|
.option('prompt-issue-reporting', {
|
|
259
264
|
type: 'boolean',
|
|
260
265
|
description: 'Enable automatic issue creation for spotted bugs/errors not related to main task. Issues will include reproducible examples, workarounds, and fix suggestions. Works for both current and third-party repositories. Only supported for --tool claude.',
|
package/src/telegram-bot.mjs
CHANGED
|
@@ -47,6 +47,9 @@ const { validateModelName } = await import('./model-validation.lib.mjs');
|
|
|
47
47
|
// Import Claude limits library for /limits command
|
|
48
48
|
const { getClaudeUsageLimits, formatUsageMessage } = await import('./claude-limits.lib.mjs');
|
|
49
49
|
|
|
50
|
+
// Import version info library for /version command
|
|
51
|
+
const { getVersionInfo, formatVersionMessage } = await import('./version-info.lib.mjs');
|
|
52
|
+
|
|
50
53
|
// Import Telegram markdown escaping utilities
|
|
51
54
|
const { escapeMarkdown, escapeMarkdownV2 } = await import('./telegram-markdown.lib.mjs');
|
|
52
55
|
|
|
@@ -762,11 +765,9 @@ bot.command('help', async (ctx) => {
|
|
|
762
765
|
}
|
|
763
766
|
|
|
764
767
|
message += '*/limits* - Show Claude usage limits\n';
|
|
765
|
-
message += '
|
|
766
|
-
message += 'Shows current session and weekly usage percentages\n\n';
|
|
767
|
-
|
|
768
|
+
message += '*/version* - Show bot and runtime versions\n';
|
|
768
769
|
message += '*/help* - Show this help message\n\n';
|
|
769
|
-
message += '⚠️ *Note:* /solve, /hive and /
|
|
770
|
+
message += '⚠️ *Note:* /solve, /hive, /limits and /version commands only work in group chats.\n\n';
|
|
770
771
|
message += '🔧 *Available Options:*\n';
|
|
771
772
|
message += '• `--fork` - Fork the repository\n';
|
|
772
773
|
message += '• `--auto-fork` - Automatically fork public repos without write access\n';
|
|
@@ -875,7 +876,18 @@ bot.command('limits', async (ctx) => {
|
|
|
875
876
|
{ parse_mode: 'Markdown' }
|
|
876
877
|
);
|
|
877
878
|
});
|
|
878
|
-
|
|
879
|
+
bot.command('version', async (ctx) => {
|
|
880
|
+
VERBOSE && console.log('[VERBOSE] /version command received');
|
|
881
|
+
await addBreadcrumb({ category: 'telegram.command', message: '/version command received', level: 'info', data: { chatId: ctx.chat?.id, chatType: ctx.chat?.type, userId: ctx.from?.id, username: ctx.from?.username } });
|
|
882
|
+
if (isOldMessage(ctx) || isForwardedOrReply(ctx)) return;
|
|
883
|
+
if (!isGroupChat(ctx)) return await ctx.reply('❌ The /version command only works in group chats. Please add this bot to a group and make it an admin.', { reply_to_message_id: ctx.message.message_id });
|
|
884
|
+
const chatId = ctx.chat.id;
|
|
885
|
+
if (!isChatAuthorized(chatId)) return await ctx.reply(`❌ This chat (ID: ${chatId}) is not authorized to use this bot. Please contact the bot administrator.`, { reply_to_message_id: ctx.message.message_id });
|
|
886
|
+
const fetchingMessage = await ctx.reply('🔄 Gathering version information...', { reply_to_message_id: ctx.message.message_id });
|
|
887
|
+
const result = await getVersionInfo(VERBOSE);
|
|
888
|
+
if (!result.success) return await ctx.telegram.editMessageText(fetchingMessage.chat.id, fetchingMessage.message_id, undefined, `❌ ${escapeMarkdownV2(result.error, { preserveCodeBlocks: true })}`, { parse_mode: 'MarkdownV2' });
|
|
889
|
+
await ctx.telegram.editMessageText(fetchingMessage.chat.id, fetchingMessage.message_id, undefined, '🤖 *Version Information*\n\n' + formatVersionMessage(result.versions), { parse_mode: 'Markdown' });
|
|
890
|
+
});
|
|
879
891
|
bot.command(/^solve$/i, async (ctx) => {
|
|
880
892
|
if (VERBOSE) {
|
|
881
893
|
console.log('[VERBOSE] /solve command received');
|
|
@@ -1264,14 +1276,12 @@ if (VERBOSE) {
|
|
|
1264
1276
|
bot.catch((error, ctx) => {
|
|
1265
1277
|
console.error('Unhandled error while processing update', ctx.update.update_id);
|
|
1266
1278
|
console.error('Error:', error);
|
|
1267
|
-
|
|
1268
1279
|
// Log detailed error information
|
|
1269
1280
|
console.error('Error details:', {
|
|
1270
1281
|
name: error.name,
|
|
1271
1282
|
message: error.message,
|
|
1272
1283
|
stack: error.stack?.split('\n').slice(0, 10).join('\n'),
|
|
1273
1284
|
});
|
|
1274
|
-
|
|
1275
1285
|
// Log context information for debugging
|
|
1276
1286
|
if (VERBOSE) {
|
|
1277
1287
|
console.log('[VERBOSE] Error context:', {
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Version information library for hive-mind project
|
|
4
|
+
// Provides comprehensive version information for bot, commands, and runtime
|
|
5
|
+
|
|
6
|
+
import { getVersion } from './version.lib.mjs';
|
|
7
|
+
import { execSync } from 'child_process';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Execute a command and return its output, or null if it fails
|
|
11
|
+
* @param {string} command - Command to execute
|
|
12
|
+
* @param {boolean} verbose - Enable verbose logging
|
|
13
|
+
* @returns {string|null} Command output or null
|
|
14
|
+
*/
|
|
15
|
+
function execCommand(command, verbose = false) {
|
|
16
|
+
try {
|
|
17
|
+
const result = execSync(command, { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'ignore'] });
|
|
18
|
+
const trimmed = result.trim();
|
|
19
|
+
// Return null if the output looks like an error message
|
|
20
|
+
if (trimmed.includes('not found') || trimmed.includes('command not found') || trimmed === '') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return trimmed;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (verbose) {
|
|
26
|
+
console.log(`[VERBOSE] Command failed: ${command}`, error.message);
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get comprehensive version information for all components
|
|
34
|
+
* @param {boolean} verbose - Enable verbose logging
|
|
35
|
+
* @returns {Promise<Object>} Version information object
|
|
36
|
+
*/
|
|
37
|
+
export async function getVersionInfo(verbose = false) {
|
|
38
|
+
try {
|
|
39
|
+
if (verbose) {
|
|
40
|
+
console.log('[VERBOSE] Gathering version information...');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Get hive-mind package version
|
|
44
|
+
const packageVersion = await getVersion();
|
|
45
|
+
if (verbose) {
|
|
46
|
+
console.log(`[VERBOSE] Package version: ${packageVersion}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// === Agents ===
|
|
50
|
+
|
|
51
|
+
// Claude Code
|
|
52
|
+
const claudeVersion = execCommand('claude --version 2>&1', verbose);
|
|
53
|
+
if (verbose && claudeVersion) {
|
|
54
|
+
console.log(`[VERBOSE] Claude Code version: ${claudeVersion}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Playwright
|
|
58
|
+
const playwrightVersion = execCommand('playwright --version 2>&1', verbose);
|
|
59
|
+
if (verbose && playwrightVersion) {
|
|
60
|
+
console.log(`[VERBOSE] Playwright version: ${playwrightVersion}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Playwright MCP (check if installed via npm)
|
|
64
|
+
const playwrightMcpVersion = execCommand('npm list -g @playwright/mcp --depth=0 2>&1 | grep @playwright/mcp | awk \'{print $2}\'', verbose);
|
|
65
|
+
if (verbose && playwrightMcpVersion) {
|
|
66
|
+
console.log(`[VERBOSE] Playwright MCP version: ${playwrightMcpVersion}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// === Language Runtimes ===
|
|
70
|
+
|
|
71
|
+
// Node.js (from process, always available)
|
|
72
|
+
const nodeVersion = process.version;
|
|
73
|
+
if (verbose) {
|
|
74
|
+
console.log(`[VERBOSE] Node.js version: ${nodeVersion}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Python
|
|
78
|
+
const pythonVersion = execCommand('python --version 2>&1', verbose);
|
|
79
|
+
if (verbose && pythonVersion) {
|
|
80
|
+
console.log(`[VERBOSE] Python version: ${pythonVersion}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Pyenv
|
|
84
|
+
const pyenvVersion = execCommand('pyenv --version 2>&1', verbose);
|
|
85
|
+
if (verbose && pyenvVersion) {
|
|
86
|
+
console.log(`[VERBOSE] Pyenv version: ${pyenvVersion}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Rust
|
|
90
|
+
const rustVersion = execCommand('rustc --version 2>&1', verbose);
|
|
91
|
+
if (verbose && rustVersion) {
|
|
92
|
+
console.log(`[VERBOSE] Rust version: ${rustVersion}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Cargo
|
|
96
|
+
const cargoVersion = execCommand('cargo --version 2>&1', verbose);
|
|
97
|
+
if (verbose && cargoVersion) {
|
|
98
|
+
console.log(`[VERBOSE] Cargo version: ${cargoVersion}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// PHP
|
|
102
|
+
const phpVersion = execCommand('php --version 2>&1 | head -n1', verbose);
|
|
103
|
+
if (verbose && phpVersion) {
|
|
104
|
+
console.log(`[VERBOSE] PHP version: ${phpVersion}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Bun
|
|
108
|
+
const bunVersion = execCommand('bun --version 2>&1', verbose);
|
|
109
|
+
if (verbose && bunVersion) {
|
|
110
|
+
console.log(`[VERBOSE] Bun version: ${bunVersion}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// .NET
|
|
114
|
+
const dotnetVersion = execCommand('dotnet --version 2>&1', verbose);
|
|
115
|
+
if (verbose && dotnetVersion) {
|
|
116
|
+
console.log(`[VERBOSE] .NET version: ${dotnetVersion}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// === Development Tools ===
|
|
120
|
+
|
|
121
|
+
// Git
|
|
122
|
+
const gitVersion = execCommand('git --version 2>&1', verbose);
|
|
123
|
+
if (verbose && gitVersion) {
|
|
124
|
+
console.log(`[VERBOSE] Git version: ${gitVersion}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// GitHub CLI
|
|
128
|
+
const ghVersion = execCommand('gh --version 2>&1 | head -n1', verbose);
|
|
129
|
+
if (verbose && ghVersion) {
|
|
130
|
+
console.log(`[VERBOSE] GitHub CLI version: ${ghVersion}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// NVM
|
|
134
|
+
const nvmVersion = execCommand('nvm --version 2>&1', verbose);
|
|
135
|
+
if (verbose && nvmVersion) {
|
|
136
|
+
console.log(`[VERBOSE] NVM version: ${nvmVersion}`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Homebrew
|
|
140
|
+
const brewVersion = execCommand('brew --version 2>&1 | head -n1', verbose);
|
|
141
|
+
if (verbose && brewVersion) {
|
|
142
|
+
console.log(`[VERBOSE] Homebrew version: ${brewVersion}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// NPM
|
|
146
|
+
const npmVersion = execCommand('npm --version 2>&1', verbose);
|
|
147
|
+
if (verbose && npmVersion) {
|
|
148
|
+
console.log(`[VERBOSE] NPM version: ${npmVersion}`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// === Platform Information ===
|
|
152
|
+
const platform = process.platform;
|
|
153
|
+
const arch = process.arch;
|
|
154
|
+
if (verbose) {
|
|
155
|
+
console.log(`[VERBOSE] Platform: ${platform} (${arch})`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Build version info object
|
|
159
|
+
const versionInfo = {
|
|
160
|
+
success: true,
|
|
161
|
+
versions: {
|
|
162
|
+
// Bot components
|
|
163
|
+
bot: packageVersion,
|
|
164
|
+
solve: packageVersion,
|
|
165
|
+
hive: packageVersion,
|
|
166
|
+
|
|
167
|
+
// Agents
|
|
168
|
+
claudeCode: claudeVersion,
|
|
169
|
+
playwright: playwrightVersion,
|
|
170
|
+
playwrightMcp: playwrightMcpVersion,
|
|
171
|
+
|
|
172
|
+
// Language runtimes
|
|
173
|
+
node: nodeVersion,
|
|
174
|
+
python: pythonVersion,
|
|
175
|
+
rust: rustVersion,
|
|
176
|
+
php: phpVersion,
|
|
177
|
+
bun: bunVersion,
|
|
178
|
+
dotnet: dotnetVersion,
|
|
179
|
+
|
|
180
|
+
// Development tools
|
|
181
|
+
git: gitVersion,
|
|
182
|
+
gh: ghVersion,
|
|
183
|
+
npm: npmVersion,
|
|
184
|
+
nvm: nvmVersion,
|
|
185
|
+
pyenv: pyenvVersion,
|
|
186
|
+
cargo: cargoVersion,
|
|
187
|
+
brew: brewVersion,
|
|
188
|
+
|
|
189
|
+
// Platform
|
|
190
|
+
platform: `${platform} (${arch})`,
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
if (verbose) {
|
|
195
|
+
console.log('[VERBOSE] Version info gathered successfully:', JSON.stringify(versionInfo, null, 2));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return versionInfo;
|
|
199
|
+
} catch (error) {
|
|
200
|
+
if (verbose) {
|
|
201
|
+
console.error('[VERBOSE] Error gathering version info:', error);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
error: error.message || 'Failed to gather version information',
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Format version information as a Telegram message
|
|
213
|
+
* @param {Object} versions - Version information object
|
|
214
|
+
* @returns {string} Formatted message
|
|
215
|
+
*/
|
|
216
|
+
export function formatVersionMessage(versions) {
|
|
217
|
+
const lines = [];
|
|
218
|
+
|
|
219
|
+
// === Bot Components ===
|
|
220
|
+
lines.push('*🤖 Bot Components*');
|
|
221
|
+
if (versions.bot) {
|
|
222
|
+
lines.push(`• Bot: \`${versions.bot}\``);
|
|
223
|
+
}
|
|
224
|
+
if (versions.solve) {
|
|
225
|
+
lines.push(`• solve: \`${versions.solve}\``);
|
|
226
|
+
}
|
|
227
|
+
if (versions.hive) {
|
|
228
|
+
lines.push(`• hive: \`${versions.hive}\``);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// === Agents ===
|
|
232
|
+
const agentLines = [];
|
|
233
|
+
if (versions.claudeCode) {
|
|
234
|
+
agentLines.push(`• Claude Code: \`${versions.claudeCode}\``);
|
|
235
|
+
}
|
|
236
|
+
if (versions.playwright) {
|
|
237
|
+
agentLines.push(`• Playwright: \`${versions.playwright}\``);
|
|
238
|
+
}
|
|
239
|
+
if (versions.playwrightMcp) {
|
|
240
|
+
agentLines.push(`• Playwright MCP: \`${versions.playwrightMcp}\``);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (agentLines.length > 0) {
|
|
244
|
+
lines.push('');
|
|
245
|
+
lines.push('*🎭 Agents*');
|
|
246
|
+
lines.push(...agentLines);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// === Language Runtimes ===
|
|
250
|
+
const runtimeLines = [];
|
|
251
|
+
if (versions.node) {
|
|
252
|
+
runtimeLines.push(`• Node.js: \`${versions.node}\``);
|
|
253
|
+
}
|
|
254
|
+
if (versions.python) {
|
|
255
|
+
runtimeLines.push(`• Python: \`${versions.python}\``);
|
|
256
|
+
}
|
|
257
|
+
if (versions.rust) {
|
|
258
|
+
runtimeLines.push(`• Rust: \`${versions.rust}\``);
|
|
259
|
+
}
|
|
260
|
+
if (versions.php) {
|
|
261
|
+
runtimeLines.push(`• PHP: \`${versions.php}\``);
|
|
262
|
+
}
|
|
263
|
+
if (versions.bun) {
|
|
264
|
+
runtimeLines.push(`• Bun: \`${versions.bun}\``);
|
|
265
|
+
}
|
|
266
|
+
if (versions.dotnet) {
|
|
267
|
+
runtimeLines.push(`• .NET: \`${versions.dotnet}\``);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (runtimeLines.length > 0) {
|
|
271
|
+
lines.push('');
|
|
272
|
+
lines.push('*⚙️ Language Runtimes*');
|
|
273
|
+
lines.push(...runtimeLines);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// === Development Tools ===
|
|
277
|
+
const toolLines = [];
|
|
278
|
+
if (versions.git) {
|
|
279
|
+
toolLines.push(`• Git: \`${versions.git}\``);
|
|
280
|
+
}
|
|
281
|
+
if (versions.gh) {
|
|
282
|
+
toolLines.push(`• GitHub CLI: \`${versions.gh}\``);
|
|
283
|
+
}
|
|
284
|
+
if (versions.npm) {
|
|
285
|
+
toolLines.push(`• NPM: \`${versions.npm}\``);
|
|
286
|
+
}
|
|
287
|
+
if (versions.nvm) {
|
|
288
|
+
toolLines.push(`• NVM: \`${versions.nvm}\``);
|
|
289
|
+
}
|
|
290
|
+
if (versions.pyenv) {
|
|
291
|
+
toolLines.push(`• Pyenv: \`${versions.pyenv}\``);
|
|
292
|
+
}
|
|
293
|
+
if (versions.cargo) {
|
|
294
|
+
toolLines.push(`• Cargo: \`${versions.cargo}\``);
|
|
295
|
+
}
|
|
296
|
+
if (versions.brew) {
|
|
297
|
+
toolLines.push(`• Homebrew: \`${versions.brew}\``);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (toolLines.length > 0) {
|
|
301
|
+
lines.push('');
|
|
302
|
+
lines.push('*🛠 Development Tools*');
|
|
303
|
+
lines.push(...toolLines);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// === Platform ===
|
|
307
|
+
if (versions.platform) {
|
|
308
|
+
lines.push('');
|
|
309
|
+
lines.push('*💻 Platform*');
|
|
310
|
+
lines.push(`• System: \`${versions.platform}\``);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return lines.join('\n');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export default {
|
|
317
|
+
getVersionInfo,
|
|
318
|
+
formatVersionMessage,
|
|
319
|
+
};
|