beplus-mcp 0.13.0 → 0.14.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.
Files changed (2) hide show
  1. package/dist/index.js +62 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -215,6 +215,10 @@ var TEAM_GATING_NOTE = " \u26A0\uFE0F DESTINO DA GERA\xC7\xC3O: toda imagem/v\xE
215
215
  function isTeamGatingError(msg) {
216
216
  return !!msg && /cliente e um projeto|selecione um cliente|sem cliente vinculado|antes de gerar/i.test(msg);
217
217
  }
218
+ function isBudgetBlockedError(msg) {
219
+ return !!msg && /budget/i.test(msg);
220
+ }
221
+ var BUDGET_BLOCKED_GUIDANCE = "\u{1F4A1} O pote deste projeto/cliente acabou. Um admin pode recarregar em Admin \u2192 IA Lab \u2192 Projetos/Clientes. Alternativa: trocar o projeto ativo com `set_active_project`.";
218
222
  async function buildPickProjectMessage(client) {
219
223
  let clientsTxt = " (n\xE3o foi poss\xEDvel listar clientes)";
220
224
  let projectsTxt = " (n\xE3o foi poss\xEDvel listar projetos)";
@@ -401,6 +405,16 @@ function weeklyAllowanceLine(wa) {
401
405
  }
402
406
  return line;
403
407
  }
408
+ function budgetLine(b) {
409
+ if (!b || !b.enabled) return "";
410
+ const scope = b.scope === "client" ? "cliente" : "projeto";
411
+ const pct = b.percentUsed;
412
+ const exhausted = pct >= 100 || b.remainingDiamonds <= 0;
413
+ const icon = exhausted ? "\u{1F6D1}" : pct >= 80 ? "\u26A0\uFE0F" : "\u{1F9FE}";
414
+ let line = `${icon} Budget do ${scope}: ${b.remainingDiamonds} de ${b.quotaDiamonds}\u{1F48E} restantes (${pct}% usado)`;
415
+ if (exhausted) line += " \u2014 pe\xE7a a um admin para recarregar";
416
+ return line;
417
+ }
404
418
  function textResult(s) {
405
419
  return { content: [{ type: "text", text: s }] };
406
420
  }
@@ -423,10 +437,16 @@ function costFooter(start, cfg) {
423
437
  footer = `\u26A0 Custo alto (${start.diamond_cost} \u{1F48E})
424
438
  ${footer}`;
425
439
  }
440
+ const budget = budgetLine(start.budget);
426
441
  if (start.project_code) {
427
- const proj = `\u{1F4C1} Projeto: ${start.project_code}${start.project_name ? ` \u2014 ${start.project_name}` : ""}`;
442
+ let proj = `\u{1F4C1} Projeto: ${start.project_code}${start.project_name ? ` \u2014 ${start.project_name}` : ""}`;
443
+ if (budget) proj = `${proj}
444
+ ${budget}`;
428
445
  footer = footer ? `${proj}
429
446
  ${footer}` : proj;
447
+ } else if (budget) {
448
+ footer = footer ? `${budget}
449
+ ${footer}` : budget;
430
450
  }
431
451
  const wa = weeklyAllowanceLine(start.weekly_allowance);
432
452
  if (wa) footer = footer ? `${footer}
@@ -664,6 +684,10 @@ ${footer}` }, ...blocks]
664
684
  } catch (e) {
665
685
  const msg = e instanceof ApiError ? e.message : e instanceof Error ? e.message : "";
666
686
  if (isTeamGatingError(msg)) return errorResult(await buildPickProjectMessage(client));
687
+ if (isBudgetBlockedError(msg)) {
688
+ return errorResult(`${apiErrorToUserMessage(e)}
689
+ ${BUDGET_BLOCKED_GUIDANCE}`);
690
+ }
667
691
  return errorResult(apiErrorToUserMessage(e));
668
692
  }
669
693
  }
