* CLI: Search for config file in additional directories.
Searches in parents up to home directory, and in global config
directory. See changes to `packages/cli/README.md#config-file` for
full directory and filename details.
* Update CLI documention for config file location.
Also sync CLI config file documentation in packages/cli/README.md and
packages/docs/docs/api/cli.md.
* [autofix.ci] apply automated fixes
* Address CodeRabbit comments.
* Fix typos.
* Mention option of trusting CA cert in CLI docs.
Tangential to the rest of the PR, but hardly worth a standalone PR.
* Mention global config directory in release note
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
* [AI] Move actual-cli out of experimental status
* [AI] Rename CLI release note to a feature slug
---------
Co-authored-by: Claude <noreply@anthropic.com>
* 🔖 (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] Neutralize CSV formula-injection in CLI output and transaction export
Prefix cells starting with =, +, -, @, tab, or CR with a single quote so
that user-controlled strings (payee/account/category/tag names, notes,
etc.) cannot evaluate as formulas when the CSV is opened in Excel,
LibreOffice Calc, or Google Sheets. Numeric values are left unprefixed.
- packages/cli/src/output.ts: harden escapeCsv used by --format csv
- packages/loot-core/src/server/transactions/export/export-to-csv.ts:
pass a cast.string option to csv-stringify
* [AI] Simplify CSV formula-injection guard
- Drop the FormattedCell type; check typeof value === 'number' inline in
the CSV path instead of threading an isNumeric flag through formatCellValue
- Shorten verbose comments and drop standards-body references
* [AI] Remove @ts-strict-ignore from export-to-csv test
* [AI] Add release notes for CSV formula-injection fix
* [AI] Quote CSV cells containing carriage returns
Per RFC 4180, bare \r inside an unquoted field can be interpreted as
a record terminator. Extend escapeCsv to also quote on \r so neutralized
formula payloads (e.g. "'\rHELLO") are emitted as a single cell.
* [autofix.ci] apply automated fixes
* [AI] Rephrase release note in user-facing language
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] CLI: hide hidden categories by default in list commands
The `categories list` and `category-groups list` commands now exclude
hidden entries by default. Pass `--include-hidden` to include them, mirroring
the existing `--include-closed` flag for `accounts list`.
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
* [AI] Rename release note to 7785.md and update author
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
* [AI] CLI: simplify category-groups list and consolidate test setup
- Flatten the include-hidden ternary on category-groups list into a
single filter chain, mirroring categories list.
- Consolidate duplicated stderr/stdout spy setup into one outer
describe in categories.test.ts.
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
* [AI] Rename release note to 7786.md to match PR number
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
* [AI] Push hidden-category filtering down to the API/query layer
Add an optional \`hidden\` filter to \`api.getCategories\` and
\`api.getCategoryGroups\`. When set, the AQL query filters category groups
by hidden status and nested categories are filtered to match. Internal
callers (no options) keep the existing "return everything" behavior.
The CLI \`categories list\` and \`category-groups list\` commands now pass
\`{ hidden: false }\` instead of filtering client-side after fetching.
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
* [AI] Document new \`hidden\` option on getCategories and getCategoryGroups
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
* [AI] getCategories: include hidden categories from visible groups in list
When \`hidden: true\` was requested, the flat list only contained hidden
categories that lived inside hidden groups, because it was derived from
the same already-filtered groups used for the grouped view. A hidden
category sitting in a visible group was silently dropped.
Fetch the unfiltered groups for the list view and filter by
\`category.hidden\` so the list reflects every hidden category regardless
of its parent group's hidden status. The grouped view is unchanged.
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
* [AI] getCategories: query categories table directly when hidden=true
Replace the second \`getCategoryGroups()\` call (which loaded every group
plus its nested categories just to be flattened and filtered) with a
direct \`q('categories').filter({ hidden: true })\` AQL query. Same
result, one targeted query instead of fetching all groups.
The non-hidden=true paths are unchanged.
https://claude.ai/code/session_01DhYiicACsWb5NGHX71Wv4F
---------
Co-authored-by: Claude <noreply@anthropic.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] 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>
* [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>
* [AI] Fix accounts list: compute balances, hide closed, sort by budget group
- Replace empty `balance_current` (bank-sync field) with computed `balance`
from transaction history via `getAccountBalance`
- Filter out closed accounts by default; add `--include-closed` flag
- Stable-sort on-budget accounts before off-budget
- Add `balance_current` to AMOUNT_FIELDS for table/csv formatting
- Update docs and tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Extract duplicate isRecord type guard to shared utils
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Add types condition to api package exports for tsc resolution
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update packages/cli/src/commands/query.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* [AI] Add balance_available/balance_limit to AMOUNT_FIELDS, validate query result.data
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[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] Improve CLI query command with new flags, subcommands, and docs
Add --last, --count, --where, --offset, --group-by flags and field:desc
order-by syntax to make the query command more usable for both humans
and AI agents. Add query tables/fields subcommands for schema discovery.
Expand CLI and ActualQL documentation with comprehensive examples.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Fix parseOrderBy empty field validation and misleading aggregate docs
Validate that order-by field names are non-empty (e.g. ":desc" now throws
a clear error). Move AVAILABLE_TABLES before first use. Update group-by
examples in CLI help text and docs to use --file with proper aggregate
JSON instead of misleading --select with plain field names.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [autofix.ci] apply automated fixes
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [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>