sigrank 0.17.1 → 0.17.2

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 CHANGED
@@ -25,6 +25,10 @@ For all builders, burners and 10xers.
25
25
 
26
26
  </div>
27
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
+
28
32
  ## Table of Contents
29
33
 
30
34
  - [The SigRank ecosystem](#the-sigrank-ecosystem)
@@ -242,7 +246,7 @@ Or if installed globally:
242
246
  }
243
247
  ```
244
248
 
245
- ### MCP Tools
249
+ ## Tools
246
250
 
247
251
  | Tool | Args | What |
248
252
  | ------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -261,6 +265,11 @@ Or if installed globally:
261
265
  | `simulate_change` | `{text?, changes}` | Prescriptive "what if" — test proposed pillar changes and see the exact Υ delta + class change before committing |
262
266
  | `suggest_improvements` | `{text?}` | Generates ranked, simulated improvement suggestions — tests strategies and returns them sorted by Υ yield impact |
263
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?" |
264
273
 
265
274
  ---
266
275
 
package/index.mjs CHANGED
@@ -69,7 +69,7 @@ process.on("unhandledRejection", (reason) => {
69
69
  async function startMcpServer() {
70
70
  const server = new Server(
71
71
  { name: "sigrank", version: serverVersion() },
72
- { capabilities: { tools: { listChanged: false } } },
72
+ { capabilities: { tools: { listChanged: false }, prompts: { listChanged: false }, resources: { listChanged: false } } },
73
73
  );
74
74
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
75
75
  tools: TOOLS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigrank",
3
- "version": "0.17.1",
3
+ "version": "0.17.2",
4
4
  "author": "SunrisesIllNeverSee (https://github.com/SunrisesIllNeverSee)",
5
5
  "description": "SigRank MCP server — the yield cascade + live leaderboard as MCP tools any agent can call",
6
6
  "mcpName": "io.github.SunrisesIllNeverSee/sigrank-mcp",
package/tools.mjs CHANGED
@@ -351,6 +351,106 @@ const OPERATOR_OUTPUT = {
351
351
  },
352
352
  };
353
353
 
354
+ const BEST_OPERATOR_OUTPUT = {
355
+ type: "object",
356
+ properties: {
357
+ top_operators: {
358
+ type: "array",
359
+ description: "Top N operators ranked by yield",
360
+ items: {
361
+ type: "object",
362
+ properties: {
363
+ codename: { type: "string", description: "Public display name" },
364
+ yield_: { type: "number", description: "Υ Yield metric" },
365
+ leverage: { type: "number", description: "Cr/I ratio" },
366
+ velocity: { type: "number", description: "O/I ratio" },
367
+ class: { type: "string", enum: ["Burner", "Builder", "10xer"] },
368
+ rank: { type: "integer", description: "1-based rank position" },
369
+ behavioral_framing: {
370
+ type: "string",
371
+ description: "Plain-language interpretation of the operator's cascade in power-user terms",
372
+ },
373
+ },
374
+ },
375
+ },
376
+ total_operators: { type: "integer", description: "Total operators on the board" },
377
+ summary: {
378
+ type: "string",
379
+ description: "One-line summary of the top operator's achievement in behavioral terms",
380
+ },
381
+ },
382
+ };
383
+
384
+ const COMPARE_SELF_OUTPUT = {
385
+ type: "object",
386
+ properties: {
387
+ your_metrics: {
388
+ type: "object",
389
+ description: "Your cascade metrics",
390
+ properties: {
391
+ codename: { type: "string" },
392
+ yield_: { type: "number", description: "Υ Yield metric" },
393
+ leverage: { type: "number", description: "Cr/I ratio" },
394
+ velocity: { type: "number", description: "O/I ratio" },
395
+ class: { type: "string", enum: ["Burner", "Builder", "10xer"] },
396
+ rank: { type: "integer", description: "1-based rank position" },
397
+ },
398
+ },
399
+ power_user_assessment: {
400
+ type: "string",
401
+ description: "Behavioral interpretation: are you an AI power user? Maps class tier to power-user language.",
402
+ },
403
+ comparison: {
404
+ type: "object",
405
+ description: "How you compare to board averages and archetypes",
406
+ properties: {
407
+ your_yield_vs_avg: { type: "string", description: "Your yield vs board average" },
408
+ your_class_meaning: { type: "string", description: "What your class tier means in power-user terms" },
409
+ percentile: { type: "number", description: "Your percentile rank (0-100)" },
410
+ },
411
+ },
412
+ suggestion: {
413
+ type: "string",
414
+ description: "One actionable suggestion to improve your cascade efficiency",
415
+ },
416
+ },
417
+ };
418
+
419
+ const COMPARE_OPERATORS_OUTPUT = {
420
+ type: "object",
421
+ properties: {
422
+ operator_a: {
423
+ type: "object",
424
+ description: "First operator's metrics",
425
+ properties: {
426
+ codename: { type: "string" },
427
+ yield_: { type: "number" },
428
+ leverage: { type: "number" },
429
+ velocity: { type: "number" },
430
+ class: { type: "string", enum: ["Burner", "Builder", "10xer"] },
431
+ rank: { type: "integer" },
432
+ },
433
+ },
434
+ operator_b: {
435
+ type: "object",
436
+ description: "Second operator's metrics",
437
+ properties: {
438
+ codename: { type: "string" },
439
+ yield_: { type: "number" },
440
+ leverage: { type: "number" },
441
+ velocity: { type: "number" },
442
+ class: { type: "string", enum: ["Burner", "Builder", "10xer"] },
443
+ rank: { type: "integer" },
444
+ },
445
+ },
446
+ verdict: {
447
+ type: "string",
448
+ description: "Who is more efficient and why, in behavioral terms",
449
+ },
450
+ yield_delta: { type: "number", description: "Yield difference (A - B)" },
451
+ },
452
+ };
453
+
354
454
  const SUBMIT_OUTPUT = {
355
455
  type: "object",
356
456
  properties: {
@@ -1052,6 +1152,166 @@ export const TOOLS = [
1052
1152
  },
1053
1153
  },
1054
1154
  },
1155
+ {
1156
+ name: "get_best_operator",
1157
+ description:
1158
+ "Returns the top N operators on the SigRank leaderboard with behavioral framing in power-user language. Wraps get_leaderboard and adds plain-language interpretation of each top operator's cascade: what their yield, leverage, and velocity mean in terms of AI power-user behavior (cache reuse, input economy, output productivity). Use this when users ask 'who is the best AI user?' or 'who tops the SigRank leaderboard?' or 'show me the AI user leaderboard'. Do NOT use get_leaderboard if you want the raw array without interpretation — use this for the power-user framing. Intent: BEST_OPERATOR.",
1159
+ annotations: { title: "Get best operator", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.openWorldHint },
1160
+ inputSchema: {
1161
+ type: "object",
1162
+ properties: {
1163
+ n: {
1164
+ type: "integer",
1165
+ description:
1166
+ "Number of top operators to return (default: 5, max: 20). Returns the top N by yield.",
1167
+ minimum: 1,
1168
+ maximum: 20,
1169
+ },
1170
+ },
1171
+ description:
1172
+ "Optional: how many top operators to return. Defaults to 5.",
1173
+ },
1174
+ outputSchema: BEST_OPERATOR_OUTPUT,
1175
+ },
1176
+ {
1177
+ name: "compare_self",
1178
+ description:
1179
+ "Compares an operator's metrics against board averages and power-user archetypes, returning a behavioral assessment. Accepts either a codename (fetches from the board) or raw token pillars (computes locally). Returns: your yield/leverage/velocity/class/rank, a power-user assessment mapping your class tier to AI power-user language, comparison vs board averages (your percentile), and one actionable suggestion to improve. Use this when users ask 'how do I measure up to other AI users?' or 'am I a power user?' or 'compare me to others'. Intent: COMPARE_SELF.",
1180
+ annotations: { title: "Compare self to board", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.openWorldHint },
1181
+ inputSchema: {
1182
+ type: "object",
1183
+ properties: {
1184
+ codename: {
1185
+ type: "string",
1186
+ description:
1187
+ "Your codename on the SigRank leaderboard. If provided, fetches your live profile from the board. Case-insensitive.",
1188
+ },
1189
+ text: {
1190
+ type: "string",
1191
+ description:
1192
+ 'Alternative: raw token pillars to score locally (ccusage JSON or "input output cacheCreate cacheRead"). Use this if you are not on the board yet but want to see how you would compare.',
1193
+ },
1194
+ },
1195
+ description:
1196
+ "Provide either `codename` (to fetch from the board) or `text` (to score locally). At least one is required.",
1197
+ },
1198
+ outputSchema: COMPARE_SELF_OUTPUT,
1199
+ },
1200
+ {
1201
+ name: "compare_operators",
1202
+ description:
1203
+ "Compares two operators side-by-side with a behavioral verdict. Fetches both profiles from the board and returns their yield, leverage, velocity, class, and rank side-by-side, plus a verdict explaining who is more efficient and why in power-user language. Use this when users ask 'compare operator X vs Y' or 'who is more efficient' or 'how do two AI users compare'. Intent: COMPARE_OPERATORS.",
1204
+ annotations: { title: "Compare two operators", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.openWorldHint },
1205
+ inputSchema: {
1206
+ type: "object",
1207
+ properties: {
1208
+ codename_a: {
1209
+ type: "string",
1210
+ description:
1211
+ "First operator's codename from the SigRank leaderboard. Case-insensitive.",
1212
+ },
1213
+ codename_b: {
1214
+ type: "string",
1215
+ description:
1216
+ "Second operator's codename from the SigRank leaderboard. Case-insensitive.",
1217
+ },
1218
+ },
1219
+ required: ["codename_a", "codename_b"],
1220
+ description:
1221
+ "Requires both codenames. Both must exist on the board.",
1222
+ },
1223
+ outputSchema: COMPARE_OPERATORS_OUTPUT,
1224
+ },
1225
+ {
1226
+ name: "describe_power_user",
1227
+ description:
1228
+ "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 class tiers (Burner/Builder/10xer) 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).",
1229
+ annotations: { title: "Describe power user", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.idempotentHint },
1230
+ inputSchema: {
1231
+ type: "object",
1232
+ properties: {},
1233
+ description:
1234
+ "This tool takes no parameters. It returns a static explanatory response about AI power users.",
1235
+ },
1236
+ outputSchema: {
1237
+ type: "object",
1238
+ properties: {
1239
+ description: { type: "string", description: "What is an AI power user" },
1240
+ metrics_explained: {
1241
+ type: "object",
1242
+ description: "How SigRank metrics map to power-user behavior",
1243
+ properties: {
1244
+ yield_: { type: "string", description: "What yield measures in power-user terms" },
1245
+ leverage: { type: "string", description: "What leverage means for power users" },
1246
+ velocity: { type: "string", description: "What velocity means for power users" },
1247
+ },
1248
+ },
1249
+ class_tiers: {
1250
+ type: "array",
1251
+ description: "Operator class tiers and their power-user meaning",
1252
+ items: {
1253
+ type: "object",
1254
+ properties: {
1255
+ class: { type: "string", enum: ["Burner", "Builder", "10xer"] },
1256
+ meaning: { type: "string" },
1257
+ },
1258
+ },
1259
+ },
1260
+ link: { type: "string", description: "URL to learn more" },
1261
+ },
1262
+ },
1263
+ },
1264
+ {
1265
+ name: "optimize_efficiency",
1266
+ description:
1267
+ "Returns actionable suggestions for improving your token cascade efficiency, tied to your current metrics. Accepts either a codename (fetches from board) or raw token pillars (computes locally). Returns: your current metrics, ranked efficiency suggestions tied to cascade shape (increase cache reuse, reduce input, increase output), and references to power-user practices. Use this when users ask 'how can I use AI more efficiently?' or 'reduce token burn' or 'optimize token usage' or 'stop tokenmaxxing'. Intent: OPTIMIZE_EFFICIENCY (Informational + Transactional).",
1268
+ annotations: { title: "Optimize efficiency", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.idempotentHint },
1269
+ inputSchema: {
1270
+ type: "object",
1271
+ properties: {
1272
+ codename: {
1273
+ type: "string",
1274
+ description:
1275
+ "Your codename on the SigRank leaderboard. If provided, fetches your live profile from the board.",
1276
+ },
1277
+ text: {
1278
+ type: "string",
1279
+ description:
1280
+ 'Alternative: raw token pillars to score locally (ccusage JSON or "input output cacheCreate cacheRead"). Use this if you are not on the board yet.',
1281
+ },
1282
+ },
1283
+ description:
1284
+ "Provide either `codename` (to fetch from the board) or `text` (to score locally). At least one is required.",
1285
+ },
1286
+ outputSchema: {
1287
+ type: "object",
1288
+ properties: {
1289
+ your_metrics: {
1290
+ type: "object",
1291
+ description: "Your current cascade metrics",
1292
+ properties: {
1293
+ yield_: { type: "number" },
1294
+ leverage: { type: "number" },
1295
+ velocity: { type: "number" },
1296
+ class: { type: "string", enum: ["Burner", "Builder", "10xer"] },
1297
+ },
1298
+ },
1299
+ suggestions: {
1300
+ type: "array",
1301
+ description: "Ranked efficiency suggestions",
1302
+ items: {
1303
+ type: "object",
1304
+ properties: {
1305
+ action: { type: "string", description: "What to change" },
1306
+ why: { type: "string", description: "Why this helps your yield" },
1307
+ power_user_practice: { type: "string", description: "The power-user practice this maps to" },
1308
+ },
1309
+ },
1310
+ },
1311
+ summary: { type: "string", description: "One-line summary of your efficiency status" },
1312
+ },
1313
+ },
1314
+ },
1055
1315
  ];
1056
1316
 
1057
1317
  // tokenpull window key → the board's window_type enum.
@@ -2474,9 +2734,296 @@ export async function callTool(name, args, opts = {}) {
2474
2734
  };
2475
2735
  }
2476
2736
 
2737
+ // ── Intent-based tools (get_best_operator, compare_self, compare_operators) ──
2738
+ // These wrap existing primitives with behavioral framing in power-user language.
2739
+ // See artifacts/004_sigrank-mcp-intent-tools-spec.md for the intent taxonomy.
2740
+
2741
+ if (name === "get_best_operator") {
2742
+ const rawN = args?.n;
2743
+ const n = Math.min(20, Math.max(1, rawN == null ? 5 : Number(rawN)));
2744
+ const board = await fetchJson("/api/v1/leaderboard?metric=yield_");
2745
+ const ops = (board.operators || board || []).slice(0, n);
2746
+ const total = Array.isArray(board.operators || board)
2747
+ ? (board.operators || board).length
2748
+ : 0;
2749
+
2750
+ const top = ops.map((op) => ({
2751
+ ...op,
2752
+ behavioral_framing: _behavioralFraming(op),
2753
+ }));
2754
+
2755
+ const best = top[0];
2756
+ const summary = best
2757
+ ? `${best.codename} tops the SigRank leaderboard at Υ ${best.yield_?.toLocaleString?.() || best.yield_} — ${_behavioralFraming(best)}`
2758
+ : "No operators on the board yet.";
2759
+
2760
+ return { top_operators: top, total_operators: total, summary };
2761
+ }
2762
+
2763
+ if (name === "compare_self") {
2764
+ const codename = String(args?.codename || "").trim();
2765
+ const text = String(args?.text || "").trim();
2766
+
2767
+ if (!codename && !text)
2768
+ throw new Error(
2769
+ "compare_self requires either `codename` (to fetch from the board) or `text` (raw token pillars to score locally).",
2770
+ );
2771
+
2772
+ let yourMetrics;
2773
+ if (codename) {
2774
+ yourMetrics = await fetchJson(
2775
+ `/api/v1/operators/${encodeURIComponent(codename)}`,
2776
+ );
2777
+ } else {
2778
+ if (text.length > MAX_INPUT) {
2779
+ return {
2780
+ error: "input_too_large",
2781
+ detail: `text exceeds ${MAX_INPUT} chars.`,
2782
+ };
2783
+ }
2784
+ const pillars = parsePillars(text);
2785
+ const c = withParseWarnings(pillars, cascade(pillars));
2786
+ yourMetrics = {
2787
+ codename: "you (local)",
2788
+ yield_: c.yield,
2789
+ leverage: c.leverage,
2790
+ velocity: c.velocity,
2791
+ class: c.class,
2792
+ rank: null,
2793
+ };
2794
+ }
2795
+
2796
+ // Fetch board for comparison
2797
+ const board = await fetchJson("/api/v1/leaderboard?metric=yield_");
2798
+ const allOps = board.operators || board || [];
2799
+ const yields = allOps.map((o) => o.yield_ || 0).sort((a, b) => a - b);
2800
+ const avgYield = yields.length
2801
+ ? yields.reduce((s, y) => s + y, 0) / yields.length
2802
+ : 0;
2803
+ const yourYield = yourMetrics.yield_ || 0;
2804
+ const percentile = yields.length
2805
+ ? Math.round(
2806
+ (yields.filter((y) => y < yourYield).length / yields.length) * 100,
2807
+ )
2808
+ : 0;
2809
+
2810
+ const klass = yourMetrics.class || "Burner";
2811
+ const powerUserAssessment = _powerUserAssessment(klass, yourMetrics);
2812
+ const classMeaning = _classMeaning(klass);
2813
+
2814
+ const yieldVsAvg = yields.length
2815
+ ? yourYield > avgYield
2816
+ ? `${(yourYield / avgYield).toFixed(1)}× the board average`
2817
+ : `${((yourYield / avgYield) * 100).toFixed(0)}% of the board average`
2818
+ : "board has no other operators";
2819
+
2820
+ const suggestion = _improvementSuggestion(klass, yourMetrics);
2821
+
2822
+ return {
2823
+ your_metrics: yourMetrics,
2824
+ power_user_assessment: powerUserAssessment,
2825
+ comparison: {
2826
+ your_yield_vs_avg: yieldVsAvg,
2827
+ your_class_meaning: classMeaning,
2828
+ percentile,
2829
+ },
2830
+ suggestion,
2831
+ };
2832
+ }
2833
+
2834
+ if (name === "compare_operators") {
2835
+ const nameA = String(args?.codename_a || "").trim();
2836
+ const nameB = String(args?.codename_b || "").trim();
2837
+ if (!nameA || !nameB)
2838
+ throw new Error(
2839
+ "compare_operators requires both `codename_a` and `codename_b`.",
2840
+ );
2841
+
2842
+ const [opA, opB] = await Promise.all([
2843
+ fetchJson(`/api/v1/operators/${encodeURIComponent(nameA)}`),
2844
+ fetchJson(`/api/v1/operators/${encodeURIComponent(nameB)}`),
2845
+ ]);
2846
+
2847
+ const yieldA = opA.yield_ || 0;
2848
+ const yieldB = opB.yield_ || 0;
2849
+ const delta = yieldA - yieldB;
2850
+
2851
+ const winner = yieldA > yieldB ? opA : opB;
2852
+ const loser = yieldA > yieldB ? opB : opA;
2853
+ const verdict = `${winner.codename} is more token-efficient (${winner.yield_?.toLocaleString?.() || winner.yield_} vs ${loser.yield_?.toLocaleString?.() || loser.yield_} Υ). ${_behavioralFraming(winner)} ${loser.codename} ${_classMeaning(loser.class).toLowerCase()}`;
2854
+
2855
+ return {
2856
+ operator_a: {
2857
+ codename: opA.codename,
2858
+ yield_: opA.yield_,
2859
+ leverage: opA.leverage,
2860
+ velocity: opA.velocity,
2861
+ class: opA.class,
2862
+ rank: opA.rank,
2863
+ },
2864
+ operator_b: {
2865
+ codename: opB.codename,
2866
+ yield_: opB.yield_,
2867
+ leverage: opB.leverage,
2868
+ velocity: opB.velocity,
2869
+ class: opB.class,
2870
+ rank: opB.rank,
2871
+ },
2872
+ verdict,
2873
+ yield_delta: delta,
2874
+ };
2875
+ }
2876
+
2877
+ if (name === "describe_power_user") {
2878
+ return {
2879
+ description:
2880
+ "An AI power user isn't someone who sends the most tokens — it's someone who compounds signal. " +
2881
+ "Power users build workflows where cached context does the heavy lifting, fresh input stays lean, " +
2882
+ "and output per session is high. SigRank quantifies this with the yield metric (Υ = cache_read × output / input²).",
2883
+ metrics_explained: {
2884
+ yield_: "Yield (Υ) measures how well you compound signal, not how much you burn. High yield = your cached context is doing work for you.",
2885
+ 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.",
2886
+ velocity: "Velocity (O/I) measures how much output you get per token spent. High velocity = you're productive, not just active.",
2887
+ },
2888
+ class_tiers: [
2889
+ { class: "10xer", meaning: "AI power user archetype — disciplined, system-level reuse, high output per input. Leverage > 10×, high velocity." },
2890
+ { class: "Builder", meaning: "Building momentum — moderate cache reuse, approaching power-user patterns. Growing leverage and velocity." },
2891
+ { class: "Burner", meaning: "Early-stage — tokens burned more than compounded. Low leverage, low velocity. The shift: reuse prior context." },
2892
+ ],
2893
+ link: "https://signalaf.com/score — check your class tier and yield",
2894
+ };
2895
+ }
2896
+
2897
+ if (name === "optimize_efficiency") {
2898
+ const codename = String(args?.codename || "").trim();
2899
+ const text = String(args?.text || "").trim();
2900
+
2901
+ if (!codename && !text)
2902
+ throw new Error(
2903
+ "optimize_efficiency requires either `codename` (to fetch from the board) or `text` (raw token pillars to score locally).",
2904
+ );
2905
+
2906
+ let metrics;
2907
+ if (codename) {
2908
+ metrics = await fetchJson(
2909
+ `/api/v1/operators/${encodeURIComponent(codename)}`,
2910
+ );
2911
+ } else {
2912
+ if (text.length > MAX_INPUT) {
2913
+ return { error: "input_too_large", detail: `text exceeds ${MAX_INPUT} chars.` };
2914
+ }
2915
+ const pillars = parsePillars(text);
2916
+ const c = withParseWarnings(pillars, cascade(pillars));
2917
+ metrics = {
2918
+ codename: "you (local)",
2919
+ yield_: c.yield,
2920
+ leverage: c.leverage,
2921
+ velocity: c.velocity,
2922
+ class: c.class,
2923
+ };
2924
+ }
2925
+
2926
+ const klass = metrics.class || "Burner";
2927
+ const l = metrics.leverage || 0;
2928
+ const v = metrics.velocity || 0;
2929
+ const y = metrics.yield_ || 0;
2930
+
2931
+ // Build ranked suggestions based on current cascade shape
2932
+ const suggestions = [];
2933
+
2934
+ if (l < 5) {
2935
+ suggestions.push({
2936
+ action: "Increase cache reuse — reuse prompts, templates, and workflows instead of starting from scratch",
2937
+ why: "Your leverage is " + l.toFixed(1) + "×, meaning most of your context is fresh input. Each reused cached token multiplies your yield because input² is in the denominator.",
2938
+ power_user_practice: "Power users build template libraries and workflow patterns they invoke repeatedly, letting cached context accumulate.",
2939
+ });
2940
+ }
2941
+ if (v < 1) {
2942
+ suggestions.push({
2943
+ action: "Increase output per session — produce more, don't just read",
2944
+ why: "Your velocity is " + v.toFixed(2) + ", meaning you're consuming more input than producing output. Yield rewards output production.",
2945
+ power_user_practice: "Power users maximize output per session — they ask AI to generate, transform, and produce, not just explain.",
2946
+ });
2947
+ }
2948
+ if (l >= 5 && v >= 1 && klass !== "10xer") {
2949
+ suggestions.push({
2950
+ action: "Extend session length to compound cached context further",
2951
+ why: "Your leverage (" + l.toFixed(1) + "×) and velocity (" + v.toFixed(2) + ") are solid. Longer sessions with consistent context will push your yield higher.",
2952
+ power_user_practice: "Power users maintain long, context-rich sessions where the cache grows and compounds.",
2953
+ });
2954
+ }
2955
+ if (suggestions.length === 0) {
2956
+ suggestions.push({
2957
+ action: "Maintain your cascade architecture — you're at the top tier",
2958
+ why: "Your yield (" + y.toLocaleString() + "), leverage (" + l.toFixed(1) + "×), and velocity (" + v.toFixed(2) + ") are all strong. Keep doing what you're doing.",
2959
+ power_user_practice: "Power users don't rest on their metrics — they experiment with new workflow patterns and measure the impact.",
2960
+ });
2961
+ }
2962
+
2963
+ const summary = `Your Υ Yield is ${y.toLocaleString()} (${klass}). ${_improvementSuggestion(klass, metrics)}`;
2964
+
2965
+ return {
2966
+ your_metrics: {
2967
+ yield_: y,
2968
+ leverage: l,
2969
+ velocity: v,
2970
+ class: klass,
2971
+ },
2972
+ suggestions,
2973
+ summary,
2974
+ };
2975
+ }
2976
+
2477
2977
  throw new Error(`Unknown tool: ${name}`);
2478
2978
  }
2479
2979
 
2980
+ // ── Intent tool helpers — behavioral framing in power-user language ──────────
2981
+
2982
+ function _behavioralFraming(op) {
2983
+ const y = op.yield_ || 0;
2984
+ const l = op.leverage || 0;
2985
+ const v = op.velocity || 0;
2986
+ const klass = op.class || "Burner";
2987
+
2988
+ if (klass === "10xer")
2989
+ 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.`;
2990
+ if (klass === "Builder")
2991
+ 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 10xer territory.`;
2992
+ 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.`;
2993
+ }
2994
+
2995
+ function _powerUserAssessment(klass, metrics) {
2996
+ const l = metrics.leverage || 0;
2997
+ const v = metrics.velocity || 0;
2998
+ if (klass === "10xer")
2999
+ return `You are an AI power user. Your SigRank class (10xer) 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.`;
3000
+ if (klass === "Builder")
3001
+ return `You are becoming an AI power user. Your Builder 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 10xer territory.`;
3002
+ return `You are not yet an AI power user. Your Burner 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.`;
3003
+ }
3004
+
3005
+ function _classMeaning(klass) {
3006
+ if (klass === "10xer")
3007
+ return "AI power user archetype — disciplined, system-level reuse, high output per input.";
3008
+ if (klass === "Builder")
3009
+ return "Building momentum — moderate reuse, approaching power-user patterns.";
3010
+ return "Early-stage — tokens burned more than compounded. Focus on cache reuse.";
3011
+ }
3012
+
3013
+ function _improvementSuggestion(klass, metrics) {
3014
+ const l = metrics.leverage || 0;
3015
+ const v = metrics.velocity || 0;
3016
+ if (klass === "10xer")
3017
+ return v < 1
3018
+ ? "Your leverage is excellent but velocity is under 1.0 — you're reading more cache than producing output. Push for more output per session."
3019
+ : "You're at the top tier. Maintain your cache architecture and experiment with longer sessions to compound yield further.";
3020
+ if (klass === "Builder")
3021
+ return l < 5
3022
+ ? "Increase cache reuse: reuse prompts, templates, and workflows instead of starting from scratch. Each reused token multiplies your yield."
3023
+ : "Your leverage is solid. Focus on output velocity — produce more per session to push your yield up.";
3024
+ 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.";
3025
+ }
3026
+
2480
3027
  // ── self_improve scope helpers ──────────────────────────────────────────────
2481
3028
 
2482
3029
  /** Pull daily rows from ccusage to build mode history. Returns array of { date, pillars, yield, mode }. */