Skip to content

feat(scanner): add Codex plugin marketplace discovery (#124)#151

Merged
luongnv89 merged 6 commits intomainfrom
feat/124-codex-plugin-marketplace-discovery
Apr 12, 2026
Merged

feat(scanner): add Codex plugin marketplace discovery (#124)#151
luongnv89 merged 6 commits intomainfrom
feat/124-codex-plugin-marketplace-discovery

Conversation

@luongnv89
Copy link
Copy Markdown
Owner

Closes #124

Summary

  • Adds scanCodexPluginCache() to discover installed Codex plugins from ~/.codex/plugins/cache/{marketplace}/{plugin}/{version}/.codex-plugin/plugin.json
  • Adds readCodexMarketplaceFiles() to read available plugins from ~/.agents/plugins/marketplace.json and .agents/plugins/marketplace.json
  • Adds loadCodexEnabledMap() with a lightweight TOML parser for ~/.codex/config.toml enabled/disabled state (no new dependencies)
  • Wires Codex plugin scanning into scanAllSkills() alongside the existing Claude plugin marketplace scan

Approach

Follows the established scanPluginMarketplaces() pattern exactly. Codex plugins are surfaced as SkillInfo entries with provider: "codex-plugin" and providerLabel: "Codex Plugin ({marketplace})" — no view changes required since all display paths already use providerLabel. Deduplication is two-tier: by realPath first, then by skill name across Claude and Codex plugin providers.

The TOML parser is intentionally minimal (regex-based [plugins.name] section parsing) to avoid adding a dependency. Highest-version directory wins when multiple versions of a plugin are cached.

Changes

File Change
src/scanner.ts Add scanCodexPluginCache(), readCodexMarketplaceFiles(), loadCodexEnabledMap(), parseTomlEnabledMap(); update scanAllSkills() signature with optional codexCacheDir; add CodexPluginManifest import
src/utils/types.ts Add codexPlugin? field to SkillInfo; add CodexPluginManifest interface
src/formatter.ts Add codex-plugin entry to PROVIDER_COLORS (cyan)
src/scanner.test.ts Add 25 tests for scanCodexPluginCache and readCodexMarketplaceFiles

Test Results

80 scanner tests pass (up from 55). Pre-existing failures in publisher.test.ts and cli.test.ts are unrelated to this change (confirmed present on main before this branch).

Acceptance Criteria

  • ASM scans Codex plugin cache path (~/.codex/plugins/cache/) to discover installed Codex plugins
  • ASM reads Codex marketplace files (marketplace.json) from repo-level and user-level .agents/plugins/ paths
  • Codex plugins appear in asm list output, distinguished from Claude skills and traditional skills (via providerLabel: "Codex Plugin (marketplace-name)")
  • asm info {skill} works for Codex plugins and displays plugin manifest metadata (name, version, description, category via codexPlugin.category)
  • ASM reads ~/.codex/config.toml to determine enabled/disabled status of Codex plugins
  • Deduplication logic detects when the same skill exists across both Claude and Codex plugin paths (name-based cross-provider dedup in scanAllSkills)

- Add scanCodexPluginCache() to scan ~/.codex/plugins/cache/{marketplace}/{plugin}/{version}/.codex-plugin/plugin.json
- Add readCodexMarketplaceFiles() to read marketplace.json from ~/.agents/plugins/ and .agents/plugins/ paths
- Add loadCodexEnabledMap() with lightweight TOML parser for ~/.codex/config.toml enabled/disabled state
- Wire Codex plugin scan into scanAllSkills() with name+realPath deduplication across Claude and Codex plugin providers
- Add CodexPluginManifest interface and codexPlugin metadata field to SkillInfo
- Register codex-plugin provider color (cyan) in formatter
- Add 25 tests covering cache discovery, TOML parsing, version selection, marketplace.json reading, and deduplication
…parser on section change

- Replace lexicographic sort with compareSemver in scanCodexPluginCache so
  versions like 10.0.0 are correctly ranked above 2.0.0
- Reset currentPlugin to null in parseTomlEnabledMap when a non-[plugins.*]
  section header is encountered, preventing enabled/disabled values from
  other sections being attributed to the last matched plugin
- Add test case covering semver vs lexicographic version selection
…lls type

- Apply name-based deduplication consistently to Claude plugin skills in
  scanAllSkills (previously seenNames was populated but never checked for
  pluginSkills, only for codexPluginSkills)
- Change CodexPluginManifest.skills type from string to string[] to match
  the actual plugin ecosystem schema
Object.keys(null) throws TypeError when plugin.json contains "mcp": null.
Use != null (loose inequality) to safely guard against both null and
undefined, preventing the entire scanCodexPluginCache call from crashing.

Adds a regression test for the null mcp case.
… marketplace utility

parseTomlEnabledMap now strips surrounding double/single quotes from
section headers like [plugins."my-plugin"], so the enabled/disabled
lookup matches the directory name correctly.

Adds a clarifying JSDoc note to readCodexMarketplaceFiles explaining it
is a catalog utility for search/install commands, not part of scanAllSkills.
@luongnv89 luongnv89 merged commit d54bf4a into main Apr 12, 2026
10 checks passed
@luongnv89 luongnv89 deleted the feat/124-codex-plugin-marketplace-discovery branch April 12, 2026 08:50
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.

Add support for Codex plugin marketplace discovery

1 participant