@link-assistant/hive-mind 1.47.2 → 1.48.1

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.48.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 6d385ab: Simplified cost display when public and Anthropic costs match, removed USD suffix from Anthropic cost line
8
+
9
+ ## 1.48.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 28f7ace: Add /do and /continue as alias commands for /solve in telegram bot
14
+
3
15
  ## 1.47.2
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.47.2",
3
+ "version": "1.48.1",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -118,15 +118,23 @@ export const displayModelUsage = async (usage, log) => {
118
118
 
119
119
  /**
120
120
  * Display cost comparison between public pricing and Anthropic's official cost
121
+ * Issue #1557: Show simplified format when costs match, remove USD suffix
121
122
  * @param {number|null} publicCost - Public pricing estimate
122
123
  * @param {number|null} anthropicCost - Anthropic's official cost
123
124
  * @param {Function} log - Logging function
124
125
  */
125
126
  export const displayCostComparison = async (publicCost, anthropicCost, log) => {
127
+ const hasPublic = publicCost !== null && publicCost !== undefined;
128
+ const hasAnthropic = anthropicCost !== null && anthropicCost !== undefined;
129
+ // Issue #1557: When both costs match, show simplified format
130
+ if (hasPublic && hasAnthropic && publicCost.toFixed(6) === anthropicCost.toFixed(6)) {
131
+ await log(`\n 💰 Cost: $${anthropicCost.toFixed(6)}`);
132
+ return;
133
+ }
126
134
  await log('\n 💰 Cost estimation:');
127
- await log(` Public pricing estimate: ${publicCost !== null && publicCost !== undefined ? `$${publicCost.toFixed(6)} USD` : 'unknown'}`);
128
- await log(` Calculated by Anthropic: ${anthropicCost !== null && anthropicCost !== undefined ? `$${anthropicCost.toFixed(6)} USD` : 'unknown'}`);
129
- if (publicCost !== null && publicCost !== undefined && anthropicCost !== null && anthropicCost !== undefined) {
135
+ await log(` Public pricing estimate: ${hasPublic ? `$${publicCost.toFixed(6)}` : 'unknown'}`);
136
+ await log(` Calculated by Anthropic: ${hasAnthropic ? `$${anthropicCost.toFixed(6)}` : 'unknown'}`);
137
+ if (hasPublic && hasAnthropic) {
130
138
  const difference = anthropicCost - publicCost;
131
139
  const percentDiff = publicCost > 0 ? (difference / publicCost) * 100 : 0;
132
140
  await log(` Difference: $${difference.toFixed(6)} (${percentDiff > 0 ? '+' : ''}${percentDiff.toFixed(2)}%)`);
@@ -15,13 +15,15 @@ import { getToolDisplayName, getModelInfoForComment } from './models/index.mjs';
15
15
  export { getToolDisplayName }; // Re-export for use by other modules
16
16
  import { buildBudgetStatsString } from './claude.budget-stats.lib.mjs';
17
17
 
18
- /** Build cost estimation string for log comments (Issue #1250) */
18
+ /** Build cost estimation string for log comments (Issue #1250, Issue #1557) */
19
19
  const buildCostInfoString = (totalCostUSD, anthropicTotalCostUSD, pricingInfo) => {
20
20
  const hasPublic = totalCostUSD !== null && totalCostUSD !== undefined;
21
21
  const hasAnthropic = anthropicTotalCostUSD !== null && anthropicTotalCostUSD !== undefined;
22
22
  const hasPricing = pricingInfo && (pricingInfo.modelName || pricingInfo.tokenUsage || pricingInfo.isFreeModel || pricingInfo.isOpencodeFreeModel);
23
23
  const hasOpencodeCost = pricingInfo?.opencodeCost !== null && pricingInfo?.opencodeCost !== undefined;
24
24
  if (!hasPublic && !hasAnthropic && !hasPricing && !hasOpencodeCost) return '';
25
+ // Issue #1557: Simplified display when public and Anthropic costs match
26
+ if (hasPublic && hasAnthropic && totalCostUSD.toFixed(6) === anthropicTotalCostUSD.toFixed(6)) return `\n\n### 💰 Cost: **$${anthropicTotalCostUSD.toFixed(6)}**`;
25
27
  let costInfo = '\n\n### 💰 **Cost estimation:**';
26
28
  if (pricingInfo?.modelName) {
27
29
  costInfo += `\n- Model: ${pricingInfo.modelName}`;
@@ -57,7 +59,7 @@ const buildCostInfoString = (totalCostUSD, anthropicTotalCostUSD, pricingInfo) =
57
59
  costInfo += tokenInfo;
58
60
  }
59
61
  if (hasAnthropic) {
60
- costInfo += `\n- Calculated by Anthropic: $${anthropicTotalCostUSD.toFixed(6)} USD`;
62
+ costInfo += `\n- Calculated by Anthropic: $${anthropicTotalCostUSD.toFixed(6)}`;
61
63
  if (hasPublic) {
62
64
  const diff = anthropicTotalCostUSD - totalCostUSD;
63
65
  const pct = totalCostUSD > 0 ? (diff / totalCostUSD) * 100 : 0;
@@ -66,12 +68,8 @@ const buildCostInfoString = (totalCostUSD, anthropicTotalCostUSD, pricingInfo) =
66
68
  }
67
69
  return costInfo;
68
70
  };
69
-
70
- // Helper function to mask GitHub tokens (alias for backward compatibility)
71
- export const maskGitHubToken = maskToken;
72
- // Escape ``` in logs for safe markdown embedding (replaces with \`\`\` to prevent code block closure)
73
- export const escapeCodeBlocksInLog = logContent => logContent.replace(/```/g, '\\`\\`\\`');
74
- // Helper function to check if a file exists in a GitHub branch
71
+ export const maskGitHubToken = maskToken; // Alias for backward compatibility
72
+ export const escapeCodeBlocksInLog = logContent => logContent.replace(/```/g, '\\`\\`\\`'); // Escape ``` in logs
75
73
  export const checkFileInBranch = async (owner, repo, fileName, branchName) => {
76
74
  const { $ } = await use('command-stream');
77
75
 
@@ -658,7 +658,7 @@ bot.command('help', async ctx => {
658
658
  message += '📝 *Available Commands:*\n\n';
659
659
 
660
660
  if (solveEnabled) {
661
- message += '*/solve* - Solve a GitHub issue\n';
661
+ message += '*/solve* (aliases: */do*, */continue*) - Solve a GitHub issue\n';
662
662
  message += 'Usage: `/solve <github-url> [options]`\n';
663
663
  message += 'Example: `/solve https://github.com/owner/repo/issues/123 --model sonnet`\n';
664
664
  message += 'Or reply to a message with a GitHub link: `/solve`\n';
@@ -667,7 +667,7 @@ bot.command('help', async ctx => {
667
667
  }
668
668
  message += '\n';
669
669
  } else {
670
- message += '*/solve* - ❌ Disabled\n\n';
670
+ message += '*/solve* (aliases: */do*, */continue*) - ❌ Disabled\n\n';
671
671
  }
672
672
 
673
673
  if (hiveEnabled) {
@@ -695,7 +695,7 @@ bot.command('help', async ctx => {
695
695
  message += '🔔 *Session Notifications:* The bot monitors sessions and notifies when they complete.\n';
696
696
  if (ISOLATION_BACKEND) message += `🔒 *Isolation Mode:* \`${ISOLATION_BACKEND}\` (experimental)\n`;
697
697
  message += '\n';
698
- message += '⚠️ *Note:* /solve, /hive, /solve\\_queue, /limits, /version, /accept\\_invites, /merge, /stop and /start commands only work in group chats.\n\n';
698
+ message += '⚠️ *Note:* /solve, /do, /continue, /hive, /solve\\_queue, /limits, /version, /accept\\_invites, /merge, /stop and /start commands only work in group chats.\n\n';
699
699
  message += '🔧 *Common Options:*\n';
700
700
  message += `• \`--model <model>\` or \`-m\` - ${buildModelOptionDescription()}\n`;
701
701
  message += '• `--base-branch <branch>` or `-b` - Target branch for PR (default: repo default branch)\n';
@@ -1041,7 +1041,7 @@ async function handleSolveCommand(ctx) {
1041
1041
  }
1042
1042
  }
1043
1043
 
1044
- bot.command(/^solve$/i, handleSolveCommand);
1044
+ bot.command([/^solve$/i, /^do$/i, /^continue$/i], handleSolveCommand); // /do and /continue are aliases (issue #525)
1045
1045
 
1046
1046
  // Named handler for /hive command - extracted for reuse by text-based fallback (issue #1207)
1047
1047
  async function handleHiveCommand(ctx) {
@@ -1268,12 +1268,8 @@ bot.on('message', async (ctx, next) => {
1268
1268
  }
1269
1269
 
1270
1270
  // Check if this is a command we handle
1271
- const handlers = {
1272
- solve: handleSolveCommand,
1273
- hive: handleHiveCommand,
1274
- solve_queue: handleSolveQueueCommand,
1275
- solvequeue: handleSolveQueueCommand,
1276
- };
1271
+ // /do and /continue are aliases for /solve (issue #525)
1272
+ const handlers = { solve: handleSolveCommand, do: handleSolveCommand, continue: handleSolveCommand, hive: handleHiveCommand, solve_queue: handleSolveQueueCommand, solvequeue: handleSolveQueueCommand };
1277
1273
 
1278
1274
  const handler = handlers[extracted.command];
1279
1275
  if (!handler) return next();