Commit History
-
Fix JSearch v2 response path: body[data][jobs] not body[data]
Claude +1: Claude Sonnet 4.6Unverified signaturev2 nests the jobs list under data.jobs, not at data directly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMf6061fc -
Handle /search-v2 response structure (jobs vs data key)
Claude +1: Claude Sonnet 4.6Unverified signaturev2 API may return {jobs:[...]} instead of {data:[...]}. Try both keys and surface the actual response if neither matches so we can diagnose further. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMef593e7 -
Fix JSearch endpoint: /search → /search-v2 (API v5)
Claude +1: Claude Sonnet 4.6Unverified signatureRapidAPI upgraded JSearch to v5 which uses /search-v2 endpoint. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMcabab3d -
Surface JSearch API errors instead of silently returning empty
Claude +1: Claude Sonnet 4.6Unverified signatureReplace bare except:pass with proper error capture and re-raise so the frontend shows the actual API error (auth failure, quota exceeded, etc). Also reduce to 1 page per query to conserve free tier quota. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMe6083c5 -
Switch Job Market to JSearch (LinkedIn/Indeed/Glassdoor via RapidAPI)
Claude +1: Claude Sonnet 4.6Unverified signatureReplace Adzuna with JSearch which aggregates real LinkedIn, Indeed, and Glassdoor postings. Add RapidAPI key field to Settings Jobs tab. Backend fetches 10 job-type queries in parallel (~300 listings/run). Adzuna credentials remain stored but JSearch takes priority when set. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhM488bff1 -
Fetch listings across 10 job categories in parallel to bypass Adzuna per-query cap
Claude +1: Claude Sonnet 4.6Unverified signatureSingle query capped at ~250 results. Now fetches 10 categories simultaneously (IT, engineering, healthcare, sales, finance, etc.), up to 250 each, deduped by listing ID. Target sample size: 1000-2500 listings for meaningful counts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMe579644 -
Replace Gemini job analysis with fast pure-Python aggregation
Claude +1: Claude Sonnet 4.6Unverified signatureGemini was timing out analyzing 500 listings. Now company/title counts come from direct frequency counting, skills from a curated 60-skill keyword catalog matched against descriptions. Runs in milliseconds vs 60-120s. Gemini key no longer required for job insights. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMd051f98 -
Keep tab panels mounted to preserve state across tab switches
Claude +1: Claude Sonnet 4.6Unverified signatureAll four panels (analysis, chat, gurus, jobs) now stay mounted and are shown/hidden via CSS. Job Market data no longer resets when switching tabs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMf15d09d -
Fetch 10 pages (500 listings) in parallel for meaningful employer counts
Claude +1: Claude Sonnet 4.6Unverified signature3 pages only gave top employers 4 openings — not representative. 10 parallel pages (500 listings) give statistically meaningful frequency counts while keeping total fetch time the same (~10-15s) since all pages run concurrently. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMe026bc9 -
Speed up job insights: parallel Adzuna fetches, smaller Gemini payload
Claude +1: Claude Sonnet 4.6Unverified signatureReplace sequential 4-page Adzuna fetch with concurrent ThreadPoolExecutor (3 pages in parallel). Trim per-listing description from 300→150 chars and cap listings sent to Gemini at 150. Cuts total time from 120s+ to ~30-40s. Increase frontend timeout to 180s as safety margin. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMa8f2f5e -
Fix deprecated Gemini model names causing 404 errors
Claude +1: Claude Sonnet 4.6Unverified signatureMap gemini-2.0-flash and other deprecated models to gemini-2.5-flash so saved DB values don't break job insights or stock analysis. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhM7e3ba1a -
Fix tab overflow on mobile: scrollable tab bars in Settings and Dashboard
ClaudeUnverified signature4a9fdcd -
Add dedicated Jobs tab in Settings for Adzuna credentials
ClaudeUnverified signature784d1e0 -
Trigger rebuild: Job Market tab
ClaudeUnverified signaturefec2c97 -
Add Job Market tab: Adzuna + Gemini job insights with top companies, titles, skills
ClaudeUnverified signatureab1ad71
-
Add RELEASES.md and tag v1.0.0
ClaudeUnverified signature17c0f3a -
Fix: pass selectionVersion prop instead of key-remount so button state is never reset
ClaudeUnverified signaturec9f0545 -
Remove disabled state from Load/Refresh button entirely — always clickable
ClaudeUnverified signature52d5c76 -
Fix pending count leak: always call onDone even on cancelled requests; add 2min safety reset
ClaudeUnverified signature9febb29 -
Remount Gurus when Settings closes so selection changes take effect immediately
ClaudeUnverified signature7f8a05b -
Fix Refresh stuck: track pending count instead of setTimeout to clear loading state
ClaudeUnverified signature0b9e662 -
Fix Refresh button always disabled; increase logo and title size
ClaudeUnverified signature1213192 -
Fix NameError: cache_key should be guru_id in holdings cache write
ClaudeUnverified signaturea39117e -
Replace Soros (not on Dataroma) with Carl Icahn - Icahn Capital
ClaudeUnverified signatureaf3a53e -
Replace Dalio (not on Dataroma) with Daniel Loeb - Third Point
ClaudeUnverified signature92aa6d3 -
Add 10 new gurus, Settings Gurus tab with checklist to control which appear
ClaudeUnverified signaturefe67331 -
Replace yfinance with direct Yahoo Finance JSON API for prices
ClaudeUnverified signature20a2f69 -
Replace Druckenmiller with Tepper (not on Dataroma), fix yfinance NaN price
ClaudeUnverified signaturec5674d0 -
Remove % portfolio column, limit to top 10, fix Druckenmiller search terms
ClaudeUnverified signatureba5a3a4 -
Fix float('.') crash: require at least one digit in % regex
ClaudeUnverified signatured2ac5c6 -
Fix Dataroma parsing: dynamic code lookup, company names, % parsing
Claude +1: Claude Sonnet 4.6Unverified signatureThree bugs fixed: 1. Manager codes wrong for Ackman/Druckenmiller — now looks up codes dynamically by fetching Dataroma's managers.php and searching by name, so codes never go stale 2. Company name was showing ≡ (the ≡ icon in first <a> tag) — now skip single-char/entity links and take the actual company name from subsequent <a> tags 3. % of portfolio was 0 — Dataroma renders the number without a % sign, so now extract any decimal number from that cell Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMf7b4ac5 -
Fix Dataroma parser: use href s=TICKER anchor; larger logo
Claude +1: Claude Sonnet 4.6Unverified signatureDataroma's HTML uses s=TICKER in the href, not parentheses in the link text. Switch to anchoring on that URL param — reliable regardless of name format. Also strip HTML tags more robustly for name and numeric fields. Increase logo from 36px (w-9) to 48px (w-12). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhM6fe9f8e -
Replace SEC EDGAR scraping with Dataroma.com — fixes holdings permanently
Claude +1: Claude Sonnet 4.6Unverified signaturewww.sec.gov/Archives is Cloudflare-protected and returns HTML challenge pages to HuggingFace Spaces IPs. All SEC-direct strategies were failing. Switch to Dataroma.com, a public aggregator of SEC 13F filings that parses and hosts the same data without IP restrictions: - Scrape holdings table via httpx + regex (no new dependencies) - Re-enable all 3 gurus: Buffett (BRK), Ackman (PS), Druckenmiller (DFO) - Tickers come pre-populated from Dataroma, yfinance still used for current prices - Remove all dead SEC XML-parsing code, _sec_get, diagnostic endpoints Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhM2fd3eda
-
Switch SEC Archives from www.sec.gov to data.sec.gov to bypass IP block
Claude +1: Claude Sonnet 4.6Unverified signaturewww.sec.gov/Archives returns HTTP 200 with Cloudflare HTML (CAPTCHA) from HuggingFace Spaces IPs. data.sec.gov is the API subdomain and is not blocked. Switch all Archives file fetches to data.sec.gov. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhMad02731 -
Fix XML parse error: validate SEC response before parsing, log raw content
Claude +1: Claude Sonnet 4.6Unverified signatureWhen SEC returns an HTML error page instead of the infotable XML, we now detect it and raise a descriptive error showing the actual response body instead of an opaque 'mismatched tag' XML parse error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhM6342f75 -
Debug SEC 13F access: focus on Buffett, return all holdings, add /gurus/test
Claude +1: Claude Sonnet 4.6Unverified signature- Reduce to Buffett only while diagnosing www.sec.gov access from HuggingFace - Return ALL holdings (not just top 5) - Fix strategy ordering: all strategies now guard with `if not xml_url` - Add Strategy 1 using data.sec.gov filing index JSON (same host as submissions API) - Add /gurus/test endpoint that probes each SEC URL step-by-step and returns raw status codes/bodies - Update frontend label from "Top 5 Holdings" to "All Holdings" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WW3MiqTRBs13dJ1SDGJbhM819dc62 -
Switch SEC Archives from www.sec.gov to data.sec.gov (unblocked from HuggingFace)
ClaudeUnverified signature4a1b223 -
Add EFTS search strategy for infotable discovery (different host from Archives)
ClaudeUnverified signaturedfb6416 -
Gurus: load on button click, debug logging, stem-guess strategy for Berkshire XML
ClaudeUnverified signaturef303f93 -
Add SEC debug endpoint, extensive logging of each fetch step, strategy D/E fallbacks
ClaudeUnverified signaturede1023e -
Fix SEC infotable discovery: handle relative hrefs, target INFORMATION TABLE doc type, fix XML namespace parsing
ClaudeUnverified signature96a733a -
Add yfinance to requirements; fix infotable discovery via index HTML parsing
ClaudeUnverified signature9ee9347 -
Pre-warm guru cache on startup, increase timeout to 90s, better loading UX
ClaudeUnverified signatured9ecb58 -
Fix SEC EDGAR 503: add retry with backoff, fallback infotable filename guesses
ClaudeUnverified signature5dededd -
Add Guru Portfolios tab: SEC 13F holdings for Buffett, Ackman, Druckenmiller with live prices
ClaudeUnverified signature96048ad -
Embed logo as base64 in TS module to avoid HF binary file rejection
Claude2ba04f2 -
Add AlphaQ logo to header, replace icon with logo image
Claudee448046 -
Fix timestamp timezone: treat backend UTC datetimes as UTC, display in browser local time
Claudebd84d41 -
Simplify Chat Insights tab: single Last Week button, remove debug panels, rename tab
Claudee063e1a -
Fix PAREN_RE catching ETF/NAV in parentheses — apply ambiguous exclusion to () detection
Claude(ETF) and (NAV) appear in financial text as abbreviations (not tickers). Now parenthetical detection also checks AMBIGUOUS_TICKERS, and requires either a KNOWN_TICKERS match or 4+ char length for unknown words.946201e