@echomem/mcp 1.4.8 → 1.4.10

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 (64) hide show
  1. package/README.md +23 -3
  2. package/assets/canonical-scorer/README.md +18 -0
  3. package/assets/canonical-scorer/analyze-10-problems.mjs +857 -0
  4. package/assets/canonical-scorer/build-session-waste-dashboard.mjs +1628 -0
  5. package/assets/canonical-scorer/golden_anchors.mjs +83 -0
  6. package/assets/canonical-scorer/optimizable_detail.mjs +633 -0
  7. package/assets/hud/github.svg +1 -0
  8. package/dist/city/README.md +9 -0
  9. package/dist/city/echo-ai-city-only.html +1067 -107
  10. package/dist/codex-session-files.js +283 -0
  11. package/dist/codex-sync.js +7 -2
  12. package/dist/context-analysis/canonical-golden.js +47 -0
  13. package/dist/context-analysis/claude-canonical-adapter.js +315 -0
  14. package/dist/context-analysis/claude-native-canonical.js +1216 -0
  15. package/dist/context-analysis/vendored-canonical.js +793 -0
  16. package/dist/context-analysis/workspace-report.js +1838 -0
  17. package/dist/context-metrics/calculate.js +43 -0
  18. package/dist/context-metrics/estimator.js +45 -0
  19. package/dist/context-metrics/ledger.js +507 -0
  20. package/dist/context-metrics/model-limits.js +26 -0
  21. package/dist/context-metrics/parse-claude.js +227 -0
  22. package/dist/context-metrics/parse-codex.js +276 -0
  23. package/dist/context-metrics/types.js +1 -0
  24. package/dist/forensics-10-problems.js +7 -6
  25. package/dist/forensics.js +863 -132
  26. package/dist/hud/adapters.js +77 -202
  27. package/dist/hud/cli.js +0 -0
  28. package/dist/hud/efficiency.js +447 -0
  29. package/dist/hud/electron-main.js +3 -2
  30. package/dist/hud/fs.js +14 -0
  31. package/dist/hud/metric.js +17 -102
  32. package/dist/hud/monitor.js +136 -28
  33. package/dist/hud/render.js +4 -3
  34. package/dist/hud/server.js +30 -0
  35. package/dist/hud/web.js +622 -353
  36. package/dist/index.js +7 -3
  37. package/dist/local-data-paths.js +87 -0
  38. package/dist/migrate.js +37 -29
  39. package/dist/report.js +101 -40
  40. package/dist/setup-page/client-core.js +475 -0
  41. package/dist/setup-page/client-extraction.js +550 -0
  42. package/dist/setup-page/client-lifecycle.js +116 -0
  43. package/dist/setup-page/client-report-audit.js +818 -0
  44. package/dist/setup-page/client-report-city.js +204 -0
  45. package/dist/setup-page/client-report.js +6 -0
  46. package/dist/setup-page/client.js +15 -0
  47. package/dist/setup-page/document.js +37 -0
  48. package/dist/setup-page/styles-city-report.js +880 -0
  49. package/dist/setup-page/styles-context-audit.js +470 -0
  50. package/dist/setup-page/styles-extraction.js +821 -0
  51. package/dist/setup-page/styles-foundation.js +231 -0
  52. package/dist/setup-page/styles.js +11 -0
  53. package/dist/setup-page.js +15 -2538
  54. package/dist/setup-preview.js +245 -0
  55. package/dist/setup.js +456 -44
  56. package/package.json +8 -7
  57. package/templates/echomem-recall.md +2 -2
  58. package/dist/city/10-problems-report.html +0 -649
  59. package/dist/city/_live.html +0 -37
  60. package/dist/city/_serve.mjs +0 -45
  61. package/dist/city/card-data.json +0 -15
  62. package/dist/city/city-data.json +0 -248
  63. package/dist/city/echo-ai-city-only.template.html +0 -1272
  64. package/dist/city/generate-echo-city-only.mjs +0 -112
