diff --git a/.release-it.json b/.release-it.json index 244f9f57..91b0b9ef 100644 --- a/.release-it.json +++ b/.release-it.json @@ -1,4 +1,7 @@ { + "hooks": { + "after:bump": "node scripts/enrich-changelog.js && git add CHANGELOG.md" + }, "git": { "commitMessage": "chore: release v${version}", "tagName": "v${version}", diff --git a/CHANGELOG.md b/CHANGELOG.md index 26a78f0f..794cf508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,64 @@ # Changelog +## [0.2.5](https://github.com/whisper-money/whisper-money/compare/v0.2.4...v0.2.5) (2026-06-15) + + +### Bug Fixes + +* **account:** block deletion while subscription or trial is active ([#531](https://github.com/whisper-money/whisper-money/issues/531)) ([2bfb569](https://github.com/whisper-money/whisper-money/commit/2bfb569a2226df44b71363e731889ab07a2a41c4)) by [@victor-falcon](https://github.com/victor-falcon) +* **analysis:** align summary card amounts to a common baseline ([#515](https://github.com/whisper-money/whisper-money/issues/515)) ([21f8f3b](https://github.com/whisper-money/whisper-money/commit/21f8f3b27719f3ff47b4769e5fdda00c323fe22d)) by [@victor-falcon](https://github.com/victor-falcon) +* **analysis:** truncate long breakdown names so amounts stay in widget ([#518](https://github.com/whisper-money/whisper-money/issues/518)) ([49acc8a](https://github.com/whisper-money/whisper-money/commit/49acc8a884617fc8a97e7b82e7dcedb5931a20b4)) by [@victor-falcon](https://github.com/victor-falcon) +* **auth:** prevent FormData crash on successful login ([#503](https://github.com/whisper-money/whisper-money/issues/503)) ([f4bbbfd](https://github.com/whisper-money/whisper-money/commit/f4bbbfd767388642b856b53814187b9c85e4ac22)) by [@victor-falcon](https://github.com/victor-falcon) +* **automation-rules:** hint amount sign for expenses vs income ([#524](https://github.com/whisper-money/whisper-money/issues/524)) ([e526f86](https://github.com/whisper-money/whisper-money/commit/e526f861b2a7f46a073273482f10111f06e44f84)) by [@victor-falcon](https://github.com/victor-falcon) +* **budgets:** make period generation idempotent ([#533](https://github.com/whisper-money/whisper-money/issues/533)) ([cd323bb](https://github.com/whisper-money/whisper-money/commit/cd323bbe529678e68bca23e84a9cdb0d78c33373)) by [@victor-falcon](https://github.com/victor-falcon) +* **cashflow:** bound trend window to prevent request timeout ([#534](https://github.com/whisper-money/whisper-money/issues/534)) ([1d4bcd5](https://github.com/whisper-money/whisper-money/commit/1d4bcd5082413071ddcc2764ab866e23ea73ab5a)) by [@victor-falcon](https://github.com/victor-falcon) +* **currency:** make rate fetching resilient to slow CDN ([#502](https://github.com/whisper-money/whisper-money/issues/502)) ([4b90bcf](https://github.com/whisper-money/whisper-money/commit/4b90bcfc96b4dd6340981d53f2e665d02872288f)) by [@victor-falcon](https://github.com/victor-falcon) +* **header:** keep mobile logo on one line, compact auth buttons ([#512](https://github.com/whisper-money/whisper-money/issues/512)) ([1530544](https://github.com/whisper-money/whisper-money/commit/1530544b8b3322f90829991df3d41d06e43e54a8)) by [@victor-falcon](https://github.com/victor-falcon) +* **import:** honor selected date format for CSV imports ([#494](https://github.com/whisper-money/whisper-money/issues/494)) ([744d874](https://github.com/whisper-money/whisper-money/commit/744d874464b803b4f9a187347cb833c9440a62d1)) by [@victor-falcon](https://github.com/victor-falcon) +* **layout:** keep bottom padding while floating nav is visible ([#537](https://github.com/whisper-money/whisper-money/issues/537)) ([6671d89](https://github.com/whisper-money/whisper-money/commit/6671d89ea10638983a5ba10a718ea16dde982697)) by [@victor-falcon](https://github.com/victor-falcon) +* **perf:** batch feature flag resolution in shared Inertia data ([#500](https://github.com/whisper-money/whisper-money/issues/500)) ([cb728ce](https://github.com/whisper-money/whisper-money/commit/cb728ce176fbac50984c183abae8af19acf1c8e7)) by [@victor-falcon](https://github.com/victor-falcon), closes [#496](https://github.com/whisper-money/whisper-money/issues/496) +* **sentry:** only report errors in production ([#467](https://github.com/whisper-money/whisper-money/issues/467)) ([d68fee6](https://github.com/whisper-money/whisper-money/commit/d68fee6c2dd54f923cb0a57c1dd483d5fa4e1ed5)) by [@victor-falcon](https://github.com/victor-falcon) +* **transactions:** combine category and label filters with OR ([#495](https://github.com/whisper-money/whisper-money/issues/495)) ([af87ac7](https://github.com/whisper-money/whisper-money/commit/af87ac75600060939b7c27e99548bace462a0d73)) by [@victor-falcon](https://github.com/victor-falcon) +* **transactions:** improve mobile analysis button affordance ([#520](https://github.com/whisper-money/whisper-money/issues/520)) ([3223824](https://github.com/whisper-money/whisper-money/commit/3223824edb03d3f5657af55dc8b01a8e79259f06)) by [@victor-falcon](https://github.com/victor-falcon) +* **transactions:** prevent crash when sorting by nullable column ([#501](https://github.com/whisper-money/whisper-money/issues/501)) ([a69c602](https://github.com/whisper-money/whisper-money/commit/a69c602366c5a2c8e18ad106827fc30693ba8471)) by [@victor-falcon](https://github.com/victor-falcon) +* **transactions:** tidy filter bar into two balanced rows ([#510](https://github.com/whisper-money/whisper-money/issues/510)) ([6486908](https://github.com/whisper-money/whisper-money/commit/6486908716e563b3b8970b9ec7b73989d7ee72be)) by [@victor-falcon](https://github.com/victor-falcon) +* verify email via signed link without requiring login ([#490](https://github.com/whisper-money/whisper-money/issues/490)) ([14b7955](https://github.com/whisper-money/whisper-money/commit/14b79557d79dd1c5c5876b6c6b1a480baedd536e)) by [@victor-falcon](https://github.com/victor-falcon) + + +### Features + +* add catch-all budgets ([#527](https://github.com/whisper-money/whisper-money/issues/527)) ([dbec1c4](https://github.com/whisper-money/whisper-money/commit/dbec1c4c134a257b95c3c1402590a6727026a4d4)) by [@tonigruni](https://github.com/tonigruni) +* **ai:** add weekly AI-suggestions cohort report ([#530](https://github.com/whisper-money/whisper-money/issues/530)) ([906e3cc](https://github.com/whisper-money/whisper-money/commit/906e3cc2b466428e7efa4c4c66cb56a068475451)) by [@victor-falcon](https://github.com/victor-falcon) +* **ai:** auto-categorize transactions with AI (behind flag) ([#535](https://github.com/whisper-money/whisper-money/issues/535)) ([8013a0b](https://github.com/whisper-money/whisper-money/commit/8013a0b6f2d53c6df64bcf6019592dd1f8e477d1)) by [@victor-falcon](https://github.com/victor-falcon) +* **ai:** defer per-transaction categorization until onboarding completes ([#536](https://github.com/whisper-money/whisper-money/issues/536)) ([e065d4a](https://github.com/whisper-money/whisper-money/commit/e065d4ab65f603f5396cafcf4634e544c2eead2f)) by [@victor-falcon](https://github.com/victor-falcon) +* **ai:** share AI sparkle icon and mark AI-generated rules ([#538](https://github.com/whisper-money/whisper-money/issues/538)) ([7dde67c](https://github.com/whisper-money/whisper-money/commit/7dde67c606fa0f8603f7603c0a6769df6755028c)) by [@victor-falcon](https://github.com/victor-falcon) +* **ai:** suggest automation rules during onboarding ([#523](https://github.com/whisper-money/whisper-money/issues/523)) ([8056ede](https://github.com/whisper-money/whisper-money/commit/8056ede63644a4fac2afa88fcc9d89d7fb3bcea1)) by [@victor-falcon](https://github.com/victor-falcon) +* **analysis:** break down spending by sub-category ([#508](https://github.com/whisper-money/whisper-money/issues/508)) ([c944a2c](https://github.com/whisper-money/whisper-money/commit/c944a2c37ecfab3c483a6c0ffa3596bdd8b73f01)) by [@victor-falcon](https://github.com/victor-falcon) +* **analysis:** per-category 12-month spending drawer ([#519](https://github.com/whisper-money/whisper-money/issues/519)) ([9c3c4d5](https://github.com/whisper-money/whisper-money/commit/9c3c4d573ee8a04155d56da39bc213b052a138a4)) by [@victor-falcon](https://github.com/victor-falcon) +* **analysis:** project-aware transaction analysis ([#513](https://github.com/whisper-money/whisper-money/issues/513)) ([7cc49a5](https://github.com/whisper-money/whisper-money/commit/7cc49a53689d95855ca254a4df8ebd6fbad5720c)) by [@victor-falcon](https://github.com/victor-falcon) +* **analysis:** shared bar-list breakdowns in transaction drawer ([#517](https://github.com/whisper-money/whisper-money/issues/517)) ([bcd025f](https://github.com/whisper-money/whisper-money/commit/bcd025f1b16490baf871718b24db71997895e07e)) by [@victor-falcon](https://github.com/victor-falcon) +* **auth:** show/hide toggle on password fields ([#499](https://github.com/whisper-money/whisper-money/issues/499)) ([58254fc](https://github.com/whisper-money/whisper-money/commit/58254fcedeb76ff99b88f5b5fafe00f807510f91)) by [@victor-falcon](https://github.com/victor-falcon) +* **banking:** add command to disconnect connections by id ([#497](https://github.com/whisper-money/whisper-money/issues/497)) ([9192947](https://github.com/whisper-money/whisper-money/commit/91929477ab94cd721bc8b6c3a7c9a28dcdfb31cf)) by [@victor-falcon](https://github.com/victor-falcon) +* **cashflow:** enlarge and color-code net cashflow and saved cards ([#505](https://github.com/whisper-money/whisper-money/issues/505)) ([346e21a](https://github.com/whisper-money/whisper-money/commit/346e21ad4eec3b9dd7369abd6503b66fd7262c92)) by [@victor-falcon](https://github.com/victor-falcon) +* **console:** add agent:db command for querying local and prod DB ([#522](https://github.com/whisper-money/whisper-money/issues/522)) ([d2a4412](https://github.com/whisper-money/whisper-money/commit/d2a44121189624ab5e5c8e1ac1baac4ffd17ec21)) by [@victor-falcon](https://github.com/victor-falcon) +* **currencies:** add Colombian and Dominican peso ([#471](https://github.com/whisper-money/whisper-money/issues/471)) ([e5b4933](https://github.com/whisper-money/whisper-money/commit/e5b493329a6b5b8e6fdf04f873e591546c42441d)) by [@victor-falcon](https://github.com/victor-falcon) +* **currency:** add NZD (New Zealand Dollar) ([#504](https://github.com/whisper-money/whisper-money/issues/504)) ([899ea6a](https://github.com/whisper-money/whisper-money/commit/899ea6a939787e567a41566aeb6fbeee6885600d)) by [@victor-falcon](https://github.com/victor-falcon) +* enable category tree for all users, remove flag ([#488](https://github.com/whisper-money/whisper-money/issues/488)) ([f8cc881](https://github.com/whisper-money/whisper-money/commit/f8cc8816a898514a558667a2938f6255363b2ed7)) by [@victor-falcon](https://github.com/victor-falcon) +* expand parent categories inline in breakdowns ([#486](https://github.com/whisper-money/whisper-money/issues/486)) ([53d0518](https://github.com/whisper-money/whisper-money/commit/53d051800bb1e676563bbc1038e607efc186bebd)) by [@victor-falcon](https://github.com/victor-falcon) +* expand Sankey subcategories inline ([#485](https://github.com/whisper-money/whisper-money/issues/485)) ([679c8d7](https://github.com/whisper-money/whisper-money/commit/679c8d7bff3b69a5b70c55ae90fd1d8236af99ee)) by [@victor-falcon](https://github.com/victor-falcon) +* **importer:** support YYYYMMDD date format ([#470](https://github.com/whisper-money/whisper-money/issues/470)) ([f9d1303](https://github.com/whisper-money/whisper-money/commit/f9d1303d986aa2cee9ee6dbf92d6a3fb708f8f05)) by [@victor-falcon](https://github.com/victor-falcon) +* **landing:** add go now button to redirect modal ([#506](https://github.com/whisper-money/whisper-money/issues/506)) ([c53c40c](https://github.com/whisper-money/whisper-money/commit/c53c40cf0b54a94c163f28ebd504dd720ff03339)) by [@victor-falcon](https://github.com/victor-falcon) +* **landing:** real testimonials with gravatar/facehash avatars ([#493](https://github.com/whisper-money/whisper-money/issues/493)) ([300188f](https://github.com/whisper-money/whisper-money/commit/300188f135a598a4ae2a5bb6f119af1d13cae7eb)) by [@victor-falcon](https://github.com/victor-falcon) +* **open-banking:** finalize bank connection without a session via state token ([#498](https://github.com/whisper-money/whisper-money/issues/498)) ([a7dde5f](https://github.com/whisper-money/whisper-money/commit/a7dde5fbc5e1a09d55d64ff101e5ea4061335fd0)) by [@victor-falcon](https://github.com/victor-falcon) +* optionally update manual account balance on transaction delete ([#491](https://github.com/whisper-money/whisper-money/issues/491)) ([45e25e0](https://github.com/whisper-money/whisper-money/commit/45e25e018de377622197ae0c3c39c9cab6053220)) by [@victor-falcon](https://github.com/victor-falcon) +* parent/child category tree ([#474](https://github.com/whisper-money/whisper-money/issues/474)) ([1cc1056](https://github.com/whisper-money/whisper-money/commit/1cc10566a36562fa37ac7ecb9592da03284f5f51)) by [@victor-falcon](https://github.com/victor-falcon) +* **settings:** let users disable bank transactions email ([#472](https://github.com/whisper-money/whisper-money/issues/472)) ([e178f1b](https://github.com/whisper-money/whisper-money/commit/e178f1b1bdb57a778ae2124e651078d1904f71c4)) by [@victor-falcon](https://github.com/victor-falcon) +* single-open Sankey expand, fit overflowing children ([#487](https://github.com/whisper-money/whisper-money/issues/487)) ([721cbef](https://github.com/whisper-money/whisper-money/commit/721cbef02464acb40ab1428c769b65a042b4d96a)) by [@victor-falcon](https://github.com/victor-falcon) +* **transactions:** filtered analysis dashboard ([#507](https://github.com/whisper-money/whisper-money/issues/507)) ([8375fd4](https://github.com/whisper-money/whisper-money/commit/8375fd490ecc473bbcb7450830ba5b55e4b6bb26)) by [@victor-falcon](https://github.com/victor-falcon) +* **transactions:** save and reuse transaction filters ([#496](https://github.com/whisper-money/whisper-money/issues/496)) ([8df44c2](https://github.com/whisper-money/whisper-money/commit/8df44c2ef492abe4a9f5d385c9eb5ca0835c7675)) by [@victor-falcon](https://github.com/victor-falcon) +* **users:** track last login and last active timestamps ([#516](https://github.com/whisper-money/whisper-money/issues/516)) ([fcf2d3d](https://github.com/whisper-money/whisper-money/commit/fcf2d3d1ad5f4f85542bd92f7bdaf23ec26c8c50)) by [@victor-falcon](https://github.com/victor-falcon) +* **welcome:** add Albert G. testimonial ([#529](https://github.com/whisper-money/whisper-money/issues/529)) ([0f48ffb](https://github.com/whisper-money/whisper-money/commit/0f48ffbbeffe12321d434c9e4714d09eb2ce9b02)) by [@victor-falcon](https://github.com/victor-falcon) + ## [0.2.4](https://github.com/whisper-money/whisper-money/compare/v0.2.3...v0.2.4) (2026-06-01) diff --git a/package-lock.json b/package-lock.json index af7eddb4..083c1e32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "whisper-money", - "version": "0.2.4", + "version": "0.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "whisper-money", - "version": "0.2.4", + "version": "0.2.5", "hasInstallScript": true, "dependencies": { "@headlessui/react": "^2.2.9", diff --git a/package.json b/package.json index 6df5d987..48d60f2f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "whisper-money", - "version": "0.2.4", + "version": "0.2.5", "private": true, "type": "module", "scripts": { diff --git a/scripts/enrich-changelog.js b/scripts/enrich-changelog.js new file mode 100644 index 00000000..c222f8fa --- /dev/null +++ b/scripts/enrich-changelog.js @@ -0,0 +1,100 @@ +/** + * Enriches the latest CHANGELOG.md release section with PR author credits. + * + * Squash-merges collapse every commit author to the repo owner, so the real + * contributor is not in git history. Instead we read the PR number already + * present in each entry (`(#531)`), resolve the GitHub handle via the `gh` + * CLI, and append `by [@handle](https://github.com/handle)` to the line. + * + * Only the most recent release section (first `## [` heading up to the next + * one) is processed, so historical sections stay untouched. The pass is + * idempotent: already-credited lines are skipped. Failures to resolve an + * author (e.g. `gh` missing or unauthenticated) are non-fatal and the entry + * is left as-is, so a release is never blocked by this step. + * + * Wired into release-it via the `after:bump` hook; can also be run manually: + * node scripts/enrich-changelog.js + */ + +import { execFileSync } from 'child_process'; +import { readFileSync, writeFileSync } from 'fs'; +import { resolve } from 'path'; +import process from 'process'; + +const FILE = resolve(import.meta.dirname, '../CHANGELOG.md'); + +const lines = readFileSync(FILE, 'utf8').split('\n'); + +const sectionStart = lines.findIndex((line) => line.startsWith('## [')); +if (sectionStart === -1) { + console.log('enrich-changelog: no release section found, nothing to do.'); + process.exit(0); +} +let sectionEnd = lines.findIndex( + (line, index) => index > sectionStart && line.startsWith('## ['), +); +if (sectionEnd === -1) { + sectionEnd = lines.length; +} + +const PR_LINK = /\[#(\d+)\]\([^)]*\/issues\/\d+\)/; +const COMMIT_LINK = /\(\[[0-9a-f]{7,40}\]\([^)]*\/commit\/[^)]*\)\)/; + +const authorByPr = new Map(); + +function resolveAuthor(pr) { + if (authorByPr.has(pr)) { + return authorByPr.get(pr); + } + + let handle = null; + try { + handle = + execFileSync( + 'gh', + ['pr', 'view', pr, '--json', 'author', '--jq', '.author.login'], + { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }, + ).trim() || null; + } catch { + handle = null; + } + + authorByPr.set(pr, handle); + return handle; +} + +let enriched = 0; +for (let index = sectionStart; index < sectionEnd; index++) { + const line = lines[index]; + + if (!line.startsWith('* ') || / by \[@/.test(line)) { + continue; + } + + const prMatch = line.match(PR_LINK); + if (!prMatch) { + continue; + } + + const handle = resolveAuthor(prMatch[1]); + if (!handle) { + continue; + } + + const credit = ` by [@${handle}](https://github.com/${handle})`; + const commitMatch = line.match(COMMIT_LINK); + if (commitMatch) { + const insertAt = commitMatch.index + commitMatch[0].length; + lines[index] = line.slice(0, insertAt) + credit + line.slice(insertAt); + } else { + lines[index] = line + credit; + } + + enriched++; +} + +if (enriched > 0) { + writeFileSync(FILE, lines.join('\n')); +} + +console.log(`enrich-changelog: ${enriched} ${enriched === 1 ? 'entry' : 'entries'} credited.`);