[PR #5741] feat: add plugin scope support for desktop multi-project lifecycle #11559

Open
opened 2026-02-16 18:16:24 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/5741

State: open
Merged: No


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.

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/5741 **State:** open **Merged:** No --- ## 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): ```typescript 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"`: ```typescript // 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.
yindo added the pull-request label 2026-02-16 18:16:24 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#11559