sigrank 0.16.0 → 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/cli.mjs CHANGED
@@ -22,20 +22,20 @@
22
22
  * green = positive movement
23
23
  */
24
24
 
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'
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, 'node_modules', '.bin')
38
- const _envPath = `${_localBin}${process.env.PATH ? ':' + 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(cmd, args, { timeout: timeoutMs, stdio: ['ignore', 'pipe', 'ignore'], maxBuffer: 10 * 1024 * 1024, env: { ...process.env, PATH: _envPath } }, (err, stdout) => {
49
- if (err) reject(err)
50
- else resolve(stdout.toString())
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 = '\x1b['
66
+ const ESC = "\x1b[";
57
67
  const c = {
58
- reset: `${ESC}0m`,
59
- bold: `${ESC}1m`,
60
- dim: `${ESC}2m`,
61
- gold: `${ESC}33m`,
68
+ reset: `${ESC}0m`,
69
+ bold: `${ESC}1m`,
70
+ dim: `${ESC}2m`,
71
+ gold: `${ESC}33m`,
62
72
  boldGold: `${ESC}1;33m`,
63
- cyan: `${ESC}36m`,
73
+ cyan: `${ESC}36m`,
64
74
  boldCyan: `${ESC}1;36m`,
65
- green: `${ESC}32m`,
66
- red: `${ESC}31m`,
67
- white: `${ESC}97m`,
68
- boldWhite:`${ESC}1;97m`,
69
- magenta: `${ESC}35m`,
70
- blue: `${ESC}34m`,
71
- }
72
- const paint = (color, str) => `${color}${str}${c.reset}`
73
- const bold = (str) => paint(c.bold, str)
74
- const dim = (str) => paint(c.dim, str)
75
- const gold = (str) => paint(c.boldGold, str)
76
- const cyan = (str) => paint(c.boldCyan, str)
77
- const green = (str) => paint(c.green, str)
78
- const red = (str) => paint(c.red, str)
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, s),
83
- 'ARCH+': (s) => paint(c.boldCyan, s),
84
- ARCH: (s) => paint(c.cyan, s),
85
- POWER: (s) => paint(c.boldWhite, s),
86
- BASE: (s) => paint(c.white, s),
87
- SEEKER: (s) => paint(c.magenta, s),
88
- REFINER: (s) => paint(c.blue, s),
89
- BEARER: (s) => paint(c.dim, s),
90
- IGNITER: (s) => paint(c.dim, s),
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 = `${ESC}2J${ESC}H`
96
- const CURSOR_UP = (n) => `${ESC}${n}A`
97
- const ERASE_LINE = `${ESC}2K`
98
- const HIDE_CURSOR = `${ESC}?25l`
99
- const SHOW_CURSOR = `${ESC}?25h`
100
- const termWidth = () => process.stdout.columns || 80
101
- const write = (s) => process.stdout.write(s)
102
- const writeln = (s = '') => process.stdout.write(s + '\n')
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) { return s.replace(/\x1b\[[0-9;]*m/g, '') }
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 + ' '.repeat(w - vis)
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 : ' '.repeat(w - vis) + 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) return `${(y / 1000).toFixed(2)}K`
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 = (n) => n != null ? `${(n * 100).toFixed(0)}%` : '—'
134
- const fmtSNR = (n) => n != null ? `${(n * 100).toFixed(1)}%` : '—'
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('en-US', { hour12: false })
151
- const right = dim(`signalaf.com ${ts}`)
152
- const rightVis = stripAnsi(right).length
153
- const leftVis = stripAnsi(title).length
154
- const gap = Math.max(1, w - leftVis - rightVis)
155
- writeln()
156
- writeln(` ${title}${' '.repeat(gap)}${right}`)
157
- if (subtitle) writeln(` ${dim(subtitle)}`)
158
- writeln(` ${dim('─'.repeat(w - 4))}`)
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('─'.repeat(w - 4))}`)
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: 'rank', label: '#', w: 4, align: 'r' },
172
- { key: 'codename', label: 'Operator',w: 20, align: 'l' },
173
- { key: 'class_tier', label: 'Class', w: 13, align: 'l' },
174
- { key: 'yield_', label: 'Υ Yield', w: 9, align: 'r' },
175
- { key: 'compression_ratio', label: 'SNR', w: 6, align: 'r' },
176
- { key: 'session_depth', label: 'Depth', w: 6, align: 'r' },
177
- { key: 'token_throughput', label: 'Tokens', w: 8, align: 'r' },
178
- { key: 'movement_7d', label: '7d Δ', w: 6, align: 'r' },
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 = colorClass(entry.class_tier ?? '—')
187
- const yld = entry.yield_ != null ? fmtYield(entry.yield_) : '—'
188
- const snr = fmtSNR(entry.compression_ratio)
189
- const dep = entry.session_depth != null ? entry.session_depth.toFixed(1) : '—'
190
- const tok = fmtTokens(entry.token_throughput)
191
- const mv = fmtMove(entry.movement_7d)
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 = '30d') {
220
+ function renderBoardHeader(window = "30d") {
208
221
  renderHeader(
209
- `${gold('⊙ SigRank')} ${bold('Leaderboard')}`,
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 === 'r'
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('·'.repeat(termWidth() - 4))}`)
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 = '30d') {
223
- const res = await fetch(`${DEFAULT_API_BASE}/api/v1/leaderboard?window=${window}&metric=yield_`, {
224
- headers: { accept: 'application/json' }
225
- })
226
- if (!res.ok) throw new Error(`Board API → HTTP ${res.status}`)
227
- return res.json()
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 = '30d', once = false, refresh = 30 } = {}) {
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 { data = await fetchBoard(window) }
236
- catch (e) {
237
- writeln(red(` ✗ Could not reach signalaf.com: ${e.message}`))
238
- return
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 = '') => out.push(s)
248
-
249
- push()
250
- const ts = new Date().toLocaleTimeString('en-US', { hour12: false })
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(` ${gold('⊙ SigRank')} ${bold('Leaderboard')}${' '.repeat(gap)}${dim(right)}`)
256
- push(` ${dim(`window: ${data.window ?? window} · ${data.total_operators ?? (data.entries?.length ?? 0)} operators`)}`)
257
- push(` ${dim('─'.repeat(w - 4))}`)
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 === 'r'
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('·'.repeat(w - 4))}`)
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 ?? '—', 19)
272
- const cls = colorClass(entry.class_tier ?? '—')
273
- const yld = entry.yield_ != null ? fmtYield(entry.yield_) : '—'
274
- const snr = fmtSNR(entry.compression_ratio)
275
- const dep = entry.session_depth != null ? entry.session_depth.toFixed(1) : '—'
276
- const tok = fmtTokens(entry.token_throughput)
277
- const mv = fmtMove(entry.movement_7d)
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('─'.repeat(w - 4))}`)
292
- if (!once) push(` ${dim(`auto-refresh every ${refresh}s · ctrl+c to exit`)}`)
293
- push()
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('\n')
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('SIGINT', () => { clearInterval(iv); resolve() })
308
- })
330
+ process.on("SIGINT", () => {
331
+ clearInterval(iv);
332
+ resolve();
333
+ });
334
+ });
309
335
  }
310
336
  } finally {
311
- if (!once) write(SHOW_CURSOR + '\n')
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 = 'claude') {
354
+ async function ccusagePillars(platform = "claude") {
329
355
  // ccusage <platform> daily --json → sum by window
330
356
  try {
331
- const raw = await execFileAsync('ccusage', [platform, 'daily', '--json'], 15000)
332
- const data = JSON.parse(raw)
333
- const rows = data.daily ?? data // ccusage may return {daily:[...]} or [...]
334
-
335
- const now = Date.now()
336
- const cutoff = { '7d': 7, '30d': 30, '90d': 90 }
337
- const result = {}
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, output = 0, cacheCreate = 0, cacheRead = 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 ?? '1970-01-01')
376
+ const d = new Date(row.date ?? row.day ?? row.week ?? "1970-01-01");
344
377
  if (d >= since) {
345
- input += row.inputTokens ?? row.input_tokens ?? 0
346
- output += row.outputTokens ?? row.output_tokens ?? 0
347
- cacheCreate += row.cacheCreationTokens ?? row.cache_create_tokens ?? 0
348
- cacheRead += row.cacheReadTokens ?? row.cache_read_tokens ?? 0
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, output = 0, cacheCreate = 0, cacheRead = 0
388
+ let input = 0,
389
+ output = 0,
390
+ cacheCreate = 0,
391
+ cacheRead = 0;
355
392
  for (const row of rows) {
356
- input += row.inputTokens ?? row.input_tokens ?? 0
357
- output += row.outputTokens ?? row.output_tokens ?? 0
358
- cacheCreate += row.cacheCreationTokens ?? row.cache_create_tokens ?? 0
359
- cacheRead += row.cacheReadTokens ?? row.cache_read_tokens ?? 0
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['all'] = { input, output, cacheCreate, cacheRead }
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 = 'claude') {
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('tokscale', ['models', '--json'], 60000)
372
- const data = JSON.parse(raw)
373
- const entries = Array.isArray(data?.entries) ? data.entries : (Array.isArray(data) ? data : [])
374
- const rows = entries.filter(e =>
375
- e && e.client === platform &&
376
- e.model !== '<synthetic>' && e.model !== 'unknown' &&
377
- ((Number(e.input) || 0) > 0 || (Number(e.output) || 0) > 0)
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((acc, e) => ({
381
- input: acc.input + (Number(e.input) || 0),
382
- output: acc.output + (Number(e.output) || 0),
383
- cacheCreate: acc.cacheCreate + (Number(e.cacheWrite) || 0),
384
- cacheRead: acc.cacheRead + (Number(e.cacheRead) || 0),
385
- }), { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 })
386
- return { all: p }
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 { /* fall through to file-based read */ }
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(), 'tokscale_report.json')
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, 'utf8'))
394
- const entries = data.entries ?? []
395
- const rows = entries.filter(e =>
396
- e.client === platform &&
397
- e.model !== '<synthetic>' && e.model !== 'unknown' &&
398
- (e.input > 0 || e.output > 0)
399
- )
400
- if (rows.length === 0) return null
401
- const p = rows.reduce((acc, e) => ({
402
- input: acc.input + (e.input ?? 0),
403
- output: acc.output + (e.output ?? 0),
404
- cacheCreate: acc.cacheCreate + (e.cacheWrite ?? 0),
405
- cacheRead: acc.cacheRead + (e.cacheRead ?? 0),
406
- }), { input: 0, output: 0, cacheCreate: 0, cacheRead: 0 })
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 { return null }
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: 6_378_000, // sum of all models: 5.6M + 102.1K + 92.9K + 130.3K + 418.9K + 33.5K
418
- output: 38_682_400, // sum: 19.6M + 6.5M + 5.4M + 6.6M + 292.4K + 290.4K
419
- cacheCreate: null, // not shown in App UI
420
- cacheRead: null, // not shown in App UI
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: 'App UI — all-time, per-model sum from screenshots 2026-06-23. No cache fields. Update when re-screenshotted.',
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: 'claude-opus-4-8', input: 5_600_000, output: 19_600_000 },
425
- { model: 'claude-sonnet-4-5',input: 102_100, output: 6_500_000 },
426
- { model: 'claude-sonnet-4-6',input: 92_900, output: 5_400_000 },
427
- { model: 'claude-opus-4-7', input: 130_300, output: 6_600_000 },
428
- { model: 'claude-fable-5', input: 418_900, output: 292_400 },
429
- { model: 'claude-haiku-4-5', input: 33_500, output: 290_400 },
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(), '.claude', 'token-dashboard.db')
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 = "(model LIKE '%claude%' OR model LIKE '%fable%' OR model LIKE '%sonnet%' OR model LIKE '%opus%' OR model LIKE '%haiku%')"
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
- ['7d', "datetime('now','-7 days')"],
443
- ['30d', "datetime('now','-30 days')"],
444
- ['90d', "datetime('now','-90 days')"],
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('sqlite3', [dbPath, sql(wins[0][1])], 5000),
451
- execFileAsync('sqlite3', [dbPath, sql(wins[1][1])], 5000),
452
- execFileAsync('sqlite3', [dbPath, sql(wins[2][1])], 5000),
453
- execFileAsync('sqlite3', [dbPath, allSql], 5000),
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('|').map(Number)
457
- return { input: i||0, output: o||0, cacheCreate: cw||0, cacheRead: cr||0 }
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
- '7d': parse(d7),
461
- '30d': parse(d30),
462
- '90d': parse(d90),
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 = a !== 0 ? `${d > 0 ? '+' : ''}${((d / a) * 100).toFixed(1)}%` : ''
475
- const abs = `${d > 0 ? '+' : ''}${fmtTokens(Math.abs(d))}`
476
- const label = `${abs} ${pct}`
477
- return d > 0 ? green(label) : red(label)
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 = p.input ?? 0
484
- const o = p.output ?? 0
485
- const cw = p.cacheCreate ?? 0
486
- const cr = p.cacheRead ?? 0
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_ = leverage * velocity
493
- const snr = (i + o) > 0 ? o / (i + o) : 0
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, C = cw / o, R = cr / cw
498
- dev10x = Math.log10(T * C * R)
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 = ((cr + cw + o) / safeI) / 4.0
502
- const cls = classify(yield_, dev10x)
503
- return { yield: yield_, velocity, leverage, snr, dev10x, efficiency, class: cls, total }
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 = 'claude' } = {}) {
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('reading all 5 sources…')}`)
511
- const [ccPillars, tpData, tdPillars, tsPillars, apPillars] = await Promise.all([
512
- ccusagePillars(platform).catch(() => null),
513
- callTool('tokenpull', { platform }).catch(() => null),
514
- (platform === 'claude' ? tokenDashPillars() : Promise.resolve(null)).catch(() => null),
515
- tokscalePillars(platform).catch(() => null),
516
- Promise.resolve(platform === 'claude' ? appPillars() : null),
517
- ])
518
- write(CURSOR_UP(1) + ERASE_LINE)
519
-
520
- const w = termWidth()
521
- const WINS = ['7d', '30d', '90d', 'all']
522
- const WIN_LABEL = { '7d': '7d', '30d': '30d', '90d': '90d', 'all': 'all-time' }
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 (tpData?.windows ?? [])) {
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
- { name: 'tokenpull', color: cyan, pillars: tpPillars, note: 'JSONL deduped by msg id · canon source' },
533
- { name: 'ccusage', color: (s) => paint(c.green, s), pillars: ccPillars ?? {}, note: 'ccusage claude subcommand · monthly only' },
534
- { name: 'token-dash', color: (s) => paint(c.magenta,s), pillars: tdPillars ?? {}, note: 'SQLite — double-counts sessions · use with caution' },
535
- { name: 'tokscale', color: (s) => paint(c.blue, s), pillars: tsPillars ?? {}, note: 'all-time only · partial export (~5% of opus-4-8)' },
536
- { name: 'App', color: gold, pillars: apPillars ?? {}, note: 'screenshots 2026-06-23 · no cache fields · update manually' },
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(` ${gold('⊙ SigRank')} ${bold('Source Comparison')} ${dim(`platform: ${platform}`)} ${dim('tokenpull · ccusage · token-dash · tokscale')}`)
541
- writeln(` ${dim('─'.repeat(w - 4))}`)
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: 'input', label: 'Input' },
546
- { key: 'output', label: 'Output' },
547
- { key: 'cacheCreate', label: 'Cache Write' },
548
- { key: 'cacheRead', label: 'Cache Read' },
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 = [padEnd(dim('Source'), 14), ...WINS.map(win => padStart(dim(WIN_LABEL[win]), 13))]
555
- writeln(` ${hcols.join(' ')}`)
556
- writeln(` ${dim('·'.repeat(Math.min(w - 4, 14 + WINS.length * 15)))}`)
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('—'), 13)
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('─'.repeat(w - 4))}`)
572
- writeln(` ${bold('Cascade Signature')} ${dim('per source · all windows where data available')}`)
573
- writeln()
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: 'yield', label: 'Υ Yield', fmt: v => fmtYield(v), w: 9 },
577
- { key: 'velocity', label: 'Vel', fmt: v => v.toFixed(2), w: 6 },
578
- { key: 'leverage', label: 'Lev', fmt: v => `${fmtLev(v)}×`, w: 7 },
579
- { key: 'snr', label: 'SNR', fmt: v => fmtSNR(v), w: 6 },
580
- { key: 'dev10x', label: '10x', fmt: v => v.toFixed(2), w: 5 },
581
- { key: 'efficiency', label: 'Eff', fmt: v => v.toFixed(1), w: 6 },
582
- { key: 'class', label: 'Class', fmt: v => colorClass(v), w: 12 },
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('Source'), 14),
588
- padEnd(dim('Window'), 8),
589
- ...SIG_METRICS.map(m => padStart(dim(m.label), m.w)),
590
- ]
591
- writeln(` ${sigHdr.join(' ')}`)
592
- writeln(` ${dim('·'.repeat(Math.min(w - 4, 80)))}`)
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('no data')}`)
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 === 'tokenpull') {
606
- const tpWin = tpData?.windows?.find(ww => ww.window === win)
607
- cas = tpWin?.cascade ? {
608
- yield: tpWin.cascade.yield,
609
- velocity: tpWin.cascade.velocity,
610
- leverage: tpWin.cascade.leverage,
611
- snr: tpWin.cascade.snr,
612
- dev10x: tpWin.cascade.dev10x,
613
- efficiency: null,
614
- class: tpWin.cascade.class,
615
- } : cascadeFromPillars(p)
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 ? src.color(src.name) : ' '.repeat(stripAnsi(src.name).length)
621
- const winLabel = win === 'all' ? bold('all-time') : win
622
- const sigCols = SIG_METRICS.map(m => {
623
- const v = cas?.[m.key]
624
- return padStart(v != null ? m.fmt(v) : dim('—'), m.w)
625
- })
626
- writeln(` ${padEnd(srcLabel, 14)} ${padEnd(winLabel, 8)} ${sigCols.join(' ')}`)
627
- first = false
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('─'.repeat(w - 4))}`)
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(` ${dim('Eff = ((cacheRead+cacheWrite+output)/input)/4.0 vs AA baseline')}`)
638
- writeln(` ${dim('App has no cache fields → Υ/Lev/Eff/10x unavailable from App source')}`)
639
- writeln()
640
- write(SHOW_CURSOR)
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 = ['7d', '30d', '90d', 'all']
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({ platform, window: win, refresh = 30, submit = false } = {}) {
661
- let lines = 0
662
- const id = submit ? ensureIdentity() : null
663
- const enrolled = !!(id && id.codename && id.operator_id && id.private_key_pkcs8_b64)
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 === 'string' && win ? win : null
667
- const platFilter = typeof platform === 'string' && platform ? platform : null
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 = '') => out.push(s)
685
- const w = termWidth()
686
- const ts = new Date().toLocaleTimeString('en-US', { hour12: false })
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 = (platFilter || 'all active platforms') + ' · ' + (winFilter ? `window: ${winFilter}` : 'all windows')
819
+ const scopeLabel =
820
+ (platFilter || "all active platforms") +
821
+ " · " +
822
+ (winFilter ? `window: ${winFilter}` : "all windows");
689
823
 
690
- push()
691
- push(` ${gold('⊙ SigRank')} ${bold('Watch')} ${dim(`${scopeLabel} · ${ts}`)}`)
692
- push(` ${dim('─'.repeat(w - 4))}`)
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(` ${dim('no active platforms detected — run some sessions, this will pick them up automatically')}`)
697
- push()
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 (d.windows || [])) byWin[ww.window] = ww
704
- push()
705
- push(` ${cyan(plat)}${d.estimated ? dim(' (est)') : ''}`)
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 (submit && enrolled && ww && yNow != null && (prev === undefined || changed)) {
853
+ if (
854
+ submit &&
855
+ enrolled &&
856
+ ww &&
857
+ yNow != null &&
858
+ (prev === undefined || changed)
859
+ ) {
716
860
  try {
717
- const r = await submitSignedWindow(wk, ww.pillars, ww.messages, id, { platform: plat })
718
- lastSubmitMsg.set(key, r.status === 'received' ? green(`✓ tier=${r.verification_tier || '—'}`) : red(`✗ ${r.reason || r.status}`))
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 === 'all' ? 'all-time' : wk
726
- const yDisplay = cas?.yield != null ? gold(fmtYield(cas.yield)) : dim('—')
727
- const indicator = changed ? green(' ▲') : dim(' ·')
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('SNR')} ${fmtSNR(cas.snr)} ${dim('Lev')} ${cas.leverage != null ? fmtLev(cas.leverage) + '×' : '—'} ${dim('Vel')} ${cas.velocity != null ? cas.velocity.toFixed(2) : '—'} ${colorClass(cas.class ?? '—')}`
730
- : dim('no data')
731
- const submitNote = (submit && enrolled) ? ' ' + (lastSubmitMsg.get(key) || dim('…')) : ''
732
- push(` ${padEnd(winLabel, 8)} ${bold('Υ')} ${yDisplay}${indicator} ${metrics}${submitNote}`)
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('─'.repeat(w - 4))}`)
895
+ push();
896
+ push(` ${dim("─".repeat(w - 4))}`);
738
897
  if (submit && !enrolled) {
739
- push(` ${red('not enrolled — run `npx sigrank enroll` to auto-submit')}`)
898
+ push(
899
+ ` ${red("not enrolled — run `npx sigrank enroll` to auto-submit")}`,
900
+ );
740
901
  }
741
- push(` ${dim(`polling every ${refresh}s · ${submit ? 'auto-submit ON · ' : ''}tokens stay on your machine · ctrl+c to exit`)}`)
742
- push()
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('\n'))
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('SIGINT', () => { clearInterval(iv); resolve() })
753
- })
915
+ process.on("SIGINT", () => {
916
+ clearInterval(iv);
917
+ resolve();
918
+ });
919
+ });
754
920
  } finally {
755
- write(SHOW_CURSOR + '\n')
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
- 'claude','codex','amp','gemini','kimi','qwen','goose','kilo',
770
- 'hermes','droid','codebuff','copilot','openclaw','pi',
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('⊙ SigRank')} ${bold('Operator Dashboard')}`)
780
- writeln(` ${dim('reading local data…')}`)
956
+ writeln();
957
+ writeln(` ${gold("⊙ SigRank")} ${bold("Operator Dashboard")}`);
958
+ writeln(` ${dim("reading local data…")}`);
781
959
 
