sigrank 1.0.9 → 1.0.11

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.
@@ -117,6 +117,7 @@ async function* _walkJsonl(dir, _counter = { n: 0 }) {
117
117
  */
118
118
  export const claudeAdapter = {
119
119
  platform: "claude",
120
+ globalMessageIdDedup: true,
120
121
  defaultRoot: () => join(homedir(), ".claude", "projects"),
121
122
  async *messages(root) {
122
123
  for await (const path of _walkJsonl(root)) {
@@ -166,16 +167,21 @@ export async function tokenpull({ adapter = claudeAdapter, root, now } = {}) {
166
167
  const nowMs =
167
168
  now == null ? Date.now() : typeof now === "number" ? now : Date.parse(now);
168
169
 
169
- // Dedup by (session_id, message_id), keeping the FINAL snapshot — matches
170
- // token-dashboard: Claude Code writes 2-3 partial→final lines per response with
171
- // the same message.id; only the final tally matches billing. No-id records each
172
- // get a unique synthetic key so they always count.
170
+ // Dedup by message ID for adapters whose logs can copy one API message into
171
+ // forked sessions; otherwise use (session_id, message_id) to preserve the
172
+ // adapter's native session semantics. Keep the FINAL snapshot: Claude Code
173
+ // writes 2-3 partial→final lines per response with the same message.id, and
174
+ // only the final tally matches billing. No-id records each get a unique key.
173
175
  const seen = new Map();
174
176
  const files = new Set();
175
177
  let noId = 0;
176
178
  for await (const msg of adapter.messages(r)) {
177
179
  const key =
178
- msg.sid && msg.id ? `${msg.sid}|${msg.id}` : msg.id || `__noid_${noId++}`;
180
+ msg.id && adapter.globalMessageIdDedup
181
+ ? msg.id
182
+ : msg.sid && msg.id
183
+ ? `${msg.sid}|${msg.id}`
184
+ : msg.id || `__noid_${noId++}`;
179
185
  seen.set(key, msg); // keep-last (final snapshot wins)
180
186
  if (msg.file) files.add(msg.file);
181
187
  }
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.8",
5
+ "version": "1.0.10",
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.9",
3
+ "version": "1.0.11",
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",