Skip to content

feat(opencode): unify Black + Go (Lite) + shared billing into one provider#98

Open
anthonybaldwin wants to merge 3 commits into
mainfrom
feat/opencode-unify
Open

feat(opencode): unify Black + Go (Lite) + shared billing into one provider#98
anthonybaldwin wants to merge 3 commits into
mainfrom
feat/opencode-unify

Conversation

@anthonybaldwin
Copy link
Copy Markdown
Owner

Summary

Replaces the existing two providers (opencode + opencodego) with one unified opencode provider that surfaces 21 namespaced metrics across three lanes:

  • black-* (5) — paid Zen subscription rate limits ($20 / $100 / $200)
  • go-* (6) — Lite (Go) plan rate limits ($12 / $30 / $60)
  • billing-* (10) — shared credit balance, monthly limit/usage, auto-reload state, payment last4

Architecture, full metric inventory, and don't-do list are in plans/opencode-tier-coverage.md. The previous opencode provider was silently parsing the wrong fields for non-Black users; this PR re-grounds the implementation against the four actual product tiers (Free / Lite / Black / Enterprise) per sst/opencode source.

User-pinned buttons auto-migrate via two-stage rebinding:

  • metricIDAliases (plugin-side + PI-side) rewrites Claude-flavored IDs (session-percent / weekly-percent / monthly-percent) to lane-namespaced IDs on willAppear, persisted via SetSettings.
  • providerIDActionAliases maps the legacy opencodego action UUID to opencode for fetch dispatch — so even though Stream Deck still labels old buttons under the removed action UUID, the unified provider serves them. One log line per launch per migration kind.

The bundle also renames the workspace-override env var from CODEXBAR_OPENCODE_WORKSPACE_IDOPENCODE_WORKSPACE_ID per plans/codexbar-env-cleanup.md. CODEXBAR_OPENCODEGO_WORKSPACE_ID collapses entirely — Black and Lite share the same workspace.

Server-function hashes — captured / TODO

Function Hash Status
workspaces.list def39973159c7f0483d8793a822b8dbb10d067e12c65455fcb4608459ba0234f already in code
subscription.get (Black) 7abeebee372f304e050aaaf92be863f4a86490e382f8c79db68fd94040d691b4 renamed subscriptionServerIDblackServerID; works
lite.subscription.get (Go) empty placeholder needs DevTools capture
billing.get (shared) empty placeholder needs DevTools capture

SolidStart content-addresses these by build at the function-key + file-position level — they're not derivable from the function name alone (we confirmed via the public sst/opencode source). The infrastructure ships with empty-string consts; Fetch() falls through to "no data" for those lanes and logMissingHashes() emits one launch-time warning. Once the hashes are captured (right-click Network panel on opencode.ai → look for the POST/GET to /_server and copy the id query param), drop them into liteServerID / billingServerID in internal/providers/opencode/opencode.go and the go-* + billing-* metrics light up immediately. No code changes required beyond the const literals.

Changes

  • New: internal/providers/opencode/opencode.go — three-lane parser (parseBlackResponse, parseLiteResponse, parseBillingResponse), parallel fan-out via goroutines, per-lane graceful degrade.
  • New: internal/providers/opencode/opencode_test.go — 12 tests covering active / null / minified-Solid / empty-workspace shapes for each parser, plus snapshot-assembly tests for Black-only, Go-only, and Billing-only paths.
  • Removed: internal/providers/opencodego/, internal/icons/opencodego.go, opencodego SVG assets, docs/provider-icons/opencodego.svg, manifest action entry.
  • cmd/plugin/main.gometricIDAliases gains opencode + opencodego entries; new providerIDActionAliases + canonicalProviderID + providerIDForAction helpers; willAppear handler rewrites + persists migrated metric IDs via SetSettings; ~15 callsites of streamdeck.ProviderIDFromAction route through the canonicalizer.
  • cmd/plugin/main_test.go — locks in the migration contracts.
  • stat.html — single METRICS["opencode"] with __group__: optgroup separators (Black / Go / Billing); plugin-mirroring METRIC_ID_ALIASES; new metricRows() + isGroupRow() helpers; populateMetrics() emits <optgroup> for group rows.
  • Manifest re-sorted alphabetically after opencodego removal (PowerShell Sort-Object Name | ConvertTo-Json).
  • README.md, docs/PROVIDERS.md, docs/index.html updated coherently. Provider count 35 → 34. OpenCode Go pill dropped.