782
- const { tokenpullAny, freshVerifierPillars } = await import('./tokenpull.mjs')
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('get_leaderboard', {}).catch(() => null),
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 !== 'fulfilled') continue
807
- const d = r.value
808
- const all = d.windows?.find(w => w.window === 'all')
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(d => freshVerifierPillars(d.platform).catch(() => ({ ccusage: null, tokscale: null, tokendash: null })))
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 === 'claude' && f.tokendash) tdPillars = f.tokendash
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(CURSOR_UP(3) + ERASE_LINE + CURSOR_UP(1) + ERASE_LINE + CURSOR_UP(1) + ERASE_LINE)
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('en-US', { hour12: false })
835
- const header = ` ${gold('⊙ SigRank')} ${bold('Operator Dashboard')}`
836
- const right = dim(`signalaf.com ${ts}`)
837
- const gap = Math.max(1, w - stripAnsi(header).length - stripAnsi(right).length)
838
- writeln()
839
- writeln(`${header}${' '.repeat(gap)}${right}`)
840
-
841
- const platformSummary = active.map(d => {
842
- const all = d.windows.find(w => w.window === 'all')
843
- return `${cyan(d.platform)} ${dim(`${d.files ?? '?'} files · ${(all?.messages ?? 0).toLocaleString()} msgs`)}`
844
- }).join(' ')
845
- writeln(` ${dim('Detected:')} ${platformSummary || dim('no local data found')}`)
846
- writeln(` ${dim('─'.repeat(w - 4))}`)
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('Your Cascade')}`)
1049
+ writeln();
1050
+ writeln(` ${bold("Your Cascade")}`);
851
1051
  const CH = [
852
- padEnd(dim('Platform'), 10),
853
- padEnd(dim('Win'), 5),
854
- padStart(dim('Input'), 8),
855
- padStart(dim('Output'), 8),
856
- padStart(dim('CacheW'), 8),
857
- padStart(dim('CacheR'), 9),
858
- padStart(dim('Υ Yield'), 9),
859
- padStart(dim('SNR'), 7),
860
- padStart(dim('Leverage'), 10),
861
- padStart(dim('Vel'), 6),
862
- padStart(dim('10x'), 6),
863
- padEnd(dim('Class'), 13),
864
- ]
865
- writeln(` ${CH.join(' ')}`)
866
- writeln(` ${dim('·'.repeat(Math.min(w - 4, 110)))}`)
867
-
868
- const WINS = ['7d', '30d', '90d', 'all']
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('~') + fmtTokens(p.input) : fmtTokens(p.input), 8),
1078
+ padStart(est ? dim("~") + fmtTokens(p.input) : fmtTokens(p.input), 8),
879
1079
  padStart(fmtTokens(p.output), 8),
880
- padStart(p.cacheCreate > 0 ? (est ? dim('~') + fmtTokens(p.cacheCreate) : fmtTokens(p.cacheCreate)) : dim('—'), 8),
881
- padStart(p.cacheRead > 0 ? fmtTokens(p.cacheRead) : dim('—'), 9),
882
- padStart(cas.yield != null ? (cas.yield > 10000 ? gold(fmtYield(cas.yield)) : fmtYield(cas.yield)) : '—', 9),
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)}×` : '—', 10),
885
- padStart(cas.velocity != null ? cas.velocity.toFixed(2) : '—', 6),
886
- padStart(cas.dev10x != null ? cas.dev10x.toFixed(2) : '—', 6),
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) => winKey === '7d' || (winKey === '30d' && !d.windows?.find(w => w.window === '7d' && (w.pillars.input + w.pillars.output) > 0))
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 ((p.input + p.output) === 0) continue
922
- combinedP.input += p.input ?? 0
923
- combinedP.output += p.output ?? 0
924
- combinedP.cacheCreate += p.cacheCreate ?? 0
925
- combinedP.cacheRead += p.cacheRead ?? 0
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('─'.repeat(w - 4))}`)
943
- writeln()
944
- writeln(` ${bold('Token Pillars')} ${dim('(all-time · per-platform verification)')}`)
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('Source'), 14),
948
- padStart(dim('Input'), 10),
949
- padStart(dim('Output'), 10),
950
- padStart(dim('Cache Write'), 12),
951
- padStart(dim('Cache Read'), 12),
952
- padStart(dim('Total'), 10),
953
- ]
954
- writeln(` ${PCOLS.join(' ')}`)
955
- writeln(` ${dim('·'.repeat(Math.min(w - 4, 74)))}`)
956
-
957
- const printPillarRow = (label, colorFn, p, note = '') => {
958
- if (!p) return
959
- const i = p.input ?? 0
960
- const o = p.output ?? 0
961
- const cw = p.cacheCreate ?? 0
962
- const cr = p.cacheRead ?? 0
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), 10),
967
- padStart(fmtTokens(o), 10),
968
- padStart(cw > 0 ? fmtTokens(cw) : dim('—'), 12),
969
- padStart(cr > 0 ? fmtTokens(cr) : dim('—'), 12),
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(' ')}${note ? ' ' + dim(note) : ''}`)
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 === 'all')
978
- if (!all) continue
979
- const v = verifierMap[d.platform] ?? {}
980
- const estMarker = d.estimated ? dim(' ~ estimated') : ''
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(` ${dim(` ~ input = output × ioRatio(${ratio}) cacheCreate = uncached − input cacheRead = exact`)}`)
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) printPillarRow(' ccusage', (s) => paint(c.green, s), v.cc.all, 'ccusage CLI')
988
- if (d.platform === 'claude' && tdPillars?.all)
989
- printPillarRow(' token-dash', (s) => paint(c.magenta, s), tdPillars.all, 'token-dashboard.db')
990
- if (v.ts?.all) printPillarRow(' tokscale', (s) => paint(c.blue, s), v.ts.all, 'tokscale_report.json')
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(` ${dim(' ^ verifiers show raw uncached input (input_tokens − cached) — different field than estimated input above')}`)
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 === 'all')
1002
- if (!all) continue
1003
- combined.input += all.pillars.input ?? 0
1004
- combined.output += all.pillars.output ?? 0
1005
- combined.cacheCreate += all.pillars.cacheCreate ?? 0
1006
- combined.cacheRead += all.pillars.cacheRead ?? 0
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, hasTs = 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 += v.cc.all.input ?? 0
1016
- ccCombined.output += v.cc.all.output ?? 0
1017
- ccCombined.cacheCreate += v.cc.all.cacheCreate ?? 0
1018
- ccCombined.cacheRead += v.cc.all.cacheRead ?? 0
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 += v.ts.all.input ?? 0
1023
- tsCombined.output += v.ts.all.output ?? 0
1024
- tsCombined.cacheCreate += v.ts.all.cacheCreate ?? 0
1025
- tsCombined.cacheRead += v.ts.all.cacheRead ?? 0
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('combined', (s) => bold(s), combined, active.map(d => d.platform).join('+'))
1030
- if (hasCc) printPillarRow(' ccusage', (s) => paint(c.green, s), ccCombined, 'ccusage CLI')
1031
- if (tdPillars?.all) printPillarRow(' token-dash', (s) => paint(c.magenta, s), tdPillars.all,'token-dashboard.db')
1032
- if (hasTs) printPillarRow(' tokscale', (s) => paint(c.blue, s), tsCombined, 'tokscale_report.json')
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('─'.repeat(w - 4))}`)
1038
- writeln()
1039
- writeln(` ${bold('Board')} ${dim('30d window · signalaf.com · sorted by Υ Yield')}`)
1040
-
1041
- const entries = boardData?.operators ?? boardData?.entries ?? boardData ?? []
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('#'), 4),
1047
- padEnd(dim('Codename'), 20),
1048
- padEnd(dim('Class'), 13),
1049
- padStart(dim('Υ Yield'), 9),
1050
- padStart(dim('SNR'), 6),
1051
- padStart(dim('Depth'), 6),
1052
- padStart(dim('Tokens'),8),
1053
- padStart(dim('Force'), 6),
1054
- padStart(dim('Pct'), 5),
1055
- padStart(dim('7d↕'), 5),
1056
- ]
1057
- writeln(` ${BH.join(' ')}`)
1058
- writeln(` ${dim('·'.repeat(Math.min(w - 4, 92)))}`)
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 = e.rank === 1 ? gold(`#${e.rank}`) : `#${e.rank}`
1061
- const name = padEnd(trunc(e.codename ?? '—', 20), 20)
1062
- const cls = padEnd(colorClass(e.class_tier ?? '—'), 13)
1063
- const yld = padStart(e.yield_ != null ? fmtYield(e.yield_) : '—', 9)
1064
- const snr = padStart(e.compression_ratio != null ? fmtSNR(e.compression_ratio) : '—', 6)
1065
- const depth = padStart(e.session_depth != null ? e.session_depth.toFixed(1) : '—', 6)
1066
- const tok = padStart(e.token_throughput != null ? fmtTokens(e.token_throughput) : '—', 8)
1067
- const force = padStart(e.signal_force != null ? e.signal_force.toFixed(1) : '—', 6)
1068
- const pct = padStart(e.percentile != null ? `${e.percentile}%` : '—', 5)
1069
- const mv7 = padStart(fmtMove(e.movement_7d), 5)
1070
- writeln(` ${padStart(rank, 4)} ${name} ${cls} ${yld} ${snr} ${depth} ${tok} ${force} ${pct} ${mv7}`)
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) writeln(` ${dim(` … ${entries.length - 5} more operators on signalaf.com`)}`)
1354
+ if (entries.length > 5)
1355
+ writeln(
1356
+ ` ${dim(` … ${entries.length - 5} more operators on signalaf.com`)}`,
1357
+ );
1073
1358
  } else {
1074
- writeln(` ${dim(' board unavailable')}`)
1359
+ writeln(` ${dim(" board unavailable")}`);
1075
1360
  }
