From 99e29a5803b4ba397cabfca599297ceaf66e4cfc Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 12:16:53 +0000 Subject: [PATCH 1/3] v2.0.2: deploy to GitHub Pages on merge to master Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013Z8iBUNj6C627mxmm1CurV --- .github/workflows/pages.yml | 60 +++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 11 +++++++ CLAUDE.md | 17 +++++++++-- README.md | 4 +-- index.html | 2 +- js/views-settings.js | 2 +- 6 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/pages.yml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..4c81277 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,60 @@ +name: Deploy to GitHub Pages + +# Publishes the app on every push to master (i.e. after a PR is merged), or by +# hand from the Actions tab. Pull requests never deploy. +# +# Before the first run: Settings → Pages → Build and deployment → Source: +# "GitHub Actions". Without it, this workflow fails at the deploy step. +on: + push: + branches: [master] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +# One deploy at a time; a newer push waits rather than cancelling a deploy mid-way. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + name: Build site + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + # Publish only what the app needs. docs/, CLAUDE.md, tests and CI files + # stay in the repo but are not served. + - name: Assemble site + run: | + mkdir -p _site + cp index.html _site/ + cp -r js samples _site/ + touch _site/.nojekyll + echo "Published files:" && find _site -type f | sort + - name: Refuse to publish data files + run: | + if find _site -iname 'finlens-state*.json' -o -iname 'finlens-export-*' -o -path '*/data/*' | grep -q .; then + echo "::error::A data or backup file is in the site folder. Nothing was published." + exit 1 + fi + - uses: actions/configure-pages@v5 + - uses: actions/upload-pages-artifact@v3 + with: + path: _site + + deploy: + name: Deploy + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index a41488d..f9b87a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). --- +## [2.0.2] — 2026-11-04 + +### Technical — Hosting +- **Deploy to GitHub Pages** (`.github/workflows/pages.yml`). On every push to `master` (after a merge), or by hand from the Actions tab, the app is published as static files to `https://gitluis.github.io/finlens/` (later, the custom domain). Pull requests never deploy. Nothing in the app changes. + - **Only the app is published:** `index.html`, `js/` and `samples/`. `docs/`, `CLAUDE.md`, tests and CI files aren't served. The build refuses to publish if a `finlens-state*.json`, export or `data/` file is in the site folder. + - **Before the first run:** Settings → Pages → Source: **GitHub Actions**. +- **CLAUDE.md §22 Hosting (new):** what's served, the one-site-per-origin rule (all of an account's Pages sites share `.github.io`, so publish no other Pages site until FinLens has its own domain), custom-domain setup, and the Pages limits (no custom headers, so CSP stays a `` tag). +- Part of the **v2.0 — Public launch** milestone. Left open on purpose until the rename and custom domain are ready. + +--- + ## [1.10.5] — 2026-11-02 ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md index d895c1b..f691af0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -59,7 +59,7 @@ Until then, this section is the rule. FinLens is a **single-origin, zero-build, vanilla JavaScript personal finance dashboard** that runs entirely in the browser. There is no server, no npm, no bundler, no framework, and no TypeScript. The entry point is `index.html`; everything else is a plain `.js` file in the `js/` folder. -**Current version:** v1.10.5 (updated in `index.html` footer, `README.md`, and `CHANGELOG.md` on every release). +**Current version:** v2.0.2 (updated in `index.html` footer, `README.md`, and `CHANGELOG.md` on every release). **What it does:** Imports CSV exports from Ally Bank (Checking + Savings) and Chase credit cards, parses and normalizes them into a unified transaction model, and renders a multi-tab financial dashboard with budgeting, debt tracking, savings forecasting, investment planning, and Claude-powered AI analysis. @@ -798,7 +798,7 @@ Multiple Chase card files can be loaded simultaneously. Each gets a unique `acco --- -*Last updated: v1.10.5 — 2026-11-02 (no section changes: Import Logs race fix; v1.10.4: §8, §13 single `~` is literal; §21 excerpts escape `~`; v1.10.3: §13 refusals; §21 declined runs; v1.10.2: §13 summary states its dates; §21 per-month derivations; v1.10.1: §13 `AI_MAX_TOKENS`, thinking and cut-off answers; v1.10.0: §21 AI Eval added; §13 `callClaude()` raw mode; v1.9.6: §14 folder access lasts until the last tab closes, not one page load; v1.9.5: §7 chart guard; v1.9.4: views-db.js changelog reads CRLF checkouts; v1.9.3: §14 folder permission: re-request on click, Reconnect banner, browser copy wins; v1.9.2: §0 branch, PR and approval workflow added; v1.9.1: §4.5 rehydrate transactions loaded from JSON; v1.9.0: §20 Data & Reset added; v1.8.1: §10 re-upload dedup rewritten for the occurrence-suffix fix; v1.8.0: AI Analysis restored with API-key and output hardening; `renderMarkdown()` added; `samples/` added; §1–3, §13, §14, §17 corrected to match the code)* +*Last updated: v2.0.2 — 2026-11-04 (§22 Hosting added; v1.10.5 — 2026-11-02: no section changes: Import Logs race fix; v1.10.4: §8, §13 single `~` is literal; §21 excerpts escape `~`; v1.10.3: §13 refusals; §21 declined runs; v1.10.2: §13 summary states its dates; §21 per-month derivations; v1.10.1: §13 `AI_MAX_TOKENS`, thinking and cut-off answers; v1.10.0: §21 AI Eval added; §13 `callClaude()` raw mode; v1.9.6: §14 folder access lasts until the last tab closes, not one page load; v1.9.5: §7 chart guard; v1.9.4: views-db.js changelog reads CRLF checkouts; v1.9.3: §14 folder permission: re-request on click, Reconnect banner, browser copy wins; v1.9.2: §0 branch, PR and approval workflow added; v1.9.1: §4.5 rehydrate transactions loaded from JSON; v1.9.0: §20 Data & Reset added; v1.8.1: §10 re-upload dedup rewritten for the occurrence-suffix fix; v1.8.0: AI Analysis restored with API-key and output hardening; `renderMarkdown()` added; `samples/` added; §1–3, §13, §14, §17 corrected to match the code)* --- @@ -883,3 +883,16 @@ A developer-only view (`showView('ai-eval')`) that measures how well AI Analysis - **Publishing a new run:** move the current `docs/EVAL.md` and `docs/eval-results.json` to `docs/eval-runs/v/` unchanged except for a one-line "Archived" banner, its JSON link label, and relative links the move would break (`eval-runs/vX/…` becomes `../vX/…`). Put the new results JSON in `docs/`, generate EVAL.md by loading it in the view (**Load results JSON** → **Download EVAL.md**), then add the hand-written sections before *Method*: the **Runs** table (one column per run: `max_tokens`, cut-off answers, tokens, figures, grounded, derived, traceable, unsupported), what changed between runs, and *Changes made after the run*. Keep README's Evaluation numbers in step. - **Changing the matcher after a run:** fix only bugs against the method EVAL.md states. Record each fix in EVAL.md's "Changes made after the run" with before and after numbers. Never add a rule just because it raises the score on answers you've already seen. - **Classification** (`classifyText()`): grounded → explicit equation (a wrong one is a math error) → standard derivations (`_candidates()`, each with context keys) → restatements, correct equations and same-line arithmetic on anchored figures → forecast (the 12-month prediction prompt only) or unsupported. When adding a derivation, give it context keys; check the chance-match rate in the report doesn't rise noticeably — it is the matcher's false-positive rate and is published alongside the headline. + +--- + +## 22. Hosting (GitHub Pages) + +FinLens is published as static files by `.github/workflows/pages.yml` on every push to `master`. Pull requests never deploy. + +- **What's served:** `index.html`, `js/` and `samples/` only. `docs/`, `CLAUDE.md`, tests and CI files stay in the repo but aren't published. The build refuses to publish if a `finlens-state*.json`, export or `data/` file ends up in the site folder. +- **Nothing about the data changes.** Pages only serves the code. Transactions, settings and the API key stay in the visitor's browser and folder, as in §4.5 and §14. +- **One site per origin.** Browsers keep IndexedDB and localStorage per origin (scheme + host + port), not per path. All Pages project sites of one account share `https://.github.io`, so any other repo published there could read FinLens's data. Until FinLens has its own domain, **publish no other Pages site from this account**. +- **Custom domain:** set it on this repo (Settings → Pages), not on a `.github.io` user-site repo, and verify it in the account settings. With an Actions deploy no `CNAME` file is needed. Moving to a new domain is a new origin, so browser data starts empty there: users reconnect their folder or re-import once. +- **No custom headers.** Pages can't send HTTP headers, so the Content Security Policy must stay a `` tag, and `frame-ancestors` (which only works as a header) isn't available. +- **The File System Access API works there**, because Pages is served over HTTPS (a secure context). diff --git a/README.md b/README.md index 1cd3fc5..c911014 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > A zero-install, browser-native finance dashboard. Drop in your bank CSVs, get instant clarity on your money. -**Version:** v1.10.5  ·  **Stack:** Vanilla JS, HTML, CSS  ·  **Install:** None +**Version:** v2.0.2  ·  **Stack:** Vanilla JS, HTML, CSS  ·  **Install:** None --- @@ -260,4 +260,4 @@ See [CHANGELOG.md](CHANGELOG.md) for the full release history. --- -*FinLens v1.10.5 — Built for one person's finances, designed to be useful for anyone's.* +*FinLens v2.0.2 — Built for one person's finances, designed to be useful for anyone's.* diff --git a/index.html b/index.html index ee48405..ba961ed 100644 --- a/index.html +++ b/index.html @@ -326,7 +326,7 @@
⚙️ Settings
diff --git a/js/views-settings.js b/js/views-settings.js index 6f7d389..c22e8eb 100644 --- a/js/views-settings.js +++ b/js/views-settings.js @@ -49,7 +49,7 @@ function _renderGeneralSettings(root) { -
FinLens v1.10.5 ·${State.transactions.length} transactions loaded${State.lastRefresh?' · Refreshed '+dayjs(State.lastRefresh).format('MMM D, YYYY h:mm A'):''}
`; +
FinLens v2.0.2 ·${State.transactions.length} transactions loaded${State.lastRefresh?' · Refreshed '+dayjs(State.lastRefresh).format('MMM D, YYYY h:mm A'):''}
`; root.appendChild(displayCard); /* ---- Anthropic API Key ---- */ From 7c06029c89f95cc6b56956f321cddf3043304d30 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 13:01:19 +0000 Subject: [PATCH 2/3] Renumber to v2.0.3: the rename PR (#58) takes v2.0.2, so versions follow the merge order Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013Z8iBUNj6C627mxmm1CurV --- CHANGELOG.md | 2 +- CLAUDE.md | 4 ++-- README.md | 4 ++-- index.html | 2 +- js/views-settings.js | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9b87a6..052024c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). --- -## [2.0.2] — 2026-11-04 +## [2.0.3] — 2026-11-04 ### Technical — Hosting - **Deploy to GitHub Pages** (`.github/workflows/pages.yml`). On every push to `master` (after a merge), or by hand from the Actions tab, the app is published as static files to `https://gitluis.github.io/finlens/` (later, the custom domain). Pull requests never deploy. Nothing in the app changes. diff --git a/CLAUDE.md b/CLAUDE.md index f691af0..76b1e2a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -59,7 +59,7 @@ Until then, this section is the rule. FinLens is a **single-origin, zero-build, vanilla JavaScript personal finance dashboard** that runs entirely in the browser. There is no server, no npm, no bundler, no framework, and no TypeScript. The entry point is `index.html`; everything else is a plain `.js` file in the `js/` folder. -**Current version:** v2.0.2 (updated in `index.html` footer, `README.md`, and `CHANGELOG.md` on every release). +**Current version:** v2.0.3 (updated in `index.html` footer, `README.md`, and `CHANGELOG.md` on every release). **What it does:** Imports CSV exports from Ally Bank (Checking + Savings) and Chase credit cards, parses and normalizes them into a unified transaction model, and renders a multi-tab financial dashboard with budgeting, debt tracking, savings forecasting, investment planning, and Claude-powered AI analysis. @@ -798,7 +798,7 @@ Multiple Chase card files can be loaded simultaneously. Each gets a unique `acco --- -*Last updated: v2.0.2 — 2026-11-04 (§22 Hosting added; v1.10.5 — 2026-11-02: no section changes: Import Logs race fix; v1.10.4: §8, §13 single `~` is literal; §21 excerpts escape `~`; v1.10.3: §13 refusals; §21 declined runs; v1.10.2: §13 summary states its dates; §21 per-month derivations; v1.10.1: §13 `AI_MAX_TOKENS`, thinking and cut-off answers; v1.10.0: §21 AI Eval added; §13 `callClaude()` raw mode; v1.9.6: §14 folder access lasts until the last tab closes, not one page load; v1.9.5: §7 chart guard; v1.9.4: views-db.js changelog reads CRLF checkouts; v1.9.3: §14 folder permission: re-request on click, Reconnect banner, browser copy wins; v1.9.2: §0 branch, PR and approval workflow added; v1.9.1: §4.5 rehydrate transactions loaded from JSON; v1.9.0: §20 Data & Reset added; v1.8.1: §10 re-upload dedup rewritten for the occurrence-suffix fix; v1.8.0: AI Analysis restored with API-key and output hardening; `renderMarkdown()` added; `samples/` added; §1–3, §13, §14, §17 corrected to match the code)* +*Last updated: v2.0.3 — 2026-11-04 (§22 Hosting added; v1.10.5 — 2026-11-02: no section changes: Import Logs race fix; v1.10.4: §8, §13 single `~` is literal; §21 excerpts escape `~`; v1.10.3: §13 refusals; §21 declined runs; v1.10.2: §13 summary states its dates; §21 per-month derivations; v1.10.1: §13 `AI_MAX_TOKENS`, thinking and cut-off answers; v1.10.0: §21 AI Eval added; §13 `callClaude()` raw mode; v1.9.6: §14 folder access lasts until the last tab closes, not one page load; v1.9.5: §7 chart guard; v1.9.4: views-db.js changelog reads CRLF checkouts; v1.9.3: §14 folder permission: re-request on click, Reconnect banner, browser copy wins; v1.9.2: §0 branch, PR and approval workflow added; v1.9.1: §4.5 rehydrate transactions loaded from JSON; v1.9.0: §20 Data & Reset added; v1.8.1: §10 re-upload dedup rewritten for the occurrence-suffix fix; v1.8.0: AI Analysis restored with API-key and output hardening; `renderMarkdown()` added; `samples/` added; §1–3, §13, §14, §17 corrected to match the code)* --- diff --git a/README.md b/README.md index c911014..4201e68 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > A zero-install, browser-native finance dashboard. Drop in your bank CSVs, get instant clarity on your money. -**Version:** v2.0.2  ·  **Stack:** Vanilla JS, HTML, CSS  ·  **Install:** None +**Version:** v2.0.3  ·  **Stack:** Vanilla JS, HTML, CSS  ·  **Install:** None --- @@ -260,4 +260,4 @@ See [CHANGELOG.md](CHANGELOG.md) for the full release history. --- -*FinLens v2.0.2 — Built for one person's finances, designed to be useful for anyone's.* +*FinLens v2.0.3 — Built for one person's finances, designed to be useful for anyone's.* diff --git a/index.html b/index.html index ba961ed..e5e2b5c 100644 --- a/index.html +++ b/index.html @@ -326,7 +326,7 @@
⚙️ Settings
diff --git a/js/views-settings.js b/js/views-settings.js index c22e8eb..548313e 100644 --- a/js/views-settings.js +++ b/js/views-settings.js @@ -49,7 +49,7 @@ function _renderGeneralSettings(root) { -
FinLens v2.0.2 ·${State.transactions.length} transactions loaded${State.lastRefresh?' · Refreshed '+dayjs(State.lastRefresh).format('MMM D, YYYY h:mm A'):''}
`; +
FinLens v2.0.3 ·${State.transactions.length} transactions loaded${State.lastRefresh?' · Refreshed '+dayjs(State.lastRefresh).format('MMM D, YYYY h:mm A'):''}
`; root.appendChild(displayCard); /* ---- Anthropic API Key ---- */ From dd2c86591d4ceaea28353cc9bd9f17c9b1e77b70 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 13:07:17 +0000 Subject: [PATCH 3/3] =?UTF-8?q?Hosting=20is=20CLAUDE.md=20=C2=A723:=20the?= =?UTF-8?q?=20redesign=20stack=20adds=20=C2=A722=20Migrations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013Z8iBUNj6C627mxmm1CurV --- CHANGELOG.md | 2 +- CLAUDE.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 052024c..ccbfd87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - **Deploy to GitHub Pages** (`.github/workflows/pages.yml`). On every push to `master` (after a merge), or by hand from the Actions tab, the app is published as static files to `https://gitluis.github.io/finlens/` (later, the custom domain). Pull requests never deploy. Nothing in the app changes. - **Only the app is published:** `index.html`, `js/` and `samples/`. `docs/`, `CLAUDE.md`, tests and CI files aren't served. The build refuses to publish if a `finlens-state*.json`, export or `data/` file is in the site folder. - **Before the first run:** Settings → Pages → Source: **GitHub Actions**. -- **CLAUDE.md §22 Hosting (new):** what's served, the one-site-per-origin rule (all of an account's Pages sites share `.github.io`, so publish no other Pages site until FinLens has its own domain), custom-domain setup, and the Pages limits (no custom headers, so CSP stays a `` tag). +- **CLAUDE.md §23 Hosting (new):** what's served, the one-site-per-origin rule (all of an account's Pages sites share `.github.io`, so publish no other Pages site until FinLens has its own domain), custom-domain setup, and the Pages limits (no custom headers, so CSP stays a `` tag). - Part of the **v2.0 — Public launch** milestone. Left open on purpose until the rename and custom domain are ready. --- diff --git a/CLAUDE.md b/CLAUDE.md index 76b1e2a..80ff1c3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -798,7 +798,7 @@ Multiple Chase card files can be loaded simultaneously. Each gets a unique `acco --- -*Last updated: v2.0.3 — 2026-11-04 (§22 Hosting added; v1.10.5 — 2026-11-02: no section changes: Import Logs race fix; v1.10.4: §8, §13 single `~` is literal; §21 excerpts escape `~`; v1.10.3: §13 refusals; §21 declined runs; v1.10.2: §13 summary states its dates; §21 per-month derivations; v1.10.1: §13 `AI_MAX_TOKENS`, thinking and cut-off answers; v1.10.0: §21 AI Eval added; §13 `callClaude()` raw mode; v1.9.6: §14 folder access lasts until the last tab closes, not one page load; v1.9.5: §7 chart guard; v1.9.4: views-db.js changelog reads CRLF checkouts; v1.9.3: §14 folder permission: re-request on click, Reconnect banner, browser copy wins; v1.9.2: §0 branch, PR and approval workflow added; v1.9.1: §4.5 rehydrate transactions loaded from JSON; v1.9.0: §20 Data & Reset added; v1.8.1: §10 re-upload dedup rewritten for the occurrence-suffix fix; v1.8.0: AI Analysis restored with API-key and output hardening; `renderMarkdown()` added; `samples/` added; §1–3, §13, §14, §17 corrected to match the code)* +*Last updated: v2.0.3 — 2026-11-04 (§23 Hosting added; v1.10.5 — 2026-11-02: no section changes: Import Logs race fix; v1.10.4: §8, §13 single `~` is literal; §21 excerpts escape `~`; v1.10.3: §13 refusals; §21 declined runs; v1.10.2: §13 summary states its dates; §21 per-month derivations; v1.10.1: §13 `AI_MAX_TOKENS`, thinking and cut-off answers; v1.10.0: §21 AI Eval added; §13 `callClaude()` raw mode; v1.9.6: §14 folder access lasts until the last tab closes, not one page load; v1.9.5: §7 chart guard; v1.9.4: views-db.js changelog reads CRLF checkouts; v1.9.3: §14 folder permission: re-request on click, Reconnect banner, browser copy wins; v1.9.2: §0 branch, PR and approval workflow added; v1.9.1: §4.5 rehydrate transactions loaded from JSON; v1.9.0: §20 Data & Reset added; v1.8.1: §10 re-upload dedup rewritten for the occurrence-suffix fix; v1.8.0: AI Analysis restored with API-key and output hardening; `renderMarkdown()` added; `samples/` added; §1–3, §13, §14, §17 corrected to match the code)* --- @@ -886,7 +886,9 @@ A developer-only view (`showView('ai-eval')`) that measures how well AI Analysis --- -## 22. Hosting (GitHub Pages) +## 23. Hosting (GitHub Pages) + +> §23, not §22: the redesign stack (#16–#51) adds §22 Migrations. FinLens is published as static files by `.github/workflows/pages.yml` on every push to `master`. Pull requests never deploy.