9 Commits

Author SHA1 Message Date
Matiss Janis Aboltins
6c2c96e826 🔖 (26.5.0) (#7621)
* 🔖 (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>
2026-05-03 17:41:17 +00:00
Matiss Janis Aboltins
9acbd6388b [AI] Cache the CLI's local budget between invocations (#7539)
* [AI] Cache the CLI's local budget between invocations

Every `actual <cmd>` call currently delta-syncs the budget with the
sync server via `api.downloadBudget`, which hits the server's
500-req/min rate limit on scripted workflows. Actual is local-first:
once the budget is on disk, most read commands do not need fresh
server data.

Introduce a CLI-only cache layer inside `withConnection` that
decides per invocation whether to skip, sync, or re-download:

- Cache state lives at `{dataDir}/.actual-cli/{syncId}/state.json`,
  keyed by `syncId` to avoid the chicken-and-egg of not knowing the
  on-disk `budgetId` before the first download. The on-disk id is
  resolved via `api.getBudgets()` and persisted after first download.
- Read commands (list, balance, query run, …) skip the `/sync`
  call while `now - lastSyncedAt < cacheTtl`. Write commands
  (create, update, delete, set-*, etc.) sync before and after the
  operation to keep server state consistent.
- Encrypted budgets force a sync per call since `api/load-budget`
  does not re-verify the password.
- New `proper-lockfile`-backed shared/exclusive lock serializes
  writes while allowing parallel reads. Reader markers live in
  `{meta}/readers/`; writers sweep stale markers by PID.

New `actual sync` command with three modes: default (sync now),
`--status` (print cache age, TTL, stale flag), `--clear` (delete
cache, holding the exclusive lock to avoid racing writers).

New config surface, following the existing flag → env → config file
→ default precedence chain:

- `--cache-ttl <s>` / `ACTUAL_CACHE_TTL` / `cacheTtl` (default 60)
- `--refresh` / `--no-cache`
- `--lock-timeout <s>` / `ACTUAL_LOCK_TIMEOUT` / `lockTimeout` (10)
- `--no-lock` / `ACTUAL_NO_LOCK` / `noLock`

Every `withConnection` call site now passes an explicit
`{ mutates: boolean, skipBudget?: boolean }` so read/write intent is
visible at the edge.

The old `budgets sync` subcommand is removed — it silently diverged
from the new top-level `actual sync`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [AI] Simplify CLI cache/lock internals

Use a discriminated SyncDecision union so connection.ts no longer needs
non-null assertions on the cached state. Thread the resolved CliConfig
through withConnection's callback to drop duplicate resolveConfig calls
in the sync and budgets commands. Extract an errorCode helper and
replace the existsSync+readdirSync TOCTOU pattern in the reader-wait
polling loop with a single readdir that tolerates ENOENT.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [AI] Address PR #7539 review comments

- cache.ts: use a unique per-writer tmp filename so concurrent shared-
  lock writers (encrypted budgets, --refresh, stale TTL) don't clobber
  each other's publish and silently drop state updates.

- index.ts/config.ts: fix --no-cache and --no-lock flags. Commander
  stores --no-foo under the positive key (cache/lock) and an explicit
  false default makes the flag a no-op; the previous code also read
  the wrong keys (noCache/noLock) so the flags had no effect at all.
  Derive refresh/noLock from the correct keys.

- budgets.ts: invert encryption password precedence so the subcommand
  flag (--encryption-password) wins over env/config-file values.

- sync.ts: report stale=true in --status when lastSyncedAt is in the
  future, matching decideSyncAction's clock-skew handling.

- connection.ts: drop unnecessary `as` cast on api.getBudgets() now
  that the return type is Promise<APIFileEntity[]>.

- utils.ts: parseBoolEnv throws on unrecognized values instead of
  silently returning undefined so typos like ACTUAL_NO_LOCK=yes fail
  loudly.

- Shorten 7539 release note to a single user-facing sentence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:58:18 +00:00
Matt Fiddaman
9d91da77ec move from tsgo dev preview to beta (#7587)
* move from tsgo dev preview to beta

* note
2026-04-22 15:22:14 +00:00
Matt Fiddaman
2f49c5c400 add repository details to package.json files (#7578)
* add package URLs

* note
2026-04-21 17:40:11 +00:00
Matt Fiddaman
8c47374b9d ⬆️ mid-month dependency bump (#7506)
* typescript (^5.9.3 -> ^6.0.2)

* eslint-plugin-perfectionist (^5.6.0 → ^5.8.0)

* @types/node (^22.19.15 → ^22.19.17)

* @typescript/native-preview (^7.0.0-dev.20260309.1 → ^7.0.0-dev.20260404.1)

* eslint (^9.39.3 → ^9.39.4)

* lage (^2.14.19 → ^2.15.5)

* lint-staged (^16.3.2 → ^16.4.0)

* minimatch (^10.2.4 → ^10.2.5)

* vitest (^4.1.0 → ^4.1.2)

* better-sqlite3 (^12.6.2 → ^12.8.0)

* commander (^13.0.0 → ^13.1.0)

* cosmiconfig (^9.0.0 → ^9.0.1)

* @chromatic-com/storybook (^5.0.1 → ^5.1.1)

* @storybook/addon-a11y (^10.2.16 → ^10.3.4)

* @storybook/addon-docs (^10.2.16 → ^10.3.4)

* @storybook/react-vite (^10.2.16 → ^10.3.4)

* eslint-plugin-storybook (^10.2.16 → ^10.3.4)

* storybook (^10.2.16 → ^10.3.4)

* @codemirror/language (^6.12.2 → ^6.12.3)

* @react-aria/interactions (^3.27.0 → ^3.27.1)

* @swc/core (^1.15.18 → ^1.15.24)

* @swc/helpers (^0.5.19 → ^0.5.21)

* @tanstack/react-query (^5.90.21 → ^5.96.2)

* @uiw/react-codemirror (^4.25.7 → ^4.25.9)

* @vitejs/plugin-basic-ssl (^2.2.0 → ^2.3.0)

* i18next (^25.8.14 → ^25.10.10)

* lru-cache (^11.2.6 → ^11.2.7)

* react-grid-layout (^2.2.2 → ^2.2.3)

* react-i18next (^16.5.6 → ^16.6.6)

* rolldown (^1.0.0-rc.12 → ^1.0.0-rc.13)

* sass (^1.97.3 → ^1.99.0)

* adm-zip (^0.5.16 → ^0.5.17)

* csv-parse (^6.1.0 → ^6.2.1)

* csv-stringify (^6.6.0 → ^6.7.0)

* jest-diff (^30.2.0 → ^30.3.0)

* express-rate-limit (^8.3.0 → ^8.3.2)

* upgrade yarn to 4.13.0

* react-aria-components (^1.15.1 → ^1.16.0)

* @vitejs/plugin-react (^6.0.0 → ^6.0.1)

* @codemirror/state (^6.5.4 → ^6.6.0), @codemirror/view (^6.38.7 → ^6.41.0)

* react-aria (^3.46.0 → ^3.47.0)

* react-error-boundary (^6.0.3 → ^6.1.1)

* recharts (^3.7.0 → ^3.8.1)

* fast-check (4.5.3 → ^4.6.0)

* rollup-plugin-visualizer (^6.0.11 → ^7.0.1)

* commander (^13.1.0 → ^14.0.3)

* note

* coderabbit feedback, and a test for good measure

* typescript (^5.9.3 -> ^6.0.2)

* @playwright/test (1.58.2 -> 1.59.1)

* yarn dedupe
2026-04-15 17:05:26 +00:00
Matiss Janis Aboltins
65b154151f [AI] Enable subpath imports across all packages (#7462)
* [AI] Enable subpath imports across all packages

Generalize the prefer-subpath-imports ESLint rule to work with any
package (not just loot-core) and enable it globally. Add subpath import
mappings to cli, component-library, and sync-server package.json files.
Auto-fix all backtracked relative imports to use #-prefixed subpath
imports.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* [AI] Add release notes for #7462

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* [AI] Fix mock specifiers in accounts.test.ts to use aliased imports

Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>

* [AI] Fix mock specifiers in query.test.ts to use aliased imports

Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>

* [AI] Fix ESLint rule to properly validate src/ directory paths

Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>

* [AI] Add publishConfig.imports for sync-server to remap aliases to build directory

Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
2026-04-11 08:56:49 +00:00
dependabot[bot]
5eaf0be744 Bump vite from 8.0.0 to 8.0.5 (#7398)
* Bump vite from 8.0.0 to 8.0.5

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.0 to 8.0.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

* note

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
2026-04-07 10:28:57 +00:00
Matt Fiddaman
a12b971670 🔖 (26.4.0) (#7389)
* bump versions

* Remove used release notes

* add docs pages

* Update check-spelling metadata

* bump cli

* change release date

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-05 18:12:51 +01:00
Matiss Janis Aboltins
a43b6f5c47 [AI] Experimental CLI tool for Actual (#7208)
* [AI] Add @actual-app/cli package

New CLI tool wrapping the full @actual-app/api surface for interacting with
Actual Budget from the command line. Connects to a sync server and supports
all CRUD operations across accounts, budgets, categories, transactions,
payees, tags, rules, schedules, and AQL queries.

* Refactor CLI options: replace `--quiet` with `--verbose` for improved message control. Update related configurations and tests to reflect this change. Adjust build command in workflow for consistency.

* Refactor tests: streamline imports in connection and accounts test files for improved clarity and consistency. Remove dynamic imports in favor of static imports.

* Enhance package.json: Add exports configuration for module resolution and publish settings. This includes specifying types and default files for better compatibility and clarity in package usage.

* Update package.json exports configuration to support environment-specific module resolution. Added 'development' and 'default' entries for improved clarity in file usage.

* Enhance CLI functionality: Update configuration loading to support additional search places for config files. Refactor error handling in command options to improve validation and user feedback. Introduce new utility functions for parsing boolean flags and update related commands to utilize these functions. Add comprehensive tests for new utility functions to ensure reliability.

* Update CLI TypeScript configuration to include Vitest globals and streamline test imports across multiple test files for improved clarity and consistency.

* Update CLI dependencies and build workflow

- Upgrade Vite to version 8.0.0 and Vitest to version 4.1.0 in package.json.
- Add rollup-plugin-visualizer for bundle analysis.
- Modify build workflow to prepare and upload CLI bundle stats.
- Update size comparison workflow to include CLI stats.
- Remove obsolete vitest.config.ts file as its configuration is now integrated into vite.config.ts.

* Enhance size comparison workflow to include CLI build checks and artifact downloads

- Added steps to wait for CLI build success in both base and PR workflows.
- Included downloading of CLI build artifacts for comparison between base and PR branches.
- Updated failure reporting to account for CLI build status.

* Update documentation to replace "CLI tool" with "Server CLI" for consistency across multiple files. This change clarifies the distinction between the command-line interface for the Actual Budget application and the sync-server CLI tool.

* Refactor configuration to replace "budgetId" with "syncId" across CLI and documentation

* Enhance configuration validation by adding support for 'ACTUAL_ENCRYPTION_PASSWORD' and implementing a new validation function for config file content. Update documentation to clarify error output format for the CLI tool.

* Enhance configuration tests to include 'encryptionPassword' checks for CLI options and environment variables, ensuring proper priority handling in the configuration resolution process.

* Update nightly versioning script to use yarn

* Align versions

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-18 18:22:38 +00:00