@claudinho/cli 0.8.15 → 0.8.17
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/dist/index.js +64 -26
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3122,7 +3122,7 @@ function winnerLabel(ctx, stage, index) {
|
|
|
3122
3122
|
n: String(index)
|
|
3123
3123
|
});
|
|
3124
3124
|
}
|
|
3125
|
-
function resolveSlot(ref, ctx, liveTeam) {
|
|
3125
|
+
function resolveSlot(ref, ctx, liveTeam, fixtureInMergedSet = false) {
|
|
3126
3126
|
const liveParticipant = confirmedLiveParticipant(liveTeam);
|
|
3127
3127
|
switch (ref.kind) {
|
|
3128
3128
|
case "seed":
|
|
@@ -3144,23 +3144,27 @@ function resolveSlot(ref, ctx, liveTeam) {
|
|
|
3144
3144
|
if (liveParticipant) return liveParticipant;
|
|
3145
3145
|
return tbd(t(ctx.lang, "bracket.slot.third", { groups: ref.groups.join("/") }));
|
|
3146
3146
|
case "winner": {
|
|
3147
|
-
const node = ctx.nodesByKey.get(matchKey(ref.stage, ref.index));
|
|
3148
|
-
const match = node ? ctx.matchesById.get(node.matchId) : void 0;
|
|
3149
|
-
if (match) {
|
|
3150
|
-
const winner = resolveWinner(match);
|
|
3151
|
-
if (winner) return participant(winner, "confirmed");
|
|
3152
|
-
}
|
|
3153
3147
|
if (liveParticipant) return liveParticipant;
|
|
3148
|
+
if (!fixtureInMergedSet) {
|
|
3149
|
+
const node = ctx.nodesByKey.get(matchKey(ref.stage, ref.index));
|
|
3150
|
+
const match = node ? ctx.matchesById.get(node.matchId) : void 0;
|
|
3151
|
+
if (match) {
|
|
3152
|
+
const winner = resolveWinner(match);
|
|
3153
|
+
if (winner) return participant(winner, "confirmed");
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3154
3156
|
return tbd(winnerLabel(ctx, ref.stage, ref.index));
|
|
3155
3157
|
}
|
|
3156
3158
|
case "loser": {
|
|
3157
|
-
const node = ctx.nodesByKey.get(matchKey(ref.stage, ref.index));
|
|
3158
|
-
const match = node ? ctx.matchesById.get(node.matchId) : void 0;
|
|
3159
|
-
if (match) {
|
|
3160
|
-
const loser = resolveLoser(match);
|
|
3161
|
-
if (loser) return participant(loser, "confirmed");
|
|
3162
|
-
}
|
|
3163
3159
|
if (liveParticipant) return liveParticipant;
|
|
3160
|
+
if (!fixtureInMergedSet) {
|
|
3161
|
+
const node = ctx.nodesByKey.get(matchKey(ref.stage, ref.index));
|
|
3162
|
+
const match = node ? ctx.matchesById.get(node.matchId) : void 0;
|
|
3163
|
+
if (match) {
|
|
3164
|
+
const loser = resolveLoser(match);
|
|
3165
|
+
if (loser) return participant(loser, "confirmed");
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3164
3168
|
return tbd(
|
|
3165
3169
|
t(ctx.lang, "bracket.slot.loser", {
|
|
3166
3170
|
stage: stageLabelI18n(ctx.lang, ref.stage),
|
|
@@ -3183,6 +3187,7 @@ function buildBracketView(topology, matches, tables, standingsDegraded, liveDegr
|
|
|
3183
3187
|
if (want && stage !== want) continue;
|
|
3184
3188
|
const nodes = topology.matches.filter((n) => n.stage === stage);
|
|
3185
3189
|
const matchViews = nodes.map((node) => {
|
|
3190
|
+
const fixtureInMergedSet = matchesById.has(node.matchId);
|
|
3186
3191
|
const match = matchesById.get(node.matchId) ?? {
|
|
3187
3192
|
id: node.matchId,
|
|
3188
3193
|
stage: node.stage,
|
|
@@ -3198,8 +3203,8 @@ function buildBracketView(topology, matches, tables, standingsDegraded, liveDegr
|
|
|
3198
3203
|
stage: node.stage,
|
|
3199
3204
|
index: node.index,
|
|
3200
3205
|
kickoff: match.kickoff,
|
|
3201
|
-
home: resolveSlot(node.home, ctx, match.home),
|
|
3202
|
-
away: resolveSlot(node.away, ctx, match.away),
|
|
3206
|
+
home: resolveSlot(node.home, ctx, match.home, fixtureInMergedSet),
|
|
3207
|
+
away: resolveSlot(node.away, ctx, match.away, fixtureInMergedSet),
|
|
3203
3208
|
match
|
|
3204
3209
|
};
|
|
3205
3210
|
});
|
|
@@ -4144,7 +4149,8 @@ var PolymarketProvider = class {
|
|
|
4144
4149
|
opts;
|
|
4145
4150
|
name = "polymarket";
|
|
4146
4151
|
async findSignal(match, options) {
|
|
4147
|
-
|
|
4152
|
+
const deadline = options?.deadlineMs != null ? Date.now() + options.deadlineMs : Number.POSITIVE_INFINITY;
|
|
4153
|
+
return (await this.resolveOne(match, options, deadline)).signal;
|
|
4148
4154
|
}
|
|
4149
4155
|
async findSignals(matches, options) {
|
|
4150
4156
|
const signals = /* @__PURE__ */ new Map();
|
|
@@ -4152,7 +4158,7 @@ var PolymarketProvider = class {
|
|
|
4152
4158
|
const deadline = options?.deadlineMs != null ? Date.now() + options.deadlineMs : Number.POSITIVE_INFINITY;
|
|
4153
4159
|
for (const m of matches) {
|
|
4154
4160
|
if (Date.now() >= deadline) break;
|
|
4155
|
-
const r = await this.resolveOne(m, options);
|
|
4161
|
+
const r = await this.resolveOne(m, options, deadline);
|
|
4156
4162
|
if (r.checked) checked.add(m.id);
|
|
4157
4163
|
if (r.signal) signals.set(m.id, r.signal);
|
|
4158
4164
|
}
|
|
@@ -4164,13 +4170,16 @@ var PolymarketProvider = class {
|
|
|
4164
4170
|
* provider/network error — so transient failures are retried, not
|
|
4165
4171
|
* negative-cached.
|
|
4166
4172
|
*/
|
|
4167
|
-
async resolveOne(match, options) {
|
|
4173
|
+
async resolveOne(match, options, deadline = Number.POSITIVE_INFINITY) {
|
|
4168
4174
|
const entry = (this.opts.mapping ?? BUNDLED_MAPPING)[match.id];
|
|
4169
4175
|
const slugs = entry?.eventSlug ? [entry.eventSlug] : deriveEventSlugs(match);
|
|
4170
4176
|
if (slugs.length === 0) return { checked: true };
|
|
4177
|
+
const configured = options?.timeoutMs ?? this.opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
4171
4178
|
try {
|
|
4172
4179
|
for (const slug of slugs) {
|
|
4173
|
-
const
|
|
4180
|
+
const remaining = deadline - Date.now();
|
|
4181
|
+
if (remaining <= 0) return { checked: false };
|
|
4182
|
+
const event = await this.fetchEvent(slug, Math.min(configured, remaining));
|
|
4174
4183
|
const signal = event ? this.toSignal(match, slug, event, options) : void 0;
|
|
4175
4184
|
if (signal) return { signal, checked: true };
|
|
4176
4185
|
}
|
|
@@ -4250,6 +4259,27 @@ var PolymarketProvider = class {
|
|
|
4250
4259
|
return signal.ambiguous ? void 0 : signal;
|
|
4251
4260
|
}
|
|
4252
4261
|
};
|
|
4262
|
+
var POLYMARKET_TOKEN = {
|
|
4263
|
+
SUI: "che",
|
|
4264
|
+
// Switzerland
|
|
4265
|
+
NED: "nld",
|
|
4266
|
+
// Netherlands
|
|
4267
|
+
URU: "ury",
|
|
4268
|
+
// Uruguay
|
|
4269
|
+
POR: "prt",
|
|
4270
|
+
// Portugal
|
|
4271
|
+
CRO: "hrv",
|
|
4272
|
+
// Croatia
|
|
4273
|
+
COD: "cdr",
|
|
4274
|
+
// DR Congo
|
|
4275
|
+
CPV: "cvi"
|
|
4276
|
+
// Cabo Verde
|
|
4277
|
+
};
|
|
4278
|
+
function pmTokens(code) {
|
|
4279
|
+
const c = code.toLowerCase();
|
|
4280
|
+
const alias = POLYMARKET_TOKEN[code.toUpperCase()];
|
|
4281
|
+
return alias && alias !== c ? [alias, c] : [c];
|
|
4282
|
+
}
|
|
4253
4283
|
function deriveEventSlugs(match) {
|
|
4254
4284
|
const home = match.home.code.toLowerCase();
|
|
4255
4285
|
const away = match.away.code.toLowerCase();
|
|
@@ -4257,10 +4287,18 @@ function deriveEventSlugs(match) {
|
|
|
4257
4287
|
if (!/^[a-z]{3}$/.test(home) || !/^[a-z]{3}$/.test(away)) return [];
|
|
4258
4288
|
const utcDate = match.kickoff.slice(0, 10);
|
|
4259
4289
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(utcDate)) return [];
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
];
|
|
4290
|
+
const dates = [utcDate, shiftUtcDate(utcDate, -1)];
|
|
4291
|
+
const homeToks = pmTokens(match.home.code);
|
|
4292
|
+
const awayToks = pmTokens(match.away.code);
|
|
4293
|
+
const slugs = [];
|
|
4294
|
+
for (const d of dates) {
|
|
4295
|
+
for (const h of homeToks) {
|
|
4296
|
+
for (const a of awayToks) {
|
|
4297
|
+
slugs.push(`fifwc-${h}-${a}-${d}`);
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
}
|
|
4301
|
+
return [...new Set(slugs)];
|
|
4264
4302
|
}
|
|
4265
4303
|
function slugToken(m) {
|
|
4266
4304
|
return (m.slug ?? "").toLowerCase().split("-").pop() ?? "";
|
|
@@ -4269,10 +4307,10 @@ function isDrawMarket(m) {
|
|
|
4269
4307
|
return slugToken(m) === "draw" || (m.groupItemTitle ?? "").trim().toLowerCase().startsWith("draw");
|
|
4270
4308
|
}
|
|
4271
4309
|
function pickMarket(markets, teamCode, teamName) {
|
|
4272
|
-
const
|
|
4310
|
+
const tokens = pmTokens(teamCode);
|
|
4273
4311
|
const name = teamName.trim().toLowerCase();
|
|
4274
4312
|
const teamMarkets = markets.filter((m) => !isDrawMarket(m));
|
|
4275
|
-
const bySlug = teamMarkets.find((m) => slugToken(m)
|
|
4313
|
+
const bySlug = teamMarkets.find((m) => tokens.includes(slugToken(m)));
|
|
4276
4314
|
if (bySlug) return bySlug;
|
|
4277
4315
|
return teamMarkets.find((m) => (m.groupItemTitle ?? "").trim().toLowerCase() === name);
|
|
4278
4316
|
}
|
|
@@ -6418,7 +6456,7 @@ function handlePipeError(stream) {
|
|
|
6418
6456
|
}
|
|
6419
6457
|
handlePipeError(process.stdout);
|
|
6420
6458
|
handlePipeError(process.stderr);
|
|
6421
|
-
var VERSION = "0.8.
|
|
6459
|
+
var VERSION = "0.8.17";
|
|
6422
6460
|
var DISCLAIMER = "Claudinho is an independent fan project. Not affiliated with or endorsed by FIFA or Anthropic.";
|
|
6423
6461
|
function ctxFrom(cmd) {
|
|
6424
6462
|
let root = cmd;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudinho/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.17",
|
|
4
4
|
"description": "Live scores, fixtures, group tables, and read-only prediction-market signals for the 2026 men's football tournament — in your terminal, Claude Code, and Cursor CLI statusline. No API keys. Not affiliated with FIFA or Anthropic.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"tsup": "^8.0.0",
|
|
62
62
|
"typescript": "^5.7.0",
|
|
63
63
|
"vitest": "^4.1.9",
|
|
64
|
-
"@claudinho/core": "0.8.
|
|
64
|
+
"@claudinho/core": "0.8.17"
|
|
65
65
|
},
|
|
66
66
|
"scripts": {
|
|
67
67
|
"build": "tsup",
|