feat: metagame workflows, sideboard workflows, Moxfield search (#49, #50)#59
feat: metagame workflows, sideboard workflows, Moxfield search (#49, #50)#59
Conversation
#50 Add MTGGoldfish, Spicerack, and Moxfield clients to the workflow server lifespan with feature-flagged initialization. Add _require_*() accessor functions. Create utils/fuzzy.py for archetype name matching. Add 7 stub tool wrappers (4 metagame, 3 sideboard) and 2 new prompts (explore_format, build_constructed_deck). Update tool count 60→67, prompt count 17→19. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… search (#49, #50) Phase 1 implementation across three parallel agents: - Metagame workflows (metagame_snapshot, archetype_decklist, archetype_comparison, format_entry_guide) - Sideboard workflows (suggest_sideboard, sideboard_guide, sideboard_matrix) - Moxfield expansion (search_decks, user_decks provider tools + MoxfieldDeckSummary/User/SearchResult models) 69 tools, 19 prompts. 1336 tests passing, 88% coverage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
69 tools, 19 prompts, 1336 tests. Add metagame/sideboard/moxfield tools to server instructions. Update ARCHITECTURE.md project structure and CLAUDE.md implementation status. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ools Update TOOL_DESIGN.md with 7 new workflow tools and 2 Moxfield tools. Add Moxfield search/user caches to CACHING_DESIGN.md. Add metagame, sideboard, and Moxfield search to smoke test skill (39→46 tests). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
archetype_decklist passed matched.slug (already format-prefixed from HTML) to get_archetype(), which prepended the format again creating "modern-modern-boros-energy". Fix: pass matched.name instead. moxfield search_users sent "q" parameter but the API expects "filter", causing HTTP 400. Fix: use correct parameter name. Also updates smoke test skill username to a known-good Moxfield account. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deduplicate three separate archetype fuzzy-matching implementations into the shared utils/fuzzy.py module. Add substring and word-overlap passes so it handles partial names and reordered words. Replace inline "4 Card Name" parsing in metagame.py with existing parse_decklist(). Cache card.name.lower() in sideboard suggest loop. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address all PR review findings: - Replace 10x `except Exception` with `except ServiceError` in metagame and sideboard workflows per CLAUDE.md convention - Fix archetype_comparison double-slug bug (arch.slug → arch.name) - Add Pydantic Field validators (ge=0, ge=1, min_length=1) to Moxfield types - Raise MoxfieldError on malformed _parse_search_result (consistent with _parse_deck) - Add structlog warnings for silent fallbacks in moxfield.py - Add 3 fuzzy matching tests (word overlap, substring, threshold boundary) - Add test_uses_name_not_slug_for_get_archetype to archetype_comparison tests - Fix test side_effects: RuntimeError/Exception → typed ServiceError subclasses - Fix overly broad test assertion in sideboard guide - Update TOOL_DESIGN.md: fix moxfield_search_decks/user_decks params, metagame_snapshot backends - Fix workflow docstrings (lifespan backends list, archetype_decklist claims) - Add sideboard_matrix to smoke test skill, update totals - Sort __all__ in types.py, remove duplicate SpicerackStanding entry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Claude encountered an error —— View job PR Review SummaryVerdict: APPROVE — solid implementation with two minor doc/test gaps worth addressing. Important Issues (should fix)1.
2. Integration conftest missing respx mocks for new Moxfield endpoints (confidence: 82)
# tests/integration/conftest.py — add inside the respx.mock block
respx.get(url__regex=re.escape(MOXFIELD_BASE) + r"/v2/decks/search").mock(
return_value=httpx.Response(
200, json=_load_json(MOXFIELD_FIXTURES / "search_decks.json")
)
)
respx.get(url__regex=re.escape(MOXFIELD_BASE) + r"/v2/users/search-sfw").mock(
return_value=httpx.Response(
200, json=_load_json(MOXFIELD_FIXTURES / "user_search.json")
)
)3.
Quick fix: expose Completeness
What's Good
|
|
All three findings addressed:
|
… signal - Add Moxfield section to SERVICE_CONTRACTS.md documenting /v2/decks/search and /v2/users/search-sfw endpoints with response shapes - Add respx mocks for both new Moxfield endpoints in integration conftest - Expose total_results in user_decks structured output; add truncation note to markdown when results exceed page size Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
metagame_snapshot,archetype_decklist,archetype_comparison,format_entry_guide) with MTGGoldfish primary / Spicerack fallbacksuggest_sideboard,sideboard_guide,sideboard_matrix) with heuristic category matching and MTGGoldfish enrichmentsearch_decks,user_decks) + 3 new Pydantic models (MoxfieldDeckSummary,MoxfieldUser,MoxfieldSearchResult)utils/fuzzy.pyfor archetype/matchup name matching (difflib.SequenceMatcher)explore_format,build_constructed_deck60 → 69 tools, 17 → 19 prompts. 1336 tests, 88% coverage.
Closes #49, closes #50.
Test plan
mise run check)mise run test:live)/smoke-test) for new metagame/sideboard/Moxfield tools🤖 Generated with Claude Code