tallyman — deconstructed notebook platform
Project description
tallyman-notebooks
Spike for the Tallyman London 2026 talk "The Future of Notebooks in a Claude Code World".
The plan and proposal live in plan.md / proposal.md. This README covers the V0 spike only.
V0 scope
End-to-end: a Claude Code MCP tool that compiles a xorq expression, materializes a parquet to a content-hashed catalog entry on disk, and pushes a live update to a browser companion via SSE.
What's working:
- MCP tools:
- Catalog:
catalog_run,catalog_load_parquet,catalog_create,catalog_revise,catalog_alias,catalog_rename,catalog_unalias,catalog_list,catalog_diff. - Notebook:
notebook_reorder,notebook_remove,notebook_edit_markdown.
- Catalog:
- Companion (FastAPI on
:7860):/catalog,/catalog/<hash>or/catalog/<alias>— entry list and detail with V_n chips, forensic history, and a link to internal lineage./notebook— curated narrative: cells anchored on aliases, vertical layout, inline markdown editor, ↑/↓ reorder, × remove./lineageand/lineage/<hash>— catalog DAG (cross-entry parents derived fromfrom_catalog) and per-entry internal expression DAG. Pure SVG, no Cytoscape dep./diff/<alias>[/<va>/<vb>]— version diff with code diff, schema diff, per-column stats, key-joined side-by-side, and head() side-by-side./errors/<id>— build-failure detail./api/{entries,aliases,errors,notebook,lineage,catalog_dag}— JSON./api/sse— live updates (new_entry,build_failed,alias_changed,notebook_changed).
- Buckaroo subprocess —
tallyman runspawnspython -m buckaroo.serveron:8700(falls back to a random port if busy), watches for theBUCKAROO_PORT=...handshake, and lazily creates per-entry sessions on first view by POSTing the entry'sxorq_build/dir to Buckaroo's/load_exprendpoint (PR 776) — sort/search push down to the xorq backend rather than paging over a materialised parquet. The build dir is expanded into a tmp copy first so${TALLYMAN_PROJECT_ROOT}placeholders are resolved before xorq's loader sees them. Sessions are persisted undercatalog/buckaroo_sessions.jsonand invalidated by start-time when Buckaroo restarts; tmp dirs are cleaned onBuckarooManager.stop(). Tear-down rides along with the companion. Disable with--no-buckaroo. - Build artifacts are portable. xorq's absolute filesystem paths are
rewritten to
${TALLYMAN_PROJECT_ROOT}on write and expanded back on load. tallyman serve <project_dir>— read-only companion against a project directory that may live anywhere on disk. Mutation routes return 403.
What's NOT yet implemented (see TICKETS.md for the full punchlist):
- SortableJS drag-reorder for the notebook (current ↑/↓ buttons are the accessibility fallback; drag is the headline UX).
- Column-level lineage (xorq has the data; current view is op-level only).
tallyman pack/tallyman replay(today's hand-off iscp -r/tar).- ML training pipeline (storyboard beats 7-8).
Running the spike
uv sync
uv run tallyman init spike # creates ~/.tallyman/projects/spike/ + fixture
uv run tallyman run --project spike # edit-mode companion on http://127.0.0.1:7860
The companion's dataframe embed is a Vite React library in packages/embed/
that builds into src/tallyman_companion/static/buckaroo-embed.{js,css}. The
build artifact is not committed — Node + pnpm are install-time
prerequisites:
cd packages/embed && pnpm install && pnpm build # one-time per checkout
# or, for active embed development:
cd packages/embed && pnpm dev # vite build --watch
Bump buckaroo-js-core in packages/embed/package.json to match the
Python buckaroo pin in pyproject.toml and rebuild whenever either
side moves.
In another terminal, launch Claude Code from this directory; it picks up
.mcp.json and exposes the tallyman MCP server.
Recommended prompts:
Use catalog_load_parquet to load
orders.parquet.Now use catalog_create to make a named entry
shoe_salesthat groups orders by region and totals the price.Now revise shoe_sales to filter to category == "boots" only.
Watch the browser update live as each tool call lands. Named entries float to the top of the catalog with a V_n chip; the previous version sticks around in forensic history.
Serving a project as an artifact
Once you've authored a project, hand it off:
tar czf my-project.tgz -C ~/.tallyman/projects spike
# colleague extracts somewhere
tar xzf my-project.tgz -C ~/projects/
uv run tallyman serve ~/projects/spike
The companion runs read-only: same catalog, same forensic history, no edit affordances. Mutation routes return 403.
Conventions worth knowing
- xorq 0.3.x reads use
xo.deferred_read_parquet(NOTxo.read_parquet— that resolves through ibis's backend loader and fails). Useimport xorq.api as xoandimport xorq.vendor.ibis as ibis. Do NOTimport ibisdirectly. - Prefer
from tallyman_xorq.io import from_project; t = from_project("name.parquet")over absolute paths — the catalog records project-relative intent and the build is portable across machines/users. - Content hash is xorq's build hash — same code + same inputs → same hash → same entry dir (idempotent).
- All catalog state lives on disk. The MCP server holds no in-memory state; the companion only holds the SSE subscriber list.
TALLYMAN_PROJECT_PATHoverrides project_dir() resolution for the active project. Used bytallyman serveto point at a project directory anywhere on disk.
Tests
uv run pytest # 76 tests, ~5s
uv run pytest tests/test_portable.py # the portability proof
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tallyman_data-0.0.1.tar.gz.
File metadata
- Download URL: tallyman_data-0.0.1.tar.gz
- Upload date:
- Size: 438.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77a1cedbf021be5230a3e311b5604b64938f7a9936af24a07b7ded09ad0adf1c
|
|
| MD5 |
420b36b080e7d33de2248f19bb858a91
|
|
| BLAKE2b-256 |
07b22a23f007fba4a06fcc3350e7c7cfa9518fa8520b55d9d85b4581a836cff2
|
File details
Details for the file tallyman_data-0.0.1-py3-none-any.whl.
File metadata
- Download URL: tallyman_data-0.0.1-py3-none-any.whl
- Upload date:
- Size: 106.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f673ae879b2a00ea578d90104ca3a9bae77f6c24e935ffc9e0096380614eac8
|
|
| MD5 |
6e474d0be6d031e04b0317ed57de6b01
|
|
| BLAKE2b-256 |
3204a1ec8002a3be86ce47c2437ec9e42c9ceea0b7ddb2f29cd4514ff6b70e21
|