Skip to content

feat(v2): V2 plugin API support - #33

Closed
kilng235 wants to merge 2 commits into
Hotakus:masterfrom
kilng235:feat/v2-support
Closed

kilng235 wants to merge 2 commits into
Hotakus:masterfrom
kilng235:feat/v2-support

Conversation

@kilng235

Copy link
Copy Markdown

Summary

V2 fork of opencode-visual-cache. Migrates src/index.tsx (~2238 → ~2220 lines) from the V1 plugin API to V2 Plugin.define({ id, setup }).

What's migrated

  • Plugin entry: const tui: TuiPlugin = async (api) => …export default Plugin.define({ id, setup(context) { … } }) from @opencode/plugin/tui
  • Theme: V2 ResolvedTheme (no flat primary etc.) mapped to the 7-key palette the components expect (primary / text / textMuted / success / warning / error / border), desaturated through the existing Morandi ceiling
  • KV: 30+ api.kv.get/set/ready → single context.storage.store("settings", { initial }) reactive pair; the .ready polling interval is gone
  • Dialogs: all 9 <api.ui.DialogPrompt> / <api.ui.DialogSelect> JSX usages → imperative await context.ui.dialog.prompt / select. The chained dialog?.replace(...) + dialog?.clear() pattern collapses to plain awaits
  • <api.ui.Prompt> override → prompt.footer.status slot (V2 doesn't let plugins replace the prompt input itself)
  • Slots: api.slots.register({ slots: { sidebar_content } })context.ui.slot({ append: "sidebar.content", render })
  • api.state.part(msgId) → iterate context.data.session.message.list(sid) and read msg.parts
  • Commands: api.command.register()context.keymap.layer(() => ({ commands: [{ slash, run }] }))
  • api.state.session.{messages,get,cost}context.data.session.message.list / get / cost
  • api.lifecycle.onDispose(...) → return a single cleanup function from setup()
  • api.route.current (used in 2 slash commands) → V2 commands receive sessionID directly in execute()

Behavior deltas

  • OpenAI / non-OpenAI provider keys: V2 doesn't expose raw provider keys via api.state.provider. Non-OpenAI providers now require /cache-balance-key; OpenAI still works via the OAuth auth.json fallback.
  • App.dataDir: doesn't exist on the V2 App interface. readOpenAIOAuthToken() derives paths from HOME / XDG_DATA_HOME / APPDATA directly.
  • Provider pricing: V2 exposes models via context.client.model.list(); pricing is filled best-effort only when the list is synchronously resolvable, so the createEffect reactive graph doesn't block.
  • Event subscriptions for token updates: V1 event.on("message.part.updated") has no exact equivalent; substituted with session.usage.updated + session.tool.success / session.tool.failed + session.idle.

Verification

  • npm install
  • npm run build ✅ emits dist/tui.js (135 KB)
  • npm run typecheck
  • npm run test:balance
  • src/server.ts deleted (V1 server stub no longer needed)

Compatibility

This is a V2-only fork. V1 OpenCode users should keep using the upstream opencode-visual-cache package. Installing @kilng235/opencode-visual-cache against V1 will not work.

If upstream accepts this back, a future change can add the dual-export pattern (per the V1→V2 migration guide) so a single package supports both.

- Rename to @kilng235/opencode-visual-cache
- Switch peerDeps to V2 @opencode/plugin
- Update install.mjs to use V2 plugins array (was: V1 plugin)
- Replace TuiPlugin/TuiPluginApi with V2 Plugin.define + setup(context)
- Replace api.slots.register / api.ui.Prompt override with context.ui.slot({append: ...})
- Replace api.command.register with context.keymap.layer({commands: [{slash: ...}]})
- Replace 9 dialog usages (DialogSelect/DialogPrompt) with await context.ui.dialog.* calls
- Replace api.kv.get/set/ready (30+ calls) with a single reactive context.storage.store
- Replace api.state.part/get/provider/etc. with context.data.session.* and context.client.model.list
- Replace api.theme.current with context.theme (V2 ResolvedTheme tokens)
- Replace api.event.on('message.part.updated') with V2 session.* events
- Replace api.lifecycle.onDispose with cleanup function returned from setup()
- Replace api.route.current with context.ui.router.current()
- Drop <api.ui.Prompt>/<api.ui.Dialog*>/<api.ui.Slot> JSX usage
- Delete src/server.ts (V1 server stub)
- Bump @opentui/{core,solid,keymap} to ^0.5.10 to satisfy V2 plugin peer deps
- Add @opencode/client devDep so TS can resolve V2 client types

Build/typecheck/tests all pass.
@kilng235

Copy link
Copy Markdown
Author

Closing — opened in wrong repo (targeted upstream instead of fork). Re-open manually at https://github.com/kilng235/opencode-visual-cache if you want to send upstream.

@kilng235 kilng235 closed this Sep 13, 2026
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