@monoes/monomindcli 2.7.12 → 2.7.13

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.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/orgrt/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/orgrt/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,4FAA4F;AAC5F,eAAO,MAAM,cAAc;;;;;;;;;;;kBAOhB,CAAC;AAEZ,eAAO,MAAM,gBAAgB;;;;;;;iBASH,CAAC;AAE3B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiBP,CAAC;AAEjB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAeT,CAAC;AAEjB,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AACjD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,mGAAmG;AACnG,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;IACjG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,OAAO,mBAAmB,CAAC"}
@@ -3672,8 +3672,8 @@ async function renderSessions() {
3672
3672
  function renderSessRow(s, idx) {
3673
3673
  const dur = s.totalDurationMs ? fmtDur(s.totalDurationMs) : '';
3674
3674
  const msgs = s.totalMessages ? s.totalMessages + ' msg' : '';
3675
- const cost = typeof s.totalCost === 'number' ? '$' + s.totalCost.toFixed(2)
3676
- : typeof s.cost === 'number' ? '$' + s.cost.toFixed(2) : '';
3675
+ const cost = typeof s.totalCost === 'number' ? fmtCost(s.totalCost, s.costIncomplete)
3676
+ : typeof s.cost === 'number' ? fmtCost(s.cost, s.costIncomplete) : '';
3677
3677
  const meta = [dur, msgs, cost].filter(Boolean).join(' · ') || s.id.slice(0, 16);
3678
3678
  const sCost = s.totalCost || 0;
3679
3679
  let anomBadge = '';
@@ -3890,7 +3890,7 @@ function buildRecap(events, sess) {
3890
3890
  const topCat = Object.entries(cats).sort((a, b) => b[1] - a[1])[0];
3891
3891
  const topPct = topCat ? Math.round(topCat[1] / tools.length * 100) : 0;
3892
3892
 
3893
- const costStr = sess?.totalCost != null ? '$' + sess.totalCost.toFixed(2) : (sess?.cost != null ? '$' + sess.cost.toFixed(2) : null);
3893
+ const costStr = sess?.totalCost != null ? fmtCost(sess.totalCost, sess.costIncomplete) : (sess?.cost != null ? fmtCost(sess.cost, sess.costIncomplete) : null);
3894
3894
 
3895
3895
  const stats = [
3896
3896
  tools.length ? `<span class="recap-stat rs-tool">${tools.length} tool calls${topCat ? ' · ' + topPct + '% ' + topCat[0] : ''}</span>` : '',
@@ -4074,7 +4074,7 @@ async function renderGlobalFeed() {
4074
4074
  el.innerHTML = '<div class="sess-list">' + entries.map(({ project, session: s }) => {
4075
4075
  const projName = project.name || project.slug || project.path?.split('/').pop() || '?';
4076
4076
  const dur = s.totalDurationMs ? fmtDur(s.totalDurationMs) : '';
4077
- const cost = typeof s.totalCost === 'number' ? '$' + s.totalCost.toFixed(2) : '';
4077
+ const cost = typeof s.totalCost === 'number' ? fmtCost(s.totalCost, s.costIncomplete) : '';
4078
4078
  const meta = [dur, cost].filter(Boolean).join(' · ') || s.id.slice(0, 12);
4079
4079
  const gfCompactBadge = (s.compactCount > 0)
4080
4080
  ? `<span class="sr-compact-badge">+${s.compactCount} compacted</span>`
@@ -4653,7 +4653,7 @@ function renderLeaderboard() {
4653
4653
  const body = document.getElementById('lb-body');
4654
4654
  if (!sorted.length) { body.innerHTML = '<tr><td colspan="4" style="text-align:center;color:var(--text-xs);padding:12px">No cost data yet</td></tr>'; return; }
4655
4655
  body.innerHTML = sorted.map((s, i) => {
4656
- const cost = '$' + s.totalCost.toFixed(2);
4656
+ const cost = fmtCost(s.totalCost, s.costIncomplete);
4657
4657
  const dur = s.totalDurationMs ? fmtDur(s.totalDurationMs) : '—';
4658
4658
  const prompt = s.lastPrompt || s.id;
4659
4659
  return `<tr onclick="jumpToSession('${esc(String(s.id).replace(/['\\]/g,'\\$&'))}')" title="${esc(prompt)}">
@@ -4741,7 +4741,7 @@ function renderDiff() {
4741
4741
  };
4742
4742
 
4743
4743
  const diffCol = (s) => {
4744
- const cost = typeof s.totalCost === 'number' ? '$' + s.totalCost.toFixed(2) : '—';
4744
+ const cost = typeof s.totalCost === 'number' ? fmtCost(s.totalCost, s.costIncomplete) : '—';
4745
4745
  const dur = s.totalDurationMs ? fmtDur(s.totalDurationMs) : '—';
4746
4746
  const tools = s.toolCalls != null ? s.toolCalls : '—';
4747
4747
  const msgs = s.userMessages != null ? s.userMessages : '—';
@@ -4782,7 +4782,7 @@ async function exportSession() {
4782
4782
  const lines = [
4783
4783
  `# Session: ${sess.lastPrompt || sess.id}`,
4784
4784
  `> ${new Date(sess.lastTs || sess.mtime).toLocaleString()}`,
4785
- sess.totalCost != null ? `> Cost: $${sess.totalCost.toFixed(2)}` : '',
4785
+ sess.totalCost != null ? `> Cost: ${fmtCost(sess.totalCost, sess.costIncomplete)}` : '',
4786
4786
  sess.totalDurationMs ? `> Duration: ${fmtDur(sess.totalDurationMs)}` : '',
4787
4787
  '',
4788
4788
  ].filter(s => s !== null);
@@ -9930,7 +9930,7 @@ function bulkExport() {
9930
9930
  const headers = ['Date', 'Session ID', 'Prompt', 'Cost ($)', 'Duration (s)', 'Tool Calls', 'Files Touched'];
9931
9931
  const rows = toExport.map(s => {
9932
9932
  const dt = new Date(s.firstTs || s.mtime || 0).toISOString().slice(0, 19).replace('T', ' ');
9933
- const cost = typeof s.totalCost === 'number' ? s.totalCost.toFixed(4) : '';
9933
+ const cost = typeof s.totalCost === 'number' && !(s.costIncomplete && !s.totalCost) ? s.totalCost.toFixed(4) : '';
9934
9934
  const dur = s.totalDurationMs ? Math.round(s.totalDurationMs / 1000) : '';
9935
9935
  const prompt = (s.lastPrompt || '').replace(/"/g, '""');
9936
9936
  const files = (s.filesTouched || []).join(';');
@@ -9975,7 +9975,7 @@ function buildTokenVelocity() {
9975
9975
  const periodLabel = { day:'24h', week:'7d', month:'30d', all:'all time' }[activePeriod] || '24h';
9976
9976
  el.innerHTML = `<div class="m-group-title">Token Velocity <span style="font-size:10px;color:var(--text-xs);font-weight:400">${periodLabel} · ${fmt(totalTok)}</span></div>
9977
9977
  <div id="vel-chart">${bars}</div>
9978
- <div style="font-size:10px;color:var(--text-xs);margin-top:4px">Cost <span style="color:oklch(78% 0.18 75)">$${totalCost.toFixed(2)}</span> <span style="color:var(--text-xs)">· ${filtered.length} sessions</span></div>`;
9978
+ <div style="font-size:10px;color:var(--text-xs);margin-top:4px">Cost <span style="color:oklch(78% 0.18 75)">${fmtCost(totalCost, anyCostIncomplete(filtered))}</span> <span style="color:var(--text-xs)">· ${filtered.length} sessions</span></div>`;
9979
9979
  }
9980
9980
 
9981
9981
  // ── feature 27: export sessions CSV ───────────────────────
@@ -9984,7 +9984,7 @@ function exportSessionsCSV() {
9984
9984
  const headers = ['Date', 'Session ID', 'Prompt', 'Cost ($)', 'Duration (s)', 'Tool Calls', 'User Messages', 'Cache Hit %', 'Input Tokens'];
9985
9985
  const rows = allSessions.map(s => {
9986
9986
  const dt = new Date(s.firstTs || s.mtime || 0).toISOString().slice(0, 19).replace('T', ' ');
9987
- const cost = typeof s.totalCost === 'number' ? s.totalCost.toFixed(4) : '';
9987
+ const cost = typeof s.totalCost === 'number' && !(s.costIncomplete && !s.totalCost) ? s.totalCost.toFixed(4) : '';
9988
9988
  const dur = s.totalDurationMs ? Math.round(s.totalDurationMs / 1000) : '';
9989
9989
  const cachePct = s.totalInputTokens > 0 ? Math.round((s.cacheReadTokens || 0) / s.totalInputTokens * 100) : '';
9990
9990
  const prompt = (s.lastPrompt || '').replace(/"/g, '""');
@@ -10171,7 +10171,7 @@ function showReportCard() {
10171
10171
  const anomalies = sessions.filter(s => (s.totalCost||0) > median * 3 && (s.totalCost||0) > 0.5).map(s => ` - ${s.lastPrompt?.slice(0,50)||s.id}: $${(s.totalCost||0).toFixed(2)}`).join('\n');
10172
10172
  return `### ${label}
10173
10173
  - Sessions: ${sessions.length}
10174
- - Total cost: $${totalCost.toFixed(3)}
10174
+ - Total cost: ${fmtCost(totalCost, anyCostIncomplete(sessions), 3)}
10175
10175
  - Total duration: ${fmtDur(totalDur)}
10176
10176
  - Tool calls: ${totalTools}${totalErrs ? ` (${totalErrs} errors)` : ''}
10177
10177
  ${topFiles ? `\nTop files touched:\n${topFiles}` : ''}${anomalies ? `\n\nCost anomalies:\n${anomalies}` : ''}
@@ -10308,9 +10308,8 @@ function showCostExplainer(sessId, event) {
10308
10308
  .map(([m,d])=>`<div class="err-item">${esc(m.replace(/^claude-/,'').replace(/-\d{8}$/,''))}: ${d.unknownPricing ? 'unknown (no pricing data)' : '$'+(d.cost||0).toFixed(4)} · ${d.calls||0} calls</div>`).join('');
10309
10309
  // costIncomplete => the server could not price at least one model, so the
10310
10310
  // session total is a floor, not the actual spend.
10311
- const costPrefix = sess.costIncomplete ? '≥' : '';
10312
- drawer.innerHTML = `<div class="err-drawer-head" style="color:oklch(70% 0.18 80)">
10313
- <span>Cost anomaly — ${costPrefix}$${(sess.totalCost||0).toFixed(3)} (${ratio}× median, top ${100-pct}%)</span>
10311
+ drawer.innerHTML = `<div class="err-drawer-head" style="color:oklch(70% 0.18 80)">
10312
+ <span>Cost anomaly — ${fmtCost(sess.totalCost, sess.costIncomplete, 3)} (${ratio}× median, top ${100-pct}%)</span>
10314
10313
  <button class="err-close" onclick="this.closest('.err-drawer').classList.remove('open');this.closest('.err-drawer').innerHTML=''">✕</button>
10315
10314
  </div>
10316
10315
  <div class="err-drawer-body">
@@ -10341,7 +10340,7 @@ function buildDailyCostTrend() {
10341
10340
  const label = i === 29 ? 'Today' : (i === 28 ? 'Yday' : '');
10342
10341
  return `<div class="dt-bar${isActive ? ' active' : ''}" style="height:${h}px" title="${dates[i]}: $${v.toFixed(3)}" onclick="setDailyTrendFilter('${dates[i]}',${v})"></div>`;
10343
10342
  }).join('');
10344
- el.innerHTML = `<div class="m-group-title">30-Day Cost <span style="font-size:10px;color:var(--text-xs);font-weight:400">$${totalCost.toFixed(2)} total</span></div>
10343
+ el.innerHTML = `<div class="m-group-title">30-Day Cost <span style="font-size:10px;color:var(--text-xs);font-weight:400">${fmtCost(totalCost, anyCostIncomplete(allSessions))} total</span></div>
10345
10344
  <div id="daily-trend-chart">${bars}</div>
10346
10345
  <div style="display:flex;justify-content:space-between;font-size:9px;color:var(--text-xs);margin-top:2px"><span>30d ago</span><span>Today</span></div>`;
10347
10346
  }
@@ -10590,6 +10589,36 @@ function restoreURLParams() {
10590
10589
  }
10591
10590
 
10592
10591
  // ── helpers ────────────────────────────────────────────────
10592
+
10593
+ /**
10594
+ * Render a session cost honestly.
10595
+ *
10596
+ * The server sets costIncomplete when at least one model had no pricing row,
10597
+ * and documents totalCost as a LOWER BOUND in that case — the unpriced model's
10598
+ * spend is missing from the sum entirely. Only one of the ~20 cost renderings
10599
+ * in this file honoured that; the rest printed the number as though it were
10600
+ * exact.
10601
+ *
10602
+ * The bad case is when NOTHING could be priced: the sum stays 0, and the UI
10603
+ * confidently reported "$0.00 spent" for a session that may have cost real
10604
+ * money. A fabricated zero is worse than an admitted unknown, so:
10605
+ *
10606
+ * priced, complete -> "$1.23"
10607
+ * priced, incomplete -> "≥$1.23" (a floor, and says so)
10608
+ * nothing priced -> "unpriced" (no number at all)
10609
+ */
10610
+ function fmtCost(value, incomplete, digits) {
10611
+ const amount = Number(value) || 0;
10612
+ const dp = typeof digits === 'number' ? digits : 2;
10613
+ if (incomplete && amount === 0) return 'unpriced';
10614
+ return (incomplete ? '≥' : '') + '$' + amount.toFixed(dp);
10615
+ }
10616
+
10617
+ /** True if any session in the list carries an unpriced model. */
10618
+ function anyCostIncomplete(sessions) {
10619
+ return (sessions || []).some(s => s && s.costIncomplete);
10620
+ }
10621
+
10593
10622
  function enc(s) { return encodeURIComponent(s); }
10594
10623
  function esc(s) {
10595
10624
  return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');