sigrank 0.0.175

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Deric J. McHenry / Ello Cello LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,420 @@
1
+ # SigRank MCP
2
+
3
+ > **🏆 SigRank is live: [signalaf.com](https://signalaf.com)** — the leaderboard for how
4
+ > efficiently you use AI, not how much. Run `npx sigrank` to see your cascade now.
5
+ > _Token counts only. Never your prompts._
6
+
7
+ <div align="center">
8
+
9
+ <p><img src="./.github/assets/og-card.png" alt="SigRank — the new standard in AI evaluation &amp; benchmarks" width="800"></p>
10
+
11
+ **The yield cascade + live leaderboard as MCP tools any agent can call.**
12
+
13
+ For all builders, burners and 10xers.
14
+
15
+ [![npm version](https://img.shields.io/npm/v/sigrank.svg?style=flat-square&color=gold)](https://www.npmjs.com/package/sigrank)
16
+ [![CI](https://github.com/SunrisesIllNeverSee/sigrank-mcp/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/SunrisesIllNeverSee/sigrank-mcp/actions/workflows/ci.yml)
17
+ [![CodeQL](https://github.com/SunrisesIllNeverSee/sigrank-mcp/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/SunrisesIllNeverSee/sigrank-mcp/actions/workflows/codeql.yml)
18
+ [![audit](https://github.com/SunrisesIllNeverSee/sigrank-mcp/actions/workflows/dependency-audit.yml/badge.svg?branch=main)](https://github.com/SunrisesIllNeverSee/sigrank-mcp/actions/workflows/dependency-audit.yml)
19
+ [![Dependabot](https://img.shields.io/badge/Dependabot-enabled-025E8C?style=flat-square&logo=dependabot)](https://github.com/SunrisesIllNeverSee/sigrank-mcp/network/dependencies)
20
+ [![license](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](./LICENSE)
21
+ [![platform](https://img.shields.io/badge/platform-node-grey.svg?style=flat-square)](https://nodejs.org)
22
+ [![live](https://img.shields.io/badge/board-signalaf.com-gold.svg?style=flat-square)](https://signalaf.com)
23
+ [![SunrisesIllNeverSee/sigrank-mcp MCP server](https://glama.ai/mcp/servers/SunrisesIllNeverSee/sigrank-mcp/badges/score.svg)](https://glama.ai/mcp/servers/SunrisesIllNeverSee/sigrank-mcp)
24
+ [![Smithery](https://smithery.ai/badge/burnmydays/sigrank)](https://smithery.ai/servers/burnmydays/sigrank)
25
+
26
+ </div>
27
+
28
+ <p align="center">
29
+ <a href="https://www.npmjs.com/package/sigrank"><img src="https://img.shields.io/badge/$%20npx%20sigrank-gold?style=for-the-badge&logo=npm&logoColor=white&labelColor=1a1a1a&color=daa520" alt="npx sigrank" /></a>
30
+ </p>
31
+
32
+ ## Table of Contents
33
+
34
+ - [The SigRank ecosystem](#the-sigrank-ecosystem)
35
+ - [Quickstart](#quickstart--3-steps-to-the-board)
36
+ - [Install from GitHub](#install-from-github)
37
+ - [Install via Smithery](#install-via-smithery)
38
+ - [Commands](#commands)
39
+ - [MCP Server mode](#mcp-server-mode)
40
+ - [Cascade math](#cascade-math)
41
+ - [Token Pillars](#token-pillars--sources)
42
+ - [Platform adapters](#platform-adapters)
43
+ - [Privacy](#privacy)
44
+ - [Env vars](#env-vars)
45
+ - [Dev / test](#dev--test)
46
+ - [File map](#file-map)
47
+ - [Contributing](#contributing)
48
+ - [License](#license)
49
+
50
+ | The board | Your operator profile |
51
+ | :-----------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------: |
52
+ | [![SigRank leaderboard](./.github/assets/board.png)](https://signalaf.com/board/all) | [![SigRank operator profile](./.github/assets/profile.png)](https://signalaf.com) |
53
+ | Every operator ranked by **Υ Yield** — the architecture of the cascade, not raw spend | Cascade layer, class, and fingerprint — derived from four token counts |
54
+
55
+ > **Run [`sigrank enroll`](#sign-in--submit) then [`sigrank submit`](#sign-in--submit) to get ranked and claim your public profile at [signalaf.com](https://signalaf.com).**
56
+
57
+ ---
58
+
59
+ ## The SigRank ecosystem
60
+
61
+ | Repo | What it is | Install |
62
+ |------|-----------|---------|
63
+ | **[sigrank-mcp](https://github.com/SunrisesIllNeverSee/sigrank-mcp)** (this repo) | The instrument — extracts 4 token pillars, computes the cascade, submits to the leaderboard. MCP server + TUI dashboard. | `npx sigrank` |
64
+ | **[sigrank-app](https://github.com/SunrisesIllNeverSee/sigrank-app)** | The leaderboard — signalaf.com. Privacy-preserving operator profiles, class tiers, board rankings. | [signalaf.com](https://signalaf.com) |
65
+ | **[signaf](https://github.com/SunrisesIllNeverSee/signa)** | The coach — reads your session logs, builds a taste profile, measures ASI, coaches you on token efficiency. | `npx @burnmydays/signaf` |
66
+ | **[sigrank-vscode](https://github.com/SunrisesIllNeverSee/sigrank-vscode)** | The IDE extension — see your cascade metrics inline in VS Code. | `code --install-extension sigrank.sigrank` |
67
+ | **[fundscore](https://github.com/SunrisesIllNeverSee/fundscore)** | The repo scorer — investor-readiness scoring for GitHub repos. CLI + MCP server. | `npx fundscore` |
68
+
69
+ ## Quickstart — 3 steps to the board
70
+
71
+ ```bash
72
+ # 1. Install (pulls ccusage + tokscale + tokendash automatically — no separate installs)
73
+ npm install -g sigrank
74
+
75
+ # 2. Sign in (paste a connect code from signalaf.com → Settings → New key)
76
+ sigrank enroll
77
+
78
+ # 3. Submit your cascade to the board
79
+ sigrank submit
80
+
81
+ # (cautious? see exactly what would be sent — four counts + a signature — sending nothing)
82
+ sigrank submit --dry-run
83
+ ```
84
+
85
+ That's it. sigrank reads your local AI session logs on-device, derives your token cascade (Υ Yield, Leverage, Velocity, 10xDEV), and publishes to [signalaf.com](https://signalaf.com). No paste, no transcript content — only the four token counts leave your machine.
86
+
87
+ Or just explore without signing in:
88
+
89
+ ```bash
90
+ sigrank # launches the full tabbed TUI (dashboard, compare, board, watch)
91
+ npx sigrank board --once # print the live leaderboard once
92
+ ```
93
+
94
+ ## Install from GitHub
95
+
96
+ ```bash
97
+ git clone https://github.com/SunrisesIllNeverSee/sigrank-mcp.git
98
+ cd sigrank-mcp
99
+ npm install
100
+
101
+ # Run CLI
102
+ node index.mjs # TUI (if TTY)
103
+ node cli.mjs board --once # leaderboard one-shot
104
+
105
+ # Or link globally for `sigrank` command
106
+ npm link
107
+ sigrank
108
+ ```
109
+
110
+ **Repo:** [`SunrisesIllNeverSee/sigrank-mcp`](https://github.com/SunrisesIllNeverSee/sigrank-mcp)
111
+ **Site:** [signalaf.com](https://signalaf.com)
112
+ **npm:** [sigrank](https://www.npmjs.com/package/sigrank)
113
+ **Smithery:** [smithery.ai/servers/burnmydays/sigrank](https://smithery.ai/servers/burnmydays/sigrank)
114
+ **Glama:** [glama.ai/mcp/servers/SunrisesIllNeverSee/sigrank-mcp](https://glama.ai/mcp/servers/SunrisesIllNeverSee/sigrank-mcp)
115
+
116
+ ---
117
+
118
+ ## Install via Smithery
119
+
120
+ SigRank is available on [Smithery](https://smithery.ai/servers/burnmydays/sigrank) as a stdio MCP bundle — one-click install for Claude Desktop, Cursor, and other MCP clients.
121
+
122
+ ### Smithery CLI
123
+
124
+ ```bash
125
+ # Install Smithery CLI
126
+ npm install -g smithery
127
+
128
+ # Connect to SigRank (downloads the MCPB bundle locally)
129
+ smithery mcp add burnmydays/sigrank --id sigrank
130
+
131
+ # List available tools
132
+ smithery tool list sigrank
133
+
134
+ # Call a tool
135
+ smithery tool call sigrank get_leaderboard '{}'
136
+ smithery tool call sigrank rank_paste '{"text": "1000000 500000 50000 800000"}'
137
+ ```
138
+
139
+ ### Claude Desktop (via Smithery)
140
+
141
+ 1. Go to [smithery.ai/servers/burnmydays/sigrank](https://smithery.ai/servers/burnmydays/sigrank)
142
+ 2. Click **Install**
143
+ 3. Smithery handles the rest — no manual config editing
144
+
145
+ ---
146
+
147
+ ## Commands
148
+
149
+ ```
150
+ ⊙ SigRank CLI v0.0.175
151
+
152
+ Default (no args)
153
+ sigrank unified dashboard: cascade + token pillars + board
154
+
155
+ Commands
156
+ enroll sign in: paste a connect code (get one at signalaf.com → Settings)
157
+ submit publish your verified runs to the board (sign in first)
158
+ board live leaderboard (refreshes every 30s)
159
+ board --window 7d board for a specific window (7d, 30d, 90d, all)
160
+ board --once print once and exit
161
+ compare raw pillar audit: tokenpull vs ccusage vs token-dash vs tokscale
162
+ compare --platform codex compare for a specific platform
163
+ tui full tabbed TUI: Dashboard / Trends / Compare / Board / Watch / Connect
164
+ tui --platform codex TUI with a different default platform
165
+ watch live tune meter — ALL active platforms × all windows, every 30s
166
+ watch --platform codex watch only one platform (optional filter)
167
+ watch --window 7d watch only one window (optional filter)
168
+
169
+ Options
170
+ --window 7d · 30d · 90d · all (default: 30d for board; all windows for watch)
171
+ --platform claude · codex · amp · gemini · opencode · goose · …
172
+ --refresh poll interval in seconds (default: 30)
173
+ --once print once and exit (board only)
174
+
175
+ For AI clients (not typeable)
176
+ In a piped/non-TTY context, sigrank is an MCP stdio server.
177
+ AI clients (Claude, Cursor, …) call its tools automatically — these are
178
+ NOT shell commands. Humans use the commands above.
179
+
180
+ Examples
181
+ sigrank # unified dashboard
182
+ sigrank board # live leaderboard
183
+ sigrank compare # pillar audit (claude)
184
+ sigrank compare --platform codex
185
+ sigrank watch --window 7d --refresh 60
186
+ sigrank board --window all --once
187
+ ```
188
+
189
+ ### The TUI is the whole app
190
+
191
+ Launch it and sign in inside it:
192
+
193
+ ```
194
+ npx sigrank
195
+ ```
196
+
197
+ Six tabs. Keys: `1`-`6` or `←` `→` to switch · `R` refresh · `Q` quit.
198
+
199
+ | Tab | Key | Content |
200
+ | ------------- | --- | ------------------------------------------------------------------------------------------------------------------------------------ |
201
+ | **Dashboard** | `1` | Cascade table (all platforms × windows + combined) · Υ sparklines · token composition bars · mini board |
202
+ | **Trends** | `2` | Every metric across windows — sub-views: You / Platform / Field |
203
+ | **Compare** | `3` | 4-source pillar audit (tokenpull vs ccusage vs token-dash vs tokscale) · delta % · cascade metrics per source · cache read bar chart |
204
+ | **Board** | `4` | Full leaderboard with all fields · `[W]` cycles window (7d/30d/90d/all) |
205
+ | **Watch** | `5` | In-TUI landing panel · `[Enter]` launches the live watcher (big numbers + pillar bars + Υ trend, auto-refreshes 30s) |
206
+ | **Connect** | `6` | Sign in / switch device — paste a connect code from signalaf.com → Settings. Then `[S]` submits. |
207
+
208
+ ### Sign in + submit
209
+
210
+ ```bash
211
+ sigrank enroll # sign in: paste a connect code (get one at signalaf.com → Settings)
212
+ sigrank submit # publish your verified runs to the board (sign in first)
213
+ sigrank submit --dry-run # inspect the exact signed payload without sending anything
214
+ ```
215
+
216
+ Or do it inside the TUI on the **Connect** tab (`6`), then press `[S]` to submit.
217
+
218
+ ---
219
+
220
+ ## MCP Server mode
221
+
222
+ When stdout is not a TTY (i.e. piped to an AI client), `sigrank` starts an MCP stdio server automatically. AI clients (Claude Code, Cursor, Windsurf, etc.) use this path.
223
+
224
+ Add to `.mcp.json` or equivalent:
225
+
226
+ ```json
227
+ {
228
+ "mcpServers": {
229
+ "sigrank": {
230
+ "command": "npx",
231
+ "args": ["-y", "sigrank"]
232
+ }
233
+ }
234
+ }
235
+ ```
236
+
237
+ Or if installed globally:
238
+
239
+ ```json
240
+ {
241
+ "mcpServers": {
242
+ "sigrank": {
243
+ "command": "sigrank"
244
+ }
245
+ }
246
+ }
247
+ ```
248
+
249
+ ## Tools
250
+
251
+ | Tool | Args | What |
252
+ | ------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
253
+ | `rank_paste(text)` | `{input, output, cacheCreate, cacheRead}` JSON or 4 whitespace-delimited numbers | Scores token pillars → Υ Yield / SNR / Leverage / Velocity / 10xDEV / Class + prose narration card |
254
+ | `get_leaderboard()` | `{window?}` | Live board from signalaf.com — sorted by Υ Yield |
255
+ | `get_operator(codename)` | `{codename}` | One operator's live profile |
256
+ | `submit_paste(text, codename)` | `{text, codename?}` | Rank locally then POST to board. Omit codename for preview-only |
257
+ | `tokenpull(platform?)` | `{platform?}` | On-device local reader: scans local logs → 4-window cascade. Zero paste, token-only |
258
+ | `tokenpull_submit(codename, window?)` | `{codename?, window?}` | `tokenpull` → publish to board. Omit codename for preview |
259
+ | `tokenpull_compare(platform?)` | `{platform?}` | All four sources side-by-side: tokenpull + ccusage + token-dash + tokscale. Returns pillars, cascade metrics, and delta % vs tokenpull per window |
260
+ | `rank_windows` | `{platform?, window?}` | Multi-window cascade from local logs |
261
+ | `watch_tokenpull` | `{platform?, interval_s?}` | One cascade snapshot per call (interval_s advisory) |
262
+ | `submit_verified` | `{window?, platform?, dry_run?}` | THE ranked path: builds + ed25519-signs Schema 1.0 snapshots and POSTs them. `platform:'multi'` sums all active platforms. `dry_run:true` returns the exact payload unsent |
263
+ | `enroll` | `{code, device_label?}` | Bind this device with a connect code from signalaf.com → Settings |
264
+ | `diagnose_cascade` | `{text?}` | Diagnoses where your token cascade is leaking efficiency — ranked findings with severity + estimated Υ impact |
265
+ | `simulate_change` | `{text?, changes}` | Prescriptive "what if" — test proposed pillar changes and see the exact Υ delta + class change before committing |
266
+ | `suggest_improvements` | `{text?}` | Generates ranked, simulated improvement suggestions — tests strategies and returns them sorted by Υ yield impact |
267
+ | `self_improve` | `{text?}` | One-click optimize: diagnoses, suggests, and simulates the best change in a single call |
268
+ | `get_best_operator(n?)` | `{n?}` | Top N operators with behavioral framing in power-user language. Intent: "who is the best AI user?" |
269
+ | `compare_self(codename? \| text?)` | `{codename?}` or `{text?}` | Your metrics vs board averages + power-user assessment + percentile + suggestion. Intent: "how do I measure up?" |
270
+ | `compare_operators(a, b)` | `{codename_a, codename_b}` | Side-by-side comparison with behavioral verdict. Intent: "compare operator X vs Y" |
271
+ | `describe_power_user()` | `{}` | Static explanation of AI power user archetype + metrics explained. Intent: "what is an AI power user?" |
272
+ | `optimize_efficiency(codename? \| text?)` | `{codename?}` or `{text?}` | Ranked efficiency suggestions tied to your cascade shape. Intent: "how can I use AI more efficiently?" |
273
+
274
+ ---
275
+
276
+ ## Cascade math
277
+
278
+ ```
279
+ Υ Yield = (cache_read × output) / input²
280
+ SNR = output / (input + output)
281
+ Leverage = cache_read / input
282
+ Velocity = output / input
283
+ 10xDEV = log₁₀(leverage)
284
+ ```
285
+
286
+ Math is in `cascade.mjs`, dependency-free. Mirrors `sigrank-app/lib/ingest/bridge.ts`.
287
+ Canon check: `MO§ES (1251211, 11296121, 128196310, 2555179769) → Υ 18436.98`.
288
+
289
+ ---
290
+
291
+ ## Token Pillars — sources
292
+
293
+ The dashboard pulls from multiple sources and shows them side-by-side for verification:
294
+
295
+ | Source | What | Platform |
296
+ | ----------------- | ------------------------------------------------------------------------------ | --------------------- |
297
+ | `tokenpull` | On-device JSONL scanner (canon source) | claude, codex, amp, … |
298
+ | `ccusage` | `ccusage <platform> daily --json` CLI (bundled) | claude, codex |
299
+ | `token-dashboard` | `~/.claude/token-dashboard.db` SQLite (bundled) | claude only |
300
+ | `tokscale` | `tokscale models --json` CLI (bundled, falls back to `~/tokscale_report.json`) | claude, codex |
301
+
302
+ **Codex input is estimated** — Codex logs don't expose true input tokens directly. The formula:
303
+
304
+ ```
305
+ input = output × ioRatio (ioRatio derived from Claude ratio, else 2.0)
306
+ cacheCreate = uncached − input (uncached = input_tokens − cached_input_tokens)
307
+ cacheRead = exact (from logs)
308
+ ```
309
+
310
+ Verifier numbers (ccusage/tokscale for codex) show **raw uncached input** (`input_tokens − cached`) — a different field than the estimated input above. The discrepancy is expected and explained inline in the dashboard.
311
+
312
+ ---
313
+
314
+ ## Platform adapters
315
+
316
+ All adapters are token-only (no message content, no cost fields, no credentials).
317
+
318
+ | Platform | Path | Notes |
319
+ | ------------------ | ---------------------------------------------- | --------------------------------------------------------------- |
320
+ | Claude Code | ✅ `~/.claude/projects` | Native; dedup by `(session_id, message_id)`; subagents included |
321
+ | Codex | ✅ `~/.codex/sessions` | Estimated input via `io_ratio`; verified vs ccusage |
322
+ | Amp | ✅ `~/.local/share/amp/threads` | Full 4-pillar; per-message |
323
+ | Kimi | ✅ `~/.kimi/sessions` | Full 4-pillar; `StatusUpdate` lines only |
324
+ | pi-agent | ✅ `~/.pi/agent/sessions` | Full 4-pillar; per-message JSONL |
325
+ | OpenClaw | ✅ `~/.openclaw` | Full 4-pillar; per-message JSONL |
326
+ | Droid | ✅ `~/.factory/sessions/*.settings.json` | Full 4-pillar; thinking→output |
327
+ | Codebuff | ✅ `~/.config/manicode` | Full 4-pillar; `chat-messages.json` |
328
+ | Hermes | ✅ `~/.hermes/state.db` | Full 4-pillar; SQLite; reasoning→output |
329
+ | Kilo | ✅ `~/.local/share/kilo/kilo.db` | Full 4-pillar; SQLite |
330
+ | Qwen | ✅ `~/.qwen/projects` | `cacheCreate=0` estimated; thought→output |
331
+ | Goose | ✅ `~/.local/share/goose/sessions/sessions.db` | `cacheCreate=cacheRead=0` estimated; SQLite |
332
+ | Gemini CLI | ✅ `~/.gemini/tmp` | `cacheCreate=0` estimated; cache extracted from input field |
333
+ | GitHub Copilot CLI | ✅ `~/.copilot/otel` | OTel JSONL; requires `COPILOT_OTEL_ENABLED=true` |
334
+ | OpenCode | ⚠️ `~/.local/share/opencode` | Raw token counts not persisted in log format |
335
+ | Cursor | 🔜 | Chat log path TBD |
336
+ | Windsurf | 🔜 | Session logs at `~/.codeium/windsurf/` |
337
+
338
+ `estimated=true` means one or more pillars are derived, not native. The server re-scores all submitted pillars authoritatively; local preview Υ is indicative only.
339
+
340
+ ---
341
+
342
+ ## Privacy
343
+
344
+ - **Token-only, always.** No message content is ever read, logged, or transmitted — only token counts (`input`, `output`, `cache_creation`, `cache_read`), message IDs, and timestamps.
345
+ - **Local by default.** `tokenpull` reads only `~/.claude/projects` (Claude) or `~/.codex` (Codex) on your device. Numbers stay on your machine unless you explicitly submit with a codename.
346
+ - **Background tooling excluded.** Memory plugins, observers, summarizers (e.g. `claude-mem`, `mem0`, `observer-sessions`) are filtered from both Claude and Codex reads. `subagents/` are kept — they represent real operator work.
347
+ - **Board reads are anonymous.** No account needed to browse, compare, or watch.
348
+ - **Ranked submissions are signed, not trusted.** `sigrank submit` requires a one-time `enroll` (device-bound ed25519 key — the private key never leaves your machine). Verify what's sent with `sigrank submit --dry-run`: the payload is four token counts, ratios, and a signature.
349
+
350
+ ---
351
+
352
+ ## Env vars
353
+
354
+ | Var | Default | Description |
355
+ | ----------------------- | ---------------------- | ---------------------------- |
356
+ | `SIGRANK_API_BASE` | `https://signalaf.com` | Override the board host |
357
+ | `SIGRANK_FETCH_TIMEOUT` | `10000` | Board API fetch timeout (ms) |
358
+
359
+ ---
360
+
361
+ ## Dev / test
362
+
363
+ ```bash
364
+ node test.mjs # 13 test groups, 200 assertions (no network, no fs writes)
365
+ node sign.test.mjs # ed25519 signing + canon parity
366
+ node index.mjs # stdio MCP server directly (pipe to MCP client)
367
+ ```
368
+
369
+ Tests verify (13 groups, 200 assertions):
370
+
371
+ - `rank_paste` canon: MO§ES `(1251211, 11296121, 128196310, 2555179769)` → Υ 18436.98 · TRANSMITTER
372
+ - `submit_paste` preview (no codename) + POST shape (injected fetch, no live writes)
373
+ - `tokenpull` dedup, window slicing, 4-window pillars (mock adapter)
374
+ - `tokenpull_submit` all 4 windows POST, sha256 hash, ddmmyy stamp
375
+ - `tokenpullCodex` io_ratio conversion per-window
376
+ - Adapter registry (15 platforms) + per-adapter shape contracts
377
+ - `rank_windows` 4-window paste scoring, partial input, no-network
378
+ - `watch_tokenpull` cascade snapshot, interval_s, submit path
379
+ - `enroll` posts identity (public key only), maps 201 enrolled + 410 code_invalid
380
+ - `submit_verified` signs Schema 1.0, server-verifiable
381
+ - `simulate_change` relative + absolute deltas, quadratic penalty, JSON input
382
+ - Hardening: div-by-zero guards, parsePillars warnings, fetch timeout, EXCLUDE_TOOLING regex, narrate safety
383
+ - `sign.test.mjs` ed25519 round-trip + canonical 926-byte payload parity
384
+
385
+ ---
386
+
387
+ ## File map
388
+
389
+ | File | Responsibility |
390
+ | --------------- | ----------------------------------------------------------------------- |
391
+ | `index.mjs` | Entry point — TTY detection, routes to CLI or MCP server |
392
+ | `cli.mjs` | CLI commands: board, compare, watch, enroll, submit, help |
393
+ | `tui.mjs` | Full tabbed TUI: Dashboard / Trends / Compare / Board / Watch / Connect |
394
+ | `cascade.mjs` | Pure cascade math (Υ, SNR, leverage, velocity, 10xDEV, class) |
395
+ | `tokenpull.mjs` | On-device log scanner — Claude, Codex, multi-platform |
396
+ | `adapters.mjs` | Platform adapter registry (15+ platforms) |
397
+ | `tools.mjs` | MCP tool table + dispatcher |
398
+ | `connect.mjs` | Connect-code enrollment + device identity |
399
+ | `keystore.mjs` | Local key management (paste-keys, not API keys) |
400
+ | `submit.mjs` | Verified submit flow (signs + POSTs to board) |
401
+ | `sign.mjs` | Schema 1.0 signing (X-Agent-Signature) |
402
+ | `narrate.mjs` | Deterministic prose narration card |
403
+ | `preflight.mjs` | Plausibility checks (Benford, bounds, anomaly detection) |
404
+ | `test.mjs` | Unit tests (no external deps) |
405
+ | `sign.test.mjs` | ed25519 signing + canon parity test |
406
+
407
+ ---
408
+
409
+ ## Contributing
410
+
411
+ Contributions welcome. SigRank MCP is built in the open.
412
+
413
+ - [Contributing guide](./.github/CONTRIBUTING.md)
414
+ - [Security policy](https://github.com/SunrisesIllNeverSee/sigrank-mcp/security/policy)
415
+ - Report bugs via [GitHub Issues](https://github.com/SunrisesIllNeverSee/sigrank-mcp/issues)
416
+ - PRs: fork → branch → `node test.mjs` passes → open PR against `main`
417
+
418
+ ## License
419
+
420
+ MIT — see [`LICENSE`](./LICENSE).