@claudinho/cli 0.8.5 → 0.8.7

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 +61 -19
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -298,8 +298,8 @@ var ES = {
298
298
  "bracket.invalidStage": "La fase debe ser una de: R32, R16, QF, SF, 3P, F",
299
299
  "bracket.unknownStage": 'Fase desconocida "{stage}". Usa R32, R16, QF, SF, 3P o F.',
300
300
  "bracket.slot.groupWinner": "Ganador del grupo {group}",
301
- "bracket.slot.groupSecond": "2.\xBA del grupo {group}",
302
- "bracket.slot.third": "3.\xBA ({groups})",
301
+ "bracket.slot.groupSecond": "2\xBA del grupo {group}",
302
+ "bracket.slot.third": "3\xBA ({groups})",
303
303
  "bracket.slot.winner": "Ganador {stage} {n}",
304
304
  "bracket.slot.loser": "Perdedor {stage} {n}",
305
305
  "bracket.slot.tbd": "Por definir",
@@ -3096,17 +3096,24 @@ function participant(team, status) {
3096
3096
  function tbd(label) {
3097
3097
  return { label, flag: "\u{1F3F3}\uFE0F", status: "tbd" };
3098
3098
  }
3099
+ function confirmedLiveParticipant(team) {
3100
+ if (!team || team.flag === "\u{1F3F3}\uFE0F") return void 0;
3101
+ return participant(team, "confirmed");
3102
+ }
3099
3103
  function winnerLabel(ctx, stage, index) {
3100
3104
  return t(ctx.lang, "bracket.slot.winner", {
3101
3105
  stage: stageLabelI18n(ctx.lang, stage),
3102
3106
  n: String(index)
3103
3107
  });
3104
3108
  }
3105
- function resolveSlot(ref, ctx) {
3109
+ function resolveSlot(ref, ctx, liveTeam) {
3110
+ const liveParticipant = confirmedLiveParticipant(liveTeam);
3106
3111
  switch (ref.kind) {
3107
3112
  case "seed":
3113
+ if (liveParticipant) return liveParticipant;
3108
3114
  return tbd(ref.label);
3109
3115
  case "group": {
3116
+ if (liveParticipant) return liveParticipant;
3110
3117
  if (!ctx.standingsDegraded && hasGroupStarted(ref.group, ctx.tables)) {
3111
3118
  const team = teamFromStandings(ref.group, ref.position, ctx.tables);
3112
3119
  if (team) {
@@ -3118,6 +3125,7 @@ function resolveSlot(ref, ctx) {
3118
3125
  return tbd(label);
3119
3126
  }
3120
3127
  case "third":
3128
+ if (liveParticipant) return liveParticipant;
3121
3129
  return tbd(t(ctx.lang, "bracket.slot.third", { groups: ref.groups.join("/") }));
3122
3130
  case "winner": {
3123
3131
  const node = ctx.nodesByKey.get(matchKey(ref.stage, ref.index));
@@ -3126,6 +3134,7 @@ function resolveSlot(ref, ctx) {
3126
3134
  const winner = resolveWinner(match);
3127
3135
  if (winner) return participant(winner, "confirmed");
3128
3136
  }
3137
+ if (liveParticipant) return liveParticipant;
3129
3138
  return tbd(winnerLabel(ctx, ref.stage, ref.index));
3130
3139
  }
3131
3140
  case "loser": {
@@ -3135,6 +3144,7 @@ function resolveSlot(ref, ctx) {
3135
3144
  const loser = resolveLoser(match);
3136
3145
  if (loser) return participant(loser, "confirmed");
3137
3146
  }
3147
+ if (liveParticipant) return liveParticipant;
3138
3148
  return tbd(
3139
3149
  t(ctx.lang, "bracket.slot.loser", {
3140
3150
  stage: stageLabelI18n(ctx.lang, ref.stage),
@@ -3172,8 +3182,8 @@ function buildBracketView(topology, matches, tables, standingsDegraded, liveDegr
3172
3182
  stage: node.stage,
3173
3183
  index: node.index,
3174
3184
  kickoff: match.kickoff,
3175
- home: resolveSlot(node.home, ctx),
3176
- away: resolveSlot(node.away, ctx),
3185
+ home: resolveSlot(node.home, ctx, match.home),
3186
+ away: resolveSlot(node.away, ctx, match.away),
3177
3187
  match
3178
3188
  };
3179
3189
  });
@@ -3832,6 +3842,22 @@ async function marketFixtureForTeam(adapter, code, now = /* @__PURE__ */ new Dat
3832
3842
  const next = nextFixtureForTeam(code, { from: now });
3833
3843
  return { match: next, degraded: false };
3834
3844
  }
3845
+ async function getNextFixtureForTeam(adapter, code, now = /* @__PURE__ */ new Date()) {
3846
+ const base = allFixtures();
3847
+ let matches = base;
3848
+ let degraded = true;
3849
+ let liveById;
3850
+ try {
3851
+ const live = adapter.fetchWindow ? await adapter.fetchWindow(KNOCKOUT_WINDOW_START, KNOCKOUT_WINDOW_END) : [];
3852
+ matches = mergeLive(base, live);
3853
+ degraded = false;
3854
+ liveById = new Set(live.map((m) => m.id));
3855
+ } catch {
3856
+ }
3857
+ const fixture = nextFixtureForTeam(code, { from: now, fixtures: matches });
3858
+ const source = fixture && liveById?.has(fixture.id) ? adapter.name : void 0;
3859
+ return { fixture, degraded, source };
3860
+ }
3835
3861
  async function getMatchById(adapter, id) {
3836
3862
  const base = allFixtures().find((m) => m.id === id);
3837
3863
  if (!base) return { match: void 0, degraded: false };
@@ -4790,8 +4816,8 @@ function header(text, c) {
4790
4816
  function disclaimer(t2, c) {
4791
4817
  return c.dim(t2("disclaimer"));
4792
4818
  }
4793
- function dataSource(source, c) {
4794
- return source ? c.dim(`Live data: ${liveSourceLabel(source)}`) : "";
4819
+ function dataSource(source, lang, c) {
4820
+ return source ? c.dim(t(lang, "live.data", { source: liveSourceLabel(source) })) : "";
4795
4821
  }
4796
4822
 
4797
4823
  // src/marketCache.ts
@@ -5437,7 +5463,7 @@ async function cmdToday(date, ctx) {
5437
5463
  }
5438
5464
  out();
5439
5465
  if (degraded) out(c.dim(" " + t2("feed.degraded")));
5440
- const src = dataSource(source, c);
5466
+ const src = dataSource(source, cfg.lang, c);
5441
5467
  if (src) out(src);
5442
5468
  out(disclaimer(t2, c));
5443
5469
  }
@@ -5463,23 +5489,28 @@ async function cmdLive(ctx) {
5463
5489
  for (const m of matches) out(matchLine(m, cfg, t2, c, flags));
5464
5490
  }
5465
5491
  out();
5466
- const src = dataSource(source, c);
5492
+ const src = dataSource(source, cfg.lang, c);
5467
5493
  if (src) out(src);
5468
5494
  out(disclaimer(t2, c));
5469
5495
  }
5470
- async function cmdNext(team, { cfg, t: t2, now }) {
5496
+ async function cmdNext(team, ctx) {
5497
+ const { cfg, t: t2, now } = ctx;
5471
5498
  precheck(cfg, t2);
5472
5499
  const code = resolveTeamArg(team, "Usage: claudinho next <team> (or set CLAUDINHO_TEAM)");
5473
- const fixture = nextFixtureForTeam(code, { from: now ?? /* @__PURE__ */ new Date() });
5500
+ const { fixture, degraded, source } = await getNextFixtureForTeam(
5501
+ adapterFor(ctx),
5502
+ code,
5503
+ now ?? /* @__PURE__ */ new Date()
5504
+ );
5474
5505
  if (cfg.json) {
5475
- emitJson({ team: code, fixture: fixture ?? null });
5506
+ emitJson({ team: code, fixture: fixture ?? null, degraded, source: source ?? null });
5476
5507
  return;
5477
5508
  }
5478
5509
  const c = painterFor(cfg);
5479
5510
  const flags = flagsEnabled();
5480
5511
  out();
5481
5512
  if (!fixture) {
5482
- out(c.dim(" " + t2("next.none", { team: code })));
5513
+ out(c.dim(" " + (degraded ? t2("live.degraded") : t2("next.none", { team: code }))));
5483
5514
  out();
5484
5515
  out(disclaimer(t2, c));
5485
5516
  return;
@@ -5494,6 +5525,8 @@ async function cmdNext(team, { cfg, t: t2, now }) {
5494
5525
  )
5495
5526
  );
5496
5527
  out();
5528
+ const src = dataSource(source, cfg.lang, c);
5529
+ if (src) out(src);
5497
5530
  out(disclaimer(t2, c));
5498
5531
  }
5499
5532
  async function cmdTable(group, ctx) {
@@ -5554,7 +5587,7 @@ async function cmdTable(group, ctx) {
5554
5587
  }
5555
5588
  out();
5556
5589
  if (degraded) out(c.dim(" " + t2("table.degraded")));
5557
- const src = dataSource(source, c);
5590
+ const src = dataSource(source, cfg.lang, c);
5558
5591
  if (src) out(src);
5559
5592
  out(disclaimer(t2, c));
5560
5593
  }
@@ -5605,7 +5638,7 @@ async function cmdBracket(stage, opts, ctx) {
5605
5638
  out();
5606
5639
  if (degraded) out(c.dim(` ${t(cfg.lang, "bracket.degraded")}`));
5607
5640
  else if (standingsDegraded) out(c.dim(` ${t(cfg.lang, "bracket.standingsDegraded")}`));
5608
- const src = dataSource(source, c);
5641
+ const src = dataSource(source, cfg.lang, c);
5609
5642
  if (src) out(src);
5610
5643
  out(disclaimer(t2, c));
5611
5644
  }
@@ -5745,7 +5778,7 @@ async function cmdMatch(id, ctx) {
5745
5778
  }
5746
5779
  out();
5747
5780
  if (degraded) out(c.dim(" " + t2("feed.degraded")));
5748
- const src = dataSource(liveSource, c);
5781
+ const src = dataSource(liveSource, cfg.lang, c);
5749
5782
  if (src) out(src);
5750
5783
  out(disclaimer(t2, c));
5751
5784
  }
@@ -6041,7 +6074,11 @@ async function cmdShare(target, team, opts, ctx) {
6041
6074
  if (target === "next") {
6042
6075
  precheck(cfg, t2);
6043
6076
  const code = resolveTeamArg(team, "Usage: claudinho share next <team> (or set CLAUDINHO_TEAM)");
6044
- const fixture = nextFixtureForTeam(code, { from: ctx.now ?? /* @__PURE__ */ new Date() });
6077
+ const { fixture, degraded: degraded2, source: source2 } = await getNextFixtureForTeam(
6078
+ adapterFor(ctx),
6079
+ code,
6080
+ ctx.now ?? /* @__PURE__ */ new Date()
6081
+ );
6045
6082
  const matches = fixture ? [fixture] : [];
6046
6083
  const signals2 = await reliableShareSignals(ctx, matches);
6047
6084
  const teamName = fixture ? fixture.home.code === code ? fixture.home.name : fixture.away.name : code;
@@ -6055,7 +6092,12 @@ async function cmdShare(target, team, opts, ctx) {
6055
6092
  title: `Next up for ${teamName}`,
6056
6093
  matches,
6057
6094
  marketSignals: signals2,
6058
- emptyNote: `No upcoming fixture found for ${code}.`,
6095
+ // Attribute the provider when the overlay resolved the tie (knockout);
6096
+ // undefined for a static group fixture — parity with CLI `next`.
6097
+ source: source2,
6098
+ degraded: degraded2,
6099
+ // Fail-closed: an outage must never paste as "no fixture" (eliminated).
6100
+ emptyNote: degraded2 ? `Couldn't reach the data provider \u2014 no upcoming fixture confirmed for ${code}.` : `No upcoming fixture found for ${code}.`,
6059
6101
  installLine: `npx @claudinho/cli next ${code}`,
6060
6102
  tz: cfg.tz,
6061
6103
  locale: cfg.lang
@@ -6192,7 +6234,7 @@ function handlePipeError(stream) {
6192
6234
  }
6193
6235
  handlePipeError(process.stdout);
6194
6236
  handlePipeError(process.stderr);
6195
- var VERSION = "0.8.5";
6237
+ var VERSION = "0.8.7";
6196
6238
  var DISCLAIMER = "Claudinho is an independent fan project. Not affiliated with or endorsed by FIFA or Anthropic.";
6197
6239
  function ctxFrom(cmd) {
6198
6240
  let root = cmd;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudinho/cli",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
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.5"
64
+ "@claudinho/core": "0.8.7"
65
65
  },
66
66
  "scripts": {
67
67
  "build": "tsup",