scout_builder
The build_runner plugin for the Scout Application Capability Intelligence Platform.
Runs at compile time, reads your go_router routes, @ApiService endpoints, and
@Capability annotations, then produces a single scout.manifest.json — a machine-readable
capability graph that AI systems (Claude Code, Cursor, Windsurf) can query directly.
Zero runtime overhead. No reflection. No app execution required.
Quick start
1. Add dependencies
# pubspec.yaml
dependencies:
scout_annotations: ^0.1.0 # for @Capability annotation
dev_dependencies:
scout_builder: ^0.1.0
build_runner: ^2.4.0
2. Configure build.yaml
# build.yaml
targets:
$default:
builders:
scout_builder:
options:
app_name: "School Management System"
app_version: "3.14.1"
router_file: "lib/router.dart"
router_class: "AppRouter"
scan_path: "lib/**/*.dart"
3. Annotate a screen (optional — inference works without annotations)
import 'package:scout_annotations/scout_annotations.dart';
@Capability(
id: 'mark_attendance',
label: 'Mark Attendance',
category: 'academic',
description: 'Record attendance for a class session.',
permissions: ['attendance:write'],
preconditions: ['authenticated_user'],
)
class MarkAttendanceScreen extends StatelessWidget { ... }
4. Build
dart run build_runner build
Output: scout.manifest.json in your package root.
Three-tier discovery pipeline
scout_builder runs three analysis passes and merges them with precedence
Tier 2 > Tier 1 (Tier 3 is opt-in via scout scan --ai-tier):
Tier 1 — Auto-inference (zero friction, ~65–75% accuracy)
Requires no code changes. The builder:
- Parses your go_router configuration → extracts paths, access levels, params, guards
- Converts route/screen names to capability IDs (
markAttendancePage→mark_attendance) - Infers verb from name prefix or HTTP method (
mark,view,create, …) - Scores confidence based on name clarity and path structure
Tier 2 — @Capability annotations (100% accuracy)
Placing @Capability on a screen or service method is the ground truth. Tier 2 always
overrides Tier 1 for the same capability ID. The builder back-fills route_id from the
inferred match so the graph stays connected even when you only annotate some screens.
Tier 3 — AI-assisted (opt-in, ~80–85% accuracy)
scout scan --ai-tier sends low-confidence inferred capabilities to the Claude API for
label and description suggestions. Developer reviews interactively; approved suggestions
are written back as @Capability annotations.
Output format
scout.manifest.json is deterministic (sorted keys, stable-sorted lists) for clean git
diffs. A changed manifest in a PR is an immediately visible signal that capability
definitions changed.
{
"$schema": "https://scout-standard.dev/schema/v1/manifest.json",
"scout_version": "1.0",
"generated_at": "2026-06-21T10:00:00Z",
"app": {
"name": "School Management System",
"type": "flutter_mobile",
"version": "3.14.1"
},
"capabilities": [
{
"category": "academic",
"confidence": 1.0,
"description": "Record attendance for a class session.",
"discovery_tier": "annotated",
"id": "mark_attendance",
"label": "Mark Attendance",
"offline_capable": false,
"permissions": ["attendance:write"],
"preconditions": ["authenticated_user"],
"requires_auth": true,
"route_id": "mark_attendance_route",
"source_file": "lib/screens/mark_attendance_screen.dart"
}
],
"routes": [ ... ],
"workflows": [ ... ]
}
Token economics — why this matters for AI integration:
| Query type | Tokens | Reduction |
|---|---|---|
| Naive full codebase | ~47,000 | — |
| Full manifest | ~14,000 | 70% |
| Selective role query | ~1,500 | 97% |
| Single capability | ~305 | 99.4% |
build.yaml options reference
| Option | Default | Description |
|---|---|---|
app_name |
Flutter App |
App name written into the manifest |
app_version |
0.0.1 |
App version written into the manifest |
router_file |
lib/router.dart |
Path to the file containing your go_router config |
router_class |
AppRouter |
Class name holding GoRoute definitions |
scan_path |
lib/**/*.dart |
Glob for files to scan for @Capability annotations |
model_scan_path |
lib/**/*.dart |
Glob for files to scan for route extra-type models |
default_access |
authenticated |
Default access level for routes with no rule match |
access_levels |
{} |
Map of list-field-name → access label (passed to scout_router) |
path_prefix_rules |
{} |
Map of path prefix → access label |
Committing the manifest
Commit scout.manifest.json to your repository. Install the pre-commit hook with
scout init to keep it automatically up to date:
# .git/hooks/pre-commit (installed by `scout init`)
if git diff --cached --name-only | grep -q '\.dart$'; then
dart run build_runner build --delete-conflicting-outputs --quiet
git add scout.manifest.json
fi
Part of Scout
scout_annotations ← @Capability, @Workflow, @Permission annotations
↓
scout_builder ← this package
↓
scout_cli ← `scout validate`, `scout graph`, `scout diff`
scout_mcp ← MCP server for Claude Code / Cursor / Windsurf
See github.com/wirecept/scout for the full platform.
License
MIT
Libraries
- scout_builder
- Scout build_runner plugin.