@claudinho/cli 0.9.4 → 0.10.0
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 +36 -22
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -3448,7 +3448,7 @@ function parseEspnStandings(raw) {
|
|
|
3448
3448
|
complete = false;
|
|
3449
3449
|
}
|
|
3450
3450
|
const entries = takeBounded(rawEntries, MAX_GROUP_ROWS);
|
|
3451
|
-
const
|
|
3451
|
+
const seenCodes = /* @__PURE__ */ new Map();
|
|
3452
3452
|
const seenRanks = /* @__PURE__ */ new Set();
|
|
3453
3453
|
const ranked = [];
|
|
3454
3454
|
for (const e of entries) {
|
|
@@ -3457,14 +3457,17 @@ function parseEspnStandings(raw) {
|
|
|
3457
3457
|
if (r.kind !== "definitive-none") complete = false;
|
|
3458
3458
|
continue;
|
|
3459
3459
|
}
|
|
3460
|
-
const
|
|
3461
|
-
|
|
3460
|
+
const { providerId, providerRank } = r.value;
|
|
3461
|
+
const code = r.value.team.code;
|
|
3462
|
+
const priorHadId = seenCodes.get(code);
|
|
3463
|
+
const codeCollision = priorHadId !== void 0 && (providerId === void 0 || priorHadId === false);
|
|
3464
|
+
if (codeCollision || seenRanks.has(providerRank) || providerId !== void 0 && seenProviderIds.has(providerId)) {
|
|
3462
3465
|
complete = false;
|
|
3463
3466
|
continue;
|
|
3464
3467
|
}
|
|
3465
|
-
|
|
3466
|
-
seenRanks.add(
|
|
3467
|
-
if (
|
|
3468
|
+
seenCodes.set(code, providerId !== void 0);
|
|
3469
|
+
seenRanks.add(providerRank);
|
|
3470
|
+
if (providerId !== void 0) seenProviderIds.add(providerId);
|
|
3468
3471
|
const { providerId: _dropId, providerRank: rank, ...row } = r.value;
|
|
3469
3472
|
ranked.push({ row, rank });
|
|
3470
3473
|
}
|
|
@@ -3492,7 +3495,7 @@ function parseEspnStandings(raw) {
|
|
|
3492
3495
|
var ESPN_SOCCER = "https://site.api.espn.com/apis/site/v2/sports/soccer";
|
|
3493
3496
|
var DEFAULT_COMPETITION = "fifa.world";
|
|
3494
3497
|
var DEFAULT_BASE = `${ESPN_SOCCER}/${DEFAULT_COMPETITION}`;
|
|
3495
|
-
var USER_AGENT = `claudinho/${"0.
|
|
3498
|
+
var USER_AGENT = `claudinho/${"0.10.0"} (+https://github.com/arturogarrido/claudinho)`;
|
|
3496
3499
|
var MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
3497
3500
|
function competitionBase(slug) {
|
|
3498
3501
|
return `${ESPN_SOCCER}/${slug}`;
|
|
@@ -4410,12 +4413,12 @@ function resolveCompetition(explicit) {
|
|
|
4410
4413
|
return DEFAULT_COMPETITION;
|
|
4411
4414
|
}
|
|
4412
4415
|
var KNOWN_SOURCES = ["espn"];
|
|
4413
|
-
function makeAdapter(source = "espn") {
|
|
4416
|
+
function makeAdapter(source = "espn", opts = {}) {
|
|
4414
4417
|
switch (source) {
|
|
4415
4418
|
case "espn": {
|
|
4416
4419
|
const competition = resolveCompetition();
|
|
4417
4420
|
const baseUrl = competition === DEFAULT_COMPETITION ? void 0 : competitionBase(competition);
|
|
4418
|
-
return new EspnAdapter({ baseUrl });
|
|
4421
|
+
return new EspnAdapter({ baseUrl, enrichGroups: opts.enrichGroups });
|
|
4419
4422
|
}
|
|
4420
4423
|
default:
|
|
4421
4424
|
throw new Error(
|
|
@@ -5278,6 +5281,10 @@ function numberish(v) {
|
|
|
5278
5281
|
}
|
|
5279
5282
|
return void 0;
|
|
5280
5283
|
}
|
|
5284
|
+
var MARKET_COMPETITIONS = /* @__PURE__ */ new Set([DEFAULT_COMPETITION]);
|
|
5285
|
+
function marketsCoverCompetition(competition = resolveCompetition()) {
|
|
5286
|
+
return MARKET_COMPETITIONS.has(competition);
|
|
5287
|
+
}
|
|
5281
5288
|
function resolveMarketSource(explicit) {
|
|
5282
5289
|
if (explicit) return explicit;
|
|
5283
5290
|
if (typeof process !== "undefined" && process.env?.CLAUDINHO_MARKETS_SOURCE) {
|
|
@@ -5294,6 +5301,7 @@ function makeMarketProvider(source) {
|
|
|
5294
5301
|
return new FakeMarketProvider();
|
|
5295
5302
|
// no synth → yields no signals, no network
|
|
5296
5303
|
default:
|
|
5304
|
+
if (!marketsCoverCompetition()) return new FakeMarketProvider();
|
|
5297
5305
|
return new PolymarketProvider();
|
|
5298
5306
|
}
|
|
5299
5307
|
}
|
|
@@ -6456,14 +6464,15 @@ function boundContext(text, marker = "") {
|
|
|
6456
6464
|
return `${points.slice(0, room).join("")}
|
|
6457
6465
|
(context truncated)${marker}`;
|
|
6458
6466
|
}
|
|
6459
|
-
function rosterPinned(t2) {
|
|
6467
|
+
function rosterPinned(t2, pin) {
|
|
6468
|
+
if (!pin) return t2;
|
|
6460
6469
|
const { team } = lookupTeam(t2.code);
|
|
6461
6470
|
return team ? { ...t2, name: team.name, flag: team.flag } : t2;
|
|
6462
6471
|
}
|
|
6463
|
-
function line(m, flags) {
|
|
6472
|
+
function line(m, flags, pin) {
|
|
6464
6473
|
const minute = m.status === "HT" ? "half-time" : m.minute ? `${m.minute}'` : "live";
|
|
6465
|
-
const h = rosterPinned(m.home);
|
|
6466
|
-
const a = rosterPinned(m.away);
|
|
6474
|
+
const h = rosterPinned(m.home, pin);
|
|
6475
|
+
const a = rosterPinned(m.away, pin);
|
|
6467
6476
|
const home = flags ? `${h.flag} ${h.name}` : h.name;
|
|
6468
6477
|
const away = flags ? `${a.name} ${a.flag}` : a.name;
|
|
6469
6478
|
return `${home} ${scoreline(m)} ${away} (${minute})`;
|
|
@@ -6472,6 +6481,7 @@ function renderHook(state, opts = {}) {
|
|
|
6472
6481
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
6473
6482
|
const team = opts.team?.toUpperCase();
|
|
6474
6483
|
const flags = opts.flags ?? true;
|
|
6484
|
+
const pin = opts.defaultCompetition ?? true;
|
|
6475
6485
|
const liveList = liveMatchesFromCache(state, now.getTime());
|
|
6476
6486
|
let live = [...liveList.items];
|
|
6477
6487
|
if (live.length === 0) return "";
|
|
@@ -6484,7 +6494,7 @@ function renderHook(state, opts = {}) {
|
|
|
6484
6494
|
}
|
|
6485
6495
|
const shown = live.slice(0, MAX_HOOK_MATCHES);
|
|
6486
6496
|
const overflow = live.length - shown.length;
|
|
6487
|
-
const lines = shown.map((mm) => line(mm, flags)).join("\n");
|
|
6497
|
+
const lines = shown.map((mm) => line(mm, flags, pin)).join("\n");
|
|
6488
6498
|
const more = !liveList.complete ? "\n(more live matches may not be shown)" : overflow > 0 ? `
|
|
6489
6499
|
(+${overflow} more not shown)` : "";
|
|
6490
6500
|
return boundContext(`[Claudinho \u2014 live football scores right now]
|
|
@@ -6516,11 +6526,7 @@ function liveWindowActive(nowMs) {
|
|
|
6516
6526
|
return inLiveWindow(nowMs);
|
|
6517
6527
|
}
|
|
6518
6528
|
function liveAdapter(source) {
|
|
6519
|
-
|
|
6520
|
-
if (source === "espn" && competition === DEFAULT_COMPETITION) {
|
|
6521
|
-
return new EspnAdapter({ enrichGroups: false });
|
|
6522
|
-
}
|
|
6523
|
-
return makeAdapter(source);
|
|
6529
|
+
return makeAdapter(source, { enrichGroups: false });
|
|
6524
6530
|
}
|
|
6525
6531
|
async function runRefresh(opts = {}) {
|
|
6526
6532
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
@@ -7164,7 +7170,13 @@ function cmdHook({ cfg }) {
|
|
|
7164
7170
|
try {
|
|
7165
7171
|
const team = resolveEnvTeam(process.env.CLAUDINHO_TEAM);
|
|
7166
7172
|
const state = readCurrentState(cfg.source, resolveCompetition());
|
|
7167
|
-
const ctx = renderHook(state, {
|
|
7173
|
+
const ctx = renderHook(state, {
|
|
7174
|
+
team,
|
|
7175
|
+
flags: flagsEnabled(),
|
|
7176
|
+
// The bundled roster names World Cup nations only; on another competition
|
|
7177
|
+
// a club sharing a nation's code must not be renamed to that nation.
|
|
7178
|
+
defaultCompetition: resolveCompetition() === DEFAULT_COMPETITION
|
|
7179
|
+
});
|
|
7168
7180
|
if (ctx) out(ctx);
|
|
7169
7181
|
if (!state && !isLockFresh() || shouldRefresh(Date.now(), state) || shouldRefreshFixtures(Date.now(), state)) {
|
|
7170
7182
|
spawnRefresh(cfg.source);
|
|
@@ -7303,6 +7315,7 @@ async function cmdMatch(id, ctx) {
|
|
|
7303
7315
|
maybeStarNudge(ctx);
|
|
7304
7316
|
}
|
|
7305
7317
|
var MARKET_INFO = "Prediction-market data is informational only.";
|
|
7318
|
+
var MARKETS_SCOPE_NOTE = "Market signals cover the World Cup only; none are read for this competition.";
|
|
7306
7319
|
function marketDisplayable(match, sig) {
|
|
7307
7320
|
return marketSignalRendersFor(match, sig) && !sig.ambiguous && sig.favorite != null && hasSaneDistribution(sig.outcomes);
|
|
7308
7321
|
}
|
|
@@ -7311,6 +7324,7 @@ function marketHeaderLine(m, cfg) {
|
|
|
7311
7324
|
return `${m.home.flag} ${m.home.name} vs ${m.away.name} ${m.away.flag} \xB7 ${when}`;
|
|
7312
7325
|
}
|
|
7313
7326
|
function noSignalLine(m, now) {
|
|
7327
|
+
if (!marketsCoverCompetition()) return MARKETS_SCOPE_NOTE;
|
|
7314
7328
|
if (marketRelevant(m, now)) return "No market signal for this match.";
|
|
7315
7329
|
return isFinished(m.status) ? "Match has finished \u2014 market signals are pre-match and in-play reads." : "Match appears to have finished \u2014 market signals are pre-match and in-play reads.";
|
|
7316
7330
|
}
|
|
@@ -7412,7 +7426,7 @@ async function cmdMarkets(target, team, ctx) {
|
|
|
7412
7426
|
if (rows.length === 0) {
|
|
7413
7427
|
out(
|
|
7414
7428
|
c.dim(
|
|
7415
|
-
complete ? ` No market signals available for ${date}.` : ` Market data unavailable or incomplete for ${date} \u2014 not all fixtures could be checked.`
|
|
7429
|
+
!marketsCoverCompetition() ? ` ${MARKETS_SCOPE_NOTE}` : complete ? ` No market signals available for ${date}.` : ` Market data unavailable or incomplete for ${date} \u2014 not all fixtures could be checked.`
|
|
7416
7430
|
)
|
|
7417
7431
|
);
|
|
7418
7432
|
} else {
|
|
@@ -7829,7 +7843,7 @@ function handlePipeError(stream) {
|
|
|
7829
7843
|
}
|
|
7830
7844
|
handlePipeError(process.stdout);
|
|
7831
7845
|
handlePipeError(process.stderr);
|
|
7832
|
-
var VERSION = "0.
|
|
7846
|
+
var VERSION = "0.10.0";
|
|
7833
7847
|
var DISCLAIMER = "Claudinho is an independent fan project. Not affiliated with or endorsed by FIFA or Anthropic.";
|
|
7834
7848
|
function ctxFrom(cmd) {
|
|
7835
7849
|
let root = cmd;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudinho/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Live 2026 World Cup scores, fixtures, group tables, and read-only prediction-market signals 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",
|
|
@@ -57,12 +57,12 @@
|
|
|
57
57
|
"picocolors": "^1.1.1"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@types/node": "^22.20.
|
|
61
|
-
"@vitest/coverage-v8": "^4.1.
|
|
60
|
+
"@types/node": "^22.20.2",
|
|
61
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
62
62
|
"tsup": "^8.0.0",
|
|
63
63
|
"typescript": "^5.7.0",
|
|
64
|
-
"vitest": "^4.1.
|
|
65
|
-
"@claudinho/core": "0.
|
|
64
|
+
"vitest": "^4.1.11",
|
|
65
|
+
"@claudinho/core": "0.10.0"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|
|
68
68
|
"build": "tsup",
|