Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

foamwiki

A Rust-backed, notebook-first Python library and thin CLI for Foam-style Markdown wikis (folders of notes connected by [[wikilinks]]).

The native core reads and parses notes in parallel, maintains the identity and resolution indexes, and stores the link graph. The Python layer preserves the convenient data-oriented API, PyYAML frontmatter values, templates, and filesystem mutation receipts.

Installation

The distribution is named foam-wiki; the Python package and command are both named foamwiki.

Install the stable release:

uv add foam-wiki
# or: python -m pip install foam-wiki

Until the first stable release, opt into the published prerelease:

uv add --prerelease allow foam-wiki
# or: python -m pip install --pre foam-wiki

Run the CLI without adding a project dependency:

uvx --from foam-wiki foamwiki --help

To install the current branch directly from Git:

foam-wiki @ git+https://github.com/nimashoghi/foampy.git

Git installations build the extension from source and require Rust 1.88 or newer. CI produces CPython stable-ABI wheels for manylinux2014 x86_64 and AArch64 (glibc-based Linux), macOS x86_64 and Apple silicon, and Windows x86_64. Each wheel supports Python 3.10 and newer.

Core API

import foamwiki

ws = foamwiki.load()                 # walk up to .foam/ ; parse + index once
note = ws["mean-flow"]             # lookup by shortest id or path
note.title, note.tags, note.outline
note.backlinks()                   # who links here

ws.resolve("flow-matching")        # -> the target Note (falsy Unresolved if broken)
hits = ws.search("TM-align")       # compact immutable Sequence[Hit]
hits[:20]                          # materialize only the rows being inspected
hits.materialize()                 # explicit eager Rows[Hit], when required
foamwiki.orphans(ws)                 # whole-graph census (free functions)
foamwiki.check(ws)                   # strict link diagnostics
foamwiki.rename(ws, note, "papers/meanflow.md")   # dry-run preview; pass dry_run=False to apply

Resolution validates #heading and #^block fragments. Ambiguous attachment suffixes return a falsy Unresolved(reason="ambiguous") rather than silently choosing one file. Percent-encode reserved characters in attachment paths, for example ![[fig%23draft%5D.png]] for fig#draft].png; diagnostic suggestions do this automatically.

Workspace-wide operations verify that the effective configuration, indexed file census, and every indexed note still match the loaded snapshot. Applied mutations also reject symlink-backed write sources, stage all output before changing the workspace, and roll back on write or reload failure. A dry run therefore remains safe to review even while another editor is active: replanning or applying it fails loudly instead of overwriting newer content.

Compact notebook output

Public records use compact, payload-free representations while keeping identifiers and paths intact. Potentially large text fields are bounded. Search hits center an 88-character excerpt on the match instead of dumping the complete source line and nested Note/Pos records:

<Hit alphafold-2/paper L272:550 '...colaboratory). TM-align v. 20190822 (https://zhanglab.dcmb.med.umich.edu/...'>

Rows, SearchResults, tag indexes, document outlines, and node child menus display at most 20 entries and report how many remain. Slice them to continue. Literal SearchResults also materialize public hit records only on access; call .materialize() for an eager Rows[Hit]. Automatic mutation diff previews are bounded; call ChangeSet.diff() for the complete diff. These limits affect display only: Hit.text and Match.line retain the exact source line (including indentation), while record fields, iteration, and .to_df() retain complete data. Passage remains intentionally unbounded because evaluating .body or .read() is an explicit request for content.

Template authoring

Markdown templates can declare foam_template.filepath and use Foam variables in both their content and destination. Preview first, then repeat the reviewed call with dry_run=False:

draft = foamwiki.create(
    ws,
    template="meeting-scratchpad",
    when="2026-07-15T14:30:00+01:00",
    dry_run=True,
)
draft.path, draft.frontmatter, draft.text

note = foamwiki.create(
    ws,
    template="meeting-scratchpad",
    when="2026-07-15T14:30:00+01:00",
    dry_run=False,
)

foamwiki.daily(ws, "2026-07-15", dry_run=True) uses daily-note.md and prefers its template filepath. Explicit destinations always override template metadata.

Structure-aware reading (for notebook agents)

Read a large markdown file without dumping it into context. foamwiki.read returns a priced, navigable map of the file's sections — orient cheaply, drill by stable numeric path, search to a section, then read only what you choose:

doc = foamwiki.read("design.md")     # (or note.doc for a vault note — no reparse)
doc                                # repr = a priced table-of-contents (~150 tok for a 40k-tok file)
doc["3.2"]                         # drill by numeric path (or doc["Method"] / doc[3]); prints a menu, never dumps
doc.search("KL")                   # term -> the sections that contain it (Rows[Match])
doc["3.2"].body                    # read just this section's prose (a priced Passage); .read() for the whole subtree
doc["3.2"].children                # tree nav as properties: .parent .children .siblings .next .prev

Every view quotes exact line counts + ~token estimates, so you budget before you spend. Works standalone on any .md file (no workspace needed).

See AGENTS.md for the design philosophy and the placement rule. pandas and networkx are optional extras used lazily by .to_df() and to_networkx(); request the all extra in the Git dependency when needed: foam-wiki[all] @ git+https://github.com/nimashoghi/foampy.git.

Development

uv sync
uv run pytest -q
uv run ruff check .
uv run basedpyright src scripts
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets --all-features

See PERFORMANCE.md for the real-workspace baseline and reproducible benchmark command. MIGRATION.md lists the intentional behavior and naming changes. RELEASING.md documents local and CI release validation.

MIT licensed.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

foam_wiki-0.4.0.dev0.tar.gz (177.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

foam_wiki-0.4.0.dev0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

File details

Details for the file foam_wiki-0.4.0.dev0.tar.gz.

File metadata

  • Download URL: foam_wiki-0.4.0.dev0.tar.gz
  • Upload date:
  • Size: 177.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for foam_wiki-0.4.0.dev0.tar.gz
Algorithm Hash digest
SHA256 bb58c9518a1286ace29b545ffedf6c4e8235cfd5c6c9b768f503e16d708ace7a
MD5 70377248cd0ea4264b196c19003b754b
BLAKE2b-256 d9c1da782d3458636c25301b55b65ef699afbd2393fe6733c8da29daf20d489d

See more details on using hashes here.

File details

Details for the file foam_wiki-0.4.0.dev0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: foam_wiki-0.4.0.dev0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for foam_wiki-0.4.0.dev0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 04917edad16e5254ac46a232fa6388c6ec1a466bc63a910156ab04fc3daef0b1
MD5 7e02b437f2ef53de6d9ae1b53bf0c02d
BLAKE2b-256 58945775abef594a3d449117bd0643c8d3e51d42ffa3fa28ed24b130e412e6b2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page