agentcrumbs

Crumb format

JSONL schema and crumb types

Each crumb is a JSON object. When stored, they are written as JSONL (one JSON object per line).

Schema

{
  "app": "my-project",
  "ts": "2026-03-07T10:00:00.123Z",
  "ns": "auth-service",
  "msg": "user logged in",
  "data": { "userId": "123", "method": "oauth" },
  "dt": 2.5,
  "pid": 12345,
  "type": "crumb",
  "ctx": { "requestId": "abc-123" },
  "traceId": "a1b2c3",
  "depth": 0,
  "tags": ["auth", "login"],
  "sid": "f7g8h9"
}

Fields

FieldTypeRequiredDescription
appstringYesApp name (auto-detected from package.json or explicit config)
tsstringYesISO 8601 timestamp
nsstringYesNamespace
msgstringYesMessage
dataunknownNoStructured data
dtnumberYesDelta time in ms since last crumb from this trail
pidnumberYesProcess ID
typestringYesCrumb type (see below)
ctxobjectNoMerged context from child() and AsyncLocalStorage
traceIdstringNoTrace ID from scope()
depthnumberNoNesting depth from scope()
tagsstring[]NoTags for filtering (omitted when empty)
sidstringNoSession ID (omitted when not in a session)

Crumb types

TypeEmitted by
crumbcrumb()
scope:entercrumb.scope() start
scope:exitcrumb.scope() end
scope:errorcrumb.scope() error
snapshotcrumb.snapshot()
assertcrumb.assert()
timecrumb.timeEnd()
session:startcrumb.session()
session:endsession.end()

Storage

Crumbs are stored per-app at ~/.agentcrumbs/<app>/crumbs.jsonl. One JSON object per line, no trailing comma, no wrapping array. The app name is auto-detected from the nearest package.json by default.

On this page