Diagnosed directly against a real generated spreadsheet the user
shared, rather than guessing:
- Player/opponent names came out blank ("- Necrons" instead of "John
Smith - Necrons"): fullName() takes the nested BCP user object
({firstName, lastName}), not the roster/teamplayer entry itself —
same convention main.js's own playerRowHTML() already follows, now
matched here via a shared nameOf() helper (with the same nickname
fallback playerRowHTML uses too).
- That cascaded into a worse, harder-to-spot bug: with the name blank,
a win-rate cell became literally " (62.5%)". Writes used
valueInputOption: USER_ENTERED, which smart-parses values — Sheets
read "(62.5%)" as accounting notation for a negative number and
silently replaced the cell with e.g. "-62.50%" instead of the
intended text. Same setting explains the "#ERROR!" cells: some raw
list text got parsed as a formula. Switched to RAW, which stores
exactly what's sent — correct for the plain descriptive labels this
writes, never intended to be interpreted.
- Lists with a New Recruit "+++...+++" header came through raw,
uncleaned: parseNRGW/parseNRTournament were vendored (needed for
NR_GW/NR_TOURMENT detectFormat() results) but never actually wired
into the format dispatch table, and aren't re-exported from the
package's own index.js (only from the internal modules/parsers.js,
which is now imported directly). Verified against the tool's own
NR-GW/NR-Tournament sample fixtures with real Node before committing
— both now correctly detected and cleaned.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SBzcNkW7JcYipnAX6HfgmK