Skip to content

feat(providers): add Crush + provider icons in README (closes #278)#286

Merged
iamtoruk merged 1 commit into
mainfrom
feat/crush-provider
May 10, 2026
Merged

feat(providers): add Crush + provider icons in README (closes #278)#286
iamtoruk merged 1 commit into
mainfrom
feat/crush-provider

Conversation

@iamtoruk
Copy link
Copy Markdown
Member

Closes #278.

Summary

  • New provider: Crush. Charmbracelet's TUI agent. Lazy-loaded SQLite parser at src/providers/crush.ts. Walks ~/.local/share/crush/projects.json (XDG and CRUSH_GLOBAL_DATA aware), opens each project's crush.db read-only, surfaces every root session as one ParsedProviderCall with real prompt_tokens / completion_tokens / cost and the dominant model from messages.model.
  • Menubar tab. Added .crush to ProviderFilter plus the color map. Tab appears automatically when a user has Crush data; the visibleFilters computed property in AgentTabStrip already filters by what is in the payload.
  • README icons. Provider table now leads with a per-row icon column. Sourced 14 icons from tokscale (MIT) plus 4 elsewhere (codex from OpenAI org avatar, cursor-agent reuses Cursor's, kiro from kiro.dev favicon, omp from can1357/oh-my-pi). Attribution line added.
  • Docs: docs/providers/crush.md, README index update, architecture provider count bump (17 -> 18), test count bump (41/558 -> 42/568).

Schema source of truth

charmbracelet/crush@v0.66.1 internal/db/migrations/20250424200609_initial.sql, verified by a research agent rather than copied from a third-party parser. Two corrections vs tokscale's PR #346:

  1. Timestamps are seconds, not milliseconds. Schema comments claim ms; every actual INSERT/UPDATE uses strftime('%s', 'now') which is seconds. Tokscale gets this wrong and is off by 1000x.
  2. Token columns exist. Tokscale records zero tokens; Crush actually stores prompt_tokens / completion_tokens on sessions and we use them, so Crush gets real per-model attribution in our dashboards.

Test plan

  • npm test -> 42 files, 568 tests passing.
  • swift build (in mac/) -> Build complete, no warnings.
  • npm run build -> tsup bundle produced.
  • On a machine with Crush installed, codeburn status --provider crush and confirm sessions surface.
  • On macOS menubar, with a real crush.db present, confirm the Crush tab renders with cost.

Note

This branch sits on top of #285 (README doc-link column). Diff against main currently includes both; once #285 merges, the diff against main reduces to just the Crush + icons changes.

Closes #278.

Adds Charmbracelet Crush as a lazy-loaded provider:
- src/providers/crush.ts: walks ~/.local/share/crush/projects.json
  (XDG_DATA_HOME and CRUSH_GLOBAL_DATA aware), opens each project's
  crush.db read-only, queries root sessions where parent_session_id
  IS NULL. Emits one ParsedProviderCall per session with real
  prompt_tokens, completion_tokens, cost (dollars), and the
  dominant model resolved from messages.model.
- src/providers/index.ts: register crush alongside cursor, goose,
  opencode, antigravity, cursor-agent in the lazy import path.
- tests/providers/crush.test.ts: 10 fixture-based tests covering
  discovery, parsing, missing-registry, malformed JSON, missing db,
  child session exclusion, dominant model selection, dedup, and
  array-shaped legacy registry.

Schema source: charmbracelet/crush@v0.66.1
internal/db/migrations/20250424200609_initial.sql, verified by
spawning a research agent against upstream. The schema *comments*
in that migration claim millisecond timestamps but every actual
INSERT/UPDATE uses strftime('%s', 'now') which returns Unix
seconds; the parser treats values as seconds. Tokscale's
parser (junhoyeo/tokscale#346) gets this wrong and is off by
1000x, plus its parser misses the prompt_tokens/completion_tokens
columns that exist in Crush's schema. Our integration uses both,
so Crush sessions get real per-model attribution.

Menubar:
- mac/Sources/CodeBurnMenubar/AppStore.swift: add .crush case to
  ProviderFilter and its cliArg switch.
- mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift: add
  Crush color to the per-tab color extension. The visibleFilters
  computed property already filters by detected providers, so the
  Crush tab appears automatically when a user has Crush data.

README:
- Replace the provider table with an icon-led layout. Icons live
  under assets/providers/<name>.<ext>. 14 icons sourced from
  junhoyeo/tokscale (MIT) under nominative fair use, 4 sourced
  separately: codex (OpenAI org avatar), cursor-agent (reuses the
  Cursor icon), kiro (kiro.dev favicon, ico->png via sips), omp
  (can1357/oh-my-pi icon.svg, MIT). Attribution line added.
- Add Crush row.

Docs:
- docs/providers/crush.md: full per-provider doc with verified
  schema excerpt, the seconds-vs-milliseconds quirk, and a
  "when fixing a bug here" checklist.
- docs/architecture.md: provider count 17 -> 18, test count
  41 -> 42, and crush in the lazy list.
- docs/providers/README.md: add Crush row to the lazy index.
- CONTRIBUTING.md: bump test count to 568 (was 558).

All 568 tests pass locally; swift build clean.
@iamtoruk iamtoruk force-pushed the feat/crush-provider branch from 1484d1a to cc06645 Compare May 10, 2026 03:47
@iamtoruk iamtoruk merged commit 4c29f6b into main May 10, 2026
3 checks passed
@iamtoruk iamtoruk deleted the feat/crush-provider branch May 10, 2026 03:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Add support for Crush agent metrics

1 participant