* [AI] Redesign first-run onboarding for web/PWA users
Fresh web/PWA installs whose origin does not serve a sync server now
start in local-only mode on a redesigned welcome screen instead of the
"Where's the server?" page, with syncing offered as an option. The
server connection page is retitled and redesigned with a back button
and friendlier copy. Transient probe failures (server unreachable)
keep the previous behavior and persist nothing, so a briefly-down
self-hosted server is retried on the next load. Electron keeps its
existing server-config first run, and origins that serve a sync
server still go to bootstrap/login.
VRT snapshots for the onboarding test were deleted and need
regenerating with yarn vrt:docker.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8495
* coderabbit
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* bcrypt -> argon2id
* coderabbit feedback
* copilot review
* switch hashing settings
* [AI] Add unit tests for sync-server password hashing
Cover password.js, focused on the bcrypt -> argon2id migration:
- loginWithPassword upgrades a legacy bcrypt hash to argon2id on a
successful login, leaves it untouched on a failed login, and does not
needlessly rehash an existing argon2id hash
- hashPassword/verifyPassword round-trip, bcrypt backward-compat, and
graceful handling of non-string/malformed hashes
- bootstrapPassword/changePassword/checkPassword behaviour
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* dedupe minimatch
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the knip tool with a monorepo-tuned config (knip.json) and a CI gate
in check.yml, plus the dead-code and dependency cleanup it surfaced. The
unused-export/type/duplicate rules are disabled so exporting an unused
symbol is allowed.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* [AI] Reduce dependencies (lodash, ua-parser-js, memoize-one, promise-retry, resize-observer polyfill)
Remove or replace several low-usage / native-coverable dependencies to shrink
the dependency surface and transitive deps:
- lodash -> es-toolkit (es-toolkit/compat) for the 5 functions in use
(debounce, keyBy, isMatch, isEqual, uniqueId)
- ua-parser-js -> inline UA regex checks in loot-core shared/platform
- memoize-one -> small local memoizeOne helper in loot-core shared
- promise-retry -> small local retry helper (loot-core shared + a local copy
in desktop-electron, which loads compiled JS at runtime)
- @juggle/resize-observer polyfill removed; native ResizeObserver is supported
by all current targets
uuid was intentionally left untouched: crypto.randomUUID is only available in
secure contexts, which would break self-hosted instances served over plain HTTP
(including loot-core code running in the browser web worker).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JdZrw7VVwyF6VJgb34U9Qo
* [AI] Use es-toolkit main entry for keyBy in report spreadsheets
The two report spreadsheet files only used keyBy from es-toolkit/compat. Switch
them to the lighter main es-toolkit entry (which takes a key function instead of
a string), so these chunks no longer pull in the compat layer. Runtime behavior
is identical.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JdZrw7VVwyF6VJgb34U9Qo
* [AI] Rename release note to slug and reword for readability
Rename the dependency-reduction release note from the guessed PR number to a
descriptive slug, and reword the body to read clearly as changelog content.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JdZrw7VVwyF6VJgb34U9Qo
* [AI] Shorten release note wording
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JdZrw7VVwyF6VJgb34U9Qo
* [AI] Harden retry helper against sync throws; simplify memoizeOne typing
- retry: run fn inside a promise chain so synchronous throws (and synchronous
retry() calls) are routed through the rejection handler instead of escaping
uncaught. Applied to both loot-core and desktop-electron copies.
- memoizeOne: use separate Args/Result generics and drop the `as T` cast.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JdZrw7VVwyF6VJgb34U9Qo
* [AI] Update yarn.lock after merge and install
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
2026-06-21 20:06:15 +00:00
Matt FiddamanGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Initial plan
* Bump desktop Electron runtime to v42.3.0
* Add release notes entry for PR #8044
* Change author from Copilot to MikesGlitch
Updated author information in release notes.
* Update node-abi mappings to support Electron 42 ABI detection
* Address validation feedback for Electron update PR
* Add better-sqlite3 Electron 42 patch
* Update lockfile for better-sqlite3 patch
* Remove better-sqlite patch protocol and target Electron 41
* Align release note with Electron 41.7.1 change
* Update better-sqlite3 ranges to ^12.8.0
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Michael Clark <5285928+MikesGlitch@users.noreply.github.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
* 🔖 (26.6.0)
* Generate release notes for v26.6.0
* Generate release notes for v26.6.0
* Update check-spelling metadata
* Generate release notes for v26.6.0
* add release summary
* links
* Generate release notes for v26.6.0
* update links
* Generate release notes for v26.6.0
* Generate release notes for v26.6.0
* Generate release notes for v26.6.0
* add EB link
* Add initial docs for Enable Banking (#7961)
* Add initial docs for Enable Banking
* Delete upcoming-release-notes/7961.md
* [Docs] UI Budget automations & month-end cleanup (#7863)
* Add files via upload
* Create documentation for budget automation feature
Added documentation for the budget automation feature, detailing its functionalities, usage, and examples.
* Add files via upload
* Revise budget automation documentation for clarity
Updated the documentation for budget automation, enhancing clarity and consistency in the descriptions of features and options.
* [autofix.ci] apply automated fixes
* Update Markdown headers for budget automation section
* Add files via upload
* Improve formatting in budget automation documentation
Updated formatting and added line breaks for better readability in the budget automation documentation.
* [autofix.ci] apply automated fixes
* Fix HTML line breaks in budget-automation.md
Updated HTML line breaks from '</br>' to '<br>' in budget automation documentation.
* Fix HTML line breaks in budget automation documentation
* Fix headings and formatting in budget-automation.md
Updated formatting and corrected headings in budget automation documentation.
* Add budget-automation to sidebar items
* Add files via upload
* Add files via upload
* Revise budget automation documentation
Updated budget automation documentation to clarify usage of notes templates and detailed instructions for month-end cleanup processes, including named pools and weight calculations.
* [autofix.ci] apply automated fixes
* Refactor budget automation documentation for clarity
Updated various sections for clarity and consistency, including grammar corrections and improved phrasing.
* [autofix.ci] apply automated fixes
* Enhance budget automation documentation
Updated budget automation documentation with new blog links and improved formatting.
* Fix links in budget-automation.md
Updated links in the budget automation documentation to remove 'docs' prefix for consistency.
* Revise budget automation documentation with updates
Updated images and text for budget automation documentation, including corrections and enhancements to clarity.
* Improve clarity and add save reminders in budget automation
Updated wording for clarity and added reminders for saving work.
* Update budget automation documentation for clarity
Clarify the process of handling leftover funds in the budget automation script.
* [autofix.ci] apply automated fixes
* Add 'overfund' and 'overfunded' to spelling expect list
* Update spelling expectations by removing 'overfunded'
Removed 'overfunded' from the spelling expectations.
* Add files via upload
* 'overfund' to 'overfunded'
First the bot tells me overfunded isn't needed if overfund is there. Now, it tells me that overfunded IS needed. I give up.
* Enhance budget automation documentation
Added new sections on automation adjustments, moved some sections around, added horizontal separators.
* Update images and descriptions in budget automation docs
* Add files via upload
* Add automation notes section to budget automation docs
Added a section on automation notes to document how automations, balance caps, and long-term goals can have associated notes for clarity and tracking.
* Add files via upload
* Update budget automation examples in documentation
* Add files via upload
* Apply suggestions from code review
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
* [autofix.ci] apply automated fixes
* Add 'unmigrate' to spelling expectations
* Improve clarity in budget automation documentation
Clarified descriptions for budget automation features and improved wording for better understanding.
* Correct spelling of 'unmigrate' to 'Unmigrate'
They are the same and github is punking me again.
* Clarify automation notes description
* Add files via upload
* Add files via upload
* Add files via upload
* Add files via upload
* Add files via upload
* Fix typos in budget-automation documentation
Corrected typos and improved clarity in the budget automation documentation.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
---------
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
Co-authored-by: Mats Nilsson <matni403@gmail.com>
Co-authored-by: Juulz <julesmcn@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] Pin Electron Playwright version to 99.9.9
The version number at the bottom of the Management page is sourced from
package.json via app.getVersion(), so each release rotates the dynamic
version string in VRT screenshots. The browser bundle already swaps in a
static '99.9.9' for Playwright (browser-preload.js); mirror that in the
Electron bootstrap data so desktop VRT snapshots don't break on version
bumps.
Existing snapshots need to be regenerated once (via /update-vrt on the PR)
since they were captured with the live package.json version.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #7965
* [AI] Pin Playwright server version to 99.9.9
The Management page footer also renders the sync server version, which
'get-server-version' fetches from the sync-server's /info endpoint (its
own package.json). Short-circuit getServerVersion() to '99.9.9' when
running under Playwright so VRT snapshots stay stable across releases.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #7965
* [AI] Set 'playwright' userAgent on Electron BrowserWindow under Playwright
playwright.config.ts only sets userAgent for direct chromium launches —
_electron.launch() leaves the BrowserWindow with Chromium's default UA, so
Platform.isPlaywright (which checks navigator.userAgent) is false in the
renderer. That's why the ServerContext shortcut wasn't pinning the server
version for desktop VRT snapshots. Force the UA on the webContents when
EXECUTION_CONTEXT=playwright so renderer-side Playwright checks light up.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #7965
* [AI] Preserve Electron substring in Playwright userAgent
Replacing the Electron renderer's UA with bare 'playwright' broke
environment.isElectron() (it greps for 'Electron' in navigator.userAgent),
which rerouted ConfigServer.tsx into the external-server branch — the
sync-server e2e test could no longer find the Start button to navigate to
the bootstrap page, so its snapshot kept falling through every
/update-vrt unchanged.
Append ' playwright' to the existing Electron UA instead, and widen the
Platform.isPlaywright check to a substring match so both
'playwright' (chromium tests) and 'Electron/… playwright' (electron tests)
resolve to true.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #7965
* Add release notes for PR #7965
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Tighten VRT per-pixel threshold so faint overlays fail
Playwright's default `threshold: 0.2` translates to a pixelmatch YIQ
delta cutoff of ~1408, which silently swallows low-alpha overlays. PR
#7841 striped the transactions table with rgba(..., .15); the resulting
per-pixel deltas (~270 light, ~320 dark) fell below the cutoff, so VRT
reported 0 diff pixels and passed despite a clearly visible change.
Drop `threshold` to 0.05 (cutoff ~88) so faint tints are flagged while
keeping headroom for anti-aliasing noise.
* [AI] Apply VRT threshold to electron config and drop redundant local override
- Remove `maxDiffPixels: 5` from `toMatchThemeScreenshots` — it duplicates
the global config and obscured the fact that per-call options would
override the global threshold if added there too.
- Mirror the threshold in desktop-electron's playwright config so its
VRT screenshots are subject to the same sensitivity.
- Tighten the threshold comment: drop the PR/task reference per
AGENTS.md and the worked-example numbers; keep the formula and the
low-alpha rationale.
* Add release notes for PR #7864
* Revert "[AI] Apply VRT threshold to electron config and drop redundant local override"
This reverts commit ec789703ea.
* Revert "[AI] Tighten VRT per-pixel threshold so faint overlays fail"
This reverts commit 334954bb33.
* [AI] Remove stale release note for reverted threshold change
* Revert "[AI] Remove stale release note for reverted threshold change"
This reverts commit 90f97d95f3.
* Reapply "[AI] Tighten VRT per-pixel threshold so faint overlays fail"
This reverts commit 98d0f8b3e7.
* Reapply "[AI] Apply VRT threshold to electron config and drop redundant local override"
This reverts commit 23f94362ec.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #7864
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Load @actual-app/crdt from source in dev, only bundle for publish
@actual-app/crdt's local exports now point at src/index.ts so consumers
(sync-server, loot-core, desktop-client) never see a stale Vite bundle.
publishConfig keeps the dist/ mapping for npm consumers. crdt's
tsconfig switches to bundler module resolution to match the rest of
the workspace (no extensions in source imports).
Sync-server's existing extension-resolution loader is extended to also
handle directory-index imports (./crdt → ./crdt/index.ts), and the
standalone `start` / `start-monitor` scripts now invoke Node with
--import ./register-loader.mjs so the loader is in place before crdt's
source resolves.
Electron's utilityProcess.fork accepts execArgv but doesn't actually
preload --import modules, so a new packages/sync-server/start.mjs
bootstrap entry registers the loader imperatively and then dynamic-
imports build/app.js. desktop-electron's startSyncServer() points the
fork at start.mjs. sync-server's "files" array now ships start.mjs,
register-loader.mjs and loader.mjs so packaged Electron / npm
consumers actually receive them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add release notes for PR #7702
* [AI] Restructure sync-server to build with Vite
Replace the hand-rolled tsgo + add-import-extensions + copy-static-assets
+ runtime loader pipeline with a single Vite SSR build. Bundles every
entry (app, bin/actual-server, scripts/*) and inlines @actual-app/crdt
source so Node never has to resolve TS at runtime — the
MODULE_TYPELESS_PACKAGE_JSON warning that surfaced via crdt's source
exports is gone. Migrations and bank handlers move from readdir-based
dynamic imports to import.meta.glob; messages.sql becomes a ?raw import.
Drop loader.mjs, register-loader.mjs, start.mjs, and
bin/add-import-extensions.mjs. Electron's startSyncServer() forks
build/app.js directly. publishConfig.imports goes away (subpath imports
are resolved at build time and don't appear in the bundle).
In dev (start:server-dev) sync-server proxies to Vite, so loosen the CSP
to allow Vite's inline preamble script and HMR websocket — production
CSP is unchanged. desktop-client skips registerSW() in dev (and disables
vite-plugin-pwa's devOptions) so stale cached assets don't override
edits between page loads.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Address review feedback
- sync-server CSP: drop 'unsafe-eval' from the production script-src;
the bundle has no genuine eval/new Function usage (only a defensive
branch in setimmediate's polyfill that's never hit). Keep it on the
dev branch where Vite's HMR runtime relies on it. Add a comment so
it's obvious which branch needs it and why.
- bank-factory: widen the loader glob to ./banks/*_*.{ts,js} so
TypeScript handlers are discovered too, mirroring migrations.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Restore 'unsafe-eval' in production CSP for Electron
The Electron app needs `'unsafe-eval'` at runtime, so revert the dev-only
restriction and keep `'unsafe-eval'` in both branches. Comment updated to
record the actual reason instead of marking it as removable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Revert bank-factory glob change
Widening the glob to ./banks/*_*.{ts,js} broke the desktop e2e tests in
CI even though every current handler is .js and the brace expansion
matches no .ts files locally. Reverting to ./banks/*_*.js — the change
had no behavioural benefit since there are no TS handlers, so the
nitpick isn't worth chasing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Strip CSP comment to restore identical state to 9513c1e16
The desktop e2e has been failing despite my prior commits being a strict
revert (only difference was a 2-line comment, which can't change runtime).
Removing even the comment so the branch matches 9513c1e16's relevant
files exactly, to isolate whether the failure is from the master merge
or from CI-environment drift.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Make rebuild-electron actually rebuild better-sqlite3
PR #7712 simplified rebuild-electron to just `electron-rebuild -f -o
better-sqlite3,bcrypt` from the repo root. Two problems with that:
1. Without `-m`, electron-rebuild scans the root workspace's package.json
for native deps. better-sqlite3 isn't a direct root dep — it lives
under packages/sync-server/ — so the scan returns no candidates and
the rebuild silently no-ops.
2. Without --build-from-source, electron-rebuild defers to
prebuild-install, which downloads a stale prebuilt binary keyed off
better-sqlite3's package.json (ABI 127) instead of recompiling
against Electron 39's bundled Node ABI 140. The download succeeds
and "Rebuild Complete" prints, but the resulting `better_sqlite3.node`
can't `dlopen` inside Electron's utility process — sync-server
crashes immediately on db init, the renderer's startSyncServer IPC
never resolves, and the e2e test hangs on "Configure your server".
Point -m at packages/desktop-electron (which transitively pulls in
better-sqlite3 and bcrypt via @actual-app/sync-server) and force a real
compile via --build-from-source. Verified locally: better-sqlite3
rebuilds to darwin-arm64-140 and the desktop e2e onboarding test passes
in 6s instead of hanging for 60s.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Restore CSP unsafe-eval comment
Bring back the explanatory comment that was stripped diagnostically in
99682268c. Now that the desktop e2e regression is traced to
rebuild-electron and not to anything in this branch, we can keep the
documentation noting why 'unsafe-eval' is retained in both CSP branches.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Restore bank-factory glob to ./banks/*_*.{ts,js}
Re-apply the glob widening originally added in 145868f9d. It was
reverted in 531b1a191 because the desktop e2e was failing — that
failure is now traced to the rebuild-electron breakage (fixed in
6e8ac0784), not to this glob. Mirroring migrations.ts so future TS
bank handlers are picked up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Fix applyAppUpdate hanging in dev mode
In dev mode browser-preload's updateSW was () => undefined, so
applyAppUpdate() — which calls updateSW() and then awaits a
deliberately never-resolving promise (waiting for the SW-driven page
reload) — hung the renderer instead of refreshing. In prod the page
is replaced by the new service worker, so the never-resolving await is
fine. The dev path now triggers a plain window.location.reload() so
the page reloads and the never-settling await is irrelevant, matching
prod's effective behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Revert rebuild-electron to master version
* Revert "[AI] Revert rebuild-electron to master version"
This reverts commit 4b6baab79f.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* 🔖 (26.5.0)
* fix release note generation script (#7635)
* fix release note generation script
* note
* fix cherrypicked commits not being respected and lint race in release note generation workflow (#7640)
* fix cherrypicked commits not being respected and lint race
* note
* coderabbit suggestions
* fix lint
* make double restore possibility safe
* fix lint (#7643)
* Generate release notes for v26.5.0
* add release note highlights
* Fix Sankey income bug, when payee it not set (#7632)
* Ensure income categories are shown correct, even if payee is not set
* Add release note
* Generate release notes for v26.5.0
* increase test coverage for budget templates (#7620)
* [AI] cover existing template engine logic with regression tests
Adds tests for goal template behavior that predates this PR so the
suite can be cherry-picked onto master to confirm no regressions. No
production code changes.
Covers:
- init() validation: schedule names, by/schedule priority match, past
by-target with and without annual/repeat, percentage source not
found, special source aliases, duplicate limit/spend/goal
directives, weekly limit missing start date, invalid limit period,
unrecognized periodic period
- runRemainder cap clamping and hideDecimal fraction removal
- Income-category branch in runTemplatesForPriority
- getLimitExcess against an aggregate weekly cap
- Past by-target rolling forward via the annual period
- runSchedule full=true (no sinking accumulation), percent and fixed
adjustments, completed-schedule filtering, past-date error for
non-repeating schedules, monthly/weekly/daily sinking contribution
branches when interval exceeds the pay-month-of cap, surplus
absorption when last-month balance exceeds the target, and
tracking-budget mode forcing all schedules pay-month-of
- applyMultipleCategoryTemplates orchestration: per-category writes,
cross-category priority clamping when funds run out, error
notification path
- applyTemplate force=false skipping already-budgeted categories
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* note
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix infinite loop when remainder is impossible to solve (#7623)
* fix infinite loop when remainder is impossible to solve
* note
* Generate release notes for v26.5.0
* Update author
Updated author information in the release notes.
* Fix shared worker resumption after tab suspend (#7656)
* [AI] Fix SharedWorker tab resume recovery
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [AI] Fix SharedWorker reload readiness
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add release notes
* Update packages/desktop-client/src/shared-browser-server-core.ts
Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
* Update docs release date
* Empty commit to bump CI
* Generate release notes for v26.5.0
* Revert "Generate release notes for v26.5.0"
This reverts commit b42c48bed5.
---------
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Emil Tveden Bjerglund <emilbp@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Julian Dominguez-Schatz <julian.dominguezschatz@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [AI] Make TypeScript work in test files across packages
Match the CRDT package's tsconfig pattern in loot-core, desktop-client,
api, and desktop-electron so test files participate in the project graph
(IDE intellisense, project-wide typecheck) while production builds still
emit clean declaration files.
- Remove test-file exclusions from each package's main tsconfig
- Add tsconfig.build.json for loot-core and api with test exclusions,
used by the build scripts
- Add e2e/tsconfig.json for desktop-client and desktop-electron with
Playwright types
- Fix latent type errors in test files now caught by typecheck
- Disable typescript/unbound-method for test files (mock matcher pattern)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Release notes
* [AI] Address review feedback on test type fixes
- goal-template.test.ts: extract amounts to typed locals so single-value
assertions no longer compare against unknown
- category-template-context.test.ts: replace `as unknown as DbCategory`
double-cast with a fully-typed object using `satisfies DbCategory`
(the previous mock had `is_income: true` which doesn't match the
`1 | 0` shape the cast was hiding)
- api/tsconfig.build.json: broaden test exclude pattern to `**/*.test.ts`
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Widen toMatchThemeScreenshots matcher to accept Page
The matcher's runtime impl already handled both Page and Locator
(via `typeof locator.page === 'function'` branch), but the type only
declared Locator. Call sites pass a Page (`expect(page).toMatchThemeScreenshots()`),
which now compiles cleanly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Type window.Actual in e2e fixtures and refactor matcher
- Pull loot-core/typings/window.ts into the e2e tsconfig include so
the ambient `window.Actual` augmentation is visible.
- Refactor toMatchThemeScreenshots to derive a Page once via
`'page' in target`, then call evaluate on the page consistently.
The previous union-typed access (locator.evaluate, locator.page)
didn't typecheck on Locator | Page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Drop tsconfig.build.json for loot-core and api
The build-config indirection was incomplete protection: typecheck
(`tsgo -b` against the main tsconfig, which now includes test files)
already emits `*.test.d.ts` into `@types/`, and the build step does
not clean before re-emitting. The same is observable in crdt's
`dist/`, which currently contains test declarations on disk.
What actually keeps test declarations out of the npm tarball is the
`files` field in package.json — and loot-core already uses that
mechanism for source files (`\!src/**/*.test.ts`). Extending the same
pattern to `@types/` is more direct than maintaining a duplicate
tsconfig that doesn't reliably do its job.
- Delete loot-core/tsconfig.build.json; revert build to `tsgo -b`;
add `\!@types/**/*.test.d.ts*`, `\!@types/**/__tests__/**`,
`\!@types/**/__mocks__/**` to `files`.
- Delete api/tsconfig.build.json; revert build to
`vite build && tsgo --emitDeclarationOnly`; add
`\!@types/**/*.test.d.ts*` to `files`.
Verified: `yarn pack --dry-run` excludes all test declarations from
both packages while production declarations still pack (428 .d.ts
files for loot-core, methods.d.ts for api).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [AI] Standardise crdt to drop tsconfig.build.json
Apply the same simplification as loot-core and api: a single tsconfig
per package, with `files`-field negations preventing test
declarations from being published.
Note: this also fixes a pre-existing issue where crdt was shipping
`crdt/timestamp.test.d.ts` and `crdt/merkle.test.d.ts` to npm. The
old `tsconfig.build.json` excluded test files from declaration emit,
but the `typecheck` script (`tsgo -b` via the main tsconfig) had
already emitted them into `dist/` and the build did not clean
first, so they were packed via `"files": ["dist"]`.
After this change, `yarn pack --dry-run` packs only production
declarations (10 .d.ts files) and excludes the test ones.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `Publish nightly npm packages` workflow started failing at the
"Pack the core package" step with:
Cannot find module '@actual-app/crdt' or its corresponding type declarations.
PR #7541 switched `@actual-app/crdt`'s package.json to conditional
exports (`types` → `./dist/index.d.ts`). `yarn pack` for
`@actual-app/core` triggers a prepack that runs `tsgo -b`, which now
resolves `@actual-app/crdt` via the `types` condition and expects
`packages/crdt/dist/index.d.ts`. Nothing was building crdt first
because loot-core's tsconfig didn't declare it as a project
reference.
Fix: declare the project reference so `tsgo -b` walks the graph and
builds crdt before loot-core. Sibling packages already do this.
Also adopt `@monorepo-utils/workspaces-to-typescript-project-references`
to keep each package's tsconfig `references` in sync with its
`workspace:*` deps, and wire it into a new `yarn check:tsconfig-references`
step in the `check` CI job plus lint-staged. Running the tool added
`../desktop-client` references to sync-server and desktop-electron
(both declare `@actual-app/web` as a workspace dep even though they
only use it at runtime via `require.resolve`); the extra references
are harmless — in CI the corresponding build is already cached by
earlier steps.
https://claude.ai/code/session_01AA2gEMqX24GWeq5BovNmaz
* [AI] Add no-extraneous-dependencies lint rule to prevent transitive dependency usage
Closes#7479. Adds a custom ESLint rule that flags imports of packages not
explicitly listed in the workspace's dependencies or devDependencies. Also
fixes all existing violations by adding missing deps and removes unused
deps (@reduxjs/toolkit, @rschedule/json-tools) from loot-core.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Fix builtin subpath detection and improve cache in no-extraneous-dependencies
Fix false positives for Node.js builtin subpaths (fs/promises, path/posix)
by checking the package name portion against builtins. Also cache all
visited directories during walk-up, not just the starting directory.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Release notes
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Migrate desktop-client to subpath imports
Replace the `@desktop-client/*` path alias with Node.js subpath
imports (`#*`) across packages/desktop-client:
- Declare the full `imports` map in packages/desktop-client/package.json
(bare index entries, root-level files, and per-subdirectory wildcards
with explicit extension overrides where `.ts` and `.tsx` mix).
- Update all source files to import from `#...` specifiers.
- Drop the `@desktop-client` group from .oxfmtrc.json.
- Enable `actual/prefer-subpath-imports` for desktop-client in
.oxlintrc.json so future code keeps using the subpath form.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Drop legacy desktop-client aliases
Remove the `@desktop-client/*` and `loot-core/*` path aliases from
vite.config.ts and tsconfig.json now that every desktop-client source
file imports via subpath imports / `@actual-app/core`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Release notes
* [AI] Use electron-renderer condition for renderer-only exports
Desktop-client's Vite build used the `electron` resolve condition, which
overlapped with loot-core exports where `electron` means the Node/main
variant (e.g. `shared/platform.electron.ts` using `os`,
`platform/server/asyncStorage/index.electron.ts` using `fs`). Once the
`loot-core` Vite alias was removed, the renderer bundle started pulling
those Node variants and crashed at runtime with
`It.default.platform is not a function` inside `platform.electron.ts`.
Introduce a distinct `electron-renderer` condition used only by
desktop-client's Vite config, and rename the `electron` key to
`electron-renderer` on the sole loot-core export whose `electron` branch
is the Electron renderer variant (`#/./platform/client/connection`, the
IPC `global.Actual.ipcConnect` file). Every other `electron`-conditioned
export keeps its Node semantics and is still matched by loot-core's own
`vite.desktop.config.ts` (`conditions: ['electron']`).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Drop .electron.* extensions from loot-core desktop resolver
Now that every Node/main variant is selected via the `electron` subpath
import condition in `packages/loot-core/package.json`, Vite's
`resolveExtensions` list no longer needs the `.electron.js`,
`.electron.ts`, `.electron.tsx` entries. Remove them to keep resolution
explicit and avoid implicit extension picking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Align desktop-client TS resolution with Vite
- Set `customConditions: ["electron-renderer"]` in
`packages/desktop-client/tsconfig.json` so TypeScript resolves
conditional imports (notably `@actual-app/core/platform/client/connection`)
to the same file Vite picks at runtime. Today the surfaces happen to
match because both variants import from a shared `index-types.ts`,
but the alignment prevents a latent drift bug.
- Fix typo in the release note (`Standartise` -> `Standardise`).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Publish loot-core (@actual-app/core) nightly first in workflow
* [autofix.ci] apply automated fixes
* Refactor imports and update configuration
- Updated .oxfmtrc.json to change "parent" to ["parent", "subpath"].
- Removed unnecessary blank lines in various TypeScript files to improve code readability.
- Adjusted import order in reports and rules files for consistency.
* Add workflow steps to pack and publish the core package nightly
* Remove nightly tag from npm publish command in workflow for core package
* Update post-build script comment to reflect correct workspace command for loot-core declarations
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] Switch typecheck from tsc to tsgo and fix Menu type narrowing
* [autofix.ci] apply automated fixes
* Add .gitignore for dist directory, update typecheck script in package.json to use -b flag, and remove noEmit option from tsconfig.json files in ci-actions and desktop-electron packages. Introduce typesVersions in loot-core package.json for improved type handling.
* Refactor SelectedTransactionsButton to improve type safety and readability. Updated items prop to use spread operator for conditional rendering of menu items, ensuring proper type annotations with MenuItem. This change enhances the clarity of the component's structure and maintains TypeScript compliance.
* Update tsconfig.json in desktop-electron package to maintain consistent formatting for plugins section. No functional changes made.
* [autofix.ci] apply automated fixes
* Update package.json and yarn.lock to add TypeScript 5.8.0 dependency. Adjust typesVersions in loot-core package.json for improved type handling. Enhance tsconfig.json in sync-server package to enable strictFunctionTypes for better type safety.
* Enhance tsconfig.json in ci-actions package by adding composite option for improved project references and build performance.
* [AI] Revert typescript to 5.9.3 for ts-node compatibility
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Update yarn.lock after TypeScript version change
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* Refactor Menu component for improved type safety and readability. Updated type assertions for Menu.line and Menu.label, simplified type checks in filtering and selection logic, and enhanced conditional rendering of menu items. This change ensures better TypeScript compliance and maintains clarity in the component's structure.
* Refactor Select and OpenIdForm components to improve type safety and simplify logic. Updated item mapping to handle Menu.line more effectively, enhancing clarity in selection processes. Adjusted SelectedTransactionsButton to streamline item creation and improve readability.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Promote typescript/restrict-template-expressions to error and fix violations
Convert the oxlint rule from "warn" to "error" and fix all 42 violations
by wrapping non-string template expressions with String(). This ensures
type safety in template literals across the codebase.
https://claude.ai/code/session_01Uk8SwFbD6HuUuo3SSMwU9z
* Add release notes for PR #7181
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Enable TypeScript composite project references across monorepo
- Add composite and declaration emit to all package tsconfigs
- Wire root and per-package project references in dependency order
- Replace cross-package include-based typing with referenced outputs
- Fix api TS5055 by emitting declarations to decl-output
- Add desktop-client alias for tests; fix oxlint import order in vite.config
- Add UsersState.data null type and openDatabase return type for strict emit
Co-authored-by: Cursor <cursoragent@cursor.com>
* Remove obsolete TypeScript configuration for API and update build script to emit declarations directly to the output directory. This streamlines the build process and ensures compatibility with the new project structure.
* Refactor TypeScript configuration in API package to remove obsolete decl-output directory and update build scripts. The changes streamline the build process by directing declaration outputs to the @types directory, ensuring better organization and compatibility with the new project structure.
* Add TypeScript declaration emission for loot-core in desktop-electron build process
* Refactor TypeScript configuration in API package to utilize composite references and streamline build scripts. Update include and exclude patterns for improved file management, ensuring better organization of declaration outputs and migration SQL files.
* Refactor TypeScript configuration in loot-core and desktop-client packages to streamline path management and remove obsolete dependencies. Update paths in tsconfig.json files for better organization and compatibility, and adjust yarn.lock to reflect changes in workspace dependencies.
* Update desktop-electron package to utilize loot-core as a workspace dependency. Adjust TypeScript import paths and tsconfig references for improved organization and compatibility across packages.
* Enhance Vite configuration for desktop-client to support Electron-specific conditions and update loot-core package.json to include Electron as a platform for client connection. This improves compatibility for Electron builds.
* Refactor TypeScript configuration across multiple packages to streamline path management. Update tsconfig.json files in root, api, and loot-core packages to improve import paths and maintain compatibility with internal typings.
* Update package dependencies and Vite configuration across component-library and desktop-client. Add vite-tsconfig-paths to component-library and remove it from desktop-client. Refactor Storybook preview file to include a TODO for future refactoring.
* Remove Node-specific path from loot-core package.json for client connection, streamlining platform configuration for Electron.
* Remove loot-core as a workspace dependency from desktop-electron package.json
* Update tsconfig.json to remove reference to desktop-client
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* [AI] Use loot-core workspace in desktop-electron and fix related types
- Add loot-core as workspace dependency in desktop-electron
- Import GlobalPrefsJson from loot-core package in desktop-electron
- Allow null in usersSlice data type (UsersState)
- Add explicit SQL.Database return type to openDatabase in sqlite electron
Made-with: Cursor
* Re-add loot-core as a workspace dependency in desktop-electron
* 🔖 (26.3.0)
* Remove used release notes
* Add release notes for PR #7097
* Remove used release notes
* Remove used release notes
* Add release notes for version 26.3.0
* Add new terms to spelling expectation list
* Fix spelling and capitalization in release notes
Corrected spelling of 'reorganisation' to 'reorganization' and updated 'coderabbit' to 'CodeRabbit' for consistency.
* Update patterns.txt to allowlist 'CodeRabbit'
Add 'CodeRabbit' to allowlist of proper nouns.
* Clarify chart theming support in release notes
Updated the release notes to specify bar/pie chart theming support and added details about theme variables for customization.
* Remove 'CodeRabbit' from spelling expectations
* Refactor release notes and improve formatting
Reorganize release notes for clarity and update content.
* Create 2026-03-02-release-26-3-0.md
* Change release date to 2026-03-02
Updated the release date for version 26.3.0.
* Update release notes for version 26.3.0
---------
Co-authored-by: jfdoming <9922514+jfdoming@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Julian Dominguez-Schatz <julian.dominguezschatz@gmail.com>
* [AI] Add per-package tsconfigs and typescript-strict-plugin for typecheck
Co-authored-by: Cursor <cursoragent@cursor.com>
* Update TypeScript configuration across multiple packages to correct plugin path key from "path" to "paths" and add reference to process-worker typings in index.electron.ts.
* Remove reference to process-worker typings in index.electron.ts and add new process-worker typings file for global Process augmentation.
* Refactor TypeScript build configurations across multiple packages by removing tsconfig.dist.json files and updating build scripts to use default TypeScript compilation. Adjusted compiler options to target ES2021 and enable declaration generation.
* Update TypeScript configuration in api package to refine include and exclude patterns for better file management.
* Update build script in api package to ensure migration SQL files are copied to the correct directory by creating the destination folder if it doesn't exist.
* Update TypeScript configurations in crdt and desktop-electron packages to refine include and exclude patterns for improved file management.
* Update TypeScript dependencies across multiple packages to include typescript-strict-plugin for enhanced type checking and maintain consistency in package.json files.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* [AI] Desktop client, E2E, loot-core, sync-server and tooling updates
Co-authored-by: Cursor <cursoragent@cursor.com>
* Refactor database handling in various modules to use async/await for improved readability and error handling. This includes updates to database opening and closing methods across multiple files, ensuring consistent asynchronous behavior. Additionally, minor adjustments were made to encryption functions to support async operations.
* Refactor sync migration tests to utilize async/await for improved readability. Updated transaction handling to streamline event expectations and cleanup process.
* Refactor various functions to utilize async/await for improved readability and error handling. Updated service stopping, encryption, and file upload/download methods to ensure consistent asynchronous behavior across the application.
* Refactor BudgetFileSelection component to use async/await for onSelect method, enhancing error handling and readability. Update merge tests to utilize async/await for improved clarity in transaction merging expectations.
* Refactor filesystem module to use async/await for init function and related database operations, enhancing error handling and consistency across file interactions. Updated tests to reflect asynchronous behavior in database operations and file writing.
* Fix typo in init function declaration to ensure it returns a Promise<void> instead of Proise<void>.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #6987
* Update tests to use async/await for init function in web filesystem, ensuring consistent asynchronous behavior in database operations.
* Update VRT screenshot for payees filter test to reflect recent changes
* [AI] Fix no-floating-promises lint error in desktop-electron
Wrapped queuedClientWinLogs.map() with Promise.all and void operator to properly handle the array of promises for executing queued logs.
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* Refactor promise handling in global and sync event handlers
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #6987
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>