GlidePath Money

Changelog

What’s new

Every release, what shipped, why. Newest first.

v0.5.13 Bank of America support + summary-block stripping for CSV imports

Pair with extension v0.4.6. Together they add Bank of America to the auto-capture pipeline.

What’s new

CSV summary-block stripping

BoA’s CSV export (despite being labeled “Microsoft Excel Format” in their UI — they killed the explicit CSV option) prepends 5 summary rows before the real transaction headers:

Description, , Summary Amt.
Beginning balance as of 11/25/2024, , 4,480.65
Total credits, , 277,139.29
Total debits, , -271,724.59
Ending balance as of 05/22/2026, , 9,895.35

Date, Description, Amount, Running Bal.    ← the real header (row 7)
...

ExtensionImportService now scans the first 20 lines of every CSV before parsing. If line 1 doesn’t look like a transactions header but a later line does, we skip ahead. Heuristic: a header-like row has 3+ non-empty fields and matches at least 2 of these keywords: date, amount/debit/credit, description/payee/merchant, balance/running bal, category. Generic enough to handle any bank with this pattern.

Bank of America added to the extension

bankofamerica.com is now a required host permission alongside Chase/Amex/Citi. The webRequest listener watches all bank URLs on those domains. BoA’s existing preset in ImportPresets.cs (Date, Description, Amount, Running Bal.) handles the format once the summary block is stripped.

The URL pattern is currently loose — once we see a real BoA download URL via the SW console (webRequest catches it), we’ll tighten the regex if needed.

How to update

Click Download on the orange update banner. Also reload the extension at chrome://extensions/ to v0.4.6.

v0.5.12 Rich context in the inbox cleanup panel

