Skip to content

Logging

NimbleBrain writes a structured workspace event log as JSONL (one JSON object per line) to daily rolling log files. These logs capture workspace-level events — bundle lifecycle, skill and file changes, data and config mutations, tool-surface changes, and audit signals.

Control logging through the logging object in nimblebrain.json:

{
"logging": {
"dir": "~/.nimblebrain/logs",
"disabled": false,
"level": "normal",
"retentionDays": 30
}
}
FieldTypeDefaultDescription
dirstring{workDir}/logsDirectory where log files are written. Created automatically if it does not exist.
disabledbooleanfalseSet to true to disable structured logging entirely.
level"normal" | "debug""normal""debug" persists additional verbose fields (full tool inputs/outputs, raw provider responses). Larger files.
retentionDaysintegerAuto-delete log files older than N days on startup. Omit for no cleanup.

Structured logging is enabled by default. To disable it:

{
"logging": {
"disabled": true
}
}

Log files follow a daily rolling pattern under a workspace/ subdirectory of dir:

{dir}/workspace/YYYY-MM-DD.jsonl

A new file is created automatically each day. Examples:

~/.nimblebrain/logs/workspace/2026-03-25.jsonl
~/.nimblebrain/logs/workspace/2026-03-26.jsonl

Every log line is a JSON object: a timestamp, the event type, and the event’s own data fields spread alongside them.

{"ts":"2026-03-25T14:30:00.123Z","event":"bundle.installed","serverName":"postgres","bundleName":"@nimblebraininc/postgres","version":"1.2.0"}
FieldTypeDescription
tsstringISO 8601 timestamp of when the event was recorded.
eventstringEvent type (e.g., bundle.installed, data.changed, audit.permission_denied).

Remaining fields vary by event type — they are the event’s payload, written inline.

Only workspace-level events are written to this log; conversation streaming events (text.delta, tool.start, and the like) are not.

Bundle lifecyclebundle.installed, bundle.uninstalled, bundle.upgraded. Track connectors entering, leaving, and upgrading in the workspace.

{"ts":"2026-03-25T14:30:00.123Z","event":"bundle.installed","wsId":"ws_product","serverName":"postgres","bundleName":"@nimblebraininc/postgres","version":"1.2.0","trustScore":92}

data.changed — A tool mutated workspace data. Carries the server and tool that wrote, and source: "agent" when emitted from the agent’s tool dispatch.

{"ts":"2026-03-25T14:30:01.200Z","event":"data.changed","source":"agent","server":"tasks","tool":"create_task"}

config.changed — Workspace configuration was modified.

skill.created, skill.updated, skill.deleted — A workspace skill or context file changed. Carry the skill’s id (filesystem path), name, and scope.

{"ts":"2026-03-25T14:30:02.000Z","event":"skill.created","id":"/skills/triage/SKILL.md","name":"triage","scope":"workspace","type":"skill"}

file.created, file.deleted — A workspace file was added or removed. file.created carries id, filename, mimeType, and size.

{"ts":"2026-03-25T14:30:03.000Z","event":"file.created","id":"file_abc","filename":"report.pdf","mimeType":"application/pdf","size":20184}

tool.promoted, tool.released — A tool entered or left the active tool set. Carry the runId and toolName; tool.released adds reason: "evicted" when the engine reclaimed a slot under the active-tool cap.

{"ts":"2026-03-25T14:30:04.000Z","event":"tool.promoted","runId":"abc123","toolName":"postgres__query"}

bridge.tool.done — A bridged tool call completed.

http.error — An HTTP-level error surfaced in the workspace.

audit.auth_failure — Authentication failed for a request. Carries ip, method, and path.

{"ts":"2026-03-25T14:30:05.000Z","event":"audit.auth_failure","ip":"203.0.113.7","method":"POST","path":"/api/chat"}

audit.permission_denied — A user declined a tool’s confirmation prompt. Carries the tool, the unprefixed action, and the target (or null).

{"ts":"2026-03-25T14:30:06.000Z","event":"audit.permission_denied","tool":"tasks__delete","action":"delete","target":"task-42"}

Log files are plain JSONL, so you can use standard command-line tools:

Terminal window
# Bundles installed today
cat ~/.nimblebrain/logs/workspace/2026-03-25.jsonl \
| jq 'select(.event == "bundle.installed") | {bundleName, version}'
# Audit events only
cat ~/.nimblebrain/logs/workspace/2026-03-25.jsonl \
| jq 'select(.event | startswith("audit."))'
# Count events by type
cat ~/.nimblebrain/logs/workspace/2026-03-25.jsonl \
| jq -s 'group_by(.event) | map({event: .[0].event, count: length})'

A new file is created each day. Set retentionDays to have NimbleBrain delete log files older than that threshold on startup. Without it, files accumulate and you can manage retention with standard tools:

Terminal window
# Delete workspace logs older than 30 days
find ~/.nimblebrain/logs/workspace -name "*.jsonl" -mtime +30 -delete