Ninja — 18 Operations for AI Agents
Ninja files are the generated build graph beneath CMake, GN, and Meson. act101 reads rules and build edges as structure, so agents debug build dependencies without untangling machine-written output by hand.
This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Ninja code through the act MCP server. 18 operations available: 0 refactor, 18 query, 0 analysis. Each operation is callable from Claude Code, Cursor, Codex, OpenCode, or any MCP-compatible agent host. Click any operation for a stable anchor link suitable for citation.
Worked Ninja examples
act101 reads a Ninja build manifest's four top-level constructs: a rule declaration surfaces as a function, a manifest-level variable binding (builddir = build) surfaces as a constant, a build edge surfaces as a block named for its explicit output rather than the rule it invokes, and the default directive surfaces as an annotation named for its own keyword. symbols covers only the rule and variable-binding pair of those four — it reports every let binding in the file, including the command = line nested inside each rule block, but has no rule for build edges or default at all. The unit of structure this grammar exposes to a build edge is its output path: act101 does not read the rule it invokes or the inputs it consumes as part of the edge's name. Each example below is the verbatim output of the command shown, run against the file shown. Query outputs are pretty-printed with the timing block omitted.
Read rules, edges, and the default target as a skeleton
build.ninja builds a documentation site: a sphinx rule renders HTML, a linkcheck rule checks links, and two build edges apply them to docs/index.rst.
$ act query skeleton build.ninja
Before
builddir = build
rule sphinx
command = sphinx-build -b html $in $out
rule linkcheck
command = sphinx-build -b linkcheck $in $out
build build/html/index.html: sphinx docs/index.rst
build build/linkcheck/output.txt: linkcheck docs/index.rst
default build/html/index.html
Output
{
"type": "Skeleton",
"declarations": [
{
"kind": "constant",
"name": "builddir",
"range": {
"start": {
"file": "build.ninja",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "build.ninja",
"line": 2,
"column": 1,
"byte_offset": 17
}
},
"name_range": {
"start": {
"file": "build.ninja",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "build.ninja",
"line": 1,
"column": 9,
"byte_offset": 8
}
}
},
{
"kind": "function",
"name": "sphinx",
"range": {
"start": {
"file": "build.ninja",
"line": 3,
"column": 1,
"byte_offset": 18
},
"end": {
"file": "build.ninja",
"line": 5,
"column": 1,
"byte_offset": 72
}
},
"name_range": {
"start": {
"file": "build.ninja",
"line": 3,
"column": 6,
"byte_offset": 23
},
"end": {
"file": "build.ninja",
"line": 3,
"column": 12,
"byte_offset": 29
}
}
},
{
"kind": "function",
"name": "linkcheck",
"range": {
"start": {
"file": "build.ninja",
"line": 6,
"column": 1,
"byte_offset": 73
},
"end": {
"file": "build.ninja",
"line": 8,
"column": 1,
"byte_offset": 135
}
},
"name_range": {
"start": {
"file": "build.ninja",
"line": 6,
"column": 6,
"byte_offset": 78
},
"end": {
"file": "build.ninja",
"line": 6,
"column": 15,
"byte_offset": 87
}
}
},
{
"kind": "block",
"name": "build/html/index.html",
"range": {
"start": {
"file": "build.ninja",
"line": 9,
"column": 1,
"byte_offset": 136
},
"end": {
"file": "build.ninja",
"line": 10,
"column": 1,
"byte_offset": 187
}
},
"name_range": {
"start": {
"file": "build.ninja",
"line": 9,
"column": 7,
"byte_offset": 142
},
"end": {
"file": "build.ninja",
"line": 9,
"column": 28,
"byte_offset": 163
}
}
},
{
"kind": "block",
"name": "build/linkcheck/output.txt",
"range": {
"start": {
"file": "build.ninja",
"line": 10,
"column": 1,
"byte_offset": 187
},
"end": {
"file": "build.ninja",
"line": 11,
"column": 1,
"byte_offset": 246
}
},
"name_range": {
"start": {
"file": "build.ninja",
"line": 10,
"column": 7,
"byte_offset": 193
},
"end": {
"file": "build.ninja",
"line": 10,
"column": 33,
"byte_offset": 219
}
}
},
{
"kind": "annotation",
"name": "default",
"range": {
"start": {
"file": "build.ninja",
"line": 12,
"column": 1,
"byte_offset": 247
},
"end": {
"file": "build.ninja",
"line": 13,
"column": 1,
"byte_offset": 277
}
},
"name_range": {
"start": {
"file": "build.ninja",
"line": 12,
"column": 1,
"byte_offset": 247
},
"end": {
"file": "build.ninja",
"line": 12,
"column": 8,
"byte_offset": 254
}
}
}
]
}
The skeleton reports builddir as a constant, sphinx and linkcheck as function rules, the two build edges as block declarations named build/html/index.html and build/linkcheck/output.txt, and default as an annotation.
List rule names and every variable binding as symbols
Each rule sets its own command binding: sphinx runs sphinx-build -b html, linkcheck runs sphinx-build -b linkcheck.
$ act query symbols build.ninja
Before
builddir = build
rule sphinx
command = sphinx-build -b html $in $out
rule linkcheck
command = sphinx-build -b linkcheck $in $out
build build/html/index.html: sphinx docs/index.rst
build build/linkcheck/output.txt: linkcheck docs/index.rst
default build/html/index.html
Output
{
"type": "Symbols",
"symbols": [
{
"name": "builddir",
"kind": "variable",
"range": {
"start": {
"file": "build.ninja",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "build.ninja",
"line": 1,
"column": 9,
"byte_offset": 8
}
},
"visibility": "unknown"
},
{
"name": "sphinx",
"kind": "function",
"range": {
"start": {
"file": "build.ninja",
"line": 3,
"column": 6,
"byte_offset": 23
},
"end": {
"file": "build.ninja",
"line": 3,
"column": 12,
"byte_offset": 29
}
},
"visibility": "unknown"
},
{
"name": "command",
"kind": "variable",
"range": {
"start": {
"file": "build.ninja",
"line": 4,
"column": 3,
"byte_offset": 32
},
"end": {
"file": "build.ninja",
"line": 4,
"column": 10,
"byte_offset": 39
}
},
"visibility": "unknown"
},
{
"name": "linkcheck",
"kind": "function",
"range": {
"start": {
"file": "build.ninja",
"line": 6,
"column": 6,
"byte_offset": 78
},
"end": {
"file": "build.ninja",
"line": 6,
"column": 15,
"byte_offset": 87
}
},
"visibility": "unknown"
},
{
"name": "command",
"kind": "variable",
"range": {
"start": {
"file": "build.ninja",
"line": 7,
"column": 3,
"byte_offset": 90
},
"end": {
"file": "build.ninja",
"line": 7,
"column": 10,
"byte_offset": 97
}
},
"visibility": "unknown"
}
]
}
symbols reports builddir as a variable, sphinx and linkcheck as function rules, and the command binding inside each rule as a variable — two separate entries both named command; the build edges and default don't appear.
Query
18 query tools, the same on every supported language. Descriptions live in the shared reference: /docs/query-tools.
callers control_flow data_flow definition diagnostics effect_closure effect_summary fix_auto get_type graph import_organize interface mutations references repo_outline skeleton symbols symbols_batch