A UX follow-up to v0.5.11. The mapping architecture works, but if you have 8 Chase cards and 12 mystery inbox rows show up as “Browser Extension Inbox (Chase #XXXXX)”, you still have to remember which is which.

What’s new

Each inbox row now shows:

  • Bank page title at the moment of capture (e.g., “Chase Freedom Unlimited — Account Activity”)
  • Top 3 payees from the captured transactions (e.g., COSTCO GAS · COSTCO WAREHOUSE · STARBUCKS)
  • Date range of the batch (Apr 19 → May 21, 2026)
  • Transaction count (unchanged)

For most users this means glancing at a row and knowing “oh, that’s my Costco card” without going back to the bank tab.

How it works

  • Extension v0.4.3 captures document.title at the moment a blob is intercepted via the blob-hijack path (Amex, Citi). For Chase (which uses the re-fetch path), the existing filename has the last4 already, so page title is less critical there.
  • App v0.5.12 stores the title in the transaction’s Source field (alongside bank, bank_account_id) and GetInboxTransactionGroups extracts it for display. Also derives the top-3 payees and date range from each group.

How to update

Click Download on the orange update banner, then reload the GlidePath browser extension at chrome://extensions/ to v0.4.3.

v0.5.11 Stable-ID auto-routing for browser-extension imports

The big architectural fix for multi-card users. Until now, every browser-extension download landed in a catch-all “Browser Extension Inbox” account, and you had to manually figure out which card each batch came from. For users with 8 Chase accounts or 4 Citi cards, that’s untenable.

What changed

Extension v0.4.2 captures the bank’s download URL

A new fetch() hook in the MAIN-world content script watches every API call the bank’s page makes. When a CSV response comes back, the URL of that fetch is paired with the blob. Each bank’s URL encodes its own per-card identifier:

  • Chase: ?accountId=12345 query param
  • Amex: ?account_key=49C26F7C25DAC13F4EC0226CFC9EE118 (UUID)
  • Citi: /accounts/c13cfd58-bd01.../transactions/download (UUID in path)

These IDs are stable per card forever (banks don’t rotate them) — the perfect routing key.

App v0.5.11 maintains a mapping table

New file bank_account_mappings.csv in your data folder. Each row maps (Bank, BankAccountId) to your GlidePath AccountId. The import flow now checks this mapping first, then falls back to last4 matching, then to the catch-all inbox.

One-time setup per card

The first download from each card still lands in the inbox (because no mapping exists yet) — but it lands in a specific bucket with the card’s bank ID encoded in the name. E.g., Browser Extension Inbox (Chase #12345) for a Chase card whose accountId is 12345. When you use the inbox-cleanup tool to assign this to “Chase Freedom Unlimited”, the mapping is saved automatically. Future downloads from that card auto-route directly.

Expected user flow

  1. First refresh after upgrade: download CSVs from all your cards. Each lands in a distinct inbox bucket per card. Visit /Accounts, pick the target account for each, click “Move all” — that’s your one-time setup.
  2. Every refresh thereafter: blast through bank downloads, walk away. Open GlidePath, everything’s already on the right card.

If you ever close a card and open a new one (new bank-internal ID), the new card needs one more round of mapping. Otherwise: silent forever.

How to update

Click Download on the orange update banner, then also reload the GlidePath browser extension at chrome://extensions/.

v0.5.10 Multi-card routing: Account.Last4 match + bank-filtered inbox cleanup

If you have multiple cards from the same bank (e.g., 8 Chase accounts), the v0.5.8 inbox cleanup tool was a nightmare — every Chase download collapsed into one “Browser Extension Inbox (Chase)” bucket with no way to tell which card it came from, and the target-account dropdown showed all your accounts mixed together.

This release fixes that across three layers.

What changed

1. Account.Last4 field is now part of the routing match

ExtensionImportService previously matched only by AccountName.Contains(last4), which only worked for accounts whose name encoded the last-four (e.g., CHASE CC x6653). Accounts named Chase Freedom Unlimited or Amex EveryDay — which use the structured Last4 field instead — were ignored. Now the matcher checks Account.Last4 first (strict equality), with the substring match as a legacy fallback.

2. Extension paired with v0.4.1 — pulls the real Chase filename

Chase’s CSV export is server-named Chase{Last4}_Activity_YYYYMMDD.CSV — but chrome.downloads.onCreated fires before Chrome resolves that name, so the background worker was seeing an empty filename and falling back to a generic chase-export.csv. Now after the re-fetch, the background worker calls chrome.downloads.search() to get the resolved filename, then parses last4 from it. End result: most Chase downloads now route directly to the right card.

3. Inbox-cleanup dropdown filters by bank

On /Accounts, the “Re-route extension-import inbox” panel now scopes its target-account dropdown to the bank embedded in the inbox name. Moving “Browser Extension Inbox (Chase)” transactions only shows Chase accounts in the dropdown. Cuts cognitive load by roughly Nx where N is how many banks you use. The dropdown also surfaces the last4 next to each account name when it’s set in the structured field.

What’s still ahead

The Amex and Citi blob-hijack paths still don’t capture last4 — those banks’ URLs use opaque UUIDs and their filenames are generic. The next step (a separate session) is DOM-based detection: have the content script read the bank’s currently-selected card from the page before the download fires.

How to update

Click Download on the orange update banner. After upgrading, also reload the GlidePath browser extension at chrome://extensions/ to pick up the new filename-resolution code.

v0.5.9 Per-bank inbox names so the cleanup tool doesn't mix banks

A correctness follow-up to v0.5.8. When the browser extension imports without a matching last-four, the transactions land in a catch-all account. Previously every bank’s imports landed in the same one (“Browser Extension Inbox”), which meant the bulk-move tool couldn’t distinguish them — moving the inbox to your Citi card would pull in Chase and Amex transactions too.

What changed

  • ExtensionImportService now includes the matched preset’s bank name in the catch-all AccountName. New format: Browser Extension Inbox (Chase), Browser Extension Inbox (Citi), Browser Extension Inbox (Amex), etc. When an account_last4 was provided but didn’t match: Browser Extension Inbox (Chase ·1234).
  • The inbox-cleanup panel on /Accounts automatically picks up the new groupings — each bank shows as its own row with its own destination dropdown.

How to update

Click Download on the orange update banner.

v0.5.8 Bulk-move tool for extension/email inbox transactions

A natural follow-up to the browser-extension MVP. Imports from Amex, Citi, and any future POST-based bank land in catch-all accounts because we can’t auto-match them by last-four (the URLs use opaque account UUIDs instead). Until this release, the only way to fix that was to edit transactions.csv by hand.

What’s new

  • Bulk-move panel on /Accounts — shows up automatically when you have transactions sitting in any catch-all inbox (AccountId=0). For each inbox grouping, pick the target account from a dropdown and click “Move all” — every matching transaction is re-pointed in one save.
  • Hidden when empty — the panel disappears once you’ve cleaned out the inbox. No visual noise on a tidy account list.

Behind the scenes

DataService.GetInboxTransactionGroups() returns (InboxName, Count) tuples grouped by AccountName for any transactions where AccountId=0. DataService.RepointInboxTransactions(inboxName, toAccountId) does the actual move — rewrites transactions.csv in place, invalidates the in-memory cache, returns the count moved.

How to update

Click Download on the orange update banner.

v0.5.7 /Transactions: filter doesn't scroll to top anymore

A small but persistent annoyance: every time you tweaked the filters on /Transactions and clicked Filter, the page reloaded and scrolled back to the top, forcing you to scroll all the way down again to see your results. Fixed by anchoring each filter form to its panel.

How to update

Click Download on the orange update banner.

v0.5.6 Citi import preset + multi-column amount summing

Third bank added to the extension, plus a small refactor of the import math to handle a bank quirk that doesn’t fit the standard mapping vocabulary.

What’s new

  • Citi credit-card preset — recognizes the Status, Date, Description, Debit, Credit, Member Name header shape and routes imports correctly.
  • Multi-column amount summing: ApplyTransactionMapping (used by /Import) and ExtensionImportService.BuildLedgerTransactions (used by the browser extension) now sum across every column mapped to “Amount (inflow)” or “Amount (outflow)” — previously each role was found at most once. This was needed because Citi puts payments as a NEGATIVE value in its Credit column. Mapping both Debit AND Credit to outflow produces amount = -(Debit + Credit), which correctly inverts: purchases become negative (expense) and Citi’s already-negative payments become positive (inflow). No behavior change for existing presets — they map each role to one column.

Browser extension changes

  • v0.3.3 of the extension adds Citi to BANK_PATTERNS and a citi.js content-script stub. URL pattern: online.citi.com/gcgapi/.../cbol/accounts/<UUID>/transactions/download.
  • Citi exports as Since {Date}.csv with no card identifier in the filename, so imports land in the Browser Extension Inbox account. Re-route once after first import.

How to update

Click Download on the orange update banner, or grab the installer from downloads.glidepathmoney.com.

v0.5.5 Amex import preset + URL-based disambiguation

A correctness fix for Amex imports via the browser extension. Before this release, Amex CSVs were silently matched as Wells Fargo because both exports have Date, Amount, Description columns. The two banks use opposite sign conventions — Amex shows purchases as POSITIVE (the amount you owe), while Wells Fargo / GlidePath expect purchases as NEGATIVE — so imports landed with inverted amounts (purchases showed as income).

What’s fixed

  • New American Express preset with Amount → Amount (outflow) mapping, which inverts the sign on the way in. Purchases now correctly land as negative (expense), payments as positive (inflow to card).
  • URL-based preset disambiguation: when an import carries a source URL (browser-extension uploads always do), presets tagged with matching UrlPatterns win over header-only matches. Amex is tagged with americanexpress.com; Wells Fargo with wellsfargo.com.
  • Header-only fallback unchanged for manual /Import page uploads — no behavior change for users importing CSVs directly from disk.

If you imported Amex via the extension before this release

The 3-ish wrong-sign transactions in your “Browser Extension Inbox” account need to be deleted and re-imported. After upgrading:

  1. Go to /Transactions, filter to the Browser Extension Inbox account
  2. Find the Amex rows (recognizable by their description format with city/state suffixes)
  3. Delete them
  4. Re-trigger the same Amex CSV download via the extension — they’ll re-import with correct signs

How to update

Click Download on the orange update banner, or grab the installer from downloads.glidepathmoney.com.

v0.5.4 Browser-extension endpoint goes live

This release is the app-side half of the browser-extension integration. By itself, v0.5.4 doesn’t change anything visible — but once you install the extension (Chrome Web Store submission coming), it can send bank CSV exports straight to your local install without you touching the file system.

What’s new

  • POST /api/import-from-extension endpoint — accepts a multipart upload (file + optional account_last4 + optional source_url), runs it through the same auto-detect + dedup-aware import pipeline as the /Import page, and returns JSON with the import result. Same security model as the rest of the app: localhost-only, no auth needed because the app runs on your machine.

How it works

The extension watches for transaction CSV downloads on supported bank sites (Chase first). When it sees one, it re-fetches the same URL with your session cookies (which never leave your browser) and POSTs the bytes to http://localhost:5000/api/import-from-extension. GlidePath auto-detects the bank format, matches the right account by last-four, and runs your normal dedup + categorize flow.

The actual CSV still lands in your Downloads folder as a backup — if the extension can’t reach your install (app not running, etc.), you can always drop the file into the extension popup manually.

How to update

Click Download on the orange “Update available” banner, or grab the installer from downloads.glidepathmoney.com.

v0.5.3 Belt-and-suspenders fix for the post-upgrade data folder

A second pass at the data-disappears-after-upgrade bug. v0.5.2 made the installer launch the app as the user account (not the elevated admin context). That’s necessary but not sufficient — the spawned process still inherits the elevated installer’s sanitized environment, which lacks the user’s persistent env vars.

What’s fixed

  • App reads GLIDEPATHMONEY_DATA_FOLDER directly from the user-scope env source (Windows: HKCU\Environment) if the process inherited environment doesn’t have it. The variable is still set at the OS level whenever the user has configured it — Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.User) reads it from there directly, bypassing process inheritance entirely. End result: even if the installer’s auto-launch hands the new process a stripped environment, the app still finds the right data folder.

Who this affects

Only customers who explicitly set a GLIDEPATHMONEY_DATA_FOLDER env var to override the default %LocalAppData%\GlidePath Money\data location. For everyone else, behavior is unchanged — the default LocalAppData path is used as before.

How to update

Click Download on the orange “Update available” banner in your dashboard, or grab the latest installer from downloads.glidepathmoney.com. Cache is freshly purged; you’ll get v0.5.3 immediately, no waiting.

v0.5.2 Installer fix — your data stays put after upgrade

A small but important bugfix.

What’s fixed

  • Installer no longer “loses” your data on upgrade. Previous installers (v0.4.0–v0.5.1) ran with UAC elevation — which is necessary for the firewall + tunnel-service install — and the auto-launch step at the end inherited that elevated environment. For customers using a custom GLIDEPATHMONEY_DATA_FOLDER env var to point the app at a non-default data location, the elevated process didn’t see the user-level env var and fell back to %LOCALAPPDATA%\GlidePath Money\data. Visible symptom: dashboard reported “Welcome to GlidePath Money” after upgrade as if it was a fresh install. Real data was safe the whole time; the app was just reading the wrong folder. v0.5.2’s installer drops privileges back to the user account before launching the app, so the env is correct from the first click.

How to update

Click Download on the orange “Update available” banner in your dashboard, or grab the latest installer from downloads.glidepathmoney.com. The installer detects upgrades automatically and preserves your existing tunnel, license, and data.

v0.5.1 Plan Inputs is friendlier — a guide for where each number comes from

A small but high-impact follow-up to v0.5.0. The retirement plan inputs form has ~25 fields, most of which are esoteric for a first-time user — what’s “Pre-retirement return”? Where do I find my “SS at FRA”? What’s a “Solo spending ratio”? This release fixes the overwhelm.

What’s new

  • New ”📖 Where these numbers come from” guide at the top of the Plan Inputs tab. Groups inputs by source: retirement balances → log into your 401(k) provider (Fidelity / Vanguard / Empower / etc.), Social Security → ssa.gov/myaccount, pension → your employer’s benefits portal, ACA → healthcare.gov for a real silver-plan quote. Open by default for first-time users; collapses once you’ve gathered everything.
  • Richer inline hints under cryptic fields. “SS / month” now says “benefit at FRA from ssa.gov/myaccount” with a direct link. Return assumptions explain the defaults (6-8% pre-retirement, 4-6% post-retirement, 12% volatility, 3% inflation — and what those numbers represent). Annual spending shows the 70-85%-of-current rule of thumb. Pension explicitly notes “0 if you don’t have one.” ACA benchmark links to healthcare.gov/see-plans.

How to update

Click Download on the orange “Update available” banner in your dashboard, or grab the latest installer from downloads.glidepathmoney.com. The installer detects upgrades automatically and preserves your existing tunnel, license, and data.

v0.5.0 Planning, made personal — benchmarks, recommendations, and a page you can actually read

A significant UX release. The retirement planner now answers the questions customers actually have (“Am I on track? What should I do?”) in plain English, supports single-person households as a first-class case, and is organized so you can find what you need without scrolling for a mile.

What’s new

  • Peer-comparison anchors. New “Are you on track for age X?” panel on /Retirement uses Fidelity’s published savings-multiple benchmarks (1× income by 30, 3× by 40, 6× by 50, 8× by 60, 10× by 67) and tells you exactly where you stand vs. the curve. New “Stanley-Danko net-worth benchmark” on /NetWorth uses the Millionaire Next Door formula — (age × income) ÷ 10 — and labels you as Prodigious / Average / Below Average / Under Accumulator with a one-word status (Excellent / Good / Catch up / Far behind). Both anchor your raw numbers against something meaningful.
  • Single-person mode. New Household type toggle on /Retirement (Joint or Single). Toggling to Single hides all spouse fields, switches the tax math to single-filer brackets ($14,600 standard deduction, harsher brackets than MFJ), suppresses the Spousal & Survivor panel entirely, and adjusts the ACA FPL base from 2-person to 1-person. The planner is now genuinely usable for single, widowed, and divorced households — not just married couples.
  • “What would help most?” recommendation engine. After the Monte Carlo runs, GlidePath now re-runs it with each of four levers individually applied (increase 401(k) contributions by $2,000/yr, delay retirement by 1 year, cut planned spending by 5%, delay Social Security claim by 2 years) and surfaces the biggest improvement to your success probability. With reasoning, not just a number. Three other ranked levers under “Other levers worth considering.”
  • Plain-English narrative summary. New paragraph at the top of /Retirement synthesizes the math into a one-paragraph human read: where you stand (strong / workable / concerning), your biggest single lever, and your Tax Valley opportunity. Generated from your numbers, not boilerplate.

A better page layout

  • /Retirement is now tabbed. The narrative summary + 4 headline stat-cards (Success Probability, Median Nest Egg, Median Final Balance, Funds Last Until) stay visible as your “vitals” no matter what. Below that, 5 thematic tabs split the rest: Overview (peer benchmark + biggest lever), Social Security (claim scenarios + spousal/survivor + retire-vs-claim strategy), Tax & Health (Tax Valley + ACA bridge), Projections (portfolio chart + milestones + year-by-year), and Plan Inputs (the editable form + 401(k) details). Each tab now fits on one screen.
  • /NetWorth got the same treatment. Three tabs: Overview (benchmark + multi-year trend), Movers (by-account-type + biggest movers this month + 12-month movers), All accounts (the full per-account table). Vitals row stays at the top.
  • Deep-linkable. Each tab updates the URL, so app.glidepathmoney.com/Retirement#tax opens straight to Tax & Health. Back/forward buttons work.

Quality of life

  • Installer upgrade is smoother. Previous versions could hit a “Setup was unable to automatically close all applications” dialog mid-upgrade because the running GlidePath process didn’t have a main window for Windows’ restart manager to talk to. v0.5.0’s installer now stops the running process itself before file replacement. One-click upgrades from this release forward.
  • New “Annual household income” input on /Retirement powers both peer benchmarks. Unset = the benchmarks politely nudge you to set it; set = the benchmark cards populate automatically.

How to update

Click Download on the orange “Update available” banner in your dashboard, or grab the latest installer from downloads.glidepathmoney.com. The installer detects upgrades automatically and preserves your existing tunnel, license, and data.

v0.4.0 Email inbox, one-click backups, and friendlier first runs

The biggest functional release since launch. Two headline features and a polish pass.

What’s new

  • Email inbox. Forward your bank’s transaction-alert emails to a private inbox address (e.g. yourname-inbox@glidepathmoney.com) and the transactions auto-appear in /Transactions within ~5 minutes. Setup recipes for Chase, Bank of America, Discover, Citi, American Express, and Capital One live on the new /EmailInbox page under Setup. The parser discards the email body the moment it extracts the transaction details — local-first holds.
  • One-click backups. New /Backup page: one click to .zip your entire data folder; one click to restore from any prior backup. Restore automatically takes a “pre-restore” safety snapshot first, so you can’t accidentally clobber newer data by restoring an older zip. Drop the backups/ folder into OneDrive, Dropbox, or Google Drive for continuous off-PC mirroring.

Improvements

  • Friendlier file imports. /Import shows visual feedback during drag-drop and detects which bank’s CSV format you’ve dropped before you click Upload.
  • No more black console window at startup. The app now runs as a Windows GUI process — internal logging still works, it just doesn’t pop a visible terminal.
  • FAQ refresh. New entries on /help: “Do I have to drop Simplifi or Monarch to use this?”, “How do I back up my data?”, and “What if you go out of business?”.

Under the hood

  • The installer writes license.json to your data folder so the app knows its own identity at startup (used by the email-inbox poller and the EmailInbox UI).
  • New internal API endpoint speeds up our turnaround when investigating email-parsing edge cases.

How to update

Click Download on the orange “Update available” banner in your dashboard, or grab the latest installer from downloads.glidepathmoney.com. The installer detects upgrades automatically and preserves your existing tunnel, license, and data.