feat: add plugin scope support for desktop multi-project lifecycle
Problem
The CLI and desktop app have fundamentally different lifecycles:
-
CLI: Single project, always starts from a project directory (
process.cwd()) - Desktop: Multi-project, starts without any project context, users select projects later
This difference wasn't accounted for in the plugin system. Plugins load regardless of whether a valid project context exists.
I discovered this while working on a plugin that requires project context (tsconfig.json). The CLI crashed when no tsconfig was present, which I initially handled poorly. But then the desktop crashed regardless - there's no project context on startup, so my plugin could never initialize.
This revealed that the plugin system has no way for plugins to declare whether they need project context.
Solution
1. Plugin scopes - Plugins can now declare "global" or "project" scope (default):
import { definePlugin } from "@opencode-ai/plugin"
export default definePlugin({
scope: "global",
plugin: async (input) => ({
auth: { provider: "my-provider", ... }
})
})
2. Predictable desktop startup - Desktop clients without explicit directory use home directory, ensuring worktree === "/" (no git repo).
3. Scope-aware loading - Project-scoped plugins skip loading when worktree === "/".
Migration for auth plugin authors
Wrap your plugin with definePlugin and set scope: "global":
// Before
export default async (input) => ({
auth: { ... }
})
// After
import { definePlugin } from "@opencode-ai/plugin"
export default definePlugin({
scope: "global",
plugin: async (input) => ({
auth: { ... }
})
})
Backwards compatibility
- Old plugins (plain functions) default to
"project"scope - Built-in auth plugins hardcoded as global temporarily
- CLI behavior unchanged
Follow-up
If accepted, I can update opencode-copilot-auth and opencode-anthropic-auth to use definePlugin, then remove the hardcoded list.