codeburn/tests
voidborne-d c16b21ec50 fix(classifier): surface skill name as subCategory for general turns (#203)
Turns whose only assistant tool is `Skill` collapse to category `general`
because `classifyByToolPattern` returns `'general'` and `refineByKeywords`
only operates on `coding`/`exploration`. In environments that lean on Claude
Code skills, the per-activity dashboard column flattens — every `/init`,
`/review`, `/security-review`, `/claude-api`, plus user-defined skills, all
land in `general` with no signal about which workflow ran.

Implements Option A from the issue:

- `ParsedApiCall.skills: string[]` populated in the Anthropic-path parser
  via a new `extractSkillNames` helper that reads `input.skill || input.name`
  from each `Skill` ToolUseBlock (mirrors `detectGhostSkills` extraction at
  optimize.ts:765 so the two stay in sync).
- `ClassifiedTurn.subCategory?: string` set to the first skill name when the
  resolved category is `general` AND any skill identifier was extracted.
  Top-level category stays `general` — existing aggregations, exports, and
  category-keyed code paths unchanged.
- `SessionSummary.skillBreakdown: Record<string, {turns,costUSD,editTurns,
  oneShotTurns}>` populated in the same per-turn loop that builds
  `categoryBreakdown`. Provider sessions (Codex/Cursor/etc.) keep `skills:
  []` — they don't expose the Skill tool surface today.
- Dashboard `ActivityBreakdown` renders top-N skill sub-rows beneath the
  `general` row when present (indented `/skill-name`, dimmed). Other
  categories render exactly as before; if no skills were invoked, the panel
  is byte-identical to current output.

Existing 419 tests still pass. New `tests/classifier.test.ts` adds 8 cases:
single skill via `input.skill`, single via `input.name`, first-wins for
multi-skill turns, aggregation across multiple assistant calls in one turn,
no-name fallback (`subCategory` stays undefined), `Skill+Edit` promoting to
`coding` and dropping subCategory, non-Skill general turns, and a legacy
ParsedApiCall shape with `skills` field absent (forward-compat). Pre-fix
verification by stashing the source change reproduces 4/8 failures with the
exact "expected 'init', received undefined" diff; restoring → 8/8 pass.

Closes #203.

🤖 AI assistance disclosure: assistant-scaffolded by Claude (Opus 4.7);
author of record reviewed every line, ran the full vitest suite locally
(`npm test` → 32 files / 427 tests pass), `npx tsc --noEmit` clean, and
`npm run build` produces a clean ESM bundle.
2026-05-04 06:26:45 +08:00
..
fixtures/security test(security): add failing test for HIGH-1 prototype pollution 2026-04-17 08:32:18 +02:00
providers review: drop streamError flag, add multi-chunk and torn-write tests 2026-05-02 02:34:41 +03:00
security feat(mac): native Swift menubar app + one-command install 2026-04-17 16:55:56 -07:00
bash-commands.test.ts chore: hoist Pi model sort + cover bash-utils edge cases 2026-04-16 02:02:32 -07:00
classifier.test.ts fix(classifier): surface skill name as subCategory for general turns (#203) 2026-05-04 06:26:45 +08:00
cli-plan.test.ts feat(plan): subscription plan tracking with usage progress bar 2026-04-21 04:20:50 -07:00
compare-stats.test.ts fix(classifier): surface skill name as subCategory for general turns (#203) 2026-05-04 06:26:45 +08:00
daily-cache.test.ts Make daily cache durable: hydrate from all commands, migrate instead of nuke 2026-04-28 22:41:01 +02:00
dashboard.test.ts fix(classifier): surface skill name as subCategory for general turns (#203) 2026-05-04 06:26:45 +08:00
date-range-filter.test.ts feat(report): add --from/--to date range filtering and avgCostPerSession (#80) 2026-04-18 15:11:33 -07:00
day-aggregator.test.ts fix(classifier): surface skill name as subCategory for general turns (#203) 2026-05-04 06:26:45 +08:00
export.test.ts fix(classifier): surface skill name as subCategory for general turns (#203) 2026-05-04 06:26:45 +08:00
fs-utils.test.ts fix: pricing accuracy, stream leak, CSV injection hardening 2026-04-21 04:20:46 -07:00
menubar-json.test.ts feat(mac): native Swift menubar app + one-command install 2026-04-17 16:55:56 -07:00
minimax.test.ts feat: add MiniMax-M2.7 and MiniMax-M2.7-highspeed model pricing 2026-04-21 05:50:52 -07:00
models.test.ts fix: pricing accuracy, stream leak, CSV injection hardening 2026-04-21 04:20:46 -07:00
optimize-fs.test.ts fix: switch scanJsonlFile and parseSessionFile to readSessionLines to prevent OOM 2026-04-22 10:11:13 +00:00
optimize.test.ts docs(optimize): remove references to non-existent .claudeignore 2026-04-17 08:32:07 +02:00
parser-filter.test.ts test: cover filterProjectsByName include/exclude semantics 2026-04-16 15:49:57 -07:00
plan-usage.test.ts feat(plan): subscription plan tracking with usage progress bar 2026-04-21 04:20:50 -07:00
plans.test.ts feat(plan): subscription plan tracking with usage progress bar 2026-04-21 04:20:50 -07:00
provider-registry.test.ts Add gpt-5.5 model display name for Codex 2026-05-02 08:57:44 -07:00