Task runnerGuidesRun Summaries

Run Summaries

Generate detailed JSON reports for debugging cache behavior

Run Summaries

Run summaries generate a detailed JSON report after execution, capturing task inputs, hashes, timings, cache status, and environment info. Useful for debugging cache misses and comparing runs.

Enable

const results = await defaultTaskRunner(
    tasks,
    {
        summarize: true,
    },
    context,
);

Output

Summary files are written to .task-runner/runs/{run-id}.json:

{
    "id": "2026-03-21T18-00-00-000Z_abc123",
    "startTime": "2026-03-21T18:00:00.000Z",
    "endTime": "2026-03-21T18:00:05.000Z",
    "duration": 5000,
    "tasks": [
        {
            "taskId": "app:build",
            "target": { "project": "app", "target": "build" },
            "hash": "a1b2c3d4...",
            "hashDetails": {
                "command": "...",
                "nodes": { "src/index.ts": "..." },
                "runtime": { "env:NODE_ENV": "..." }
            },
            "cacheStatus": "MISS",
            "exitCode": 0,
            "duration": 3000,
            "dependencies": ["lib:build"],
            "cacheable": true
        }
    ],
    "taskGraph": {
        "dependencies": {
            "app:build": ["lib:build"],
            "lib:build": []
        },
        "roots": ["lib:build"]
    },
    "stats": {
        "total": 5,
        "succeeded": 3,
        "failed": 0,
        "cached": 2,
        "skipped": 0
    },
    "environment": {
        "nodeVersion": "v22.0.0",
        "platform": "linux",
        "arch": "x64"
    }
}

Cache Status Values

  • HIT - Local cache hit
  • REMOTE_HIT - Remote cache hit
  • MISS - No cache, task executed
  • SKIPPED - Dry-run mode

Standalone Usage

import { generateRunSummary, writeRunSummary } from "@visulima/task-runner";

const summary = generateRunSummary(results, taskGraph, startTime);
const filePath = await writeRunSummary(summary, workspaceRoot);

Last-run replay (last-summary.json)

The orchestrator writes a .task-runner/last-summary.json after every completed run regardless of whether summarize is enabled. It's a single overwritten file — always the most-recent run — designed for CLIs that want to show "last run details" without re-executing.

import { readLastRunSummary } from "@visulima/task-runner";

const previous = await readLastRunSummary(workspaceRoot);

if (previous) {
    console.log(`Last run: ${previous.stats.succeeded} succeeded, ${previous.stats.failed} failed`);
}

readLastRunSummary returns undefined when no previous run exists or the file can't be parsed. Treat it as an informational lookup, not a hard dependency.

Interrupted runs (Ctrl-C) are not persisted — the incomplete snapshot would mislead callers.

Chrome Tracing Profile

For visual timeline analysis, convert a summary to Chrome Tracing JSON:

import { writeChromeTrace } from "@visulima/task-runner";

await writeChromeTrace(summary, "trace.json");

Open the file in chrome://tracing or Perfetto to see a gantt of task execution with dependency arrows. Parallel tasks are packed into separate lanes automatically — useful for spotting over-serialized dependsOn chains.

Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues