{"id":45520907,"url":"https://github.com/colonelpanic8/keepbook","last_synced_at":"2026-06-13T03:12:01.489Z","repository":{"id":335458521,"uuid":"1145818882","full_name":"colonelpanic8/keepbook","owner":"colonelpanic8","description":"Open-source personal finance manager with git-backed, human-readable storage","archived":false,"fork":false,"pushed_at":"2026-06-11T08:18:53.000Z","size":8030,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-06-11T10:12:46.976Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/colonelpanic8.png","metadata":{"files":{"readme":"README.org","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-30T08:54:55.000Z","updated_at":"2026-06-11T08:18:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/colonelpanic8/keepbook","commit_stats":null,"previous_names":["colonelpanic8/keepbook"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/colonelpanic8/keepbook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colonelpanic8%2Fkeepbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colonelpanic8%2Fkeepbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colonelpanic8%2Fkeepbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colonelpanic8%2Fkeepbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/colonelpanic8","download_url":"https://codeload.github.com/colonelpanic8/keepbook/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colonelpanic8%2Fkeepbook/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34270485,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-22T22:55:22.702Z","updated_at":"2026-06-13T03:12:01.483Z","avatar_url":"https://github.com/colonelpanic8.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"#+TITLE: keepbook\n#+AUTHOR:\n#+OPTIONS: toc:2\n\n* Overview\n\nKeepbook is a local-first personal finance toolkit focused on data ownership.\n\n- Your data is stored in plain JSON/TOML/JSONL files.\n- The on-disk format is human-readable and easy to inspect/edit with normal tools.\n- The data directory is fully portable: copy it, back it up, version it, and keep it long-term without lock-in.\n\n* App Downloads\n\nAndroid APKs and desktop app bundles are attached to the latest GitHub release:\n\n- https://github.com/colonelpanic8/keepbook/releases/latest\n\n* CLI\n\nThe main Rust binary is =keepbook=. Commands emit JSON.\n\nCLI usage is intentionally not duplicated in this README. The command tree,\nflags, arguments, defaults, conflicts, and help text are defined in the Rust\n=clap= parser and should be read from the binary:\n\n#+BEGIN_SRC bash\nkeepbook --help\nkeepbook \u003ccommand\u003e --help\nkeepbook \u003ccommand\u003e \u003csubcommand\u003e --help\n\n# From a checkout:\ncargo run --bin keepbook -- --help\n#+END_SRC\n\n* Configuration\n\nDefault config path resolution:\n\n1. =./keepbook.toml= if present.\n2. Platform data dir fallback via =dirs::data_dir()=:\n   - Linux: =$XDG_DATA_HOME/keepbook/keepbook.toml=, or =~/.local/share/keepbook/keepbook.toml= when =XDG_DATA_HOME= is unset.\n   - macOS: =~/Library/Application Support/keepbook/keepbook.toml=.\n\nWhen no config file exists, defaults are used and the intended config directory becomes =data_dir=.\n\nConfig fields:\n\n#+BEGIN_SRC toml\n# Optional; if relative, resolved against config directory\n# data_dir = \"./data\"\n\nreporting_currency = \"USD\"\n\n[display]\n# Optional; if set, values denominated in the reporting currency are rounded to\n# this many decimal places in CLI output.\n# currency_decimals = 2\n#\n# Optional UI-oriented display fields (canonical JSON numeric values are unchanged):\n# currency_grouping = true\n# currency_symbol = \"$\"\n# currency_fixed_decimals = true\n\n[refresh]\nbalance_staleness = \"14d\"\nprice_staleness = \"24h\"\n\n[tray]\n# Start the desktop UI hidden and open it from the tray icon.\nstart_minimized = false\n# Number of most-recent portfolio history rows shown in tray menu.\nhistory_points = 8\n# Spending lookback windows (in days) shown as \"Last Nd\" rows.\nspending_windows_days = [7, 30, 90]\n\n[spending]\n# Ignore matching account IDs or names in default portfolio spending reports.\n# ignore_accounts = [\"Individual\", \"acct-123\"]\n# Ignore matching connection IDs or names in default portfolio spending reports.\n# ignore_connections = [\"Schwab\", \"conn-123\"]\n# Ignore accounts containing any matching account tag in default portfolio spending reports.\n# ignore_tags = [\"brokerage\"]\n\n[portfolio.latent_capital_gains_tax]\n# Disabled by default. When enabled, portfolio snapshot subtracts a dynamic\n# virtual liability account from total net worth; no account is written to disk.\nenabled = false\n# Decimal fraction, e.g. 0.23 for 23%.\n# rate = 0.23\naccount_name = \"Latent Capital Gains Tax\"\n\n[git]\nauto_commit = false\n# When omitted, auto_push defaults to auto_commit.\n# Set auto_push = false to auto-commit without pushing.\nauto_push = false\nmerge_master_before_command = false\n#+END_SRC\n\n* Encrypted Credentials\n\nConnection credentials can use =pass=, =env=, or =age= backends. The mobile\nDioxus path should prefer =age= so credentials can live encrypted in the\nkeepbook data repo without depending on =pass=.\n\nThe keepbook data repo should contain a public =keys.nix= file that lists the\nSSH public keys allowed to decrypt age credential files. The source flake reads\nthat repo-local file by default; it does not reference any external checkout at\nruntime. For this data repo, =keys.nix= owns the same recipient grouping used\nfor existing agenix secrets:\n\n#+BEGIN_SRC nix\n# keys.nix in the keepbook data repo\n{\n  agenixKeys = hostKeys ++ kanivanKeys;\n}\n#+END_SRC\n\nPrint the exact SSH public key recipients used by =age -R=:\n\n#+BEGIN_SRC bash\n# Run from the keepbook data repo.\nnix run /path/to/keepbook-source#keepbook-age-recipients\n#+END_SRC\n\nUse a different key attribute when needed:\n\n#+BEGIN_SRC bash\nnix run /path/to/keepbook-source#keepbook-age-recipients -- --attr hostKeys\nKEEPBOOK_AGE_KEYS_ATTR=hostKeys nix run /path/to/keepbook-source#keepbook-age-recipients\n#+END_SRC\n\nEncrypt a pass-style credential payload:\n\n#+BEGIN_SRC bash\ncd /path/to/keepbook-data\npass show finance/coinbase-api \\\n  | nix run /path/to/keepbook-source#keepbook-age-encrypt -- \\\n      -o connections/\u003cconnection-id\u003e/credentials.age\n#+END_SRC\n\nPoint the connection at the encrypted file:\n\n#+BEGIN_SRC toml\n[credentials]\nbackend = \"age\"\npath = \"credentials/coinbase.age\"\n\n# Optional. If omitted in the Dioxus/server path, keepbook uses the saved\n# [git_sync].ssh_key_path from keepbook.toml as the age identity.\n# identity_path = \".ssh/keepbook_sync_key\"\n#+END_SRC\n\nThe decrypted payload uses the same field format as =pass show= output. For\nCoinbase, the relevant fields are =key-name= and =private-key=.\n\n* Storage Layout\n\nPrimary storage root is the resolved =data_dir=.\n\n#+BEGIN_SRC text\ndata/\n  connections/\n    by-name/                      # symlinks to connection dirs\n    {connection-id}/\n      connection.toml             # human config\n      connection.json             # machine state\n      accounts/                   # symlinks to account dirs\n\n  accounts/\n    {account-id}/\n      account.json\n      account_config.toml         # optional\n      balances.jsonl              # append-only BalanceSnapshot rows\n      transactions.jsonl          # append-only Transaction rows\n      transaction_annotations.jsonl\n\n  # market data store (also under data_dir)\n  assets/\n    index.jsonl                   # AssetId -\u003e Asset registry entries\n  prices/\n    {asset-id}/\n      {year}.jsonl\n  fx/\n    {BASE}-{QUOTE}/\n      {year}.jsonl\n\n  # configured network sources\n  price_sources/\n    {source-name}/\n      source.toml\n#+END_SRC\n\nNotes:\n\n- Balances are stored as full snapshots (all holdings for an account at one timestamp).\n- Transaction files are append-only; read path dedupes with last-write-wins by transaction id.\n- Transaction annotations are append-only patches stored separately from raw transactions.\n- Symlinks are rebuilt with =keepbook sync symlinks=.\n- =account_config.toml= supports per-account overrides such as\n  =balance_staleness=, =balance_backfill=, and =exclude_from_portfolio=.\n\n* Price Sources\n\nConfigured in =price_sources/*/source.toml=. Source type controls required credentials and supported asset classes.\n\nImplemented source types:\n\n- Equities: =eodhd=, =twelve_data=, =alpha_vantage=, =marketstack=\n- Crypto: =coingecko=, =cryptocompare=, =coincap=\n- FX: =frankfurter=\n\n* Development\n\n- Rust tests: =cargo test=\n\nUseful helper commands from =justfile=:\n\n- =just kb -- --help=\n- =just run-tray -- --help=\n\n* Architecture\n\nRust modules:\n\n- =src/storage= - storage trait + JSON file implementation.\n- =src/sync= - synchronizer traits, orchestration, auth flows.\n- =src/market_data= - store, source adapters, routers, service builder.\n- =src/portfolio= - valuation, history, and change-point logic.\n- =src/app/= - application command handlers/types.\n- =src/main.rs= - CLI entrypoint.\n- =src/bin/keepbook-sync-daemon.rs= - optional tray sync daemon.\n\n* Why \"Keepbook\"?\n\nKeepbook is about keeping control of your own financial records.\nThe point is durable ownership: plain files, readable forever, portable anywhere.\n\n* License\n\nMIT OR Apache-2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolonelpanic8%2Fkeepbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcolonelpanic8%2Fkeepbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolonelpanic8%2Fkeepbook/lists"}