sigrank 0.0.181 → 0.0.183
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -22
- package/adapters/index.mjs +55 -22
- package/adapters/tokenpull.mjs +20 -28
- package/analytics/cascade.mjs +117 -12
- package/identity/keystore.mjs +1 -12
- package/lib/constants.mjs +111 -0
- package/lib/pkg-version.mjs +59 -0
- package/package.json +2 -1
- package/presentation/cli.mjs +51 -53
- package/presentation/tui.mjs +37 -40
- package/resources/class-tiers.md +79 -21
- package/resources/privacy-model.md +8 -5
- package/submit/index.mjs +8 -21
- package/tokscale_analytics.mjs +5 -16
- package/tools/_framing.mjs +95 -17
- package/tools/_helpers.mjs +5 -10
- package/tools/_schemas.mjs +68 -38
- package/tools/compare-operators.mjs +2 -1
- package/tools/compare-self.mjs +4 -2
- package/tools/describe-power-user.mjs +16 -6
- package/tools/diagnose-cascade.mjs +1 -1
- package/tools/enroll.mjs +1 -3
- package/tools/get-best-operator.mjs +2 -1
- package/tools/get-leaderboard.mjs +3 -2
- package/tools/get-operator.mjs +1 -1
- package/tools/index.mjs +4 -42
- package/tools/optimize-efficiency.mjs +15 -5
- package/tools/rank-paste.mjs +1 -1
- package/tools/self-improve.mjs +1 -1
- package/tools/submit-paste.mjs +13 -10
- package/tools/tokenpull-submit.mjs +11 -10
- package/tools/tokscale-breakdown.mjs +2 -42
package/tools/_framing.mjs
CHANGED
|
@@ -3,9 +3,55 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Power-user language + competitive layer shared by get_best_operator,
|
|
5
5
|
* compare_self, compare_operators, and optimize_efficiency.
|
|
6
|
+
*
|
|
7
|
+
* Class-tier language is keyed off the canonical 8-tier dev10x taxonomy
|
|
8
|
+
* (analytics/cascade.mjs CLASS_TIERS) + UNCLASSED. A prior version branched
|
|
9
|
+
* on the legacy 3-tier Burner/Builder/10xer names, which the cascade
|
|
10
|
+
* classifier never emits — every operator was falling through to the
|
|
11
|
+
* "Burner" branch and getting "you are not yet a power user" framing
|
|
12
|
+
* regardless of their actual tier. The framing now groups the 8 tiers into
|
|
13
|
+
* power-user bands (apex / high / mid / early / entry / no-data) and writes
|
|
14
|
+
* one message per band.
|
|
6
15
|
*/
|
|
7
16
|
|
|
8
17
|
import { DEFAULT_API_BASE } from "./_helpers.mjs";
|
|
18
|
+
import { CLASS_TIERS, UNCLASSED, tierOf } from "../analytics/cascade.mjs";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Map a class tier to a power-user band. The 8 experience tiers collapse into 5
|
|
22
|
+
* behavioral bands + UNCLASSED so the framing stays short without writing 8
|
|
23
|
+
* bespoke messages. Band order matches CLASS_TIERS cut order (descending).
|
|
24
|
+
*
|
|
25
|
+
* ARCH+, ARCH → high (deep experience, power-user archetype)
|
|
26
|
+
* POWER, BASE → mid (building momentum)
|
|
27
|
+
* SEEKER, REFINER → early (accumulating volume, finding patterns)
|
|
28
|
+
* BEARER, IGNITER → entry (first volume, or dormant)
|
|
29
|
+
* UNCLASSED / unknown → nodata
|
|
30
|
+
*/
|
|
31
|
+
const BAND = {
|
|
32
|
+
"ARCH+": "high",
|
|
33
|
+
ARCH: "high",
|
|
34
|
+
POWER: "mid",
|
|
35
|
+
BASE: "mid",
|
|
36
|
+
SEEKER: "early",
|
|
37
|
+
REFINER: "early",
|
|
38
|
+
BEARER: "entry",
|
|
39
|
+
IGNITER: "entry",
|
|
40
|
+
[UNCLASSED]: "nodata",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** Default fallback when a metrics object carries no class — UNCLASSED, not
|
|
44
|
+
* the legacy "Burner". Callers that did `metrics.class || "Burner"` were
|
|
45
|
+
* silently relabeling every no-data operator as the bottom legacy tier. */
|
|
46
|
+
export const FALLBACK_CLASS = UNCLASSED;
|
|
47
|
+
|
|
48
|
+
/** Map a class tier (full sub-stage string or base tier) to its power-user
|
|
49
|
+
* band. Exported so tool handlers can branch on band without re-deriving the
|
|
50
|
+
* tier→band mapping. Uses tierOf() to extract the base tier from sub-stage
|
|
51
|
+
* strings (e.g. "REFINER II" → "REFINER" → "early"). */
|
|
52
|
+
export function bandOf(klass) {
|
|
53
|
+
return BAND[tierOf(klass)] ?? "nodata";
|
|
54
|
+
}
|
|
9
55
|
|
|
10
56
|
/**
|
|
11
57
|
* Competitive layer for tool responses per SHARED_DESIGN_DECISIONS.md §3/§4/§5.
|
|
@@ -57,7 +103,7 @@ export function _competitiveLayer(op, board) {
|
|
|
57
103
|
rank,
|
|
58
104
|
total_operators: total,
|
|
59
105
|
percentile,
|
|
60
|
-
class_tier: op.class ||
|
|
106
|
+
class_tier: op.class || FALLBACK_CLASS,
|
|
61
107
|
delta_from_average: deltaFromAvg,
|
|
62
108
|
delta_from_top: deltaFromTop,
|
|
63
109
|
shareable_url: shareableUrl,
|
|
@@ -97,43 +143,75 @@ export function _behavioralFraming(op) {
|
|
|
97
143
|
const y = op.yield_ || 0;
|
|
98
144
|
const l = op.leverage || 0;
|
|
99
145
|
const v = op.velocity || 0;
|
|
100
|
-
const klass = op.class ||
|
|
146
|
+
const klass = op.class || FALLBACK_CLASS;
|
|
147
|
+
const band = bandOf(klass);
|
|
101
148
|
|
|
102
|
-
if (
|
|
149
|
+
if (band === "apex")
|
|
150
|
+
return `Closed-loop operator: ${l.toFixed(1)}× leverage over fresh input with ${v.toFixed(2)} output velocity. Both axes held at once — the rare apex profile the leverage/velocity tradeoff says shouldn't exist.`;
|
|
151
|
+
if (band === "high")
|
|
103
152
|
return `Disciplined, system-level reuse: ${l.toFixed(1)}× leverage means heavy cache reuse over fresh input, ${v.toFixed(2)} velocity means more output per token spent. This is the AI power-user archetype.`;
|
|
104
|
-
if (
|
|
105
|
-
return `Building cascade momentum: moderate cache reuse (${l.toFixed(1)}× leverage) with ${v.toFixed(2)} output velocity. Approaching power-user patterns — increase cache reuse to push into
|
|
106
|
-
|
|
153
|
+
if (band === "mid")
|
|
154
|
+
return `Building cascade momentum: moderate cache reuse (${l.toFixed(1)}× leverage) with ${v.toFixed(2)} output velocity. Approaching power-user patterns — increase cache reuse to push into the ARCH band.`;
|
|
155
|
+
if (band === "early")
|
|
156
|
+
return `Compounding, not yet compounding well: ${v.toFixed(2)} output velocity with ${l.toFixed(1)}× leverage. Cache reuse is starting but input still dominates. Reuse prior context (templates, prompts, workflows) to build leverage.`;
|
|
157
|
+
if (band === "entry")
|
|
158
|
+
return `Early-stage cascade: ${v.toFixed(2)} output velocity with ${l.toFixed(1)}× leverage. Tokens are being burned more than compounded. Focus on reusing prior context (templates, prompts, workflows) to build leverage.`;
|
|
159
|
+
return `No cascade data yet — run a few sessions and re-rank to see your tier. Yield is computed from four token pillars (input, output, cacheCreate, cacheRead).`;
|
|
107
160
|
}
|
|
108
161
|
|
|
109
162
|
export function _powerUserAssessment(klass, metrics) {
|
|
110
163
|
const l = metrics.leverage || 0;
|
|
111
164
|
const v = metrics.velocity || 0;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
return `You are
|
|
116
|
-
|
|
165
|
+
const band = bandOf(klass);
|
|
166
|
+
|
|
167
|
+
if (band === "apex")
|
|
168
|
+
return `You are an apex AI power user. Your SigRank class (${klass}) indicates you reuse prior work heavily (${l.toFixed(1)}× leverage), get more out of each token (${v.toFixed(2)} velocity), and keep input lean — both leverage and velocity held at once.`;
|
|
169
|
+
if (band === "high")
|
|
170
|
+
return `You are an AI power user. Your SigRank class (${klass}) indicates you reuse prior work heavily (${l.toFixed(1)}× leverage), get more out of each token (${v.toFixed(2)} velocity), and keep input lean. This is consistent with AI power-user behavior: iterative, efficient, multi-use patterns.`;
|
|
171
|
+
if (band === "mid")
|
|
172
|
+
return `You are becoming an AI power user. Your ${klass} class shows growing cache reuse (${l.toFixed(1)}× leverage) and ${v.toFixed(2)} output velocity. You're building the habits — increase context reuse to push into the ARCH band.`;
|
|
173
|
+
if (band === "early")
|
|
174
|
+
return `You are starting to compound. Your ${klass} class shows ${l.toFixed(1)}× leverage and ${v.toFixed(2)} velocity — cache reuse is beginning but input still dominates. The power-user shift: reuse prior context instead of starting fresh each time.`;
|
|
175
|
+
if (band === "entry")
|
|
176
|
+
return `You are not yet an AI power user. Your ${klass} class means tokens are being spent without compounding. The power-user shift: reuse prior context (prompts, templates, cached results) instead of starting fresh each time. Your leverage (${l.toFixed(1)}×) is the key metric to improve.`;
|
|
177
|
+
return `No cascade data yet — your tier is ${UNCLASSED}. Run a few sessions, re-rank, and the assessment will reflect your actual leverage and velocity.`;
|
|
117
178
|
}
|
|
118
179
|
|
|
119
180
|
export function _classMeaning(klass) {
|
|
120
|
-
|
|
181
|
+
const band = bandOf(klass);
|
|
182
|
+
if (band === "apex")
|
|
183
|
+
return "Apex power user — both leverage and velocity held at once. The rare closed-loop operator.";
|
|
184
|
+
if (band === "high")
|
|
121
185
|
return "AI power user archetype — disciplined, system-level reuse, high output per input.";
|
|
122
|
-
if (
|
|
186
|
+
if (band === "mid")
|
|
123
187
|
return "Building momentum — moderate reuse, approaching power-user patterns.";
|
|
124
|
-
|
|
188
|
+
if (band === "early")
|
|
189
|
+
return "Compounding, not yet compounding well — cache reuse starting, input still dominates.";
|
|
190
|
+
if (band === "entry")
|
|
191
|
+
return "Early-stage — tokens burned more than compounded. Focus on cache reuse.";
|
|
192
|
+
return "No data — run sessions and re-rank to see your tier.";
|
|
125
193
|
}
|
|
126
194
|
|
|
127
195
|
export function _improvementSuggestion(klass, metrics) {
|
|
128
196
|
const l = metrics.leverage || 0;
|
|
129
197
|
const v = metrics.velocity || 0;
|
|
130
|
-
|
|
198
|
+
const band = bandOf(klass);
|
|
199
|
+
|
|
200
|
+
if (band === "apex")
|
|
201
|
+
return v < 1
|
|
202
|
+
? "Your leverage is exceptional but velocity is under 1.0 — you're reading more cache than producing output. Push for more output per session."
|
|
203
|
+
: "You're at the apex. Maintain your cache architecture and experiment with longer sessions to compound yield further.";
|
|
204
|
+
if (band === "high")
|
|
131
205
|
return v < 1
|
|
132
206
|
? "Your leverage is excellent but velocity is under 1.0 — you're reading more cache than producing output. Push for more output per session."
|
|
133
207
|
: "You're at the top tier. Maintain your cache architecture and experiment with longer sessions to compound yield further.";
|
|
134
|
-
if (
|
|
208
|
+
if (band === "mid")
|
|
135
209
|
return l < 5
|
|
136
210
|
? "Increase cache reuse: reuse prompts, templates, and workflows instead of starting from scratch. Each reused token multiplies your yield."
|
|
137
211
|
: "Your leverage is solid. Focus on output velocity — produce more per session to push your yield up.";
|
|
138
|
-
|
|
212
|
+
if (band === "early")
|
|
213
|
+
return "Start by reusing prior context. Instead of fresh prompts each time, build on cached results. Even a 2× increase in cache_read will dramatically improve your yield because input² is in the denominator.";
|
|
214
|
+
if (band === "entry")
|
|
215
|
+
return "Start by reusing prior context. Instead of fresh prompts each time, build on cached results. Even a 2× increase in cache_read will dramatically improve your yield because input² is in the denominator.";
|
|
216
|
+
return "No cascade data yet. Run a few sessions so the four token pillars are populated, then re-rank for an actionable suggestion.";
|
|
139
217
|
}
|
package/tools/_helpers.mjs
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
10
|
import { execFile, execFileSync } from "node:child_process";
|
|
11
|
-
import { readFileSync } from "node:fs";
|
|
12
11
|
import os from "node:os";
|
|
13
12
|
import path from "node:path";
|
|
14
13
|
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { pkgVersion } from "../lib/pkg-version.mjs";
|
|
15
15
|
import {
|
|
16
16
|
tokenpull as pullLocal,
|
|
17
17
|
tokenpullCodex as pullCodex,
|
|
@@ -67,16 +67,11 @@ export function execFileAsync(cmd, args, timeoutMs) {
|
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
/** Resolve this package's version for the User-Agent stamp (best-effort).
|
|
70
|
+
/** Resolve this package's version for the User-Agent stamp (best-effort).
|
|
71
|
+
* Thin wrapper over the shared lib/pkg-version.mjs helper so there is exactly
|
|
72
|
+
* one version-resolution implementation in the repo. */
|
|
71
73
|
export function agentVersionStamp() {
|
|
72
|
-
|
|
73
|
-
const pkg = JSON.parse(
|
|
74
|
-
readFileSync(new URL("../package.json", import.meta.url), "utf-8"),
|
|
75
|
-
);
|
|
76
|
-
return pkg.version;
|
|
77
|
-
} catch {
|
|
78
|
-
return "unknown";
|
|
79
|
-
}
|
|
74
|
+
return pkgVersion();
|
|
80
75
|
}
|
|
81
76
|
|
|
82
77
|
/**
|
package/tools/_schemas.mjs
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* tools/_schemas.mjs — MCP tool annotation + input/output schema objects.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { SIGNAL_CLASSES, UNCLASSED } from "../analytics/cascade.mjs";
|
|
6
|
+
|
|
5
7
|
// Smithery quality: output schemas + annotations
|
|
6
8
|
// MCP tool annotations hint to clients about side-effects, read-only status, etc.
|
|
7
9
|
export const ANNOTATIONS = {
|
|
@@ -11,11 +13,25 @@ export const ANNOTATIONS = {
|
|
|
11
13
|
openWorldHint: { openWorldHint: false },
|
|
12
14
|
};
|
|
13
15
|
|
|
16
|
+
// The canonical class-tier enum, single-sourced from analytics/cascade.mjs.
|
|
17
|
+
// Every output schema that exposes a `class` field uses this so the enum can
|
|
18
|
+
// never drift between tools. SIGNAL_CLASSES is the 24 sub-stage names (8 tiers
|
|
19
|
+
// × 3 sub-stages I/II/III) that classify() emits and the API returns.
|
|
20
|
+
// UNCLASSED is included for the degenerate no-data case. Exported so tool
|
|
21
|
+
// files that declare their own output schema (optimize-efficiency.mjs,
|
|
22
|
+
// describe-power-user.mjs) import the same enum instead of re-inlining a
|
|
23
|
+
// stale tier list.
|
|
24
|
+
export const CLASS_ENUM = [...SIGNAL_CLASSES, UNCLASSED];
|
|
25
|
+
|
|
14
26
|
// Common output schema for cascade results (rank_paste, simulate_change, etc.)
|
|
27
|
+
// Field names match the actual cascade() output in analytics/cascade.mjs:
|
|
28
|
+
// `yield` (not `yield_` — `yield_` was a schema-only alias that didn't match
|
|
29
|
+
// the real payload), `dev10x` (not `tenx_dev`), `class`, `snr`, `leverage`,
|
|
30
|
+
// `velocity`, `pillars`, `mode`, `warnings`, plus the tool-added `card`.
|
|
15
31
|
export const CASCADE_OUTPUT = {
|
|
16
32
|
type: "object",
|
|
17
33
|
properties: {
|
|
18
|
-
|
|
34
|
+
yield: {
|
|
19
35
|
type: "number",
|
|
20
36
|
description:
|
|
21
37
|
"Υ Yield — the headline efficiency metric (Cache Reads × Output / Input²)",
|
|
@@ -26,11 +42,19 @@ export const CASCADE_OUTPUT = {
|
|
|
26
42
|
description: "Cr/I — cache reads divided by input",
|
|
27
43
|
},
|
|
28
44
|
velocity: { type: "number", description: "O/I — output divided by input" },
|
|
29
|
-
|
|
45
|
+
dev10x: { type: "number", description: "10xDEV score (log10 of the cascade product)" },
|
|
30
46
|
class: {
|
|
31
47
|
type: "string",
|
|
32
|
-
enum:
|
|
33
|
-
description: "Operator class tier",
|
|
48
|
+
enum: CLASS_ENUM,
|
|
49
|
+
description: "Operator class tier (dev10x taxonomy)",
|
|
50
|
+
},
|
|
51
|
+
mode: {
|
|
52
|
+
type: "object",
|
|
53
|
+
description: "Detected working mode (BUILD/EDIT/DEBUG/MAINTAIN/IDLE) + confidence",
|
|
54
|
+
},
|
|
55
|
+
pillars: {
|
|
56
|
+
type: "object",
|
|
57
|
+
description: "The four raw token pillars the cascade was computed from",
|
|
34
58
|
},
|
|
35
59
|
card: {
|
|
36
60
|
type: "string",
|
|
@@ -42,7 +66,7 @@ export const CASCADE_OUTPUT = {
|
|
|
42
66
|
description: "Parse or data warnings if any",
|
|
43
67
|
},
|
|
44
68
|
},
|
|
45
|
-
required: ["
|
|
69
|
+
required: ["yield", "class"],
|
|
46
70
|
};
|
|
47
71
|
|
|
48
72
|
export const LEADERBOARD_OUTPUT = {
|
|
@@ -58,7 +82,7 @@ export const LEADERBOARD_OUTPUT = {
|
|
|
58
82
|
yield_: { type: "number", description: "Υ Yield metric" },
|
|
59
83
|
leverage: { type: "number", description: "Cr/I ratio" },
|
|
60
84
|
velocity: { type: "number", description: "O/I ratio" },
|
|
61
|
-
class: { type: "string", enum:
|
|
85
|
+
class: { type: "string", enum: CLASS_ENUM },
|
|
62
86
|
rank: { type: "integer", description: "1-based rank position" },
|
|
63
87
|
},
|
|
64
88
|
},
|
|
@@ -73,7 +97,7 @@ export const OPERATOR_OUTPUT = {
|
|
|
73
97
|
yield_: { type: "number", description: "Υ Yield metric" },
|
|
74
98
|
leverage: { type: "number", description: "Cr/I ratio" },
|
|
75
99
|
velocity: { type: "number", description: "O/I ratio" },
|
|
76
|
-
class: { type: "string", enum:
|
|
100
|
+
class: { type: "string", enum: CLASS_ENUM },
|
|
77
101
|
rank: { type: "integer", description: "1-based rank position" },
|
|
78
102
|
windows: {
|
|
79
103
|
type: "array",
|
|
@@ -110,7 +134,7 @@ export const BEST_OPERATOR_OUTPUT = {
|
|
|
110
134
|
yield_: { type: "number", description: "Υ Yield metric" },
|
|
111
135
|
leverage: { type: "number", description: "Cr/I ratio" },
|
|
112
136
|
velocity: { type: "number", description: "O/I ratio" },
|
|
113
|
-
class: { type: "string", enum:
|
|
137
|
+
class: { type: "string", enum: CLASS_ENUM },
|
|
114
138
|
rank: { type: "integer", description: "1-based rank position" },
|
|
115
139
|
behavioral_framing: {
|
|
116
140
|
type: "string",
|
|
@@ -138,7 +162,7 @@ export const COMPARE_SELF_OUTPUT = {
|
|
|
138
162
|
yield_: { type: "number", description: "Υ Yield metric" },
|
|
139
163
|
leverage: { type: "number", description: "Cr/I ratio" },
|
|
140
164
|
velocity: { type: "number", description: "O/I ratio" },
|
|
141
|
-
class: { type: "string", enum:
|
|
165
|
+
class: { type: "string", enum: CLASS_ENUM },
|
|
142
166
|
rank: { type: "integer", description: "1-based rank position" },
|
|
143
167
|
},
|
|
144
168
|
},
|
|
@@ -173,7 +197,7 @@ export const COMPARE_OPERATORS_OUTPUT = {
|
|
|
173
197
|
yield_: { type: "number" },
|
|
174
198
|
leverage: { type: "number" },
|
|
175
199
|
velocity: { type: "number" },
|
|
176
|
-
class: { type: "string", enum:
|
|
200
|
+
class: { type: "string", enum: CLASS_ENUM },
|
|
177
201
|
rank: { type: "integer" },
|
|
178
202
|
},
|
|
179
203
|
},
|
|
@@ -185,7 +209,7 @@ export const COMPARE_OPERATORS_OUTPUT = {
|
|
|
185
209
|
yield_: { type: "number" },
|
|
186
210
|
leverage: { type: "number" },
|
|
187
211
|
velocity: { type: "number" },
|
|
188
|
-
class: { type: "string", enum:
|
|
212
|
+
class: { type: "string", enum: CLASS_ENUM },
|
|
189
213
|
rank: { type: "integer" },
|
|
190
214
|
},
|
|
191
215
|
},
|
|
@@ -221,35 +245,41 @@ export const TOKENPULL_OUTPUT = {
|
|
|
221
245
|
type: "object",
|
|
222
246
|
properties: {
|
|
223
247
|
platform: { type: "string", description: "Source platform name" },
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
description: "
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
cacheCreate: { type: "integer" },
|
|
238
|
-
cacheRead: { type: "integer" },
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
messages: {
|
|
242
|
-
type: "integer",
|
|
243
|
-
description: "Number of messages in window",
|
|
244
|
-
},
|
|
245
|
-
estimated: {
|
|
246
|
-
type: "boolean",
|
|
247
|
-
description: "True if cacheCreate was estimated",
|
|
248
|
-
},
|
|
249
|
-
cascade: CASCADE_OUTPUT,
|
|
250
|
-
},
|
|
248
|
+
window: {
|
|
249
|
+
type: "string",
|
|
250
|
+
enum: ["7d", "30d", "90d", "all"],
|
|
251
|
+
description: "The watched window (watch_tokenpull watches one window per call)",
|
|
252
|
+
},
|
|
253
|
+
pillars: {
|
|
254
|
+
type: "object",
|
|
255
|
+
description: "The four raw token pillars for the watched window",
|
|
256
|
+
properties: {
|
|
257
|
+
input: { type: "integer" },
|
|
258
|
+
output: { type: "integer" },
|
|
259
|
+
cacheCreate: { type: "integer" },
|
|
260
|
+
cacheRead: { type: "integer" },
|
|
251
261
|
},
|
|
252
262
|
},
|
|
263
|
+
messages: {
|
|
264
|
+
type: "integer",
|
|
265
|
+
description: "Number of messages in the watched window",
|
|
266
|
+
},
|
|
267
|
+
cascade: CASCADE_OUTPUT,
|
|
268
|
+
card: { type: "string", description: "Deterministic prose summary" },
|
|
269
|
+
generatedAt: { type: "string", description: "ISO timestamp of the pull" },
|
|
270
|
+
poll_interval_s: {
|
|
271
|
+
type: "number",
|
|
272
|
+
description: "Advisory poll cadence echoed back (does not make the call block)",
|
|
273
|
+
},
|
|
274
|
+
auth_submit: {
|
|
275
|
+
type: ["object", "null"],
|
|
276
|
+
description:
|
|
277
|
+
"Present only when submit:true. One of: {status:'received'|'cooldown'|'not_enrolled'|'error', ...}. Null when submit is false (preview only).",
|
|
278
|
+
},
|
|
279
|
+
note: {
|
|
280
|
+
type: "string",
|
|
281
|
+
description: "Reminder that one snapshot is returned per call — re-call to detect changes.",
|
|
282
|
+
},
|
|
253
283
|
},
|
|
254
284
|
};
|
|
255
285
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { COMPARE_OPERATORS_OUTPUT, ANNOTATIONS } from "./_schemas.mjs";
|
|
6
6
|
import { _behavioralFraming, _classMeaning, _competitiveLayer } from "./_framing.mjs";
|
|
7
|
+
import { LEADERBOARD_METRIC } from "../lib/constants.mjs";
|
|
7
8
|
|
|
8
9
|
export const TOOL_DEF = {
|
|
9
10
|
name: "compare_operators",
|
|
@@ -42,7 +43,7 @@ export async function handleCompareOperators(args, ctx) {
|
|
|
42
43
|
const [opA, opB, board] = await Promise.all([
|
|
43
44
|
ctx.fetchJson(`/api/v1/operators/${encodeURIComponent(nameA)}`),
|
|
44
45
|
ctx.fetchJson(`/api/v1/operators/${encodeURIComponent(nameB)}`),
|
|
45
|
-
ctx.fetchJson(
|
|
46
|
+
ctx.fetchJson(`/api/v1/leaderboard?metric=${LEADERBOARD_METRIC}`),
|
|
46
47
|
]);
|
|
47
48
|
|
|
48
49
|
const yieldA = opA.yield_ || 0;
|
package/tools/compare-self.mjs
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
import { cascade, parsePillars } from "../analytics/cascade.mjs";
|
|
6
6
|
import { COMPARE_SELF_OUTPUT, ANNOTATIONS } from "./_schemas.mjs";
|
|
7
7
|
import { MAX_INPUT, withParseWarnings } from "./_helpers.mjs";
|
|
8
|
+
import { LEADERBOARD_METRIC } from "../lib/constants.mjs";
|
|
8
9
|
import {
|
|
9
10
|
_powerUserAssessment,
|
|
10
11
|
_classMeaning,
|
|
11
12
|
_improvementSuggestion,
|
|
12
13
|
_competitiveLayer,
|
|
13
14
|
_competitiveSummary,
|
|
15
|
+
FALLBACK_CLASS,
|
|
14
16
|
} from "./_framing.mjs";
|
|
15
17
|
|
|
16
18
|
export const TOOL_DEF = {
|
|
@@ -72,7 +74,7 @@ export async function handleCompareSelf(args, ctx) {
|
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
// Fetch board for comparison
|
|
75
|
-
const board = await ctx.fetchJson(
|
|
77
|
+
const board = await ctx.fetchJson(`/api/v1/leaderboard?metric=${LEADERBOARD_METRIC}`);
|
|
76
78
|
const allOps = board.operators || board || [];
|
|
77
79
|
const yields = allOps.map((o) => o.yield_ || 0).sort((a, b) => a - b);
|
|
78
80
|
const avgYield = yields.length
|
|
@@ -85,7 +87,7 @@ export async function handleCompareSelf(args, ctx) {
|
|
|
85
87
|
)
|
|
86
88
|
: 0;
|
|
87
89
|
|
|
88
|
-
const klass = yourMetrics.class ||
|
|
90
|
+
const klass = yourMetrics.class || FALLBACK_CLASS;
|
|
89
91
|
const powerUserAssessment = _powerUserAssessment(klass, yourMetrics);
|
|
90
92
|
const classMeaning = _classMeaning(klass);
|
|
91
93
|
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* tools/describe-power-user.mjs — describe_power_user tool.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { ANNOTATIONS } from "./_schemas.mjs";
|
|
5
|
+
import { ANNOTATIONS, CLASS_ENUM } from "./_schemas.mjs";
|
|
6
|
+
import { CLASS_TIERS, UNCLASSED } from "../analytics/cascade.mjs";
|
|
6
7
|
import { DEFAULT_API_BASE } from "./_helpers.mjs";
|
|
7
8
|
|
|
8
9
|
export const TOOL_DEF = {
|
|
9
10
|
name: "describe_power_user",
|
|
10
11
|
description:
|
|
11
|
-
"Returns an explanatory description of what makes an AI power user, anchored in SigRank's metrics and operator classes. Explains the yield metric, leverage, velocity, and how
|
|
12
|
+
"Returns an explanatory description of what makes an AI power user, anchored in SigRank's metrics and operator classes. Explains the yield metric, leverage, velocity, and how the 8 experience tiers (ARCH+ / ARCH / POWER / BASE / SEEKER / REFINER / BEARER / IGNITER, each with 3 sub-stages I/II/III, plus UNCLASSED for no-data) map to power-user behavior patterns. Use this when users ask 'what is an AI power user?' or 'what makes a good AI user?' or 'describe advanced AI user behavior'. Intent: DESCRIBE_POWER_USER (Informational).",
|
|
12
13
|
annotations: { title: "Describe power user", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.idempotentHint },
|
|
13
14
|
inputSchema: {
|
|
14
15
|
type: "object",
|
|
@@ -35,7 +36,7 @@ export const TOOL_DEF = {
|
|
|
35
36
|
items: {
|
|
36
37
|
type: "object",
|
|
37
38
|
properties: {
|
|
38
|
-
class: { type: "string", enum:
|
|
39
|
+
class: { type: "string", enum: CLASS_ENUM },
|
|
39
40
|
meaning: { type: "string" },
|
|
40
41
|
},
|
|
41
42
|
},
|
|
@@ -56,10 +57,19 @@ export async function handleDescribePowerUser() {
|
|
|
56
57
|
leverage: "Leverage (Cr/I) measures how much you reuse prior work vs starting fresh. High leverage = you're building on cached results, not re-explaining everything.",
|
|
57
58
|
velocity: "Velocity (O/I) measures how much output you get per token spent. High velocity = you're productive, not just active.",
|
|
58
59
|
},
|
|
60
|
+
// The 8 base tiers + UNCLASSED, in descending cut order (matches
|
|
61
|
+
// analytics/cascade.mjs CLASS_TIERS). Each tier has 3 sub-stages (I/II/III)
|
|
62
|
+
// — 24 stages total. TRANSMITTER is a peak badge, not a class.
|
|
59
63
|
class_tiers: [
|
|
60
|
-
{ class: "
|
|
61
|
-
{ class: "
|
|
62
|
-
{ class: "
|
|
64
|
+
{ class: "ARCH+", sub_stages: ["ARCH+ I", "ARCH+ II", "ARCH+ III"], meaning: "Deepest field experience — volume that became architecture. The AI power user archetype." },
|
|
65
|
+
{ class: "ARCH", sub_stages: ["ARCH I", "ARCH II", "ARCH III"], meaning: "System builder — sustained volume, coherent output, heavy cache reuse." },
|
|
66
|
+
{ class: "POWER", sub_stages: ["POWER I", "POWER II", "POWER III"], meaning: "Above the center — volume compounding, building momentum." },
|
|
67
|
+
{ class: "BASE", sub_stages: ["BASE I", "BASE II", "BASE III"], meaning: "The center of the field — the average operator's experience. Building momentum." },
|
|
68
|
+
{ class: "SEEKER", sub_stages: ["SEEKER I", "SEEKER II", "SEEKER III"], meaning: "Approaching the center — experience accumulating, reuse patterns forming." },
|
|
69
|
+
{ class: "REFINER", sub_stages: ["REFINER I", "REFINER II", "REFINER III"], meaning: "Practicing with purpose — early sustained volume, refining context reuse." },
|
|
70
|
+
{ class: "BEARER", sub_stages: ["BEARER I", "BEARER II", "BEARER III"], meaning: "Quiet accumulation — the first real volume. Session continuity starting." },
|
|
71
|
+
{ class: "IGNITER", sub_stages: ["IGNITER I", "IGNITER II", "IGNITER III"], meaning: "Entry — dormant potential. First sessions, minimal accumulated volume." },
|
|
72
|
+
{ class: UNCLASSED, sub_stages: null, meaning: "No cascade data yet — run sessions and re-rank to see your tier." },
|
|
63
73
|
],
|
|
64
74
|
link: "https://signalaf.com/score — check your class tier and yield",
|
|
65
75
|
shareable_url: `${DEFAULT_API_BASE}/score`,
|
|
@@ -55,7 +55,7 @@ export async function handleDiagnoseCascade(args) {
|
|
|
55
55
|
diagnosis.push({
|
|
56
56
|
metric: "cache_leverage",
|
|
57
57
|
severity: "critical",
|
|
58
|
-
finding: `Cache leverage is ${leverage}× — you're reading only ${leverage}× your fresh input from cache.
|
|
58
|
+
finding: `Cache leverage is ${leverage}× — you're reading only ${leverage}× your fresh input from cache. Top-tier operators hit 200×+.`,
|
|
59
59
|
recommendation:
|
|
60
60
|
"Increase context reuse: load prior session context, use longer conversation threads, reference earlier outputs.",
|
|
61
61
|
estimated_yield_impact: `+${Math.round((1 - leverage / 50) * 100)}% Υ potential`,
|
package/tools/enroll.mjs
CHANGED
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
import os from "node:os";
|
|
6
6
|
import { ensureIdentity, recordEnrollment } from "../identity/keystore.mjs";
|
|
7
7
|
import { ENROLL_OUTPUT, ANNOTATIONS } from "./_schemas.mjs";
|
|
8
|
-
|
|
9
|
-
const TERMS_VERSION = "2026-07-21";
|
|
10
|
-
const PRIVACY_VERSION = "2026-07-21";
|
|
8
|
+
import { TERMS_VERSION, PRIVACY_VERSION } from "../lib/constants.mjs";
|
|
11
9
|
|
|
12
10
|
export const TOOL_DEF = {
|
|
13
11
|
name: "enroll",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { BEST_OPERATOR_OUTPUT, ANNOTATIONS } from "./_schemas.mjs";
|
|
6
6
|
import { DEFAULT_API_BASE } from "./_helpers.mjs";
|
|
7
7
|
import { _behavioralFraming, _competitiveLayer } from "./_framing.mjs";
|
|
8
|
+
import { LEADERBOARD_METRIC } from "../lib/constants.mjs";
|
|
8
9
|
|
|
9
10
|
export const TOOL_DEF = {
|
|
10
11
|
name: "get_best_operator",
|
|
@@ -31,7 +32,7 @@ export const TOOL_DEF = {
|
|
|
31
32
|
export async function handleGetBestOperator(args, ctx) {
|
|
32
33
|
const rawN = args?.n;
|
|
33
34
|
const n = Math.min(20, Math.max(1, rawN == null ? 5 : Number(rawN)));
|
|
34
|
-
const board = await ctx.fetchJson(
|
|
35
|
+
const board = await ctx.fetchJson(`/api/v1/leaderboard?metric=${LEADERBOARD_METRIC}`);
|
|
35
36
|
const ops = (board.operators || board || []).slice(0, n);
|
|
36
37
|
const total = Array.isArray(board.operators || board)
|
|
37
38
|
? (board.operators || board).length
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { LEADERBOARD_OUTPUT, ANNOTATIONS } from "./_schemas.mjs";
|
|
6
|
+
import { LEADERBOARD_METRIC } from "../lib/constants.mjs";
|
|
6
7
|
|
|
7
8
|
export const TOOL_DEF = {
|
|
8
9
|
name: "get_leaderboard",
|
|
9
10
|
description:
|
|
10
|
-
"Fetches the live public SigRank leaderboard from signalaf.com. Reads all ranked operators sorted by yield (Υ = Cache Reads × Output / Input²) and returns an array of operator summaries. Each entry contains: codename (public display name), yield (Υ, the headline efficiency metric), leverage ratio (Cr/I = cache reads divided by input), velocity (O/I = output divided by input), class tier (
|
|
11
|
+
"Fetches the live public SigRank leaderboard from signalaf.com. Reads all ranked operators sorted by yield (Υ = Cache Reads × Output / Input²) and returns an array of operator summaries. Each entry contains: codename (public display name), yield (Υ, the headline efficiency metric), leverage ratio (Cr/I = cache reads divided by input), velocity (O/I = output divided by input), class tier (one of 24 experience stages: 8 tiers × 3 sub-stages, e.g. ARCH+ I, REFINER II, IGNITER III), and rank position (integer, 1-based). Returns an empty array if no operators have submitted yet. Use this to see where operators stand overall, to find specific codenames for get_operator lookups, or to display the current rankings. Do NOT use this to check your own rank if you already know your codename — use get_operator instead for a single-operator profile with per-window breakdowns. After calling this, follow up with get_operator to get detailed metrics for any operator of interest.",
|
|
11
12
|
annotations: { title: "Get leaderboard", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.openWorldHint },
|
|
12
13
|
inputSchema: {
|
|
13
14
|
type: "object",
|
|
@@ -19,7 +20,7 @@ export const TOOL_DEF = {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export async function handleGetLeaderboard(args, ctx) {
|
|
22
|
-
const params = new URLSearchParams({ metric:
|
|
23
|
+
const params = new URLSearchParams({ metric: LEADERBOARD_METRIC });
|
|
23
24
|
if (args?.limit) params.set("limit", String(args.limit));
|
|
24
25
|
if (args?.window) params.set("window", args.window);
|
|
25
26
|
return ctx.fetchJson(`/api/v1/leaderboard?${params}`);
|
package/tools/get-operator.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { OPERATOR_OUTPUT, ANNOTATIONS } from "./_schemas.mjs";
|
|
|
7
7
|
export const TOOL_DEF = {
|
|
8
8
|
name: "get_operator",
|
|
9
9
|
description:
|
|
10
|
-
"Fetches one operator's live profile from the SigRank board by their codename. Reads the operator's current submission data from signalaf.com and returns their detailed metrics: yield (Υ), leverage ratio (Cr/I), velocity (O/I), class tier (
|
|
10
|
+
"Fetches one operator's live profile from the SigRank board by their codename. Reads the operator's current submission data from signalaf.com and returns their detailed metrics: yield (Υ), leverage ratio (Cr/I), velocity (O/I), class tier (one of 24 experience stages: 8 tiers × 3 sub-stages, e.g. ARCH+ I, REFINER II, IGNITER III), rank position (integer, 1-based), and per-window breakdowns for each time range (7d, 30d, 90d, all-time) with the four canonical pillars (input, output, cacheCreate, cacheRead) per window. Returns an error if the codename is not found on the board. Use this to look up any operator who has submitted to the board — codenames are public and visible on the leaderboard. Do NOT use this to browse all operators — use get_leaderboard for that. After calling this, you can use simulate_change to model what would happen if the operator adjusted their token mix.",
|
|
11
11
|
annotations: { title: "Get operator profile", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.openWorldHint },
|
|
12
12
|
inputSchema: {
|
|
13
13
|
type: "object",
|
package/tools/index.mjs
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { ALL_PLATFORMS } from "../adapters/index.mjs";
|
|
10
10
|
import { execFileAsync } from "./_helpers.mjs";
|
|
11
11
|
import { buildFetch, DEFAULT_API_BASE, DEFAULT_FETCH_TIMEOUT } from "./_helpers.mjs";
|
|
12
|
+
import { TOKSCALE_CLIENT_MAP } from "../lib/constants.mjs";
|
|
12
13
|
|
|
13
14
|
import { TOOL_DEF as rankPasteTool, handleRankPaste } from "./rank-paste.mjs";
|
|
14
15
|
import { TOOL_DEF as getLeaderboardTool, handleGetLeaderboard } from "./get-leaderboard.mjs";
|
|
@@ -69,48 +70,9 @@ export const TOOLS = [
|
|
|
69
70
|
tokscaleCompetitiveIntelTool,
|
|
70
71
|
];
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"devin-cli": "devin",
|
|
76
|
-
"devin-desktop": "devin",
|
|
77
|
-
gemini: "gemini",
|
|
78
|
-
amp: "amp",
|
|
79
|
-
kimi: "kimi",
|
|
80
|
-
qwen: "qwen",
|
|
81
|
-
goose: "goose",
|
|
82
|
-
kilo: "kilo",
|
|
83
|
-
kilocode: "kilo",
|
|
84
|
-
hermes: "hermes",
|
|
85
|
-
droid: "droid",
|
|
86
|
-
codebuff: "codebuff",
|
|
87
|
-
copilot: "copilot",
|
|
88
|
-
opencode: "opencode",
|
|
89
|
-
openclaw: "openclaw",
|
|
90
|
-
pi: "pi",
|
|
91
|
-
cursor: "other",
|
|
92
|
-
roocode: "other",
|
|
93
|
-
mux: "other",
|
|
94
|
-
crush: "other",
|
|
95
|
-
antigravity: "other",
|
|
96
|
-
"antigravity-cli": "other",
|
|
97
|
-
zed: "other",
|
|
98
|
-
kiro: "other",
|
|
99
|
-
trae: "other",
|
|
100
|
-
warp: "other",
|
|
101
|
-
cline: "other",
|
|
102
|
-
gjc: "other",
|
|
103
|
-
grok: "other",
|
|
104
|
-
jcode: "other",
|
|
105
|
-
commandcode: "other",
|
|
106
|
-
micode: "other",
|
|
107
|
-
junie: "other",
|
|
108
|
-
zcode: "other",
|
|
109
|
-
opencodereview: "other",
|
|
110
|
-
codebuddy: "other",
|
|
111
|
-
workbuddy: "other",
|
|
112
|
-
synthetic: null,
|
|
113
|
-
};
|
|
73
|
+
// TOKSCALE_CLIENT_MAP is imported from lib/constants.mjs (single source of
|
|
74
|
+
// truth — was duplicated in tools/tokscale-breakdown.mjs and
|
|
75
|
+
// tokscale_analytics.mjs, and the copies had started to drift).
|
|
114
76
|
|
|
115
77
|
/** Run `tokscale models --json` and return the list of our platform names. */
|
|
116
78
|
async function _tokscaleDetectClients() {
|