feat(settings): add third-party integrations dashboard
Add a Settings → Integrations page for installing and managing the three supported OpenCode provider plugins (Claude Code, Command Code, Cursor), with search, i18n, and plugin-registry status wiring. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
committed by
Cursor Agent
co-authored by
Serhii Dziupin
parent
3f266232f9
commit
af380081c2
@@ -25,7 +25,8 @@ export type SettingsPageSlug =
|
||||
| 'notifications'
|
||||
| 'voice'
|
||||
| 'tunnel'
|
||||
| 'about';
|
||||
| 'about'
|
||||
| 'integrations';
|
||||
|
||||
type SettingsPageGroup =
|
||||
| 'general'
|
||||
@@ -201,6 +202,7 @@ export const SETTINGS_PAGE_METADATA: readonly SettingsPageMeta[] = [
|
||||
{ slug: 'voice', title: 'Voice', group: 'general', kind: 'single', keywords: ['tts', 'speech', 'voice'], isAvailable: (ctx) => !ctx.isVSCode },
|
||||
{ slug: 'tunnel', title: 'External Tunnel', group: 'projects', kind: 'single', keywords: ['tunnel', 'external', 'cloudflare', 'qr', 'remote', 'mobile', 'share'], isAvailable: (ctx) => !ctx.isVSCode },
|
||||
{ slug: 'about', title: 'About', group: 'general', kind: 'single', keywords: ['about', 'version', 'updates', 'release', 'changelog'], isAvailable: (ctx) => ctx.isMobile && !ctx.isVSCode },
|
||||
{ slug: 'integrations', title: 'Integrations', group: 'general', kind: 'single', keywords: ['integration', 'plugin', 'provider', 'oauth', 'claude', 'cursor', 'command code', 'connect'] },
|
||||
] as const;
|
||||
|
||||
const LEGACY_SIDEBAR_SECTION_TO_SETTINGS_SLUG: Record<SidebarSection, SettingsPageSlug> = {
|
||||
@@ -286,6 +288,9 @@ export function getSettingsNavIcon(slug: SettingsPageSlug): IconName | null {
|
||||
case 'git':
|
||||
return 'git-branch';
|
||||
|
||||
case 'integrations':
|
||||
return 'plug';
|
||||
|
||||
case 'usage':
|
||||
return 'bar-chart-2';
|
||||
case 'voice':
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import type { I18nKey } from '@/lib/i18n/store';
|
||||
import { buildSettingsSearchResults } from './search';
|
||||
|
||||
const t = (key: I18nKey): string => key;
|
||||
|
||||
const runtimeCtx = {
|
||||
isVSCode: false,
|
||||
isWeb: true,
|
||||
isDesktop: false,
|
||||
isMobile: false,
|
||||
isDesktopLocalOrigin: false,
|
||||
isMac: false,
|
||||
isWindows: false,
|
||||
isLinux: false,
|
||||
isWindowsArm64: false,
|
||||
};
|
||||
|
||||
describe('settings search', () => {
|
||||
test('finds the Claude Code third-party integration', () => {
|
||||
const results = buildSettingsSearchResults({
|
||||
query: 'claude',
|
||||
runtimeCtx,
|
||||
t,
|
||||
getPageTitle: (page) => page,
|
||||
});
|
||||
|
||||
expect(results.some((result) => result.id === 'integrations.third-party.opencode-claude')).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -933,6 +933,34 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
|
||||
keywords: ['background', 'push'],
|
||||
isAvailable: (ctx) => ctx.isWeb && !ctx.isDesktop && !ctx.isVSCode,
|
||||
},
|
||||
|
||||
{
|
||||
id: 'integrations.third-party',
|
||||
page: 'integrations',
|
||||
titleKey: 'settings.integrations.thirdParty.title',
|
||||
keywords: ['plugin', 'provider', 'oauth', 'install', 'update', 'remove'],
|
||||
},
|
||||
{
|
||||
id: 'integrations.third-party.opencode-claude',
|
||||
page: 'integrations',
|
||||
titleKey: 'settings.integrations.thirdParty.opencodeClaude.name',
|
||||
descriptionKey: 'settings.integrations.thirdParty.opencodeClaude.description',
|
||||
keywords: ['claude', 'anthropic', 'claude code', 'pro', 'max', 'agent sdk'],
|
||||
},
|
||||
{
|
||||
id: 'integrations.third-party.opencode-commandcode',
|
||||
page: 'integrations',
|
||||
titleKey: 'settings.integrations.thirdParty.opencodeCommandcode.name',
|
||||
descriptionKey: 'settings.integrations.thirdParty.opencodeCommandcode.description',
|
||||
keywords: ['command code', 'commandcode', 'laguna', 'poolside', 'gateway'],
|
||||
},
|
||||
{
|
||||
id: 'integrations.third-party.opencode-cursor-oauth',
|
||||
page: 'integrations',
|
||||
titleKey: 'settings.integrations.thirdParty.opencodeCursorOauth.name',
|
||||
descriptionKey: 'settings.integrations.thirdParty.opencodeCursorOauth.description',
|
||||
keywords: ['cursor', 'oauth', 'subscription', 'openai compatible'],
|
||||
},
|
||||
] as const;
|
||||
|
||||
interface BuildSettingsSearchResultsOptions {
|
||||
|
||||
Reference in New Issue
Block a user