Local-first flow editor and engine — visual flows that live in git, compose into bigger flows, and run headless in CI
Project description
napflow
Local-first, git-friendly, node-based flow editor and engine for complex API request/response processing — think "Postman Flows, but open, file-based, Python-powered, and composable." Built for QA and dev teams who test APIs and want their flows reviewed, diffed, and run in CI like any other code.
Status: v0.1.0 — developer preview. The first working milestone:
file format, validator, CLI, headless engine (full node catalog), and
the visual canvas (edit, run, inspect, history) work end to end on
macOS, Windows, and Linux. All v0.x formats—including the current
schema: napflow/v1 marker—are experimental and may change before
v1.0. napflow assumes trusted workspaces (flows run real Python on
your machine) and is localhost-only. The accepted v0.2
full-fidelity/hardening plan is in docs/PLAN.md
(D33–D37).
Why
- Git-friendly — a flow is one YAML file + one
nodes.pyin one folder; diffs are small and reviewable, canvas layout never pollutes logic diffs. - Composable — any flow is usable as a node inside another flow (by reference, never copy). Every canvas is a flow.
- Python-native — response parsing/logic are real Python functions,
testable with pytest; the engine is importable
(
from napflow.core import ...). - CI-first — headless
napf runwith assert-driven exit codes is a first-class citizen, not an afterthought. - Full observability — request/response detail (headers, bodies, timing, retries) captured in run history; v0.2 removes the remaining destructive capture limits with store-once full-fidelity content.
What works today
| Command | Status | Does |
|---|---|---|
napf init |
✅ | scaffold a workspace (demo + offline smoke flow included) |
napf list |
✅ | discovered flows with their input/output ports |
napf check |
✅ | validate everything — schema, edges, guards, references, env — with file:line diagnostics and CI exit codes |
napf run |
✅ | headless engine — full node catalog incl. python worker, JSONL run history, exit codes 0/1/2/130 |
napf ui |
✅ | visual canvas on localhost — edit flows (autosaved through the canonical serializer, clean diffs), edit nodes.py in-browser, run with live animated events + full request/response detail, replay any run from history, drill into subflows, clone shared flows |
Try it
Needs Python 3.12+; simplest with uv:
uv tool install napflow
napf init my-flows && cd my-flows
napf check
napf run flows/smoke # headless, offline demo flow
napf ui # opens the canvas in your browser
Install from PyPI (above) or a GitHub release wheel. Direct
git+httpsinstalls serve a placeholder UI — the bundle is build output, not in git; deterministic Git installs are planned (FR-1113).
What a flow looks like
schema: napflow/v1
flow:
name: example
nodes:
- id: start
type: start
config:
ports:
- {name: base_url, type: string, default: "{{ env.BASE_URL }}"}
- id: get_echo
type: request
config: {url: "{{ inputs.base_url }}/get"}
- id: verify
type: assert
config:
checks:
- {kind: status, equals: 200}
- id: end
type: end
config: {ports: [{name: response}]}
edges:
- {from: start.out, to: get_echo.trigger}
- {from: get_echo.response, to: verify.in}
- {from: verify.passed, to: end.response}
Message-driven, not a DAG: nodes fire when messages arrive, retry cycles
are legal (guarded by counter/timeout nodes), errors travel on
error ports as data, and an unproduced required output fails the run —
no false greens.
Documentation
| Doc | What it pins |
|---|---|
| napflow-flow-schema.md | flow.yaml format + the full node catalog |
| napflow-workspace-manifest.md | napflow.yaml, CLI surface, env model |
| napflow-engine-spec.md | scheduler, frames, firing rules, events, check rules |
| yaml-profile.md | the canonical YAML read/emit profile |
| DECISIONS.md / EDGE_CASES.md | why, and what almost went wrong |
| PLAN.md / JOURNAL.md | roadmap + working journal |
| RELEASING.md | versioning scheme + release flow |
Development
uv sync
uv run pytest # test suite
uv run ruff check # lint
uv run lint-imports # architecture contract: core imports nothing from cli/server
UI (dev-time only — users get the pre-built bundle inside the wheel):
cd ui
npm ci
npm run build # bundle → src/napflow/server/static (what `napf ui` serves)
npm run dev # Vite dev server, proxies /api + /ws to a running `napf ui`
npm run e2e # Playwright against the built bundle (needs npm run build)
Conventional commits (type(scope): subject) — they feed the
git-cliff changelog.
License
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 napflow-0.1.0.tar.gz.
File metadata
- Download URL: napflow-0.1.0.tar.gz
- Upload date:
- Size: 700.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
730a0470f525a9ef8292deaa18485287d647f50ef04fc8874dc7afb142f88591
|
|
| MD5 |
e2c3a1f54260a7f16aaf8529cb9fa024
|
|
| BLAKE2b-256 |
d2639d307c3000185726e9e3f40b021252ddd235d71567196b7135bf12731f70
|
Provenance
The following attestation bundles were made for napflow-0.1.0.tar.gz:
Publisher:
release.yml on nickosh/napflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
napflow-0.1.0.tar.gz -
Subject digest:
730a0470f525a9ef8292deaa18485287d647f50ef04fc8874dc7afb142f88591 - Sigstore transparency entry: 2144798597
- Sigstore integration time:
-
Permalink:
nickosh/napflow@0dca1c0438eb7f0a0dbbc43d52797b025ef7371a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/nickosh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0dca1c0438eb7f0a0dbbc43d52797b025ef7371a -
Trigger Event:
push
-
Statement type:
File details
Details for the file napflow-0.1.0-py3-none-any.whl.
File metadata
- Download URL: napflow-0.1.0-py3-none-any.whl
- Upload date:
- Size: 376.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
407768d54464a9406094bf59d6942909c8cf351334126588f8d1545d21f81269
|
|
| MD5 |
0d06a584c6f20a509d7774a4cfd9d683
|
|
| BLAKE2b-256 |
c58684e8de7565463cba8699317ad3963171899fcda42aba476d317b96ebda9f
|
Provenance
The following attestation bundles were made for napflow-0.1.0-py3-none-any.whl:
Publisher:
release.yml on nickosh/napflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
napflow-0.1.0-py3-none-any.whl -
Subject digest:
407768d54464a9406094bf59d6942909c8cf351334126588f8d1545d21f81269 - Sigstore transparency entry: 2144798646
- Sigstore integration time:
-
Permalink:
nickosh/napflow@0dca1c0438eb7f0a0dbbc43d52797b025ef7371a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/nickosh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0dca1c0438eb7f0a0dbbc43d52797b025ef7371a -
Trigger Event:
push
-
Statement type: