@bobfrankston/rmfmail 1.2.251 → 1.2.252
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/bin/mailx.js +20 -0
- package/bin/mailx.js.map +1 -1
- package/bin/mailx.ts +21 -0
- package/client/app.bundle.js +10 -1
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +16 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +16 -0
- package/client/components/message-viewer.js +13 -2
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +13 -2
- package/package.json +1 -1
- package/packages/mailx-service/ai-usage.d.ts +32 -0
- package/packages/mailx-service/ai-usage.d.ts.map +1 -0
- package/packages/mailx-service/ai-usage.js +98 -0
- package/packages/mailx-service/ai-usage.js.map +1 -0
- package/packages/mailx-service/ai-usage.ts +110 -0
- package/packages/mailx-service/index.d.ts +6 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +64 -2
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +66 -2
- package/packages/mailx-service/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-83100 → node_modules.npmglobalize-stash-85680}/.package-lock.json +0 -0
package/bin/mailx.ts
CHANGED
|
@@ -425,6 +425,27 @@ if (hasFlag("register-share") || hasFlag("unregister-share")) {
|
|
|
425
425
|
process.exit(r.ok ? 0 : 1);
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
+
// AI spend report. Reads the per-call log written by aiTransform — no daemon
|
|
429
|
+
// needed, no IPC, so it works whether or not rmfmail is running. Bob asked to
|
|
430
|
+
// monitor AI costs (2026-08-11); this is the surface that answers it.
|
|
431
|
+
if (hasFlag("aiusage") || hasFlag("ai-usage")) {
|
|
432
|
+
const { summarizeAiUsage } = await import("@bobfrankston/mailx-service/ai-usage.js");
|
|
433
|
+
const all = summarizeAiUsage(0);
|
|
434
|
+
const mtd = summarizeAiUsage();
|
|
435
|
+
const fmt = (s: typeof all, label: string): void => {
|
|
436
|
+
console.log(`\n${label}: ${s.calls} call(s), ${s.inputTokens} input + ${s.outputTokens} output tokens`);
|
|
437
|
+
console.log(` cost: $${s.costUsd.toFixed(4)}${s.unpricedCalls ? ` (+ ${s.unpricedCalls} call(s) with no published price — tokens counted, cost not)` : ""}`);
|
|
438
|
+
for (const [model, m] of Object.entries(s.byModel)) {
|
|
439
|
+
console.log(` ${model}: ${m.calls} call(s), ${m.inputTokens} in / ${m.outputTokens} out, $${m.costUsd.toFixed(4)}`);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
fmt(mtd, "This month");
|
|
443
|
+
fmt(all, "All time");
|
|
444
|
+
console.log("\nLocal models (ollama) run on this machine and cost $0 — they are counted so the total is measured, not assumed.");
|
|
445
|
+
console.log(`Per-call log: ${path.join(process.env.USERPROFILE || process.env.HOME || ".", ".rmfmail", "logs", "ai-usage.jsonl")}`);
|
|
446
|
+
process.exit(0);
|
|
447
|
+
}
|
|
448
|
+
|
|
428
449
|
// Read our own version once — used for the instance file + upgrade check below.
|
|
429
450
|
const __selfRoot = path.join(import.meta.dirname, "..");
|
|
430
451
|
const __selfVersion: string = (() => {
|
package/client/app.bundle.js
CHANGED
|
@@ -2066,7 +2066,10 @@ async function translateAndShow(text) {
|
|
|
2066
2066
|
if (status)
|
|
2067
2067
|
status.textContent = "";
|
|
2068
2068
|
} else {
|
|
2069
|
-
|
|
2069
|
+
const reason = r.reason || "no result";
|
|
2070
|
+
const isDisabled = /disabled in settings|not configured/i.test(reason);
|
|
2071
|
+
const hint = isDisabled ? "Enable AI translate in Settings \u2192 AI features (off by default)." : /can't reach/i.test(reason) ? "The AI provider isn't answering. Check Settings \u2192 AI features, or start the local model server." : "";
|
|
2072
|
+
body.innerHTML = `<div style="color:var(--muted, #888);">No result.</div><div style="margin-top:8px;font-size:12px;color:var(--muted, #888);">${escapeHtml3(reason)}</div>` + (hint ? `<div style="margin-top:14px;font-size:12px;">${hint}</div>` : "");
|
|
2070
2073
|
if (status)
|
|
2071
2074
|
status.textContent = `Translate: ${r.reason || "no result"}`;
|
|
2072
2075
|
}
|
|
@@ -11957,6 +11960,12 @@ function closeToolbarDropdowns() {
|
|
|
11957
11960
|
if (dd && !dd.hidden) hideDropdownHard(dd);
|
|
11958
11961
|
}
|
|
11959
11962
|
}
|
|
11963
|
+
window.addEventListener("message", (e) => {
|
|
11964
|
+
if (e.data?.type !== "iframePointerDown") return;
|
|
11965
|
+
closeToolbarDropdowns();
|
|
11966
|
+
document.getElementById("rail-menu-backdrop")?.remove();
|
|
11967
|
+
refreshToolbarOverlayShield();
|
|
11968
|
+
});
|
|
11960
11969
|
function refreshToolbarOverlayShield() {
|
|
11961
11970
|
const dropdownOpen = ["settings-dropdown", "view-dropdown", "restart-dropdown"].some((id) => {
|
|
11962
11971
|
const el = document.getElementById(id);
|