@bobfrankston/rmfmail 1.2.250 → 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/check-bridge-contract.mjs +9 -1
- 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/client/lib/mailxapi.js +12 -0
- package/package.json +5 -5
- 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-52956 → node_modules.npmglobalize-stash-85680}/.package-lock.json +0 -0
|
@@ -29,7 +29,15 @@ const bridge = read("client/lib/mailxapi.js");
|
|
|
29
29
|
const rpc = read("packages/mailx-service/jsonrpc.ts");
|
|
30
30
|
|
|
31
31
|
const called = new Set();
|
|
32
|
-
|
|
32
|
+
// Match every shape api-client uses to reach the bridge:
|
|
33
|
+
// ipc().foo?.(…) plain
|
|
34
|
+
// (ipc() as any).foo?.(…) cast — the old pattern required a literal
|
|
35
|
+
// "ipc()." and skipped ALL of these
|
|
36
|
+
// const fn = (ipc() as any).foo; captured first, called later
|
|
37
|
+
// Hence: no trailing "(" requirement — a property read off the bridge is
|
|
38
|
+
// a call site as far as this contract is concerned. fetchRemoteImage was
|
|
39
|
+
// invisible to the old regex on both counts (Bob 2026-08-11).
|
|
40
|
+
for (const m of api.matchAll(/ipc\(\)(?:\s+as\s+[\w.<>[\]]+)?\s*\)?\.(\w+)/g)) called.add(m[1]);
|
|
33
41
|
|
|
34
42
|
const inBridge = new Set();
|
|
35
43
|
for (const m of bridge.matchAll(/^\s+(\w+)\s*:\s*(?:async\s+)?function/gm)) inBridge.add(m[1]);
|
package/bin/mailx.js
CHANGED
|
@@ -448,6 +448,26 @@ if (hasFlag("register-share") || hasFlag("unregister-share")) {
|
|
|
448
448
|
console.log(r.message);
|
|
449
449
|
process.exit(r.ok ? 0 : 1);
|
|
450
450
|
}
|
|
451
|
+
// AI spend report. Reads the per-call log written by aiTransform — no daemon
|
|
452
|
+
// needed, no IPC, so it works whether or not rmfmail is running. Bob asked to
|
|
453
|
+
// monitor AI costs (2026-08-11); this is the surface that answers it.
|
|
454
|
+
if (hasFlag("aiusage") || hasFlag("ai-usage")) {
|
|
455
|
+
const { summarizeAiUsage } = await import("@bobfrankston/mailx-service/ai-usage.js");
|
|
456
|
+
const all = summarizeAiUsage(0);
|
|
457
|
+
const mtd = summarizeAiUsage();
|
|
458
|
+
const fmt = (s, label) => {
|
|
459
|
+
console.log(`\n${label}: ${s.calls} call(s), ${s.inputTokens} input + ${s.outputTokens} output tokens`);
|
|
460
|
+
console.log(` cost: $${s.costUsd.toFixed(4)}${s.unpricedCalls ? ` (+ ${s.unpricedCalls} call(s) with no published price — tokens counted, cost not)` : ""}`);
|
|
461
|
+
for (const [model, m] of Object.entries(s.byModel)) {
|
|
462
|
+
console.log(` ${model}: ${m.calls} call(s), ${m.inputTokens} in / ${m.outputTokens} out, $${m.costUsd.toFixed(4)}`);
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
fmt(mtd, "This month");
|
|
466
|
+
fmt(all, "All time");
|
|
467
|
+
console.log("\nLocal models (ollama) run on this machine and cost $0 — they are counted so the total is measured, not assumed.");
|
|
468
|
+
console.log(`Per-call log: ${path.join(process.env.USERPROFILE || process.env.HOME || ".", ".rmfmail", "logs", "ai-usage.jsonl")}`);
|
|
469
|
+
process.exit(0);
|
|
470
|
+
}
|
|
451
471
|
// Read our own version once — used for the instance file + upgrade check below.
|
|
452
472
|
const __selfRoot = path.join(import.meta.dirname, "..");
|
|
453
473
|
const __selfVersion = (() => {
|