@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.
Files changed (2) hide show
  1. package/dist/index.js +64 -26
  2. 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
- return (await this.resolveOne(match, options)).signal;
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 event = await this.fetchEvent(slug, options?.timeoutMs);
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
- return [
4261
- `fifwc-${home}-${away}-${utcDate}`,
4262
- `fifwc-${home}-${away}-${shiftUtcDate(utcDate, -1)}`
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 code = teamCode.toLowerCase();
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) === code);
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.15";
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.15",
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.15"
64
+ "@claudinho/core": "0.8.17"
65
65
  },
66
66
  "scripts": {
67
67
  "build": "tsup",