@claudinho/cli 0.10.1 → 0.11.1

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 (3) hide show
  1. package/README.md +116 -56
  2. package/dist/index.js +4730 -1284
  3. package/package.json +22 -8
package/README.md CHANGED
@@ -1,48 +1,55 @@
1
1
  # @claudinho/cli ⚽
2
2
 
3
- **The 2026 men's football tournament, right in your terminal.** Live scores, fixtures, group tables, and market signals — TZ-aware, localized, scriptable. No API key, no signup.
3
+ **Live football scores, fixtures and standings in your terminal and your Claude Code and Cursor CLI statusline, for the competition you follow: the World Cup, the Premier League, LALIGA, the Champions League and 12 more.** The `claudinho` command: TZ-aware, localized, scriptable, with read-only market signals for the World Cup. No API key, no signup. It ran the 2026 World Cup from the opener to the final.
4
4
 
5
- > ⭐ Installing via `npx` or globally? **[Star the repo](https://github.com/arturogarrido/claudinho)** — a fan project runs on stars. (`claudinho star` shows you how anytime.)
5
+ > ⭐ Installing via `npx` or globally? **[Star the repo](https://github.com/arturogarrido/claudinho)**: a fan project runs on stars. (`claudinho star` shows you how anytime.)
6
6
 
7
7
  ## Install
8
8
 
9
9
  ```bash
10
10
  npm i -g @claudinho/cli # installs the `claudinho` binary
11
- # or run without installing:
12
- npx @claudinho/cli today
11
+ claudinho follow world-cup # choose a competition once (claudinho follow --list shows them all)
12
+ # or run without installing, choosing per command (or once: npx @claudinho/cli follow world-cup):
13
+ npx @claudinho/cli --competition world-cup today
13
14
  ```
14
15
 
15
- `claudinho today` on a knockout night — penalty shootouts and all:
16
+ `claudinho today` on a World Cup knockout night, penalty shootouts and all:
16
17
 
17
- <!-- DEMO: verbatim `claudinho today <date>` from a knockout matchday. Shootouts render
18
- as 1(3)–1(4). REGENERATE per matchday (capture after the day's games finish, so the
19
- scores are live and current). Never hand-edit. -->
18
+ <!-- DEMO: verbatim `claudinho --tz America/Los_Angeles today 2026-06-29` with the World Cup
19
+ followed (`claudinho follow world-cup`), from a knockout matchday. Shootouts render as 1(3)–1(4). REGENERATE per matchday
20
+ (capture after the day's games finish, so the scores are live and current). Never
21
+ hand-edit. Re-rendered on 2026-10-05 (0.11) through the CLI's own `today` command,
22
+ offline: a provider double served the capture's three results on the bundled
23
+ fixtures' ids, at a frozen clock of 2026-06-30T12:00Z. A US zone, because the capture's
24
+ was west of UTC: in UTC the third tie (01:00Z on Jun 30) leaves this date. -->
20
25
  ```text
21
26
  Matches · 2026-06-29
27
+ World Cup
22
28
 
23
- 🇧🇷 Brazil 2–1 Japan 🇯🇵 FT into the history books!
24
- 🇩🇪 Germany 1(3)–1(4) Paraguay 🇵🇾 FT it's all over!
25
- 🇳🇱 Netherlands 1(2)–1(3) Morocco 🇲🇦 FT the final whistle blows!
29
+ 🇧🇷 Brazil 2–1 Japan 🇯🇵 FT into the history books!
30
+ 🇩🇪 Germany 1(3)–1(4) Paraguay 🇵🇾 FT it's all over!
31
+ 🇳🇱 Netherlands 1(2)–1(3) Morocco 🇲🇦 FT the final whistle blows!
26
32
 
27
33
  Live data: ESPN
28
- Not affiliated with FIFA or Anthropic.
34
+ Not affiliated with FIFA, any confederation, league or club, or Anthropic.
29
35
  ```
30
36
 
31
- All 104 fixtures ship bundled, so the schedule works offline; only live scores hit the network.
37
+ The World Cup's schedule ships bundled (104 fixtures), so it works offline and only its live scores hit the network; the other competitions' schedules are read from the feed, so `today` and `next` need the network there.
32
38
 
33
39
  ## Commands
34
40
 
35
41
  ```bash
42
+ claudinho follow [ALIAS] # choose the competition every surface follows (saved); --team <name> pins your team; --list; off
36
43
  claudinho today [date] # a day's fixtures in your timezone (default: today), live scores inline
37
44
  claudinho live # matches in play right now
38
- claudinho next [TEAM] # a team's next fixture + countdown — TEAM is a name OR code (Mexico | MEX | "DR Congo"); default $CLAUDINHO_TEAM
39
- claudinho table [GROUP] # live cumulative group standings (default: all groups)
45
+ claudinho next [TEAM] # a team's next fixture + countdown — TEAM is a name OR code (Mexico | MEX | "DR Congo", or a club: Arsenal | ARS); default $CLAUDINHO_TEAM, else your pinned team
46
+ claudinho table [KEY] # live cumulative standings (default: every table); KEY is a group letter, or A1, A-B, LEAGUE
40
47
  claudinho bracket [STAGE] # knockout bracket (R32, R16, QF, SF, 3P, F); --tree for ASCII tree
41
48
  claudinho match <id> # a single match's detail
42
- claudinho team <query> # resolve a name/code to its FIFA code, flag, and group (e.g. team "DR Congo")
49
+ claudinho team <query> # resolve a World Cup nation's name/code to its FIFA code, flag, and group (e.g. team "DR Congo")
43
50
  claudinho markets [target] # prediction-market signals: today | <date> | <id> | next <TEAM>
44
51
  # (next prefers the team's IN-PLAY match while one is live)
45
- claudinho share [target] # copy-pasteable snippet: today | live | <date> | <id> | next <TEAM> | table <GROUP> | bracket [STAGE]
52
+ claudinho share [target] # copy-pasteable snippet: today | live | <date> | <id> | next <TEAM> | table <KEY> | bracket [STAGE]
46
53
  claudinho prompt # one compact status line (for statusline/tmux/Starship)
47
54
  claudinho init cursor # one-step Cursor setup: statusline + MCP paste (--print for snippets)
48
55
  claudinho init claude # one-step Claude Code setup: statusline + hook + MCP one-liner
@@ -54,6 +61,31 @@ claudinho vibe # a matchday-coder one-liner (#VibingLaVidaLoca)
54
61
  claudinho star # how to support the project (star the repo ⭐)
55
62
  ```
56
63
 
64
+ In a club competition, `next` resolves a club's name or code against the
65
+ competition's own table and answers its next match within 14 days (several teams
66
+ matching a name are listed, never guessed); `match <id>` looks from yesterday to
67
+ 14 days ahead and names the days it searched when the match is not there;
68
+ `bracket` says when a league season has no bracket; and `today`, `live`, `next`
69
+ and `match` say "between editions" once a competition's edition has ended and
70
+ the next has not started. A club shows by its name (or its code on the
71
+ statusline: `ARS 2–1 CHE 50'`), with nothing where a nation's flag would be, and
72
+ `next`/`match` say the stage it is in ("League", "Play-offs", or the provider's
73
+ words for a phase Claudinho does not know).
74
+
75
+ `claudinho follow <alias>` saves the competition every surface follows;
76
+ `--team <name>` pins a team in it, resolved as `next <name>` resolves it. Pin a
77
+ team while its competition has fixtures ahead: between editions `next` answers
78
+ the verdict before it resolves a club, so there is nothing to pin (a `follow
79
+ <alias>` without `--team` still works there). A pin is scoped to its
80
+ competition, whatever chose it (`--competition`, `CLAUDINHO_COMPETITION`, or the
81
+ saved choice), and never applies to another. `follow --json` says the same facts as
82
+ its text: `competition` (`follow` alone: this command's; after a write or `off`: what
83
+ the next command follows), `override` (its source when it is not the saved choice),
84
+ `sources` (the flag, the environment and `CLAUDINHO_TEAM` this command ran under),
85
+ `refused` (each refused value under its source's name, `flag`, `env` or `team`; a
86
+ `CLAUDINHO_TEAM` with nothing readable is `"team": ""`, which the team-taking
87
+ commands refuse), `saved` (the file as read) and `path`.
88
+
57
89
  ### Examples
58
90
 
59
91
  ```bash
@@ -64,6 +96,9 @@ claudinho bracket R32 --tree
64
96
  claudinho live --json | jq '.matches[].status'
65
97
  claudinho today --flavor off # just the facts, no commentary
66
98
  claudinho share next MEX --copy # a shareable card, copied to your clipboard
99
+ claudinho follow premier-league --team Arsenal # follow a competition, pin a team: `claudinho next` answers for it
100
+ claudinho --competition laliga today # another competition for one command, by its alias
101
+ CLAUDINHO_COMPETITION=laliga claudinho table # the environment works too (the statusline and hook follow it)
67
102
  ```
68
103
 
69
104
  ## Global options
@@ -71,30 +106,40 @@ claudinho share next MEX --copy # a shareable card, copied to your cl
71
106
  | Flag | Description |
72
107
  |---|---|
73
108
  | `--lang <code>` | `en`, `es`, `pt`, `fr` (also via `CLAUDINHO_LANG`; falls back to `$LANG`) |
74
- | `--tz <zone>` | IANA timezone, e.g. `America/Mexico_City` (also `CLAUDINHO_TZ`; default: system). Kickoff times **and** which day a fixture falls on are computed in this zone — a late-night-UTC match shows on the day you actually watch it. |
109
+ | `--tz <zone>` | IANA timezone, e.g. `America/Mexico_City` (also `CLAUDINHO_TZ`; default: system). Kickoff times **and** which day a fixture falls on are computed in this zone: a late-night-UTC match shows on the day you actually watch it. |
75
110
  | `--json` | machine-readable output for scripting |
76
111
  | `--no-color` | disable ANSI color (also honors `NO_COLOR`; auto-off when piped) |
112
+ | `-c, --competition <alias\|slug>` | the competition: an alias such as `premier-league` (the sixteen competitions are listed in the [root README](https://github.com/arturogarrido/claudinho#competitions)), or an ESPN slug such as `eng.1` (any other lower-case dotted ESPN slug works too, labelled experimental). Also `CLAUDINHO_COMPETITION` (an alias or a slug), which the statusline and the hook follow, and the choice `claudinho follow <alias>` saves: the flag, then the environment, then the saved choice; with none, a command says so (exit 1; `--json` prints `{ "competition": null, "noCompetition": true }`), the statusline reads `⚽ claudinho follow`, and the hook stays silent. Every answer names its competition on a line after its header (`Premier League · from the command line`; first where an answer has none; `table` once, before its tables) and in `--json` as `competition`; `share` prints no such line: its card's title names the competition and its run cue selects it; `team` names the World Cup roster it reads. An unknown value is refused with the list. |
77
113
  | `--source <name>` | live data provider (advanced; sensible default) |
78
114
  | `--flavor <level>` | commentary flair: `off`, `subtle`, `full` (default: `full`; also `CLAUDINHO_FLAVOR`) |
79
115
  | `--no-markets` | hide prediction-market signals in `today`/`match` (also `CLAUDINHO_MARKETS=off`) |
80
116
 
81
- Team codes are 3-letter (FIFA/IOC-style): `MEX`, `BRA`, `USA`, `ENG`, …
117
+ Team codes: a nation's is FIFA-style, 3 letters (`MEX`, `BRA`, `USA`, `ENG`); a club's is the provider's abbreviation (`ARS`, `LEE`), and a club is also taken by name (`next Arsenal`).
82
118
 
83
119
  ### Commentary flair
84
120
 
85
- By default Claudinho narrates with a bit of localized football-broadcast energy —
86
- `¡GOOOOL!` on a goal, `¡a cancha llena!` before kickoff. These are generic,
87
- genre-style exclamations (no real commentator is quoted or impersonated),
88
- localized per `--lang`, and they never affect `--json` output.
121
+ By default Claudinho narrates with a bit of localized football-broadcast energy:
122
+ `¡GOOOOL!` on a goal, `¡a cancha llena!` before kickoff, something for the break,
123
+ the last ten minutes and a draw. The bank holds a few hundred lines in four
124
+ languages (genre exclamations and the catchphrases fans know; no real person is
125
+ named or impersonated), localized per `--lang`; a day's list never prints the
126
+ same line twice while the bank has another, and none of it reaches `--json`.
127
+
128
+ When one side has a rally cry of its own, the cry takes the slot instead, in
129
+ every language: Mexico's `¿Y si sí?`, Pumas' `¡Goya!`, Arsenal's `COYG!` (when
130
+ both sides have one, the team you pinned with `follow --team`, else the home
131
+ side's; `CLAUDINHO_TEAM` picks the team `next` asks about, not the cry). A row
132
+ with a cry takes no line from the bank, so the others in the list stay
133
+ different; a postponed or cancelled match prints neither.
89
134
 
90
- - `--flavor full` *(default)* — flair on fixtures, live play, goals, and full-time
91
- - `--flavor subtle` — only goals and full-time
92
- - `--flavor off` — just the facts
135
+ - `--flavor full` *(default)*: flair on fixtures, live play, goals, the break, the closing minutes, and full time
136
+ - `--flavor subtle`: only goals, full time and draws, and the rally cries
137
+ - `--flavor off`: just the facts
93
138
 
94
139
  ## Prediction-market signals
95
140
 
96
- `claudinho markets` shows **read-only** prediction-market signals — "who's favored" as
97
- market-implied percentages — for a date, a match, or a team's next fixture:
141
+ `claudinho markets` shows **read-only** prediction-market signals ("who's favored" as
142
+ market-implied percentages) for a date, a match, or a team's next fixture:
98
143
 
99
144
  ```bash
100
145
  claudinho markets # today's signals
@@ -105,7 +150,7 @@ claudinho markets today --json # structured sidecar output
105
150
  ```
106
151
 
107
152
  A short market line is also added under `claudinho today` and `claudinho match`
108
- when a reliable market is available. It's **informational only — not betting
153
+ when a reliable market is available. It's **informational only, not betting
109
154
  advice:** market-implied percentages with attribution, no trading, no links. Data
110
155
  comes from Polymarket public market data and is shown
111
156
  only when the market maps cleanly to the result and is fresh.
@@ -114,20 +159,20 @@ default-on `today`/`match` enrichment. `false` means the optional read did not
114
159
  finish and is paired with an explicit warning, not a confident empty result.
115
160
 
116
161
  Opt out with `--no-markets` (per command) or `CLAUDINHO_MARKETS=off` (global). The
117
- statusline and hook **never** show market data — it stays off the hot path.
162
+ statusline and hook **never** show market data: it stays off the hot path.
118
163
 
119
164
  > **How matches are matched:** event slugs are derived automatically from each
120
165
  > fixture (`fifwc-{home}-{away}-{date}`), so real signals appear for any match with a
121
- > live Polymarket market — no mapping needed (`mapping.2026.json` is for slug
166
+ > live Polymarket market, with no mapping needed (`mapping.2026.json` is for slug
122
167
  > *overrides* only). Matching fails closed, so an unmatched fixture simply shows
123
- > nothing — and finished matches never show one (market signals are pre-match
168
+ > nothing, and finished matches never show one (market signals are pre-match
124
169
  > and in-play reads). For an offline preview, set `CLAUDINHO_MARKETS_SOURCE=fake`
125
170
  > to render clearly-labeled synthetic **"demo data"** signals.
126
171
 
127
172
  ## Shareable snippets
128
173
 
129
174
  `claudinho share` prints a polished, **copy-pasteable** match card for chats,
130
- social posts, READMEs, and issue comments — your terminal football, ready to post:
175
+ social posts, READMEs, and issue comments: your terminal football, ready to post:
131
176
 
132
177
  ```bash
133
178
  claudinho share # today's matches
@@ -140,25 +185,28 @@ claudinho share 760415 # one match by id
140
185
  claudinho share next MEX --copy # …and copy it straight to the clipboard
141
186
  ```
142
187
 
143
- <!-- DEMO CARD: verbatim output of `claudinho share next MEX --tz America/Los_Angeles`.
144
- REGENERATE before release — the matchup advances each round and any market block
145
- drifts. Never hand-edit. -->
188
+ <!-- DEMO CARD: verbatim output of `claudinho --competition world-cup --tz UTC share next MEX`.
189
+ REGENERATE before release: the matchup advances each round and any market block
190
+ drifts. Never hand-edit. Re-rendered on 2026-10-05 (0.11) through the CLI's own
191
+ `share next MEX` command, offline: a provider double served the Round of 32 tie the
192
+ capture showed (Mexico vs Ecuador, on the bundled fixture's id, kickoff and venue),
193
+ at a frozen clock of 2026-06-28T12:00Z. -->
146
194
  ```text
147
- Next up for Mexico
195
+ Next up for Mexico · World Cup
148
196
 
149
197
  🇲🇽 Mexico vs Ecuador 🇪🇨
150
- Jun 30 · 18:00 America/Los_Angeles
198
+ Jul 1 · 01:00 UTC
151
199
  Estadio Banorte, Mexico City, Mexico
152
200
  Round of 32
153
201
 
154
202
  Live data: ESPN
155
- #VibingLaVidaLoca · Independent fan project · not affiliated with FIFA or Anthropic.
156
- Try it: npx @claudinho/cli next MEX
203
+ #VibingLaVidaLoca · Independent fan project · Not affiliated with FIFA, any confederation, league or club, or Anthropic.
204
+ Try it: npx @claudinho/cli --competition world-cup next MEX
157
205
  ```
158
206
 
159
- Snippets are **plain text** (no color codes — they paste cleanly everywhere) and
207
+ Snippets are **plain text** (no color codes: they paste cleanly everywhere) and
160
208
  carry the non-affiliation disclaimer on every paste. The market line uses the
161
- same reliable gate as `today`/`match` (**informational only — never betting
209
+ same reliable gate as `today`/`match` (**informational only, never betting
162
210
  advice**) and disappears when no reliable market exists. Per-command options:
163
211
 
164
212
  | Flag | Description |
@@ -172,11 +220,20 @@ advice**) and disappears when no reliable market exists. Per-command options:
172
220
  (`{ kind, snippet, matches, marketSignals, marketComplete, … }`) for scripts and
173
221
  future reuse. An incomplete optional market read is stated in the snippet and reported
174
222
  as `marketComplete: false`; it is never presented as a confident empty market result.
223
+ When the provider's knockout answer was not whole (a record it sent could not be read,
224
+ was a second copy of a fixture, or lay beyond the bound Claudinho reads), `next`,
225
+ `bracket` and their share cards say so before what was read, and `--json` carries
226
+ `partial` (`{ omitted }`, the count of provider records left out, when known): no fixture
227
+ is then not "eliminated". `today`, `live`, `match`, `markets` and their share cards do the
228
+ same for their own reads: an empty answer then says nothing was *read*, never that nothing
229
+ exists, and a World Cup day names the fixtures shown from the bundled schedule without
230
+ their live state (with no "Live data" line when none shown was served). Off the World Cup a day
231
+ the provider could not be asked for says so, never "no matches scheduled".
175
232
  No clipboard tool? `claudinho share … | pbcopy` works too.
176
233
 
177
234
  ### Want an image?
178
235
 
179
- The snippet is plain text, so a screenshot *is* your share card — or render one with an
236
+ The snippet is plain text, so a screenshot *is* your share card, or render one with an
180
237
  existing tool, e.g. `freeze --execute "claudinho share next MEX" -o card.png`
181
238
  (charmbracelet/freeze), `silicon`, or carbon.now.sh. Claudinho stays text-first:
182
239
  no bundled image renderer, no fonts or licensing to worry about.
@@ -192,15 +249,17 @@ The statusline reads from a local micro-cache and **never blocks on the
192
249
  network** (<150ms). When several matches are live it shows them all inline:
193
250
  `⚽ 🇳🇴 1–1 🇫🇷 87' · 🇸🇳 1–2 🇮🇶 86'`. Customize via env:
194
251
 
195
- - `CLAUDINHO_TEAM=MEX` — show only your team's match (a nation name works too, e.g. `CLAUDINHO_TEAM=mexico`); also the default team for `next`, `markets next`, and `share next` when the argument is omitted
196
- - `CLAUDINHO_MAX=2` — cap how many live matches show inline (rest collapse to exact `+N`
252
+ - `CLAUDINHO_TEAM=MEX`: your team's match first, the others counted (`+N`) (a nation name works too, e.g. `CLAUDINHO_TEAM=mexico`); also the default team for `next`, `markets next`, and `share next` when the argument is omitted. A team pinned with `claudinho follow <alias> --team <name>` does the same when this is not set, under its own competition (a pin is scoped to its competition, whatever chose it): a preference, never a filter
253
+ - `CLAUDINHO_MAX=2`: cap how many live matches show inline (rest collapse to exact `+N`
197
254
  after a complete cache scan, or `+more` when the bounded scan cannot know the count; default: 8,
198
255
  and values above 8 are capped at 8)
199
- - `CLAUDINHO_COMPACT=0` — show 3-letter codes alongside flags
200
- - `CLAUDINHO_FLAGS=off` — drop emoji flags for 3-letter codes (statusline) / plain names (`today`, `live`, `table`, `next`, hook); already automatic on terminals that can't render flag emoji, e.g. Warp
256
+ - `CLAUDINHO_COMPACT=0`: show 3-letter codes alongside flags
257
+ - `CLAUDINHO_FLAGS=off`: drop emoji flags for 3-letter codes (statusline) / plain names (`today`, `live`, `table`, `next`, hook); already automatic on terminals that can't render flag emoji, e.g. Warp
258
+
259
+ A background refresher writes that cache. Whenever no cache could be read (none, unreadable, or rejected), its attempts are paced by a small attempt record beside the throttle note, both named by scope like the cache itself (`attempt*.json`, `backoff*.json`: bare for the World Cup, `attempt.json`; with the source and competition for another, `attempt.espn.eng.1.json` for the Premier League): after each attempt the next waits one minute, the wait doubling to at most thirty, and only an attempt whose own cache then reads back resets it (a cache repaired by hand does not, so if it disappears again the retained wait applies). A rewrite repairs most of what can be at the cache path (a corrupted cache, a link, a file or a pipe whose own mode lets its owner read it, a file refused by an access-control list or owned by another user included; not a file marked immutable or append-only, a flag the refresher cannot see, which it treats exactly as it would without the flag: one that cannot be read as a cache and is not among the entries named next as beyond a rewrite has its attempts paced while the attempt record works, and repeated as before the record existed when it does not; one that reads as a cache never involves the record, so the refresher fetches whenever an update is due and never replaces it, as before); it cannot repair a directory, or anything but a link whose own mode denies its owner a read (a file or a pipe at mode 000, say: a rewrite keeps those mode bits), unless the directory's own inherited permissions let a new file at those bits be read, which is measured, not assumed. There, if the attempt record cannot be written or read either, the refresher asks nothing while the statusline keeps starting one on every update, until a rewrite could repair the cache path (the entry removed, its owner-read bit set, or the directory's inherited permissions letting a new file at those bits be read) or the attempt record works again; a cache file that merely opens is not enough (a mode-000 file with its own allow-read access-control entry opens, and a rewrite keeps its bits, not its entry). The same holds in a cache directory whose new files nobody can read (an inherited deny-read access-control list): no attempt asks or publishes anything (the refresher cannot read back its own lock), and the statusline keeps starting one on every update, until files in that directory can be read again.
201
260
 
202
261
  Use the same `claudinho prompt` in **tmux** (`set -g status-right '#(claudinho prompt)'`)
203
- or a **Starship** custom command — it works in any shell.
262
+ or a **Starship** custom command: it works in any shell.
204
263
 
205
264
  ### Score-aware Claude (hook)
206
265
 
@@ -219,7 +278,7 @@ claudinho init-cursor-statusline # patches ~/.cursor/cli-config.json (b
219
278
  claudinho init-cursor-statusline --print # just print the snippet
220
279
  ```
221
280
 
222
- Uses the same `claudinho prompt` hot path as Claude Code — so the same
281
+ Uses the same `claudinho prompt` hot path as Claude Code, so the same
223
282
  `CLAUDINHO_TEAM` / `CLAUDINHO_MAX` / `CLAUDINHO_COMPACT` customizations above apply
224
283
  here too. Cursor-specific tuning is applied automatically (`updateIntervalMs: 1000`,
225
284
  `timeoutMs: 1500`).
@@ -242,31 +301,32 @@ claudinho init-cursor-statusline --command "node ./packages/cli/dist/index.js pr
242
301
 
243
302
  ## How it works
244
303
 
245
- The full fixture list (104 matches, groups, venues, host cities, kickoffs) ships **bundled**
246
- in the package, so the common path is offline and instant. Only live match
247
- state hits the network. Live scores come from **ESPN's** public scoreboard (a
304
+ The World Cup's full fixture list (104 matches, groups, venues, host cities, kickoffs) ships
305
+ **bundled** in the package, so its schedule is offline and instant; the other competitions'
306
+ schedules are read from the feed, so `today` and `next` need the network there. Live match
307
+ state always hits the network. Live scores come from **ESPN's** public scoreboard (a
248
308
  swappable provider, attributed in output as `Live data: ESPN`) and market signals
249
309
  from Polymarket; provider attribution and rate limits are respected.
250
310
 
251
311
  ## Privacy Policy
252
312
 
253
- No personal data collected — no accounts, no telemetry, no analytics, no tracking, and no
313
+ No personal data collected: no accounts, no telemetry, no analytics, no tracking, and no
254
314
  Claudinho server. To show live results, the CLI makes read-only requests to public services
255
315
  (ESPN; Polymarket for informational-only market signals) with no account or personal data
256
316
  attached, though those services still receive standard request metadata (such as your IP
257
317
  address) like any HTTP call. It keeps a small cache of public match data in your local cache
258
318
  directory (`~/.cache/claudinho`, or `$XDG_CACHE_HOME/claudinho`), and the optional `init`
259
319
  commands update your Claude Code / Cursor settings file after saving a one-time
260
- `.claudinho.bak` backup — all on your machine, never uploaded. Full policy:
320
+ `.claudinho.bak` backup, all on your machine, never uploaded. Full policy:
261
321
  [PRIVACY.md](https://github.com/arturogarrido/claudinho/blob/main/PRIVACY.md).
262
322
 
263
323
  ## License
264
324
 
265
325
  MIT © 2026 Arturo Garrido · [source & issues](https://github.com/arturogarrido/claudinho)
266
326
 
267
- > **Not affiliated with, endorsed by, or connected to FIFA or Anthropic.** An independent,
327
+ > **Not affiliated with FIFA, any confederation, league or club, or Anthropic. Nor endorsed by or connected to any of them.** An independent,
268
328
  > open-source fan project showing factual match data (scores, fixtures, standings) with emoji
269
- > flags only — no logos, crests, kits, broadcast footage, or player likenesses.
329
+ > flags only: no logos, crests, kits, broadcast footage, or player likenesses.
270
330
 
271
331
  ---
272
332