sigrank 0.15.5 → 0.16.1
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/README.md +132 -77
- package/adapters.mjs +508 -240
- package/badges.mjs +264 -0
- package/cascade.mjs +185 -54
- package/cli.mjs +1311 -893
- package/connect.mjs +2 -2
- package/index.mjs +78 -59
- package/keystore.mjs +64 -44
- package/narrate.mjs +34 -22
- package/package.json +4 -2
- package/preflight.mjs +191 -0
- package/sign.mjs +46 -27
- package/submit.mjs +166 -62
- package/tokenpull.mjs +337 -188
- package/tools.mjs +2154 -534
- package/tui.mjs +1860 -1081
package/cli.mjs
CHANGED
|
@@ -22,20 +22,20 @@
|
|
|
22
22
|
* green = positive movement
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import { callTool, DEFAULT_API_BASE, pullActivePlatforms } from
|
|
26
|
-
import { classify } from
|
|
27
|
-
import { ensureIdentity, keystorePath } from
|
|
28
|
-
import { submitSignedWindow } from
|
|
29
|
-
import { execFile } from
|
|
30
|
-
import { existsSync, readFileSync } from
|
|
31
|
-
import os from
|
|
32
|
-
import path from
|
|
33
|
-
import { fileURLToPath } from
|
|
25
|
+
import { callTool, DEFAULT_API_BASE, pullActivePlatforms } from "./tools.mjs";
|
|
26
|
+
import { classify } from "./cascade.mjs";
|
|
27
|
+
import { ensureIdentity, keystorePath } from "./keystore.mjs";
|
|
28
|
+
import { submitSignedWindow } from "./submit.mjs";
|
|
29
|
+
import { execFile } from "child_process";
|
|
30
|
+
import { existsSync, readFileSync } from "fs";
|
|
31
|
+
import os from "os";
|
|
32
|
+
import path from "path";
|
|
33
|
+
import { fileURLToPath } from "url";
|
|
34
34
|
|
|
35
35
|
// Resolve local node_modules/.bin for bundled deps (ccusage, tokscale)
|
|
36
|
-
const _pkgRoot = path.dirname(fileURLToPath(import.meta.url))
|
|
37
|
-
const _localBin = path.join(_pkgRoot,
|
|
38
|
-
const _envPath = `${_localBin}${process.env.PATH ?
|
|
36
|
+
const _pkgRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
37
|
+
const _localBin = path.join(_pkgRoot, "node_modules", ".bin");
|
|
38
|
+
const _envPath = `${_localBin}${process.env.PATH ? ":" + process.env.PATH : ""}`;
|
|
39
39
|
|
|
40
40
|
// ASYNC FIX (2026-06-27): execFile wrapped in a Promise — replaces execSync for
|
|
41
41
|
// defense-in-depth (shell injection prevention). execFile passes args as an
|
|
@@ -45,150 +45,163 @@ const _envPath = `${_localBin}${process.env.PATH ? ':' + process.env.PATH : ''}`
|
|
|
45
45
|
// are found even when sigrank isn't globally installed.
|
|
46
46
|
function execFileAsync(cmd, args, timeoutMs) {
|
|
47
47
|
return new Promise((resolve, reject) => {
|
|
48
|
-
execFile(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
execFile(
|
|
49
|
+
cmd,
|
|
50
|
+
args,
|
|
51
|
+
{
|
|
52
|
+
timeout: timeoutMs,
|
|
53
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
54
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
55
|
+
env: { ...process.env, PATH: _envPath },
|
|
56
|
+
},
|
|
57
|
+
(err, stdout) => {
|
|
58
|
+
if (err) reject(err);
|
|
59
|
+
else resolve(stdout.toString());
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
});
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
// ── ANSI helpers (no chalk dep) ────────────────────────────────────────────
|
|
56
|
-
const ESC =
|
|
66
|
+
const ESC = "\x1b[";
|
|
57
67
|
const c = {
|
|
58
|
-
reset:
|
|
59
|
-
bold:
|
|
60
|
-
dim:
|
|
61
|
-
gold:
|
|
68
|
+
reset: `${ESC}0m`,
|
|
69
|
+
bold: `${ESC}1m`,
|
|
70
|
+
dim: `${ESC}2m`,
|
|
71
|
+
gold: `${ESC}33m`,
|
|
62
72
|
boldGold: `${ESC}1;33m`,
|
|
63
|
-
cyan:
|
|
73
|
+
cyan: `${ESC}36m`,
|
|
64
74
|
boldCyan: `${ESC}1;36m`,
|
|
65
|
-
green:
|
|
66
|
-
red:
|
|
67
|
-
white:
|
|
68
|
-
boldWhite
|
|
69
|
-
magenta:
|
|
70
|
-
blue:
|
|
71
|
-
}
|
|
72
|
-
const paint = (color, str) => `${color}${str}${c.reset}
|
|
73
|
-
const bold
|
|
74
|
-
const dim
|
|
75
|
-
const gold
|
|
76
|
-
const cyan
|
|
77
|
-
const green = (str) => paint(c.green, str)
|
|
78
|
-
const red
|
|
75
|
+
green: `${ESC}32m`,
|
|
76
|
+
red: `${ESC}31m`,
|
|
77
|
+
white: `${ESC}97m`,
|
|
78
|
+
boldWhite: `${ESC}1;97m`,
|
|
79
|
+
magenta: `${ESC}35m`,
|
|
80
|
+
blue: `${ESC}34m`,
|
|
81
|
+
};
|
|
82
|
+
const paint = (color, str) => `${color}${str}${c.reset}`;
|
|
83
|
+
const bold = (str) => paint(c.bold, str);
|
|
84
|
+
const dim = (str) => paint(c.dim, str);
|
|
85
|
+
const gold = (str) => paint(c.boldGold, str);
|
|
86
|
+
const cyan = (str) => paint(c.boldCyan, str);
|
|
87
|
+
const green = (str) => paint(c.green, str);
|
|
88
|
+
const red = (str) => paint(c.red, str);
|
|
79
89
|
|
|
80
90
|
// ── Class tier → color ─────────────────────────────────────────────────────
|
|
81
91
|
const CLASS_COLOR = {
|
|
82
|
-
TRANSMITTER: (s) => paint(c.boldGold,
|
|
83
|
-
|
|
84
|
-
ARCH:
|
|
85
|
-
POWER:
|
|
86
|
-
BASE:
|
|
87
|
-
SEEKER:
|
|
88
|
-
REFINER:
|
|
89
|
-
BEARER:
|
|
90
|
-
IGNITER:
|
|
91
|
-
}
|
|
92
|
-
const colorClass = (cls) => (CLASS_COLOR[cls] ?? ((s) => s))(cls)
|
|
92
|
+
TRANSMITTER: (s) => paint(c.boldGold, s),
|
|
93
|
+
"ARCH+": (s) => paint(c.boldCyan, s),
|
|
94
|
+
ARCH: (s) => paint(c.cyan, s),
|
|
95
|
+
POWER: (s) => paint(c.boldWhite, s),
|
|
96
|
+
BASE: (s) => paint(c.white, s),
|
|
97
|
+
SEEKER: (s) => paint(c.magenta, s),
|
|
98
|
+
REFINER: (s) => paint(c.blue, s),
|
|
99
|
+
BEARER: (s) => paint(c.dim, s),
|
|
100
|
+
IGNITER: (s) => paint(c.dim, s),
|
|
101
|
+
};
|
|
102
|
+
const colorClass = (cls) => (CLASS_COLOR[cls] ?? ((s) => s))(cls);
|
|
93
103
|
|
|
94
104
|
// ── Terminal utils ──────────────────────────────────────────────────────────
|
|
95
|
-
const CLEAR_SCREEN
|
|
96
|
-
const CURSOR_UP
|
|
97
|
-
const ERASE_LINE
|
|
98
|
-
const HIDE_CURSOR
|
|
99
|
-
const SHOW_CURSOR
|
|
100
|
-
const termWidth
|
|
101
|
-
const write
|
|
102
|
-
const writeln
|
|
105
|
+
const CLEAR_SCREEN = `${ESC}2J${ESC}H`;
|
|
106
|
+
const CURSOR_UP = (n) => `${ESC}${n}A`;
|
|
107
|
+
const ERASE_LINE = `${ESC}2K`;
|
|
108
|
+
const HIDE_CURSOR = `${ESC}?25l`;
|
|
109
|
+
const SHOW_CURSOR = `${ESC}?25h`;
|
|
110
|
+
const termWidth = () => process.stdout.columns || 80;
|
|
111
|
+
const write = (s) => process.stdout.write(s);
|
|
112
|
+
const writeln = (s = "") => process.stdout.write(s + "\n");
|
|
103
113
|
|
|
104
114
|
// Right-pad or truncate to exact width (ANSI-escape-aware via strip helper)
|
|
105
|
-
function stripAnsi(s) {
|
|
115
|
+
function stripAnsi(s) {
|
|
116
|
+
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
117
|
+
}
|
|
106
118
|
function padEnd(s, w) {
|
|
107
|
-
const vis = stripAnsi(s).length
|
|
108
|
-
return vis >= w ? s : s +
|
|
119
|
+
const vis = stripAnsi(s).length;
|
|
120
|
+
return vis >= w ? s : s + " ".repeat(w - vis);
|
|
109
121
|
}
|
|
110
122
|
function padStart(s, w) {
|
|
111
|
-
const vis = stripAnsi(s).length
|
|
112
|
-
return vis >= w ? s :
|
|
123
|
+
const vis = stripAnsi(s).length;
|
|
124
|
+
return vis >= w ? s : " ".repeat(w - vis) + s;
|
|
113
125
|
}
|
|
114
126
|
function trunc(s, w) {
|
|
115
|
-
const stripped = stripAnsi(s)
|
|
116
|
-
if (stripped.length <= w) return s
|
|
127
|
+
const stripped = stripAnsi(s);
|
|
128
|
+
if (stripped.length <= w) return s;
|
|
117
129
|
// truncate the raw string, not the escape-aware one — safe for plain strings
|
|
118
|
-
return s.slice(0, w - 1) +
|
|
130
|
+
return s.slice(0, w - 1) + "…";
|
|
119
131
|
}
|
|
120
132
|
|
|
121
133
|
// ── Number formatters ───────────────────────────────────────────────────────
|
|
122
134
|
const fmtYield = (y) => {
|
|
123
|
-
if (y == null) return
|
|
124
|
-
if (y >= 10000) return `${(y / 1000).toFixed(1)}K
|
|
125
|
-
if (y >= 1000)
|
|
126
|
-
return y.toFixed(1)
|
|
127
|
-
}
|
|
135
|
+
if (y == null) return "—";
|
|
136
|
+
if (y >= 10000) return `${(y / 1000).toFixed(1)}K`;
|
|
137
|
+
if (y >= 1000) return `${(y / 1000).toFixed(2)}K`;
|
|
138
|
+
return y.toFixed(1);
|
|
139
|
+
};
|
|
128
140
|
const fmtLev = (l) => {
|
|
129
|
-
if (l == null) return
|
|
130
|
-
if (l >= 1000) return `${(l / 1000).toFixed(1)}K
|
|
131
|
-
return l.toFixed(0)
|
|
132
|
-
}
|
|
133
|
-
const fmtPct
|
|
134
|
-
const fmtSNR
|
|
141
|
+
if (l == null) return "—";
|
|
142
|
+
if (l >= 1000) return `${(l / 1000).toFixed(1)}K`;
|
|
143
|
+
return l.toFixed(0);
|
|
144
|
+
};
|
|
145
|
+
const fmtPct = (n) => (n != null ? `${(n * 100).toFixed(0)}%` : "—");
|
|
146
|
+
const fmtSNR = (n) => (n != null ? `${(n * 100).toFixed(1)}%` : "—");
|
|
135
147
|
const fmtMove = (n) => {
|
|
136
|
-
if (n == null || n === 0) return dim(
|
|
137
|
-
return n > 0 ? green(`+${n}`) : red(`${n}`)
|
|
138
|
-
}
|
|
148
|
+
if (n == null || n === 0) return dim(" —");
|
|
149
|
+
return n > 0 ? green(`+${n}`) : red(`${n}`);
|
|
150
|
+
};
|
|
139
151
|
const fmtTokens = (n) => {
|
|
140
|
-
if (n == null) return
|
|
141
|
-
if (n >= 1e9) return `${(n / 1e9).toFixed(1)}B
|
|
142
|
-
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M
|
|
143
|
-
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K
|
|
144
|
-
return String(n)
|
|
145
|
-
}
|
|
152
|
+
if (n == null) return "—";
|
|
153
|
+
if (n >= 1e9) return `${(n / 1e9).toFixed(1)}B`;
|
|
154
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
155
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
156
|
+
return String(n);
|
|
157
|
+
};
|
|
146
158
|
|
|
147
159
|
// ── Header / footer ─────────────────────────────────────────────────────────
|
|
148
|
-
function renderHeader(title, subtitle =
|
|
149
|
-
const w = termWidth()
|
|
150
|
-
const ts = new Date().toLocaleTimeString(
|
|
151
|
-
const right = dim(`signalaf.com ${ts}`)
|
|
152
|
-
const rightVis = stripAnsi(right).length
|
|
153
|
-
const leftVis
|
|
154
|
-
const gap = Math.max(1, w - leftVis - rightVis)
|
|
155
|
-
writeln()
|
|
156
|
-
writeln(` ${title}${
|
|
157
|
-
if (subtitle) writeln(` ${dim(subtitle)}`)
|
|
158
|
-
writeln(` ${dim(
|
|
160
|
+
function renderHeader(title, subtitle = "") {
|
|
161
|
+
const w = termWidth();
|
|
162
|
+
const ts = new Date().toLocaleTimeString("en-US", { hour12: false });
|
|
163
|
+
const right = dim(`signalaf.com ${ts}`);
|
|
164
|
+
const rightVis = stripAnsi(right).length;
|
|
165
|
+
const leftVis = stripAnsi(title).length;
|
|
166
|
+
const gap = Math.max(1, w - leftVis - rightVis);
|
|
167
|
+
writeln();
|
|
168
|
+
writeln(` ${title}${" ".repeat(gap)}${right}`);
|
|
169
|
+
if (subtitle) writeln(` ${dim(subtitle)}`);
|
|
170
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
159
171
|
}
|
|
160
172
|
|
|
161
|
-
function renderFooter(hint =
|
|
162
|
-
const w = termWidth()
|
|
163
|
-
writeln(` ${dim(
|
|
164
|
-
if (hint) writeln(` ${dim(hint)}`)
|
|
165
|
-
writeln()
|
|
173
|
+
function renderFooter(hint = "") {
|
|
174
|
+
const w = termWidth();
|
|
175
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
176
|
+
if (hint) writeln(` ${dim(hint)}`);
|
|
177
|
+
writeln();
|
|
166
178
|
}
|
|
167
179
|
|
|
168
180
|
// ── BOARD command ────────────────────────────────────────────────────────────
|
|
169
181
|
|
|
170
182
|
const BOARD_COLS = [
|
|
171
|
-
{ key:
|
|
172
|
-
{ key:
|
|
173
|
-
{ key:
|
|
174
|
-
{ key:
|
|
175
|
-
{ key:
|
|
176
|
-
{ key:
|
|
177
|
-
{ key:
|
|
178
|
-
{ key:
|
|
179
|
-
]
|
|
183
|
+
{ key: "rank", label: "#", w: 4, align: "r" },
|
|
184
|
+
{ key: "codename", label: "Operator", w: 20, align: "l" },
|
|
185
|
+
{ key: "class_tier", label: "Class", w: 13, align: "l" },
|
|
186
|
+
{ key: "yield_", label: "Υ Yield", w: 9, align: "r" },
|
|
187
|
+
{ key: "compression_ratio", label: "SNR", w: 6, align: "r" },
|
|
188
|
+
{ key: "session_depth", label: "Depth", w: 6, align: "r" },
|
|
189
|
+
{ key: "token_throughput", label: "Tokens", w: 8, align: "r" },
|
|
190
|
+
{ key: "movement_7d", label: "7d Δ", w: 6, align: "r" },
|
|
191
|
+
];
|
|
180
192
|
|
|
181
193
|
function renderBoardRow(entry, highlight = false) {
|
|
182
|
-
const rank = entry.rank === 1 ? gold(`#${entry.rank}`) : `#${entry.rank}
|
|
194
|
+
const rank = entry.rank === 1 ? gold(`#${entry.rank}`) : `#${entry.rank}`;
|
|
183
195
|
const name = highlight
|
|
184
196
|
? cyan(trunc(entry.codename, 19))
|
|
185
|
-
: trunc(entry.codename, 19)
|
|
186
|
-
const cls
|
|
187
|
-
const yld
|
|
188
|
-
const snr
|
|
189
|
-
const dep
|
|
190
|
-
|
|
191
|
-
const
|
|
197
|
+
: trunc(entry.codename, 19);
|
|
198
|
+
const cls = colorClass(entry.class_tier ?? "—");
|
|
199
|
+
const yld = entry.yield_ != null ? fmtYield(entry.yield_) : "—";
|
|
200
|
+
const snr = fmtSNR(entry.compression_ratio);
|
|
201
|
+
const dep =
|
|
202
|
+
entry.session_depth != null ? entry.session_depth.toFixed(1) : "—";
|
|
203
|
+
const tok = fmtTokens(entry.token_throughput);
|
|
204
|
+
const mv = fmtMove(entry.movement_7d);
|
|
192
205
|
|
|
193
206
|
const cols = [
|
|
194
207
|
padStart(rank, 4),
|
|
@@ -199,82 +212,91 @@ function renderBoardRow(entry, highlight = false) {
|
|
|
199
212
|
padStart(dep, 6),
|
|
200
213
|
padStart(tok, 8),
|
|
201
214
|
padStart(mv, 6),
|
|
202
|
-
]
|
|
203
|
-
const prefix = highlight ? `${c.boldCyan}▶${c.reset} ` :
|
|
204
|
-
writeln(prefix + cols.join(
|
|
215
|
+
];
|
|
216
|
+
const prefix = highlight ? `${c.boldCyan}▶${c.reset} ` : " ";
|
|
217
|
+
writeln(prefix + cols.join(" "));
|
|
205
218
|
}
|
|
206
219
|
|
|
207
|
-
function renderBoardHeader(window =
|
|
220
|
+
function renderBoardHeader(window = "30d") {
|
|
208
221
|
renderHeader(
|
|
209
|
-
`${gold(
|
|
210
|
-
`window: ${window} · sorted by Υ Yield · top 25 operators
|
|
211
|
-
)
|
|
222
|
+
`${gold("⊙ SigRank")} ${bold("Leaderboard")}`,
|
|
223
|
+
`window: ${window} · sorted by Υ Yield · top 25 operators`,
|
|
224
|
+
);
|
|
212
225
|
// column headers
|
|
213
|
-
const headers = BOARD_COLS.map(col =>
|
|
214
|
-
col.align ===
|
|
226
|
+
const headers = BOARD_COLS.map((col) =>
|
|
227
|
+
col.align === "r"
|
|
215
228
|
? padStart(dim(col.label), col.w)
|
|
216
|
-
: padEnd(dim(col.label), col.w)
|
|
217
|
-
)
|
|
218
|
-
writeln(` ${headers.join(
|
|
219
|
-
writeln(` ${dim(
|
|
229
|
+
: padEnd(dim(col.label), col.w),
|
|
230
|
+
);
|
|
231
|
+
writeln(` ${headers.join(" ")}`);
|
|
232
|
+
writeln(` ${dim("·".repeat(termWidth() - 4))}`);
|
|
220
233
|
}
|
|
221
234
|
|
|
222
|
-
async function fetchBoard(window =
|
|
223
|
-
const res = await fetch(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
235
|
+
async function fetchBoard(window = "30d") {
|
|
236
|
+
const res = await fetch(
|
|
237
|
+
`${DEFAULT_API_BASE}/api/v1/leaderboard?window=${window}&metric=yield_`,
|
|
238
|
+
{
|
|
239
|
+
headers: { accept: "application/json" },
|
|
240
|
+
},
|
|
241
|
+
);
|
|
242
|
+
if (!res.ok) throw new Error(`Board API → HTTP ${res.status}`);
|
|
243
|
+
return res.json();
|
|
228
244
|
}
|
|
229
245
|
|
|
230
|
-
async function runBoard({ window =
|
|
231
|
-
let lines = 0
|
|
246
|
+
async function runBoard({ window = "30d", once = false, refresh = 30 } = {}) {
|
|
247
|
+
let lines = 0;
|
|
232
248
|
|
|
233
249
|
const draw = async () => {
|
|
234
|
-
let data
|
|
235
|
-
try {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
250
|
+
let data;
|
|
251
|
+
try {
|
|
252
|
+
data = await fetchBoard(window);
|
|
253
|
+
} catch (e) {
|
|
254
|
+
writeln(red(` ✗ Could not reach signalaf.com: ${e.message}`));
|
|
255
|
+
return;
|
|
239
256
|
}
|
|
240
257
|
|
|
241
258
|
if (!once && lines > 0) {
|
|
242
259
|
// move cursor up and redraw in-place
|
|
243
|
-
write(CURSOR_UP(lines))
|
|
260
|
+
write(CURSOR_UP(lines));
|
|
244
261
|
}
|
|
245
262
|
|
|
246
|
-
const out = []
|
|
247
|
-
const push = (s =
|
|
248
|
-
|
|
249
|
-
push()
|
|
250
|
-
const ts = new Date().toLocaleTimeString(
|
|
251
|
-
const right = `signalaf.com ${ts}
|
|
252
|
-
const title = `⊙ SigRank Leaderboard
|
|
253
|
-
const w = termWidth()
|
|
254
|
-
const gap = Math.max(1, w - 2 - title.length - right.length)
|
|
255
|
-
push(
|
|
256
|
-
|
|
257
|
-
|
|
263
|
+
const out = [];
|
|
264
|
+
const push = (s = "") => out.push(s);
|
|
265
|
+
|
|
266
|
+
push();
|
|
267
|
+
const ts = new Date().toLocaleTimeString("en-US", { hour12: false });
|
|
268
|
+
const right = `signalaf.com ${ts}`;
|
|
269
|
+
const title = `⊙ SigRank Leaderboard`;
|
|
270
|
+
const w = termWidth();
|
|
271
|
+
const gap = Math.max(1, w - 2 - title.length - right.length);
|
|
272
|
+
push(
|
|
273
|
+
` ${gold("⊙ SigRank")} ${bold("Leaderboard")}${" ".repeat(gap)}${dim(right)}`,
|
|
274
|
+
);
|
|
275
|
+
push(
|
|
276
|
+
` ${dim(`window: ${data.window ?? window} · ${data.total_operators ?? data.entries?.length ?? 0} operators`)}`,
|
|
277
|
+
);
|
|
278
|
+
push(` ${dim("─".repeat(w - 4))}`);
|
|
258
279
|
|
|
259
280
|
// column header row
|
|
260
|
-
const headers = BOARD_COLS.map(col =>
|
|
261
|
-
col.align ===
|
|
281
|
+
const headers = BOARD_COLS.map((col) =>
|
|
282
|
+
col.align === "r"
|
|
262
283
|
? padStart(dim(col.label), col.w)
|
|
263
|
-
: padEnd(dim(col.label), col.w)
|
|
264
|
-
).join(
|
|
265
|
-
push(` ${headers}`)
|
|
266
|
-
push(` ${dim(
|
|
284
|
+
: padEnd(dim(col.label), col.w),
|
|
285
|
+
).join(" ");
|
|
286
|
+
push(` ${headers}`);
|
|
287
|
+
push(` ${dim("·".repeat(w - 4))}`);
|
|
267
288
|
|
|
268
|
-
const entries = data.entries ?? []
|
|
289
|
+
const entries = data.entries ?? [];
|
|
269
290
|
for (const entry of entries) {
|
|
270
|
-
const rank = entry.rank === 1 ? gold(`#${entry.rank}`) : `#${entry.rank}
|
|
271
|
-
const name = trunc(entry.codename ??
|
|
272
|
-
const cls
|
|
273
|
-
const yld
|
|
274
|
-
const snr
|
|
275
|
-
const dep
|
|
276
|
-
|
|
277
|
-
const
|
|
291
|
+
const rank = entry.rank === 1 ? gold(`#${entry.rank}`) : `#${entry.rank}`;
|
|
292
|
+
const name = trunc(entry.codename ?? "—", 19);
|
|
293
|
+
const cls = colorClass(entry.class_tier ?? "—");
|
|
294
|
+
const yld = entry.yield_ != null ? fmtYield(entry.yield_) : "—";
|
|
295
|
+
const snr = fmtSNR(entry.compression_ratio);
|
|
296
|
+
const dep =
|
|
297
|
+
entry.session_depth != null ? entry.session_depth.toFixed(1) : "—";
|
|
298
|
+
const tok = fmtTokens(entry.token_throughput);
|
|
299
|
+
const mv = fmtMove(entry.movement_7d);
|
|
278
300
|
const cols = [
|
|
279
301
|
padStart(rank, 4),
|
|
280
302
|
padEnd(name, 20),
|
|
@@ -284,31 +306,35 @@ async function runBoard({ window = '30d', once = false, refresh = 30 } = {}) {
|
|
|
284
306
|
padStart(dep, 6),
|
|
285
307
|
padStart(tok, 8),
|
|
286
308
|
padStart(mv, 6),
|
|
287
|
-
]
|
|
288
|
-
push(` ${cols.join(
|
|
309
|
+
];
|
|
310
|
+
push(` ${cols.join(" ")}`);
|
|
289
311
|
}
|
|
290
312
|
|
|
291
|
-
push(` ${dim(
|
|
292
|
-
if (!once)
|
|
293
|
-
|
|
313
|
+
push(` ${dim("─".repeat(w - 4))}`);
|
|
314
|
+
if (!once)
|
|
315
|
+
push(` ${dim(`auto-refresh every ${refresh}s · ctrl+c to exit`)}`);
|
|
316
|
+
push();
|
|
294
317
|
|
|
295
318
|
// write all at once to minimize flicker
|
|
296
|
-
const rendered = out.join(
|
|
297
|
-
write(rendered)
|
|
298
|
-
lines = out.length
|
|
299
|
-
}
|
|
319
|
+
const rendered = out.join("\n");
|
|
320
|
+
write(rendered);
|
|
321
|
+
lines = out.length;
|
|
322
|
+
};
|
|
300
323
|
|
|
301
|
-
if (!once) write(HIDE_CURSOR)
|
|
324
|
+
if (!once) write(HIDE_CURSOR);
|
|
302
325
|
try {
|
|
303
|
-
await draw()
|
|
326
|
+
await draw();
|
|
304
327
|
if (!once) {
|
|
305
|
-
const iv = setInterval(draw, refresh * 1000)
|
|
328
|
+
const iv = setInterval(draw, refresh * 1000);
|
|
306
329
|
await new Promise((resolve) => {
|
|
307
|
-
process.on(
|
|
308
|
-
|
|
330
|
+
process.on("SIGINT", () => {
|
|
331
|
+
clearInterval(iv);
|
|
332
|
+
resolve();
|
|
333
|
+
});
|
|
334
|
+
});
|
|
309
335
|
}
|
|
310
336
|
} finally {
|
|
311
|
-
if (!once) write(SHOW_CURSOR +
|
|
337
|
+
if (!once) write(SHOW_CURSOR + "\n");
|
|
312
338
|
}
|
|
313
339
|
}
|
|
314
340
|
|
|
@@ -325,88 +351,118 @@ async function runBoard({ window = '30d', once = false, refresh = 30 } = {}) {
|
|
|
325
351
|
// identical to _freshCcusage and could be consolidated in a future pass if compare
|
|
326
352
|
// switches to live data — but that's a behavior change, not a refactor.
|
|
327
353
|
|
|
328
|
-
async function ccusagePillars(platform =
|
|
354
|
+
async function ccusagePillars(platform = "claude") {
|
|
329
355
|
// ccusage <platform> daily --json → sum by window
|
|
330
356
|
try {
|
|
331
|
-
const raw = await execFileAsync(
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const
|
|
337
|
-
const
|
|
357
|
+
const raw = await execFileAsync(
|
|
358
|
+
"ccusage",
|
|
359
|
+
[platform, "daily", "--json"],
|
|
360
|
+
15000,
|
|
361
|
+
);
|
|
362
|
+
const data = JSON.parse(raw);
|
|
363
|
+
const rows = data.daily ?? data; // ccusage may return {daily:[...]} or [...]
|
|
364
|
+
|
|
365
|
+
const now = Date.now();
|
|
366
|
+
const cutoff = { "7d": 7, "30d": 30, "90d": 90 };
|
|
367
|
+
const result = {};
|
|
338
368
|
|
|
339
369
|
for (const [win, days] of Object.entries(cutoff)) {
|
|
340
|
-
const since = new Date(now - days * 86400000)
|
|
341
|
-
let input = 0,
|
|
370
|
+
const since = new Date(now - days * 86400000);
|
|
371
|
+
let input = 0,
|
|
372
|
+
output = 0,
|
|
373
|
+
cacheCreate = 0,
|
|
374
|
+
cacheRead = 0;
|
|
342
375
|
for (const row of rows) {
|
|
343
|
-
const d = new Date(row.date ?? row.day ?? row.week ??
|
|
376
|
+
const d = new Date(row.date ?? row.day ?? row.week ?? "1970-01-01");
|
|
344
377
|
if (d >= since) {
|
|
345
|
-
input
|
|
346
|
-
output
|
|
347
|
-
cacheCreate +=
|
|
348
|
-
|
|
378
|
+
input += row.inputTokens ?? row.input_tokens ?? 0;
|
|
379
|
+
output += row.outputTokens ?? row.output_tokens ?? 0;
|
|
380
|
+
cacheCreate +=
|
|
381
|
+
row.cacheCreationTokens ?? row.cache_create_tokens ?? 0;
|
|
382
|
+
cacheRead += row.cacheReadTokens ?? row.cache_read_tokens ?? 0;
|
|
349
383
|
}
|
|
350
384
|
}
|
|
351
|
-
result[win] = { input, output, cacheCreate, cacheRead }
|
|
385
|
+
result[win] = { input, output, cacheCreate, cacheRead };
|
|
352
386
|
}
|
|
353
387
|
// all-time = sum everything
|
|
354
|
-
let input = 0,
|
|
388
|
+
let input = 0,
|
|
389
|
+
output = 0,
|
|
390
|
+
cacheCreate = 0,
|
|
391
|
+
cacheRead = 0;
|
|
355
392
|
for (const row of rows) {
|
|
356
|
-
input
|
|
357
|
-
output
|
|
358
|
-
cacheCreate += row.cacheCreationTokens ?? row.cache_create_tokens ?? 0
|
|
359
|
-
cacheRead
|
|
393
|
+
input += row.inputTokens ?? row.input_tokens ?? 0;
|
|
394
|
+
output += row.outputTokens ?? row.output_tokens ?? 0;
|
|
395
|
+
cacheCreate += row.cacheCreationTokens ?? row.cache_create_tokens ?? 0;
|
|
396
|
+
cacheRead += row.cacheReadTokens ?? row.cache_read_tokens ?? 0;
|
|
360
397
|
}
|
|
361
|
-
result[
|
|
362
|
-
return result
|
|
398
|
+
result["all"] = { input, output, cacheCreate, cacheRead };
|
|
399
|
+
return result;
|
|
363
400
|
} catch {
|
|
364
|
-
return null
|
|
401
|
+
return null;
|
|
365
402
|
}
|
|
366
403
|
}
|
|
367
404
|
|
|
368
|
-
async function tokscalePillars(platform =
|
|
405
|
+
async function tokscalePillars(platform = "claude") {
|
|
369
406
|
// Try the bundled tokscale CLI first (fresh data), fall back to saved report file.
|
|
370
407
|
try {
|
|
371
|
-
const raw = await execFileAsync(
|
|
372
|
-
const data = JSON.parse(raw)
|
|
373
|
-
const entries = Array.isArray(data?.entries)
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
408
|
+
const raw = await execFileAsync("tokscale", ["models", "--json"], 60000);
|
|
409
|
+
const data = JSON.parse(raw);
|
|
410
|
+
const entries = Array.isArray(data?.entries)
|
|
411
|
+
? data.entries
|
|
412
|
+
: Array.isArray(data)
|
|
413
|
+
? data
|
|
414
|
+
: [];
|
|
415
|
+
const rows = entries.filter(
|
|
416
|
+
(e) =>
|
|
417
|
+
e &&
|
|
418
|
+
e.client === platform &&
|
|
419
|
+
e.model !== "<synthetic>" &&
|
|
420
|
+
e.model !== "unknown" &&
|
|
421
|
+
((Number(e.input) || 0) > 0 || (Number(e.output) || 0) > 0),
|
|
422
|
+
);
|
|
379
423
|
if (rows.length) {
|
|
380
|
-
const p = rows.reduce(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
424
|
+
const p = rows.reduce(
|
|
425
|
+
(acc, e) => ({
|
|
426
|
+
input: acc.input + (Number(e.input) || 0),
|
|
427
|
+
output: acc.output + (Number(e.output) || 0),
|
|
428
|
+
cacheCreate: acc.cacheCreate + (Number(e.cacheWrite) || 0),
|
|
429
|
+
cacheRead: acc.cacheRead + (Number(e.cacheRead) || 0),
|
|
430
|
+
}),
|
|
431
|
+
{ input: 0, output: 0, cacheCreate: 0, cacheRead: 0 },
|
|
432
|
+
);
|
|
433
|
+
return { all: p };
|
|
387
434
|
}
|
|
388
|
-
} catch {
|
|
435
|
+
} catch {
|
|
436
|
+
/* fall through to file-based read */
|
|
437
|
+
}
|
|
389
438
|
// Fallback: read saved tokscale_report.json — all-time only (no timestamps in export)
|
|
390
|
-
const reportPath = path.join(os.homedir(),
|
|
391
|
-
if (!existsSync(reportPath)) return null
|
|
439
|
+
const reportPath = path.join(os.homedir(), "tokscale_report.json");
|
|
440
|
+
if (!existsSync(reportPath)) return null;
|
|
392
441
|
try {
|
|
393
|
-
const data = JSON.parse(readFileSync(reportPath,
|
|
394
|
-
const entries = data.entries ?? []
|
|
395
|
-
const rows = entries.filter(
|
|
396
|
-
e
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
442
|
+
const data = JSON.parse(readFileSync(reportPath, "utf8"));
|
|
443
|
+
const entries = data.entries ?? [];
|
|
444
|
+
const rows = entries.filter(
|
|
445
|
+
(e) =>
|
|
446
|
+
e.client === platform &&
|
|
447
|
+
e.model !== "<synthetic>" &&
|
|
448
|
+
e.model !== "unknown" &&
|
|
449
|
+
(e.input > 0 || e.output > 0),
|
|
450
|
+
);
|
|
451
|
+
if (rows.length === 0) return null;
|
|
452
|
+
const p = rows.reduce(
|
|
453
|
+
(acc, e) => ({
|
|
454
|
+
input: acc.input + (e.input ?? 0),
|
|
455
|
+
output: acc.output + (e.output ?? 0),
|
|
456
|
+
cacheCreate: acc.cacheCreate + (e.cacheWrite ?? 0),
|
|
457
|
+
cacheRead: acc.cacheRead + (e.cacheRead ?? 0),
|
|
458
|
+
}),
|
|
459
|
+
{ input: 0, output: 0, cacheCreate: 0, cacheRead: 0 },
|
|
460
|
+
);
|
|
407
461
|
// tokscale export has no timestamps → only all-time available
|
|
408
|
-
return { all: p }
|
|
409
|
-
} catch {
|
|
462
|
+
return { all: p };
|
|
463
|
+
} catch {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
410
466
|
}
|
|
411
467
|
|
|
412
468
|
function appPillars() {
|
|
@@ -414,230 +470,295 @@ function appPillars() {
|
|
|
414
470
|
// Hard-coded from 2026-06-23 screenshot capture (update when re-screenshotted)
|
|
415
471
|
return {
|
|
416
472
|
all: {
|
|
417
|
-
input:
|
|
418
|
-
output:
|
|
419
|
-
cacheCreate: null,
|
|
420
|
-
cacheRead:
|
|
473
|
+
input: 6_378_000, // sum of all models: 5.6M + 102.1K + 92.9K + 130.3K + 418.9K + 33.5K
|
|
474
|
+
output: 38_682_400, // sum: 19.6M + 6.5M + 5.4M + 6.6M + 292.4K + 290.4K
|
|
475
|
+
cacheCreate: null, // not shown in App UI
|
|
476
|
+
cacheRead: null, // not shown in App UI
|
|
421
477
|
},
|
|
422
|
-
_note:
|
|
478
|
+
_note:
|
|
479
|
+
"App UI — all-time, per-model sum from screenshots 2026-06-23. No cache fields. Update when re-screenshotted.",
|
|
423
480
|
_perModel: [
|
|
424
|
-
{ model:
|
|
425
|
-
{ model:
|
|
426
|
-
{ model:
|
|
427
|
-
{ model:
|
|
428
|
-
{ model:
|
|
429
|
-
{ model:
|
|
481
|
+
{ model: "claude-opus-4-8", input: 5_600_000, output: 19_600_000 },
|
|
482
|
+
{ model: "claude-sonnet-4-5", input: 102_100, output: 6_500_000 },
|
|
483
|
+
{ model: "claude-sonnet-4-6", input: 92_900, output: 5_400_000 },
|
|
484
|
+
{ model: "claude-opus-4-7", input: 130_300, output: 6_600_000 },
|
|
485
|
+
{ model: "claude-fable-5", input: 418_900, output: 292_400 },
|
|
486
|
+
{ model: "claude-haiku-4-5", input: 33_500, output: 290_400 },
|
|
430
487
|
],
|
|
431
|
-
}
|
|
488
|
+
};
|
|
432
489
|
}
|
|
433
490
|
|
|
434
491
|
async function tokenDashPillars() {
|
|
435
|
-
const dbPath = path.join(os.homedir(),
|
|
436
|
-
if (!existsSync(dbPath)) return null
|
|
492
|
+
const dbPath = path.join(os.homedir(), ".claude", "token-dashboard.db");
|
|
493
|
+
if (!existsSync(dbPath)) return null;
|
|
437
494
|
// Read directly with sqlite3 — no python script needed (bundled dep).
|
|
438
495
|
// Windowed queries using sqlite3's datetime() function.
|
|
439
|
-
const cf =
|
|
496
|
+
const cf =
|
|
497
|
+
"(model LIKE '%claude%' OR model LIKE '%fable%' OR model LIKE '%sonnet%' OR model LIKE '%opus%' OR model LIKE '%haiku%')";
|
|
440
498
|
try {
|
|
441
499
|
const wins = [
|
|
442
|
-
[
|
|
443
|
-
[
|
|
444
|
-
[
|
|
445
|
-
]
|
|
500
|
+
["7d", "datetime('now','-7 days')"],
|
|
501
|
+
["30d", "datetime('now','-30 days')"],
|
|
502
|
+
["90d", "datetime('now','-90 days')"],
|
|
503
|
+
];
|
|
446
504
|
const sql = (cutoff) =>
|
|
447
|
-
`SELECT SUM(input_tokens),SUM(output_tokens),SUM(cache_create_5m_tokens+cache_create_1h_tokens),SUM(cache_read_tokens) FROM messages WHERE timestamp>=${cutoff} AND ${cf}
|
|
448
|
-
const allSql = `SELECT SUM(input_tokens),SUM(output_tokens),SUM(cache_create_5m_tokens+cache_create_1h_tokens),SUM(cache_read_tokens) FROM messages WHERE ${cf}
|
|
505
|
+
`SELECT SUM(input_tokens),SUM(output_tokens),SUM(cache_create_5m_tokens+cache_create_1h_tokens),SUM(cache_read_tokens) FROM messages WHERE timestamp>=${cutoff} AND ${cf}`;
|
|
506
|
+
const allSql = `SELECT SUM(input_tokens),SUM(output_tokens),SUM(cache_create_5m_tokens+cache_create_1h_tokens),SUM(cache_read_tokens) FROM messages WHERE ${cf}`;
|
|
449
507
|
const [d7, d30, d90, dAll] = await Promise.all([
|
|
450
|
-
execFileAsync(
|
|
451
|
-
execFileAsync(
|
|
452
|
-
execFileAsync(
|
|
453
|
-
execFileAsync(
|
|
454
|
-
])
|
|
508
|
+
execFileAsync("sqlite3", [dbPath, sql(wins[0][1])], 5000),
|
|
509
|
+
execFileAsync("sqlite3", [dbPath, sql(wins[1][1])], 5000),
|
|
510
|
+
execFileAsync("sqlite3", [dbPath, sql(wins[2][1])], 5000),
|
|
511
|
+
execFileAsync("sqlite3", [dbPath, allSql], 5000),
|
|
512
|
+
]);
|
|
455
513
|
const parse = (raw) => {
|
|
456
|
-
const [i,o,cw,cr] = raw.trim().split(
|
|
457
|
-
return {
|
|
458
|
-
|
|
514
|
+
const [i, o, cw, cr] = raw.trim().split("|").map(Number);
|
|
515
|
+
return {
|
|
516
|
+
input: i || 0,
|
|
517
|
+
output: o || 0,
|
|
518
|
+
cacheCreate: cw || 0,
|
|
519
|
+
cacheRead: cr || 0,
|
|
520
|
+
};
|
|
521
|
+
};
|
|
459
522
|
return {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
523
|
+
"7d": parse(d7),
|
|
524
|
+
"30d": parse(d30),
|
|
525
|
+
"90d": parse(d90),
|
|
463
526
|
all: parse(dAll),
|
|
464
|
-
}
|
|
527
|
+
};
|
|
465
528
|
} catch {
|
|
466
|
-
return null
|
|
529
|
+
return null;
|
|
467
530
|
}
|
|
468
531
|
}
|
|
469
532
|
|
|
470
533
|
function fmtDelta(a, b) {
|
|
471
|
-
if (a == null || b == null) return dim(
|
|
472
|
-
const d = b - a
|
|
473
|
-
if (d === 0) return dim(
|
|
474
|
-
const pct =
|
|
475
|
-
|
|
476
|
-
const
|
|
477
|
-
|
|
534
|
+
if (a == null || b == null) return dim(" —");
|
|
535
|
+
const d = b - a;
|
|
536
|
+
if (d === 0) return dim(" =");
|
|
537
|
+
const pct =
|
|
538
|
+
a !== 0 ? `${d > 0 ? "+" : ""}${((d / a) * 100).toFixed(1)}%` : "";
|
|
539
|
+
const abs = `${d > 0 ? "+" : ""}${fmtTokens(Math.abs(d))}`;
|
|
540
|
+
const label = `${abs} ${pct}`;
|
|
541
|
+
return d > 0 ? green(label) : red(label);
|
|
478
542
|
}
|
|
479
543
|
|
|
480
544
|
// Compute cascade metrics from raw pillars (mirrors bridge.ts computeCascadeMetrics)
|
|
481
545
|
function cascadeFromPillars(p) {
|
|
482
|
-
if (!p) return null
|
|
483
|
-
const i
|
|
484
|
-
const o
|
|
485
|
-
const cw = p.cacheCreate ?? 0
|
|
486
|
-
const cr = p.cacheRead
|
|
487
|
-
if (i === 0 && o === 0) return null
|
|
488
|
-
const safeI = Math.max(i, 1)
|
|
489
|
-
const total = i + o + cw + cr
|
|
490
|
-
const velocity = o / safeI
|
|
491
|
-
const leverage = cr / safeI
|
|
492
|
-
const yield_
|
|
493
|
-
const snr
|
|
546
|
+
if (!p) return null;
|
|
547
|
+
const i = p.input ?? 0;
|
|
548
|
+
const o = p.output ?? 0;
|
|
549
|
+
const cw = p.cacheCreate ?? 0;
|
|
550
|
+
const cr = p.cacheRead ?? 0;
|
|
551
|
+
if (i === 0 && o === 0) return null;
|
|
552
|
+
const safeI = Math.max(i, 1);
|
|
553
|
+
const total = i + o + cw + cr;
|
|
554
|
+
const velocity = o / safeI;
|
|
555
|
+
const leverage = cr / safeI;
|
|
556
|
+
const yield_ = leverage * velocity;
|
|
557
|
+
const snr = i + o > 0 ? o / (i + o) : 0;
|
|
494
558
|
// dev10x = log10(T × C × R) — only when all four pillars present
|
|
495
|
-
let dev10x = null
|
|
559
|
+
let dev10x = null;
|
|
496
560
|
if (cw > 0 && o > 0 && i > 0 && cr > 0) {
|
|
497
|
-
const T = o / i,
|
|
498
|
-
|
|
561
|
+
const T = o / i,
|
|
562
|
+
C = cw / o,
|
|
563
|
+
R = cr / cw;
|
|
564
|
+
dev10x = Math.log10(T * C * R);
|
|
499
565
|
}
|
|
500
566
|
// efficiency = ((cr+cw+o)/i) / 4.0
|
|
501
|
-
const efficiency = (
|
|
502
|
-
const cls = classify(yield_, dev10x)
|
|
503
|
-
return {
|
|
567
|
+
const efficiency = (cr + cw + o) / safeI / 4.0;
|
|
568
|
+
const cls = classify(yield_, dev10x);
|
|
569
|
+
return {
|
|
570
|
+
yield: yield_,
|
|
571
|
+
velocity,
|
|
572
|
+
leverage,
|
|
573
|
+
snr,
|
|
574
|
+
dev10x,
|
|
575
|
+
efficiency,
|
|
576
|
+
class: cls,
|
|
577
|
+
total,
|
|
578
|
+
};
|
|
504
579
|
}
|
|
505
580
|
|
|
506
|
-
async function runCompare({ platform =
|
|
507
|
-
write(HIDE_CURSOR)
|
|
581
|
+
async function runCompare({ platform = "claude" } = {}) {
|
|
582
|
+
write(HIDE_CURSOR);
|
|
508
583
|
|
|
509
584
|
// Pull all five sources in parallel (verifiers now async via execFile)
|
|
510
|
-
writeln(` ${dim(
|
|
511
|
-
const [ccPillars, tpData, tdPillars, tsPillars, apPillars] =
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
585
|
+
writeln(` ${dim("reading all 5 sources…")}`);
|
|
586
|
+
const [ccPillars, tpData, tdPillars, tsPillars, apPillars] =
|
|
587
|
+
await Promise.all([
|
|
588
|
+
ccusagePillars(platform).catch(() => null),
|
|
589
|
+
callTool("tokenpull", { platform }).catch(() => null),
|
|
590
|
+
(platform === "claude"
|
|
591
|
+
? tokenDashPillars()
|
|
592
|
+
: Promise.resolve(null)
|
|
593
|
+
).catch(() => null),
|
|
594
|
+
tokscalePillars(platform).catch(() => null),
|
|
595
|
+
Promise.resolve(platform === "claude" ? appPillars() : null),
|
|
596
|
+
]);
|
|
597
|
+
write(CURSOR_UP(1) + ERASE_LINE);
|
|
598
|
+
|
|
599
|
+
const w = termWidth();
|
|
600
|
+
const WINS = ["7d", "30d", "90d", "all"];
|
|
601
|
+
const WIN_LABEL = { "7d": "7d", "30d": "30d", "90d": "90d", all: "all-time" };
|
|
523
602
|
|
|
524
603
|
// build tokenpull pillar lookup
|
|
525
|
-
const tpPillars = {}
|
|
526
|
-
for (const win of
|
|
527
|
-
tpPillars[win.window] = win.pillars
|
|
604
|
+
const tpPillars = {};
|
|
605
|
+
for (const win of tpData?.windows ?? []) {
|
|
606
|
+
tpPillars[win.window] = win.pillars;
|
|
528
607
|
}
|
|
529
608
|
|
|
530
609
|
// sources: name, color, pillars-by-window, note
|
|
531
610
|
const SOURCES = [
|
|
532
|
-
{
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
611
|
+
{
|
|
612
|
+
name: "tokenpull",
|
|
613
|
+
color: cyan,
|
|
614
|
+
pillars: tpPillars,
|
|
615
|
+
note: "JSONL deduped by msg id · canon source",
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
name: "ccusage",
|
|
619
|
+
color: (s) => paint(c.green, s),
|
|
620
|
+
pillars: ccPillars ?? {},
|
|
621
|
+
note: "ccusage claude subcommand · monthly only",
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
name: "token-dash",
|
|
625
|
+
color: (s) => paint(c.magenta, s),
|
|
626
|
+
pillars: tdPillars ?? {},
|
|
627
|
+
note: "SQLite — double-counts sessions · use with caution",
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
name: "tokscale",
|
|
631
|
+
color: (s) => paint(c.blue, s),
|
|
632
|
+
pillars: tsPillars ?? {},
|
|
633
|
+
note: "all-time only · partial export (~5% of opus-4-8)",
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
name: "App",
|
|
637
|
+
color: gold,
|
|
638
|
+
pillars: apPillars ?? {},
|
|
639
|
+
note: "screenshots 2026-06-23 · no cache fields · update manually",
|
|
640
|
+
},
|
|
641
|
+
];
|
|
538
642
|
|
|
539
|
-
writeln()
|
|
540
|
-
writeln(
|
|
541
|
-
|
|
643
|
+
writeln();
|
|
644
|
+
writeln(
|
|
645
|
+
` ${gold("⊙ SigRank")} ${bold("Source Comparison")} ${dim(`platform: ${platform}`)} ${dim("tokenpull · ccusage · token-dash · tokscale")}`,
|
|
646
|
+
);
|
|
647
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
542
648
|
|
|
543
649
|
// ── PILLARS TABLE ──────────────────────────────────────────────────────────
|
|
544
650
|
const PILLARS = [
|
|
545
|
-
{ key:
|
|
546
|
-
{ key:
|
|
547
|
-
{ key:
|
|
548
|
-
{ key:
|
|
549
|
-
]
|
|
651
|
+
{ key: "input", label: "Input" },
|
|
652
|
+
{ key: "output", label: "Output" },
|
|
653
|
+
{ key: "cacheCreate", label: "Cache Write" },
|
|
654
|
+
{ key: "cacheRead", label: "Cache Read" },
|
|
655
|
+
];
|
|
550
656
|
|
|
551
657
|
for (const { key, label } of PILLARS) {
|
|
552
|
-
writeln()
|
|
553
|
-
writeln(` ${bold(label)}`)
|
|
554
|
-
const hcols = [
|
|
555
|
-
|
|
556
|
-
|
|
658
|
+
writeln();
|
|
659
|
+
writeln(` ${bold(label)}`);
|
|
660
|
+
const hcols = [
|
|
661
|
+
padEnd(dim("Source"), 14),
|
|
662
|
+
...WINS.map((win) => padStart(dim(WIN_LABEL[win]), 13)),
|
|
663
|
+
];
|
|
664
|
+
writeln(` ${hcols.join(" ")}`);
|
|
665
|
+
writeln(` ${dim("·".repeat(Math.min(w - 4, 14 + WINS.length * 15)))}`);
|
|
557
666
|
|
|
558
667
|
for (const src of SOURCES) {
|
|
559
|
-
const vals = WINS.map(win => {
|
|
560
|
-
const p = src.pillars[win]
|
|
561
|
-
const v = p?.[key]
|
|
562
|
-
if (v == null) return padStart(dim(
|
|
563
|
-
return padStart(fmtTokens(v), 13)
|
|
564
|
-
})
|
|
565
|
-
writeln(` ${padEnd(src.color(src.name), 14)} ${vals.join(
|
|
668
|
+
const vals = WINS.map((win) => {
|
|
669
|
+
const p = src.pillars[win];
|
|
670
|
+
const v = p?.[key];
|
|
671
|
+
if (v == null) return padStart(dim("—"), 13);
|
|
672
|
+
return padStart(fmtTokens(v), 13);
|
|
673
|
+
});
|
|
674
|
+
writeln(` ${padEnd(src.color(src.name), 14)} ${vals.join(" ")}`);
|
|
566
675
|
}
|
|
567
676
|
}
|
|
568
677
|
|
|
569
678
|
// ── SIGNATURE TABLE ────────────────────────────────────────────────────────
|
|
570
|
-
writeln()
|
|
571
|
-
writeln(` ${dim(
|
|
572
|
-
writeln(
|
|
573
|
-
|
|
679
|
+
writeln();
|
|
680
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
681
|
+
writeln(
|
|
682
|
+
` ${bold("Cascade Signature")} ${dim("per source · all windows where data available")}`,
|
|
683
|
+
);
|
|
684
|
+
writeln();
|
|
574
685
|
|
|
575
686
|
const SIG_METRICS = [
|
|
576
|
-
{ key:
|
|
577
|
-
{ key:
|
|
578
|
-
{ key:
|
|
579
|
-
{ key:
|
|
580
|
-
{ key:
|
|
581
|
-
{ key:
|
|
582
|
-
{ key:
|
|
583
|
-
]
|
|
687
|
+
{ key: "yield", label: "Υ Yield", fmt: (v) => fmtYield(v), w: 9 },
|
|
688
|
+
{ key: "velocity", label: "Vel", fmt: (v) => v.toFixed(2), w: 6 },
|
|
689
|
+
{ key: "leverage", label: "Lev", fmt: (v) => `${fmtLev(v)}×`, w: 7 },
|
|
690
|
+
{ key: "snr", label: "SNR", fmt: (v) => fmtSNR(v), w: 6 },
|
|
691
|
+
{ key: "dev10x", label: "10x", fmt: (v) => v.toFixed(2), w: 5 },
|
|
692
|
+
{ key: "efficiency", label: "Eff", fmt: (v) => v.toFixed(1), w: 6 },
|
|
693
|
+
{ key: "class", label: "Class", fmt: (v) => colorClass(v), w: 12 },
|
|
694
|
+
];
|
|
584
695
|
|
|
585
696
|
// header
|
|
586
697
|
const sigHdr = [
|
|
587
|
-
padEnd(dim(
|
|
588
|
-
padEnd(dim(
|
|
589
|
-
...SIG_METRICS.map(m => padStart(dim(m.label), m.w)),
|
|
590
|
-
]
|
|
591
|
-
writeln(` ${sigHdr.join(
|
|
592
|
-
writeln(` ${dim(
|
|
698
|
+
padEnd(dim("Source"), 14),
|
|
699
|
+
padEnd(dim("Window"), 8),
|
|
700
|
+
...SIG_METRICS.map((m) => padStart(dim(m.label), m.w)),
|
|
701
|
+
];
|
|
702
|
+
writeln(` ${sigHdr.join(" ")}`);
|
|
703
|
+
writeln(` ${dim("·".repeat(Math.min(w - 4, 80)))}`);
|
|
593
704
|
|
|
594
705
|
for (const src of SOURCES) {
|
|
595
|
-
const availWins = WINS.filter(win => src.pillars[win] != null)
|
|
706
|
+
const availWins = WINS.filter((win) => src.pillars[win] != null);
|
|
596
707
|
if (availWins.length === 0) {
|
|
597
|
-
writeln(` ${padEnd(src.color(src.name), 14)} ${dim(
|
|
598
|
-
continue
|
|
708
|
+
writeln(` ${padEnd(src.color(src.name), 14)} ${dim("no data")}`);
|
|
709
|
+
continue;
|
|
599
710
|
}
|
|
600
|
-
let first = true
|
|
711
|
+
let first = true;
|
|
601
712
|
for (const win of availWins) {
|
|
602
|
-
const p = src.pillars[win]
|
|
713
|
+
const p = src.pillars[win];
|
|
603
714
|
// For tokenpull, use the pre-computed cascade from the tool if available
|
|
604
|
-
let cas
|
|
605
|
-
if (src.name ===
|
|
606
|
-
const tpWin = tpData?.windows?.find(ww => ww.window === win)
|
|
607
|
-
cas = tpWin?.cascade
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
715
|
+
let cas;
|
|
716
|
+
if (src.name === "tokenpull") {
|
|
717
|
+
const tpWin = tpData?.windows?.find((ww) => ww.window === win);
|
|
718
|
+
cas = tpWin?.cascade
|
|
719
|
+
? {
|
|
720
|
+
yield: tpWin.cascade.yield,
|
|
721
|
+
velocity: tpWin.cascade.velocity,
|
|
722
|
+
leverage: tpWin.cascade.leverage,
|
|
723
|
+
snr: tpWin.cascade.snr,
|
|
724
|
+
dev10x: tpWin.cascade.dev10x,
|
|
725
|
+
efficiency: null,
|
|
726
|
+
class: tpWin.cascade.class,
|
|
727
|
+
}
|
|
728
|
+
: cascadeFromPillars(p);
|
|
616
729
|
} else {
|
|
617
|
-
cas = cascadeFromPillars(p)
|
|
730
|
+
cas = cascadeFromPillars(p);
|
|
618
731
|
}
|
|
619
732
|
|
|
620
|
-
const srcLabel = first
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
733
|
+
const srcLabel = first
|
|
734
|
+
? src.color(src.name)
|
|
735
|
+
: " ".repeat(stripAnsi(src.name).length);
|
|
736
|
+
const winLabel = win === "all" ? bold("all-time") : win;
|
|
737
|
+
const sigCols = SIG_METRICS.map((m) => {
|
|
738
|
+
const v = cas?.[m.key];
|
|
739
|
+
return padStart(v != null ? m.fmt(v) : dim("—"), m.w);
|
|
740
|
+
});
|
|
741
|
+
writeln(
|
|
742
|
+
` ${padEnd(srcLabel, 14)} ${padEnd(winLabel, 8)} ${sigCols.join(" ")}`,
|
|
743
|
+
);
|
|
744
|
+
first = false;
|
|
628
745
|
}
|
|
629
746
|
}
|
|
630
747
|
|
|
631
748
|
// ── NOTES ─────────────────────────────────────────────────────────────────
|
|
632
|
-
writeln()
|
|
633
|
-
writeln(` ${dim(
|
|
749
|
+
writeln();
|
|
750
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
634
751
|
for (const src of SOURCES) {
|
|
635
|
-
writeln(` ${src.color(src.name.padEnd(12))} ${dim(src.note)}`)
|
|
752
|
+
writeln(` ${src.color(src.name.padEnd(12))} ${dim(src.note)}`);
|
|
636
753
|
}
|
|
637
|
-
writeln(
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
754
|
+
writeln(
|
|
755
|
+
` ${dim("Eff = ((cacheRead+cacheWrite+output)/input)/4.0 vs AA baseline")}`,
|
|
756
|
+
);
|
|
757
|
+
writeln(
|
|
758
|
+
` ${dim("App has no cache fields → Υ/Lev/Eff/10x unavailable from App source")}`,
|
|
759
|
+
);
|
|
760
|
+
writeln();
|
|
761
|
+
write(SHOW_CURSOR);
|
|
641
762
|
}
|
|
642
763
|
|
|
643
764
|
// ── WATCH command ─────────────────────────────────────────────────────────────
|
|
@@ -648,111 +769,156 @@ async function runCompare({ platform = 'claude' } = {}) {
|
|
|
648
769
|
// refresh loop + --submit behavior are preserved; submit publishes whichever windows are
|
|
649
770
|
// shown whenever their Υ changes.
|
|
650
771
|
|
|
651
|
-
const WATCH_WINDOWS = [
|
|
772
|
+
const WATCH_WINDOWS = ["7d", "30d", "90d", "all"];
|
|
652
773
|
|
|
653
774
|
// Detect which platforms have real local data (input+output > 0 in any window) via tokenpull.
|
|
654
775
|
// Returns an array of pull results (the same shape tokenpullAny yields), one per active platform.
|
|
655
776
|
async function detectActivePulls() {
|
|
656
777
|
// Unified: one loader for me / watch / the TUI Dashboard (was a separate tokenpullAny loop).
|
|
657
|
-
return pullActivePlatforms()
|
|
778
|
+
return pullActivePlatforms();
|
|
658
779
|
}
|
|
659
780
|
|
|
660
|
-
async function runWatch({
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
781
|
+
async function runWatch({
|
|
782
|
+
platform,
|
|
783
|
+
window: win,
|
|
784
|
+
refresh = 30,
|
|
785
|
+
submit = false,
|
|
786
|
+
} = {}) {
|
|
787
|
+
let lines = 0;
|
|
788
|
+
const id = submit ? ensureIdentity() : null;
|
|
789
|
+
const enrolled = !!(
|
|
790
|
+
id &&
|
|
791
|
+
id.codename &&
|
|
792
|
+
id.operator_id &&
|
|
793
|
+
id.private_key_pkcs8_b64
|
|
794
|
+
);
|
|
664
795
|
|
|
665
796
|
// Filters: when provided, narrow the grid; when absent, watch all active × all windows.
|
|
666
|
-
const winFilter = typeof win ===
|
|
667
|
-
const platFilter = typeof platform ===
|
|
668
|
-
const windows = winFilter ? [winFilter] : WATCH_WINDOWS
|
|
797
|
+
const winFilter = typeof win === "string" && win ? win : null;
|
|
798
|
+
const platFilter = typeof platform === "string" && platform ? platform : null;
|
|
799
|
+
const windows = winFilter ? [winFilter] : WATCH_WINDOWS;
|
|
669
800
|
|
|
670
801
|
// Per-cell Υ memory (key = `${platform}|${window}`) so each cell tracks its own change.
|
|
671
|
-
const prevY = new Map()
|
|
672
|
-
const lastSubmitMsg = new Map()
|
|
802
|
+
const prevY = new Map();
|
|
803
|
+
const lastSubmitMsg = new Map();
|
|
673
804
|
|
|
674
|
-
write(HIDE_CURSOR)
|
|
805
|
+
write(HIDE_CURSOR);
|
|
675
806
|
|
|
676
807
|
const draw = async () => {
|
|
677
808
|
// Re-detect each tick so a platform that just started writing logs appears automatically.
|
|
678
|
-
let pulls = await detectActivePulls().catch(() => [])
|
|
679
|
-
if (platFilter) pulls = pulls.filter((d) => d.platform === platFilter)
|
|
809
|
+
let pulls = await detectActivePulls().catch(() => []);
|
|
810
|
+
if (platFilter) pulls = pulls.filter((d) => d.platform === platFilter);
|
|
680
811
|
|
|
681
|
-
if (lines > 0) write(CURSOR_UP(lines))
|
|
812
|
+
if (lines > 0) write(CURSOR_UP(lines));
|
|
682
813
|
|
|
683
|
-
const out = []
|
|
684
|
-
const push = (s =
|
|
685
|
-
const w = termWidth()
|
|
686
|
-
const ts = new Date().toLocaleTimeString(
|
|
814
|
+
const out = [];
|
|
815
|
+
const push = (s = "") => out.push(s);
|
|
816
|
+
const w = termWidth();
|
|
817
|
+
const ts = new Date().toLocaleTimeString("en-US", { hour12: false });
|
|
687
818
|
|
|
688
|
-
const scopeLabel =
|
|
819
|
+
const scopeLabel =
|
|
820
|
+
(platFilter || "all active platforms") +
|
|
821
|
+
" · " +
|
|
822
|
+
(winFilter ? `window: ${winFilter}` : "all windows");
|
|
689
823
|
|
|
690
|
-
push()
|
|
691
|
-
push(
|
|
692
|
-
|
|
824
|
+
push();
|
|
825
|
+
push(
|
|
826
|
+
` ${gold("⊙ SigRank")} ${bold("Watch")} ${dim(`${scopeLabel} · ${ts}`)}`,
|
|
827
|
+
);
|
|
828
|
+
push(` ${dim("─".repeat(w - 4))}`);
|
|
693
829
|
|
|
694
830
|
if (pulls.length === 0) {
|
|
695
|
-
push()
|
|
696
|
-
push(
|
|
697
|
-
|
|
831
|
+
push();
|
|
832
|
+
push(
|
|
833
|
+
` ${dim("no active platforms detected — run some sessions, this will pick them up automatically")}`,
|
|
834
|
+
);
|
|
835
|
+
push();
|
|
698
836
|
}
|
|
699
837
|
|
|
700
838
|
for (const d of pulls) {
|
|
701
|
-
const plat = d.platform
|
|
702
|
-
const byWin = {}
|
|
703
|
-
for (const ww of
|
|
704
|
-
push()
|
|
705
|
-
push(` ${cyan(plat)}${d.estimated ? dim(
|
|
839
|
+
const plat = d.platform;
|
|
840
|
+
const byWin = {};
|
|
841
|
+
for (const ww of d.windows || []) byWin[ww.window] = ww;
|
|
842
|
+
push();
|
|
843
|
+
push(` ${cyan(plat)}${d.estimated ? dim(" (est)") : ""}`);
|
|
706
844
|
for (const wk of windows) {
|
|
707
|
-
const ww = byWin[wk]
|
|
708
|
-
const cas = ww ? cascadeFromPillars(ww.pillars) : null
|
|
709
|
-
const key = `${plat}|${wk}
|
|
710
|
-
const prev = prevY.get(key)
|
|
711
|
-
const yNow = cas?.yield ?? null
|
|
712
|
-
const changed = prev !== undefined && prev !== yNow
|
|
845
|
+
const ww = byWin[wk];
|
|
846
|
+
const cas = ww ? cascadeFromPillars(ww.pillars) : null;
|
|
847
|
+
const key = `${plat}|${wk}`;
|
|
848
|
+
const prev = prevY.get(key);
|
|
849
|
+
const yNow = cas?.yield ?? null;
|
|
850
|
+
const changed = prev !== undefined && prev !== yNow;
|
|
713
851
|
|
|
714
852
|
// --submit: publish this cell on first observation + whenever its Υ changes.
|
|
715
|
-
if (
|
|
853
|
+
if (
|
|
854
|
+
submit &&
|
|
855
|
+
enrolled &&
|
|
856
|
+
ww &&
|
|
857
|
+
yNow != null &&
|
|
858
|
+
(prev === undefined || changed)
|
|
859
|
+
) {
|
|
716
860
|
try {
|
|
717
|
-
const r = await submitSignedWindow(
|
|
718
|
-
|
|
861
|
+
const r = await submitSignedWindow(
|
|
862
|
+
wk,
|
|
863
|
+
ww.pillars,
|
|
864
|
+
ww.messages,
|
|
865
|
+
id,
|
|
866
|
+
{ platform: plat },
|
|
867
|
+
);
|
|
868
|
+
lastSubmitMsg.set(
|
|
869
|
+
key,
|
|
870
|
+
r.status === "received"
|
|
871
|
+
? green(`✓ tier=${r.verification_tier || "—"}`)
|
|
872
|
+
: red(`✗ ${r.reason || r.status}`),
|
|
873
|
+
);
|
|
719
874
|
} catch (e) {
|
|
720
|
-
lastSubmitMsg.set(key, red(`✗ ${e.message}`))
|
|
875
|
+
lastSubmitMsg.set(key, red(`✗ ${e.message}`));
|
|
721
876
|
}
|
|
722
877
|
}
|
|
723
|
-
prevY.set(key, yNow)
|
|
878
|
+
prevY.set(key, yNow);
|
|
724
879
|
|
|
725
|
-
const winLabel = wk ===
|
|
726
|
-
const yDisplay =
|
|
727
|
-
|
|
880
|
+
const winLabel = wk === "all" ? "all-time" : wk;
|
|
881
|
+
const yDisplay =
|
|
882
|
+
cas?.yield != null ? gold(fmtYield(cas.yield)) : dim("—");
|
|
883
|
+
const indicator = changed ? green(" ▲") : dim(" ·");
|
|
728
884
|
const metrics = cas
|
|
729
|
-
? `${dim(
|
|
730
|
-
: dim(
|
|
731
|
-
const submitNote =
|
|
732
|
-
|
|
885
|
+
? `${dim("SNR")} ${fmtSNR(cas.snr)} ${dim("Lev")} ${cas.leverage != null ? fmtLev(cas.leverage) + "×" : "—"} ${dim("Vel")} ${cas.velocity != null ? cas.velocity.toFixed(2) : "—"} ${colorClass(cas.class ?? "—")}`
|
|
886
|
+
: dim("no data");
|
|
887
|
+
const submitNote =
|
|
888
|
+
submit && enrolled ? " " + (lastSubmitMsg.get(key) || dim("…")) : "";
|
|
889
|
+
push(
|
|
890
|
+
` ${padEnd(winLabel, 8)} ${bold("Υ")} ${yDisplay}${indicator} ${metrics}${submitNote}`,
|
|
891
|
+
);
|
|
733
892
|
}
|
|
734
893
|
}
|
|
735
894
|
|
|
736
|
-
push()
|
|
737
|
-
push(` ${dim(
|
|
895
|
+
push();
|
|
896
|
+
push(` ${dim("─".repeat(w - 4))}`);
|
|
738
897
|
if (submit && !enrolled) {
|
|
739
|
-
push(
|
|
898
|
+
push(
|
|
899
|
+
` ${red("not enrolled — run `npx sigrank enroll` to auto-submit")}`,
|
|
900
|
+
);
|
|
740
901
|
}
|
|
741
|
-
push(
|
|
742
|
-
|
|
902
|
+
push(
|
|
903
|
+
` ${dim(`polling every ${refresh}s · ${submit ? "auto-submit ON · " : ""}tokens stay on your machine · ctrl+c to exit`)}`,
|
|
904
|
+
);
|
|
905
|
+
push();
|
|
743
906
|
|
|
744
|
-
write(out.join(
|
|
745
|
-
lines = out.length
|
|
746
|
-
}
|
|
907
|
+
write(out.join("\n"));
|
|
908
|
+
lines = out.length;
|
|
909
|
+
};
|
|
747
910
|
|
|
748
911
|
try {
|
|
749
|
-
await draw()
|
|
750
|
-
const iv = setInterval(draw, refresh * 1000)
|
|
912
|
+
await draw();
|
|
913
|
+
const iv = setInterval(draw, refresh * 1000);
|
|
751
914
|
await new Promise((resolve) => {
|
|
752
|
-
process.on(
|
|
753
|
-
|
|
915
|
+
process.on("SIGINT", () => {
|
|
916
|
+
clearInterval(iv);
|
|
917
|
+
resolve();
|
|
918
|
+
});
|
|
919
|
+
});
|
|
754
920
|
} finally {
|
|
755
|
-
write(SHOW_CURSOR +
|
|
921
|
+
write(SHOW_CURSOR + "\n");
|
|
756
922
|
}
|
|
757
923
|
}
|
|
758
924
|
|
|
@@ -766,26 +932,39 @@ async function runWatch({ platform, window: win, refresh = 30, submit = false }
|
|
|
766
932
|
// - [S] submit [B] board [Q] quit
|
|
767
933
|
|
|
768
934
|
const ALL_PLATFORMS = [
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
935
|
+
"claude",
|
|
936
|
+
"codex",
|
|
937
|
+
"amp",
|
|
938
|
+
"gemini",
|
|
939
|
+
"kimi",
|
|
940
|
+
"qwen",
|
|
941
|
+
"goose",
|
|
942
|
+
"kilo",
|
|
943
|
+
"hermes",
|
|
944
|
+
"droid",
|
|
945
|
+
"codebuff",
|
|
946
|
+
"copilot",
|
|
947
|
+
"openclaw",
|
|
948
|
+
"pi",
|
|
949
|
+
];
|
|
772
950
|
|
|
773
951
|
async function runSigRank() {
|
|
774
|
-
write(HIDE_CURSOR)
|
|
775
|
-
const w = termWidth()
|
|
952
|
+
write(HIDE_CURSOR);
|
|
953
|
+
const w = termWidth();
|
|
776
954
|
|
|
777
955
|
// ── 1. Show immediate header so screen isn't blank ────────────────────────
|
|
778
|
-
writeln()
|
|
779
|
-
writeln(` ${gold(
|
|
780
|
-
writeln(` ${dim(
|
|
956
|
+
writeln();
|
|
957
|
+
writeln(` ${gold("⊙ SigRank")} ${bold("Operator Dashboard")}`);
|
|
958
|
+
writeln(` ${dim("reading local data…")}`);
|
|
781
959
|
|
|
782
|
-
const { tokenpullAny, freshVerifierPillars } =
|
|
960
|
+
const { tokenpullAny, freshVerifierPillars } =
|
|
961
|
+
await import("./tokenpull.mjs");
|
|
783
962
|
|
|
784
963
|
// Local sources first (fast) — board fetch with 5s timeout runs in parallel
|
|
785
964
|
const boardPromise = Promise.race([
|
|
786
|
-
callTool(
|
|
787
|
-
new Promise(r => setTimeout(() => r(null), 5000)),
|
|
788
|
-
])
|
|
965
|
+
callTool("get_leaderboard", {}).catch(() => null),
|
|
966
|
+
new Promise((r) => setTimeout(() => r(null), 5000)),
|
|
967
|
+
]);
|
|
789
968
|
|
|
790
969
|
// FIX A1-CLI (2026-06-27): verifiers (ccusage/tokscale/tokendash) are fetched
|
|
791
970
|
// ON-DEMAND for ACTIVE platforms only — not synchronously for all 15 platforms
|
|
@@ -794,360 +973,506 @@ async function runSigRank() {
|
|
|
794
973
|
// over ALL_PLATFORMS is replaced by parallel freshVerifierPillars() calls after
|
|
795
974
|
// we know which platforms actually have local data.
|
|
796
975
|
const [platformResults] = await Promise.all([
|
|
797
|
-
Promise.allSettled(ALL_PLATFORMS.map(p => tokenpullAny(p))),
|
|
798
|
-
])
|
|
976
|
+
Promise.allSettled(ALL_PLATFORMS.map((p) => tokenpullAny(p))),
|
|
977
|
+
]);
|
|
799
978
|
|
|
800
|
-
const boardData = await boardPromise
|
|
979
|
+
const boardData = await boardPromise;
|
|
801
980
|
|
|
802
981
|
// filter to platforms with actual data
|
|
803
|
-
const active = []
|
|
982
|
+
const active = [];
|
|
804
983
|
for (let i = 0; i < ALL_PLATFORMS.length; i++) {
|
|
805
|
-
const r = platformResults[i]
|
|
806
|
-
if (r.status !==
|
|
807
|
-
const d = r.value
|
|
808
|
-
const all = d.windows?.find(w => w.window ===
|
|
809
|
-
if (!all) continue
|
|
810
|
-
const total = (all.pillars.input ?? 0) + (all.pillars.output ?? 0)
|
|
811
|
-
if (total === 0) continue
|
|
812
|
-
active.push(d)
|
|
984
|
+
const r = platformResults[i];
|
|
985
|
+
if (r.status !== "fulfilled") continue;
|
|
986
|
+
const d = r.value;
|
|
987
|
+
const all = d.windows?.find((w) => w.window === "all");
|
|
988
|
+
if (!all) continue;
|
|
989
|
+
const total = (all.pillars.input ?? 0) + (all.pillars.output ?? 0);
|
|
990
|
+
if (total === 0) continue;
|
|
991
|
+
active.push(d);
|
|
813
992
|
}
|
|
814
993
|
|
|
815
994
|
// Fetch verifiers on-demand for active platforms only (parallel, never throws).
|
|
816
995
|
// tdPillars (token-dashboard) is claude-only and pulled from the claude fresh result.
|
|
817
|
-
const verifierMap = {}
|
|
818
|
-
let tdPillars = null
|
|
996
|
+
const verifierMap = {};
|
|
997
|
+
let tdPillars = null;
|
|
819
998
|
if (active.length > 0) {
|
|
820
999
|
const fresh = await Promise.all(
|
|
821
|
-
active.map(
|
|
822
|
-
|
|
1000
|
+
active.map((d) =>
|
|
1001
|
+
freshVerifierPillars(d.platform).catch(() => ({
|
|
1002
|
+
ccusage: null,
|
|
1003
|
+
tokscale: null,
|
|
1004
|
+
tokendash: null,
|
|
1005
|
+
})),
|
|
1006
|
+
),
|
|
1007
|
+
);
|
|
823
1008
|
for (let i = 0; i < active.length; i++) {
|
|
824
|
-
const f = fresh[i]
|
|
825
|
-
verifierMap[active[i].platform] = { cc: f.ccusage, ts: f.tokscale }
|
|
826
|
-
if (active[i].platform ===
|
|
1009
|
+
const f = fresh[i];
|
|
1010
|
+
verifierMap[active[i].platform] = { cc: f.ccusage, ts: f.tokscale };
|
|
1011
|
+
if (active[i].platform === "claude" && f.tokendash)
|
|
1012
|
+
tdPillars = f.tokendash;
|
|
827
1013
|
}
|
|
828
1014
|
}
|
|
829
1015
|
|
|
830
1016
|
// clear the 3 loading lines (blank + header + "reading…")
|
|
831
|
-
write(
|
|
1017
|
+
write(
|
|
1018
|
+
CURSOR_UP(3) +
|
|
1019
|
+
ERASE_LINE +
|
|
1020
|
+
CURSOR_UP(1) +
|
|
1021
|
+
ERASE_LINE +
|
|
1022
|
+
CURSOR_UP(1) +
|
|
1023
|
+
ERASE_LINE,
|
|
1024
|
+
);
|
|
832
1025
|
|
|
833
1026
|
// ── 2. Header ─────────────────────────────────────────────────────────────
|
|
834
|
-
const ts = new Date().toLocaleTimeString(
|
|
835
|
-
const header = ` ${gold(
|
|
836
|
-
const right = dim(`signalaf.com ${ts}`)
|
|
837
|
-
const gap = Math.max(
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
1027
|
+
const ts = new Date().toLocaleTimeString("en-US", { hour12: false });
|
|
1028
|
+
const header = ` ${gold("⊙ SigRank")} ${bold("Operator Dashboard")}`;
|
|
1029
|
+
const right = dim(`signalaf.com ${ts}`);
|
|
1030
|
+
const gap = Math.max(
|
|
1031
|
+
1,
|
|
1032
|
+
w - stripAnsi(header).length - stripAnsi(right).length,
|
|
1033
|
+
);
|
|
1034
|
+
writeln();
|
|
1035
|
+
writeln(`${header}${" ".repeat(gap)}${right}`);
|
|
1036
|
+
|
|
1037
|
+
const platformSummary = active
|
|
1038
|
+
.map((d) => {
|
|
1039
|
+
const all = d.windows.find((w) => w.window === "all");
|
|
1040
|
+
return `${cyan(d.platform)} ${dim(`${d.files ?? "?"} files · ${(all?.messages ?? 0).toLocaleString()} msgs`)}`;
|
|
1041
|
+
})
|
|
1042
|
+
.join(" ");
|
|
1043
|
+
writeln(
|
|
1044
|
+
` ${dim("Detected:")} ${platformSummary || dim("no local data found")}`,
|
|
1045
|
+
);
|
|
1046
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
847
1047
|
|
|
848
1048
|
// ── 3. Cascade table — all platforms × all windows ─────────────────────────
|
|
849
|
-
writeln()
|
|
850
|
-
writeln(` ${bold(
|
|
1049
|
+
writeln();
|
|
1050
|
+
writeln(` ${bold("Your Cascade")}`);
|
|
851
1051
|
const CH = [
|
|
852
|
-
padEnd(dim(
|
|
853
|
-
padEnd(dim(
|
|
854
|
-
padStart(dim(
|
|
855
|
-
padStart(dim(
|
|
856
|
-
padStart(dim(
|
|
857
|
-
padStart(dim(
|
|
858
|
-
padStart(dim(
|
|
859
|
-
padStart(dim(
|
|
860
|
-
padStart(dim(
|
|
861
|
-
padStart(dim(
|
|
862
|
-
padStart(dim(
|
|
863
|
-
padEnd(dim(
|
|
864
|
-
]
|
|
865
|
-
writeln(` ${CH.join(
|
|
866
|
-
writeln(` ${dim(
|
|
867
|
-
|
|
868
|
-
const WINS = [
|
|
1052
|
+
padEnd(dim("Platform"), 10),
|
|
1053
|
+
padEnd(dim("Win"), 5),
|
|
1054
|
+
padStart(dim("Input"), 8),
|
|
1055
|
+
padStart(dim("Output"), 8),
|
|
1056
|
+
padStart(dim("CacheW"), 8),
|
|
1057
|
+
padStart(dim("CacheR"), 9),
|
|
1058
|
+
padStart(dim("Υ Yield"), 9),
|
|
1059
|
+
padStart(dim("SNR"), 7),
|
|
1060
|
+
padStart(dim("Leverage"), 10),
|
|
1061
|
+
padStart(dim("Vel"), 6),
|
|
1062
|
+
padStart(dim("10x"), 6),
|
|
1063
|
+
padEnd(dim("Class"), 13),
|
|
1064
|
+
];
|
|
1065
|
+
writeln(` ${CH.join(" ")}`);
|
|
1066
|
+
writeln(` ${dim("·".repeat(Math.min(w - 4, 110)))}`);
|
|
1067
|
+
|
|
1068
|
+
const WINS = ["7d", "30d", "90d", "all"];
|
|
869
1069
|
|
|
870
1070
|
// helper to render one platform/combined row
|
|
871
1071
|
const renderCascadeRow = (label, labelColorFn, winKey, p, est = false) => {
|
|
872
|
-
const cas = cascadeFromPillars(p)
|
|
873
|
-
if (!cas) return
|
|
874
|
-
const clsFn = CLASS_COLOR[cas.class] ?? ((s) => s)
|
|
1072
|
+
const cas = cascadeFromPillars(p);
|
|
1073
|
+
if (!cas) return;
|
|
1074
|
+
const clsFn = CLASS_COLOR[cas.class] ?? ((s) => s);
|
|
875
1075
|
const cols = [
|
|
876
1076
|
padEnd(labelColorFn(label), 10),
|
|
877
1077
|
padEnd(dim(winKey), 5),
|
|
878
|
-
padStart(est ? dim(
|
|
1078
|
+
padStart(est ? dim("~") + fmtTokens(p.input) : fmtTokens(p.input), 8),
|
|
879
1079
|
padStart(fmtTokens(p.output), 8),
|
|
880
|
-
padStart(
|
|
881
|
-
|
|
882
|
-
|
|
1080
|
+
padStart(
|
|
1081
|
+
p.cacheCreate > 0
|
|
1082
|
+
? est
|
|
1083
|
+
? dim("~") + fmtTokens(p.cacheCreate)
|
|
1084
|
+
: fmtTokens(p.cacheCreate)
|
|
1085
|
+
: dim("—"),
|
|
1086
|
+
8,
|
|
1087
|
+
),
|
|
1088
|
+
padStart(p.cacheRead > 0 ? fmtTokens(p.cacheRead) : dim("—"), 9),
|
|
1089
|
+
padStart(
|
|
1090
|
+
cas.yield != null
|
|
1091
|
+
? cas.yield > 10000
|
|
1092
|
+
? gold(fmtYield(cas.yield))
|
|
1093
|
+
: fmtYield(cas.yield)
|
|
1094
|
+
: "—",
|
|
1095
|
+
9,
|
|
1096
|
+
),
|
|
883
1097
|
padStart(fmtSNR(cas.snr), 7),
|
|
884
|
-
padStart(cas.leverage != null ? `${fmtLev(cas.leverage)}×` :
|
|
885
|
-
padStart(cas.velocity != null ? cas.velocity.toFixed(2) :
|
|
886
|
-
padStart(cas.dev10x
|
|
1098
|
+
padStart(cas.leverage != null ? `${fmtLev(cas.leverage)}×` : "—", 10),
|
|
1099
|
+
padStart(cas.velocity != null ? cas.velocity.toFixed(2) : "—", 6),
|
|
1100
|
+
padStart(cas.dev10x != null ? cas.dev10x.toFixed(2) : "—", 6),
|
|
887
1101
|
padEnd(clsFn(cas.class), 13),
|
|
888
|
-
]
|
|
889
|
-
writeln(` ${cols.join(
|
|
890
|
-
}
|
|
1102
|
+
];
|
|
1103
|
+
writeln(` ${cols.join(" ")}`);
|
|
1104
|
+
};
|
|
891
1105
|
|
|
892
1106
|
// per-platform rows
|
|
893
1107
|
for (const d of active) {
|
|
894
|
-
const isFirst = (winKey) =>
|
|
1108
|
+
const isFirst = (winKey) =>
|
|
1109
|
+
winKey === "7d" ||
|
|
1110
|
+
(winKey === "30d" &&
|
|
1111
|
+
!d.windows?.find(
|
|
1112
|
+
(w) => w.window === "7d" && w.pillars.input + w.pillars.output > 0,
|
|
1113
|
+
));
|
|
895
1114
|
for (const winKey of WINS) {
|
|
896
|
-
const wdata = d.windows?.find(ww => ww.window === winKey)
|
|
897
|
-
if (!wdata) continue
|
|
1115
|
+
const wdata = d.windows?.find((ww) => ww.window === winKey);
|
|
1116
|
+
if (!wdata) continue;
|
|
898
1117
|
renderCascadeRow(
|
|
899
1118
|
d.platform,
|
|
900
|
-
(s) => isFirst(winKey) ? cyan(s) : dim(s),
|
|
1119
|
+
(s) => (isFirst(winKey) ? cyan(s) : dim(s)),
|
|
901
1120
|
winKey,
|
|
902
1121
|
wdata.pillars,
|
|
903
1122
|
d.estimated === true,
|
|
904
|
-
)
|
|
1123
|
+
);
|
|
905
1124
|
}
|
|
906
|
-
writeln()
|
|
1125
|
+
writeln();
|
|
907
1126
|
}
|
|
908
1127
|
|
|
909
1128
|
// combined row (only when 2+ platforms active)
|
|
910
1129
|
if (active.length > 1) {
|
|
911
|
-
const combinedLabel = active.map(d => d.platform).join(
|
|
912
|
-
const hasEstimated = active.some(d => d.estimated === true)
|
|
913
|
-
let isFirstWin = true
|
|
1130
|
+
const combinedLabel = active.map((d) => d.platform).join("+");
|
|
1131
|
+
const hasEstimated = active.some((d) => d.estimated === true);
|
|
1132
|
+
let isFirstWin = true;
|
|
914
1133
|
for (const winKey of WINS) {
|
|
915
|
-
const combinedP = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 }
|
|
916
|
-
let hasData = false
|
|
1134
|
+
const combinedP = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 };
|
|
1135
|
+
let hasData = false;
|
|
917
1136
|
for (const d of active) {
|
|
918
|
-
const wdata = d.windows?.find(ww => ww.window === winKey)
|
|
919
|
-
if (!wdata) continue
|
|
920
|
-
const p = wdata.pillars
|
|
921
|
-
if (
|
|
922
|
-
combinedP.input
|
|
923
|
-
combinedP.output
|
|
924
|
-
combinedP.cacheCreate += p.cacheCreate ?? 0
|
|
925
|
-
combinedP.cacheRead
|
|
926
|
-
hasData = true
|
|
1137
|
+
const wdata = d.windows?.find((ww) => ww.window === winKey);
|
|
1138
|
+
if (!wdata) continue;
|
|
1139
|
+
const p = wdata.pillars;
|
|
1140
|
+
if (p.input + p.output === 0) continue;
|
|
1141
|
+
combinedP.input += p.input ?? 0;
|
|
1142
|
+
combinedP.output += p.output ?? 0;
|
|
1143
|
+
combinedP.cacheCreate += p.cacheCreate ?? 0;
|
|
1144
|
+
combinedP.cacheRead += p.cacheRead ?? 0;
|
|
1145
|
+
hasData = true;
|
|
927
1146
|
}
|
|
928
|
-
if (!hasData) continue
|
|
1147
|
+
if (!hasData) continue;
|
|
929
1148
|
renderCascadeRow(
|
|
930
1149
|
combinedLabel,
|
|
931
|
-
(s) => isFirstWin ? bold(cyan(s)) : dim(s),
|
|
1150
|
+
(s) => (isFirstWin ? bold(cyan(s)) : dim(s)),
|
|
932
1151
|
winKey,
|
|
933
1152
|
combinedP,
|
|
934
1153
|
hasEstimated,
|
|
935
|
-
)
|
|
936
|
-
isFirstWin = false
|
|
1154
|
+
);
|
|
1155
|
+
isFirstWin = false;
|
|
937
1156
|
}
|
|
938
|
-
writeln()
|
|
1157
|
+
writeln();
|
|
939
1158
|
}
|
|
940
1159
|
|
|
941
1160
|
// ── 4. Token Pillars — per-platform verification + combined ──────────────
|
|
942
|
-
writeln(` ${dim(
|
|
943
|
-
writeln()
|
|
944
|
-
writeln(
|
|
1161
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
1162
|
+
writeln();
|
|
1163
|
+
writeln(
|
|
1164
|
+
` ${bold("Token Pillars")} ${dim("(all-time · per-platform verification)")}`,
|
|
1165
|
+
);
|
|
945
1166
|
|
|
946
1167
|
const PCOLS = [
|
|
947
|
-
padEnd(dim(
|
|
948
|
-
padStart(dim(
|
|
949
|
-
padStart(dim(
|
|
950
|
-
padStart(dim(
|
|
951
|
-
padStart(dim(
|
|
952
|
-
padStart(dim(
|
|
953
|
-
]
|
|
954
|
-
writeln(` ${PCOLS.join(
|
|
955
|
-
writeln(` ${dim(
|
|
956
|
-
|
|
957
|
-
const printPillarRow = (label, colorFn, p, note =
|
|
958
|
-
if (!p) return
|
|
959
|
-
const i
|
|
960
|
-
const o
|
|
961
|
-
const cw = p.cacheCreate ?? 0
|
|
962
|
-
const cr = p.cacheRead
|
|
963
|
-
const total = i + o + cw + cr
|
|
1168
|
+
padEnd(dim("Source"), 14),
|
|
1169
|
+
padStart(dim("Input"), 10),
|
|
1170
|
+
padStart(dim("Output"), 10),
|
|
1171
|
+
padStart(dim("Cache Write"), 12),
|
|
1172
|
+
padStart(dim("Cache Read"), 12),
|
|
1173
|
+
padStart(dim("Total"), 10),
|
|
1174
|
+
];
|
|
1175
|
+
writeln(` ${PCOLS.join(" ")}`);
|
|
1176
|
+
writeln(` ${dim("·".repeat(Math.min(w - 4, 74)))}`);
|
|
1177
|
+
|
|
1178
|
+
const printPillarRow = (label, colorFn, p, note = "") => {
|
|
1179
|
+
if (!p) return;
|
|
1180
|
+
const i = p.input ?? 0;
|
|
1181
|
+
const o = p.output ?? 0;
|
|
1182
|
+
const cw = p.cacheCreate ?? 0;
|
|
1183
|
+
const cr = p.cacheRead ?? 0;
|
|
1184
|
+
const total = i + o + cw + cr;
|
|
964
1185
|
const cols = [
|
|
965
1186
|
padEnd(colorFn(label), 14),
|
|
966
|
-
padStart(fmtTokens(i),
|
|
967
|
-
padStart(fmtTokens(o),
|
|
968
|
-
padStart(cw > 0 ? fmtTokens(cw) : dim(
|
|
969
|
-
padStart(cr > 0 ? fmtTokens(cr) : dim(
|
|
1187
|
+
padStart(fmtTokens(i), 10),
|
|
1188
|
+
padStart(fmtTokens(o), 10),
|
|
1189
|
+
padStart(cw > 0 ? fmtTokens(cw) : dim("—"), 12),
|
|
1190
|
+
padStart(cr > 0 ? fmtTokens(cr) : dim("—"), 12),
|
|
970
1191
|
padStart(fmtTokens(total), 10),
|
|
971
|
-
]
|
|
972
|
-
writeln(` ${cols.join(
|
|
973
|
-
}
|
|
1192
|
+
];
|
|
1193
|
+
writeln(` ${cols.join(" ")}${note ? " " + dim(note) : ""}`);
|
|
1194
|
+
};
|
|
974
1195
|
|
|
975
1196
|
// ── Per-platform blocks ─────────────────────────────────────────────────
|
|
976
1197
|
for (const d of active) {
|
|
977
|
-
const all = d.windows?.find(ww => ww.window ===
|
|
978
|
-
if (!all) continue
|
|
979
|
-
const v = verifierMap[d.platform] ?? {}
|
|
980
|
-
const estMarker = d.estimated ? dim(
|
|
981
|
-
printPillarRow(d.platform, cyan, all.pillars, `tokenpull${estMarker}`)
|
|
1198
|
+
const all = d.windows?.find((ww) => ww.window === "all");
|
|
1199
|
+
if (!all) continue;
|
|
1200
|
+
const v = verifierMap[d.platform] ?? {};
|
|
1201
|
+
const estMarker = d.estimated ? dim(" ~ estimated") : "";
|
|
1202
|
+
printPillarRow(d.platform, cyan, all.pillars, `tokenpull${estMarker}`);
|
|
982
1203
|
if (d.estimated) {
|
|
983
1204
|
// show the estimation formula inline
|
|
984
|
-
const ratio = d.ioRatio != null ? d.ioRatio.toFixed(3) :
|
|
985
|
-
writeln(
|
|
1205
|
+
const ratio = d.ioRatio != null ? d.ioRatio.toFixed(3) : "?";
|
|
1206
|
+
writeln(
|
|
1207
|
+
` ${dim(` ~ input = output × ioRatio(${ratio}) cacheCreate = uncached − input cacheRead = exact`)}`,
|
|
1208
|
+
);
|
|
986
1209
|
}
|
|
987
|
-
if (v.cc?.all)
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1210
|
+
if (v.cc?.all)
|
|
1211
|
+
printPillarRow(
|
|
1212
|
+
" ccusage",
|
|
1213
|
+
(s) => paint(c.green, s),
|
|
1214
|
+
v.cc.all,
|
|
1215
|
+
"ccusage CLI",
|
|
1216
|
+
);
|
|
1217
|
+
if (d.platform === "claude" && tdPillars?.all)
|
|
1218
|
+
printPillarRow(
|
|
1219
|
+
" token-dash",
|
|
1220
|
+
(s) => paint(c.magenta, s),
|
|
1221
|
+
tdPillars.all,
|
|
1222
|
+
"token-dashboard.db",
|
|
1223
|
+
);
|
|
1224
|
+
if (v.ts?.all)
|
|
1225
|
+
printPillarRow(
|
|
1226
|
+
" tokscale",
|
|
1227
|
+
(s) => paint(c.blue, s),
|
|
1228
|
+
v.ts.all,
|
|
1229
|
+
"tokscale_report.json",
|
|
1230
|
+
);
|
|
991
1231
|
if (d.estimated && (v.cc?.all || v.ts?.all)) {
|
|
992
|
-
writeln(
|
|
1232
|
+
writeln(
|
|
1233
|
+
` ${dim(" ^ verifiers show raw uncached input (input_tokens − cached) — different field than estimated input above")}`,
|
|
1234
|
+
);
|
|
993
1235
|
}
|
|
994
|
-
writeln()
|
|
1236
|
+
writeln();
|
|
995
1237
|
}
|
|
996
1238
|
|
|
997
1239
|
// ── Combined (if more than one platform) ───────────────────────────────
|
|
998
1240
|
if (active.length > 1) {
|
|
999
|
-
const combined = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 }
|
|
1241
|
+
const combined = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 };
|
|
1000
1242
|
for (const d of active) {
|
|
1001
|
-
const all = d.windows?.find(ww => ww.window ===
|
|
1002
|
-
if (!all) continue
|
|
1003
|
-
combined.input
|
|
1004
|
-
combined.output
|
|
1005
|
-
combined.cacheCreate += all.pillars.cacheCreate ?? 0
|
|
1006
|
-
combined.cacheRead
|
|
1243
|
+
const all = d.windows?.find((ww) => ww.window === "all");
|
|
1244
|
+
if (!all) continue;
|
|
1245
|
+
combined.input += all.pillars.input ?? 0;
|
|
1246
|
+
combined.output += all.pillars.output ?? 0;
|
|
1247
|
+
combined.cacheCreate += all.pillars.cacheCreate ?? 0;
|
|
1248
|
+
combined.cacheRead += all.pillars.cacheRead ?? 0;
|
|
1007
1249
|
}
|
|
1008
1250
|
// sum verifiers across all active platforms
|
|
1009
|
-
const ccCombined = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 }
|
|
1010
|
-
const tsCombined = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 }
|
|
1011
|
-
let hasCc = false,
|
|
1251
|
+
const ccCombined = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 };
|
|
1252
|
+
const tsCombined = { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 };
|
|
1253
|
+
let hasCc = false,
|
|
1254
|
+
hasTs = false;
|
|
1012
1255
|
for (const d of active) {
|
|
1013
|
-
const v = verifierMap[d.platform] ?? {}
|
|
1256
|
+
const v = verifierMap[d.platform] ?? {};
|
|
1014
1257
|
if (v.cc?.all) {
|
|
1015
|
-
ccCombined.input
|
|
1016
|
-
ccCombined.output
|
|
1017
|
-
ccCombined.cacheCreate += v.cc.all.cacheCreate ?? 0
|
|
1018
|
-
ccCombined.cacheRead
|
|
1019
|
-
hasCc = true
|
|
1258
|
+
ccCombined.input += v.cc.all.input ?? 0;
|
|
1259
|
+
ccCombined.output += v.cc.all.output ?? 0;
|
|
1260
|
+
ccCombined.cacheCreate += v.cc.all.cacheCreate ?? 0;
|
|
1261
|
+
ccCombined.cacheRead += v.cc.all.cacheRead ?? 0;
|
|
1262
|
+
hasCc = true;
|
|
1020
1263
|
}
|
|
1021
1264
|
if (v.ts?.all) {
|
|
1022
|
-
tsCombined.input
|
|
1023
|
-
tsCombined.output
|
|
1024
|
-
tsCombined.cacheCreate += v.ts.all.cacheCreate ?? 0
|
|
1025
|
-
tsCombined.cacheRead
|
|
1026
|
-
hasTs = true
|
|
1265
|
+
tsCombined.input += v.ts.all.input ?? 0;
|
|
1266
|
+
tsCombined.output += v.ts.all.output ?? 0;
|
|
1267
|
+
tsCombined.cacheCreate += v.ts.all.cacheCreate ?? 0;
|
|
1268
|
+
tsCombined.cacheRead += v.ts.all.cacheRead ?? 0;
|
|
1269
|
+
hasTs = true;
|
|
1027
1270
|
}
|
|
1028
1271
|
}
|
|
1029
|
-
printPillarRow(
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1272
|
+
printPillarRow(
|
|
1273
|
+
"combined",
|
|
1274
|
+
(s) => bold(s),
|
|
1275
|
+
combined,
|
|
1276
|
+
active.map((d) => d.platform).join("+"),
|
|
1277
|
+
);
|
|
1278
|
+
if (hasCc)
|
|
1279
|
+
printPillarRow(
|
|
1280
|
+
" ccusage",
|
|
1281
|
+
(s) => paint(c.green, s),
|
|
1282
|
+
ccCombined,
|
|
1283
|
+
"ccusage CLI",
|
|
1284
|
+
);
|
|
1285
|
+
if (tdPillars?.all)
|
|
1286
|
+
printPillarRow(
|
|
1287
|
+
" token-dash",
|
|
1288
|
+
(s) => paint(c.magenta, s),
|
|
1289
|
+
tdPillars.all,
|
|
1290
|
+
"token-dashboard.db",
|
|
1291
|
+
);
|
|
1292
|
+
if (hasTs)
|
|
1293
|
+
printPillarRow(
|
|
1294
|
+
" tokscale",
|
|
1295
|
+
(s) => paint(c.blue, s),
|
|
1296
|
+
tsCombined,
|
|
1297
|
+
"tokscale_report.json",
|
|
1298
|
+
);
|
|
1033
1299
|
}
|
|
1034
1300
|
|
|
1035
1301
|
// ── 5. Board position ─────────────────────────────────────────────────────
|
|
1036
|
-
writeln()
|
|
1037
|
-
writeln(` ${dim(
|
|
1038
|
-
writeln()
|
|
1039
|
-
writeln(
|
|
1040
|
-
|
|
1041
|
-
|
|
1302
|
+
writeln();
|
|
1303
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
1304
|
+
writeln();
|
|
1305
|
+
writeln(
|
|
1306
|
+
` ${bold("Board")} ${dim("30d window · signalaf.com · sorted by Υ Yield")}`,
|
|
1307
|
+
);
|
|
1308
|
+
|
|
1309
|
+
const entries = boardData?.operators ?? boardData?.entries ?? boardData ?? [];
|
|
1042
1310
|
if (Array.isArray(entries) && entries.length > 0) {
|
|
1043
|
-
const top5 = entries.slice(0, 5)
|
|
1311
|
+
const top5 = entries.slice(0, 5);
|
|
1044
1312
|
// header
|
|
1045
1313
|
const BH = [
|
|
1046
|
-
padStart(dim(
|
|
1047
|
-
padEnd(dim(
|
|
1048
|
-
padEnd(dim(
|
|
1049
|
-
padStart(dim(
|
|
1050
|
-
padStart(dim(
|
|
1051
|
-
padStart(dim(
|
|
1052
|
-
padStart(dim(
|
|
1053
|
-
padStart(dim(
|
|
1054
|
-
padStart(dim(
|
|
1055
|
-
padStart(dim(
|
|
1056
|
-
]
|
|
1057
|
-
writeln(` ${BH.join(
|
|
1058
|
-
writeln(` ${dim(
|
|
1314
|
+
padStart(dim("#"), 4),
|
|
1315
|
+
padEnd(dim("Codename"), 20),
|
|
1316
|
+
padEnd(dim("Class"), 13),
|
|
1317
|
+
padStart(dim("Υ Yield"), 9),
|
|
1318
|
+
padStart(dim("SNR"), 6),
|
|
1319
|
+
padStart(dim("Depth"), 6),
|
|
1320
|
+
padStart(dim("Tokens"), 8),
|
|
1321
|
+
padStart(dim("Force"), 6),
|
|
1322
|
+
padStart(dim("Pct"), 5),
|
|
1323
|
+
padStart(dim("7d↕"), 5),
|
|
1324
|
+
];
|
|
1325
|
+
writeln(` ${BH.join(" ")}`);
|
|
1326
|
+
writeln(` ${dim("·".repeat(Math.min(w - 4, 92)))}`);
|
|
1059
1327
|
for (const e of top5) {
|
|
1060
|
-
const rank
|
|
1061
|
-
const name
|
|
1062
|
-
const cls
|
|
1063
|
-
const yld
|
|
1064
|
-
const snr
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
1328
|
+
const rank = e.rank === 1 ? gold(`#${e.rank}`) : `#${e.rank}`;
|
|
1329
|
+
const name = padEnd(trunc(e.codename ?? "—", 20), 20);
|
|
1330
|
+
const cls = padEnd(colorClass(e.class_tier ?? "—"), 13);
|
|
1331
|
+
const yld = padStart(e.yield_ != null ? fmtYield(e.yield_) : "—", 9);
|
|
1332
|
+
const snr = padStart(
|
|
1333
|
+
e.compression_ratio != null ? fmtSNR(e.compression_ratio) : "—",
|
|
1334
|
+
6,
|
|
1335
|
+
);
|
|
1336
|
+
const depth = padStart(
|
|
1337
|
+
e.session_depth != null ? e.session_depth.toFixed(1) : "—",
|
|
1338
|
+
6,
|
|
1339
|
+
);
|
|
1340
|
+
const tok = padStart(
|
|
1341
|
+
e.token_throughput != null ? fmtTokens(e.token_throughput) : "—",
|
|
1342
|
+
8,
|
|
1343
|
+
);
|
|
1344
|
+
const force = padStart(
|
|
1345
|
+
e.signal_force != null ? e.signal_force.toFixed(1) : "—",
|
|
1346
|
+
6,
|
|
1347
|
+
);
|
|
1348
|
+
const pct = padStart(e.percentile != null ? `${e.percentile}%` : "—", 5);
|
|
1349
|
+
const mv7 = padStart(fmtMove(e.movement_7d), 5);
|
|
1350
|
+
writeln(
|
|
1351
|
+
` ${padStart(rank, 4)} ${name} ${cls} ${yld} ${snr} ${depth} ${tok} ${force} ${pct} ${mv7}`,
|
|
1352
|
+
);
|
|
1071
1353
|
}
|
|
1072
|
-
if (entries.length > 5)
|
|
1354
|
+
if (entries.length > 5)
|
|
1355
|
+
writeln(
|
|
1356
|
+
` ${dim(` … ${entries.length - 5} more operators on signalaf.com`)}`,
|
|
1357
|
+
);
|
|
1073
1358
|
} else {
|
|
1074
|
-
writeln(` ${dim(
|
|
1359
|
+
writeln(` ${dim(" board unavailable")}`);
|
|
1075
1360
|
}
|
|
1076
1361
|
|
|
1077
1362
|
// ── 6. Footer / submit prompt ────────────────────────────────────────────
|
|
1078
|
-
writeln()
|
|
1079
|
-
writeln(` ${dim(
|
|
1080
|
-
writeln(
|
|
1081
|
-
|
|
1363
|
+
writeln();
|
|
1364
|
+
writeln(` ${dim("─".repeat(w - 4))}`);
|
|
1365
|
+
writeln(
|
|
1366
|
+
` ${dim("[S]")} submit to board ${dim("[B]")} open board in browser ${dim("[Q]")} quit`,
|
|
1367
|
+
);
|
|
1368
|
+
writeln();
|
|
1082
1369
|
|
|
1083
1370
|
// ── 7. Keypress handler ───────────────────────────────────────────────────
|
|
1084
1371
|
if (process.stdin.isTTY) {
|
|
1085
|
-
process.stdin.setRawMode(true)
|
|
1086
|
-
process.stdin.resume()
|
|
1087
|
-
process.stdin.setEncoding(
|
|
1372
|
+
process.stdin.setRawMode(true);
|
|
1373
|
+
process.stdin.resume();
|
|
1374
|
+
process.stdin.setEncoding("utf8");
|
|
1088
1375
|
|
|
1089
1376
|
await new Promise((resolve) => {
|
|
1090
|
-
process.stdin.on(
|
|
1091
|
-
const k = key.toLowerCase()
|
|
1092
|
-
if (k ===
|
|
1093
|
-
|
|
1094
|
-
|
|
1377
|
+
process.stdin.on("data", async (key) => {
|
|
1378
|
+
const k = key.toLowerCase();
|
|
1379
|
+
if (k === "q" || key === "\u0003") {
|
|
1380
|
+
// q or ctrl+c
|
|
1381
|
+
resolve();
|
|
1382
|
+
} else if (k === "b") {
|
|
1095
1383
|
// ASYNC FIX (2026-06-27): execFile instead of dynamic execSync import
|
|
1096
|
-
execFile(
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1384
|
+
execFile(
|
|
1385
|
+
"open",
|
|
1386
|
+
["https://signalaf.com"],
|
|
1387
|
+
{ stdio: "ignore" },
|
|
1388
|
+
() => {},
|
|
1389
|
+
);
|
|
1390
|
+
resolve();
|
|
1391
|
+
} else if (k === "s") {
|
|
1392
|
+
const id = ensureIdentity();
|
|
1393
|
+
const enrolled = !!(
|
|
1394
|
+
id.codename &&
|
|
1395
|
+
id.operator_id &&
|
|
1396
|
+
id.private_key_pkcs8_b64
|
|
1397
|
+
);
|
|
1398
|
+
process.stdin.setRawMode(false);
|
|
1399
|
+
write(SHOW_CURSOR);
|
|
1103
1400
|
if (enrolled) {
|
|
1104
1401
|
// VERIFIED path (D7 §7): signed submit from the enrolled device. No codename
|
|
1105
1402
|
// prompt — it comes from the keystore. Only signed submissions rank on the board.
|
|
1106
|
-
writeln()
|
|
1107
|
-
writeln(
|
|
1108
|
-
|
|
1403
|
+
writeln();
|
|
1404
|
+
writeln(
|
|
1405
|
+
` ${dim("Publishing verified runs for")} ${cyan(id.codename)}${dim("…")}`,
|
|
1406
|
+
);
|
|
1407
|
+
write(HIDE_CURSOR);
|
|
1109
1408
|
try {
|
|
1110
1409
|
for (const d of active) {
|
|
1111
|
-
for (const ww of
|
|
1112
|
-
const r = await submitSignedWindow(
|
|
1113
|
-
|
|
1114
|
-
|
|
1410
|
+
for (const ww of d.windows ?? []) {
|
|
1411
|
+
const r = await submitSignedWindow(
|
|
1412
|
+
ww.window,
|
|
1413
|
+
ww.pillars,
|
|
1414
|
+
ww.messages,
|
|
1415
|
+
id,
|
|
1416
|
+
{ platform: d.platform },
|
|
1417
|
+
);
|
|
1418
|
+
const ok = r.status === "received";
|
|
1419
|
+
writeln(
|
|
1420
|
+
` ${ok ? green("✓") : red("✗")} ${d.platform} ${ww.window}${ok ? dim(` tier=${r.verification_tier || "—"}`) : dim(` ${r.reason || r.status}`)}`,
|
|
1421
|
+
);
|
|
1115
1422
|
}
|
|
1116
1423
|
}
|
|
1117
|
-
writeln()
|
|
1118
|
-
writeln(
|
|
1424
|
+
writeln();
|
|
1425
|
+
writeln(
|
|
1426
|
+
` ${green("✓")} Published. Reload ${cyan(`signalaf.com/user/${id.codename}`)}`,
|
|
1427
|
+
);
|
|
1119
1428
|
} catch (e) {
|
|
1120
|
-
writeln(red(` ✗ ${e.message}`))
|
|
1429
|
+
writeln(red(` ✗ ${e.message}`));
|
|
1121
1430
|
}
|
|
1122
|
-
resolve()
|
|
1123
|
-
return
|
|
1431
|
+
resolve();
|
|
1432
|
+
return;
|
|
1124
1433
|
}
|
|
1125
1434
|
// NOT enrolled → the anonymous paste path (preview-only; does NOT rank) + a hint.
|
|
1126
|
-
writeln()
|
|
1127
|
-
writeln(
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
process.
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1435
|
+
writeln();
|
|
1436
|
+
writeln(
|
|
1437
|
+
` ${dim("Not enrolled — run")} ${bold("npx sigrank enroll")} ${dim("to rank as a verified operator. Anonymous paste below:")}`,
|
|
1438
|
+
);
|
|
1439
|
+
process.stdout.write(" Codename: ");
|
|
1440
|
+
let codename = "";
|
|
1441
|
+
process.stdin.on("data", async function onData(chunk) {
|
|
1442
|
+
if (chunk === "\r" || chunk === "\n") {
|
|
1443
|
+
process.stdin.removeListener("data", onData);
|
|
1444
|
+
codename = codename.trim();
|
|
1445
|
+
if (!codename) {
|
|
1446
|
+
writeln(red(" ✗ codename required"));
|
|
1447
|
+
resolve();
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
writeln();
|
|
1451
|
+
writeln(
|
|
1452
|
+
` ${dim("Submitting all windows for")} ${cyan(codename)}${dim("…")}`,
|
|
1453
|
+
);
|
|
1454
|
+
write(HIDE_CURSOR);
|
|
1138
1455
|
try {
|
|
1139
1456
|
for (const d of active) {
|
|
1140
|
-
const apiBase = DEFAULT_API_BASE
|
|
1141
|
-
const WINDOW_TYPE = {
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1457
|
+
const apiBase = DEFAULT_API_BASE;
|
|
1458
|
+
const WINDOW_TYPE = {
|
|
1459
|
+
"7d": "7d",
|
|
1460
|
+
"30d": "30d",
|
|
1461
|
+
"90d": "90d",
|
|
1462
|
+
all: "all_time",
|
|
1463
|
+
};
|
|
1464
|
+
for (const ww of d.windows ?? []) {
|
|
1465
|
+
const rawPaste = `${ww.pillars.input} ${ww.pillars.output} ${ww.pillars.cacheCreate} ${ww.pillars.cacheRead}`;
|
|
1466
|
+
const windowType = WINDOW_TYPE[ww.window] || ww.window;
|
|
1467
|
+
const now = new Date();
|
|
1468
|
+
const ddmmyy = `${String(now.getDate()).padStart(2, "0")}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getFullYear()).slice(-2)}`;
|
|
1469
|
+
const content_hash = `sha256:${codename}|${windowType}|${rawPaste}|${ddmmyy}`;
|
|
1148
1470
|
const res = await fetch(`${apiBase}/api/v1/ingest-paste`, {
|
|
1149
|
-
method:
|
|
1150
|
-
headers: {
|
|
1471
|
+
method: "POST",
|
|
1472
|
+
headers: {
|
|
1473
|
+
"content-type": "application/json",
|
|
1474
|
+
accept: "application/json",
|
|
1475
|
+
},
|
|
1151
1476
|
body: JSON.stringify({
|
|
1152
1477
|
codename,
|
|
1153
1478
|
raw_paste: rawPaste,
|
|
@@ -1157,272 +1482,365 @@ async function runSigRank() {
|
|
|
1157
1482
|
submitted_ddmmyy: ddmmyy,
|
|
1158
1483
|
submitted_at: now.toISOString(),
|
|
1159
1484
|
}),
|
|
1160
|
-
}).catch(() => null)
|
|
1161
|
-
const ok = res?.ok ?? false
|
|
1162
|
-
const status = ok ? green(
|
|
1163
|
-
writeln(
|
|
1485
|
+
}).catch(() => null);
|
|
1486
|
+
const ok = res?.ok ?? false;
|
|
1487
|
+
const status = ok ? green("✓") : red("✗");
|
|
1488
|
+
writeln(
|
|
1489
|
+
` ${status} ${d.platform} ${ww.window}${!ok ? dim(` HTTP ${res?.status ?? "err"}`) : ""}`,
|
|
1490
|
+
);
|
|
1164
1491
|
}
|
|
1165
1492
|
}
|
|
1166
|
-
writeln()
|
|
1167
|
-
writeln(
|
|
1493
|
+
writeln();
|
|
1494
|
+
writeln(
|
|
1495
|
+
` ${green("✓")} Submitted. Visit ${cyan(`signalaf.com/user/${codename}`)}`,
|
|
1496
|
+
);
|
|
1168
1497
|
} catch (e) {
|
|
1169
|
-
writeln(red(` ✗ ${e.message}`))
|
|
1498
|
+
writeln(red(` ✗ ${e.message}`));
|
|
1170
1499
|
}
|
|
1171
|
-
resolve()
|
|
1172
|
-
} else if (chunk ===
|
|
1500
|
+
resolve();
|
|
1501
|
+
} else if (chunk === "\u007f") {
|
|
1502
|
+
// backspace
|
|
1173
1503
|
if (codename.length > 0) {
|
|
1174
|
-
codename = codename.slice(0, -1)
|
|
1175
|
-
process.stdout.write(
|
|
1504
|
+
codename = codename.slice(0, -1);
|
|
1505
|
+
process.stdout.write("\b \b");
|
|
1176
1506
|
}
|
|
1177
1507
|
} else {
|
|
1178
|
-
codename += chunk
|
|
1179
|
-
process.stdout.write(chunk)
|
|
1508
|
+
codename += chunk;
|
|
1509
|
+
process.stdout.write(chunk);
|
|
1180
1510
|
}
|
|
1181
|
-
})
|
|
1182
|
-
process.stdin.resume()
|
|
1511
|
+
});
|
|
1512
|
+
process.stdin.resume();
|
|
1183
1513
|
}
|
|
1184
|
-
})
|
|
1185
|
-
})
|
|
1514
|
+
});
|
|
1515
|
+
});
|
|
1186
1516
|
}
|
|
1187
1517
|
|
|
1188
|
-
write(SHOW_CURSOR)
|
|
1518
|
+
write(SHOW_CURSOR);
|
|
1189
1519
|
if (process.stdin.isTTY) {
|
|
1190
|
-
process.stdin.setRawMode(false)
|
|
1191
|
-
process.stdin.pause()
|
|
1520
|
+
process.stdin.setRawMode(false);
|
|
1521
|
+
process.stdin.pause();
|
|
1192
1522
|
}
|
|
1193
1523
|
}
|
|
1194
1524
|
|
|
1195
1525
|
// ── HELP ─────────────────────────────────────────────────────────────────────
|
|
1196
1526
|
|
|
1197
1527
|
async function showHelp() {
|
|
1198
|
-
const { createRequire } = await import(
|
|
1199
|
-
const pkg = createRequire(import.meta.url)(
|
|
1200
|
-
writeln()
|
|
1201
|
-
writeln(` ${gold(
|
|
1202
|
-
writeln()
|
|
1203
|
-
writeln(` ${bold(
|
|
1204
|
-
writeln(
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
writeln(
|
|
1208
|
-
writeln(`
|
|
1209
|
-
writeln(
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
writeln(
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
writeln(
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
writeln(
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
writeln(` ${
|
|
1222
|
-
writeln(
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
writeln(
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
writeln(
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
writeln(
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
writeln(
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
writeln(
|
|
1238
|
-
|
|
1528
|
+
const { createRequire } = await import("module");
|
|
1529
|
+
const pkg = createRequire(import.meta.url)("./package.json");
|
|
1530
|
+
writeln();
|
|
1531
|
+
writeln(` ${gold("⊙ SigRank")} ${bold("CLI")} ${dim("v" + pkg.version)}`);
|
|
1532
|
+
writeln();
|
|
1533
|
+
writeln(` ${bold("Default (no args)")}`);
|
|
1534
|
+
writeln(
|
|
1535
|
+
` ${cyan("sigrank")} unified dashboard: cascade + token pillars + board`,
|
|
1536
|
+
);
|
|
1537
|
+
writeln();
|
|
1538
|
+
writeln(` ${bold("Commands")}`);
|
|
1539
|
+
writeln(
|
|
1540
|
+
` ${cyan("enroll")} sign in: paste a connect code (get one at signalaf.com → Settings)`,
|
|
1541
|
+
);
|
|
1542
|
+
writeln(
|
|
1543
|
+
` ${cyan("submit")} publish your verified runs to the board (sign in first)`,
|
|
1544
|
+
);
|
|
1545
|
+
writeln(
|
|
1546
|
+
` ${cyan("board")} live leaderboard (refreshes every 30s)`,
|
|
1547
|
+
);
|
|
1548
|
+
writeln(
|
|
1549
|
+
` ${cyan("board --window 7d")} board for a specific window (7d, 30d, 90d, all)`,
|
|
1550
|
+
);
|
|
1551
|
+
writeln(` ${cyan("board --once")} print once and exit`);
|
|
1552
|
+
writeln(
|
|
1553
|
+
` ${cyan("compare")} raw pillar audit: tokenpull vs ccusage vs token-dash vs tokscale`,
|
|
1554
|
+
);
|
|
1555
|
+
writeln(
|
|
1556
|
+
` ${cyan("compare --platform codex")} compare for a specific platform`,
|
|
1557
|
+
);
|
|
1558
|
+
writeln(
|
|
1559
|
+
` ${cyan("tui")} full tabbed TUI: Dashboard / Compare / Board / Watch`,
|
|
1560
|
+
);
|
|
1561
|
+
writeln(
|
|
1562
|
+
` ${cyan("tui --platform codex")} TUI with a different default platform`,
|
|
1563
|
+
);
|
|
1564
|
+
writeln(
|
|
1565
|
+
` ${cyan("watch")} live tune meter — ALL active platforms × all windows, every 30s`,
|
|
1566
|
+
);
|
|
1567
|
+
writeln(
|
|
1568
|
+
` ${cyan("watch --platform codex")} watch only one platform (optional filter)`,
|
|
1569
|
+
);
|
|
1570
|
+
writeln(
|
|
1571
|
+
` ${cyan("watch --window 7d")} watch only one window (optional filter)`,
|
|
1572
|
+
);
|
|
1573
|
+
writeln();
|
|
1574
|
+
writeln(` ${bold("Options")}`);
|
|
1575
|
+
writeln(
|
|
1576
|
+
` ${dim("--window")} 7d · 30d · 90d · all (default: 30d for board; all windows for watch)`,
|
|
1577
|
+
);
|
|
1578
|
+
writeln(
|
|
1579
|
+
` ${dim("--platform")} claude · codex · amp · gemini · opencode · goose · …`,
|
|
1580
|
+
);
|
|
1581
|
+
writeln(` ${dim("--refresh")} poll interval in seconds (default: 30)`);
|
|
1582
|
+
writeln(` ${dim("--once")} print once and exit (board only)`);
|
|
1583
|
+
writeln();
|
|
1584
|
+
writeln(` ${bold("For AI clients (not typeable)")}`);
|
|
1585
|
+
writeln(
|
|
1586
|
+
` ${dim("In a piped/non-TTY context, sigrank is an MCP stdio server.")}`,
|
|
1587
|
+
);
|
|
1588
|
+
writeln(
|
|
1589
|
+
` ${dim("AI clients (Claude, Cursor, …) call its tools automatically — these are")}`,
|
|
1590
|
+
);
|
|
1591
|
+
writeln(` ${dim("NOT shell commands. Humans use the commands above.")}`);
|
|
1592
|
+
writeln();
|
|
1593
|
+
writeln(` ${bold("Examples")}`);
|
|
1594
|
+
writeln(` ${dim("sigrank")} # unified dashboard`);
|
|
1595
|
+
writeln(` ${dim("sigrank board")} # live leaderboard`);
|
|
1596
|
+
writeln(
|
|
1597
|
+
` ${dim("sigrank compare")} # pillar audit (claude)`,
|
|
1598
|
+
);
|
|
1599
|
+
writeln(` ${dim("sigrank compare --platform codex")}`);
|
|
1600
|
+
writeln(` ${dim("sigrank watch --window 7d --refresh 60")}`);
|
|
1601
|
+
writeln(` ${dim("sigrank board --window all --once")}`);
|
|
1602
|
+
writeln();
|
|
1239
1603
|
}
|
|
1240
1604
|
|
|
1241
1605
|
// ── ENTRY POINT ───────────────────────────────────────────────────────────────
|
|
1242
1606
|
|
|
1243
1607
|
// ── enroll: bind this device to your operator via a web connect code (D7 §4.5) ──
|
|
1244
1608
|
async function runEnroll({ label } = {}) {
|
|
1245
|
-
const id = ensureIdentity()
|
|
1246
|
-
writeln()
|
|
1247
|
-
writeln(` ${gold(
|
|
1248
|
-
writeln(` ${dim(`device ${id.device_id}`)}`)
|
|
1609
|
+
const id = ensureIdentity();
|
|
1610
|
+
writeln();
|
|
1611
|
+
writeln(` ${gold("⊙ SigRank")} ${bold("Connect this device")}`);
|
|
1612
|
+
writeln(` ${dim(`device ${id.device_id}`)}`);
|
|
1249
1613
|
if (id.codename && id.operator_id) {
|
|
1250
|
-
writeln(
|
|
1614
|
+
writeln(
|
|
1615
|
+
` ${dim(`already enrolled as ${id.codename} — re-enrolling a bound device is rejected this slice.`)}`,
|
|
1616
|
+
);
|
|
1251
1617
|
}
|
|
1252
|
-
writeln(
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1618
|
+
writeln(
|
|
1619
|
+
` ${dim("Get a code at signalaf.com → Settings → Connect a device.")}`,
|
|
1620
|
+
);
|
|
1621
|
+
writeln();
|
|
1622
|
+
|
|
1623
|
+
const { createInterface } = await import("node:readline/promises");
|
|
1624
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
1625
|
+
let code;
|
|
1258
1626
|
try {
|
|
1259
|
-
code = (await rl.question(
|
|
1627
|
+
code = (await rl.question(" Paste your connect code: ")).trim();
|
|
1260
1628
|
} finally {
|
|
1261
|
-
rl.close()
|
|
1629
|
+
rl.close();
|
|
1262
1630
|
}
|
|
1263
1631
|
if (!code) {
|
|
1264
|
-
writeln(red(
|
|
1265
|
-
process.exitCode = 1
|
|
1266
|
-
return
|
|
1632
|
+
writeln(red(" ✗ No code entered."));
|
|
1633
|
+
process.exitCode = 1;
|
|
1634
|
+
return;
|
|
1267
1635
|
}
|
|
1268
1636
|
|
|
1269
|
-
let out
|
|
1637
|
+
let out;
|
|
1270
1638
|
try {
|
|
1271
|
-
out = await callTool(
|
|
1639
|
+
out = await callTool("enroll", {
|
|
1640
|
+
code,
|
|
1641
|
+
device_label: typeof label === "string" ? label : undefined,
|
|
1642
|
+
});
|
|
1272
1643
|
} catch (e) {
|
|
1273
|
-
writeln(red(` ✗ ${e.message}`))
|
|
1274
|
-
process.exitCode = 1
|
|
1275
|
-
return
|
|
1644
|
+
writeln(red(` ✗ ${e.message}`));
|
|
1645
|
+
process.exitCode = 1;
|
|
1646
|
+
return;
|
|
1276
1647
|
}
|
|
1277
1648
|
|
|
1278
|
-
if (out.status ===
|
|
1279
|
-
writeln()
|
|
1280
|
-
writeln(
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1649
|
+
if (out.status === "enrolled") {
|
|
1650
|
+
writeln();
|
|
1651
|
+
writeln(
|
|
1652
|
+
` ${green("✓")} Signed in as ${cyan(out.codename || "(operator)")}.`,
|
|
1653
|
+
);
|
|
1654
|
+
writeln(
|
|
1655
|
+
` ${dim("Your runs now cascade to the board. Publish with ")}${bold("npx sigrank submit")}${dim(" (one-shot) or ")}${bold("npx sigrank watch --submit")}${dim(" (continuous).")}`,
|
|
1656
|
+
);
|
|
1657
|
+
writeln(` ${dim(`identity: ${keystorePath()}`)}`);
|
|
1658
|
+
return;
|
|
1284
1659
|
}
|
|
1285
1660
|
|
|
1286
1661
|
const msg =
|
|
1287
1662
|
{
|
|
1288
|
-
code_invalid:
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1663
|
+
code_invalid:
|
|
1664
|
+
"That code is invalid, expired, or already used — generate a fresh one.",
|
|
1665
|
+
device_already_enrolled:
|
|
1666
|
+
'This device is already enrolled. Need a new key? Click "New key" at signalaf.com → Settings, then paste it here.',
|
|
1667
|
+
bad_request: "The code or device key was malformed.",
|
|
1668
|
+
rate_limited: "Too many attempts — wait a few minutes and retry.",
|
|
1669
|
+
persistence_unavailable:
|
|
1670
|
+
"Enrollment is temporarily unavailable — try again shortly.",
|
|
1671
|
+
}[out.reason] || `Enrollment failed (${out.reason || "unknown"}).`;
|
|
1672
|
+
writeln(red(` ✗ ${msg}`));
|
|
1673
|
+
process.exitCode = 1;
|
|
1296
1674
|
}
|
|
1297
1675
|
|
|
1298
1676
|
// ── submit: publish your verified (signed) runs to the board (D7 §5/§8) ─────────
|
|
1299
|
-
async function runSubmit({ platform =
|
|
1300
|
-
const id = ensureIdentity()
|
|
1677
|
+
async function runSubmit({ platform = "claude", window } = {}) {
|
|
1678
|
+
const id = ensureIdentity();
|
|
1301
1679
|
if (!id.codename || !id.operator_id) {
|
|
1302
|
-
writeln(
|
|
1303
|
-
|
|
1304
|
-
|
|
1680
|
+
writeln(
|
|
1681
|
+
red(" ✗ This device is not enrolled. Run `npx sigrank enroll` first."),
|
|
1682
|
+
);
|
|
1683
|
+
process.exitCode = 1;
|
|
1684
|
+
return;
|
|
1305
1685
|
}
|
|
1306
|
-
writeln()
|
|
1307
|
-
writeln(
|
|
1308
|
-
|
|
1686
|
+
writeln();
|
|
1687
|
+
writeln(
|
|
1688
|
+
` ${gold("⊙ SigRank")} ${bold("Publishing verified runs")} ${dim(`as ${id.codename}`)}`,
|
|
1689
|
+
);
|
|
1690
|
+
writeln(` ${dim("reading local token logs + signing…")}`);
|
|
1309
1691
|
|
|
1310
|
-
let out
|
|
1692
|
+
let out;
|
|
1311
1693
|
try {
|
|
1312
|
-
out = await callTool(
|
|
1694
|
+
out = await callTool("submit_verified", {
|
|
1695
|
+
platform,
|
|
1696
|
+
window: typeof window === "string" ? window : undefined,
|
|
1697
|
+
dry_run: process.argv.includes("--dry-run"),
|
|
1698
|
+
});
|
|
1313
1699
|
} catch (e) {
|
|
1314
|
-
writeln(red(` ✗ ${e.message}`))
|
|
1315
|
-
process.exitCode = 1
|
|
1316
|
-
return
|
|
1700
|
+
writeln(red(` ✗ ${e.message}`));
|
|
1701
|
+
process.exitCode = 1;
|
|
1702
|
+
return;
|
|
1317
1703
|
}
|
|
1318
|
-
if (out.status ===
|
|
1319
|
-
writeln(red(
|
|
1320
|
-
process.exitCode = 1
|
|
1321
|
-
return
|
|
1704
|
+
if (out.status === "not_enrolled") {
|
|
1705
|
+
writeln(red(" ✗ Not enrolled — run `npx sigrank enroll`."));
|
|
1706
|
+
process.exitCode = 1;
|
|
1707
|
+
return;
|
|
1322
1708
|
}
|
|
1323
1709
|
|
|
1324
|
-
writeln()
|
|
1325
|
-
let anyRanked = false
|
|
1326
|
-
let anyReceivedNotRanked = false
|
|
1710
|
+
writeln();
|
|
1711
|
+
let anyRanked = false;
|
|
1712
|
+
let anyReceivedNotRanked = false;
|
|
1327
1713
|
for (const w of out.windows || []) {
|
|
1328
|
-
const label = String(w.window).padEnd(8)
|
|
1329
|
-
if (w.status ===
|
|
1330
|
-
writeln(
|
|
1714
|
+
const label = String(w.window).padEnd(8);
|
|
1715
|
+
if (w.status === "dry_run") {
|
|
1716
|
+
writeln(
|
|
1717
|
+
` ${gold("◇")} ${bold(label)} ${gold("DRY RUN")} ${dim("· nothing sent")}`,
|
|
1718
|
+
);
|
|
1331
1719
|
} else if (w.ranked) {
|
|
1332
|
-
anyRanked = true
|
|
1333
|
-
writeln(
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1720
|
+
anyRanked = true;
|
|
1721
|
+
writeln(
|
|
1722
|
+
` ${green("✓")} ${bold(label)} ${green("RANKED")} ${dim("· live on the board")}`,
|
|
1723
|
+
);
|
|
1724
|
+
} else if (w.status === "received") {
|
|
1725
|
+
anyReceivedNotRanked = true;
|
|
1726
|
+
writeln(
|
|
1727
|
+
` ${gold("⚠")} ${bold(label)} ${gold("received · NOT ranked")} ${dim(`(tier=${w.verification_tier || "—"})`)}`,
|
|
1728
|
+
);
|
|
1337
1729
|
} else {
|
|
1338
|
-
writeln(
|
|
1730
|
+
writeln(
|
|
1731
|
+
` ${red("✗")} ${bold(label)} ${dim(w.reason || w.status || "failed")}`,
|
|
1732
|
+
);
|
|
1339
1733
|
}
|
|
1340
1734
|
}
|
|
1341
|
-
writeln()
|
|
1735
|
+
writeln();
|
|
1342
1736
|
if (anyRanked) {
|
|
1343
|
-
writeln(
|
|
1737
|
+
writeln(
|
|
1738
|
+
` ${dim("Your board row:")} ${cyan(`signalaf.com/user/${id.codename}`)}`,
|
|
1739
|
+
);
|
|
1344
1740
|
} else if (anyReceivedNotRanked) {
|
|
1345
|
-
writeln(
|
|
1741
|
+
writeln(
|
|
1742
|
+
` ${gold("Received, but NOT ranked")} ${dim("— this device is unenrolled or revoked. Re-enroll to rank:")} ${cyan("npx sigrank enroll")}`,
|
|
1743
|
+
);
|
|
1346
1744
|
}
|
|
1347
1745
|
}
|
|
1348
1746
|
|
|
1349
1747
|
export async function runCli(argv) {
|
|
1350
|
-
const args = argv.slice(2) // strip 'node' + script path
|
|
1351
|
-
const cmd
|
|
1748
|
+
const args = argv.slice(2); // strip 'node' + script path
|
|
1749
|
+
const cmd = args[0];
|
|
1352
1750
|
|
|
1353
1751
|
// parse --key value AND --key=value flags. E4: validate against the known set and warn
|
|
1354
1752
|
// (don't crash) on anything unknown, so a typo'd flag is visible instead of silently ignored.
|
|
1355
|
-
const KNOWN_FLAGS = new Set([
|
|
1356
|
-
|
|
1753
|
+
const KNOWN_FLAGS = new Set([
|
|
1754
|
+
"window",
|
|
1755
|
+
"platform",
|
|
1756
|
+
"refresh",
|
|
1757
|
+
"once",
|
|
1758
|
+
"submit",
|
|
1759
|
+
"compare",
|
|
1760
|
+
"label",
|
|
1761
|
+
"dry-run",
|
|
1762
|
+
]);
|
|
1763
|
+
const flags = {};
|
|
1357
1764
|
for (let i = 1; i < args.length; i++) {
|
|
1358
|
-
const a = args[i]
|
|
1359
|
-
if (!a.startsWith(
|
|
1360
|
-
const body = a.slice(2)
|
|
1361
|
-
let key, val
|
|
1362
|
-
const eq = body.indexOf(
|
|
1765
|
+
const a = args[i];
|
|
1766
|
+
if (!a.startsWith("--")) continue;
|
|
1767
|
+
const body = a.slice(2);
|
|
1768
|
+
let key, val;
|
|
1769
|
+
const eq = body.indexOf("=");
|
|
1363
1770
|
if (eq !== -1) {
|
|
1364
1771
|
// --flag=value form
|
|
1365
|
-
key = body.slice(0, eq)
|
|
1366
|
-
val = body.slice(eq + 1)
|
|
1772
|
+
key = body.slice(0, eq);
|
|
1773
|
+
val = body.slice(eq + 1);
|
|
1367
1774
|
} else {
|
|
1368
1775
|
// --flag [value] form: consume the next token as the value unless it's another flag
|
|
1369
|
-
key = body
|
|
1370
|
-
val = args[i + 1] && !args[i + 1].startsWith(
|
|
1776
|
+
key = body;
|
|
1777
|
+
val = args[i + 1] && !args[i + 1].startsWith("--") ? args[++i] : true;
|
|
1371
1778
|
}
|
|
1372
|
-
if (!key) continue
|
|
1779
|
+
if (!key) continue;
|
|
1373
1780
|
if (!KNOWN_FLAGS.has(key)) {
|
|
1374
|
-
writeln(
|
|
1375
|
-
|
|
1781
|
+
writeln(
|
|
1782
|
+
dim(
|
|
1783
|
+
` (ignoring unknown flag --${key}; known: ${[...KNOWN_FLAGS].join(", ")})`,
|
|
1784
|
+
),
|
|
1785
|
+
);
|
|
1786
|
+
continue;
|
|
1376
1787
|
}
|
|
1377
|
-
flags[key] = val
|
|
1788
|
+
flags[key] = val;
|
|
1378
1789
|
}
|
|
1379
1790
|
|
|
1380
1791
|
try {
|
|
1381
|
-
if (cmd ===
|
|
1792
|
+
if (cmd === "board") {
|
|
1382
1793
|
await runBoard({
|
|
1383
|
-
window:
|
|
1384
|
-
once:
|
|
1794
|
+
window: flags.window ?? "30d",
|
|
1795
|
+
once: flags.once === true || flags.once === "true",
|
|
1385
1796
|
refresh: Number(flags.refresh) || 30,
|
|
1386
|
-
})
|
|
1387
|
-
} else if (cmd ===
|
|
1388
|
-
await runCompare({ platform: flags.platform ??
|
|
1389
|
-
} else if (cmd ===
|
|
1390
|
-
const { runTui } = await import(
|
|
1391
|
-
await runTui({
|
|
1392
|
-
|
|
1797
|
+
});
|
|
1798
|
+
} else if (cmd === "compare") {
|
|
1799
|
+
await runCompare({ platform: flags.platform ?? "claude" });
|
|
1800
|
+
} else if (cmd === "tui") {
|
|
1801
|
+
const { runTui } = await import("./tui.mjs");
|
|
1802
|
+
await runTui({
|
|
1803
|
+
platform: flags.platform ?? "claude",
|
|
1804
|
+
window: flags.window ?? "7d",
|
|
1805
|
+
});
|
|
1806
|
+
} else if (cmd === "watch") {
|
|
1393
1807
|
// A5: no --platform/--window → watch ALL active platforms × ALL windows. Pass the raw
|
|
1394
1808
|
// flags through (undefined = no filter) so runWatch's auto-all mode engages by default;
|
|
1395
1809
|
// a provided flag narrows the grid (back-compat).
|
|
1396
1810
|
await runWatch({
|
|
1397
|
-
platform:
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1811
|
+
platform:
|
|
1812
|
+
typeof flags.platform === "string" ? flags.platform : undefined,
|
|
1813
|
+
window: typeof flags.window === "string" ? flags.window : undefined,
|
|
1814
|
+
refresh: Number(flags.refresh) || 30,
|
|
1815
|
+
submit: flags.submit === true || flags.submit === "true",
|
|
1816
|
+
});
|
|
1817
|
+
} else if (cmd === "enroll") {
|
|
1818
|
+
await runEnroll({ label: flags.label });
|
|
1819
|
+
} else if (cmd === "submit") {
|
|
1820
|
+
await runSubmit({
|
|
1821
|
+
platform: flags.platform ?? "claude",
|
|
1822
|
+
window: flags.window,
|
|
1823
|
+
});
|
|
1824
|
+
} else if (cmd === "--help" || cmd === "-h" || cmd === "help") {
|
|
1825
|
+
await showHelp();
|
|
1826
|
+
} else if (cmd === "--version" || cmd === "-v") {
|
|
1827
|
+
const { createRequire } = await import("module");
|
|
1828
|
+
const req = createRequire(import.meta.url);
|
|
1829
|
+
const pkg = req("./package.json");
|
|
1830
|
+
writeln(pkg.version);
|
|
1831
|
+
} else if (!cmd || cmd === "start" || cmd === "run") {
|
|
1414
1832
|
// default: full unified view
|
|
1415
|
-
await runSigRank()
|
|
1833
|
+
await runSigRank();
|
|
1416
1834
|
} else {
|
|
1417
1835
|
// unknown command: show help + exit non-zero so typos fail loudly (index.mjs now
|
|
1418
1836
|
// routes ALL arg'd invocations here instead of falling through to the MCP server)
|
|
1419
|
-
writeln(red(`\n ✗ unknown command: ${cmd}`))
|
|
1420
|
-
await showHelp()
|
|
1421
|
-
process.exit(2)
|
|
1837
|
+
writeln(red(`\n ✗ unknown command: ${cmd}`));
|
|
1838
|
+
await showHelp();
|
|
1839
|
+
process.exit(2);
|
|
1422
1840
|
}
|
|
1423
1841
|
} catch (e) {
|
|
1424
|
-
write(SHOW_CURSOR)
|
|
1425
|
-
writeln(red(`\n ✗ ${e.message}`))
|
|
1426
|
-
process.exit(1)
|
|
1842
|
+
write(SHOW_CURSOR);
|
|
1843
|
+
writeln(red(`\n ✗ ${e.message}`));
|
|
1844
|
+
process.exit(1);
|
|
1427
1845
|
}
|
|
1428
1846
|
}
|