sigrank 1.0.45 → 1.0.47
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/CHANGELOG.md +28 -0
- package/README.md +6 -3
- package/adapters/index.mjs +2 -0
- package/adapters/tokenpull.mjs +1 -1
- package/identity/keystore.mjs +3 -1
- package/manifest.json +1 -1
- package/package.json +3 -3
- package/presentation/cli.mjs +9 -4
- package/presentation/tui-themes.mjs +43 -28
- package/presentation/tui.mjs +960 -269
- package/proxy.mjs +16 -0
- package/resources/privacy-model.md +7 -4
- package/tokscale_analytics.mjs +0 -1
- package/tools/_helpers.mjs +6 -0
- package/tools/enroll.mjs +17 -3
- package/tools/submit-verified.mjs +13 -1
- package/tools/tokscale-developer-profile.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
### TUI
|
|
6
|
+
|
|
7
|
+
* Dashboard identity block: build archetype (pixel glyph + name), Υ, operating ratio and class for your combined all-time cascade; one-line form on small terminals
|
|
8
|
+
* Cascade table: Build (archetype) column per window on wide terminals; note when 7d/30d/90d are identical because no activity was logged between 7 and 90 days ago
|
|
9
|
+
* Four Degrees: values match signalaf.com/wiki/four-degrees; "Your Read" and the Top column no longer compare you against your own all-time numbers; new "Where you sit" Υ line
|
|
10
|
+
* Submit preview ([S]): shows every stat that will be sent per platform × window (token pillars, messages, mode, health, badges) plus what the board derives (Υ, op ratio, class, archetype), including the combined multi submission; [P] pages platforms
|
|
11
|
+
* Board: [U] toggles all submissions ↔ best row per operator; large Υ shown as M/B; spaced operating ratios
|
|
12
|
+
* Trends: unimplemented metrics folded into one "coming later" line; compact op ratio on narrow terminals
|
|
13
|
+
* Compare: source checklist (found / how to install) instead of a wall of text; sections render whole or not at all
|
|
14
|
+
* Narrow windows: footer hints wrap/compact instead of being cut off; tab bar sheds the clock/site/version before overflowing; terminal-cell-accurate widths; cut lines end in "…"; sections that don't fit are listed on a "▾ … below" line
|
|
15
|
+
* Platform colors follow brand colors (Claude orange, OpenAI green, Google blue/green, Devin blue, Copilot/Qwen purple, Kilo yellow, xAI silver, OpenClaw red)
|
|
16
|
+
|
|
17
|
+
## 1.0.46
|
|
18
|
+
|
|
19
|
+
### Security / privacy
|
|
20
|
+
|
|
21
|
+
* `enroll`: device label no longer defaults to the OS hostname; default is `sigrank <version> · <platform>` (opt-in override: `device_label` arg or `SIGRANK_DEVICE_LABEL`)
|
|
22
|
+
* `enroll` (MCP): refuses to re-bind an already-enrolled device; re-enroll from the CLI
|
|
23
|
+
* `submit_verified`: requires `confirm: true` to publish (not for `dry_run`); CLI/TUI pass it after their own consent
|
|
24
|
+
* `tokscale_developer_profile`: returns `workspace_count` only, no workspace/project names
|
|
25
|
+
* `validateApiBase`: https required except loopback hosts
|
|
26
|
+
* Pinned `ccusage` 20.0.30 and `tokscale` 4.18.0 exactly; removed stale `tokscale@latest` comment
|
|
27
|
+
* Proxy: rejects non-loopback Host headers and cross-site browser requests (403)
|
|
28
|
+
* Keystore: identity backups chmod 0600
|
|
29
|
+
* README / privacy-model corrected to list exactly what leaves the machine
|
|
30
|
+
|
|
3
31
|
## [1.0.44](https://github.com/SunrisesIllNeverSee/sigrank-mcp/releases/tag/v1.0.44) (2026-10-05)
|
|
4
32
|
|
|
5
33
|
### Features
|
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ sigrank submit
|
|
|
95
95
|
sigrank submit --dry-run
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
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 —
|
|
98
|
+
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 — what leaves your machine is limited to the four token pillars plus the identifiers listed under [Privacy](#privacy).
|
|
99
99
|
|
|
100
100
|
Or just explore without signing in:
|
|
101
101
|
|
|
@@ -314,7 +314,7 @@ Or if installed globally:
|
|
|
314
314
|
| `self_improve` | `{text?}` | One-click optimize: diagnoses, suggests, and simulates the best change in a single call |
|
|
315
315
|
| `tokscale_breakdown(threshold?)` | `{threshold?}` | Per-model token breakdown across platforms (models under threshold → "other") |
|
|
316
316
|
| `tokscale_market_share()` | `{}` | AI tool market share: each tool's % of tokens/cost/messages, ranked. From local tokscale data |
|
|
317
|
-
| `tokscale_developer_profile()` | `{}` | Per-developer usage profile across all detected tools: model mix, pillars, sessions,
|
|
317
|
+
| `tokscale_developer_profile()` | `{}` | Per-developer usage profile across all detected tools: model mix, pillars, sessions, workspace count (no names). Paths redacted |
|
|
318
318
|
| `tokscale_model_trends()` | `{}` | Model adoption over time: per-model first/last seen, active days, month-by-month adoption curve |
|
|
319
319
|
| `tokscale_cost_analysis()` | `{}` | Cost per developer per model: cost_per_million_tokens, cost_per_message, share_cost, client rollup |
|
|
320
320
|
| `tokscale_device_profile()` | `{}` | Device fingerprinting: installed tools, session counts, active days, day-of-week distribution, concurrency. Paths redacted |
|
|
@@ -405,6 +405,8 @@ All adapters are token-only (no message content, no cost fields, no credentials)
|
|
|
405
405
|
|
|
406
406
|
## Privacy
|
|
407
407
|
|
|
408
|
+
- **Exactly what leaves your machine (signed submit):** the four token pillars (input, output, cache create, cache read) per window, your codename, device id, device public key, ed25519 signature, agent version, platform, message/session counts, and the weekly report block. `enroll` additionally sends a device label, which defaults to `sigrank <version> · <platform>` (your hostname is never sent unless you set `SIGRANK_DEVICE_LABEL` or pass `device_label`). Never sent: prompts, responses, file paths, repo/project names, or environment variables.
|
|
409
|
+
- **MCP safety rails.** The `enroll` tool refuses to re-bind a device that is already enrolled (re-enroll from the CLI), and `submit_verified` requires `confirm: true` to publish (not needed with `dry_run`). `tokscale_developer_profile` returns workspace counts only, never workspace or project names.
|
|
408
410
|
- **Token-only persistence and submission.** Local-log adapters read usage metadata only. The optional proxy necessarily handles provider-bound request and response bytes in memory, but never persists their content; it writes only token counts, model/backend metadata, and timestamps. Only token telemetry is submitted to SigRank SignalAF.
|
|
409
411
|
- **Local by default.** `tokenpull` reads only the selected or detected adapter paths on your device (e.g. `~/.claude/projects` for Claude, `~/.codex` for Codex, plus additional paths for Amp, Devin, Gemini, Goose, and other supported platforms). Numbers stay on your machine unless you explicitly submit with a codename.
|
|
410
412
|
- **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.
|
|
@@ -417,7 +419,8 @@ All adapters are token-only (no message content, no cost fields, no credentials)
|
|
|
417
419
|
|
|
418
420
|
| Var | Default | Description |
|
|
419
421
|
| ----------------------- | ---------------------- | ---------------------------- |
|
|
420
|
-
| `SIGRANK_API_BASE` | `https://signalaf.com` | Override the board host
|
|
422
|
+
| `SIGRANK_API_BASE` | `https://signalaf.com` | Override the board host (https required; http only for loopback) |
|
|
423
|
+
| `SIGRANK_DEVICE_LABEL` | `sigrank <version> · <platform>` | Optional device label sent at enroll |
|
|
421
424
|
| `SIGRANK_FETCH_TIMEOUT` | `10000` | Board API fetch timeout (ms) |
|
|
422
425
|
|
|
423
426
|
---
|
package/adapters/index.mjs
CHANGED
|
@@ -1099,6 +1099,8 @@ async function execCcusage(args) {
|
|
|
1099
1099
|
if (existsSync(localEntrypoint)) {
|
|
1100
1100
|
return execFileP(process.execPath, [localEntrypoint, ...args], options);
|
|
1101
1101
|
}
|
|
1102
|
+
// Fallback only: the bundled (pinned) ccusage above is preferred; this resolves "ccusage"
|
|
1103
|
+
// from PATH when the bundled entrypoint is missing, so a PATH binary is trusted code here.
|
|
1102
1104
|
return execFileP("ccusage", args, options);
|
|
1103
1105
|
}
|
|
1104
1106
|
|
package/adapters/tokenpull.mjs
CHANGED
|
@@ -564,7 +564,7 @@ async function _freshTokscale(platform = "claude") {
|
|
|
564
564
|
*
|
|
565
565
|
* - ccusage : `ccusage <platform> daily --json` → 7d/30d/90d/all
|
|
566
566
|
* - tokendash: refresh + read ~/.claude/token-dashboard.db → all (claude only)
|
|
567
|
-
* - tokscale : `
|
|
567
|
+
* - tokscale : `tokscale models --json` (bundled, pinned) → all
|
|
568
568
|
*/
|
|
569
569
|
export async function freshVerifierPillars(platform = "claude") {
|
|
570
570
|
const p = platform || "claude";
|
package/identity/keystore.mjs
CHANGED
|
@@ -61,7 +61,9 @@ export function persistIdentity(identity) {
|
|
|
61
61
|
if (existsSync(PATH)) {
|
|
62
62
|
try {
|
|
63
63
|
const stamp = Date.now();
|
|
64
|
-
|
|
64
|
+
const bakPath = join(DIR, `${BACKUP_PREFIX}${stamp}`);
|
|
65
|
+
copyFileSync(PATH, bakPath);
|
|
66
|
+
chmodSync(bakPath, 0o600);
|
|
65
67
|
pruneBackups();
|
|
66
68
|
} catch {
|
|
67
69
|
/* best-effort — don't block the write */
|
package/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/anthropics/mcpb/main/schemas/mcpb-manifest-v0.4.schema.json",
|
|
3
3
|
"manifest_version": "0.4",
|
|
4
4
|
"name": "sigrank",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.47",
|
|
6
6
|
"description": "Ranks AI coding operators by token cascade efficiency (Yield = cache_read \u00d7 output / input\u00b2). 25 tools including SigRank Standard record, yield calculation, local token usage pulls, signed submission, and tokscale-powered analytics (market share, developer profiles, model trends, cost analysis, device profiles, MCP usage, competitive intelligence). Privacy-first: runs locally, only four token counts leave the machine.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "SunrisesIllNeverSee",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigrank",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.47",
|
|
4
4
|
"author": "SunrisesIllNeverSee (https://github.com/SunrisesIllNeverSee)",
|
|
5
5
|
"description": "Upsilon measurement engine distributed through the sigrank CLI/MCP compatibility package, with SigRank public leaderboard tools.",
|
|
6
6
|
"mcpName": "io.github.SunrisesIllNeverSee/sigrank-mcp",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
],
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"token-cascade": "0.2.1",
|
|
85
|
-
"ccusage": "
|
|
86
|
-
"tokscale": "
|
|
85
|
+
"ccusage": "20.0.30",
|
|
86
|
+
"tokscale": "4.18.0",
|
|
87
87
|
"@modelcontextprotocol/server": "2.3.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
package/presentation/cli.mjs
CHANGED
|
@@ -1719,10 +1719,14 @@ async function runEnroll({ label } = {}) {
|
|
|
1719
1719
|
|
|
1720
1720
|
let out;
|
|
1721
1721
|
try {
|
|
1722
|
-
out = await callTool(
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1722
|
+
out = await callTool(
|
|
1723
|
+
"enroll",
|
|
1724
|
+
{
|
|
1725
|
+
code,
|
|
1726
|
+
device_label: typeof label === "string" ? label : undefined,
|
|
1727
|
+
},
|
|
1728
|
+
{ allowReenroll: true }, // human at a TTY already consented above
|
|
1729
|
+
);
|
|
1726
1730
|
} catch (e) {
|
|
1727
1731
|
writeln(red(` ✗ ${e.message}`));
|
|
1728
1732
|
process.exitCode = 1;
|
|
@@ -1778,6 +1782,7 @@ async function runSubmit({ platform = "claude", window } = {}) {
|
|
|
1778
1782
|
platform,
|
|
1779
1783
|
window: typeof window === "string" ? window : undefined,
|
|
1780
1784
|
dry_run: process.argv.includes("--dry-run"),
|
|
1785
|
+
confirm: true, // explicit CLI invocation is the confirmation
|
|
1781
1786
|
});
|
|
1782
1787
|
} catch (e) {
|
|
1783
1788
|
writeln(red(` ✗ ${e.message}`));
|
|
@@ -132,40 +132,31 @@ export function getThemeNames() {
|
|
|
132
132
|
// (the default theme). For light theme, darker 256-color variants are used.
|
|
133
133
|
// Monochrome theme returns no color (bold only) — colorblind-safe.
|
|
134
134
|
//
|
|
135
|
-
// Color assignments (dark theme 256-color codes):
|
|
136
|
-
// claude = 75 (blue-cyan)
|
|
137
|
-
// codex = 114 (green)
|
|
138
|
-
// amp = 179 (orange)
|
|
139
|
-
// gemini = 129 (purple-magenta)
|
|
140
|
-
// kimi = 213 (pink)
|
|
141
|
-
// qwen = 68 (steel blue)
|
|
142
|
-
// goose = 142 (olive)
|
|
143
|
-
// kilo = 166 (dark orange)
|
|
144
|
-
// hermes = 96 (plum)
|
|
145
|
-
// droid = 167 (salmon)
|
|
146
|
-
// codebuff = 72 (teal-green)
|
|
147
|
-
// copilot = 33 (bright blue)
|
|
148
|
-
// openclaw = 136 (gold-brown)
|
|
149
|
-
// pi = 177 (light purple)
|
|
150
|
-
// omp = 220 (gold — the "oh my pi" platform gets gold)
|
|
151
|
-
// opencode = 60 (slate)
|
|
152
|
-
// devin = 30 (teal)
|
|
153
|
-
// proxy = 245 (gray — synthetic passthrough)
|
|
154
|
-
// other = 245 (gray — catch-all)
|
|
155
135
|
|
|
136
|
+
// Brand-matched (owner 2026-10-15: "claude orange, devin blue, etc"):
|
|
137
|
+
// claude Anthropic orange · codex OpenAI green · gemini Google blue ·
|
|
138
|
+
// antigravity Google green · devin Cognition blue · copilot GitHub purple ·
|
|
139
|
+
// qwen purple · kilo yellow · grok xAI silver · openclaw lobster red ·
|
|
140
|
+
// amp red · kimi Moonshot blue · hermes Nous blue · droid Factory orange ·
|
|
141
|
+
// codebuff acid green · pi gold (π palette) · zcode Z.ai blue.
|
|
142
|
+
// goose / opencode have monochrome brands → distinct neutral greys.
|
|
143
|
+
// omp keeps its gold. Codes nudged where the nearest brand code collided
|
|
144
|
+
// with another platform (amp 196 vs openclaw 203, droid 208 vs 202, …).
|
|
156
145
|
const PLATFORM_COLORS_DARK = {
|
|
157
|
-
claude:
|
|
158
|
-
qwen:
|
|
159
|
-
codebuff:
|
|
160
|
-
opencode:
|
|
146
|
+
claude: 173, codex: 36, amp: 196, gemini: 69, kimi: 33,
|
|
147
|
+
qwen: 63, goose: 245, kilo: 227, hermes: 27, droid: 208,
|
|
148
|
+
codebuff: 48, copilot: 98, openclaw: 203, pi: 179, omp: 220,
|
|
149
|
+
opencode: 252, devin: 39, proxy: 240, other: 240,
|
|
150
|
+
antigravity: 71, grok: 250, zcode: 111,
|
|
161
151
|
};
|
|
162
152
|
|
|
163
153
|
// Light theme: darker shades of the same hues for contrast on white
|
|
164
154
|
const PLATFORM_COLORS_LIGHT = {
|
|
165
|
-
claude:
|
|
166
|
-
qwen:
|
|
167
|
-
codebuff:
|
|
168
|
-
opencode:
|
|
155
|
+
claude: 130, codex: 29, amp: 160, gemini: 26, kimi: 27,
|
|
156
|
+
qwen: 56, goose: 243, kilo: 136, hermes: 21, droid: 94,
|
|
157
|
+
codebuff: 29, copilot: 55, openclaw: 124, pi: 136, omp: 136,
|
|
158
|
+
opencode: 243, devin: 25, proxy: 242, other: 242,
|
|
159
|
+
antigravity: 28, grok: 240, zcode: 24,
|
|
169
160
|
};
|
|
170
161
|
|
|
171
162
|
/**
|
|
@@ -187,3 +178,27 @@ export function platformColor(platform) {
|
|
|
187
178
|
}
|
|
188
179
|
return (s) => `${ESC}38;5;${code}m${s}${currentTheme.reset}`;
|
|
189
180
|
}
|
|
181
|
+
|
|
182
|
+
// ── Build archetype colors ──────────────────────────────────────────────────
|
|
183
|
+
// Hues follow signalaf.com/field (build archetypes), mapped to 256-color codes.
|
|
184
|
+
// Keys match classifyArchetype().key in presentation/narrate.mjs.
|
|
185
|
+
const ARCHETYPE_COLORS_DARK = {
|
|
186
|
+
convergent: 140, kinetic: 204, amplifier: 209, recursive: 178, builder: 214,
|
|
187
|
+
archivist: 35, "deep-reader": 41, contextual: 79, priming: 74, "input-bound": 33,
|
|
188
|
+
};
|
|
189
|
+
const ARCHETYPE_COLORS_LIGHT = {
|
|
190
|
+
convergent: 97, kinetic: 161, amplifier: 166, recursive: 136, builder: 130,
|
|
191
|
+
archivist: 29, "deep-reader": 28, contextual: 30, priming: 31, "input-bound": 25,
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/** Paint function for a build archetype key, theme-aware (monochrome → bold). */
|
|
195
|
+
export function archetypeColor(key) {
|
|
196
|
+
const themeName = currentTheme.name;
|
|
197
|
+
if (themeName === "monochrome") {
|
|
198
|
+
return (s) => `${currentTheme.bold}${s}${currentTheme.reset}`;
|
|
199
|
+
}
|
|
200
|
+
const map = themeName === "light" ? ARCHETYPE_COLORS_LIGHT : ARCHETYPE_COLORS_DARK;
|
|
201
|
+
const code = map[key];
|
|
202
|
+
if (code == null) return (s) => `${currentTheme.cyan}${s}${currentTheme.reset}`;
|
|
203
|
+
return (s) => `${ESC}38;5;${code}m${s}${currentTheme.reset}`;
|
|
204
|
+
}
|