* [AI] Add impeccable design skill wiring and project design context
Commit only the shareable parts of the impeccable frontend-design skill
setup: defensive hook wiring (.codex, .cursor, .github hooks that no-op
when the skill is not installed locally) and the generated design
context files (PRODUCT.md, DESIGN.md, DESIGN.json) derived from the
existing component-library tokens and themes. The skill payload itself
is gitignored; developers install it locally.
Co-Authored-By: Claude Fable 5 <[email protected]>
* [AI] Recommend installing the impeccable skill to agents at boot
AGENTS.md documents the install step, a Claude Code SessionStart hook
surfaces it when the skill is missing from the checkout, and the Codex
and Copilot hook wiring echoes the same hint instead of silently
no-oping.
Co-Authored-By: Claude Fable 5 <[email protected]>
* [AI] Mention DESIGN.json among committed design context files
Co-Authored-By: Claude Fable 5 <[email protected]>
* [AI] Keep DESIGN.json out of the repo as a generated artifact
It is a regenerable sidecar of DESIGN.md consumed only by the locally
installed impeccable live panel, so gitignore it like the skill payload.
Co-Authored-By: Claude Fable 5 <[email protected]>
* [AI] Clarify that DESIGN.md hex values are the light-theme mapping
Co-Authored-By: Claude Fable 5 <[email protected]>
---------
Co-authored-by: Claude Fable 5 <[email protected]>
* Context Menu is implemented
* allow Document and Window in ref event listener hook
* did stupid examples to showcase api usage
* recreated TransactionMenu using new context action
* fixed styling and removed excess calls to useContextMenuAction
* removed extra call
* extra imports
* started converting files to useContextMenu
* fixed context menus in reports
* linting and formatting
* deleted TransactionMenu
* release notes
* fixed coderabbit
* light context menu refactor
* added nested contexts for state and actions
* refactored useContextMenuAction
* [autofix.ci] apply automated fixes
* removed log
* updated contextMenuSlice
* removed package.json change
* filter => some
* tried to improve test
* [AI] test: fix payees e2e right-click test by scoping row query to table
* linting
* [AI] chore: fix all linting issues from new context menu files
* fixed compiler
* fixed linting/formatting
* coderabbit fix
* [AI] fix(electron): connect to sync server on 127.0.0.1 instead of localhost
Node.js > 17 resolves localhost to ::1 (IPv6) by default, while the Electron
sync server binds explicitly to 127.0.0.1 (IPv4). This caused setServerUrl to
fail when the desktop app starts its internal sync server, trapping the user
in an onboarding loop between /config-server and /bootstrap.
This commit updates the URL to use 127.0.0.1 to match the server binding.
* [AI] Fix isPlaywright detection for Electron Playwright tests
The userAgent check was changed from includes('playwright') to
=== 'playwright', but the Electron main process appends ' playwright'
to the default userAgent (preserving the 'Electron' substring that
isElectron() relies on). Use includes() so the flag is detected
correctly in Electron e2e tests.
Also reverts the localhost→127.0.0.1 change which did not resolve the
VRT pixel diffs.
* re-added missing menu option
---------
Co-authored-by: Alec Bakholdin <alecbakholdin.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] Disable oxlint no-useless-default-assignment rule
This rule requires the `strictNullChecks` compiler option to function, but
the project intentionally keeps `strict: false` (per-file strictness is
handled by typescript-strict-plugin, which oxc's type-aware linter doesn't
understand). As a result the rule only emitted noise — over 1,200 warnings
telling us it couldn't run — so turn it off explicitly, matching how other
ill-fitting type-aware rules are already disabled.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014K4HhohrAYT7K4vY1L7Q2G
* [AI] Simplify no-useless-default-assignment disable comment
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014K4HhohrAYT7K4vY1L7Q2G
* [AI] Add release note for disabling no-useless-default-assignment
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014K4HhohrAYT7K4vY1L7Q2G
* [AI] Enable no-useless-default-assignment, disable only in non-strict packages
Turn the rule on by default so the strict packages (ci-actions, cli,
component-library, crdt) enforce it, and add an override disabling it in the
packages that still set `strict: false` (api, desktop-client,
desktop-electron, loot-core, plugins-service, sync-server), where the rule
can't function without strictNullChecks.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014K4HhohrAYT7K4vY1L7Q2G
* [AI] Trim no-useless-default-assignment override comment to just the TODO
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014K4HhohrAYT7K4vY1L7Q2G
* [AI] Rename release note to a slug
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014K4HhohrAYT7K4vY1L7Q2G
---------
Co-authored-by: Claude <[email protected]>
* [AI] Replace mechanical agent rules with shared agent hooks + nano-staged
Move the mechanical "remember to run X" rules out of AGENTS.md and the
agent guidance docs into deterministic, cross-agent hooks, and migrate
the pre-commit runner from lint-staged to nano-staged.
- Add shared hook scripts in scripts/agent-hooks/ (git-guard,
format-edited-file, no-strict-ignore-new-file, prefer-one-component,
check-on-stop, common helpers) wired for Claude (.claude/settings.json),
Codex (.codex/config.toml), and Cursor (.cursor/hooks.json + adapters).
- Enforce "avoid enum" via a new actual/no-enum lint rule, grandfathering
the two existing declarations in .oxlintrc.json overrides.
- Migrate lint-staged -> nano-staged (.nano-staged.json, .husky/pre-commit,
package.json).
- Trim AGENTS.md, .github/agents/pr-and-commit-rules.md, the Cursor rule,
and the committing skill down to the rules that aren't auto-enforced.
- Add release note 8089.md.
* [AI] Align PR-title wording in AGENTS.md with canonical rules
* [AI] Fix check-on-stop hook on bash 3.2 and TSV column collapse
The Stop hook silently no-op'd in two ways:
- `declare -A` isn't supported on stock macOS bash 3.2, and the
slash/hyphen path subscript aborted under `set -u`. Dedupe via a
space-padded string match instead.
- jq emitted an empty middle TSV field for a package with test but no
typecheck; tab is IFS-whitespace so `read` collapsed it and shifted the
columns (eslint-plugin-actual then ran neither). Emit non-empty
sentinels (-, yes/no) so no field can collapse.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
---------
Co-authored-by: Claude <[email protected]>
* [AI] Load @actual-app/crdt from source in dev, only bundle for publish
@actual-app/crdt's local exports now point at src/index.ts so consumers
(sync-server, loot-core, desktop-client) never see a stale Vite bundle.
publishConfig keeps the dist/ mapping for npm consumers. crdt's
tsconfig switches to bundler module resolution to match the rest of
the workspace (no extensions in source imports).
Sync-server's existing extension-resolution loader is extended to also
handle directory-index imports (./crdt → ./crdt/index.ts), and the
standalone `start` / `start-monitor` scripts now invoke Node with
--import ./register-loader.mjs so the loader is in place before crdt's
source resolves.
Electron's utilityProcess.fork accepts execArgv but doesn't actually
preload --import modules, so a new packages/sync-server/start.mjs
bootstrap entry registers the loader imperatively and then dynamic-
imports build/app.js. desktop-electron's startSyncServer() points the
fork at start.mjs. sync-server's "files" array now ships start.mjs,
register-loader.mjs and loader.mjs so packaged Electron / npm
consumers actually receive them.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* Add release notes for PR #7702
* [AI] Restructure sync-server to build with Vite
Replace the hand-rolled tsgo + add-import-extensions + copy-static-assets
+ runtime loader pipeline with a single Vite SSR build. Bundles every
entry (app, bin/actual-server, scripts/*) and inlines @actual-app/crdt
source so Node never has to resolve TS at runtime — the
MODULE_TYPELESS_PACKAGE_JSON warning that surfaced via crdt's source
exports is gone. Migrations and bank handlers move from readdir-based
dynamic imports to import.meta.glob; messages.sql becomes a ?raw import.
Drop loader.mjs, register-loader.mjs, start.mjs, and
bin/add-import-extensions.mjs. Electron's startSyncServer() forks
build/app.js directly. publishConfig.imports goes away (subpath imports
are resolved at build time and don't appear in the bundle).
In dev (start:server-dev) sync-server proxies to Vite, so loosen the CSP
to allow Vite's inline preamble script and HMR websocket — production
CSP is unchanged. desktop-client skips registerSW() in dev (and disables
vite-plugin-pwa's devOptions) so stale cached assets don't override
edits between page loads.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Address review feedback
- sync-server CSP: drop 'unsafe-eval' from the production script-src;
the bundle has no genuine eval/new Function usage (only a defensive
branch in setimmediate's polyfill that's never hit). Keep it on the
dev branch where Vite's HMR runtime relies on it. Add a comment so
it's obvious which branch needs it and why.
- bank-factory: widen the loader glob to ./banks/*_*.{ts,js} so
TypeScript handlers are discovered too, mirroring migrations.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Restore 'unsafe-eval' in production CSP for Electron
The Electron app needs `'unsafe-eval'` at runtime, so revert the dev-only
restriction and keep `'unsafe-eval'` in both branches. Comment updated to
record the actual reason instead of marking it as removable.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Revert bank-factory glob change
Widening the glob to ./banks/*_*.{ts,js} broke the desktop e2e tests in
CI even though every current handler is .js and the brace expansion
matches no .ts files locally. Reverting to ./banks/*_*.js — the change
had no behavioural benefit since there are no TS handlers, so the
nitpick isn't worth chasing.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Strip CSP comment to restore identical state to 9513c1e16
The desktop e2e has been failing despite my prior commits being a strict
revert (only difference was a 2-line comment, which can't change runtime).
Removing even the comment so the branch matches 9513c1e16's relevant
files exactly, to isolate whether the failure is from the master merge
or from CI-environment drift.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Make rebuild-electron actually rebuild better-sqlite3
PR #7712 simplified rebuild-electron to just `electron-rebuild -f -o
better-sqlite3,bcrypt` from the repo root. Two problems with that:
1. Without `-m`, electron-rebuild scans the root workspace's package.json
for native deps. better-sqlite3 isn't a direct root dep — it lives
under packages/sync-server/ — so the scan returns no candidates and
the rebuild silently no-ops.
2. Without --build-from-source, electron-rebuild defers to
prebuild-install, which downloads a stale prebuilt binary keyed off
better-sqlite3's package.json (ABI 127) instead of recompiling
against Electron 39's bundled Node ABI 140. The download succeeds
and "Rebuild Complete" prints, but the resulting `better_sqlite3.node`
can't `dlopen` inside Electron's utility process — sync-server
crashes immediately on db init, the renderer's startSyncServer IPC
never resolves, and the e2e test hangs on "Configure your server".
Point -m at packages/desktop-electron (which transitively pulls in
better-sqlite3 and bcrypt via @actual-app/sync-server) and force a real
compile via --build-from-source. Verified locally: better-sqlite3
rebuilds to darwin-arm64-140 and the desktop e2e onboarding test passes
in 6s instead of hanging for 60s.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Restore CSP unsafe-eval comment
Bring back the explanatory comment that was stripped diagnostically in
99682268c. Now that the desktop e2e regression is traced to
rebuild-electron and not to anything in this branch, we can keep the
documentation noting why 'unsafe-eval' is retained in both CSP branches.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Restore bank-factory glob to ./banks/*_*.{ts,js}
Re-apply the glob widening originally added in 145868f9d. It was
reverted in 531b1a191 because the desktop e2e was failing — that
failure is now traced to the rebuild-electron breakage (fixed in
6e8ac0784), not to this glob. Mirroring migrations.ts so future TS
bank handlers are picked up.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Fix applyAppUpdate hanging in dev mode
In dev mode browser-preload's updateSW was () => undefined, so
applyAppUpdate() — which calls updateSW() and then awaits a
deliberately never-resolving promise (waiting for the SW-driven page
reload) — hung the renderer instead of refreshing. In prod the page
is replaced by the new service worker, so the never-resolving await is
fine. The dev path now triggers a plain window.location.reload() so
the page reloads and the never-settling await is irrelevant, matching
prod's effective behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Revert rebuild-electron to master version
* Revert "[AI] Revert rebuild-electron to master version"
This reverts commit 4b6baab79f.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* [AI] Revert crypto.randomUUID back to uuid library
Partial revert of #7529. Restores the `uuid` package dependency in
api, crdt, desktop-client, loot-core, and sync-server, swapping every
`crypto.randomUUID()` call introduced by that PR back to `uuidv4()`
(and the `uuid()` alias in RuleEditor.tsx and ruleUtils.ts where it
was previously used). The lint rule, docs entry, and `vi.mock('uuid')`
test setup are restored as well. The `fs-extra` removals in
desktop-electron from the same PR are left in place.
https://claude.ai/code/session_01KTg1g416Jdjf5feGke8MQw
* Add release notes for PR #7734
* [check-spelling] Update metadata
Update for https://github.com/actualbudget/actual/actions/runs/25480733101/attempts/1
Accepted in https://github.com/actualbudget/actual/pull/7734#issuecomment-4394811498
Signed-off-by: check-spelling-bot <[email protected]>
on-behalf-of: @check-spelling <[email protected]>
* [AI] Use the uuidv4 alias in RuleEditor and ruleUtils
The previous commit preserved the `v4 as uuid` alias in these two files
to match their pre-#7529 state, but the project convention (and lint
rule message) is `v4 as uuidv4`. CodeRabbit flagged the inconsistency,
so normalize the alias and call sites in both files.
https://claude.ai/code/session_01KTg1g416Jdjf5feGke8MQw
* [AI] Pin uuid to ^11.1.0 to fix Electron e2e
uuid v13 is ESM-only (no CJS entry, only an exports map with `node` and
`default` conditions both pointing to ESM files). The Electron backend is
bundled as CJS by `loot-core/vite.desktop.config.mts` and loaded via a
dynamic `await import(process.env.lootCoreScript!)` in the
desktop-electron utilityProcess; that pipeline appears to fall over on
the ESM-to-CJS transform of uuid v13 in Vite 8 / rolldown, which makes
the Functional Desktop App e2e job fail consistently while every other
check (web e2e, VRT, unit tests, lint, typecheck) passes.
uuid v11 still ships `dist/cjs/index.js`, so pinning each workspace's
uuid range to ^11.1.0 sidesteps the resolution path entirely. The API
is unchanged (`v4` is still the same export), so no source-code changes
are needed.
https://claude.ai/code/session_01KTg1g416Jdjf5feGke8MQw
* [AI] Capture Electron stdout/stderr in desktop e2e fixture (TEMP DEBUG)
Pipe the Electron main+utility process stdout/stderr into both the
playwright runner stderr and an electron.log file inside the test's
output directory. This makes the actual backend error visible in the
Functional Desktop App job output and in the desktop-app-test-results
artifact.
Will be reverted once the failure cause is identified.
https://claude.ai/code/session_01KTg1g416Jdjf5feGke8MQw
* Revert "[AI] Capture Electron stdout/stderr in desktop e2e fixture (TEMP DEBUG)"
This reverts commit 4cb5148859.
* [AI] Fix rebuild-electron and bump uuid back to ^13.0.0
The Functional Desktop App e2e job had been failing with
ERR_DLOPEN_FAILED on better-sqlite3 (NODE_MODULE_VERSION 127 vs 140),
which surfaced because this PR's yarn.lock change invalidated the
GitHub Actions node_modules cache. With a fresh install,
rebuild-electron is responsible for compiling better-sqlite3 and
bcrypt against Electron's ABI — but since #7712 the script has been
running from the repo root, where neither module is a direct
dependency, so electron-rebuild silently exits as a no-op.
Restore the `-m ./packages/desktop-electron` scoping that #7712
removed, so the rebuild actually finds and rebuilds the modules.
This fix is technically out of scope for this PR but it blocks any
PR that touches yarn.lock.
Also revert the `^11.1.0` pin from the previous commit back to
`^13.0.0`. The pin was based on a wrong hypothesis (that uuid v13's
ESM-only packaging was breaking the bundle); now that the real
cause is identified, there is no reason to deviate from the
pre-#7529 version.
https://claude.ai/code/session_01KTg1g416Jdjf5feGke8MQw
---------
Signed-off-by: check-spelling-bot <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* [AI] Make TypeScript work in test files across packages
Match the CRDT package's tsconfig pattern in loot-core, desktop-client,
api, and desktop-electron so test files participate in the project graph
(IDE intellisense, project-wide typecheck) while production builds still
emit clean declaration files.
- Remove test-file exclusions from each package's main tsconfig
- Add tsconfig.build.json for loot-core and api with test exclusions,
used by the build scripts
- Add e2e/tsconfig.json for desktop-client and desktop-electron with
Playwright types
- Fix latent type errors in test files now caught by typecheck
- Disable typescript/unbound-method for test files (mock matcher pattern)
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* Release notes
* [AI] Address review feedback on test type fixes
- goal-template.test.ts: extract amounts to typed locals so single-value
assertions no longer compare against unknown
- category-template-context.test.ts: replace `as unknown as DbCategory`
double-cast with a fully-typed object using `satisfies DbCategory`
(the previous mock had `is_income: true` which doesn't match the
`1 | 0` shape the cast was hiding)
- api/tsconfig.build.json: broaden test exclude pattern to `**/*.test.ts`
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Widen toMatchThemeScreenshots matcher to accept Page
The matcher's runtime impl already handled both Page and Locator
(via `typeof locator.page === 'function'` branch), but the type only
declared Locator. Call sites pass a Page (`expect(page).toMatchThemeScreenshots()`),
which now compiles cleanly.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Type window.Actual in e2e fixtures and refactor matcher
- Pull loot-core/typings/window.ts into the e2e tsconfig include so
the ambient `window.Actual` augmentation is visible.
- Refactor toMatchThemeScreenshots to derive a Page once via
`'page' in target`, then call evaluate on the page consistently.
The previous union-typed access (locator.evaluate, locator.page)
didn't typecheck on Locator | Page.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Drop tsconfig.build.json for loot-core and api
The build-config indirection was incomplete protection: typecheck
(`tsgo -b` against the main tsconfig, which now includes test files)
already emits `*.test.d.ts` into `@types/`, and the build step does
not clean before re-emitting. The same is observable in crdt's
`dist/`, which currently contains test declarations on disk.
What actually keeps test declarations out of the npm tarball is the
`files` field in package.json — and loot-core already uses that
mechanism for source files (`\!src/**/*.test.ts`). Extending the same
pattern to `@types/` is more direct than maintaining a duplicate
tsconfig that doesn't reliably do its job.
- Delete loot-core/tsconfig.build.json; revert build to `tsgo -b`;
add `\!@types/**/*.test.d.ts*`, `\!@types/**/__tests__/**`,
`\!@types/**/__mocks__/**` to `files`.
- Delete api/tsconfig.build.json; revert build to
`vite build && tsgo --emitDeclarationOnly`; add
`\!@types/**/*.test.d.ts*` to `files`.
Verified: `yarn pack --dry-run` excludes all test declarations from
both packages while production declarations still pack (428 .d.ts
files for loot-core, methods.d.ts for api).
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Standardise crdt to drop tsconfig.build.json
Apply the same simplification as loot-core and api: a single tsconfig
per package, with `files`-field negations preventing test
declarations from being published.
Note: this also fixes a pre-existing issue where crdt was shipping
`crdt/timestamp.test.d.ts` and `crdt/merkle.test.d.ts` to npm. The
old `tsconfig.build.json` excluded test files from declaration emit,
but the `typecheck` script (`tsgo -b` via the main tsconfig) had
already emitted them into `dist/` and the build did not clean
first, so they were packed via `"files": ["dist"]`.
After this change, `yarn pack --dry-run` packs only production
declarations (10 .d.ts files) and excludes the test ones.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
* [AI] Add no-extraneous-dependencies lint rule to prevent transitive dependency usage
Closes#7479. Adds a custom ESLint rule that flags imports of packages not
explicitly listed in the workspace's dependencies or devDependencies. Also
fixes all existing violations by adding missing deps and removes unused
deps (@reduxjs/toolkit, @rschedule/json-tools) from loot-core.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Fix builtin subpath detection and improve cache in no-extraneous-dependencies
Fix false positives for Node.js builtin subpaths (fs/promises, path/posix)
by checking the package name portion against builtins. Also cache all
visited directories during walk-up, not just the starting directory.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Release notes
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
* [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) <[email protected]>
* [AI] Add release notes for #7462
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Fix mock specifiers in accounts.test.ts to use aliased imports
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* [AI] Fix mock specifiers in query.test.ts to use aliased imports
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* [AI] Fix ESLint rule to properly validate src/ directory paths
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* [AI] Add publishConfig.imports for sync-server to remap aliases to build directory
Co-authored-by: Matiss Janis Aboltins <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* [AI] Consolidate loot-core connection: default web path, electron split, drop .browser
* [autofix.ci] apply automated fixes
* [AI] Replace browser-preload .browser extension with package.json subpath imports
Use the imports field in desktop-client/package.json with conditional
resolution (electron → empty stub, default → real implementation) to
eliminate the last .browser file extension from the codebase.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Refactor connection imports to use @actual-app/core
* Implement connection mock for desktop-client tests and update import path
* [AI] Fix formatting and update imports after master merge
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Fix connection mock in TransactionsTable tests and use electron-renderer condition
Wire up the manual connection mock for TransactionsTable tests since the
__mocks__ directory was removed, and restore electron-renderer condition
in loot-core package.json exports.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [autofix.ci] apply automated fixes
* [AI] Remove redundant resolveExtensions from vite configs
These arrays were identical to Vite's built-in default and served no purpose.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Remove remaining resolveExtensions from vite/vitest configs
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Fix build failures: update browser-preload import path and condition
- Change loot-core/shared/platform to @actual-app/core/shared/platform
- Use electron-renderer condition for #browser-preload to match vite resolve
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Remove redundant resolveExtensions from api and loot-core desktop configs
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Remove '*.browser.ts' extension and alias resolutions
Removed the special '*.browser.ts' file extension and file resolutions via alias, preferring conditions.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Migrate desktop-client to subpath imports
Replace the `@desktop-client/*` path alias with Node.js subpath
imports (`#*`) across packages/desktop-client:
- Declare the full `imports` map in packages/desktop-client/package.json
(bare index entries, root-level files, and per-subdirectory wildcards
with explicit extension overrides where `.ts` and `.tsx` mix).
- Update all source files to import from `#...` specifiers.
- Drop the `@desktop-client` group from .oxfmtrc.json.
- Enable `actual/prefer-subpath-imports` for desktop-client in
.oxlintrc.json so future code keeps using the subpath form.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Drop legacy desktop-client aliases
Remove the `@desktop-client/*` and `loot-core/*` path aliases from
vite.config.ts and tsconfig.json now that every desktop-client source
file imports via subpath imports / `@actual-app/core`.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Release notes
* [AI] Use electron-renderer condition for renderer-only exports
Desktop-client's Vite build used the `electron` resolve condition, which
overlapped with loot-core exports where `electron` means the Node/main
variant (e.g. `shared/platform.electron.ts` using `os`,
`platform/server/asyncStorage/index.electron.ts` using `fs`). Once the
`loot-core` Vite alias was removed, the renderer bundle started pulling
those Node variants and crashed at runtime with
`It.default.platform is not a function` inside `platform.electron.ts`.
Introduce a distinct `electron-renderer` condition used only by
desktop-client's Vite config, and rename the `electron` key to
`electron-renderer` on the sole loot-core export whose `electron` branch
is the Electron renderer variant (`#/./platform/client/connection`, the
IPC `global.Actual.ipcConnect` file). Every other `electron`-conditioned
export keeps its Node semantics and is still matched by loot-core's own
`vite.desktop.config.ts` (`conditions: ['electron']`).
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Drop .electron.* extensions from loot-core desktop resolver
Now that every Node/main variant is selected via the `electron` subpath
import condition in `packages/loot-core/package.json`, Vite's
`resolveExtensions` list no longer needs the `.electron.js`,
`.electron.ts`, `.electron.tsx` entries. Remove them to keep resolution
explicit and avoid implicit extension picking.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Align desktop-client TS resolution with Vite
- Set `customConditions: ["electron-renderer"]` in
`packages/desktop-client/tsconfig.json` so TypeScript resolves
conditional imports (notably `@actual-app/core/platform/client/connection`)
to the same file Vite picks at runtime. Today the surfaces happen to
match because both variants import from a shared `index-types.ts`,
but the alignment prevents a latent drift bug.
- Fix typo in the release note (`Standartise` -> `Standardise`).
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Add subpath import wildcard patterns and explicit directory entries to loot-core
Extend the package.json imports field with prefix-specific wildcard patterns
(#server/*, #shared/*, #types/*, #mocks/*, #platform/*) and explicit entries
for directory imports (#server/db, #server/sync, etc.) to support the ongoing
migration from relative imports to subpath imports.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* [AI] Add release notes for #7429
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* [AI] Promote typescript/no-for-in-array lint rule from warn to error
Convert the oxlint rule from "warn" to "error" as noted by the existing
TODO comment, and fix the three violations by replacing for-in loops
with for-of using .entries().
https://claude.ai/code/session_01N6F8DMzUVDxNJC56jMGknf
* Add release notes for PR #7193
---------
Co-authored-by: Claude <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Promote typescript/restrict-template-expressions to error and fix violations
Convert the oxlint rule from "warn" to "error" and fix all 42 violations
by wrapping non-string template expressions with String(). This ensures
type safety in template literals across the codebase.
https://claude.ai/code/session_01Uk8SwFbD6HuUuo3SSMwU9z
* Add release notes for PR #7181
---------
Co-authored-by: Claude <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Desktop client, E2E, loot-core, sync-server and tooling updates
Co-authored-by: Cursor <[email protected]>
* Refactor database handling in various modules to use async/await for improved readability and error handling. This includes updates to database opening and closing methods across multiple files, ensuring consistent asynchronous behavior. Additionally, minor adjustments were made to encryption functions to support async operations.
* Refactor sync migration tests to utilize async/await for improved readability. Updated transaction handling to streamline event expectations and cleanup process.
* Refactor various functions to utilize async/await for improved readability and error handling. Updated service stopping, encryption, and file upload/download methods to ensure consistent asynchronous behavior across the application.
* Refactor BudgetFileSelection component to use async/await for onSelect method, enhancing error handling and readability. Update merge tests to utilize async/await for improved clarity in transaction merging expectations.
* Refactor filesystem module to use async/await for init function and related database operations, enhancing error handling and consistency across file interactions. Updated tests to reflect asynchronous behavior in database operations and file writing.
* Fix typo in init function declaration to ensure it returns a Promise<void> instead of Proise<void>.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #6987
* Update tests to use async/await for init function in web filesystem, ensuring consistent asynchronous behavior in database operations.
* Update VRT screenshot for payees filter test to reflect recent changes
* [AI] Fix no-floating-promises lint error in desktop-electron
Wrapped queuedClientWinLogs.map() with Promise.all and void operator to properly handle the array of promises for executing queued logs.
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* Refactor promise handling in global and sync event handlers
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #6987
---------
Co-authored-by: Cursor <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matiss Janis Aboltins <[email protected]>
* Refactor: extract tooltip components and clean up lint suppressions
Extract CustomTooltip components from CrossoverGraph and NetWorthGraph
to module level to fix unstable nested components lint warnings. Also
consolidate theme file lint rule into oxlintrc.json and add proper
typing to styles object.
* Add release notes for maintenance updates addressing lint violations
* Remove style prop from CustomTooltip to prevent container layout styles from affecting tooltip
Co-authored-by: matiss <[email protected]>
* Refactor NetWorthGraph component by extracting TrendTooltip and StackedTooltip into separate functions for improved readability and maintainability. Update tooltip props to include necessary parameters for rendering. Clean up unused code and enhance tooltip styling.
* Refactor NetWorthGraph component to streamline tooltip handling
- Removed unnecessary prop passing for translation function in TrendTooltip.
- Adjusted import statements for better clarity and consistency.
- Cleaned up code to enhance readability and maintainability.
---------
Co-authored-by: Cursor Agent <[email protected]>
* Upgrade oxfmt/oxlint and migrate import sorting to oxfmt
Upgrade oxfmt from 0.22.0 to 0.26.0 and oxlint from 1.38.0 to 1.41.0.
Move import sorting configuration from oxlint (perfectionist/sort-imports)
to oxfmt's new experimentalSortImports feature, which provides native
import sorting support in the formatter.
* Add release notes for maintenance updates including oxlint and oxfmt upgrades
* Fix accessibility issues: use semantic HTML and correct tab indices
- Replace View with semantic h1 in ModalHeader
- Fix tabIndex from 1 to 0 in Menu component
- Remove disabled oxlint accessibility rules
- Update components to use proper semantic HTML elements
* Refactor button elements to semantic HTML in Autocomplete and CategoryAutocomplete components
- Replace button elements with div/View while maintaining role="button" for accessibility.
- Update styles and props accordingly to ensure consistent behavior.
- Adjust onClick types in Item and SecondaryItem components for better type safety.
* Add release notes for upcoming maintenance updates addressing various accessibility issues
* Refactor autocomplete components to improve text alignment and button semantics
- Added textAlign: 'left' style to AccountItem and PayeeItem for consistent text alignment.
- Removed type="button" from CategoryItem to streamline button semantics.
- Updated ItemContent to use the Button component instead of a button element, enhancing accessibility and consistency.
* Refactor budget and report components to improve text alignment
- Removed font: 'inherit' style from EnvelopeBudgetComponents and TrackingBudgetComponents for cleaner styling.
- Updated ActionableGridListItem and ReportCard components to replace font: 'inherit' with textAlign: 'left' for consistent text alignment.
* Update ActionableGridListItem to include font inheritance for improved styling consistency
* Refactor button elements to use the Button component for consistency and improved semantics
- Updated various components (EnvelopeBudgetComponents, IncomeCategoryMonth, CategoryMonth, ActionableGridListItem, ReportCard, DesktopLinkedNotes) to replace native button elements with the custom Button component.
- Adjusted styles and event handlers to align with the new Button implementation, ensuring consistent behavior and accessibility across the application.
* Update Button and ActionableGridListItem styles for consistency
- Set a fixed borderRadius of 4 for the Button component, ensuring uniformity across variants.
- Adjusted ActionableGridListItem to have a borderRadius of 0 for a cleaner design.
* Update CategoryAutocomplete to include button type attribute for improved semantics
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #6679
* Update VRT screenshot for Payees search functionality
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Apply import sorting with perfectionist/sort-named-imports rule
- Add perfectionist/sort-named-imports oxlint rule
- Sort named imports: value imports before type imports
- Update component-library and desktop-client files to match new rule
* Add release notes for linting updates on named imports
* lint: patch some no-empty-function violations
* docs: update ESLint rules and remove unused loadOwner function in UserAccess component
* refactor: remove getRemoteFile function and associated method from budget file handlers
* chore: disable docstring checks in coderabbit configuration
* Update linting rules and replace @ts-ignore with @ts-expect-error
* Add release notes for PR #6636
* Fix TypeScript linting issue by adding @ts-ignore for electron types in server start message
* Change category to Maintenance and update linting rules
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* lint: clean up unnecessary config and disables
* fix: update package import path in browser preload script
* lint: create custom ESLint rules for rules not in oxlint
- Add object-shorthand-properties rule (replaces object-shorthand)
- Add prefer-const rule (replaces prefer-const)
- Add no-anchor-tag rule (replaces no-restricted-syntax for <a> tags)
- Add no-react-default-import rule (replaces no-restricted-syntax for React.*)
These custom rules are needed because oxlint doesn't support these rules yet.
All rules are properly tested and integrated into the ESLint config.
* refactor: enhance prefer-const rule to track variable reassignments by scope
- Introduced a mapping of scopes to reassigned variable names, improving the accuracy of the prefer-const rule.
- Added helper functions to determine variable scopes and reassignment status.
- Updated logic to check variable reassignments during declaration analysis.
- Adjusted test cases to reflect changes in variable handling.
* Add a name to the eslint plugin.
* Add release note.
* Also update the no-restricted-imports patterns in .oxlintrc.json.
The glob library is different from what ESLint uses, so the globs need
a bit of adjustment.
* lint: move actual eslint rules to oxlint and some eslint
* Update ESLint configuration to remove test file patterns from linting
* Add review status configuration to .coderabbit.yaml
* Remove oxlint plugin from ESLint configuration and package dependencies
* Update linting configuration and fix related issues
* Fix type coercion for comment ID in check-first-comment.js to ensure proper comparison with summary comment IDs
* Simplify ESLint config and add oxlint configuration
- Switch from typescript-eslint recommended to base config
- Remove redundant TypeScript-specific rules that are handled by base config
- Add oxlint configuration with appropriate rules
- Simplify globals configuration using globals package
- Add coverage directory to ESLint ignores
- Clean up various TypeScript rule configurations
* Add release notes for PR #6443
* [autofix.ci] apply automated fixes
* Refactor release note generator and update CLI argument parsing
- Adjusted the release note generator to fix string formatting.
- Refactored CLI argument parsing in migrate/cli.ts to use parseSync for improved clarity and consistency.
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
- Removed temporary ignores for the docs package.
- Updated linting rules for the docs package to improve code quality.
- Refactored variable declarations from `let` to `const` for better consistency.
- Added a new configuration file for oxlint in the docs directory.
- Made minor formatting adjustments across various components.