1076
1361
 
1077
1362
  // ── 6. Footer / submit prompt ────────────────────────────────────────────
1078
- writeln()
1079
- writeln(` ${dim('─'.repeat(w - 4))}`)
1080
- writeln(` ${dim('[S]')} submit to board ${dim('[B]')} open board in browser ${dim('[Q]')} quit`)
1081
- writeln()
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('utf8')
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('data', async (key) => {
1091
- const k = key.toLowerCase()
1092
- if (k === 'q' || key === '\u0003') { // q or ctrl+c
1093
- resolve()
1094
- } else if (k === 'b') {
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('open', ['https://signalaf.com'], { stdio: 'ignore' }, () => {})
1097
- resolve()
1098
- } else if (k === 's') {
1099
- const id = ensureIdentity()
1100
- const enrolled = !!(id.codename && id.operator_id && id.private_key_pkcs8_b64)
1101
- process.stdin.setRawMode(false)
1102
- write(SHOW_CURSOR)
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(` ${dim('Publishing verified runs for')} ${cyan(id.codename)}${dim('…')}`)
1108
- write(HIDE_CURSOR)
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 (d.windows ?? [])) {
1112
- const r = await submitSignedWindow(ww.window, ww.pillars, ww.messages, id, { platform: d.platform })
1113
- const ok = r.status === 'received'
1114
- writeln(` ${ok ? green('✓') : red('✗')} ${d.platform} ${ww.window}${ok ? dim(` tier=${r.verification_tier || '—'}`) : dim(` ${r.reason || r.status}`)}`)
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(` ${green('✓')} Published. Reload ${cyan(`signalaf.com/user/${id.codename}`)}`)
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(` ${dim('Not enrolled — run')} ${bold('npx sigrank enroll')} ${dim('to rank as a verified operator. Anonymous paste below:')}`)
1128
- process.stdout.write(' Codename: ')
1129
- let codename = ''
1130
- process.stdin.on('data', async function onData(chunk) {
1131
- if (chunk === '\r' || chunk === '\n') {
1132
- process.stdin.removeListener('data', onData)
1133
- codename = codename.trim()
1134
- if (!codename) { writeln(red(' ✗ codename required')); resolve(); return }
1135
- writeln()
1136
- writeln(` ${dim('Submitting all windows for')} ${cyan(codename)}${dim('…')}`)
1137
- write(HIDE_CURSOR)
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 = { '7d': '7d', '30d': '30d', '90d': '90d', 'all': 'all_time' }
1142
- for (const ww of (d.windows ?? [])) {
1143
- const rawPaste = `${ww.pillars.input} ${ww.pillars.output} ${ww.pillars.cacheCreate} ${ww.pillars.cacheRead}`
1144
- const windowType = WINDOW_TYPE[ww.window] || ww.window
1145
- const now = new Date()
1146
- const ddmmyy = `${String(now.getDate()).padStart(2,'0')}${String(now.getMonth()+1).padStart(2,'0')}${String(now.getFullYear()).slice(-2)}`
1147
- const content_hash = `sha256:${codename}|${windowType}|${rawPaste}|${ddmmyy}`
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: 'POST',
1150
- headers: { 'content-type': 'application/json', accept: 'application/json' },
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('✓') : red('✗')
1163
- writeln(` ${status} ${d.platform} ${ww.window}${!ok ? dim(` HTTP ${res?.status ?? 'err'}`) : ''}`)
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(` ${green('✓')} Submitted. Visit ${cyan(`signalaf.com/user/${codename}`)}`)
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 === '\u007f') { // backspace
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('\b \b')
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('module')
1199
- const pkg = createRequire(import.meta.url)('./package.json')
1200
- writeln()
1201
- writeln(` ${gold('⊙ SigRank')} ${bold('CLI')} ${dim('v' + pkg.version)}`)
1202
- writeln()
1203
- writeln(` ${bold('Default (no args)')}`)
1204
- writeln(` ${cyan('sigrank')} unified dashboard: cascade + token pillars + board`)
1205
- writeln()
1206
- writeln(` ${bold('Commands')}`)
1207
- writeln(` ${cyan('enroll')} sign in: paste a connect code (get one at signalaf.com → Settings)`)
1208
- writeln(` ${cyan('submit')} publish your verified runs to the board (sign in first)`)
1209
- writeln(` ${cyan('board')} live leaderboard (refreshes every 30s)`)
1210
- writeln(` ${cyan('board --window 7d')} board for a specific window (7d, 30d, 90d, all)`)
1211
- writeln(` ${cyan('board --once')} print once and exit`)
1212
- writeln(` ${cyan('compare')} raw pillar audit: tokenpull vs ccusage vs token-dash vs tokscale`)
1213
- writeln(` ${cyan('compare --platform codex')} compare for a specific platform`)
1214
- writeln(` ${cyan('tui')} full tabbed TUI: Dashboard / Compare / Board / Watch`)
1215
- writeln(` ${cyan('tui --platform codex')} TUI with a different default platform`)
1216
- writeln(` ${cyan('watch')} live tune meter — ALL active platforms × all windows, every 30s`)
1217
- writeln(` ${cyan('watch --platform codex')} watch only one platform (optional filter)`)
1218
- writeln(` ${cyan('watch --window 7d')} watch only one window (optional filter)`)
1219
- writeln()
1220
- writeln(` ${bold('Options')}`)
1221
- writeln(` ${dim('--window')} 7d · 30d · 90d · all (default: 30d for board; all windows for watch)`)
1222
- writeln(` ${dim('--platform')} claude · codex · amp · gemini · opencode · goose · …`)
1223
- writeln(` ${dim('--refresh')} poll interval in seconds (default: 30)`)
1224
- writeln(` ${dim('--once')} print once and exit (board only)`)
1225
- writeln()
1226
- writeln(` ${bold('For AI clients (not typeable)')}`)
1227
- writeln(` ${dim('In a piped/non-TTY context, sigrank is an MCP stdio server.')}`)
1228
- writeln(` ${dim('AI clients (Claude, Cursor, …) call its tools automatically — these are')}`)
1229
- writeln(` ${dim('NOT shell commands. Humans use the commands above.')}`)
1230
- writeln()
1231
- writeln(` ${bold('Examples')}`)
1232
- writeln(` ${dim('sigrank')} # unified dashboard`)
1233
- writeln(` ${dim('sigrank board')} # live leaderboard`)
1234
- writeln(` ${dim('sigrank compare')} # pillar audit (claude)`)
1235
- writeln(` ${dim('sigrank compare --platform codex')}`)
1236
- writeln(` ${dim('sigrank watch --window 7d --refresh 60')}`)
1237
- writeln(` ${dim('sigrank board --window all --once')}`)
1238
- writeln()
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('⊙ SigRank')} ${bold('Connect this device')}`)
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(` ${dim(`already enrolled as ${id.codename} — re-enrolling a bound device is rejected this slice.`)}`)
1614
+ writeln(
1615
+ ` ${dim(`already enrolled as ${id.codename} — re-enrolling a bound device is rejected this slice.`)}`,
1616
+ );
1251
1617
  }
1252
- writeln(` ${dim('Get a code at signalaf.com → Settings → Connect a device.')}`)
1253
- writeln()
1254
-
1255
- const { createInterface } = await import('node:readline/promises')
1256
- const rl = createInterface({ input: process.stdin, output: process.stdout })
1257
- let code
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(' Paste your connect code: ')).trim()
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(' ✗ No code entered.'))
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('enroll', { code, device_label: typeof label === 'string' ? label : undefined })
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 === 'enrolled') {
1279
- writeln()
1280
- writeln(` ${green('✓')} Signed in as ${cyan(out.codename || '(operator)')}.`)
1281
- writeln(` ${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).')}`)
1282
- writeln(` ${dim(`identity: ${keystorePath()}`)}`)
1283
- return
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: 'That code is invalid, expired, or already used — generate a fresh one.',
1289
- device_already_enrolled: 'This device is already enrolled. Need a new key? Click "New key" at signalaf.com → Settings, then paste it here.',
1290
- bad_request: 'The code or device key was malformed.',
1291
- rate_limited: 'Too many attempts — wait a few minutes and retry.',
1292
- persistence_unavailable: 'Enrollment is temporarily unavailable — try again shortly.',
1293
- }[out.reason] || `Enrollment failed (${out.reason || 'unknown'}).`
1294
- writeln(red(` ✗ ${msg}`))
1295
- process.exitCode = 1
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 = 'claude', window } = {}) {
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(red(' ✗ This device is not enrolled. Run `npx sigrank enroll` first.'))
1303
- process.exitCode = 1
1304
- return
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(` ${gold('⊙ SigRank')} ${bold('Publishing verified runs')} ${dim(`as ${id.codename}`)}`)
1308
- writeln(` ${dim('reading local token logs + signing…')}`)
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('submit_verified', { platform, window: typeof window === 'string' ? window : undefined, dry_run: process.argv.includes('--dry-run') })
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 === 'not_enrolled') {
1319
- writeln(red(' ✗ Not enrolled — run `npx sigrank enroll`.'))
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 === 'dry_run') {
1330
- writeln(` ${gold('◇')} ${bold(label)} ${gold('DRY RUN')} ${dim('· nothing sent')}`)
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(` ${green('✓')} ${bold(label)} ${green('RANKED')} ${dim('· live on the board')}`)
1334
- } else if (w.status === 'received') {
1335
- anyReceivedNotRanked = true
1336
- writeln(` ${gold('⚠')} ${bold(label)} ${gold('received · NOT ranked')} ${dim(`(tier=${w.verification_tier || '—'})`)}`)
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(` ${red('✗')} ${bold(label)} ${dim(w.reason || w.status || 'failed')}`)
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(` ${dim('Your board row:')} ${cyan(`signalaf.com/user/${id.codename}`)}`)
1737
+ writeln(
1738
+ ` ${dim("Your board row:")} ${cyan(`signalaf.com/user/${id.codename}`)}`,
1739
+ );
1344
1740
  } else if (anyReceivedNotRanked) {
1345
- writeln(` ${gold('Received, but NOT ranked')} ${dim('— this device is unenrolled or revoked. Re-enroll to rank:')} ${cyan('npx sigrank enroll')}`)
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 = args[0]
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(['window', 'platform', 'refresh', 'once', 'submit', 'compare', 'label', 'dry-run'])
1356
- const flags = {}
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('--')) continue
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('--') ? args[++i] : true
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(dim(` (ignoring unknown flag --${key}; known: ${[...KNOWN_FLAGS].join(', ')})`))
1375
- continue
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 === 'board') {
1792
+ if (cmd === "board") {
1382
1793
  await runBoard({
1383
- window: flags.window ?? '30d',
1384
- once: flags.once === true || flags.once === 'true',
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 === 'compare') {
1388
- await runCompare({ platform: flags.platform ?? 'claude' })
1389
- } else if (cmd === 'tui') {
1390
- const { runTui } = await import('./tui.mjs')
1391
- await runTui({ platform: flags.platform ?? 'claude', window: flags.window ?? '7d' })
1392
- } else if (cmd === 'watch') {
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: typeof flags.platform === 'string' ? flags.platform : undefined,
1398
- window: typeof flags.window === 'string' ? flags.window : undefined,
1399
- refresh: Number(flags.refresh) || 30,
1400
- submit: flags.submit === true || flags.submit === 'true',
1401
- })
1402
- } else if (cmd === 'enroll') {
1403
- await runEnroll({ label: flags.label })
1404
- } else if (cmd === 'submit') {
1405
- await runSubmit({ platform: flags.platform ?? 'claude', window: flags.window })
1406
- } else if (cmd === '--help' || cmd === '-h' || cmd === 'help') {
1407
- await showHelp()
1408
- } else if (cmd === '--version' || cmd === '-v') {
1409
- const { createRequire } = await import('module')
1410
- const req = createRequire(import.meta.url)
1411
- const pkg = req('./package.json')
1412
- writeln(pkg.version)
1413
- } else if (!cmd || cmd === 'start' || cmd === 'run') {
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
  }