@@ -721,6 +745,10 @@ ${footer}` }, ...blocks] };
721
745
  } catch (e) {
722
746
  const msg = e instanceof ApiError ? e.message : e instanceof Error ? e.message : "";
723
747
  if (isTeamGatingError(msg)) return errorResult(await buildPickProjectMessage(client));
748
+ if (isBudgetBlockedError(msg)) {
749
+ return errorResult(`${apiErrorToUserMessage(e)}
750
+ ${BUDGET_BLOCKED_GUIDANCE}`);
751
+ }
724
752
  return errorResult(apiErrorToUserMessage(e));
725
753
  }
726
754
  }
@@ -813,6 +841,10 @@ ${footer}`);
813
841
  } catch (e) {
814
842
  const msg = e instanceof ApiError ? e.message : e instanceof Error ? e.message : "";
815
843
  if (isTeamGatingError(msg)) return errorResult(await buildPickProjectMessage(client));
844
+ if (isBudgetBlockedError(msg)) {
845
+ return errorResult(`${apiErrorToUserMessage(e)}
846
+ ${BUDGET_BLOCKED_GUIDANCE}`);
847
+ }
816
848
  return errorResult(apiErrorToUserMessage(e));
817
849
  }
818
850
  }
@@ -990,15 +1022,21 @@ function registerAudioTools(server, client, cfg) {
990
1022
  const projLine = res.project_code ? `
991
1023
  \u{1F4C1} Projeto: ${res.project_code}${res.project_name ? ` \u2014 ${res.project_name}` : ""}` : "";
992
1024
  const wa = weeklyAllowanceLine(res.weekly_allowance);
1025
+ const budget = budgetLine(res.budget);
993
1026
  return textResult(
994
1027
  `\u2705 \xC1udio gerado (${res.model}, voz ${res.voice}, ${res.duration_sec.toFixed(1)}s).
995
1028
  ${res.url}
996
- ${parts.join(" \xB7 ")}${projLine}` + (wa ? `
1029
+ ${parts.join(" \xB7 ")}${projLine}` + (budget ? `
1030
+ ${budget}` : "") + (wa ? `
997
1031
  ${wa}` : "")
998
1032
  );
999
1033
  } catch (e) {
1000
1034
  const msg = e instanceof ApiError ? e.message : e instanceof Error ? e.message : "";
1001
1035
  if (isTeamGatingError(msg)) return errorResult(await buildPickProjectMessage(client));
1036
+ if (isBudgetBlockedError(msg)) {
1037
+ return errorResult(`${apiErrorToUserMessage(e)}
1038
+ ${BUDGET_BLOCKED_GUIDANCE}`);
1039
+ }
1002
1040
  return errorResult(apiErrorToUserMessage(e));
1003
1041
  }
1004
1042
  }
@@ -1082,6 +1120,10 @@ ${footer}`);
1082
1120
  } catch (e) {
1083
1121
  const msg = e instanceof ApiError ? e.message : e instanceof Error ? e.message : "";
1084
1122
  if (isTeamGatingError(msg)) return errorResult(await buildPickProjectMessage(client));
1123
+ if (isBudgetBlockedError(msg)) {
1124
+ return errorResult(`${apiErrorToUserMessage(e)}
1125
+ ${BUDGET_BLOCKED_GUIDANCE}`);
1126
+ }
1085
1127
  return errorResult(apiErrorToUserMessage(e));
1086
1128
  }
1087
1129
  }
@@ -1102,10 +1144,12 @@ function registerAccountTools(server, client, _cfg) {
1102
1144
  try {
1103
1145
  const me = await client.me();
1104
1146
  const wa = weeklyAllowanceLine(me.weekly_allowance);
1147
+ const budget = budgetLine(me.budget);
1105
1148
  return textResult(
1106
1149
  `\u{1F464} ${me.name ?? "(sem nome)"} <${me.email ?? "sem email"}>
1107
1150
  Saldo: ${me.diamonds} \u{1F48E} \xB7 auth: ${me.authType}` + (wa ? `
