sigrank 0.0.215 → 0.0.217
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/manifest.json +1 -1
- package/package.json +1 -1
- package/presentation/tui-themes.mjs +63 -0
- package/presentation/tui.mjs +96 -45
package/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/anthropics/mcpb/main/schemas/mcpb-manifest-v0.4.schema.json",
|
|
3
3
|
"manifest_version": "0.4",
|
|
4
4
|
"name": "sigrank",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.216",
|
|
6
6
|
"description": "Ranks AI coding operators by token cascade efficiency (Yield = cache_read \u00d7 output / input\u00b2). 23 tools for yield calculation, local token usage pulls, signed submission, and tokscale-powered analytics (market share, developer profiles, model trends, cost analysis, device profiles, MCP usage, competitive intelligence). Privacy-first: runs locally, only four token counts leave the machine.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "SunrisesIllNeverSee",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigrank",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.217",
|
|
4
4
|
"author": "SunrisesIllNeverSee (https://github.com/SunrisesIllNeverSee)",
|
|
5
5
|
"description": "SigRank MCP server — AI operator evaluation and token cascade efficiency tools. The yield cascade + live leaderboard as MCP tools any agent can call.",
|
|
6
6
|
"mcpName": "io.github.SunrisesIllNeverSee/sigrank-mcp",
|
|
@@ -124,3 +124,66 @@ export function setTheme(name) {
|
|
|
124
124
|
export function getThemeNames() {
|
|
125
125
|
return Object.keys(THEMES);
|
|
126
126
|
}
|
|
127
|
+
|
|
128
|
+
// ── Platform color map ─────────────────────────────────────────────────────
|
|
129
|
+
// Each platform gets a distinct 256-color code so platforms are visually
|
|
130
|
+
// distinguishable in the cascade table, token composition bars, board, and
|
|
131
|
+
// watch tabs. The colors are chosen for distinguishability on dark terminals
|
|
132
|
+
// (the default theme). For light theme, darker 256-color variants are used.
|
|
133
|
+
// Monochrome theme returns no color (bold only) — colorblind-safe.
|
|
134
|
+
//
|
|
135
|
+
// Color assignments (dark theme 256-color codes):
|
|
136
|
+
// claude = 75 (blue-cyan)
|
|
137
|
+
// codex = 114 (green)
|
|
138
|
+
// amp = 179 (orange)
|
|
139
|
+
// gemini = 129 (purple-magenta)
|
|
140
|
+
// kimi = 213 (pink)
|
|
141
|
+
// qwen = 68 (steel blue)
|
|
142
|
+
// goose = 142 (olive)
|
|
143
|
+
// kilo = 166 (dark orange)
|
|
144
|
+
// hermes = 96 (plum)
|
|
145
|
+
// droid = 167 (salmon)
|
|
146
|
+
// codebuff = 72 (teal-green)
|
|
147
|
+
// copilot = 33 (bright blue)
|
|
148
|
+
// openclaw = 136 (gold-brown)
|
|
149
|
+
// pi = 177 (light purple)
|
|
150
|
+
// omp = 220 (gold — the "oh my pi" platform gets gold)
|
|
151
|
+
// opencode = 60 (slate)
|
|
152
|
+
// devin = 30 (teal)
|
|
153
|
+
// proxy = 245 (gray — synthetic passthrough)
|
|
154
|
+
// other = 245 (gray — catch-all)
|
|
155
|
+
|
|
156
|
+
const PLATFORM_COLORS_DARK = {
|
|
157
|
+
claude: 75, codex: 114, amp: 179, gemini: 129, kimi: 213,
|
|
158
|
+
qwen: 68, goose: 142, kilo: 166, hermes: 96, droid: 167,
|
|
159
|
+
codebuff: 72, copilot: 33, openclaw: 136, pi: 177, omp: 220,
|
|
160
|
+
opencode: 60, devin: 30, proxy: 245, other: 245,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Light theme: darker shades of the same hues for contrast on white
|
|
164
|
+
const PLATFORM_COLORS_LIGHT = {
|
|
165
|
+
claude: 24, codex: 28, amp: 130, gemini: 54, kimi: 90,
|
|
166
|
+
qwen: 19, goose: 100, kilo: 130, hermes: 54, droid: 124,
|
|
167
|
+
codebuff: 23, copilot: 19, openclaw: 130, pi: 90, omp: 130,
|
|
168
|
+
opencode: 19, devin: 23, proxy: 242, other: 242,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Returns a paint function for the given platform name, theme-aware.
|
|
173
|
+
* Usage: `const pc = platformColor("claude"); pc("claude")` → colored string.
|
|
174
|
+
* Falls back to the theme's cyan for unknown platforms.
|
|
175
|
+
*/
|
|
176
|
+
export function platformColor(platform) {
|
|
177
|
+
const themeName = currentTheme.name;
|
|
178
|
+
// Monochrome: no color, just bold (colorblind-safe)
|
|
179
|
+
if (themeName === "monochrome") {
|
|
180
|
+
return (s) => `${currentTheme.bold}${s}${currentTheme.reset}`;
|
|
181
|
+
}
|
|
182
|
+
const map = themeName === "light" ? PLATFORM_COLORS_LIGHT : PLATFORM_COLORS_DARK;
|
|
183
|
+
const code = map[platform];
|
|
184
|
+
if (code == null) {
|
|
185
|
+
// Unknown platform — fall back to cyan
|
|
186
|
+
return (s) => `${currentTheme.cyan}${s}${currentTheme.reset}`;
|
|
187
|
+
}
|
|
188
|
+
return (s) => `${ESC}38;5;${code}m${s}${currentTheme.reset}`;
|
|
189
|
+
}
|
package/presentation/tui.mjs
CHANGED
|
@@ -54,6 +54,7 @@ export function dashboardEnabledPlatforms({
|
|
|
54
54
|
// The `c` object is a live proxy to the current theme — changing the theme
|
|
55
55
|
// via setTheme() updates all colors. Supports dark/light/high-contrast/monochrome.
|
|
56
56
|
import * as _themeMod from "./tui-themes.mjs";
|
|
57
|
+
import { platformColor } from "./tui-themes.mjs";
|
|
57
58
|
const ESC = "\x1b[";
|
|
58
59
|
// `c` is a live proxy — reads currentTheme at access time so theme switches
|
|
59
60
|
// take effect immediately. The helper functions below (paint/bold/dim/etc.)
|
|
@@ -477,13 +478,18 @@ const TABS = [
|
|
|
477
478
|
{ key: "6", label: "Connect", short: "N" }, // sign in / switch device — the whole app is the TUI
|
|
478
479
|
];
|
|
479
480
|
|
|
480
|
-
//
|
|
481
|
-
//
|
|
482
|
-
//
|
|
481
|
+
// Four Degrees of Leverage — reference values matching signalaf.com/wiki/four-degrees.
|
|
482
|
+
// base = AA baseline (7:2:1 modeled reference, static)
|
|
483
|
+
// hcm = Human Center of Mass (median of all real operators)
|
|
484
|
+
// power = Power users (median of top 100 real operators)
|
|
485
|
+
// top = Top Evals (single top real operator)
|
|
486
|
+
// STATIC fallback values match the web app's GoldColumn fallbacks (lib/marketing/top-operator-column.ts).
|
|
487
|
+
// Goes live (hcm/power/top computed from the board) once there's real user volume.
|
|
483
488
|
const TD = {
|
|
484
|
-
base:
|
|
485
|
-
|
|
486
|
-
|
|
489
|
+
base: { yield: 1.75, snr: 0.33, vel: 0.50, lev: 3.5, d10: 0.54 },
|
|
490
|
+
hcm: { yield: 1.57, snr: 0.33, vel: 0.50, lev: 3.2, d10: 0.50 },
|
|
491
|
+
power: { yield: 1.51, snr: 0.07, vel: 0.08, lev: 22.3, d10: 1.35 },
|
|
492
|
+
top: { yield: 488.65, snr: 0.58, vel: 1.36, lev: 360.2, d10: 2.56 },
|
|
487
493
|
};
|
|
488
494
|
|
|
489
495
|
function renderTabBar(activeIdx) {
|
|
@@ -737,8 +743,8 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
737
743
|
// which is what was starving codex's cascade rows after the Your-Read/Three-Degrees panels landed.)
|
|
738
744
|
const platformCount = active.length;
|
|
739
745
|
const barLines = 4 + platformCount + (platformCount > 1 ? 1 : 0); // Token Composition: hr + header + platforms + combined + note
|
|
740
|
-
// Your Read (hr+header
|
|
741
|
-
const boardLines =
|
|
746
|
+
// Your Read (hr+header+up to 4 wins+up to 5 gaps+summary = 13) + Four Degrees (blank+hr+header+col-header+5 rows+note = 10) + status
|
|
747
|
+
const boardLines = 20;
|
|
742
748
|
const sectionsBelow = barLines + boardLines;
|
|
743
749
|
const maxCascadeRows = Math.max(8, budget - used - sectionsBelow);
|
|
744
750
|
|
|
@@ -789,7 +795,10 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
789
795
|
if (lastPlatform !== null && row.platform !== lastPlatform) emit();
|
|
790
796
|
renderRow(
|
|
791
797
|
row.platform,
|
|
792
|
-
(s) =>
|
|
798
|
+
(s) => {
|
|
799
|
+
const pc = platformColor(row.platform);
|
|
800
|
+
return row.winKey === firstWin[row.platform] ? bold(pc(s)) : dim(s);
|
|
801
|
+
},
|
|
793
802
|
row.winKey,
|
|
794
803
|
row.pillars,
|
|
795
804
|
row.estimated,
|
|
@@ -843,7 +852,7 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
843
852
|
const all = d.windows?.find((w) => w.window === "all");
|
|
844
853
|
if (!all) continue;
|
|
845
854
|
emit(
|
|
846
|
-
` ${padEnd(
|
|
855
|
+
` ${padEnd(platformColor(d.platform)(d.platform), 10)} ${tokenBar(all.pillars, 50)} ${dim(fmtTok((all.pillars.input ?? 0) + (all.pillars.output ?? 0) + (all.pillars.cacheCreate ?? 0) + (all.pillars.cacheRead ?? 0)))}`,
|
|
847
856
|
);
|
|
848
857
|
}
|
|
849
858
|
if (active.length > 1) {
|
|
@@ -886,9 +895,9 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
886
895
|
}
|
|
887
896
|
}
|
|
888
897
|
|
|
889
|
-
// ── Your insights + the
|
|
898
|
+
// ── Your insights + the Four Degrees panel (replaces the old top-3 mini board)
|
|
890
899
|
// The user's own cascade (the firstWin/combined row computed above) read against the
|
|
891
|
-
//
|
|
900
|
+
// Four Degrees reference so the Dashboard says "here's you, here's the field, here's the ceiling."
|
|
892
901
|
const you = (() => {
|
|
893
902
|
// Best available cascade for the user: prefer claude's first-window, else any computed row.
|
|
894
903
|
for (const d of active) {
|
|
@@ -914,24 +923,38 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
914
923
|
if (you) {
|
|
915
924
|
const wins = [],
|
|
916
925
|
gaps = [];
|
|
917
|
-
|
|
926
|
+
let aboveHcm = 0,
|
|
927
|
+
abovePower = 0,
|
|
928
|
+
totalMetrics = 0;
|
|
929
|
+
// Three-tier comparison: HCM (field median) → Power (top-100 median) → Top (best operator)
|
|
930
|
+
const chk = (label, val, hcm, power, top, fmt, tip) => {
|
|
918
931
|
if (val == null) return;
|
|
919
|
-
|
|
932
|
+
totalMetrics++;
|
|
933
|
+
if (val >= top * 0.9) {
|
|
920
934
|
wins.push(`${label} ${fmt(val)} — ${gold("top tier")}`);
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
else
|
|
935
|
+
aboveHcm++;
|
|
936
|
+
abovePower++;
|
|
937
|
+
} else if (val >= power) {
|
|
938
|
+
wins.push(`${label} ${fmt(val)} — ${paint(c.boldCyan, "power-user tier")}`);
|
|
939
|
+
aboveHcm++;
|
|
940
|
+
abovePower++;
|
|
941
|
+
} else if (val >= hcm) {
|
|
942
|
+
wins.push(`${label} ${fmt(val)} — above field, ${dim("approaching power-user")}`);
|
|
943
|
+
aboveHcm++;
|
|
944
|
+
} else {
|
|
924
945
|
gaps.push({
|
|
925
946
|
label,
|
|
926
|
-
txt: `${label} ${fmt(val)} — below field (${fmt(
|
|
947
|
+
txt: `${label} ${fmt(val)} — below field (${fmt(hcm)}): ${tip}`,
|
|
927
948
|
val,
|
|
928
|
-
|
|
949
|
+
hcm,
|
|
929
950
|
});
|
|
951
|
+
}
|
|
930
952
|
};
|
|
931
953
|
chk(
|
|
932
954
|
"Υ Yield",
|
|
933
955
|
you.yield,
|
|
934
|
-
TD.
|
|
956
|
+
TD.hcm.yield,
|
|
957
|
+
TD.power.yield,
|
|
935
958
|
TD.top.yield,
|
|
936
959
|
fmtY,
|
|
937
960
|
"compound more — reuse cache, raise output",
|
|
@@ -939,7 +962,8 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
939
962
|
chk(
|
|
940
963
|
"SNR",
|
|
941
964
|
you.snr,
|
|
942
|
-
TD.
|
|
965
|
+
TD.hcm.snr,
|
|
966
|
+
TD.power.snr,
|
|
943
967
|
TD.top.snr,
|
|
944
968
|
fmtSNR,
|
|
945
969
|
"tighten prompts — less input per unit output",
|
|
@@ -947,7 +971,8 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
947
971
|
chk(
|
|
948
972
|
"Leverage",
|
|
949
973
|
you.leverage,
|
|
950
|
-
TD.
|
|
974
|
+
TD.hcm.lev,
|
|
975
|
+
TD.power.lev,
|
|
951
976
|
TD.top.lev,
|
|
952
977
|
(v) => fmtLev(v) + "×",
|
|
953
978
|
"lean on cache-read — amplify prior context",
|
|
@@ -955,55 +980,80 @@ function renderDashboard(data, status = "", scrollOffset = 0) {
|
|
|
955
980
|
chk(
|
|
956
981
|
"Velocity",
|
|
957
982
|
you.velocity,
|
|
958
|
-
TD.
|
|
983
|
+
TD.hcm.vel,
|
|
984
|
+
TD.power.vel,
|
|
959
985
|
TD.top.vel,
|
|
960
986
|
(v) => v.toFixed(2),
|
|
961
987
|
"more output per input token",
|
|
962
988
|
);
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
989
|
+
chk(
|
|
990
|
+
"10xDEV",
|
|
991
|
+
you.dev10x,
|
|
992
|
+
TD.hcm.d10,
|
|
993
|
+
TD.power.d10,
|
|
994
|
+
TD.top.d10,
|
|
995
|
+
(v) => v.toFixed(2),
|
|
996
|
+
"raise leverage — every 10× lev adds 1 to 10xDEV",
|
|
997
|
+
);
|
|
998
|
+
for (const w of wins.slice(0, 4)) emit(` ${paint(c.green, "▲")} ${w}`);
|
|
999
|
+
// all gaps shown; weakest gets the prescriptive tip
|
|
1000
|
+
const sortedGaps = gaps.sort(
|
|
1001
|
+
(a, b) => a.val / a.hcm - b.val / b.hcm,
|
|
1002
|
+
);
|
|
1003
|
+
for (let i = 0; i < sortedGaps.length; i++) {
|
|
1004
|
+
const g = sortedGaps[i];
|
|
1005
|
+
if (i === 0) emit(` ${paint(c.magenta, "▽")} ${dim(g.txt)}`);
|
|
1006
|
+
else emit(` ${paint(c.magenta, "▽")} ${dim(g.label + " below field")}`);
|
|
1007
|
+
}
|
|
1008
|
+
if (!wins.length && !sortedGaps.length) emit(` ${dim(" building your read…")}`);
|
|
1009
|
+
// summary line — where you sit across all metrics
|
|
1010
|
+
if (totalMetrics > 0) {
|
|
1011
|
+
const hcmStr = `${aboveHcm}/${totalMetrics}`;
|
|
1012
|
+
const pwrStr = `${abovePower}/${totalMetrics}`;
|
|
1013
|
+
emit(
|
|
1014
|
+
` ${dim(`above HCM on ${bold(hcmStr)} · above Power on ${bold(pwrStr)}`)}`,
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
970
1017
|
} else {
|
|
971
1018
|
emit(` ${dim(" reading your cascade… (press [R] to refresh)")}`);
|
|
972
1019
|
}
|
|
973
1020
|
|
|
974
|
-
// ──
|
|
1021
|
+
// ── Four Degrees — AA baseline · Human Center of Mass · Power users · Top Evals
|
|
1022
|
+
// Matches signalaf.com/wiki/four-degrees (expanded from 3 → 4 degrees 2026-07-17).
|
|
975
1023
|
emit();
|
|
976
1024
|
emit(` ${hr()}`);
|
|
977
1025
|
emit(
|
|
978
|
-
` ${bold("
|
|
1026
|
+
` ${bold("Four Degrees")} ${dim("AA baseline · Human Center of Mass · Power users · Top Evals — signalaf.com/wiki")}`,
|
|
979
1027
|
);
|
|
980
1028
|
const tdHead = [
|
|
981
1029
|
padEnd(hdr("Metric"), 10),
|
|
982
|
-
padStart(hdr("
|
|
983
|
-
padStart(hdr("
|
|
1030
|
+
padStart(hdr("AA base"), 9),
|
|
1031
|
+
padStart(hdr("HCM"), 9),
|
|
1032
|
+
padStart(hdr("Power"), 9),
|
|
984
1033
|
padStart(hdr("Top"), 9),
|
|
985
1034
|
];
|
|
986
1035
|
emit(` ${tdHead.join(" ")}`);
|
|
987
1036
|
const white = (s) => paint(c.white, s);
|
|
988
|
-
const tdRow = (label, b,
|
|
1037
|
+
const tdRow = (label, b, h, p, t, fmt) =>
|
|
989
1038
|
emit(
|
|
990
|
-
` ${padEnd(label, 10)} ${padStart(
|
|
1039
|
+
` ${padEnd(label, 10)} ${padStart(dim(fmt(b)), 9)} ${padStart(white(fmt(h)), 9)} ${padStart(white(fmt(p)), 9)} ${padStart(gold(fmt(t)), 9)}`,
|
|
991
1040
|
);
|
|
992
|
-
tdRow("Υ Yield", TD.base.yield, TD.
|
|
993
|
-
tdRow("SNR", TD.base.snr, TD.
|
|
994
|
-
tdRow("Velocity", TD.base.vel, TD.
|
|
1041
|
+
tdRow("Υ Yield", TD.base.yield, TD.hcm.yield, TD.power.yield, TD.top.yield, fmtY);
|
|
1042
|
+
tdRow("SNR", TD.base.snr, TD.hcm.snr, TD.power.snr, TD.top.snr, fmtSNR);
|
|
1043
|
+
tdRow("Velocity", TD.base.vel, TD.hcm.vel, TD.power.vel, TD.top.vel, (v) =>
|
|
995
1044
|
v.toFixed(2),
|
|
996
1045
|
);
|
|
997
1046
|
tdRow(
|
|
998
1047
|
"Leverage",
|
|
999
1048
|
TD.base.lev,
|
|
1000
|
-
TD.
|
|
1049
|
+
TD.hcm.lev,
|
|
1050
|
+
TD.power.lev,
|
|
1001
1051
|
TD.top.lev,
|
|
1002
1052
|
(v) => fmtLev(v) + "×",
|
|
1003
1053
|
);
|
|
1004
|
-
tdRow("10xDEV", TD.base.d10, TD.
|
|
1054
|
+
tdRow("10xDEV", TD.base.d10, TD.hcm.d10, TD.power.d10, TD.top.d10, (v) => v.toFixed(2));
|
|
1005
1055
|
emit(
|
|
1006
|
-
` ${dim("reference values until live user volume calibrates
|
|
1056
|
+
` ${dim("reference values until live user volume calibrates HCM · Power · Top")}`,
|
|
1007
1057
|
);
|
|
1008
1058
|
}
|
|
1009
1059
|
|
|
@@ -1526,7 +1576,7 @@ function renderSubmissions(
|
|
|
1526
1576
|
const cells = [
|
|
1527
1577
|
padStart(rk, 4),
|
|
1528
1578
|
nm,
|
|
1529
|
-
padEnd(
|
|
1579
|
+
padEnd(platformColor(gPlat(e))(trunc(gPlat(e), 10)), 10),
|
|
1530
1580
|
padEnd(dim(trunc(gWin(e), 6)), 6),
|
|
1531
1581
|
yld,
|
|
1532
1582
|
...(showOpRatio ? [padEnd(dim(fmtOp(gOpRatio(e))), 18)] : []),
|
|
@@ -1717,6 +1767,7 @@ function renderWatchInfo(platform, win, refresh) {
|
|
|
1717
1767
|
const winLabel = !win || win === "all-windows" ? "all windows" : win;
|
|
1718
1768
|
const allDefault =
|
|
1719
1769
|
platLabel === "all active platforms" && winLabel === "all windows";
|
|
1770
|
+
const platColorFn = (!platform || platform === "all") ? cyan : platformColor(platform);
|
|
1720
1771
|
writeln();
|
|
1721
1772
|
writeln(
|
|
1722
1773
|
` ${bold("Live Watch")} ${dim("the agent that keeps your rank current")}`,
|
|
@@ -1724,7 +1775,7 @@ function renderWatchInfo(platform, win, refresh) {
|
|
|
1724
1775
|
writeln();
|
|
1725
1776
|
writeln(` ${dim("What it does")}`);
|
|
1726
1777
|
writeln(
|
|
1727
|
-
` Re-reads your local token logs for ${
|
|
1778
|
+
` Re-reads your local token logs for ${platColorFn(platLabel)} across ${cyan(winLabel)} every`,
|
|
1728
1779
|
);
|
|
1729
1780
|
writeln(
|
|
1730
1781
|
` ${gold(refresh + "s")} and recomputes each cascade (Υ Yield · SNR · Leverage · class) live, on`,
|
|
@@ -1746,7 +1797,7 @@ function renderWatchInfo(platform, win, refresh) {
|
|
|
1746
1797
|
writeln();
|
|
1747
1798
|
writeln(` ${dim("Settings")}`);
|
|
1748
1799
|
writeln(
|
|
1749
|
-
` ${dim("Platform")} ${
|
|
1800
|
+
` ${dim("Platform")} ${platColorFn(platLabel)} ${dim("Window")} ${cyan(winLabel)} ${dim("Refresh")} ${gold(refresh + "s")}`,
|
|
1750
1801
|
);
|
|
1751
1802
|
writeln(
|
|
1752
1803
|
` ${dim(allDefault ? "watching everything (default)" : "focused — press [P]/[W] to widen back to all")}`,
|