Menu

Guides

View as Markdown

Dataflow devtool

Kovo's repo-internal devtool turns a Kovo graph into two surfaces: a visual dataflow app and an MCP tool named kovo_explain. Both render the same graph cards, so the page a developer reads and the artifact an agent consumes stay aligned.

The @kovojs/devtool package is private in the current technical preview. Treat the imports below as repository tooling examples, not public app dependencies.

Build or capture a graph first#

The devtool consumes graph JSON but does not require generated files to live under src/generated. Example apps keep graph assertions in tests:

sh
pnpm --filter @kovojs/example-commerce run build:demo
pnpm --filter @kovojs/example-crm test -- src/interactive-app.test.ts
pnpm --filter @kovojs/example-stackoverflow test -- src/interactive-app.test.ts

For a visual devtool host, pass the graph object or a build-produced graph file into buildBundle(). The CLI writes that file at dist/.kovo/graph.json; the discovery rules are in Check current source and inspect artifacts explicitly.

Mount it under a repo dev server#

Inside this repository, the Vite plugin can mount the devtool under an existing dev server path such as /__kovo:

ts
import { devtoolMountPlugin } from '@kovojs/devtool/vite';

export default {
  plugins: [devtoolMountPlugin('/__kovo', { handlerModuleId: '/src/app-shell.ts' })],
};

Set KOVO_DEVTOOL_BASE=/__kovo so emitted links match the mount path, then run the dev server for the host example you are testing. The exact package script is repo-local; it is not part of create-kovo.

sh
KOVO_DEVTOOL_BASE=/__kovo pnpm --filter @kovojs/example-devtool run dev

Build a bundle directly in repo tooling#

For repo tooling that owns the host, provide the graph JSON and source root:

ts
import { readFileSync } from 'node:fs';
import { buildBundle } from '@kovojs/devtool';
import { createDevtoolApp } from '@kovojs/devtool/app';

const bundle = buildBundle({
  app: 'my-app',
  label: 'My App',
  graph: JSON.parse(readFileSync('./dist/.kovo/graph.json', 'utf8')),
  srcRoot: './src',
});

export const { app, nodeHandler } = createDevtoolApp({ bundles: [bundle] });
export default app;

The package is data-free: the host provides app graph and source root; the devtool derives node cards, lanes, source previews, and edges from that input.

Query the same graph through MCP#

Run the MCP server over the same graph:

sh
kovo-devtool mcp --graph ./dist/.kovo/graph.json --src ./src --label "My App"

kovo_explain({ query, app?, limit? }) resolves exact node names when possible, then falls back to deterministic BM25-ranked cards. Results include stable kovo-explain/v1 text and structured content for agents.

Check that both surfaces match#

Use the repo check that exercises the devtool against real graphs rather than rerunning the MCP command above:

sh
pnpm run check

When a graph assertion fails, fix the app facts first: route, query, mutation, domain, or generated graph emission. The devtool should explain the graph you built, not patch around it.

Next#

Spec & diagnostics

The graph/explain artifact contract and stable kovo-explain/v1 text shape: SPEC §11.4. Machine- auditable generation and authorable outputs: SPEC §1.3, Constitution #3.

API reference: @kovojs/server.