Skip to main content
Version: Next

How it works

Understanding-oriented explanations of insight-flow's design — the mental model behind the commands and the dashboard. If the CLI and Agents tell you what the pieces do, this section explains why they fit together the way they do.

One idea: everything is a module

insight-flow is built on a single atom: everything is a module. A prompt section, an @include line, an MCP server, a Claude Code hook, a skill, a handover rule, a status transition, even a bundle of other modules — all of it is one shape, an entry in a registry, validated by one schema (AgentModuleSchema in packages/taskflow/src/core/schema/index.ts).

From that atom, three layers emerge:

Module ──▶ Agent ──▶ Flow
(atom) (an ordered (a lifecycle:
list of agents wired
modules, together by
composed into edges &
one role handovers,
prompt) with its own
statuses)
  • Modules are the smallest unit. Some are prompt text (section, include), some are installable artifacts (mcp-server, hook, skill), some are pure behavior-as-data (handover, status-transition), and one (bundle) is a molecule that groups other modules.
  • Agents are composed from an ordered list of module ids into a single role prompt — the *_ROLE.md files and slash commands you run. The composer (packages/taskflow/src/agents/compose.ts) walks the list, expands any bundles, and renders the text modules in order.
  • Flows wire agents into a lifecycle: a set of agents, the edges between them, the things they install, the statuses work moves through, and the entryAgents that can start work. The shipped default flow is the canonical task lifecycle.
  • A task is bound to exactly one flow. Task.flowId ("default" or "custom:<slug>") records which flow governs it, and the task moves through that flow's statuses as agents hand off to one another.

How a task binds to a flow

When a new task is created, insight-flow resolves its flow from the project's flows config: it looks up the task's type in flows.byType, falls back to flows.defaultFlow, and stamps the result onto Task.flowId. Legacy tasks with no flowId read back as "default" — zero behavior change. Once bound, the flow's status set and its handovers describe how that task should travel from ready to a terminal state.

The concept pages

  • Everything is a module — the module kinds, the three categories, locked modules, and why behavior is stored as data.
  • From modules to agents — composition, bundle expansion, and the drift guard that keeps *_ROLE.md in sync with the JSON.
  • Flows & the lifecycle — agents, edges, install, statuses, entry agents, and how Task.flowId binds.
  • The handover system — module-level vs flow-edge handovers, the canonical lifecycle chain, and auto vs gated.

See also