Test plan

  • go build ./... clean
  • go vet ./... clean
  • golangci-lint run ./... clean (0 issues)
  • go test ./... clean — all opencode parser tests pass; main_test migration contract tests pass; manifest UUID resolution test passes (opencodego no longer claimed by manifest)
  • Plugin binary builds (go build -ldflags="-H=windowsgui" ...)
  • Manual verify on a live opencode.ai-logged-in browser: Black-tier user sees black-* metrics populated, button rebinds work after restart
  • Once lite.subscription.get + billing.get hashes are captured: re-run with a Lite-tier account and verify go-* + billing-* lanes populate

References

🤖 Generated with Claude Code

anthonybaldwin and others added 3 commits May 3, 2026 14:43
Folds the previous opencode + opencodego split back into a single
provider that surfaces 21 namespaced metrics across three lanes:

- black-* : paid Zen subscription rolling/weekly/status/plan
- go-*    : Lite (Go) rolling/weekly/monthly with status
- billing-* : shared balance, monthly limit/usage, auto-reload, last4

The three _server function calls (subscription.get, lite.subscription.get,
billing.get) fan out in parallel via goroutines; missing lanes degrade
to "no data" rather than erroring the whole snapshot — Black-only and
Lite-only users both see a working tile without one lane breaking the
other.

The lite.subscription.get and billing.get hashes ship as empty
placeholders. SolidStart content-addresses these at build time and they
need DevTools network capture from a live opencode.ai session to
populate. logMissingHashes() emits a one-time launch warning. Black
metrics work today; go-* and billing-* light up once the hashes land.

Also renames CODEXBAR_OPENCODE_WORKSPACE_ID to OPENCODE_WORKSPACE_ID
per plans/codexbar-env-cleanup.md (the workspace ID is now shared by
Black and Lite, so the opencodego variant collapses too).

See plans/opencode-tier-coverage.md for the architecture decision and
the full metric inventory.

Co-Authored-By: Claude <noreply@anthropic.com>
Removes the standalone OpenCode Go provider — its three metrics
(session/weekly/monthly) now live as `go-rolling-percent`,
`go-weekly-percent`, `go-monthly-percent` on the unified opencode
provider. User-pinned buttons keep working via two-stage migration:

- metricIDAliases gains `opencode` + `opencodego` entries that rewrite
  Claude-flavored IDs (session-percent/weekly-percent/monthly-percent)
  to the lane-namespaced equivalents on willAppear, persisted via
  SetSettings so the canonical ID flows back to the PI dropdown.
- providerIDActionAliases maps the legacy `opencodego` action UUID to
  `opencode` for fetch dispatch — buttons surface the new metric
  immediately even though Stream Deck still labels them under the
  removed action UUID.

One log line per launch announces each migration kind. Subsequent
rebinds stay silent.

The opencodego package, manifest action, glyph, SVG assets, website
icon, and cache.go provider-list entry are all dropped. Plugin-level
ProviderIDFromAction callers route through providerIDForAction so
they pick up the alias automatically.

Co-Authored-By: Claude <noreply@anthropic.com>
…ider

- stat.html METRICS["opencode"] gains 21 namespaced rows split across
  three optgroups (Black, Go, Billing) — same __group__ syntax pattern
  used elsewhere. METRICS["opencodego"] entry, BRAND_COLORS/BRAND_BG
  duplicate, AUTH_PROVIDERS entry, and provider-name label all
  dropped.
- METRIC_ID_ALIASES mirrors the plugin-side opencode + opencodego
  metric rename so the PI dropdown selects the right option for
  pre-rename buttons.
- populateMetrics now emits <optgroup> separators for group rows;
  metricRows() helper strips them so default-metric resolution and
  feature-visibility logic keep using flat .find().
- PROVIDERS.md collapses two rows into one with the full metric
  inventory.
- README.md drops opencodego/ from the provider tree.
- docs/index.html provider count goes 35 → 34, OpenCode Go pill
  removed.
- Workspace override env var renamed CODEXBAR_OPENCODE_WORKSPACE_ID →
  OPENCODE_WORKSPACE_ID per plans/codexbar-env-cleanup.md (one var
  covers both lanes since they share the workspace ID).

Co-Authored-By: Claude <noreply@anthropic.com>
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.

1 participant