Commit Graph
278 Commits
Author SHA1 Message Date
Tim 1d8570d6b8 Apply suggestion from @tim-smart 2026-11-06 08:38:48 +00:00
Tim Smart 02a53448de [AI] Start the budget range at the earliest persistent rollover
A month's rollover reaches later months through the previous month's
chain cell, so a budget opened after its created months had moved past
the toggled month lost the flag. Also note in the docs that auto hold
enabled before this version still stops until it's enabled again.
2026-11-06 08:38:48 +00:00
Tim Smart 312f3cc922 [AI] Make new rollover toggles persistent instead of seeding old windows
Switching rollover or auto hold on now stores 2, which following months
without a flag continue. A 1 keeps its old meaning of on for that month
only, so runs written by earlier versions end where they always did and
no existing balance changes. That removes the need for the carryover
seed, its post-sync and load-time scheduling, the seeded preference and
the budget table filter it relied on.
2026-11-06 08:38:48 +00:00
fd0715a37a [AI] Show a goal progress ring beside underfunded category balances (#9297)
* [AI] Show goal funding status and an Assign action in balance menus

Use the existing Budget Automation engine to add a panel to category
balance menus with the month's recommendation, what is assigned so far,
what is still needed, and an Assign action that adds the money still
needed (undoable).

- budget/category-funding reads the dryRunCategoryTemplate projection
  without writing goal_def; categories without funding templates get
  null, and invalid automations fail closed.
- budget/fund-category recomputes on the server, assigns the full
  recommendation and goal in one batch, and is a no-op when already
  funded.
- Funding reads are gated by the goal templates flag, only run for
  categories with templates, and refresh after data changes and funding.
- Covers desktop and mobile envelope and tracking balance menus,
  including tracking income categories.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJDNR72i3yEZttwMUuk4cq

* [AI] Fold goal funding into the existing goal status and never overbudget

Address review feedback on the category funding change:

- Replace the separate funding panel with the existing goal status. It
  now shows at the top of the desktop envelope and tracking balance
  menus (as it already did on mobile) with a thin progress bar, and the
  desktop hover tooltip is removed along with its tooltipDisabled
  workaround.
- Replace the Assign button with a "Fund goal from To Budget" balance
  menu item (envelope only, not for long-term goals) that uses the
  existing undoable transfer-available action, so it never moves more
  than To Budget and never lowers a budget. It is hidden when the goal
  is met or To Budget is empty.
- Drop the live dry-run endpoint, the fund-category endpoint, their
  client queries and refresh wiring, and the tracking income additions.
  Status, bar, colour and fund amount now all read the stored goal.
- Add transferAvailable tests and menu wiring tests, and update the
  budget automation docs for the moved goal status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJDNR72i3yEZttwMUuk4cq

* [AI] Show goal status as a colored pill on category balances

Draw the balance of a category with a goal as a pill with an icon:
yellow with a clock when underfunded, green with a check when funded
and red with an exclamation when overspent. Categories without a goal,
or with goal templates off, render as before.

- The pill, the balance colour and the goal status share one comparison
  (compareToGoal/getGoalFundingState), made on displayed amounts so they
  agree when decimals are hidden.
- Desktop envelope and tracking tables and the mobile budget table;
  narrow desktop columns drop the icon to keep the amount readable, and
  mobile amounts shrink to fit instead of being cut off.
- Status is announced to screen readers, not shown by colour alone.
- Pill colours get their own theme tokens so the funded pill keeps
  enough contrast in the midnight theme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJDNR72i3yEZttwMUuk4cq

* [AI] Move GoalStatus into its own file

GoalStatus isn't specific to BalanceWithCarryover, so give it a
type-strict module of its own alongside its row helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Update goal status screenshots to show the balance menu

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Clarify how funding a goal affects next month's To Budget

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Update docs screenshots to show the goal status pill

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Describe the underfunded goal status as yellow in the docs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Update mobile budget template VRT snapshots for the goal status pill

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Replace the goal status pill with a goal progress ring

Keep category balances in their usual colours and draw a small ring
beside balances with a goal instead: a gold arc that fills as the goal
is funded, and a green check once it is met. Overspent balances stay red
like any other negative amount, without an extra marker.

The ring sits beside the amount in the balance cell on desktop, inside
the balance pill on mobile, and next to the heading of the goal status
in the balance menu, so one shape carries the status everywhere. The
pill-only theme tokens are removed, the docs text and screenshots and
the mobile VRT snapshots are updated, and the release note is replaced.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4sNu2G32qCLcAe2YznUCM

* [AI] Only mark goals that still need money, with a filling ring

Draw the goal ring only beside balances whose goal is not met yet, so a
fully funded budget looks like one without goals and the one mark in the
table points at rows that still need money. The ring is a single gold
pie: a hollow outline when nothing is funded yet, a wedge that grows
with the funded share and that never closes, since the ring disappears
the moment the goal is met. Funded rows carry no mark and overspent
rows stay red like any other negative amount.

The glyph shrinks to 10px to sit within the cap height of the figures
and draws in one theme token, so it keeps 3:1 contrast on every surface
in all three themes. The amount keeps its full width in narrow month
columns; the ring is what yields. The balance menu shows the same ring
only beside "Underfunded", as its legend. The three-way funding state
is replaced by one helper that returns the progress to draw or nothing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4sNu2G32qCLcAe2YznUCM

* [AI] Keep the funded balance green, ring only while the goal is unmet

A category whose goal is met keeps the green balance the goal templates
feature already gives it, so a met goal still reads differently from no
goal. The ring stays the only mark on an unfunded goal; its amount keeps
the normal colour instead of upstream's gold text.

Docs text and screenshots, the release note and the mobile template VRT
snapshots follow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4sNu2G32qCLcAe2YznUCM

* [AI] Keep funded balances green in the mobile balance sheet and the ring in view

- Add an explicit isIncome prop instead of reading isDisabled as "income",
  so the mobile balance sheet header (which is only disabled because it is
  not clickable) colours a funded balance green again, and mobile income
  balances keep their hover style
- Let a long amount shrink beside the ring on desktop so the ring is not
  pushed out of the column
- Describe the ring instead of yellow balances in the goal directive docs
- Drop a snapshot change that had no visible difference

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Drop the ring from the goal status in the balance menu

The progress bar right below it already shows the same thing, so the menu
keeps its plain status line. Retake the balance menu screenshots in the
docs to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Keep the balance yellow while its goal is unmet

Per review, an unmet goal keeps the yellow balance text it has on master and
gains the progress ring beside it, so every category with a goal is
coloured. The balance colour logic is back to master's; the docs and their
screenshots describe and show yellow text with the ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Show income goals only in tracking budgets

Envelope budgets don't apply templates to income categories, so the
balance now ignores an income goal only when the budget is not
tracking, instead of on every income category. Tracking income pills
get their goal colour back and show the ring when underfunded. The
envelope income balance sheet no longer shows a goal status, and the
mobile income group menu no longer offers "Overwrite with templates"
in envelope budgets.

The isIncome props on the tracking budget table and balance menu are
removed, since those only ever render expense categories.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MRjoaUi1WAUGsSNp3sb7p

* [AI] Keep goals from one budget type out of the other

Envelope and tracking budgets share spreadsheet cell names, so a goal
from one type could show up after switching to the other:

- Switching type (by sync, undo or redo) left the old type's cells in
  the saved spreadsheet cache, and goals came back from it on the next
  open. setType now clears the cache and waits for the budget values to
  reload.
- Changes to the inactive type's budget table were still applied to the
  sheet. Only the active table's rows are applied now.
- Applying templates to specific categories wrote amounts and goals for
  income categories in envelope budgets, and saving automations stored
  their goals. Envelope budgets now skip income categories in both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MRjoaUi1WAUGsSNp3sb7p

* [AI] Show income goals on the desktop tracking budget

Desktop tracking budgets have no balance column for income categories,
so their goals showed nowhere, while the mobile income pill already
showed them. An income category with a goal now shows the goal colour
on its received amount, with the ring while underfunded. Income
categories without a goal, and budgets with goal templates off, keep
the plain received amount.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018MRjoaUi1WAUGsSNp3sb7p

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: youngcw <calebyoung94@gmail.com>
2026-11-05 19:48:15 +00:00
Michael ClarkandGitHub a4830bf639 Remove actual-appimage link from installation guide (#9429)
* Remove actual-appimage link from installation guide

* Remove AUR actual-appimage from install docs

Removed references to AUR actual-appimage from community installation documentation for clarity.

* Remove actual AppImage from documentation
2026-11-04 14:14:46 +00:00
b13f5c299e [AI] Release Akahu bank sync as a stable feature (#9426)
Remove the experimental akahuBankSync feature flag so the Akahu provider
is always shown on the Bank Sync page.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-04 14:13:03 +00:00
Michael ClarkandGitHub a3a1c7fc41 📈 Monte Carlo - Stop the min spending from raising the spending above planned (#9414)
* stop the min spending floor from raising the spending above planned

* feedback
2026-11-03 22:15:02 +00:00
15571bd6bb [AI] Update MASH documentation link (#9425)
MASH moved each service's documentation into its component directory, so docs/services/actual.md now 404s.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 21:27:25 +00:00
TimandGitHub b450a9f269 [AI] Add "Average of previous weeks" budget automation (#9405)
* [AI] Add "Average of previous weeks" budget automation

* [AI] Keep weekly average unrounded and label fixed adjustments per week

* [AI] Simplify weekly average template plumbing

- Collapse the historical template type conversions in the automation
  reducer into one helper instead of six pairwise cases.
- Dispatch the adjustment update once from AmountAdjustment; the template
  type discriminant narrows the payload without branching.
- Drop the redundant early return in trimWeeklyAverageWindow: the general
  formula already returns the untouched window when activity predates it.

* Update upcoming-release-notes/average-of-previous-weeks-automation.md

* [AI] Default weekly average automations to 12 weeks

* [AI] Only carry percentage adjustments between monthly and weekly averages

* [AI] Run weekly averages through the average template and share the weekday count

* [AI] Share the weekday names with the date utils

* [AI] Trim weekly average tests to the essential cases

* Apply batched suggestions from code review

Co-authored-by: Tim <hello@timsmart.co>

* Apply suggestion from @tim-smart

* Apply suggestion from @tim-smart

* Apply suggestion from @tim-smart
2026-11-03 19:01:57 +00:00
github-actions[bot]GitHubgithub-merge-queuegithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Julian Dominguez-Schatz
741d1615b7 🔖 (26.11.0) (#9321)
* 🔖 (26.11.0)

* Generate release notes for v26.11.0

* Generate release notes for v26.11.0

* [AI] Add November release highlights and upgrade notices

* Generate release notes for v26.11.0

---------

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: Julian Dominguez-Schatz <julian.dominguezschatz@gmail.com>
2026-11-02 00:11:25 +00:00
fd08b56eef [AI] Store amounts of every currency with two implied decimals (#9313)
* [AI] Name the stored scale of amounts

- Add STORED_DECIMAL_PLACES: amounts are stored with two implied decimals whatever the currency, and a currency's own decimals only decide how many digits are shown
- Make integerToCurrencyWithDecimal with a currency divide by 100 and show that currency's digits
- Remove amountToCurrencyInteger, which had no callers and stored amounts with the currency's decimals
- Update the tests

Issue: actualbudget/actual#8858

* [AI] Show and read amounts at the stored scale in every currency

- Make useFormat divide and multiply by 100 for every currency, so balances, totals, budget cells, rules, schedules, filters and reconciliation agree with the register, imports and bank sync
- Take typed digits as whole units for currencies without decimals in the desktop and mobile amount inputs
- Read formula card results at the stored scale
- Add tests for useFormat and the mobile amount input in dollars and yen

Issue: actualbudget/actual#8858

* [AI] Use the stored scale in budget templates and goals

- Convert template, goal, limit and schedule adjustment amounts with two implied decimals for every currency, and round to whole units of the currency when decimals are hidden
- Remove the currency from the template engine, which no longer needs it
- Read and write the goal editors' amounts at the stored scale
- Update the yen template tests

Issue: actualbudget/actual#8858

* [AI] Show budget movement notes at the stored scale

- Divide amounts by 100 and show the currency's digits in the notes written when money moves between categories
- Add a yen test

Issue: actualbudget/actual#8858

* [AI] Document that amounts are always stored x100

- State in the API docs that amounts are always the value x 100, whatever the currency
- Add the release note

Issue: actualbudget/actual#8858

* [AI] Reduce tests to the stored-scale change

- Drop the JPY template tests: the template engine no longer reads the currency
- Drop the round-trip test of the removed amountToCurrencyInteger
- Keep one yen case each for useFormat and the mobile amount input

* [AI] Simplify the stored-scale change

- Remove STORED_DECIMAL_PLACES and the unused decimalPlaces parameter of integerToCurrency
- Format budget movement notes with integerToCurrencyWithDecimal
- Drop the toAmount/fromAmount wrappers in useFormat
- Mobile amount input: format through useFormat so currencies without decimals show whole units while editing and after saving, whatever the hideFraction setting
- Drop the movement notes test, now covered by the integerToCurrencyWithDecimal tests

* [AI] Compare goals at the stored scale

Master's goal helper (#9304) still divided by the currency's decimal places.
Round to the currency's displayed digits through the formatter instead, and
return the difference ×100.

* [AI] Skip separator reformatting for whole-unit mobile entry

The zero-decimal branch strips every non-digit before formatting, so
reapplying thousands separators first did nothing there. Only the
two-decimal branch needs the reformatted text.

* [AI] Tidy comments, API docs and release note for stored amounts

* [AI] Keep stored fractions in edit text

forEdit rounded a stored fraction to the currency's digits, so focusing and
leaving an amount field unedited saved the rounded value (¥1,500.50 became
¥1,501). Show two decimals while editing when the stored value has a
fraction, unless fractions are hidden.

* [AI] Keep the exact amount when an amount field is left unedited

With decimals hidden, the edit text rounds a stored fraction (¥1,500.50
shows as 1,501), and blur, Enter or Tab saved that rounded text. The
desktop amount input, the financial input and budget cells now keep the
original amount when the text is unchanged.

* [AI] Track edits instead of comparing amount text

Comparing the text with the edit form missed the display text left after
Enter or a sign toggle, and treated clearing and retyping the rounded value
as untouched. Track whether the user typed: the desktop amount input keeps
the exact amount its text stands for, and the financial input and budget
cells parse only edited text.

---------

Co-authored-by: Tim Smart <hello@timsmart.co>
2026-10-27 09:12:35 +00:00
d9d15c12fa [AI] Scroll to and highlight the other side of a transfer (#9326)
* [AI] Center list items correctly near the edges of a list

- Center an item by the offset that puts it in the middle, kept within the list, instead of jumping to the top whenever the list can scroll less than half its height
- Add tests

Issue: rapastranac/actual#10

* [AI] Scroll to and highlight the other side of a transfer

- Pass the linked transaction along when the transfer arrow opens the other account
- Load more of that account until the transaction is there, open its split, center it and point it out briefly with a pulse, or a steady highlight with reduced motion; leave the account at the top when the current view can't show it
- Keep the transaction in view while it's pointed out, also while rows load above it; drop it when the user searches, and ignore results of a query replaced since
- Add tests

Issue: rapastranac/actual#10

* [AI] Document finding the other side of a transfer

- Explain the transfer arrow in the transfers docs and add a release note

Issue: rapastranac/actual#10

* [AI] Reduce the tests for pointing out the other side of a transfer

- Keep one list test for the case that used to jump to the top and one for a centered item
- Check the pulse and its end in a single table test

* [AI] Load up to the other side of a transfer in one query

Use PagedQuery.refetchUpToRow instead of paging until the transaction
shows up, and only look for it in the account's first query so a sort
or filter applied meanwhile drops it. refetchUpToRow keeps the data as
it is when the row isn't in the query instead of throwing.

* [AI] Keep loading the other side of a transfer through a sync refresh

A sync refresh while loading the account up to the transaction dropped
the loaded rows, and the next onData gave up on it. fetchData now tells
whether a newer request superseded it, and the account loads again in
that case, giving up only when the query doesn't have the transaction.

* [AI] Fetch up to a row through sync refreshes in PagedQuery

A refresh during refetchUpToRow now makes it fetch again instead of
replacing its rows, and refetchUpToRow resolves once the rows up to the
row are loaded. The account awaits it and reads the transaction from
the loaded rows instead of guessing from the order of onData calls,
which drops the retry loop and the superseded flag on fetchData.

* [AI] Find the other side of a transfer on the account's current query

React can call componentWillReceiveProps twice for one account change,
which fetches the account twice. The pending transaction was tied to the
first query, which the second replaced, so it was never shown. Look for
it on the first load of the current query instead, as long as the
account isn't sorted.

refetchUpToRow also refetches the loaded rows when the row is missing
instead of keeping them, so a row deleted by a sync during the fetch
doesn't stay listed.

* [AI] Tidy the transfer focus code and its comments

---------

Co-authored-by: Tim Smart <hello@timsmart.co>
2026-10-27 03:02:09 +00:00
21c2b3f703 [AI] Show a category's goal as soon as its automations are saved (#9304)
* [AI] Record a category's goal when its automations are saved

Saving automations in the editor now also stores the goal it projects
for that month, without changing the budgeted amount, so the goal
status and "Fund goal from To Budget" work without running templates.
Undo now also clears the goal on a newly created budget row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Make the goal status agree with the balance colour

The balance menu's goal status, progress bar and "Fund goal from To
Budget" item now compare amounts as they are displayed, like the
balance colour does, using the currency's own decimal places so
currencies without decimals are not rounded to the nearest hundred.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Drop an unneeded cast in the goal-on-save tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Show the goal shortfall between the displayed amounts

With hidden decimals the goal status could read "Underfunded (0)", because
the label compared the displayed amounts while the amount in brackets used
the raw difference. Both now use the difference between the displayed
amounts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-26 16:20:42 +00:00
bd2b08240d [AI] Submit App Store releases automatically and move TestFlight uploads to nightly (#9330)
* [AI] Submit App Store releases automatically and move TestFlight uploads to nightly

On a published release both the iOS and Mac App Store workflows now wait for
Apple to process the uploaded build, attach it to the App Store version for
the release, fill in the release notes and submit it for review with
automatic release after approval. The TestFlight uploads run on a nightly
schedule instead of on every master push.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] Publish App Store builds with the Codemagic App Store Connect CLI

Replace the hand-written submission script and the altool upload with
`app-store-connect publish`, which uploads the build, waits for processing
and submits it for review in one step. The iOS export now writes the .ipa
locally so the CLI can upload it, matching the Mac flow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] Run the App Store Connect CLI through pipx instead of a virtualenv

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] Share the App Store Connect publish step between the iOS and Mac workflows

Move the upload and review submission into one composite action so the CLI
version and submission flags live in a single place, drop step outputs that
nothing read, clean up signing material right after signing instead of after
the processing wait, and remove export options that were already defaults.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] Do not submit prereleases for App Store review

Prereleases still upload to TestFlight; only full releases are submitted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] Send TestFlight builds to the external beta testers group

Every uploaded build is now added to the "Beta testers" TestFlight group and
submitted for Beta App Review, so external testers get the nightly builds
without a manual step. The FAQ links to the public TestFlight invite.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] Wait for the uploaded build to appear before the processing wait

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-26 15:00:51 +00:00
Julian Dominguez-SchatzandGitHub 97a7ca50f3 [AI] Add per-budget SimpleFIN credentials (#9214)
* [AI] Add per-budget SimpleFIN credentials

* [AI] Clear budget credentials when switching SimpleFIN to global

* [AI] Reject SimpleFIN access to deleted budgets

* [AI] Use distinct keys in SimpleFIN isolation test
2026-10-23 12:46:49 +00:00
6ef6d303d4 [AI] Show goal progress in the balance menu and fund goals from To Budget (#9281)
* [AI] Show goal funding status and an Assign action in balance menus

Use the existing Budget Automation engine to add a panel to category
balance menus with the month's recommendation, what is assigned so far,
what is still needed, and an Assign action that adds the money still
needed (undoable).

- budget/category-funding reads the dryRunCategoryTemplate projection
  without writing goal_def; categories without funding templates get
  null, and invalid automations fail closed.
- budget/fund-category recomputes on the server, assigns the full
  recommendation and goal in one batch, and is a no-op when already
  funded.
- Funding reads are gated by the goal templates flag, only run for
  categories with templates, and refresh after data changes and funding.
- Covers desktop and mobile envelope and tracking balance menus,
  including tracking income categories.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJDNR72i3yEZttwMUuk4cq

* [AI] Fold goal funding into the existing goal status and never overbudget

Address review feedback on the category funding change:

- Replace the separate funding panel with the existing goal status. It
  now shows at the top of the desktop envelope and tracking balance
  menus (as it already did on mobile) with a thin progress bar, and the
  desktop hover tooltip is removed along with its tooltipDisabled
  workaround.
- Replace the Assign button with a "Fund goal from To Budget" balance
  menu item (envelope only, not for long-term goals) that uses the
  existing undoable transfer-available action, so it never moves more
  than To Budget and never lowers a budget. It is hidden when the goal
  is met or To Budget is empty.
- Drop the live dry-run endpoint, the fund-category endpoint, their
  client queries and refresh wiring, and the tracking income additions.
  Status, bar, colour and fund amount now all read the stored goal.
- Add transferAvailable tests and menu wiring tests, and update the
  budget automation docs for the moved goal status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJDNR72i3yEZttwMUuk4cq

* [AI] Move GoalStatus into its own file

GoalStatus isn't specific to BalanceWithCarryover, so give it a
type-strict module of its own alongside its row helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Update goal status screenshots to show the balance menu

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

* [AI] Clarify how funding a goal affects next month's To Budget

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpAtycTVCRhkLcuD6AJeTM

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: youngcw <calebyoung94@gmail.com>
2026-10-21 21:09:10 +00:00
StephanandGitHub ffc68afae0 [AI] docs: add Pethost to Additional Installation Options (#9222)
* [AI] docs: add Pethost to Additional Installation Options

* [AI] docs: link Pethost's template page
2026-10-19 19:57:30 +00:00
Julian Dominguez-SchatzandGitHub 7474a94299 [AI] Restrict SimpleFIN private network access to configured ranges (#9245) 2026-10-18 22:01:42 +00:00
f36804f046 [AI] Return what a bank sync reconciled from the API's runBankSync (#8998)
* Return what a bank sync reconciled from the API's runBankSync

`accounts-bank-sync` and `simplefin-batch-sync` already reconcile each
account and report the transactions they added and matched, but
`api/bank-sync` destructured `{ errors }` out of that and returned nothing.
An API consumer could tell a sync had succeeded, not whether it had done
anything, so tools built on the API either notify on every scheduled run or
diff the transaction table themselves to find out.

The handler now collects `newTransactions`, `matchedTransactions` and
`updatedAccounts` across both the single-account and batch paths and returns
them. Errors still throw, so a resolved promise continues to mean the sync
succeeded, and `void` to an object breaks no existing caller. This also
makes `runBankSync` consistent with `importTransactions`, which already
surfaces its reconciliation result.

Verified against a live sync server with a GoCardless-linked account, two
runs back to back:

  published 26.9.0   undefined
  first run          16 newTransactions, 0 matched, 1 updatedAccount
  second run         0, 0, 0

All 16 returned ids resolve to real transactions in the ledger. The second
run is the case this is for: successful, and nothing happened.

* Address review: real error fixtures, existing doc convention, bounded appends

Three fixes from the CodeRabbit review.

The docs entry named a `BankSyncResult` type that does not exist anywhere in
the repo. It now spells the shape inline, the way the neighbouring
`importTransactions` entry already does.

The test fixtures passed a bare string where a sync error goes, but a real
SyncError is an object and the handler reads two fields off it:
getBankSyncError(errors[0]) for the message and errors[0].code for the code
it attaches. The code half was therefore never exercised. Fixtures are now
typed SyncResponseWithErrors with a real error object, the mock reads
`.message` like the real helper, and a new test asserts the code reaches the
thrown error. Confirmed it fails if `withErrorCode` is dropped.

The id lists are appended one at a time instead of spread, since they are as
long as the sync is big. `allErrors` keeps its existing spread: it is bounded
by the account count, not by the transaction count.

* docs(api): type runBankSync's result and mark its argument optional

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YPyenH5t6DHfoqqkXLWfEn

* [AI] docs(api): correct runBankSync's updatedAccounts and note partial imports on rejection

updatedAccounts only lists accounts that received new transactions, not
accounts whose balance was refreshed. When syncing every account, one
failing account rejects the call after the others have already imported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011AwAzzZALs5RFb454j3cMV

* [AI] docs(api): say runBankSync's arrays are empty only when nothing was added or updated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnubtGYPLiUFthYYeUxMaY

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 11:19:11 +00:00
Michael ClarkandGitHub 8d59f30cfb 📈 Monte carlo investment phases (#9233)
* investment phases

* screenshot update

* feedback
2026-10-17 07:51:44 +00:00
Matt FiddamanandGitHub 63180ceeab ⬆️ october dependency bump (#9244)
* @types/node (^22.20.1 → ^22.20.5)

* eslint (^10.7.0 → ^10.12.0)

* eslint-plugin-perfectionist (^5.10.0 → ^5.12.1)

* knip (^6.27.0 → ^6.41.0)

* lage (^2.15.17 → ^2.17.0)

* minimatch (^10.2.5 → ^10.2.6)

* p-limit (^7.3.0 → ^7.3.3)

* vitest (^5.0.0 → ^5.0.4)

* uuid (^14.0.2 → ^14.0.3)

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

* vite (^8.1.5 → ^8.3.4)

* @bufbuild/protobuf, @bufbuild/protoc-gen-es (^2.12.1 → ^2.16.0)

* @chromatic-com/storybook (^5.2.1 → ^5.5.1), @storybook/addon-a11y, @storybook/addon-docs, @storybook/react-vite, eslint-plugin-storybook, storybook (^10.5.2 → ^10.6.2)

* fix tests

* @internationalized/date (^3.12.2 → ^3.12.4), react-aria-components (^1.19.0 → ^1.22.1), react-aria (^3.50.0 → ^3.53.1)

* @rolldown/plugin-babel (~0.2.3 → ~0.2.4)

* @testing-library/react (16.3.2 → 16.3.3), @testing-library/dom (10.4.1 → 10.4.2), @testing-library/user-event (14.6.1 → 14.6.8)

* @types/react (^19.2.17 → ^19.3.0), @types/react-dom (^19.2.3 → ^19.3.0)

* @vitejs/plugin-react (^6.0.3 → ^6.1.2)

* react, react-dom (19.2.7 → 19.3.0)

* @babel/core (^8.0.1 → ^8.0.7)

* @codemirror/language (^6.12.4 → ^6.13.1), @codemirror/state (^6.7.1 → ^6.7.6), @codemirror/view (^6.43.6 → ^6.43.14), @lezer/highlight (^1.2.3 → ^1.2.5), @uiw/react-codemirror (^4.25.11 → ^4.25.12)

* @fontsource-variable/inter, @fontsource/redacted-script (^5.2.8 → ^5.3.0)

* @reduxjs/toolkit (^2.12.0 → ^2.13.0)

* @tanstack/react-query (^5.101.2 → ^5.104.2)

* csv-stringify (^6.8.1 → ^6.9.0)

* es-toolkit (^1.49.0 → ^1.52.0)

* hyperformula (^3.3.0 → ^3.5.0)

* i18next (^26.3.6 → ^26.4.4)

* i18next-resources-to-backend (^1.2.1 → ^1.2.3)

* lru-cache (^11.5.2 → ^11.5.3)

* react-error-boundary (^6.1.2 → ^6.1.6)

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

* react-i18next (^17.0.10 → ^17.0.16)

* react-router (8.3.0 → 8.4.0)

* recharts (^3.9.2 → ^3.10.1)

* rolldown (^1.2.0 → ^1.2.13)

* sass (^1.101.0 → ^1.105.1)

* @easyops-cn/docusaurus-search-local (^0.55.2 → ^0.55.3)

* @r74tech/docusaurus-plugin-panzoom (^2.4.2 → ^2.5.0)

* eslint-vitest-rule-tester (^3.1.0 → ^3.2.0)

* csv-parse (^7.0.2 → ^7.0.3)

* fast-check (^4.9.0 → ^4.10.2)

* jest-diff (^30.4.1 → ^30.5.2)

* yargs (^18.0.0 → ^18.2.0)

* @capacitor/android (^8.4.3 → ^8.5.3), @capacitor/core, @capacitor/cli (^8.4.2 → ^8.5.3)

* express (^5.2.1 → ^5.3.0)

* express-rate-limit (^8.6.0 → ^8.7.1)

* ipaddr.js (^2.4.0 → ^2.5.0)

* supertest (^7.2.2 → ^7.3.1)

* oxlint, @oxlint/plugins (^1.74.0 → ^1.88.0), oxlint-tsgolint (^0.25.0 → ^7.0.2004)

* oxfmt (^0.59.0 → ^0.73.0)

* cosmiconfig (^9.0.2 → ^10.0.1)

* @testing-library/jest-dom (^6.9.1 → ^7.0.1)

* jsdom (^29.1.1 → ^30.1.2)

* vite-plugin-pwa (^1.3.0 → ^2.0.0)

* argon2 (^0.44.0 → ^0.45.1)

* pluggy-sdk (^0.89.0 → ^0.92.0)

* note

* bump crdt

* Revert "@capacitor/android (^8.4.3 → ^8.5.3), @capacitor/core, @capacitor/cli (^8.4.2 → ^8.5.3)"
2026-10-17 02:02:36 +00:00
Michael ClarkandGitHub cba8cbd3f9 📈 Monte Carlo pot balances chart (#9158)
* monte carlo pot balances

* feedback

* regenerating screenshots
2026-10-12 21:01:31 +00:00
Matt FiddamanGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
425a0a0f0e make sidebar menu items configurable (#9193)
* make toggle switches reachable by keyboard

* route sidebar pages from a configurable menu

* add a sidebar menu setting

* build command bar navigation from the sidebar menu

* docs

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #9193

* coderabbit

* remove modal

* jfdoming feedback

* coderabbit

* Update VRT screenshots

Auto-generated by VRT workflow

PR: #9193

* wording tweaks

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 18:36:23 +00:00
Matt FiddamanGitHubClaude Fable 5.1autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
68d18f19f5 docs: regenerate all screenshots (#9195)
* [AI] docs: regenerate accounts screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate accounts/reconciliation screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate advanced/bank-sync screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate advanced/bank-sync/gocardless screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate advanced/bank-sync/pluggyai screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate advanced/bank-sync/simplefin screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate advanced/restart screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate backup-restore/backup screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate backup-restore/restore screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting/categories screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting/credit-cards/carrying-debt screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting/credit-cards/paying-in-full screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting/joint-accounts screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting/multi-currency screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting/returns-and-reimbursements screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate budgeting/rules/custom screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate config/multi-user screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate config/oauth-auth screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/balance-forecast-report screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/budget-analysis-report screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/budget-automation screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/formulas screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/goal-templates screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/monte-carlo-analysis screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/monthly-cleanup screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/redesigned-sidebar screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/rule-templating screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate experimental/sankey-report screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate getting-started/starting-fresh screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate getting-started/tips-tricks screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate getting-started/tracking-budget screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate install/desktop-app screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate install/fly screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate install/pikapods screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate migration/nynab screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate notifications screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate reports/custom-reports screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate reports screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate schedules screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate settings screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate tour/accounts screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate tour/budget screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate tour/payees screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate tour/reports screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate tour/rules screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate tour/schedules screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate tour/user-interface screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/bulk-editing screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/filters screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/importing screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/merging screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/payee-locations screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/payees screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/split-transactions screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/tags screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: regenerate transactions/transfers screenshots

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [AI] docs: update homepage screenshots and remove replaced image files

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* [AI] docs: retake the DEMO card payment screenshot before locking the reconciliation

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-10-12 18:09:12 +00:00
bubbletroublesandGitHub 48cac5930c [AI] Add AI Assistant Integrations (MCP) section to Community Projects (#9171)
* Add AI Assistant Integrations section and update entries

Added a new section for AI Assistant Integrations (MCP) and reintroduced the actual-budget-mcp entry with detailed descriptions.

* [AI] Add release note for MCP community projects section
2026-10-12 11:10:17 +00:00
89384e0b7b [AI] Add getScheduleDates to the API (#9020)
* [AI] Add getScheduleDates to the API

Expand a schedule date (single date or RecurConfig) into the dates it
falls on within a window, honouring frequency, interval, monthly
patterns, end mode and the weekend move.

Also type the return value of recurConfigToRSchedule, and fix the API
vitest setup, where inlined UMD builds of @rschedule registered the
date adapter and recurrence rules on a second @rschedule/core instance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfQCMhYExnAqVNC4gJjF8E

* [AI] Build getScheduleDates on getNextDateAfter

Walk the schedule with getNextDateAfter, the step the app uses to
advance a schedule, instead of expanding the rschedule occurrences.
A date that several occurrences move onto (a daily schedule's Saturday
and Sunday both landing on Monday with skipWeekend) is now listed once,
and count counts distinct dates.

Add an API test that pins the first listed date to the next_date the
app stores, so the two cannot drift. Drop the recurConfigToRSchedule
typing change, which is no longer needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HRp7PBTgAChF39Dv9iFLyc

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:48:02 +00:00
c59c4979e0 [AI] docs: link experimental features to feedback issues, drop Discord (#9186)
Remove "or post a message in the Discord" from the shared
ExperimentalFeatureWarning so feedback goes to GitHub issues.

- Monte Carlo analysis docs now link to feedback issue #8571.
- Multi-currency docs use the shared warning component, linked to the
  rule action templating feedback issue (#3606).
- Budget Analysis toggle in Settings links to /issues/6742 instead of
  /pull/6742.

Assisted-by: ClaudeCode:claude-opus-5-5

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:43:28 +00:00
tabedzkiandGitHub aa5c8841c1 docs: add @tabedzki as a main contributor (#9183)
Add @tabedzki to the Main Contributors list in the contributing docs
and include an upcoming release note.

Assisted-by: ClaudeCode:claude-opus-5-5
2026-10-11 17:40:18 +00:00
Julian Dominguez-SchatzandGitHub 42e9d79d4a Merge commit from fork
* [AI] Reject invalid password inputs before hashing

- Require non-empty strings at password validation, hashing and verification
  boundaries so JSON objects, arrays and other scalar types cannot reach
  Argon2's buffer conversion.
- Add regressions for malformed passwords on fresh and configured servers,
  including assertions that rejected input never reaches Argon2.

Advisory:
https://github.com/actualbudget/actual/security/advisories/GHSA-3jjw-2hq7-mmm2

* [AI] Require admin permission for EnableBanking configuration

- Require administrator permission to configure EnableBanking, even when
  credentials have not been configured yet.
- Check permission before validating credentials with the provider or
  persisting secrets, and disable configuration controls for non-admins.
- Test unauthenticated, BASIC and ADMIN requests against empty and existing
  configuration, preserving secrets and avoiding provider calls on denial.

Advisories:
https://github.com/actualbudget/actual/security/advisories/GHSA-hfxx-qc34-gqcw

* [AI] Neutralize BOM-prefixed CSV formulas

- Detect spreadsheet formula triggers after leading BOM characters and
  prepend an apostrophe before the original text.
- Protect textual CSV headers and scalar values as well as ordinary strings.
- Preserve numeric output, including negative amounts, and cover repeated
  BOMs, formula triggers, quoting and Unicode text in regression tests.

Advisories:
https://github.com/actualbudget/actual/security/advisories/GHSA-7jvc-qfpw-85g2

* [AI] Remove ambiguous Commerzbank payee matching

- Split Commerzbank payees into non-empty whitespace/slash-delimited tokens
  and escape their literal text before constructing the cleanup expression.
- Use consuming separators that cannot overlap the literal tokens, avoiding
  ambiguous matching on long runs of spaces or slashes.
- Require separators between payee tokens: concatenated words in notes are
  no longer stripped. Allow 20 seconds for the hostile-case subprocess,
  including Node and Vite startup on slower CI runners.
- Skip matching for empty payees while preserving normal note cleanup.
- Exercise hostile payees, including the report's spaced-word reproducer,
  in a subprocess with a hard timeout; retain the existing bank fixtures.

Advisories:
https://github.com/actualbudget/actual/security/advisories/GHSA-p34v-m2gp-w3jm

* [AI] Reject unsafe IPv6 address classes in SSRF checks

- Allow public unicast addresses by default. The private-network option
  additionally permits private, loopback, unique-local and carrier-grade NAT addresses.
- Permit the well-known NAT64 prefix only for embedded public IPv4
  destinations; private and metadata addresses remain blocked in both modes.
- Reject other IPv6 transition, multicast, reserved and link-local classes in
  both modes, and classify IPv4-mapped addresses by the embedded IPv4 address.
- Cover literal URLs, DNS answers, redirects and both SimpleFIN fetch paths,
  including NAT64, 6to4 and Teredo addresses, with synthetic upstreams.

Advisories:
https://github.com/actualbudget/actual/security/advisories/GHSA-97j5-6g5r-42v5

* [AI] Exclude callback secrets from ordinary server logs

- Log request method, pathname and response status without query strings,
  and restrict serialized metadata to the same safe fields.
- Keep full OpenID and banking provider messages, response bodies, session
  identifiers and error stacks behind existing actual-sensitive namespaces.
- Apply the same opt-in handling to shared banking errors, proxy target
  URLs and unhandled rejections; do not forward raw streaming errors to
  Express's ordinary error logger.
- Stop logging stored secret values, including with debugging enabled.
- Document targeted sensitive debugging and private support exchanges.
- Test ordinary and opt-in output, query and serialized metadata leaks,
  provider failures, session URLs, streaming errors and secret storage.

- Preserve provider format sequences by passing SimpleFIN response text as
  a debug format argument, rather than part of the format string.

Advisories:
https://github.com/actualbudget/actual/security/advisories/GHSA-ppcp-hx2h-fm35

* [AI] Revoke password sessions when credentials change

- Update the password hash and revoke all password-authenticated sessions
  in one transaction, including password changes through the local CLI.
- Issue a fresh token for each successful password login instead of reusing
  an existing session token.
- Recheck the verified password hash before creating a session so an
  in-flight login cannot restore access after a credential change.
- Correct the UI's claim that other sessions remain signed in, and test
  multiple sessions, CLI resets, transaction rollback and login/reset races.

This addresses session revocation and token reuse. Requiring the current
password for remote changes is covered by the following commit.

Advisories:
https://github.com/actualbudget/actual/security/advisories/GHSA-7363-3qq5-2frj
https://github.com/actualbudget/actual/security/advisories/GHSA-4wgp-48c6-v9w3

* [AI] Require the current password for remote password changes

- Require currentPassword alongside the replacement password for remote
  changes, preserving the administrator and password-authentication checks.
- Verify the current credential, rate-limit attempts and reject a change
  if the verified password hash changes before the update.
- Collect the current password in the client and handle failure to sign in
  after a successful change. Keep the local reset command available without
  the old password.
- Test that a session token alone cannot change credentials and that failed
  requests preserve the existing password and sessions.

- Clear the redundant success notice when signing in with the new password fails.

Advisories:
https://github.com/actualbudget/actual/security/advisories/GHSA-4wgp-48c6-v9w3

* [AI] Restrict Electron protocol launches and network file reveals

- Allow only parsed HTTP/HTTPS URLs through external-opening IPC,
  new-window handling and navigation, addressing GHSA-7pf2-w24j-p6h2.
- Also reject network/UNC paths in the separate file-reveal handler.
  A note such as [View receipt](//host/share/invoice.pdf) reaches
  showItemInFolder without passing through openExternal. On Windows,
  resolving that share can disclose NTLM authentication responses to an
  attacker-controlled server where network and authentication policies
  permit it. This additional flow was not demonstrated in the advisory.
- Accept native absolute local paths without adding file-URL conversion.
- Test protocol filtering and network-path rejection without invoking OS
  handlers. The note-to-file-reveal flow is code-confirmed; an actual
  Windows authentication exchange has not been reproduced.

The following commit addresses the advisory's separate internal-origin
classification finding.

Advisory:
https://github.com/actualbudget/actual/security/advisories/GHSA-7pf2-w24j-p6h2

Additional finding references:
https://github.com/electron/electron/blob/v43.4.0/shell/common/platform_util_win.cc#L270-L340
https://learn.microsoft.com/en-us/windows-server/storage/file-server/smb-ntlm-blocking

- Exercise Windows path semantics on all test platforms and exclude generated
  Electron tests and Vitest configuration from the packaged application.

* [AI] Classify Electron app URLs exactly and block redirects

- Replace substring checks with exact app://actual scheme/host matching
  and the existing development origin, http://localhost:3001.
- Use the classification for browser handoffs and focus/log script
  execution so remote URLs containing app:// or localhost: are not
  mistaken for app pages.
- Preserve the existing global renderer-navigation block and add redirect
  blocking there, without duplicating it in the main-window handlers.
- Keep ordinary IPC registration unchanged; broad sender validation is
  outside this URL-classification fix.
- Test misleading hosts, ports and URL substrings. Exercise ordinary
  clicks, new-window links and explicit browser IPC in Electron, asserting
  the exact HTTP/HTTPS URLs handed to the browser without opening real
  OS handlers. Exercise a local HTTP redirect to check the app stays put.

Advisory:
https://github.com/actualbudget/actual/security/advisories/GHSA-7pf2-w24j-p6h2

- Retain startup logs until an internal page finishes loading, then forward
  them to DevTools; cover startup delivery in the Electron navigation suite.

* [AI] Choose import destinations from trusted local context

- Allocate fresh local IDs for cloud downloads and local archive imports,
  ignoring destination IDs supplied in archived metadata.
- Pass an explicit local destination for replacement downloads and verify
  its cloud-file association. Do not require matching sync group IDs, so
  downloading the reset version of the same cloud file remains possible.
- Reject server metadata describing a different cloud file and close the
  budget before an authorized replacement.
- Retain existing import metadata compatibility, collision error handling,
  nested archive layouts and backups; do not require a budget name.
- Test targeted collisions, local recovery imports with obsolete IDs or
  missing optional metadata, mismatched cloud associations and replacement
  after a sync ID reset using real local files and databases.

Advisory:
https://github.com/actualbudget/actual/security/advisories/GHSA-7fr5-fjj8-hwjq

- Reuse the matching local budget for API downloads after a sync reset,
  report cloud-file mismatches in API/CLI errors, and document local IDs.

* [AI] Revoke sessions on sign-out and API shutdown

Revoke only the supplied session on explicit sign-out. Clear local credentials if the server cannot be reached, and revoke password-created API sessions during shutdown without revoking caller-supplied tokens.

Cover isolated and repeated revocation, invalid tokens, offline sign-out, borrowed API tokens and shutdown after a close failure. Session expiry policy is unchanged.

Follow-up to:
https://github.com/actualbudget/actual/security/advisories/GHSA-7363-3qq5-2frj
2026-10-08 08:34:05 -04:00
5240d5b051 [AI] Add MASH to additional installation options (#9026)
Claude-Session: https://claude.ai/code/session_01FK49NqPPMe9sJGo6uXE1Vg

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:15:35 +00:00
Michael ClarkandGitHub cef7e63bf7 monte carlo block bootstrap (#9101) 2026-10-07 16:43:57 +00:00
1ad8477abd [AI] Use amounts instead of cents in rule formulas (#8717)
* [AI] Use amounts instead of cents in rule formulas

Rule formulas handed `amount`, `balance`, `parent_amount` and BALANCE_OF()
to the formula as integer cents, but read a numeric result back as an
amount, so `=amount * 1.05` came out 100x too large and users had to write
`=amount / 100 * 1.05`.

Convert the monetary variables with `integerToAmount` when building the
named expressions, so a formula reads and returns the same units either
way. The `amountToInteger` on the result moves out of executeFormulaSync
into the two branches that actually write an amount column, so a numeric
result stringified into a text field is no longer scaled up.

The transaction object itself stays in integers, keeping rule conditions,
Handlebars templates and the split percent/remainder math unchanged.

A migration rewrites stored formulas (`=amount / 100` becomes
`=(amount * 100) / 100`) so they keep producing the same result. It keeps
its own frozen copy of the variable names and the factor of 100, since
those describe how formulas worked when it was written.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* [AI] Stop spelling out the units in rule formula docs

With formulas working in the amounts shown in the app, saying so on every
variable is noise — the values now read the way you would expect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* [AI] Move the rule formula migration after the account groups one

The migration id has to sort last, since checkDatabaseValidity compares
applied ids to available ones by position — a nightly user who already ran
1787013118115_add_account_groups would otherwise fail to open their budget
with out-of-sync-migrations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* [AI] Drop the rule formula migration in favour of a documented break

Per review: the migration cannot hold up across devices. A new device
migrates and then replays newer messages, so a formula saved after the
migration ran is never converted; and once one device upgrades, the
converted formula it syncs reads 100x off on a device still running the
old build.

Rule formulas are experimental, so document the break instead and let
people drop the `/ 100` themselves. Also clears the leftover `/ 100` from
the ROUND, ROUNDDOWN, ROUNDUP and TRUNC examples.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* note update

* note update2

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-06 18:05:10 +00:00
Emil GeorgeandGitHub f3b8f85b20 [DOCS] - Add Indian statement convertor to community repos (#8962)
* docs: add indian statement convertor to community repo doc

* fix: use trimmed version
2026-10-05 18:00:01 +00:00
Emil GeorgeGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
9732a4463a [Issue-3831] - Auto bank sync (#8744)
* [AI] feat: auto bank sync

* chore: add release note

* [AI] fix: move auto sync settings to bank sync screen

* fix: typecheck failure due to missing required prop

* fix: update available intervals for auto sync

* [AI] feat: add custom interval logic

* [AI] fix: address review comments

* fix: consider server status to run auto sync

* fix: use oldest sync as reference point

* fix: update description

* [autofix.ci] apply automated fixes

* fix: rm irrelevant comments

* fix: rm cast

* doc: add auto bank sync info

* fix: discard empty non numeric draft val

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-10-04 22:23:40 +00:00
Michael ClarkandGitHub 984ce48038 🎨 Notifications style updates (#9084)
* updating styles of notifications

* lint
2026-10-04 09:20:11 +00:00
github-actions[bot]GitHubgithub-merge-queuegithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Matt Fiddamanautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
3a77479e14 🔖 (26.10.0) (#9011)
* 🔖 (26.10.0)

* Generate release notes for v26.10.0

* add frontmatter

* [autofix.ci] apply automated fixes

* Generate release notes for v26.10.0

* Generate release notes for v26.10.0

* link to experimental sidebar docs

* [autofix.ci] apply automated fixes

* cleanup from cherrypicks

* Generate release notes for v26.10.0

* cleanup cp notes

* update release date

* [autofix.ci] apply automated fixes

---------

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: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-10-02 15:23:08 +00:00
eb28966d6c [AI] Prevent custom CSS indicator overlap in theme settings (#8896) (#8910)
Fixes #8896

Co-authored-by: Felipe Medici <femedicidev1@gmail.com>
2026-09-29 00:56:20 +00:00
Boris RybalkinandGitHub 421f16638b Add Syncloud to the additional installation options (#9034)
* Add Syncloud to the additional installation options

Syncloud is a server operating system for a Raspberry Pi, a spare PC or a VPS,
which packages actual-server as one of the apps it installs and updates. Listed
under the community options alongside the other platform guides, with one link
for what it is and one for setting a device up.

* Drop the Syncloud description and setup link

Keep only the link that is about running Actual, as requested in review.
2026-09-28 21:11:18 +00:00
815286d253 docs: add Rauthy to the list of tested OpenID providers (#8966)
* docs: add Rauthy to the list of tested OpenID providers

Closes #8838

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: note Rauthy needs RS256 for token and ID token algorithms

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Fionn Jones <264670603+jonesfionn101-dotcom@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: youngcw <calebyoung94@gmail.com>
2026-09-28 17:29:37 +00:00
Matt FiddamanandGitHub 6d224f676c 📝 add experimental sidebar docs (#9022)
* add images

* add docs

* fix spelling
2026-09-27 21:18:01 +00:00
Spaghettio73andGitHub 15fb66368b docs: add receipt2actual and actual2ics to Community Projects (#8945) 2026-09-19 07:26:08 +00:00
Michael ClarkandGitHub dc006aa192 📈 Monte Carlo income streams (#8955)
* monte carlo income streams

* simplify release note

* enhancement

* fix withdrawal rule floor when income is specified

* update screenshots

* suplus pot and images

* way better description in the run details

* covering case where income is all thats setup and spending is the same as the income

* feedback

* screenshots and rename of minimum withdrawal to min spending

* additional docs
2026-09-18 15:23:05 +00:00
Michael ClarkandGitHub 2ff97090d6 :electron: When data folder is unavailable show a friendly message (#8928)
* when data folder is unavailable due to permissions etc, show a friendly prompt

* feedback from rabbit
2026-09-15 19:43:59 +00:00
danielcovillandGitHub 021ceba57c Tips tricks docs fix (#8940)
* Update tips-tricks.md

Correct out of date documentation.

* Add release notes

* Clearer writing, filename fix for release notes
2026-09-15 01:48:11 +00:00
f8ad7c0ebd [AI] Warn API users about deferred sync messages and fix stale docs row (#8925)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 21:34:35 +00:00
Albert BendichoGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
ccaaa90cd8 Update enable-banking.md Clarify needed steps (#8821)
* Clarify enable-banking.md steps

It seems to be a common problem people face that they skip the `Link the accounts you want in the Enable Banking interface`

https://github.com/actualbudget/actual/issues/7799#issuecomment-4433943297
https://github.com/actualbudget/actual/issues/7799#issuecomment-4629194825
https://github.com/actualbudget/actual/issues/7799#issuecomment-4641704020
https://github.com/actualbudget/actual/issues/7799#issuecomment-4477748895
https://github.com/actualbudget/actual/issues/7799#issuecomment-4488926240
https://github.com/actualbudget/actual/issues/7799#issuecomment-4511171800
https://github.com/actualbudget/actual/issues/7799#issuecomment-4641704020

* [autofix.ci] apply automated fixes

* coderabbitai requested improvements

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-13 21:26:43 +00:00
Michael ClarkandGitHub 59bde67ba6 📈 Monte carlo - Cashflow chart (#8903)
* cashflow chart

* showing years that are unfunded

* update screenshots

* refactor a bit

* fix dead years withdrawal rules
2026-09-11 18:44:21 +00:00
Ruben van DuyneveldtandGitHub bbb9fc02fb [AI] Document mobile bank sync refresh (#8908) 2026-09-09 18:04:55 +00:00
Alexander LopezandGitHub 4befce86cc Add api.setPreference(id, value) for setting synced preferences (#8893)
* Added api.setPreference({id, value})

Added the setPreference({id, value}) function to the api methods to allow api consumers to set SyncedPerfs values.

* Added return type to api.setPreference(id, value)

Added return type and removed unnecessary function comment. Updated api docs with correct return type Promise<void> instead of void.

* Removed useless setPreference persist test

* Type setPreference value by preference key

Hardened type on setPreference so that values are based on the type corresponding to the id. Also updated api doc reference.md
2026-09-09 06:45:06 +00:00
Michael ClarkandGitHub db1b0ea975 📈 Monte carlo - withdrawal rule breakdown (#8863)
* fix floor and ceiling and boundaries rules when retirement starts after years of no spending

* updated doc

* added a breakdown of how the withdrwal rule was calculated

* add a bit of a gap between table and explainations

* unneded comment
2026-09-07 06:50:24 +00:00