Skip to content

OpenCode: skills[] and subagents[] report sections always empty (parser ignores skill/task tool input) #556

Description

@KevNev19

Summary

For OpenCode sessions, the skills and subagents report sections are always empty, even when skills and subagents are heavily used. The tools table correctly shows aggregate Skill and Agent call counts, so the tool invocations are being read — but the per-call name (which skill / which subagent) is never extracted, so the dedicated breakdowns stay empty.

This is not the same as #336 (Claude CLI / Gemini subagent tool-call tracking) or #308 (OpenCode MCP attribution). This is specifically the OpenCode skill / task tool argument extraction for the skills and subagents sections.

Environment

  • CodeBurn: 0.9.12 (global npm install)
  • OpenCode: 1.17.9
  • macOS 26.5.1 (arm64)
  • OpenCode storage: ~/.local/share/opencode/storage/

Evidence

codeburn report --period 30days --format json returns:

{
  "skills": [],
  "subagents": [],
  "tools": [
    { "name": "Skill", "calls": 203 },
    { "name": "Agent", "calls": 339 },
    ...
  ]
}

So 203 skill calls and 339 subagent (Agent) calls are counted, but skills and subagents are both [].

Root cause

In OpenCode's on-disk format, each tool call is a separate JSON file under ~/.local/share/opencode/storage/part/<messageID>/<partID>.json. The skill/subagent name lives in state.input, not in the tool name. The parser appears to count the tool by name (skill/task) but never joins state.input to recover the name.

Skill call part (tool: "skill"):

{
  "type": "tool",
  "tool": "skill",
  "callID": "...",
  "state": { "input": { "name": "plan-spec" } }
}

Subagent call part (tool: "task"):

{
  "type": "tool",
  "tool": "task",
  "callID": "...",
  "state": {
    "input": {
      "description": "Find service connection code",
      "prompt": "...",
      "subagent_type": "explore"
    }
  }
}

Note: in the part files the tool names are lowercase (skill, task), while the tools report displays them capitalised (Skill, Agent) — so there is name normalisation happening for the count path but not the breakdown path.

Expected behaviour

  • skills[] populated, grouped by state.input.name from skill tool parts (e.g. plan-spec), with call counts and token/cost.
  • subagents[] populated, grouped by state.input.subagent_type from task tool parts (e.g. explore), with call counts and token/cost.

Suggested fix

When parsing OpenCode part files, for tool === "skill" read state.input.name, and for tool === "task" read state.input.subagent_type (fall back to description), then attribute those to the skills / subagents aggregations the same way the tools count is already attributed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions