Skip to content

feat: add unified plugin marketplace - #7134

Open
zortos293 wants to merge 24 commits into
pingdotgg:mainfrom
zortos293:t3code/build-unified-marketplace-prototype
Open

feat: add unified plugin marketplace#7134
zortos293 wants to merge 24 commits into
pingdotgg:mainfrom
zortos293:t3code/build-unified-marketplace-prototype

Conversation

@zortos293

@zortos293 zortos293 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Adds a unified Plugins marketplace to Settings, the command palette, and the desktop sidebar.
  • Normalizes Codex, Claude Code, and Cursor marketplace entries into one environment-scoped contract while preserving each provider's native installation model.
  • Groups equivalent packages across harnesses, presents provider support badges and real package metadata, and exposes MCP servers, skills, apps, commands, subagents, hooks, rules, and language servers in a settings-style detail view.
  • Supports per-harness install and removal for Codex and Claude, delegates Cursor changes to Cursor, and verifies Codex removal against the native runtime before reporting success.
  • Adds native remote-HTTP MCP authentication state and controls: Codex OAuth through app-server, Claude's browser/callback flow, and externally managed Cursor authentication. Credentials remain in each provider's native store; stdio servers are excluded.
  • Resolves enabled skills from explicitly mentioned installed Codex plugins when a turn starts, so a newly installed package is usable in a new chat.
  • Adds the macOS Automation description and entitlement required by the Computer Use permission setup.
  • Documents the marketplace, installation semantics, package inventory, and MCP authentication behavior.

Why

T3 Code users currently have to discover, inspect, and manage extensions independently in each provider. The providers expose different catalog schemas, installation identifiers, package layouts, and authentication commands, so there was no shared model the clients could render without flattening away provider-specific behavior.

This change keeps that complexity at the server adapter boundary. The web client consumes one typed environment API, while Codex, Claude, and Cursor continue to own their installation and credential stores. That makes the marketplace usable through local, desktop-hosted, and remote environments without copying OAuth tokens into T3 state.

The PR is intentionally opened as a draft because this is a large vertical slice. The implementation stays scoped to plugin discovery, package inspection, provider-native lifecycle management, authentication, and making installed Codex skills available to turns. Maintainer direction on decomposition is welcome before review for merge.

UI Changes

After:
image

Plugins page
image

Plugin details
image

Oauth authentication
image

Package information
image

Validation

  • pnpm --dir apps/server exec vitest run src/plugins/McpOAuthRuntime.test.ts src/plugins/CodexPluginMarketplace.test.ts src/provider/Layers/CodexSessionRuntime.test.ts src/server.test.ts — 166 passed
  • pnpm --dir apps/web exec vitest run src/components/settings/pluginMarketplace/PluginMarketplacePresentation.test.tsx src/pluginMarketplace/filter.test.ts src/pluginMarketplace/store.test.ts src/components/settings/settingsSearch.test.ts — 19 passed
  • pnpm exec vp test run apps/desktop/scripts/electron-launcher.test.mjs — 5 passed
  • Changed desktop packaging cases — 2 passed
  • Contracts, web, and desktop typechecks passed
  • Integrated desktop pass covered marketplace routing/back navigation, search and filters, multi-harness details, native MCP status, and five-item package expansion

The full desktop-artifact file has one existing Apple-Silicon-local failure in the unrelated skips the primary native probe for cross-architecture Windows payloads test. The Windows probe implementation is unchanged from upstream; the two macOS packaging cases changed here pass.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Generated with GPT-5.6 using the Codex harness.


Note

High Risk
Large new surface area spanning subprocess/CLI orchestration, OAuth callback handling, and macOS codesigning/entitlements; mistakes could affect install state, auth flows, or local dev bundle security posture.

Overview
Adds a server-side unified plugin marketplace that merges Codex, Claude Code, and Cursor catalogs into one environment API: catalog/detail/logo, install/remove via native CLIs (with a separate Codex app-server runtime for curated-remote plugins), GitHub/Cursor HTML remote previews, sanitized metadata, and Computer Use macOS setup that opens the bundled app and System Settings.

Introduces McpOAuthRuntime for provider-native remote MCP auth—Codex via app-server OAuth login, Claude via mcp login and callback validation, Cursor reported as externally managed—with strict callback URL/state checks.

On desktop macOS dev, replaces the shell Electron launcher with a compiled C stub (execv), adds Apple Events usage text and dev entitlements, and ad-hoc codesigns nested frameworks and the app bundle so Automation permissions work for Computer Use.

Reviewed by Cursor Bugbot for commit 328b8da. Configure here.

Note

