Skip to main content

kedge

CI PyPI Python Licence

Turn manual Excel processes into reviewable, reproducible marimo notebooks, with an AI copilot that operates the notebook through a controlled tool surface.

Status: under active construction. See PLAN.md for the full brief.

What it does

  1. Analyses a workbook offline — formula regions, dependency graph, SQL connections, Power Query M, cached values, and a findings list (circular refs, volatile functions, IFERROR swallowing, inconsistent formulas within a region).
  2. Plans the conversion — an AI-proposed, user-approved ProcessPlan describing stages, open questions, and what it intends to drop.
  3. Scaffolds a marimo notebook from the approved plan.
  4. Reconciles the generated Python against the values Excel last cached, so the translation checks itself against evidence rather than declaring itself finished.

Quick start

uv tool install kedge
kedge hub                  # a browser landing page: every workbook kedge has seen
kedge open process.xlsx    # straight to one, if you already know which

kedge hub starts the server with nothing open and puts a browser on the list. Add a workbook by browsing the filesystem, pasting a path, or dropping one on the page; each row shows whether the file is still there, whether a notebook and an approved plan exist, how many findings the analysis turned up and how much of the workbook the plan believes it can convert. Opening one runs the same sequence kedge open runs — clean up, analyse, plan, scaffold, spawn marimo, bootstrap the session — with the progress streamed into the page, and lands you in the chat-plus-notebook view. Where a marimo kedge started is still running, the hub offers to reattach rather than starting a second.

The AI half needs an endpoint. Open Settings on the hub and give it an OpenAI-compatible base URL, a key and a model — the hosted API, a gateway, or something local. The base URL and model go to ~/.kedge/config.toml; the key goes to the operating system's keyring and never to a file. Until a key is stored, workbooks open in demo mode, where a scripted agent answers and nothing is sent to a model — so the analysis, the scaffold and the notebook all work with no endpoint at all.

Behind a corporate proxy, kedge verifies the endpoint against your operating system's trust store rather than against Python's bundled certifi, so a TLS-inspecting proxy whose root your IT department has already installed just works. Where it does not, kedge doctor says which certificates are in play and what to do; the fix is ca_bundle under [model], pointing at the proxy's root as a PEM. There is no option to disable verification (SECURITY.md says why).

Reasoning is set in the same panel, and left unset by default. kedge prefers the responses API because it is the only one that carries a reasoning model's thinking across a tool call, and every kedge turn is tool calls. Neither that choice nor the reasoning setting can end a turn: an endpoint with no /responses route is discovered on the first call and spoken to in chat completions from then on, and a request refused over reasoning is retried without it. Pin api under [model] in ~/.kedge/config.toml to skip the probe.

Or, offline and standalone — the analyser is useful on its own:

kedge inspect process.xlsx --out analysis.json --report report.html

docs/analyser-worked-example.md walks that output line by line over two of the test fixtures — a clean pipeline and a deliberately hostile workbook — which is the quickest way to see what the analyser actually finds before pointing it at anything of your own.

The planning step is a set of commands as well as a conversation, and the review gate is the same either way:

kedge plan propose process.xlsx --dry-run   # read the plan; write nothing
kedge plan propose process.xlsx             # save it, as a draft
kedge plan show process.xlsx                # stages, open questions, drops, what blocks approval
kedge plan acknowledge process.xlsx --all   # sign off the ranges it proposes to drop
kedge plan approve process.xlsx             # nothing is scaffolded before this

Only propose needs a model. Every other verb reads a plan from disk and writes a decision back, so a plan can be read, questioned and approved with no endpoint configured at all. Approving is always a separate act — there is no flag that proposes and approves in one breath — and a plan that proposes dropping a range cannot be approved until each drop has been confirmed or refused, because silent removal is indistinguishable from a bug. kedge plan reject and kedge plan request-changes are the other two answers, and kedge plan history lists every version with its approval state: when the process changes next quarter, the diff of the plan is the change record, which only works if last quarter's plan is still there.

Replacing a plan that is already approved shows you what changes before it happens. propose prints the diff against the version in force, and approve prints it again and asks, so nobody swaps one decomposition for another without seeing the two side by side; --yes skips the question for scripts. Taking an approval back is deliberate in the same way: reject and request-changes refuse an approved plan unless you pass --withdraw-approval, because a notebook may already have been scaffolded from it. A rejection is terminal — the way on from one is a new plan, not an edit to the rejected one.

propose exits 2 when triage recommends against converting the workbook at all. That is a result rather than a failure, and it is a different exit code from an ordinary error so a script can tell "this workbook should not be converted" from "no such workbook". --force overrides it.

Once the notebook exists, hand-ins arrive through a watched folder rather than by hand:

kedge watch process.xlsx --dir \\share\inbox --once   # sweep and exit; for a scheduled task
kedge watch process.xlsx                              # watch until Ctrl-C

Every file is copied into the workbook's managed store, hashed, dated and receipted, so "this run consumed this file" is a claim you can defend. --once is idempotent: a file already in the store is skipped by hash. --dir is relative to where you are standing; set ingest.watch_dir in a kedge.toml beside the workbook instead and it is relative to the workbook, so a scheduled sweep finds the same folder you did.

Design notes

  • Generated code is polars, never pandas — enforced in the validation gate.
  • Excel's semantics do not match polars' (rounding mode, empty-vs-null, divide-by-zero). kedge.xl is a registered polars namespace that makes each compatibility choice explicit and greppable: col("amount").xl.round(2).
  • Single-user, local, loopback-bound. No accounts, no server deployment.

Contributing

CONTRIBUTING.md is the short version; CONVENTIONS.md is binding — read it before opening a pull request. CLAUDE.md is the shortest useful orientation to the codebase, RELEASING.md covers how a version tag becomes a release, and SECURITY.md describes the actual trust boundary (loopback, no auth, the machine rather than the account), which is worth reading before touching anything that binds a socket or logs a payload.

uv sync
uv run pytest                       # unit + corpus
uv run pytest -m contract           # live-kernel tests; spawns a real marimo
uv run ruff check . && uv run ruff format --check .
uv run python scripts/guardrails.py

Apache-2.0.

Release files for kedge 0.0.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kedge 0.0.10
File Size Uploaded
kedge-0.0.10.tar.gz 1.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for kedge 0.0.10
File Interpreter ABI Platform
kedge-0.0.10-py3-none-any.whl Python 3 none any Details

Total release size: 2.0 MB

Release files / kedge-0.0.10.tar.gz

Download URL kedge-0.0.10.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
ac417be717fa1b795dcc72c0364e1ed2da77deb24d48940363354a4047bfa78e
BLAKE2b-256 checksum
How to use checksums
1723ef099054a1b30827ade44a49046488b4ca1f9c1851ceaba4afc1cad68d27
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 13, 2026.

Transparency log

Release files / kedge-0.0.10-py3-none-any.whl

Download URL kedge-0.0.10-py3-none-any.whl
Size 688.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0aa37f8376748b50db6e0f3d944ed57f9a7bc964427c1c8b70ee425fa9f3c498
BLAKE2b-256 checksum
How to use checksums
3ed29bc139fc5b6bad986b4325612341b184cdb0654e0bcde815ebe6b8ec94d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 13, 2026.

Transparency log

Release history Release notifications | RSS feed

0.0.11

2 release files

This release

0.0.10 This release

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page