No description
  • Python 54.1%
  • Zig 35.4%
  • TypeScript 3.9%
  • JavaScript 2.5%
  • HTML 2.1%
  • Other 2%
Find a file
2026-06-06 22:03:36 -07:00
.agents/plugins Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
.codex-plugin Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
apps Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
assets Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
evolution/proposals Add native Python bridge and expand CLI 2026-04-04 19:38:33 -07:00
nvim/beanz Reach upstream Python parity and add editor surfaces 2026-04-04 21:22:47 -07:00
obsidian-plugin Remove custom Obsidian UI 2026-05-17 00:45:22 -07:00
python python: load packaged native library 2026-06-06 22:00:33 -07:00
scripts Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
skills/beanz-ledger Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
src Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
tests Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
third_party Add upstream beanquery compatibility harness 2026-04-04 23:47:19 -07:00
tools Add upstream beanquery compatibility harness 2026-04-09 20:49:39 -07:00
vscode-extension Reach upstream Python parity and add editor surfaces 2026-04-04 21:22:47 -07:00
wasm Reach upstream Python parity and add editor surfaces 2026-04-04 21:22:47 -07:00
.gitignore Remove custom Obsidian UI 2026-05-17 00:45:22 -07:00
.mcp.json Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00
beanz-format.json Initial beanz import 2026-04-03 21:23:47 -07:00
build.zig Add native Python bridge and expand CLI 2026-04-04 19:38:33 -07:00
build.zig.zon Initial beanz import 2026-04-03 21:23:47 -07:00
CONSTITUTION.md Add native Python bridge and expand CLI 2026-04-04 19:38:33 -07:00
flake.lock Initial beanz import 2026-04-03 21:23:47 -07:00
flake.nix nix: patch linux native libc dependency 2026-06-06 22:03:36 -07:00
README.md Add Codex plugin marketplace for Beanz 2026-05-17 02:50:38 -07:00

beanz

beanz is a zero-copy Beancount reimplementation in Zig.

The project is shaped around the Zig compiler's parser architecture:

  • immutable AST over externally-owned source
  • zero-copy token spans
  • explicit parse/lower/check phases
  • mergeable per-file units
  • editor-first workspace state for LSP, MCP, Neovim, VS Code, Obsidian, and native host APIs

The first deployment target is replacing Beancount inside local repos without depending on upstream Python runtime.

Status

What is working now:

  • parser, lowering, formatter, checker, LSP, MCP, native Neovim host
  • WebAssembly host for Obsidian/mobile integration
  • single beanz binary for CLI, LSP, MCP, and Neovim
  • native shared library at zig-out/lib/libbeanz_native.*
  • initial Python compatibility package in python/ backed by the native library, not the CLI

What is not complete yet:

  • full upstream Beancount Python API/data-model parity
  • full upstream checker/loader/plugin semantics
  • direct CPython binary extension module
  • full upstream bean-doctor/treeify parity

Toolchain

This repo is pinned to Zig master through Mitchell Hashimoto's Zig overlay.

nix develop

Core verification:

zig build test
zig build native
zig build wasm
zig build install
python3 tools/report_parser_fixture_progress.py

Current parser fixture target remains:

272 / 272 static extracted parser fixtures passing

CLI

The main binary is beanz.

beanz parse ledger.beancount
beanz check ledger.beancount
beanz lint ledger.beancount
beanz query ledger.beancount 'select distinct account, count(*) as count group by account order by account desc'
beanz format --check ledger.beancount
beanz format -i ledger.beancount
beanz doctor parse --json ledger.beancount
beanz doctor snapshot --json ledger.beancount
beanz lsp
beanz mcp --file ledger.beancount
beanz nvim

Notes:

  • check and lint are aliases.
  • query runs a native bean-query-style executor over the loaded workspace and is also exposed through LSP (beanz/query) and MCP (query_ledger).
  • doctor list-options and doctor print-options alias doctor options.
  • format accepts Beancount width flags for compatibility, but current formatting is driven by beanz-format.json.

Codex Plugin

This repo is also a Codex plugin marketplace. The marketplace manifest is in .agents/plugins/marketplace.json, the plugin manifest is in .codex-plugin/plugin.json, the MCP server bundle is declared by .mcp.json, and the local interactive chart app is served from the MCP resource ui://beanz/ledger-chart.html.

Install from the compatible.systems Git repo:

codex plugin marketplace add https://compatible.systems/conrad/beanz.git --ref main
codex plugin add beanz@compatible-systems

For local development, add this checkout as a marketplace instead:

codex plugin marketplace add .
codex plugin add beanz@compatible-systems