1108
- ${wa}` : "")
1151
+ ${wa}` : "") + (budget ? `
1152
+ ${budget}` : "")
1109
1153
  );
1110
1154
  } catch (e) {
1111
1155
  return errorResult(apiErrorToUserMessage(e));
@@ -1123,8 +1167,12 @@ ${wa}` : "")
1123
1167
  try {
1124
1168
  const b = await client.balance();
1125
1169
  const wa = weeklyAllowanceLine(b.weekly_allowance);
1126
- return textResult(`Saldo: ${b.diamonds} \u{1F48E}` + (wa ? `
1127
- ${wa}` : ""));
1170
+ const budget = budgetLine(b.budget);
1171
+ return textResult(
1172
+ `Saldo: ${b.diamonds} \u{1F48E}` + (wa ? `
1173
+ ${wa}` : "") + (budget ? `
1174
+ ${budget}` : "")
1175
+ );
1128
1176
  } catch (e) {
1129
1177
  return errorResult(apiErrorToUserMessage(e));
1130
1178
  }
@@ -1242,7 +1290,8 @@ function projectLine(p, active) {
1242
1290
  const marker = active ? "\u25CF " : "\u25CB ";
1243
1291
  const counts = `${p.generation_count ?? 0} gera\xE7\xF5es`;
1244
1292
  const owner = p.client_name ? ` \xB7 cliente: ${p.client_name}` : "";
1245
- return `${marker}${p.code} \u2014 ${p.name} (${counts}${owner})`;
1293
+ const budget = p.budget?.enabled ? ` \xB7 budget ${p.budget.remainingDiamonds}/${p.budget.quotaDiamonds}\u{1F48E}` : "";
1294
+ return `${marker}${p.code} \u2014 ${p.name} (${counts}${owner})${budget}`;
1246
1295
  }
1247
1296
  function registerProjectTools(server, client, _cfg) {
1248
1297
  server.registerTool(
@@ -1262,7 +1311,10 @@ function registerProjectTools(server, client, _cfg) {
1262
1311
  }
1263
1312
  const lines = projects.map((p) => projectLine(p, !!p.is_active_for_user));
1264
1313
  const active = projects.find((p) => p.is_active_for_user);
1265
- const header = active ? `Projeto ativo: ${active.code} \u2014 ${active.name}` : "Nenhum projeto ativo (gera\xE7\xF5es ficam sem projeto).";
1314
+ let header = active ? `Projeto ativo: ${active.code} \u2014 ${active.name}` : "Nenhum projeto ativo (gera\xE7\xF5es ficam sem projeto).";
1315
+ const activeBudget = budgetLine(active?.budget);
1316
+ if (activeBudget) header += `
1317
+ ${activeBudget}`;
1266
1318
  return textResult(`${header}
1267
1319
 
1268
1320
  ${lines.join("\n")}`);
@@ -1313,7 +1365,9 @@ ${lines.join("\n")}`);
1313
1365
  try {
1314
1366
  const { project: active } = await client.setActiveProject(project ?? null);
1315
1367
  if (!active) return textResult("\u2705 Projeto ativo removido \u2014 novas gera\xE7\xF5es ficar\xE3o sem projeto.");
1316
- return textResult(`\u2705 Projeto ativo: ${active.code} \u2014 ${active.name}.`);
1368
+ const budget = budgetLine(active.budget);
1369
+ return textResult(`\u2705 Projeto ativo: ${active.code} \u2014 ${active.name}.` + (budget ? `
1370
+ ${budget}` : ""));
1317
1371
  } catch (e) {
1318
1372
  return errorResult(apiErrorToUserMessage(e));
1319
1373
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beplus-mcp",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Conector MCP da equipe BePlus — gere imagens/vídeos/áudio e consulte calls, projetos e clientes pela sua conta BePlus (diamantes, limites e histórico aplicados pela plataforma).",
5
5
  "type": "module",
6
6
  "bin": {