feat: deck dropdown, user-decks pipeline, deckgen fixes, gpt-oss removal

- Add user-decks/ directory and USER_DECKS_DIR config for exported decks
- Update export-to-sim to write to user-decks/ with static mount in lab_api
- Replace import/paste UI with API-backed "My Decks" dropdown in LAN client
  and AI Lab, fetching from GET /api/lab/decks with source grouping
- Fix GET /api/lab/decks to JOIN deck_cards for totalCards count
- Fix deckgenerator: add missing DOM elements (dg-strategy-bar, dg-stats-bar,
  dg-card-groups) inside #dg-results, null guards on render functions,
  fix setLoading always hiding results
- Replace gpt-oss:20b with claude-opus-4-20250514 across all files
- Add user-decks/ to _BUILTIN_DECK_DIRS in deck_service.py
- Enrich missing type_line from Forge card cache in DB deck path
- Collapse import bar behind <details> toggle in AI Lab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
rgriffithandClaude Opus 4.6 committed 2026-04-05 01:17:30 -04:00
1 parent 409aba26f4
commit 9eaa41a4ae
23 files changed
+376 -152

No files matched your search

+21 -7
View File
@@ -142,11 +142,10 @@
<div class="dg-model-row">
<label class="dg-label">
AI Model
<span class="tip-icon" data-tip="The local LLM used to generate the deck list. Larger models produce better card selections but are slower. Requires Ollama running locally with the selected model pulled.">?</span>
<span class="tip-icon" data-tip="Deck generation is powered by Claude Opus 4, Anthropic's most capable model.">?</span>
</label>
<select class="dg-select" id="dg-model">
<option value="gpt-oss:20b" selected>gpt-oss:20b (Local Ollama)</option>
</select>
<input type="hidden" id="dg-model" value="claude-opus-4-20250514" />
<span style="font-size:0.8rem; color:var(--text-muted, #888);">claude-opus-4-20250514</span>
</div>
</div>
</div>
@@ -196,7 +195,7 @@
<!-- Loading State -->
<div class="dg-loading" id="dg-loading" style="display:none">
<div class="dg-spinner"></div>
<div class="dg-loading-text" id="dg-loading-text">Generating deck via Local AI...</div>
<div class="dg-loading-text" id="dg-loading-text">Generating deck via Claude Opus 4...</div>
</div>
<div class="dg-progress-wrap" id="dg-progress-wrap" style="display:none">
<div class="dg-progress-bar">
@@ -208,8 +207,23 @@
</div>
</div>
<!-- Results placeholder — rest generated dynamically by deckgenerator.js -->
<div class="dg-results" id="dg-results" style="display:none"></div>
<!-- Results -->
<div class="dg-results" id="dg-results" style="display:none">
<div class="dg-results-header">
<div id="dg-strategy-bar"></div>
<div id="dg-stats-bar" class="dg-stats-bar"></div>
<div id="dg-sub-summary" style="display:none"></div>
<div class="dg-result-actions">
<button class="dg-btn dg-btn-secondary" id="dg-regenerate-btn">&#8635; Regenerate</button>
<button class="dg-btn dg-btn-primary" id="dg-save-btn">&#128190; Save to Deck Builder</button>
<button class="dg-btn dg-btn-ghost" id="dg-export-csv">CSV</button>
<button class="dg-btn dg-btn-ghost" id="dg-export-dck">Forge .dck</button>
<button class="dg-btn dg-btn-ghost" id="dg-export-moxfield">Moxfield</button>
<button class="dg-btn dg-btn-ghost" id="dg-export-shopping">&#128722; Shopping</button>
</div>
</div>
<div id="dg-card-groups" class="dg-card-groups"></div>
</div>
</section>
</main>