feat(providers): add Crush + provider icons in README (closes #278)#286
Merged
Conversation
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.
1484d1a to
cc06645
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #278.
Summary
src/providers/crush.ts. Walks~/.local/share/crush/projects.json(XDG andCRUSH_GLOBAL_DATAaware), opens each project'scrush.dbread-only, surfaces every root session as oneParsedProviderCallwith realprompt_tokens/completion_tokens/costand the dominant model frommessages.model..crushtoProviderFilterplus the color map. Tab appears automatically when a user has Crush data; thevisibleFilterscomputed property inAgentTabStripalready filters by what is in the payload.kiro.devfavicon, omp fromcan1357/oh-my-pi). Attribution line added.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.1internal/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:strftime('%s', 'now')which is seconds. Tokscale gets this wrong and is off by 1000x.prompt_tokens/completion_tokensonsessionsand we use them, so Crush gets real per-model attribution in our dashboards.Test plan
npm test-> 42 files, 568 tests passing.swift build(inmac/) -> Build complete, no warnings.npm run build-> tsup bundle produced.codeburn status --provider crushand confirm sessions surface.crush.dbpresent, 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.