Project
Architecture
How the pieces fit together — the shared core, three interfaces, the daemon, and the invariants that keep them honest.
This page is the map. The authoritative, always-current version lives in
docs/ARCHITECTURE.md in
the repository; this is the version worth reading before you have cloned anything.
The shape
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Web UI │ │ Terminal UI │ │ CLI │
│ (kandown.html) │ (bin/tui) │ │ (bin/kandown)│
└───────┬──────┘ └───────┬──────┘ └───────┬──────┘
│ │ │
└────────┬────────┴────────┬────────┘
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ daemon │ │ shared │
│ module │─────│ core │
└───────────┘ └─────┬─────┘
│
┌─────▼─────┐
│ tasks/*.md│
└───────────┘
Three interfaces, one core, one storage layer that is the filesystem.
The shared core
The task parser, the dependency gate and the daemon module each exist exactly once. Every interface calls the same implementation.
This is the single most important structural decision in the project. It means:
- the web board and
kandown movecannot disagree about whether a move is legal, - a bug fixed in the gate is fixed in all three places,
- there is one place to read when you want to know how something behaves.
The daemon
A small per-project HTTP server. It serves kandown.html, exposes the task API, and outlives the
terminal UI so closing your shell does not close your browser tab.
It binds to 127.0.0.1, mints a per-project token at startup, and requires that token on every
route except a read-only identity check. See
Configuration § security.
Storage
tasks/*.md, and nothing else. No index, no cache, no manifest, no sidecar database.
Every read walks the folder. On a board of a few hundred tasks that is fast enough to be unnoticeable, and the property it buys — that the directory is the state, with no way for a cache to be wrong — is worth far more than the microseconds.
Invariants
The rules that must not be broken, restated from the repository:
- Task state lives in
tasks/*.mdand nowhere else. No second source of truth. - The gate, the parser and the daemon module exist once and are shared by all three interfaces.
- Generated files are never edited by hand.
bin/*.js,CODEMAP.md,src/lib/version.tsand the rootAGENT_KANDOWN.mdare build output; edit the source and regenerate. - UI text is authored in English. Every other locale is translated from English, never into it.
- Every source file carries a JSDoc header with
@fileand@description.CODEMAP.mdis generated from those headers and CI fails when one is missing.
Finding your way around the code
The repository generates its own map:
CODEMAP.md— every source file with a one-line summary, generated from the JSDoc headers. Read this before grepping.CODEMAP.json— the same data, plus symbols. Look a symbol up here instead of searching.graphify query "<question>"— asks what depends on what.
Next
Contributing covers the workflow: setting up, the build commands, and what CI checks before it will accept a change.