Add unified plugin marketplace with catalog browsing, MCP OAuth flows, and plugin skill injection

  • Adds a full plugin marketplace UI at /settings/plugins with search, harness/kind/category filtering, discovery sections, and per-plugin detail pages via PluginMarketplace and PluginDetail components.
  • Exposes new authenticated HTTP API endpoints under /api/plugins for catalog, detail, logo, install/remove/setup, and MCP OAuth start/complete/disconnect flows defined in packages/contracts/src/pluginMarketplace.ts.
  • Introduces McpOAuthRuntime, a DI service that orchestrates OAuth login sessions against Codex, Claude Code, and Cursor CLIs/app-server, with typed error classes and per-provider status parsing.
  • Adds usePluginMarketplaceStore (Zustand) to manage catalog loading, search, per-plugin detail caching, and install/uninstall with in-flight request deduplication.
  • Extends makeCodexSessionRuntime to resolve $-mention plugin skills from a user's prompt and inject them as skill inputs into Codex turn start parameters.
  • Adds sidebar footer and command palette entries for quick navigation to the plugin marketplace.
  • Risk: MCP OAuth for Cursor is explicitly unsupported and will return an error; Codex plugin skill resolution failures are logged and silently skipped rather than surfacing errors to the user.

Macroscope summarized 731d43d.

- Add cross-harness plugin discovery, details, install, and removal
- Expose marketplace settings UI and Codex plugin runtime integration
- Support Computer Use macOS launching and permissions
- Add MCP OAuth management across Codex, Claude, and Cursor
- Expose plugin authentication controls in settings
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d0de1d96-1a56-42ca-983b-6ba90bb2633e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 15, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new Effect service code under apps/server/src/plugins/ (plus its call sites) against the service conventions. Six convention violations found: service dependencies injected as plain Effect-returning objects in production construction, two error classes that carry a prose detail instead of structured attributes and drop the underlying cause, a pass-through error constructor helper, raw CLI stderr copied into a caller-visible error detail, and a named service-tag import at a service boundary.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/plugins/http.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/desktop/scripts/electron-launcher.mjs Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/desktop/scripts/electron-launcher.mjs Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two consistency issues in the new plugin marketplace UI: the search field rebuilds the shared InputGroup composition instead of using it, and the four new disclosure rows put the group/* marker on the Collapsible root, where Base UI never sets data-panel-open, so the chevrons never rotate.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Effect Service Conventions: one new finding on the marketplace contract error. The six findings from my previous review (service-instance injection through PluginMarketplaceOptions, unstructured CodexPluginRuntimeError/McpOAuthRuntimeError payloads with no cause, the commandError pass-through helper, raw CLI stderr in caller-visible detail, and the non-namespaced service import in plugins/http.ts) still apply to the current head and are not repeated here.

Posted via Macroscope — Effect Service Conventions

Comment thread packages/contracts/src/pluginMarketplace.ts Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/provider/Layers/CodexSessionRuntime.ts Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Follow-up on the earlier group-data-panel-open note: the same misplacement is present in three more collapsible rows, and the new fallback plugin logo palette only carries dark-theme text tones.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new Effect services (CodexPluginMarketplace, McpOAuthRuntime, CodexPluginRuntime, plugins/http.ts) and the plugin marketplace contracts against the Effect service conventions. Earlier findings on namespace imports, runtime dependency acquisition, CodexPluginRuntimeError, and raw CLI output in caller-visible details are resolved. Three items remain.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread packages/contracts/src/pluginMarketplace.ts
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new plugin marketplace services against the Effect service conventions. The earlier findings (missing cause on the contract errors, split McpOAuthRuntime error classes with make/layer in their owning module, runtime dependencies now acquired from the environment in production make, namespace import in plugins/http.ts) are resolved.

One convention issue remains across the three new error definitions: cause is now required on errors that frequently fail with no underlying failure, so ~30 sites construct a synthetic new Error("…") purely to fill it, and CLI exit statuses are embedded in those synthetic messages instead of being structural attributes.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread packages/contracts/src/pluginMarketplace.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new plugin marketplace UI for shared-primitive and theming consistency. The prior findings (Collapsible group markers on the trigger, InputGroup search field, fallback logo light/dark tones) are resolved.

Remaining findings: three new status/banner surfaces use the fill-tone tokens (text-success, text-warning) for body text instead of the -foreground tokens the theme pairs with text. In light theme --success is emerald-500 and --warning is amber-500, so this text renders at roughly 2:1 contrast on the near-white card/banner; the repo convention is fill tone for icons/graphics and *-foreground for text (Badge success/warning variants, AgentsPanel, FilePreviewPanel).

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new marketplace card's focus ring uses a ring offset without an offset color, which falls back to white in dark theme. Prior findings from earlier runs (fill-tone vs. -foreground text tokens, group/* markers on the Collapsible root instead of the trigger, hand-rolled search field, fallback logo light-theme tone) are resolved on this head.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One remaining convention issue: PluginMarketplaceOperationError.detail is populated by copying cause.message at the MCP auth boundaries, and the wrapper's message is then derived from that copy. Everything else flagged in earlier runs (namespace import in plugins/http.ts, runtime services acquired from the environment via tags/layers, structured errors with preserved cause, sanitized process failure details) looks addressed.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new plugin marketplace UI against the shared primitives. Prior findings (success/warning text tones, Collapsible group markers on the trigger, InputGroup search field, fallback logo light-theme tone, ring offset color) are all resolved in this revision. One remaining composition issue: both empty states place their action buttons inside EmptyHeader, which has no gap, so the buttons render flush against the description text.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new plugin marketplace UI against the shared primitives. Prior findings (success/warning text tones, Collapsible group markers on the trigger, InputGroup search field, fallback logo light-theme tone, ring offset color) are all resolved in this revision. One remaining composition issue: both empty states place their action buttons inside EmptyHeader, which has no gap, so the buttons render flush against the description text.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated
Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated
@zortos293
zortos293 marked this pull request as ready for review August 16, 2026 08:59

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One composition inconsistency left in the plugin marketplace UI; the earlier EmptyContent, collapsible group marker, focus-ring offset, and success/warning token findings all look resolved.

Posted via Macroscope — UI Consistency

@macroscopeapp

macroscopeapp Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

3 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

UI consistency review of the new plugin marketplace surfaces. Two findings; the earlier rounds' issues (Empty composition, ring offset color, success/warning tone tokens, Collapsible group markers, InputGroup search field, fallback logo light-theme tones) all look resolved.

Posted via Macroscope — UI Consistency

Comment on lines +195 to +199
{
id: "plugin-marketplace",
title: "Plugin marketplace",
to: "/settings/plugins",
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is the only entry in SETTINGS_SEARCH_ITEMS without a rendered anchor. Every other item's page spreads searchableSetting(...) onto a SettingsSection/SettingsRow (ProviderSettingsPanel, KeybindingsSettings, ConnectionsSettings, SourceControlSettings, SettingsPanels), which is what useSettingsSearchTarget needs to scroll, focus and pulse the destination.

Because nothing on /settings/plugins carries the plugin-marketplace id, picking this result navigates to /settings/plugins#plugin-marketplace, no target is ever handled, so there is no scroll/focus indication and onTargetHandled never runs — the dangling hash stays in the URL until another settings link clears it.

Suggest giving the plugins page the matching anchor, e.g. wrapping the results in a SettingsSection that spreads searchableSetting("plugin-marketplace") in PluginMarketplace.tsx.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding on the new plugins settings page: the marketplace section suppresses SettingsSection's header from the call site, which couples the page to the primitive's child order and breaks the settings-search scroll anchor. Everything else (Empty composition, Collapsible group markers, success/warning/destructive tones, InputGroup, fallback-logo light/dark tones, sidebar and command-palette entries) now matches the shared component system.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new Effect services (CodexPluginMarketplace, McpOAuthRuntime, CodexPluginRuntime, PluginProviderCommands) and their call sites. Module shape (tag → makelayer), namespace imports, environment-based dependency acquisition in make, and the split MCP OAuth error classes all look consistent with the conventions now.

One remaining issue: the new service constructors read host process state from Node globals instead of the shared HostProcess* references, which hides those dependencies from the Effect environment and makes them unoverridable in tests — notably inconsistent since makeWithOptions already resolves the platform via HostProcessPlatform.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/plugins/McpOAuthRuntime.ts Outdated
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts
Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One convention finding on the new plugin marketplace service code: CodexPluginRuntimeError uses an optional outcome discriminator to pick between four distinct user-facing messages, which the conventions ask to model as separate error classes (as was already done for the McpOAuth* errors in McpOAuthRuntime.ts). Everything else in the touched Effect service code looks consistent — subpath namespace imports, Context.Service tags with inline interfaces, make/layer exports, dependencies acquired from the environment in production make, and structural errors that preserve cause.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding in the plugin marketplace presentation: the compact harness badges expose no accessible name, so the per-card harness/support information is invisible to assistive tech. Everything else (SettingsSection hideHeader/contentClassName ownership, Empty composition, Collapsible group/* markers on the triggers, InputGroup search field, success/warning/destructive text tones, fallback logo tones) now matches the shared component system.

Posted via Macroscope — UI Consistency

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One accessibility/consistency finding in the plugin marketplace loading state. Everything else previously flagged (empty-state composition, collapsible group markers, success/warning token tones, InputGroup search field, searchable section anchor, fallback logo light-theme tones, badge naming role) now matches the shared component conventions.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginMarketplace.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding on the plugin detail loading state: the skeleton reserves a logo box that the loaded header never renders, so the page reflows when the request resolves.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the MCP callback row pairs a default-size Input with a size="sm" Button, so the two controls no longer line up once the row goes horizontal at sm.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx
zortos293 and others added 2 commits August 16, 2026 13:53
- Add harness icons to marketplace filters and support badges
- Simplify marketplace section headers and spacing
- Replace the macOS development launcher binary with a shell script

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new Effect service code (plugins/CodexPluginMarketplace.ts, plugins/McpOAuthRuntime.ts, plugins/http.ts, contract errors, and the CodexSessionRuntime call sites) against the service conventions. Imports, environment-based dependency acquisition, error modeling (separate tagged classes with structural attributes plus cause), sanitized caller-visible details, and the exported make/layer for the marketplace service all look consistent now. One residual module-layout note below.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/plugins/CodexPluginMarketplace.ts
- Add ChatGPT public plugin discovery and search
- Merge same-name plugins into unified listings with shared install targets
Comment on lines +173 to +178
await get()
.loadCatalog(true)
.catch(() => undefined);
await get()
.loadDetail(pluginId, true)
.catch(() => undefined);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium pluginMarketplace/store.ts:173

setInstalled resolves successfully after the install/remove request even when either refresh fails, so callers can show success while the store retains stale installation state. The .catch(() => undefined) calls suppress those refresh errors; let them propagate so the mutation reports failure when state could not be refreshed.

       await get()
-        .loadCatalog(true)
-        .catch(() => undefined);
+        .loadCatalog(true);
       await get()
-        .loadDetail(pluginId, true)
-        .catch(() => undefined);
+        .loadDetail(pluginId, true);
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/pluginMarketplace/store.ts around lines 173-178:

`setInstalled` resolves successfully after the install/remove request even when either refresh fails, so callers can show success while the store retains stale installation state. The `.catch(() => undefined)` calls suppress those refresh errors; let them propagate so the mutation reports failure when state could not be refreshed.

const harnessName = MARKETPLACE_HARNESS_LABELS[target.harness];
const externalHost = externalMarketplaceLabel(target, harnessName);
const changeInstallation = (installed: boolean) => {
void setInstalled(target.pluginId, installed)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium pluginMarketplace/PluginDetail.tsx:164

A success toast is shown even when the install-state refresh fails, and target.installed remains stale, so the switch can continue to display the pre-operation state and prompt the user to repeat the wrong action. setInstalled resolves after swallowing forced loadCatalog and loadDetail errors; propagate those refresh failures (or return an explicit refresh result) before treating the operation as successful.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/pluginMarketplace/PluginDetail.tsx around line 164:

A success toast is shown even when the install-state refresh fails, and `target.installed` remains stale, so the switch can continue to display the pre-operation state and prompt the user to repeat the wrong action. `setInstalled` resolves after swallowing forced `loadCatalog` and `loadDetail` errors; propagate those refresh failures (or return an explicit refresh result) before treating the operation as successful.

- Detect missing MCP servers through nested causes
- Close unused OAuth windows and document Codex sign-in behavior
export function codexMcpLoginArgs(name: string, url?: string | null): ReadonlyArray<string> {
const trimmedUrl = url?.trim();
return trimmedUrl
? ["-c", `mcp_servers.${name}.url=${JSON.stringify(trimmedUrl)}`, "mcp", "login", name]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 High plugins/McpOAuthRuntime.ts:248

For a server named acme.prod, codexMcpLoginArgs emits mcp_servers.acme.prod.url, so Codex interprets the name as nested key segments instead of configuring mcp_servers["acme.prod"]; the CLI fallback then runs without the intended URL override and authentication fails or targets an unconfigured server. Quote or otherwise escape the server-name segment in the -c key.

Suggested change
? ["-c", `mcp_servers.${name}.url=${JSON.stringify(trimmedUrl)}`, "mcp", "login", name]
? ["-c", `mcp_servers.${JSON.stringify(name)}.url=${JSON.stringify(trimmedUrl)}`, "mcp", "login", name]
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/plugins/McpOAuthRuntime.ts around line 248:

For a server named `acme.prod`, `codexMcpLoginArgs` emits `mcp_servers.acme.prod.url`, so Codex interprets the name as nested key segments instead of configuring `mcp_servers["acme.prod"]`; the CLI fallback then runs without the intended URL override and authentication fails or targets an unconfigured server. Quote or otherwise escape the server-name segment in the `-c` key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant