Skip to content

Commit 08931e5

Browse files
committed
docs: add the MkDocs + Read the Docs site
MkDocs Material site (mkdocs.yml, .readthedocs.yaml, docs/requirements.txt) matching the house setup, plus initial content: home, concepts (the model + engine states), installation (from source; npm coming), front doors, the MCP tools reference, architecture, and development. Point the README's Docs badge and Documentation section at flowcontrol.readthedocs.io.
1 parent 3d576a0 commit 08931e5

11 files changed

Lines changed: 399 additions & 3 deletions

.readthedocs.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: 2
2+
3+
build:
4+
os: ubuntu-24.04
5+
tools:
6+
python: "3.12"
7+
8+
mkdocs:
9+
configuration: mkdocs.yml
10+
11+
python:
12+
install:
13+
- requirements: docs/requirements.txt

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
[![CI](https://github.com/mbe24/flowcontrol/actions/workflows/ci.yml/badge.svg)](https://github.com/mbe24/flowcontrol/actions/workflows/ci.yml)
99
![npm](https://img.shields.io/badge/npm-not_yet_published-lightgrey)
10-
![Docs](https://img.shields.io/badge/docs-coming_soon-lightgrey)
10+
[![Docs](https://readthedocs.org/projects/flowcontrol/badge/?version=latest)](https://flowcontrol.readthedocs.io/en/latest/)
1111
[![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-orange.svg)](LICENSE)
1212

1313
**flowcontrol** is a **dependency-aware task graph** for humans and the agents working
@@ -106,8 +106,8 @@ flowui # open the web board (starts the daemo
106106

107107
## Documentation
108108

109-
Full documentation is on its way. For now, the [Quickstart](#quickstart-from-source) above and
110-
the in-repo design notes are the reference.
109+
Full documentation lives at **<https://flowcontrol.readthedocs.io/>** — concepts, installation,
110+
the MCP tools reference, and the architecture.
111111

112112
## License
113113

docs/architecture.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Architecture
2+
3+
flowcontrol is one engine with many surfaces. The design goal: **one data model, one schema,
4+
one set of generated bindings**, reachable natively, from Node, and from the browser.
5+
6+
## flowcore — the engine
7+
8+
`flowcore` (Rust) holds all the logic: the node tree, dependency evaluation, the status
9+
cascade. It talks to storage through a narrow **`Sql` seam** (execute / query / transaction)
10+
rather than a concrete database, so the same engine compiles two ways:
11+
12+
- **native** — over `rusqlite`, for a native daemon;
13+
- **wasm32** — pure Rust, no C toolchain, calling back into a **host** for SQL
14+
(`__flowHostExec` / `__flowHostQuery`).
15+
16+
That host-import design is what lets the identical engine run inside a Node daemon _and_
17+
directly in a browser tab.
18+
19+
## One proto, one dispatch
20+
21+
A single protobuf definition generates the bindings for every language (TypeScript, Go, Rust).
22+
The engine exposes one synchronous `dispatch()` entry point, so a "mutation" is the same shape
23+
whether it arrives from the web board, the CLI, or an agent.
24+
25+
## The daemon
26+
27+
`flowd` (and its Node twin, `flowd.js`) is the **single writer** to one SQLite file. It serves
28+
the task-graph API over **gRPC-web/Connect on HTTP/1.1**, bound to `127.0.0.1`. The web board
29+
is served from the same origin, which removes CORS, mixed-content, and certificate concerns in
30+
one move. A **bearer token** (in `~/.flowcontrol/session.json`, mode 0600) guards the RPC
31+
paths; the daemon also enforces a `Host` allow-list against DNS-rebinding.
32+
33+
## Lifecycle — the store, not the daemon
34+
35+
The daemon is disposable; **SQLite is the source of truth**. Every client runs the same
36+
_ensure-on-connect_: connect to the daemon if one is up (discovered via `session.json`, guarded
37+
by a single-instance lock), else spawn one. If the daemon dies, no data is lost — the next
38+
client brings it back. Persistence is emergent: whichever client's process isn't torn down
39+
keeps the daemon alive; when it goes, the data stays on disk.
40+
41+
## The browser
42+
43+
The standalone web build runs `flowcore` as wasm in a **Web Worker**, persisting to **OPFS**
44+
via `@sqlite.org/sqlite-wasm` (a durable SAHPool VFS). It is the real engine over real SQLite —
45+
fully functional, private to the browser, no network — which is what powers the GitHub Pages
46+
demo.
47+
48+
## Transport, everywhere the same
49+
50+
Browser (`connect-web`), agent server (`connect-node`), and CLI (`connect-go`) all speak the
51+
same gRPC-web/Connect dialect to the same loopback daemon. One transport choice keeps the
52+
clients thin and makes a future hosted, multi-tenant deployment (the `Sql` seam over a cloud
53+
database, keyed by a `workspace`) a natural extension rather than a rewrite.

docs/concepts.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Concepts
2+
3+
## The hierarchy
4+
5+
flowcontrol has one fixed shape:
6+
7+
| Kind | Parent | Purpose |
8+
| --- | --- | --- |
9+
| **Work package** | — (top level) | a body of work; groups tasks |
10+
| **Task** | a work package | a unit of work with a verifiable **condition** |
11+
| **Step** | a task | the granular thing an agent executes and checks off |
12+
13+
Everything lives inside a **project** — the namespace that holds the whole tree.
14+
15+
## Dependencies
16+
17+
Any node can block any other node **across levels** — a step can block a whole work package.
18+
A dependency edge means _the blocker must be `DONE` before the blocked node can become
19+
workable_. Cycles are rejected.
20+
21+
## Declared vs. effective status
22+
23+
Every node carries a **declared** status you set, and an **effective** status the engine
24+
computes from the graph. You only ever set the declared one:
25+
26+
| You set (declared) | meaning |
27+
| --- | --- |
28+
| `OPEN` | workable — hand it to the engine |
29+
| `DEFERRED` | paused on purpose |
30+
| `DONE` | complete |
31+
32+
The engine derives the effective status — you cannot set these directly:
33+
34+
| Effective | meaning |
35+
| --- | --- |
36+
| 🟢 **READY** | every blocker is `DONE` — workable now |
37+
| 🔴 **BLOCKED** | still waiting on a blocker |
38+
|**DEFERRED** | you paused it |
39+
| 🔵 **DONE** | complete — marking it re-evaluates everything downstream |
40+
41+
That single rule — **mark one node `DONE`, the cascade re-flows** — is the whole idea, and it
42+
is what the logo shows: one filled node releasing two hollow ones.
43+
44+
## Conditions
45+
46+
A task carries a free-text **condition** — a verifiable check (often a command), e.g.
47+
`pnpm --filter flowmcp test passes`. It records _how you know the task is truly done_, and can
48+
be confirmed later with the `report_condition` tool.
49+
50+
## Projects, comments, events, undo
51+
52+
- **Projects** partition the graph; a single daemon can hold many.
53+
- **Comments** attach discussion to any node.
54+
- **Events** are an append-only log of every change, with a `seq` cursor so clients can ask
55+
"what changed since?" (`poll_changes`).
56+
- **Undo** reverts the last change.

docs/development.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Development
2+
3+
## Repository layout
4+
5+
| Path | What |
6+
| --- | --- |
7+
| `flowcore/` | the Rust engine (native + wasm) over the `Sql` seam |
8+
| `flowd/` | the native Rust daemon |
9+
| `flowwasm/` | the wasm cdylib (flowcore for the browser / Node) |
10+
| `flowdjs/` | the Node daemon — flowcore-as-wasm over `node:sqlite` |
11+
| `flowmcp/` | the MCP server (TypeScript) |
12+
| `flowui/` | the web board (Svelte) |
13+
| `flowcli/` | the terminal UI (Go) |
14+
| `shared/flowapi/` | generated protobuf bindings (internal) |
15+
| `proto/` | the single proto + `buf` generation config |
16+
17+
`flowcore`, `flowd`, and `flowwasm` form a Cargo **workspace** (target/ at the repo root). The
18+
TypeScript packages are a **pnpm** workspace.
19+
20+
## Prerequisites
21+
22+
- **Node ≥ 22.5** and **pnpm** via `corepack`
23+
- **Rust** with the `wasm32-unknown-unknown` target (or **Docker**) to generate the wasm
24+
- **Go** (for `flowcli`)
25+
26+
## Common commands
27+
28+
```sh
29+
corepack pnpm install # install the TS workspace
30+
corepack pnpm gen:wasm # (re)generate the flowcore wasm glue
31+
32+
corepack pnpm --filter flowdjs dev # run the Node daemon (from source)
33+
corepack pnpm --filter flowdjs ui # daemon + open the web board
34+
corepack pnpm --filter flowui dev # the in-browser demo (no daemon)
35+
36+
cd flowcli && go build -o flowcli . && ./flowcli # the terminal UI
37+
```
38+
39+
## Tests
40+
41+
```sh
42+
corepack pnpm test:flowd # flowcore / native daemon (Rust)
43+
corepack pnpm --filter flowdjs test
44+
corepack pnpm --filter flowmcp test
45+
corepack pnpm test:flowcli # Go
46+
```
47+
48+
## CI
49+
50+
GitHub Actions builds and tests each language, including an **MCP integration** job that runs
51+
the real `flowd` binary end-to-end. A separate, manually-triggered workflow deploys the
52+
in-browser demo to GitHub Pages.
53+
54+
!!! note
55+
The wasm glue is generated, not committed. Run `corepack pnpm gen:wasm` after a clean
56+
checkout (CI does the equivalent natively).

docs/front-doors.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Front doors
2+
3+
One data model, reached four ways. The first three are the doors you use; the fourth is the
4+
process behind them.
5+
6+
## `flowui` — the web board
7+
8+
The browser view of the graph. It is a Svelte SPA **served by the daemon** same-origin, so
9+
there is no CORS, no certificate, and no separate server to run — opening the board is what
10+
starts (or connects to) the daemon. The daemon injects its bearer token into the page, so the
11+
board authenticates automatically.
12+
13+
The same UI also builds as a **standalone demo** that runs the engine entirely in the browser
14+
over OPFS — that is what is deployed to GitHub Pages, with no daemon and no agent.
15+
16+
## `flowcli` — the terminal UI
17+
18+
A Go TUI for people who live in the terminal. It connects to the same machine-local daemon
19+
(reading `~/.flowcontrol/session.json` for the address and token) and renders the same graph.
20+
21+
## `flowmcp` — the agent server
22+
23+
An MCP (Model Context Protocol) server your coding agent speaks to over stdio. It exposes the
24+
task graph as [tools](mcp-tools.md) — create projects and nodes, set status and dependencies,
25+
search, undo. It ensures the daemon on startup and connects to it.
26+
27+
## `flowd` — the daemon
28+
29+
The process the three doors share. It is the **single writer** to one SQLite file and serves
30+
the task-graph API (plus the web board) over gRPC-web/Connect on `127.0.0.1`. You rarely run
31+
it by hand — every client starts it on demand. See [Architecture](architecture.md) for how the
32+
daemon's lifecycle works and why the store, not the daemon, is the source of truth.
33+
34+
## How they share
35+
36+
All three clients speak the same transport (gRPC-web/Connect over HTTP/1.1) to the same
37+
loopback daemon, guarded by a bearer token. Because the store is a plain SQLite file, the
38+
daemon can come and go without losing anything.

docs/index.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# flowcontrol
2+
3+
**flowcontrol** is a **dependency-aware task graph** for humans and the agents working
4+
alongside them. Work packages hold tasks, tasks hold verifiable steps, and dependencies
5+
cross any level — mark one node **DONE** and the engine re-evaluates everything downstream.
6+
One data model, three front doors: a **web app**, a **terminal UI**, and an **MCP server**.
7+
8+
!!! note "Pre-release"
9+
The core is built and running. The npm packages, the published command surface, and
10+
these docs are being finalized — expect names and commands to still move.
11+
12+
## Why
13+
14+
- **One graph, shared live** — an agent adds tasks over MCP; you watch them appear on the
15+
board or in the terminal. Same store, same moment.
16+
- **The engine derives readiness** — you never set _READY_ or _BLOCKED_; they fall out of the
17+
dependency edges. Flip a blocker to _DONE_ and its dependents unblock automatically.
18+
- **Three front doors, one model** — the web board, the terminal UI, and the agent server all
19+
read and write the same task graph.
20+
- **Local & private by default** — a single daemon owns one SQLite file on your machine and
21+
serves everything over loopback with a bearer token. No cloud, no account.
22+
- **The daemon is not the store** — SQLite is. Any client starts the daemon on demand; if it
23+
dies, your data is untouched and the next client brings it back.
24+
25+
## At a glance
26+
27+
The hierarchy is fixed — **work package → task → step** — and dependencies may cross levels:
28+
29+
```
30+
WORK PACKAGE Release-UX development
31+
TASK Wire the board launcher [DONE]
32+
TASK Bundle the web build into the daemon [READY] ← unblocked when the task above went DONE
33+
STEP copy flowui/dist → flowd/dist/ui
34+
STEP default uiDir to the built path
35+
```
36+
37+
## Next
38+
39+
- [Concepts](concepts.md) — the data model and how the engine derives status.
40+
- [Installation](installation.md) — run it from source today; npm is coming.
41+
- [Front doors](front-doors.md) — the web board, terminal UI, and agent server.
42+
- [MCP tools](mcp-tools.md) — the tools your agent calls.
43+
- [Architecture](architecture.md) — one engine, native and in the browser.

docs/installation.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Installation
2+
3+
!!! note "Pre-release"
4+
flowcontrol is not on npm yet, so today you run it from the repository. The npm one-liners
5+
below are the intended surface once published.
6+
7+
## Run from source
8+
9+
Requires **Node ≥ 22.5**, **pnpm** (via `corepack`), and a Rust toolchain (or Docker) to
10+
generate the WebAssembly engine.
11+
12+
```sh
13+
git clone https://github.com/mbe24/flowcontrol
14+
cd flowcontrol
15+
16+
corepack pnpm install
17+
corepack pnpm gen:wasm # build the flowcore wasm
18+
corepack pnpm --filter flowui build # build the web board (daemon-connected)
19+
corepack pnpm --filter flowdjs ui # start the daemon + open the board in your browser
20+
```
21+
22+
The last command starts a machine-local daemon (writing `~/.flowcontrol/session.json` and a
23+
SQLite file) and opens the web board pointed at it.
24+
25+
## Wire up your agent (MCP)
26+
27+
Point any MCP client — Claude Code, Claude Desktop, Cursor, … — at the from-source server:
28+
29+
```json
30+
{
31+
"mcpServers": {
32+
"flowcontrol": {
33+
"command": "node",
34+
"args": ["--import", "tsx", "<path>/flowcontrol/flowmcp/src/index.ts"]
35+
}
36+
}
37+
}
38+
```
39+
40+
The MCP connects to the **same** machine-local daemon the board uses, so tasks your agent
41+
creates appear on the board immediately. Discovery and the bearer token are shared through
42+
`~/.flowcontrol/session.json` — nothing to copy.
43+
44+
!!! tip "One daemon per machine"
45+
State is per-machine (`~/.flowcontrol`); flowcontrol's own `project` entity partitions the
46+
graph. Whichever client you open first starts the daemon; the rest connect to it.
47+
48+
## Coming soon (npm)
49+
50+
Once published, each front door is a single command — no toolchain required:
51+
52+
```sh
53+
npm i -g @mbe24/flowmcp @mbe24/flowcli # the agent server + the terminal UI
54+
flowui # open the web board (starts the daemon)
55+
```
56+
57+
A `flowmcp install` command will write the MCP config into your agent host automatically.

docs/mcp-tools.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# MCP tools
2+
3+
`flowmcp` exposes the task graph to your agent as MCP tools. Start with `list_projects` to get
4+
a `project_id`, then `get_project` to load the tree; everything else edits it.
5+
6+
## Projects
7+
8+
| Tool | What it does |
9+
| --- | --- |
10+
| `list_projects` | List projects — id, name, description, archived. Start here. |
11+
| `create_project` | Create a project (the namespace all nodes live in). |
12+
| `get_project` | Load a project's node tree with status, dependency edges, and the `seq` cursor. |
13+
| `update_project` | Edit a project's name/description, or archive it. |
14+
15+
## Nodes
16+
17+
| Tool | What it does |
18+
| --- | --- |
19+
| `create_node` | Create a `WORK_PACKAGE`, `TASK`, or `STEP` (parent required for tasks and steps). |
20+
| `update_node` | Edit a node — title, description, condition, note, position, reference. |
21+
| `move_node` | Promote / demote / reparent / reorder a node. |
22+
| `delete_node` | Remove a node. |
23+
24+
## Status & dependencies
25+
26+
| Tool | What it does |
27+
| --- | --- |
28+
| `set_status` | Set the declared status: `OPEN`, `DEFERRED`, or `DONE`. `READY`/`BLOCKED` are derived. |
29+
| `set_dependency` | Add or remove a blocker → blocked edge (cycles rejected). |
30+
| `report_condition` | Verify a task's free-text condition (the "how you know it's done" check). |
31+
32+
## Collaboration & history
33+
34+
| Tool | What it does |
35+
| --- | --- |
36+
| `add_comment` | Attach a comment to a node. |
37+
| `list_events` | The append-only change log. |
38+
| `poll_changes` | What changed since a `seq` cursor — the basis for live updates. |
39+
| `search` | Full-text search across the graph. |
40+
| `undo` | Revert the last change. |
41+
42+
!!! tip "Decompose into steps"
43+
Work packages and tasks are the skeleton; the real execution lives in **steps**. After
44+
creating a task, break it into verifiable steps — that is what makes the graph actionable
45+
for both agents and humans.

docs/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mkdocs==1.6.1
2+
mkdocs-material==9.6.12

0 commit comments

Comments
 (0)