Commit Graph
6 Commits
Author SHA1 Message Date
1dcf7aaa71 [AI] Support reading secrets from a file with a _FILE environment variable (#8868)
* [AI] Support reading any setting from a file with a _FILE environment variable

Adds the `_FILE` environment-variable suffix convention used by Docker
secrets and Kubernetes file-mounted secrets. Setting `<VAR>_FILE` to a path
makes Actual read that setting's value from the file, so secrets can be
mounted rather than passed through the environment.

This covers both config systems: every env-backed setting in the sync
server's convict schema, and every env-backed setting in the CLI.

On the sync-server side the override is applied after `loadFile()` and
before `validate()`, using `set()`. convict re-imports the environment at
the end of both `load()` and `loadFile()`, so an override applied any
earlier would be clobbered by the plain environment variable.

A `_FILE` variable pointing at an unreadable file is a hard error rather
than a silent fallback, so a secret that failed to mount stops startup
instead of leaving the server running with an empty value.

Refs #5233, #7686. Supersedes the approach in #5235, which applied the
override before `loadFile()` and so had the precedence backwards.

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

* [AI] Address review feedback on _FILE support

- Treat a `_FILE` variable that is set but empty as an unreadable path rather
  than as unset. Previously it fell back to the plain environment variable,
  which contradicted the documented behaviour and hid a failed mount. This
  applied to both the CLI and the sync server; regression tests added for both.
- Read `_FILE` variables by their literal name in the CLI's resolution chain,
  so the `_FILE` variables are greppable in the config module and the
  precedence order is visible in the chain itself. This also keeps `utils.ts`
  free of filesystem access.
- List the remaining supported variables in the CLI environment variable table.
- Rename a test to describe what it asserts.
- Narrow the release note, which overstated the scope: `_FILE` applies to
  settings that already have an environment variable binding.

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

* [AI] Limit _FILE support to secrets

Following the convention set by Docker's official images, where only secrets
get a _FILE variant, this narrows the scope to:

- sync server: ACTUAL_OPENID_CLIENT_SECRET, ACTUAL_GITHUB_TOKEN
- CLI: ACTUAL_PASSWORD, ACTUAL_SESSION_TOKEN, ACTUAL_ENCRYPTION_PASSWORD

ACTUAL_HTTPS_KEY and ACTUAL_HTTPS_CERT already accept a path, so they get no
_FILE variant.

Both sides now name the `_FILE` variables literally at the point of use, so
they are greppable and the precedence order is visible in the call itself.
On the sync server this replaces the generic schema walk, which had to mirror
convict's internal rule for telling a setting from a group; the schema no
longer has to be hoisted to a named const, so load-config.js is reduced to an
import and the override loop.

Also documents ACTUAL_ENCRYPTION_PASSWORD, which the CLI supports but neither
environment variable table listed.

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

* [AI] Use a descriptive name for the temp directory in the config file env tests

Addresses the remaining review nitpick: `dir` did not say what the directory
held. Renamed in both test files for consistency.

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

* [AI] Trim comments and documentation per review

- Shorten the readFileEnv doc comments in both packages, and drop the note in
  load-config.js about which variables are deliberately excluded, keeping the
  two lines explaining why the override runs between loadFile and validate.
- Reduce the server documentation to a short note and move it to the top of
  the page.
- Point at the runtime's own secret support (e.g. Docker secrets) in the CLI
  security notes rather than suggesting a hand-made file.
- Drop the per-variable OpenID section, which repeated the note above it.

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

* [AI] Simplify the wording of the _FILE precedence note

Replaces the sentence in the server docs, the CLI docs and the CLI README with
a shorter statement of precedence, and drops the note about stopping on an
unreadable file, which can be inferred.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
2026-09-07 00:19:26 +00:00
thromerGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>Matiss Janis Aboltins
448e86443b CLI: Search for config file in additional directories. (#8208)
* CLI: Search for config file in additional directories.

Searches in parents up to home directory, and in global config
directory. See changes to `packages/cli/README.md#config-file` for
full directory and filename details.

* Update CLI documention for config file location.

Also sync CLI config file documentation in packages/cli/README.md and
packages/docs/docs/api/cli.md.

* [autofix.ci] apply automated fixes

* Address CodeRabbit comments.

* Fix typos.

* Mention option of trusting CA cert in CLI docs.

Tangential to the rest of the PR, but hardly worth a standalone PR.

* Mention global config directory in release note

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
2026-06-17 20:48:50 +00:00
fd571104c5 [AI] Remove experimental status from Actual CLI (#8102)
* [AI] Move actual-cli out of experimental status

* [AI] Rename CLI release note to a feature slug

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-05 20:21:27 +00:00
9acbd6388b [AI] Cache the CLI's local budget between invocations (#7539)
* [AI] Cache the CLI's local budget between invocations

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

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

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

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

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

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

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

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

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

* [AI] Simplify CLI cache/lock internals

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

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

* [AI] Address PR #7539 review comments

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

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

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

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

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

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

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

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:58:18 +00:00
Matiss Janis AboltinsGitHubClaude Opus 4.6coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>Cursor AgentMatiss Janis Aboltins
edc0242203 [AI] Fix CLI accounts list: compute balances, hide closed, sort by group (#7378)
* [AI] Fix accounts list: compute balances, hide closed, sort by budget group

- Replace empty `balance_current` (bank-sync field) with computed `balance`
  from transaction history via `getAccountBalance`
- Filter out closed accounts by default; add `--include-closed` flag
- Stable-sort on-budget accounts before off-budget
- Add `balance_current` to AMOUNT_FIELDS for table/csv formatting
- Update docs and tests

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

* [AI] Extract duplicate isRecord type guard to shared utils

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

* [AI] Add types condition to api package exports for tsc resolution

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

* Update packages/cli/src/commands/query.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* [AI] Add balance_available/balance_limit to AMOUNT_FIELDS, validate query result.data

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
2026-04-07 19:28:46 +00:00
a43b6f5c47 [AI] Experimental CLI tool for Actual (#7208)
* [AI] Add @actual-app/cli package

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

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

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

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

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

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

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

* Update CLI dependencies and build workflow

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

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

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

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

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

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

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

* Update nightly versioning script to use yarn

* Align versions

---------

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