Commit Graph
159 Commits
Author SHA1 Message Date
Lucas WintherandClaude Opus 5 e9f69ea8dc chore: update agents and skills for the parser-only pipeline
Removes the extraction-evaluator agent and reframes adapter-author around
reusing an existing site parser before writing a new one.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:11:08 +02:00
Lucas WintherandClaude Opus 5 3ea7286f56 docs: drop the LLM extraction layer, document multi-source ingestion
Event data is parsed deterministically; there is no model call, API key or
per-run cost anywhere in the pipeline. A source that cannot be parsed
deterministically gets no adapter rather than an inference fallback.

Documents the parser/adapter/merge split, records that Game8 uses three
page templates, and adds Neverness to Everness.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:11:08 +02:00
Lucas WintherandClaude Opus 5 493fc9f22a feat: merge events across multiple sources per game
Collapses the same event seen by two sources, matching on ID or on title
similarity plus start-date proximity. Proximity is the real guard against
false positives, since a rerun reuses its name months later.

Agreement from an independent source raises confidence; the same row seen
twice in one document does not. Disagreement on an end date is recorded as
a conflict for the review gate rather than averaged — splitting the
difference would publish a date neither source asserts.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:11:08 +02:00
Lucas WintherandClaude Opus 5 489ce92ef5 feat: add Game8 parser with Genshin and NTE adapters
Parsers are keyed by site template, not game: one Game8 parser serves
every Game8 page, and adapters bind a URL and game to a parser. Adding a
source for a known site is one SOURCES entry.

Game8 uses at least three templates. This handles label/value detail
tables (Genshin, 9 events) and column tables (NTE, 13 events). Its
image-grid schedule has no year and no end date, so Arknights: Endfield
is not supportable from that source and gets no adapter.

canParse is a structural tripwire: a site redesign fails the run loudly
instead of publishing an empty calendar that reads as "no events".

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:10:53 +02:00
Lucas WintherandClaude Opus 5 caefe6b0d7 feat: add HTML table reader and date parsing
Every date function returns null rather than inferring a missing year,
month or end date. A source that does not state an end yields
endsAt: null, never a plausible guess — a confidently wrong end date is
the failure this product exists to prevent.

Handles the three formats seen on Game8: "August 12, 2026",
"August 12 - September 21, 2026" (year applies to both ends, rolling the
start back when the range crosses New Year), and a slash datetime range.
Abbreviated months parse too, so a source switching to "Apr. 29" does not
silently drop events.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:10:53 +02:00
Lucas WintherandClaude Opus 5 e8293c7e8c feat: add GachaEvent schema and stable event IDs
Schema-level invariants enforce that endsAt is null exactly when
endPrecision is "unknown", and that regionEnds is populated exactly when
regionScoped is set, so an event object cannot be constructed in a state
the UI would misrender.

Event IDs double as localStorage keys on the client, so slugify() and
eventId() carry a warning: changing them orphans every user's completion
marks with no server-side recovery.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:10:35 +02:00
Lucas WintherandClaude Opus 5 3a1c604284 chore: add Bun + TypeScript project scaffolding
Bun is the runtime, bundler, test runner and SQLite driver, so zod is the
only dependency. Strict TS with noUncheckedIndexedAccess.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:10:35 +02:00
Lucas Winther 5db608563f Initial agent auxilliary files. 2026-08-14 23:45:35 +02:00
Lucas Winther 308f288e6a Initial commit 2026-08-14 23:27:06 +02:00