dart_minify 0.2.1
dart_minify: ^0.2.1 copied to clipboard
Semantic context packing and structured edit application for Dart agents.
dart_minify #
dart_minify is a local, provider-agnostic codec for Dart and Flutter coding
agents. It builds a semantic project index, packs only task-relevant context,
accepts declaration-level edit operations, applies them atomically, and returns
compact verification diagnostics.
It optimizes both directions of an agent exchange:
index -> pack -> agent edits -> apply -> verify -> repair pack
Source files remain ordinary Dart. dart_minify is not an obfuscator, does not
call a model, and does not require a provider SDK.
Requirements #
- Dart SDK 3.9 or later
- A Dart or Flutter-shaped project for indexing
- Project tools such as Flutter or custom test commands only when selected by verification
The package itself is developed and tested with the Dart SDK; a Flutter SDK is needed only when a selected target-project verification command invokes it.
Install #
dart pub global activate dart_minify
dart-minify --help
From a checkout:
dart pub get
dart run bin/dart_minify.dart --help
Quickstart #
Start by checking the target project and building its local index:
dart-minify doctor --project-root /path/to/project
dart-minify index --project-root /path/to/project
Create a task-focused pack. Use --format compact for an agent exchange or
--format json while inspecting an integration:
dart-minify pack \
--project-root /path/to/project \
--file lib/src/session.dart \
--max-tokens 12000 \
--format compact > /tmp/session.pack.dmp
Ask the agent to return protocol edit operations rather than rewritten files. Preflight the response before writing anything:
dart-minify apply \
--project-root /path/to/project \
--stdin \
--dry-run < /tmp/session.edits.dmp
Apply the same validated response without --dry-run, then verify the affected
closure:
dart-minify apply --project-root /path/to/project --stdin \
< /tmp/session.edits.dmp
dart-minify verify --project-root /path/to/project
apply parses planned Dart sources and resolves the transitive affected closure
by default, rejecting newly introduced analyzer errors before the atomic
commit. Use --no-analyze to skip closure analysis; unrelated pre-existing
errors do not block the edit.
The exact focus, budget, and verification options are listed by each command's
--help output.
Savings (balanced-v1) #
The medium-commerce fixture, measured as a complete agent exchange with
protocol overhead included. Estimated model tokens use the balanced-v1
heuristic, not a provider tokenizer.
| Exchange | Before → after (est. tokens) | Savings |
|---|---|---|
| Focused pack | 8,955 → 2,742 | 69.38% |
| Structured edit | 2,212 → 324 | 85.35% |
| Follow-up delta | 2,742 → 461 | 83.19% |
Reproduce from a source checkout (benchmark/ is not in the pub archive):
dart run benchmark/medium_scenario.dart \
> /tmp/medium-commerce-v2.json
cmp /tmp/medium-commerce-v2.json \
benchmark/results/medium-commerce-v2.json
On your own project, stats reports the focused-pack analog. It will not
match 69.38% unless your tree is that fixture, and even on the fixture the
wire differs because the scenario rewrites projectRoot to a stable
benchmark path.
dart-minify stats --project-root /path/to/project \
--symbol CheckoutService.quote --format json
Read packSavings.estimatedModelTokens. Existing byteSavings is still
compact-source versus raw source, not pack savings.
Try it with your coding CLI #
If Claude Code, Codex, OpenCode, or Cursor Agent is already installed and authenticated, run the same checkout edit twice: once with the Dart sources dumped into the prompt, once with a focused pack.
dart run benchmark/cli_liveday.dart
The runner records balanced-v1 context tokens, vendor usage when the CLI
prints it, wall time, captured output, and whether CheckoutService.quote
set reservationsAvailable to true. Missing CLIs are skipped. The runner
does not install, upgrade, or change those CLIs. CI does not call a model.
One continuous macOS arm64 run of that command is in
benchmark/results/cli-liveday/sample.json. Injected context was 9,134 →
2,788 balanced-v1 tokens (69.48% smaller). Vendor billed tokens include
tools and cache, so they do not match the dump.
[Pack vs raw dump on four coding CLIs]
Each pack bar is that CLI as a percent of its own raw dump. Gray is always 100%. Lower is leaner or faster. Bars above 125% are clipped; the label still shows the true percent.
| vs raw dump | billed input | billed output | time | edit |
|---|---|---|---|---|
| Claude Code | -14% | -6% | -13% | pass |
| Codex | -47% | -9% | -31% | pass |
| OpenCode | -18% | +1% | -44% | pass |
| Cursor Agent | +38% | +26% | +30% | pass |
Claude Code, Codex, and OpenCode used the pack and billed less input. Cursor Agent applied the edit but billed more on the pack arm.
Redraw the figure after a new run:
dart run benchmark/cli_liveday_chart.dart
See Run the liveday benchmark.
Commands #
| Command | Purpose |
|---|---|
index |
Build or refresh the content-addressed semantic project index. |
pack |
Select task context and emit a compact or JSON pack within a hard budget. |
apply |
Validate anchors and hashes, analyze the affected closure by default, then commit atomically. |
verify |
Parse, format-check, analyze, test, and emit normalized diagnostics. |
stats |
Report bytes, lexical tokens, estimated model tokens, and protocol overhead. |
doctor |
Check SDK, analyzer, project-root, configuration, and cache readiness. |
Machine-readable output is written to stdout. Progress and logs are written to stderr, so packs and edit results can be piped safely.
Safety model #
- The Dart analyzer, rather than a handwritten scanner, drives source tokenization and parsing.
- Packs identify files and declarations with stable IDs, content hashes, and structural fingerprints.
- Edit resolution never falls back to line-number guessing.
- Missing, extra, stale, and deleted files are explicit protocol states.
- Every edit and affected path is validated before the first source write.
apply --dry-runperforms preflight without committing source changes.applyresolves planned sources and their indexed dependents in an in-memory overlay before committing;--no-analyzeskips this step.- A stale or ambiguous edit is a conflict and requires a fresh pack.
Local indexes and session state live under .dart_minify/. Recoverable
transaction journals use root-level .dart_minify.transaction.* files, while
transaction-owned temporary and backup files are created beside their target
files so replacement stays on the same filesystem. These local artifacts are
ignored by Git and are not part of an agent pack unless selected data is
explicitly encoded.
Protocol formats #
compact is a counted, checksummed, line-oriented envelope designed for model
traffic. json is the canonical debugging and storage representation. Both
decode to the same validated protocol models and support the same operations.
See Protocol v2 for document fields, edit operations, anchors, validation rules, and framing.
Agent integrations #
Adapters should stay thin: run the local commands, transmit the pack, require a
protocol edit response, and pass that response back to apply. They should not
translate the wire format into provider-specific edit semantics or write files
on the model's behalf.
See Agent integration for a provider-neutral adapter contract and prompt preamble.
Upgrading from 0.1.x #
Version 0.2.0 removes minify, expand, lossy-build, apply-lossy, the
build-runner builder, framed whole-file payloads, and .llm.* sidecars. There
is no compatibility decoder for 0.1 maps or manifests.
Follow the 0.1.x to 0.2.0 migration guide before upgrading automated workflows.
Development #
dart format --output=none --set-exit-if-changed .
dart analyze
dart test
dart pub publish --dry-run
CI covers the minimum Dart SDK and latest stable Dart. Flutter target-project integration remains a separate fixture lane because this package itself is a pure Dart package.
Documentation #
- Protocol v2
- Agent integration
- Migration from 0.1.x
- Benchmark methodology
Limits #
- The core performs no network calls and chooses no model provider.
- Generated files remain owned by their generator unless an operation explicitly creates or deletes a file.
- Automatic semantic repair is out of scope; repair packs provide focused context for another explicit agent response.
- Compression statistics are estimates, not provider billing counts.