The MCP tools include:

  • set_ledger_file: loads the Beancount file to manage when BEANZ_LEDGER was not configured.
  • ledger_sankey: builds a transaction-posting Sankey locally from the active ledger.
  • ledger_chart: runs a ledger query and opens the bundled chart app for Sankey, bar, or table views.
  • query_ledger, document_snapshot, account_state, diagnostics, quick fixes, and deterministic edit tools.

For local plugin debugging in a second Codex desktop instance:

scripts/codex-debug-sidecar --detach

That launcher creates an isolated CODEX_HOME, a separate Electron user-data directory via CODEX_ELECTRON_USER_DATA_PATH, and a local compatible-systems marketplace that points back at this checkout. It does not copy login state unless BEANZ_CODEX_DEBUG_COPY_AUTH=1 is set.

Native Python

The Python compatibility layer is in python/ and loads the native shared library in-process through ctypes.

Build the shared library first:

zig build native

Then run the Python tests:

PYTHONPATH=python/src python3 -m unittest discover -s python/tests

Optional upstream compatibility suite:

python3 tools/run_upstream_python_suite.py --sync-only
python3 tools/run_upstream_python_suite.py --no-sync --limit 10
python3 tools/run_upstream_python_suite.py --no-sync --summary-only
python3 tools/run_upstream_beanquery_suite.py --sync-only
python3 tools/run_upstream_beanquery_suite.py --no-sync --summary-only
python3 tools/report_compat_progress.py --include-upstream-python --include-upstream-beanquery

Current upstream compatibility baselines:

  • Python API suite: 76 / 76 modules passing
  • Beanquery parser/execution suite: 414 / 414 captured cases passing, with 95 value-only passes and 40 skipped helper-incompatible methods in the broader upstream test tree

Quick smoke:

PYTHONPATH=python/src python3 - <<'PY'
from beancount.loader import load_string
entries, errors, options = load_string("""
2013-05-18 open Assets:Cash USD
2013-05-18 open Expenses:Food USD
2013-05-19 * "Coffee"
  Assets:Cash -4 USD
  Expenses:Food 4 USD
""".strip() + "\n", filename="example.beancount")
print(len(entries), len(errors), sorted(options.keys()))
PY

The Python distribution is beanz, but it vends the upstream-facing module and CLI names:

  • beancount.*
  • beanquery.*
  • beanz.*
  • bean-check
  • bean-query
  • bean-format
  • bean-doctor

Current compatibility also includes the internal BeanQuery-facing modules needed by downstream code that imports the Python API directly:

  • beanquery.connect, Connection, Cursor, Column
  • beanquery.query.run_query
  • beanquery.numberify
  • beanquery.query_compile, query_env, query_render, hashable
  • beanquery.sources.beancount, beanquery.sources.test

The wheel includes Provides-Dist/Obsoletes-Dist metadata for beancount and beanquery, but current pip installers do not treat that as a hard conflict or automatic replacement. In practice, this means:

  • use beanz as the installed Python distribution name
  • treat Nix/system packaging as the place to enforce replacement/conflict rules
  • keep the module names and CLI names compatible inside the single distribution

For older local Python environments that still stumble on modern editable-install paths, python/setup.py develop is included as a compatibility bridge.

Editor Surfaces

LSP

beanz lsp

Native Neovim

The repo ships a native Neovim plugin under nvim/beanz/. The host is Zig, not Lua.

Smoke tests:

bash tools/run_nvim_plugin_smoke.sh
bash tools/run_nvim_completion_smoke.sh
bash tools/run_nvim_syntax_smoke.sh

VS Code

The repo includes a bundled VS Code extension in vscode-extension/ that launches beanz lsp and renders account state in a sidebar.

Obsidian

The mobile-safe Obsidian plugin lives in obsidian-plugin/ and uses the wasm host. The installable bundle is produced under built/obsidian-plugin/beanz/.

Reference Trees

The workspace is bootstrapped around three local references:

  • upstream/beancount
  • upstream/zig
  • upstream/zig-overlay

third_party/beancount-python/ is vendored as the spec/reference tree for fixtures, command/API parity work, and compatibility evaluation. third_party/beanquery-python/ is vendored as the query-language spec/reference tree for optional compatibility evaluation.

Repository Layout

  • src/ast.zig: compact AST/token storage
  • src/tokenizer.zig: zero-copy lexer
  • src/parse.zig: syntax builder
  • src/lower.zig: typed lowering
  • src/check.zig: balance/assertion checking
  • src/edit.zig: editor/workspace state
  • src/cli.zig: batch CLI surface
  • src/native.zig: native C ABI for Python
  • src/wasm.zig: wasm host API
  • python/: native Python compatibility package
  • nvim/: native Neovim plugin
  • vscode-extension/: VS Code extension
  • obsidian-plugin/: Obsidian plugin
  • tools/: fixture extraction, smoke tests, and reports

Governance

Non-trivial architectural changes should land with a BZP-XXXX proposal.