@@ -1,112 +0,0 @@
1
- #!/usr/bin/env node
2
- // Repo City share-card generator.
3
- // node generate-echo-city-only.mjs → render echo-ai-city-only.html from card-data.json
4
- // node generate-echo-city-only.mjs --refresh → (dev only) re-pull the scalar metrics from
5
- // buildForensicReport() into card-data.json, then render
6
- //
7
- // Pipeline: echo-ai-city-only.template.html + card-data.json → echo-ai-city-only.html
8
- // PURE data→html transform: same card-data.json → same html (no Date.now/random/hidden state).
9
- // The 3-D city geometry + the persona block are still hand-authored design (not yet data-derived) —
10
- // see docs/repo-city-setup-integration-plan.md for the path to rendering any user's scan.
11
-
12
- import fs from "node:fs";
13
- import path from "node:path";
14
- import { fileURLToPath } from "node:url";
15
-
16
- const DIR = path.dirname(fileURLToPath(import.meta.url));
17
- const CARD = path.join(DIR, "card-data.json");
18
- const TPL = path.join(DIR, "echo-ai-city-only.template.html");
19
- const OUT = path.join(DIR, "echo-ai-city-only.html");
20
-
21
- const MONTHS = ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"];
22
- // fail-loud: a null/invalid date must throw, not silently bake "JAN 1" / "undefined NaN".
23
- // (new Date(null) === epoch, a *valid* date → "JAN 1", so null must be rejected before the Date.)
24
- const fmtDate = (iso) => {
25
- if (iso == null) throw new Error(`fmtDate: missing date (${iso})`);
26
- const d = new Date(iso);
27
- if (Number.isNaN(d.getTime())) throw new Error(`fmtDate: invalid date ${JSON.stringify(iso)}`);
28
- return `${MONTHS[d.getUTCMonth()]} ${d.getUTCDate()}`;
29
- };
30
-
31
- async function refresh(card) {
32
- // DEV-ONLY CLI: re-pull the scalar metrics from the live forensic report on this machine.
33
- // The persona block (primary/rank/rhythm/sides/verdict) is hand-authored design, not in the
34
- // report, so it is left untouched here. (For the setup web flow this whole path is replaced by a
35
- // pure renderFromReport(r) that derives every field — see the integration plan doc.)
36
- const { buildForensicReport } = await import("../packages/mcp-server/dist/forensics.js");
37
- const r = buildForensicReport();
38
-
39
- // Classify each model's tokens into the Codex/Claude split. Fail loud on an unrecognized
40
- // provider instead of silently dumping it into the Claude bucket.
41
- let codexTok = 0, claudeTok = 0;
42
- for (const [model, v] of Object.entries(r.cost?.byModel || {})) {
43
- const tok = v.total || 0;
44
- if (/claude|opus|sonnet|haiku|anthropic/i.test(model)) claudeTok += tok;
45
- else if (/gpt|codex|openai|o\d/i.test(model)) codexTok += tok;
46
- else throw new Error(`refresh: unrecognized model provider ${JSON.stringify(model)} — cannot classify the Codex/Claude split`);
47
- }
48
- const totTok = codexTok + claudeTok || 1;
49
- const codexPct = Math.round(codexTok / totTok * 100); // derive the other so they always sum to 100
50
-
51
- card.computeCost = "$" + Math.round(r.cost.total).toLocaleString("en-US");
52
- card.attentionHours = Number(r.userWorkingHours?.userAttentionHours ?? 0).toFixed(1);
53
- card.split = { codexPct, claudePct: 100 - codexPct };
54
- card.dirty = { pct: Number(r.cleanliness.staleReadSharePct).toFixed(1) };
55
- if (r.counterfactual) {
56
- card.counterfactual = {
57
- ...card.counterfactual,
58
- reachDate: fmtDate(r.counterfactual.counterfactualDate),
59
- daysEarlier: Math.round(r.counterfactual.daysGained),
60
- };
61
- }
62
- fs.writeFileSync(CARD, JSON.stringify(card, null, 2) + "\n");
63
- console.log("↻ refreshed card-data.json from buildForensicReport()");
64
- return card;
65
- }
66
-
67
- const card = JSON.parse(fs.readFileSync(CARD, "utf8"));
68
- if (process.argv.includes("--refresh")) await refresh(card);
69
-
70
- const personaVerdict = card.persona.verdict;
71
-
72
- // "Jun 2" → month "JUN", day "2" for the counterfactual calendar icon. Guard the shape.
73
- const reachParts = String(card.counterfactual.reachDate).trim().split(/\s+/);
74
- if (reachParts.length !== 2) {
75
- throw new Error(`counterfactual.reachDate must be "MON DD", got ${JSON.stringify(card.counterfactual.reachDate)}`);
76
- }
77
- const [cfReachMonth, cfReachDay] = reachParts;
78
-
79
- // Coding Persona Card: side-trait chips (uniform — palette is limited to ink + the one red 85%).
80
- const personaSides = card.persona.sides
81
- .map((s) => `<span class="ct">${s}</span>`)
82
- .join("");
83
-
84
- // Exactly the tokens the template substitutes — nothing more (orphans are a static-analysis defect).
85
- const tokens = {
86
- computeCost: card.computeCost,
87
- attentionHours: card.attentionHours,
88
- codexPct: card.split.codexPct,
89
- claudePct: card.split.claudePct,
90
- personaPrimary: card.persona.primary,
91
- personaRankRhythm: `${card.persona.rank} · ${card.persona.rhythm}`,
92
- personaSides,
93
- personaVerdict,
94
- dirtyPct: card.dirty.pct,
95
- cfReachMonth: cfReachMonth.toUpperCase(),
96
- cfReachDay,
97
- cfReachDate: card.counterfactual.reachDate,
98
- cfInsteadOf: card.counterfactual.insteadOf,
99
- cfDaysEarlier: card.counterfactual.daysEarlier,
100
- };
101
-
102
- // Substitute {{token}}. The detector matches ANY {{...}} (not just \w+) so a malformed placeholder
103
- // can't slip through the fail-loud guard.
104
- const template = fs.readFileSync(TPL, "utf8");
105
- const html = template.replace(/\{\{([^}]+)\}\}/g, (_, raw) => {
106
- const key = raw.trim();
107
- if (!(key in tokens)) throw new Error(`Unknown template token: {{${key}}}`);
108
- return String(tokens[key]);
109
- });
110
-
111
- fs.writeFileSync(OUT, html);
112
- console.log("✓ wrote", path.relative(process.cwd(), OUT));