FEATURED · 精选文章

Actual Budget CLI 完全实战指南:在终端中查询与修改个人预算数据

发布时间 / 2026/9/10 14:43:01
来源 / 创域科博编辑部
栏目 / 资讯中心
Actual Budget CLI 完全实战指南:在终端中查询与修改个人预算数据 Actual Budget CLI 完全实战指南在终端中查询与修改个人预算数据【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actualActual Budget 是一款本地优先local-first的个人财务管理应用而actual-app/cli是它的官方命令行工具让你不必打开网页就能在终端里查询和修改预算数据——账户、交易、分类、收款方、规则、排期交易一应俱全。本文以 packages/cli/README.md 为骨架结合 packages/cli/src 下的源码实现完整讲解 CLI 的安装、配置体系、全部命令、金额约定、缓存与锁机制以及如何在 monorepo 内本地运行调试。读完本文你将掌握用一行命令查余额、批量导入导出交易、执行 ActualQL 查询、自动化设置预算等实战技能。一、认识 actual-app/cli定位与安装CLI 的定位在 packages/cli/README.md 开头就已明确它是 Actual Budget 的命令行接口用于在终端中查询和修改预算数据。有一个关键前提必须理解该 CLI 连接的是正在运行的 Actual 同步服务器sync server它不会直接操作本地预算文件。也就是说CLI 是同步服务器的一个客户端预算数据存储在服务器端CLI 通过actual-app/api与之通信并会在本地保留一份缓存副本用于加速重复读取详见后文缓存机制章节。这一设计从 packages/cli/src/connection.ts 的withConnection实现中可以得到印证——每次命令执行都会先api.init建立连接再按需下载/加载/同步预算。安装与运行环境npm install -g actual-app/cli安装要求Node.js 22这一点同时写在 README 与 packages/cli/package.json 的engines字段中。安装后npm 会注册两个可执行命令见 packages/cli/package.jsonactualactual-cliactual的别名两者都指向构建产物./dist/cli.js。CLI 基于commander构建packages/cli/src/index.ts因此每个命令都支持标准的--help帮助输出。二、快速开始三个命令上手安装完成后先通过环境变量配置连接信息然后就能立即开始使用# 设置连接信息 export ACTUAL_SERVER_URLhttp://localhost:5006 export ACTUAL_PASSWORDyour-password export ACTUAL_SYNC_IDyour-sync-id # 在 设置 → 高级 → Sync ID 中找到 # 列出你的账户 actual accounts list # 查看某个账户余额 actual accounts balance account-id # 查看某月预算 actual budgets month 2026-03三个环境变量各自的职责变量用途ACTUAL_SERVER_URLActual 同步服务器的 URL必填ACTUAL_PASSWORD服务器密码未使用 token 时必填ACTUAL_SYNC_ID预算的 Sync ID大多数命令需要其中 Sync ID 需要在 Actual 网页端「设置 → 高级 → Sync ID」页面获取它用于把 CLI 指向服务器上对应的那一个预算文件。三、配置体系从全局 Flag 到配置文件3.1 配置解析优先级CLI 按以下顺序解析配置优先级从高到低CLI flags--server-url、--password等环境变量配置文件通过 cosmiconfig 查找默认值dataDir默认是~/.actual-cli/data这套优先级逻辑在 packages/cli/src/config.ts 的resolveConfig中逐字段实现例如serverUrl的取值顺序是cliOpts.serverUrl ?? process.env.ACTUAL_SERVER_URL ?? fileConfig.serverUrl ?? dataDir的兜底默认值是join(homedir(), .actual-cli, data)。最终解析出的配置结构CliConfig包含serverUrl、password、sessionToken、syncId、dataDir、encryptionPassword、cacheTtl、lockTimeout、refresh、noLock等字段。需要特别指出的是resolveConfig中有两道硬性校验packages/cli/src/config.ts未配置serverUrl直接报错Server URL is required...未同时配置password与sessionToken直接报错Authentication required...所以密码和会话令牌session token至少二选一二者都没有时命令无法运行。3.2 环境变量全表变量说明ACTUAL_SERVER_URLActual 同步服务器的 URL必填ACTUAL_PASSWORD服务器密码未使用 token 时必填ACTUAL_SESSION_TOKEN会话令牌密码的替代方案ACTUAL_SYNC_ID预算 Sync ID大多数命令需要ACTUAL_DATA_DIR缓存预算数据的本地目录ACTUAL_CACHE_TTL缓存 TTL单位秒默认 60ACTUAL_LOCK_TIMEOUT预算目录锁的等待超时单位秒默认 10ACTUAL_NO_LOCK设为1时禁用预算目录锁除此之外从源码还可以发现一个 README 环境变量表中未列出的变量ACTUAL_ENCRYPTION_PASSWORD对应--encryption-password全局 Flag用于端到端加密E2E encryption预算的解密见 packages/cli/src/index.ts。如果你的预算开启了端到端加密需要在同步时提供这把加密密码connection.ts中下载预算时会将config.encryptionPassword传给api.downloadBudgetpackages/cli/src/connection.ts。3.3 配置文件CLI 使用 cosmiconfig 查找配置文件查找范围是当前工作目录到主目录之间的任意位置向上逐级查找。可以使用的文件名格式.actualrcJSON 或 YAML.actualrc.json、.actualrc.yaml、.actualrc.ymlactual.config.json、actual.config.yaml、actual.config.ymlpackage.json中的actual键此外还可以把配置放在全局配置目录的actual子目录中Linux 上例如~/.config/actual/支持的文件名configJSON 或 YAMLconfig.jsonconfig.yamlconfig.yml配置查找顺序在 packages/cli/src/config.ts 中与 cosmiconfig 的searchPlaces完全对应。一个典型的.actualrc.json示例{ serverUrl: http://localhost:5006, password: your-password, syncId: 1cfdbb80-6274-49bf-b0c2-737235a4c81f, cacheTtl: 60, lockTimeout: 10, noLock: false }配置文件可用的键与全局配置一一对应serverUrl、password、sessionToken、syncId、dataDir、encryptionPassword字符串键cacheTtl、lockTimeout非负整数键noLock布尔键。配置文件的校验逻辑相当严格packages/cli/src/config.ts文件必须是对象、不能包含未知键、字符串键必须是字符串、数值键必须是非负整数、布尔键必须是布尔值否则直接报错。安全提示重要不要在配置文件中保存明文密码包括上面示例里的password键。如果文件确实包含密码请设置严格的文件权限Linux 上例如600如果文件位于 git 仓库内务必加入.gitignore更推荐使用ACTUAL_PASSWORD或ACTUAL_SESSION_TOKEN环境变量或者在配置文件中使用会话令牌session token代替密码。3.4 全局 Flags 全表Flag说明--server-url url服务器 URL--password pw服务器密码--session-token token会话令牌--sync-id id预算 Sync ID--data-dir path数据目录--cache-ttl seconds缓存 TTL0表示禁用缓存默认 60--refresh本次调用强制同步忽略缓存--no-cache--refresh的别名--lock-timeout secs锁等待超时默认 10--no-lock禁用预算目录锁谨慎使用--format format输出格式json默认、table、csv--verbose显示信息性消息以上 Flags 在 packages/cli/src/index.ts 中均有对应定义且每个选项都标注了对应的环境变量。两个值得注意的细节--format使用 commander 的.choices([json, table, csv])约束取值非法值会直接报错--cache-ttl与--lock-timeout都经过parseNonNegativeIntFlag校验必须是非负整数packages/cli/src/index.ts。四、命令总览与实战解析4.1 命令总览表命令说明accounts管理账户budgets管理预算与分配categories管理分类category-groups管理分类组transactions管理交易payees管理收款方tags管理标签rules管理交易规则schedules管理排期交易query运行 ActualQL 查询server服务器工具与查找sync刷新或检查本地缓存运行actual command --help可以查看每个命令的子命令和选项。下面重点剖析几个最常用的命令组均可在 packages/cli/src/commands 目录中看到实现。4.2 accounts账户管理accounts命令组packages/cli/src/commands/accounts.ts包含以下子命令accounts list [--include-closed]列出所有账户。默认排除已关闭账户加--include-closed才包含输出会做稳定排序——预算内账户在前、预算外账户在后并在每组内保持 API 的sort_order同时批量拉取每个账户的余额。accounts create --name name [--offbudget] [--balance amount]创建账户--balance是初始余额整数分默认0。accounts update id [--name name] [--offbudget bool]更新账户名称或预算内外属性不提供任何字段会报错。accounts close id [--transfer-account id] [--transfer-category id]关闭账户可把剩余余额转入指定账户或分类。accounts reopen id重新打开已关闭的账户。accounts delete id删除账户。accounts balance id [--cutoff date]查询账户余额--cutoff支持指定日期YYYY-MM-DD返回该日期节点的余额。4.3 budgets预算管理budgets命令组packages/cli/src/commands/budgets.ts负责预算数据与分配操作budgets list列出服务器上所有可用预算此命令无需 Sync IDskipBudget: true。budgets download syncId [--encryption-password password]按 Sync ID 下载预算加密预算需要提供加密密码。budgets months列出所有存在数据的预算月份。budgets month month查看指定月份YYYY-MM的完整预算数据。budgets set-amount --month month --category id --amount amount为某分类在指定月份设置预算金额整数分。budgets set-carryover --month month --category id --flag bool开启/关闭某分类的结转carryover。budgets hold-next-month --month month --amount amount为下月预留预算金额。budgets reset-hold --month month重置某月的预算预留。4.4 transactions交易增删改查与导入导出transactions命令组packages/cli/src/commands/transactions.tstransactions list --account id --start date --end date列出指定账户在日期区间内的交易。transactions add --account id [--data json] [--file path] [--learn-categories] [--run-transfers]新增交易--data传 JSON 数组或用--file从文件/标准输入读取--learn-categories启用分类学习--run-transfers处理转账。transactions import --account id [--data json] [--file path] [--dry-run]导入交易去重语义与add不同--dry-run可以先预览导入结果而不真正写入。transactions update id [--data json] [--file path]更新指定交易字段。transactions delete id删除交易。--data与--file是互斥的 JSON 输入来源--file -表示从标准输入读取方便与其他命令用管道组合详见readJsonInput的实现。4.5 query用 ActualQL 查询数据query命令组packages/cli/src/commands/query.ts是 CLI 中最强大的数据检索能力底层使用 Actual 的查询语言 ActualQLAQLquery run执行一条 AQL 查询。query tables列出可查询的表。query fields table列出某张表的所有字段及其类型。query run的核心选项选项说明--table table要查询的表可用query tables查看--select fields逗号分隔的字段列表--filter jsonJSON 格式的过滤条件如{amount:{$lt:0}}--where json--filter的别名不能同时使用--order-by fields排序字段可带方向field1:desc,field2默认 asc--limit n结果数量上限--offset n跳过前 N 条用于分页--last n显示最近 N 笔交易隐含--table transactions与--order-by date:desc--count统计匹配行数而非返回数据--group-by fields分组字段配合聚合 select 使用--file path从 JSON 文件读取完整查询对象-表示标准输入从 packages/cli/src/commands/query.ts 的TABLE_SCHEMA可以看到当前可查询的表transactions、accounts、categories、payees、rules、schedules。transactions表的字段非常丰富包括id、account、date、amount、payee、category、notes、cleared、reconciled、is_parent、is_child、parent_id、schedule以及便捷的关联字段account.name、payee.name、category.name、category.group.name。--order-by支持date:desc,amount:asc,id这种带方向的多字段写法解析逻辑在 packages/cli/src/commands/query.ts 的parseOrderBy中实现。4.6 server 与 sync服务器工具与缓存管理server命令组packages/cli/src/commands/server.tsserver version获取服务器版本此命令不需要 Sync ID。server get-id --type type --name name按名称查找实体 ID--type可选accounts、categories、payees、schedules。在脚本中非常实用——先用名字查 ID再拿去查询或写入。server bank-sync [--account id]触发银行同步可只同步指定账户。sync命令组packages/cli/src/commands/sync.tssync立即把本地缓存与服务器同步。sync --status显示本地缓存有多旧stale返回syncedAt、lastDownloadedAt、ageSeconds、ttlSeconds、stale等字段。sync --clear删除本地缓存下次命令会重新下载。五、金额约定整数分cents所有作为输入传入的货币金额无论是 Flag 还是 JSON都使用整数分CLI 值美元金额5000$50.00-12350-$123.50例如-2500表示 -$25.0050000表示 $500.00。这种约定避免了一切浮点精度问题与 Actual 内部的数据存储方式一致。输出格式化规则--format table和--format csv输出时会把分值字段自动转换为十进制例如显示1665.00而不是166500--format json输出始终返回原始分值方便程序化处理。这个自动转换在 packages/cli/src/output.ts 中通过AMOUNT_FIELDS集合实现——amount、balance、balance_available、balance_current、balance_limit、budgeted、spent、carryover这些字段在表格/CSV 输出时都会执行value / 100并保留两位小数。值得一提的安全细节CSV 输出对以、、-、、制表符、回车开头的非数值字符串做了公式注入防护前缀中和但数值型金额如-25.00不会被打引号保证负数金额在电子表格中仍以数值呈现packages/cli/src/output.ts。六、实战示例合集以下示例完整覆盖 README 中的常用场景并补充了便于直接复制运行的注释# 以表格形式列出所有账户默认排除已关闭账户 actual accounts list [--include-closed] --format table # 按名称查找实体 ID脚本自动化第一步 actual server get-id --type accounts --name Checking # 新增一笔交易金额为整数分-2500 -$25.00 actual transactions add --account id \ --data [{date:2026-03-14,amount:-2500,payee_name:Coffee Shop}] # 导出整年交易到 CSV actual transactions list --account id \ --start 2026-01-01 --end 2026-12-31 --format csv transactions.csv # 为某分类设置预算金额$500 50000 分 actual budgets set-amount --month 2026-03 --category id --amount 50000 # 运行一条 ActualQL 查询最近 10 笔支出 actual query run --table transactions \ --select date,amount,payee --filter {amount:{$lt:0}} --limit 10 # 快捷方式最近 5 笔交易 actual query run --last 5 # 统计交易数量 actual query run --table transactions --count # 按分类分组聚合配合 --file 使用聚合表达式 echo {table:transactions,groupBy:[category.name],select:[category.name,{amount:{$sum:$amount}}]} | actual query run --file - # 分页 actual query run --table transactions --order-by date:desc --limit 10 --offset 20 # --where 是 --filter 的别名 actual query run --table transactions --where {payee.name:Grocery Store} --limit 5 # 从 JSON 文件读取完整查询 actual query run --file query.jsonquery run还支持从标准输入读取查询 JSON--file -这让它天然适合被其他脚本和命令管道驱动。AQL 常用过滤操作符包括$eq、$ne、$lt、$lte、$gt、$gte、$like、$and、$or。七、常见坑与实用建议1. 拆分交易Split transactions会重复计数。统计或求和交易时务必过滤is_parent: false。拆分交易的父交易持有总额子交易持有各部分金额——把两者都算进去等于把总额数了两遍。这是 README 明确强调、且query帮助文本中反复出现的注意事项。2. 未分类交易的category.name是null。按分类过滤或分组时要把这个情况考虑进去。3. AQL 不支持日期子字段。date.month、date.year等不能作为查询字段使用。如果需要按月份分组正确做法是用日期范围过滤拉取原始交易然后在本地脚本中自行聚合。4. 高频顺序请求的性能。CLI 默认会在本地缓存预算见下一节所以读多写少的脚本不再需要单查询式的规避方案。对于请求非常频繁的脚本可以先执行一次actual sync然后用较长的--cache-ttl做后续读取actual sync actual --cache-ttl 3600 query run ... actual --cache-ttl 3600 accounts list这样后续的读命令在 TTL 内直接命中本地缓存不产生网络往返。5. 先查 ID 再操作。所有写操作如transactions add、budgets set-amount都要求传实体 ID。在脚本中建议先用actual server get-id --type ... --name ...把人类可读的名字解析成 ID再执行后续操作避免硬编码 UUID。八、缓存机制深度解析CLI 会在本地保留一份预算副本让重复命令不必每次都打同步服务器。在默认 TTL60 秒内读命令list、balance、query run等直接复用缓存不做网络往返写命令add、update、set-amount等则始终在写入前后各同步一次服务器。缓存相关的操作actual sync—— 立即刷新缓存。actual sync --status—— 查看本地缓存有多旧。actual sync --clear—— 删除本地缓存下次命令重新下载。--refresh或--no-cache—— 单次调用强制同步。--cache-ttl seconds—— 单次调用覆盖 TTL用0禁用缓存。缓存的底层决策逻辑非常清晰见 packages/cli/src/cache.ts 的decideSyncAction本地没有缓存状态 → 动作download首次下载预算缓存中的syncId或serverUrl与当前配置不一致 → 动作download重新下载是写操作、或指定了--refresh、或 TTL 为0、或预算加密→ 动作sync先加载再同步距上次同步时间小于 TTL → 动作skip直接用缓存缓存过期超过 TTL→ 动作sync。缓存状态存放在数据目录下以syncId命名的子目录中的state.json文件里包含version、syncId、budgetId、serverUrl、lastSyncedAt、lastDownloadedAt等字段packages/cli/src/cache.ts目录结构为dataDir/.actual-cli/syncId/state.json。缓存写入采用临时文件 原子重命名策略并用进程 PID 随机数保证临时文件名唯一避免并发写者互相破坏packages/cli/src/cache.ts同时缓存持久化是尽力而为的写不进也不至于让命令崩溃。从 packages/cli/src/connection.ts 可以看到完整流程读缓存状态 →decideSyncAction决策 → 按需downloadBudget/loadBudget/sync→ 执行命令回调 → 若是写操作再sync一次并刷新lastSyncedAt。九、并发与锁机制CLI 针对每个预算的缓存目录加锁读操作加共享锁多个并行读安全写操作加排他锁写操作串行化。如果另一个 CLI 进程持锁后续调用最多等待--lock-timeout秒默认 10然后报错退出。在可信的单进程环境中可以传--no-lock跳过加锁。锁实现细节见 packages/cli/src/lock.ts排他锁基于proper-lockfile的目录锁锁文件lock等待超时换算为重试策略共享锁则在readers目录下写入以PID-随机数命名的标记文件写操作要等所有 reader 标记消失才继续。实现里还包含陈旧 reader 清理——通过process.kill(pid, 0)探测进程是否存活自动清扫死进程遗留的标记避免死锁packages/cli/src/lock.ts。锁文件另有 30 秒的 stale 判定崩溃进程遗留的锁也能被后续进程接管。十、在 monorepo 中本地运行与开发如果你想直接在这个仓库里跑 CLI例如调试新功能或不想走 npm 全局安装README 给出了完整流程# 1. 构建 CLI yarn build:cli # 2. 在另一个终端启动本地同步服务器 yarn start:server-dev # 3. 浏览器打开 http://localhost:5006创建一个预算 # 然后在 设置 → 高级 → Sync ID 中拿到 Sync ID # 4. 直接从构建产物运行 CLI ACTUAL_SERVER_URLhttp://localhost:5006 \ ACTUAL_PASSWORDyour-password \ ACTUAL_SYNC_IDyour-sync-id \ node packages/cli/dist/cli.js accounts list # 或者定义一个简写别名方便使用 alias actual-devnode $(pwd)/packages/cli/dist/cli.js actual-dev budgets listyarn build:cli会调用 packages/cli/package.json 中的vite build将 TypeScript 源码编译到dist/。CLI 依赖actual-app/api工作区内的 packages/api、commander参数解析、cosmiconfig配置文件查找、proper-lockfile目录锁、cli-table3表格输出这些依赖关系同样记录在 packages/cli/package.json。结语actual-app/cli把 Actual Budget 的绝大部分核心操作带到了终端账户、交易、分类、预算分配、规则、排期乃至完整的 ActualQL 查询能力。配合环境变量/配置文件的三层配置体系、整数分的金额约定、本地缓存与细粒度锁机制它非常适合承担定时脚本、CI 流水线、数据导出备份等自动化任务。需要进一步探索某个子命令的细节时actual command --help永远是最好的起点——查询相关的actual query run --help还会直接列出所有可用表与常用过滤操作符。【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