Agent Deck Insights
Agent Deck Insights explains the numbers Agent Deck records about your coding-agent sessions. When you click, it sends Agent Deck's session statistics and one fixed prompt to the agent CLI you already have installed (Claude Code or Codex). Agent Deck then shows the findings in its own Insights view: what to change first, then the detail, why it happened, and the numbers each finding rests on, with whether it is new since the last run, and which kinds are no longer reported. Each finding cites the exact numbers it rests on, and a finding whose numbers do not match the statistics that were sent is discarded.
Insights is an add-on to Agent Deck (nvitlam.agent-deck), which records the statistics. Agent Deck is free and works without Insights. Insights is free to install, and sending a run needs a licence key. With a valid licence, Insights registers with Agent Deck and Agent Deck shows its findings. Without one, Insights registers nothing and Agent Deck shows its own free view.
How a run works
Every run starts with a click on Agent Deck Insights: Run Insights. Nothing runs on its own, and Agent Deck has no Run button for Insights: Send is in the preview. The steps always happen in this order, and each one stops the run with a named reason if it cannot proceed:
- Discovery. Insights finds your agent CLI: the path in
agentDeckInsights.agent, or else the one supported CLI on PATH. It runs <cli> --version, because a binary that is only present on PATH might not start.
- Probe. The first time Insights sees a given path and version, it sends a fixed probe prompt and checks for an exact JSON reply. The result is kept, so the probe does not run again for that path and version. No insights run is sent to a CLI without a passing probe.
- Window. Insights reads Agent Deck's stored statistics for the last 7 days through Agent Deck's API. Only sessions Agent Deck read in full are used, and the newest are kept up to the cap (8 by default). At least 3 are needed.
- Licence. Your key is verified offline against the public key built into the extension.
- Preview. A panel shows the exact bytes that will be written to the CLI's stdin: the statistics and the prompt. Send and Cancel are the only choices. Without a valid licence no Insights command reaches this step: each is refused before it, and nothing is previewed. A key that expires after Run Insights was clicked and before this step still opens the preview, with the refusal stated and no Send button.
- Spawn. After Send, the CLI runs in a new, empty temporary directory, which is deleted afterwards. If another process still holds it after about a second of retries (on Windows, a process the CLI left running there), it is left in place and the run is refused as "temp folder not removed". It runs with tool use forbidden (see the table below). A notification with a Cancel button stays open until the result arrives, and Cancel stops the CLI and every process it started.
- Validate. The reply must match the output schema. Every citation must name a path in the statistics that were sent, with the same value. A finding that fails is dropped and counted. The whole reply is refused if a finding's suggested change opens with a sentence longer than 15 words, if a number in a finding's text is not in the statistics that were sent (money, ratios and rates may be rounded to two decimals: a cost, cost per hour, cache ratio, context fill, or tokens or calls per minute), or if a finding's text names a file path, tool name or project from the statistics that the finding does not cite. Names are matched by exact spelling: a file path or project wherever it appears, a tool name only when written as a tool (in backticks, or followed by the word "tool").
- Store and show. The finding set is saved to the extension's own storage, and Agent Deck lists it in the run history of its Insights view; selecting a run shows its findings. A run refused after Send (at the spawn or the validation), or refused by the pipeline itself before the preview (discovery, the probe, the statistics window), is reported in a notification that names the step and the reason, and is stored too: Agent Deck lists it in the history, and for a run refused after the statistics were read, shows the step and reason and can open its raw output. Closing or cancelling the preview before Send is not a run: nothing is stored or listed, and the "Agent Deck Insights" output channel says "preview cancelled". With storing turned off, runs are still listed and shown until the window closes.
Investigate Report
When Agent Deck shows a run's findings, its Investigate Report button hands that run to Insights. Insights builds one prompt from the whole stored report: every finding's suggested change, its detail, its cause, and each evidence row with the id of the session it came from. The prompt ends with this line:
Read-only investigation: you cannot edit files. Explain what you find and propose changes for me to make.
A preview opens beside Agent Deck's panel. It shows the prompt in full and states exactly what Start starts: the mode, the agent CLI and its path, your workspace folder, the read-only flags and the arguments. Cancel, or closing the preview, starts nothing, stores nothing and shows no message; the "Agent Deck Insights" output channel notes it. The investigation needs exactly one workspace folder open, on this machine. Its agent is the one a run uses (agentDeckInsights.agent, or the one supported CLI on PATH).
agentDeckInsights.investigate.mode decides how Start starts it (default advanced):
- simple: the CLI runs headless in your workspace, with the prompt on stdin. Its reply is shown in a panel beside Agent Deck, with the raw output, and stored with the run in the insights history. The token counts are shown as for a run, and for Claude Code the cost it reports. A refusal (a non-zero exit, a timeout, an error reported by the CLI, an output Insights cannot read) is shown there by name, with the raw output, and stored the same way.
- advanced: an integrated terminal opens in your workspace and runs the CLI with the prompt as its initial argument. You carry on in that terminal.
- expert: the terminal opens with the CLI started, and the prompt is placed on the clipboard. Insights types nothing into the terminal; one message says "Prompt copied — paste it with Ctrl+V when the CLI prompt shows".
agentDeckInsights.investigate.bringToFront (default on) decides only whether that terminal is brought to the front. The terminal is opened either way.
Every mode starts the CLI read-only:
| CLI |
Read-only flags, in every mode |
Simple mode, in full |
claude |
--tools "Read,Grep,Glob" --strict-mcp-config --disallowedTools "Edit,Write,MultiEdit,NotebookEdit,Bash": only the three read tools exist, and no MCP server is loaded |
-p --output-format json --max-turns 20 with those flags |
codex |
-s read-only -a never: the read-only sandbox, and no request to approve anything outside it |
-a never exec --json -s read-only --skip-git-repo-check |
The investigation is an ordinary session of your CLI in your workspace, so Agent Deck shows it among that workspace's sessions, like any other session you start there.
What it never does
From the specification, verbatim:
What is never done: reading transcripts, reading files, network calls from the extension, writing under any engine's data directory.
In practice:
- It never reads a transcript or a file of your project. The files it reads are its own: its probe records and its insights history, both in the extension's global storage. Investigate Report (above) lets your agent CLI read your project, read-only, when you press Start; Insights itself still reads none of it.
- The extension itself makes no network call, for licensing or for anything else. Your agent CLI connects to its provider on your account, as it always does.
- It never writes under
~/.claude, ~/.codex or any other agent engine's data directory. It writes to its own global storage and to temporary directories it creates and deletes.
- An insights run never runs the CLI inside your repository: its working directory is a new, empty temporary directory. Investigate Report is the one exception: on your Start, it runs your CLI read-only in your workspace.
- It never runs without your click. Nothing is sent to your agent CLI that you have not seen, except the fixed probe prompt, which is printed in full under "The prompt" below.
- It never writes a setting other than its own
agentDeckInsights.* settings.
SECURITY.md, shipped inside the extension package, states what the tests behind each of these claims prove, and names each test. The tests live in the private source repository.
Supported agent CLIs
The versions below have a fixture in the extension: the exact arguments, the stdin, and captured output that the tests replay.
| CLI |
Fixture version |
Other versions |
Arguments (prompt on stdin) |
Tool use |
claude |
2.1.270 |
supported when the capability probe passes |
-p --output-format json --tools "" --strict-mcp-config --max-turns 1 |
forbidden by flag: --tools "" --strict-mcp-config |
codex |
0.154.0 |
refused: "unsupported version" |
exec --json -s read-only --skip-git-repo-check |
by observation: -s read-only, and a stream reporting a tool call or an unknown event is refused |
Claude Code versions without a fixture are accepted when the capability probe passes. The one live in-product run recorded so far used Claude Code 2.1.272. Codex is accepted only at a version whose event types are pinned by a fixture, because Codex has no flag that forbids tool use. Insights therefore checks every event Codex reports, and refuses the run if one reports a tool call or has a type it does not recognise.
Requirements
- VS Code 1.134 or later.
- Agent Deck (
nvitlam.agent-deck) 0.9.0 or later, installed and enabled: Insights needs its API version 2. It is declared as a dependency, so VS Code installs it with Insights. Agent Deck's stored statistics must be on, and hold at least 3 fully read sessions from the last 7 days.
- Claude Code (
claude) or Codex (codex), installed and signed in.
- A licence key.
Getting a licence
Licences are sold at https://agent-deck.app/insights.html. Polar is the merchant of record, and prices are in US dollars. Every plan is the same product, for 1, 6 or 12 months, paid once or as a subscription that renews. The licence tier is solo: one key per person.
The key is sent to the email address you use at checkout. A key is valid until the expiry date written into it. The extension checks the key without a network call, against your computer's clock.
Where to enter the key
- Open the Command Palette (
Ctrl+Shift+P, or Cmd+Shift+P on macOS) and run Agent Deck Insights: Set License Key.
- Paste the whole key into the box, which masks what you type. The key is one line: two base64url parts joined by a dot.
The key is checked before it is stored. A key that is malformed, signed by another key or expired is refused with the reason, and nothing is stored. A valid key is kept in VS Code's secret storage, never in your settings, and Agent Deck shows Insights at once. Agent Deck Insights: Remove License Key deletes it.
A key pasted into the old agentDeckInsights.licenseKey setting by an earlier build is moved into secret storage the next time VS Code starts, and the setting is cleared.
Without a valid key, every command but those two is refused with a message naming it, and does nothing.
How to pick an agent
If exactly one supported CLI on PATH runs, Insights uses it, and you do not need to pick. Otherwise, run Agent Deck Insights: Pick Agent. It lists every claude and codex found on PATH, runs each one, and shows its version and probe status. The path you choose is written to agentDeckInsights.agent in your user settings. You can also type an absolute path into that setting yourself.
Commands
- Agent Deck Insights: Run Insights (
agentDeckInsights.run)
- Agent Deck Insights: Pick Agent (
agentDeckInsights.pickAgent)
- Agent Deck Insights: Clear Insights History (
agentDeckInsights.clearHistory)
- Agent Deck Insights: Show Payload (
agentDeckInsights.showPayload)
- Agent Deck Insights: Set License Key (
agentDeckInsights.setLicenseKey)
- Agent Deck Insights: Remove License Key (
agentDeckInsights.removeLicenseKey)
Show Payload opens the same preview as Run Insights, with Send: it is the same run, from discovery to the stored result. Closing or cancelling the preview before Send is not a run, and leaves nothing in the history. The preview opens beside Agent Deck's panel, so that panel stays in view. Clear Insights History asks for confirmation in a modal dialog before it removes anything.
While your licence is valid, Agent Deck's Insights view lists your runs and shows the one you select, and offers Pick Agent, Show Payload and Clear History under Open Insights. Each does exactly what the command of the same name does, Clear History's confirmation included, and each checks the licence again when pressed: if it no longer verifies, the action says so, does nothing else, and Insights leaves Agent Deck. Without a valid licence Agent Deck shows none of them.
Without a valid licence key, every command but Set License Key and Remove License Key is refused with a message naming it, and does nothing: nothing is spawned, no preview opens, and the history is not read.
Settings
| Setting |
Default |
What it holds |
agentDeckInsights.agent |
"" |
Resolved absolute path of the agent CLI (claude or codex) that insights runs spawn. Empty: the one runnable supported CLI on PATH. |
agentDeckInsights.store.enabled |
true |
When true, each finding set is appended to the insights history under the extension's globalStorage. |
agentDeckInsights.window.days |
7 |
Days of Agent Deck stored stats in the insights window. |
agentDeckInsights.window.minSessions |
3 |
Full-coverage sessions the window needs before a payload is built. |
agentDeckInsights.window.maxSessions |
8 |
At most this many full-coverage sessions, the newest, are sent in a payload. |
agentDeckInsights.investigate.mode |
"advanced" |
How Investigate Report starts the agent CLI; every mode is read-only. simple: headless in the workspace, its reply shown in a panel and stored with the report. advanced: an integrated terminal in the workspace runs the CLI with the prompt as its initial argument. expert: an integrated terminal runs the CLI, and the prompt is placed on the clipboard; nothing is typed into the terminal. |
agentDeckInsights.investigate.bringToFront |
true |
Tweaks: when true, the Investigate Report terminal is brought to the front. The terminal exists either way. |
Honest limits
- The prompt is not secret. It is printed in full below, and every run shows it in the preview. What you buy is the engine, the prompt pack as maintained, and your local history.
- Finding quality depends on your model and your plan. Validation proves that every cited number was in the statistics that were sent, with that exact value. It does not prove that a finding is correct, useful or well written.
- Every run costs tokens on your own account, and Agent Deck shows the counts the CLI reports after each run. Recorded figures:
- One in-product run with Claude Code 2.1.272, before the session cap existed: 17 sessions and 319,428 bytes on stdin, 184,875 prompt tokens and 6,467 output tokens, "cost $2.142399 estimated by Claude Code".
- One captured Claude Code run on the 4-session test payload (14,753 bytes on stdin): 8,700 prompt tokens and 2,484 output tokens, with a reported cost of $0.154626.
- Cost grows with the number and size of the sessions sent.
- The session cap. At most
agentDeckInsights.window.maxSessions sessions are sent (default 8): the newest fully read sessions in the window. Older sessions beyond the cap are counted in the preview and not sent. Sessions Agent Deck could not read in full are counted and never sent. With fewer than agentDeckInsights.window.minSessions (default 3) sessions, no payload is built.
- Codex reports no cost. Codex reports token counts only, so no cost is recorded for Codex runs.
- What Agent Deck shows is checked twice. Agent Deck refuses text it cannot show safely: over 2,000 characters, or carrying control or invisible characters. Insights applies the same rules first and drops such a finding, counted with the rejected ones.
- "Since last run" is by kind. A finding is "new" or "still" depending on whether the previous set had a finding of the same kind. Kinds the previous set had and this one lacks are listed as no longer reported. A refused run lists none, because it did not look.
- A run refused early has no report. A run refused before the statistics were read (at the probe, for example) has no window to state. Agent Deck lists it in the history, but selecting it shows no report, and its raw output cannot be opened from Agent Deck. The notification names the refusal.
- The number check is coarse. Small numbers occur in almost every set of statistics, so the check mostly catches invented large or precise figures. It does not prove that a number belongs to the fact a sentence is about.
- A CLI update can break a run. A Claude Code version whose probe fails is unsupported. A Codex version without a fixture is refused as "unsupported version" until an update of Insights adds one. Insights refuses what it cannot check, rather than guessing.
- Codex tool use is checked by observation, not forbidden. Codex offers no flag that forbids tools. Insights sets its strictest sandbox (
-s read-only), and refuses any run whose event stream reports a tool call or an event type outside the pinned set. The refused run has already used tokens, and its output is not used.
- Your CLI's own configuration applies. Hooks and other settings in your Claude Code or Codex configuration run as they normally would. The CLI writes its own session files wherever it always writes them. Runs happen in a temporary directory, so Agent Deck does not show them as sessions of your workspace.
- Timeouts. The probe has 60 seconds and a run has 300 seconds. If the reply is not JSON, the run is retried once, which costs a second run. There is no retry after a timeout, a non-zero exit or any other refusal.
- The licence check uses your computer's clock. Moving the clock back is not detected.
- Remote and WSL windows. Discovery runs whatever the extension host resolves on
PATH. In a WSL or remote window, the non-interactive PATH may not include directories your shell profile adds. Setting an absolute path in agentDeckInsights.agent avoids that lookup.
- Investigate Report reads your project, through your CLI. The extension reads none of your files. The CLI it starts does, in your workspace: Claude Code with its three read tools, Codex with the commands its read-only sandbox allows. Codex enforces that sandbox itself; Insights only sets it. In simple mode, a Codex event stream with an event or item type outside the pinned set is still refused, as for a run. Read commands are expected there, so they do not refuse it.
- Investigation cost. In simple mode the CLI's own figures are shown and stored: token counts, and for Claude Code its cost. In advanced and expert mode the CLI runs in a terminal whose output Insights does not read, so Insights cannot show what the investigation cost.
- Unmeasured numbers. Simple mode's timeout (600 seconds) is provisional; it is set from the first timed investigation. Its turn cap for Claude Code (20) is measured: the first investigation took 5 turns.
- Parsed, not measured. Codex's
-a never goes before exec, the one place codex exec accepts it. That this position applies it to exec has been checked against codex --help only, not observed in a run.
- Advanced mode's prompt goes on a command line. Windows allows 32,767 characters in one. A longer prompt is refused, as "prompt too long for a command line", before anything starts; simple and expert mode have no such limit.
- Another extension may type into the terminal before you paste (for example a Python environment activation line).
The prompt
The exact text sent after the statistics, rendered from the constant the extension uses (prompt version 3):
You are reviewing Layer 1 statistics recorded by Agent Deck, a VS Code extension that measures AI coding-agent sessions. The JSON document above this text is your complete input. Its `sessions` array holds one record per session, every one with full coverage.
Your task: find patterns in these numbers that explain wasted tokens, time or effort, state the likely cause, and state what the user could change. Every finding must cite the exact numbers it rests on.
## Hard rules
1. Use only the numbers and identifiers in the JSON above. Do not estimate, extrapolate, or invent a value, a session, an agent, a file, a tool or a skill.
2. Do not read files, run commands, search, browse, or use any tool. Everything you may use is above.
3. Reply with one JSON object that matches the output schema below, and nothing else: no prose, no code fences, no explanation before or after it.
4. If the numbers support no finding, reply with an empty `findings` array.
5. Every number you write in `cause` or `action` must appear in the JSON above, written as it is written there or rounded as the rounding line below allows. A reply that breaks this rule is refused whole.
## Input envelope
- `promptVersion`: the version of this template.
- `statsSchemaVersion`: the version of the session record format.
- `window`: the time window the sessions were selected from.
- `window.sinceMs`: start of the window, Unix epoch milliseconds.
- `window.sessions`: how many sessions are included in `sessions`.
- `window.excluded`: how many sessions in the window were left out because they could not be read in full. Their data is not included.
- `sessions`: the session records, defined below.
## Session record (one element of `sessions`)
The fact ids F1 to F15 name the facts Agent Deck derives. Counts are integers; token figures count model tokens; durations are milliseconds. A field that is absent means the engine did not state it: never read an absence as zero.
- `statsSchemaVersion`: the record format version.
- `sessionId`: the session's identifier as the agent engine wrote it.
- `engine`: which agent engine produced the session: `cc` (Claude Code), `codex` or `opencode`.
- `projectSlug`: the engine's identifier for the project directory.
- `startedAt`: when the session started, Unix epoch milliseconds.
- `endedAt`: when the session ended, Unix epoch milliseconds, where stated.
- `coverage` (F11): `full` when every event of the session was attributed. Only `full` sessions are sent.
- `agents`: one entry per agent in the session: the main agent and each subagent it spawned.
- `agents[].agentId`: the agent's identifier; `root` is the main agent.
- `agents[].kind`: `main` or `subagent`.
- `agents[].spawnDepth`: 0 for the main agent, 1 for an agent it spawned, and so on.
- `agents[].prompt` (F5): prompt tokens this agent sent, summed over its turns, cached tokens included.
- `agents[].output` (F5): output tokens this agent received, summed over its turns.
- `agents[].cacheRead` (F6): prompt tokens served from the prompt cache.
- `agents[].cacheRatio` (F6): `cacheRead / prompt`. Higher means more of the prompt was reused from cache.
- `agents[].toolCalls`: tool calls this agent made, at any status.
- `agents[].silent` (F8): true for a subagent that made no tool call at all. Never true of the main agent.
- `agents[].resultUnreceived` (F15): true for a subagent whose spawning call has no result yet in this snapshot.
- `agents[].model`: the model identifier as the engine wrote it.
- `agents[].agentType`: a subagent's type as its spawn named it, for example the name of an agent definition. It names a role, not the task the agent was given. Absent for the main agent and where the engine stated none.
- `files` (F1): one entry per file named by a tool call in the session.
- `files[].filePath`: the file's path as the tool call named it.
- `files[].reads`: read calls naming this file.
- `files[].edits`: edit calls naming this file.
- `files[].writes`: whole-file write calls naming this file.
- `files[].errors`: calls naming this file that ended in an error.
- `files[].firstTouchSeq`: position of the first call naming this file in the session-wide call sequence (0-based, comparable across agents).
- `files[].lastTouchSeq`: position of the last call naming this file in the same sequence.
- `tools` (F2): one entry per tool name used in the session.
- `tools[].toolName`: the tool's name as the engine wrote it.
- `tools[].class`: what the tool does: `read`, `write`, `edit`, `search`, `shell`, `spawn` or `other`.
- `tools[].calls`: calls of this tool.
- `tools[].errors`: calls of this tool that ended in an error, where the engine states tool status.
- `tools[].durationMsSum`: total duration of this tool's calls, where calls carried a duration.
- `tools[].durationMsMax`: the longest single call of this tool.
- `loops` (F3): repeated identical calls: `params.loopMin` or more calls of one tool with one identical input, inside one agent.
- `loops[].agentId`: the agent that repeated the call.
- `loops[].toolName`: the repeated tool.
- `loops[].class`: the repeated tool's class.
- `loops[].count`: how many calls share the identical input.
- `loops[].ordinals`: each repeat's position among that agent's own tool calls (per-agent numbering).
- `loops[].filePath`: the file every repeat named, where the tool names one.
- `churn` (F4): churn chains: a write or edit of a file, then at least one failing call, then another write or edit of the same file, inside one agent.
- `churn[].agentId`: the agent the chain belongs to.
- `churn[].filePath`: the file written twice.
- `churn[].fromOrdinal`: the first write's position among that agent's tool calls.
- `churn[].toOrdinal`: the next write's position.
- `churn[].ordinals`: every call position strictly between the two writes.
- `churn[].errors`: how many of those calls failed, every failing call in the gap, whether it named this file or not; at least 1.
- `churn[].fileErrors`: how many of those failing calls named this chain's own file; 0 when every failure named another file or none. Cite `fileErrors`, not `errors`, for any claim that the file was reworked because it failed.
- `contextChurn` (F7): turns whose cache-creation tokens rose by at least `params.spikeTokens` over the previous turn: the prompt cache was rebuilt.
- `contextChurn[].agentId`: the agent the turn belongs to.
- `contextChurn[].ordinal`: the turn's position in that agent's turn sequence.
- `contextChurn[].delta`: the rise in cache-creation tokens over the previous turn.
- `contextChurn[].gapBeforeMs`: the idle time before this turn, milliseconds from the previous turn to this one; `null` where the engine stated no instant for either turn. A large `delta` after a gap longer than the prompt cache lifetime is the cache being rebuilt after it expired, not a large tool result: check `gapBeforeMs` and `agents[].cacheRatio` before naming the cause.
- `compactions` (F12): context compactions: the conversation was summarised to free context.
- `compactions[].agentId`: the agent whose context was compacted.
- `compactions[].ordinal`: position among that agent's tool calls when the compaction happened.
- `compactions[].trigger`: `auto`, `manual` or `engine`.
- `compactions[].preTokens`: prompt tokens immediately before the compaction, where stated.
- `compactions[].postTokens`: prompt tokens immediately after, where stated.
- `compactions[].durationMs`: how long the compaction took, where stated.
- `stalls` (F13): tools that had been silent past the stall threshold when the record was taken.
- `stalls[].agentId`: the agent whose tool stalled.
- `stalls[].toolName`: the stalled tool.
- `stalls[].ordinal`: the stalled call's position among that agent's tool calls.
- `stalls[].stalledMs`: milliseconds since the threshold was crossed.
- `skills`: every skill the session invoked, one entry per Skill tool call, in call order. Empty when the session invoked no skill.
- `skills[].name`: the skill's name as the call named it.
- `skills[].seq`: the call's position in the session-wide call sequence, the same numbering as `files[].firstTouchSeq`. Agent Deck does not record which later calls a skill's instructions produced, so no call can be attributed to a skill.
- `timing` (F14): figures derived from the session's own timestamps. Any member may be absent.
- `timing.wallMs`: last stated instant minus first stated instant in the session.
- `timing.timeToFirstToolMs`: first tool start minus the first stated instant.
- `timing.longestGapMs`: the longest interval between one call starting and the next call starting, session-wide.
- `timing.tokensPerMin`: `(totals.prompt + totals.output)` per minute of `timing.wallMs`.
- `timing.callsPerMin`: tool calls per minute of `timing.wallMs`.
- `timing.costPerHourUsd`: `totals.costUsd` per hour of `timing.wallMs`.
- `totals`: session totals over all agents.
- `totals.prompt` (F5): prompt tokens.
- `totals.output` (F5): output tokens.
- `totals.cacheRead` (F6): prompt tokens served from cache.
- `totals.costUsd` (F9): cost in US dollars, where a cost source exists.
- `totals.costSource` (F9): where the cost came from: `engine`, `telemetry` or `user` (the user's own price table).
- `totals.compactions` (F12): number of compactions.
- `totals.contextFill` (F10): the latest prompt size as a fraction of the model's context window, where the engine states the window. Above 1 means the prompt exceeded it.
- `totals.subagents`: number of subagents spawned.
- `totals.silentSubagents` (F8): subagents that made no tool call.
- `totals.subagentsUnreceived` (F15): subagents whose spawning call has no result yet.
- `totals.stalls` (F13): number of stalled tools.
- `params`: the thresholds the facts were derived with.
- `params.loopMin`: the minimum number of identical calls that counts as a loop (F3).
- `params.spikeTokens`: the cache-creation rise that counts as context churn (F7), where the engine has one.
- `unavailable`: fact ids this engine could not supply for this session, for example `F7:opencode`. A fact listed here is unknown, not zero. An entry of the form `<section>:string-overlength:<field>`, for example `files:string-overlength:filePath`, means a name or a path in that section was too long to export: the field was left out, or its row was dropped. `fileErrors:absent` means the record was written before `churn[].fileErrors` existed, and `gapBeforeMs:absent` before `contextChurn[].gapBeforeMs` existed: the rows of that section carry no such field, and its value is unknown, not zero.
## Output schema
Reply with exactly one JSON object of this shape:
{"schemaVersion":1,"findings":[{"id":"...","kind":"...","evidence":[{"statsKey":"...","value":0}],"cause":"...","action":"...","confidence":"..."}]}
- `schemaVersion`: the number 1.
- `findings`: an array of finding objects, possibly empty, in the order the user would act on them. No other top-level key.
- `id`: a short identifier of letters, digits, `.`, `_`, `:` or `-`, unique within your reply.
- `kind`: exactly one of `re-read-loop`, `churn-chain`, `context-churn`, `stall`, `silent-subagent`, `compaction`, `cache-miss`, `other`.
- `evidence`: one or more citations. Each is `{"statsKey": path, "value": number or string}`.
- `cause`: one or two sentences: why the cited numbers look the way they do.
- `action`: the action first, as one imperative sentence of at most 15 words on one line that says what the user could change. One to three sentences of detail may follow it. A reply whose first `action` sentence has more than 15 words is refused whole.
- `confidence`: `low`, `medium` or `high`.
- A finding object has no other keys; an evidence object has no other keys.
## Writing `cause` and `action`
- Name facts in plain words, as a person would say them: "read the same file 3 times", "the subagent made no tool call". Never write a `statsKey` path or a field name in these two fields.
- Copy every number from the JSON above as it is written there: the same digits, not converted to another unit, not a percentage, a difference or a total you worked out. If a point needs a number that is not in the input, make the point without the number.
- In prose, round money to cents, ratios and rates to two decimals; the evidence rows carry the exact values.
- End every sentence with a full stop, a question mark or an exclamation mark.
- A cause or an action may name only what its own evidence names. When it refers to a file, a tool or a project, write the `filePath`, `toolName` or `projectSlug` string exactly as it is in the JSON above, and cite that string in the same finding's evidence. A reply in which a cause or an action names a file path, a tool name or a project slug from the JSON that the same finding does not cite is refused whole. Write a tool name in backticks, for example `Read`. A tool name in backticks, or followed by the word "tool", names that tool; a file path or a project slug names its file or project wherever its exact text appears.
- Never say that two sessions share a tool, a file or a project unless the finding cites that string in both sessions.
- When the numbers cannot tell a deliberate failure, for example a test written to fail first, from an accidental one, say so in the cause and lower the confidence.
## Evidence
- `statsKey` is a path into the JSON above that starts at `sessions`: array positions in square brackets, object keys after dots. Examples: `sessions[0].totals.prompt`, `sessions[2].loops[0].count`, `sessions[1].agents[1].cacheRatio`.
- `value` is copied exactly from that path: the same number or the same string, not rounded, not reformatted.
- Only a number or a string can be cited. To cite an object, an array or a true/false value, cite a number or string inside it.
- A finding with any citation that does not match the input exactly is discarded.
The capability probe, sent once per CLI path and version:
Reply with exactly this JSON object and nothing else: {"ok":true,"schemaVersion":1}
No prose, no code fences, no explanation.
Appended in a second spawn, only when a reply is not JSON:
Reply with only the JSON object that matches the output schema above, and nothing else: no prose, no code fences.
History
Each validated finding set is appended to weekly files in the extension's global storage (insights/insights-<year>-W<week>.jsonl). Refused runs are shown and never stored. Set agentDeckInsights.store.enabled to false to stop storing. Existing history stays readable, and Clear Insights History removes it.
Support
Email: support@agent-deck.app
Insights is proprietary software. See LICENSE.md.
| |