mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-07-10 01:29:41 +00:00
Some checks are pending
CI / semgrep (push) Waiting to run
Surfaces real subagent-transcript spend grouped by agentType (workflow-subagent / Explore / general-purpose / …), read from each agent's sibling .meta.json (cached on CachedFile; session cache bumped 3→4). This makes ultra/workflow usage visible — the existing Task-input-based "subagents" section never sees workflow agents. Shown in `report --format json` (claudeAgentTypes) and a "Claude Agent Types" dashboard panel that renders only when Claude agent transcripts exist, so it never appears for the other providers.
61 lines
2.8 KiB
TypeScript
61 lines
2.8 KiB
TypeScript
import { mkdtemp, mkdir, rm, writeFile } from 'fs/promises'
|
||
import { tmpdir } from 'os'
|
||
import { join, basename } from 'path'
|
||
|
||
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
||
|
||
import { collectJsonlFiles, readAgentType } from '../src/parser.js'
|
||
|
||
let root: string
|
||
beforeEach(async () => { root = await mkdtemp(join(tmpdir(), 'codeburn-collect-')) })
|
||
afterEach(async () => { await rm(root, { recursive: true, force: true }) })
|
||
|
||
describe('collectJsonlFiles', () => {
|
||
// Regression for #470: workflow/ultracode subagent transcripts live nested at
|
||
// `<session>/subagents/workflows/<wf>/agent-*.jsonl`. A flat scan dropped them,
|
||
// so usage went uncounted whenever the workflow feature was on.
|
||
it('collects nested workflow subagent transcripts, not just top-level subagent files', async () => {
|
||
const sessionDir = join(root, 'session-1')
|
||
const wfDir = join(sessionDir, 'subagents', 'workflows', 'wf_abc')
|
||
await mkdir(wfDir, { recursive: true })
|
||
|
||
await writeFile(join(root, 'session-1.jsonl'), '{}\n')
|
||
await writeFile(join(sessionDir, 'subagents', 'agent-direct.jsonl'), '{}\n')
|
||
await writeFile(join(wfDir, 'agent-nested.jsonl'), '{}\n')
|
||
// Sidecar metadata must never be picked up as a transcript.
|
||
await writeFile(join(wfDir, 'agent-nested.meta.json'), '{}\n')
|
||
|
||
const found = (await collectJsonlFiles(root)).map(f => basename(f)).sort()
|
||
|
||
expect(found).toContain('session-1.jsonl')
|
||
expect(found).toContain('agent-direct.jsonl')
|
||
expect(found).toContain('agent-nested.jsonl')
|
||
expect(found).not.toContain('agent-nested.meta.json')
|
||
})
|
||
|
||
it('returns an empty list for a missing directory without throwing', async () => {
|
||
await expect(collectJsonlFiles(join(root, 'does-not-exist'))).resolves.toEqual([])
|
||
})
|
||
})
|
||
|
||
describe('readAgentType (Claude-scoped agent-type detection)', () => {
|
||
it('reads agentType from a subagent transcript’s sibling .meta.json', async () => {
|
||
const dir = join(root, 'session', 'subagents')
|
||
await mkdir(dir, { recursive: true })
|
||
await writeFile(join(dir, 'agent-x.jsonl'), '{}\n')
|
||
await writeFile(join(dir, 'agent-x.meta.json'), JSON.stringify({ agentType: 'Explore' }))
|
||
expect(await readAgentType(join(dir, 'agent-x.jsonl'))).toBe('Explore')
|
||
})
|
||
|
||
it('falls back to workflow-subagent for nested workflow agents without a meta', async () => {
|
||
const dir = join(root, 'session', 'subagents', 'workflows', 'wf_1')
|
||
await mkdir(dir, { recursive: true })
|
||
await writeFile(join(dir, 'agent-y.jsonl'), '{}\n')
|
||
expect(await readAgentType(join(dir, 'agent-y.jsonl'))).toBe('workflow-subagent')
|
||
})
|
||
|
||
it('returns undefined for an ordinary (non-subagent) session file', async () => {
|
||
await writeFile(join(root, 'session.jsonl'), '{}\n')
|
||
expect(await readAgentType(join(root, 'session.jsonl'))).toBeUndefined()
|
||
})
|
||
})
|