Skip to content

Add OpenCode as 5th AI coding tool provider#13

Open
hjshin-ubob wants to merge 5 commits intoaroido:mainfrom
sigco3111:main
Open

Add OpenCode as 5th AI coding tool provider#13
hjshin-ubob wants to merge 5 commits intoaroido:mainfrom
sigco3111:main

Conversation

@hjshin-ubob
Copy link
Copy Markdown

Summary

  • Add OpenCode (https://github.com/opencode-ai/opencode) as the 5th AI coding tool provider with full data ingestion pipeline
  • OpenCode SQLite DB (read-only) → Tokenmon DB → UI (Tokens, Now/현황 tabs)
  • Provider chip colors unified across all tabs: Claude=orange, Codex=teal, Gemini=indigo, Cursor=green, OpenCode=purple

Changes

Pipeline

  • OpenCodeSQLiteAdapter — reads OpenCode SQLite DB, parses message JSON, filters assistant messages, computes cumulative tokens
  • OpenCodeBackfillService — mirrors Codex backfill pattern, uses ndjson_file sourceKind, sets sessionOriginHint: .startedDuringLiveRuntime so tokens contribute to encounter/exploration system
  • DB migration v10 — seeds 'opencode' provider row

Integration

  • TokenmonMenuModelsyncOpenCodeUsageInBackground(), performOpenCodeUsageSync(), wired into runTranscriptBackfill
  • TokenmonStatusItemController — 30s periodic OpenCode sync task on startup
  • TokenmonAutomationCommands — wired backfill command
  • 11 switch exhaustiveness filescase .opencode additions
  • EN/KO localization — 15 keys each

UI

  • NowTab provider chips use provider-specific colors (opacity indicates health state)
  • Popover height increased (520→560) for 5-provider layout
  • TokensTab providerSplitOrder includes .opencode

Tests

  • 9 adapter tests + 2 contract tests — all pass

Commits (5)

  1. 8202698 — Add OpenCode as 5th provider with SQLite ingestion pipeline
  2. d55605f — Increase popover height for 5-provider layout
  3. 681a9df — Fix OpenCode tokens not contributing to encounter/exploration system
  4. e048c42 — Set sessionOriginHint=.startedDuringLiveRuntime for OpenCode events
  5. a1d017b — Unify provider chip colors in NowTab with provider-specific tints

- Add OpenCode provider domain type (best_effort support level)
- Create OpenCodeSQLiteAdapter for reading OpenCode's SQLite DB
- Create OpenCodeBackfillService mirroring Codex transcript backfill pattern
- Wire 30s periodic sync into StatusItemController on app startup
- Wire manual backfill into MenuModel and automation commands
- Add case .opencode to 11 switch exhaustiveness files
- DB migration v10 seeds opencode provider row
- 9 adapter tests + 2 contract tests (migration + provider metadata)
- EN/KO localization keys for OpenCode
- Fix bottom margin on NowTab, add .opencode to token split bar
- Update README to list all 5 supported providers
- Popover height 520→560 to accommodate 3-row provider chip grid
- NowTab bottom padding 16→20 for breathing room
Change sourceKind from 'recovery_scan' to 'ndjson_file' so OpenCode events
pass through gameplayEligibilityDecision instead of being short-circuited
to recoveryOnly with gameplayDeltaTokens=0. OpenCode's 30s periodic sync
is effectively a live data source, not a one-time recovery scan.
Override the default .unknown origin hint so OpenCode events pass through
gameplayEligibilityDecision and contribute to encounter/exploration progress.
Combined with the ndjson_file sourceKind change, OpenCode tokens now flow
correctly into the Now tab's encounter progress bar and stats.
@aroido-bigcat
Copy link
Copy Markdown
Contributor

Thanks for the provider proposal. I’m holding this PR during the public-canonical cutover, so I’m not merging new provider scope while the repository contract is changing.

After the cutover lands, please rebase or reopen against the public canonical repo and the updated CONTRIBUTING rules. For a new provider, we’ll need a provider-contract design first: documented machine-readable source, privacy posture, normalized usage event shape, degraded-mode behavior, and tests. Private maintainer workflow assets or internal operator files should not be included in the public PR.

Copy link
Copy Markdown
Contributor

@aroido-bigcat aroido-bigcat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking on OpenCode support. I’m requesting changes because there are a couple of blockers before this can be safely reviewed for merge.

  1. The branch is currently stale/conflicting against main (mergeable: CONFLICTING). Please rebase/refresh first so the public canonical repo changes are represented cleanly.

  2. The incremental SQLite sync can regress same-session totals and then skip new messages. OpenCodeBackfillService.swift:63-69 only fetches rows after the saved checkpoint, but OpenCodeSQLiteAdapter.swift:155-183 computes cumulativeTotalsBySession from zero for just that fetched subset. On a second sync for the same session, the emitted normalizedTotalTokens can be lower than the previous persisted total. UsageSampleIngestionService.swift:360-383 rejects that as negative_total_regression, and OpenCodeBackfillService.swift:126-132 / 305-318 still advances the checkpoint to the last raw message id. That can permanently skip the newly fetched message without recording usable usage.

    Please make the OpenCode samples absolute cumulative totals across the provider session, or seed the running totals from Tokenmon’s previous persisted sample before ingest. Also add a regression test that runs OpenCode sync twice for the same session and verifies the second run is accepted with a positive delta rather than rejected as a total regression.

  3. The checkpoint query uses WHERE m.id > ? while ordering by m.time_created (OpenCodeSQLiteAdapter.swift:96-100). Unless OpenCode documents message ids as lexicographically monotonic in creation order, this can miss or reorder rows. Please use a stable cursor such as (time_created, id) or another documented monotonic source.

  4. Because this adds a new provider, please include the provider-contract documentation before exposing it in README/onboarding: documented machine-readable source, privacy posture for the SQLite message store, token normalization semantics, degraded-mode behavior, and tests for malformed/duplicate/missing-field input.

The direction is useful, but this needs the sync semantics and provider contract tightened before it is mergeable.

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.

2 participants