From fd15f852d80c3ed611e1a6c6c3cdb8b2bf0c8d89 Mon Sep 17 00:00:00 2001 From: Jamie McGregor Nelson Date: Sun, 15 Mar 2026 09:34:43 -0400 Subject: [PATCH] test(claude-import): use portable marketplace fixtures --- src/resources/extensions/gsd/claude-import.ts | 10 ++++++++++ src/resources/extensions/gsd/marketplace-discovery.ts | 11 ++++++++--- .../extensions/gsd/tests/claude-import-tui.test.ts | 8 ++++++-- .../extensions/gsd/tests/plugin-importer-live.test.ts | 8 +++++--- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/resources/extensions/gsd/claude-import.ts b/src/resources/extensions/gsd/claude-import.ts index df48d2fab..969bca0d4 100644 --- a/src/resources/extensions/gsd/claude-import.ts +++ b/src/resources/extensions/gsd/claude-import.ts @@ -52,6 +52,9 @@ export function getClaudeSearchRoots(cwd: string): { skillRoots: string[]; plugi const parent = resolve(cwd, ".."); const grandparent = resolve(cwd, "..", ".."); + // Claude Code user-scope skills live under ~/.claude/skills. + // Keep sibling/local clone fallbacks for developer workflows, but they are + // examples/convenience paths rather than the primary Claude storage model. const skillRoots = uniqueExistingDirs([ join(home, ".claude", "skills"), join(home, "repos", "claude_skills"), @@ -62,7 +65,14 @@ export function getClaudeSearchRoots(cwd: string): { skillRoots: string[]; plugi join(grandparent, "skills"), ]); + // Anthropic docs model marketplaces as sources users add with + // `/plugin marketplace add ...`, and Claude stores those marketplaces under + // ~/.claude/plugins/marketplaces/. Installed plugin payloads are copied into + // ~/.claude/plugins/cache/. We prefer those stable Claude-managed locations + // before local example clones. const pluginRoots = uniqueExistingDirs([ + join(home, ".claude", "plugins", "marketplaces"), + join(home, ".claude", "plugins", "cache"), join(home, ".claude", "plugins"), join(home, "repos", "claude-plugins-official"), join(home, "repos", "claude_skills"), diff --git a/src/resources/extensions/gsd/marketplace-discovery.ts b/src/resources/extensions/gsd/marketplace-discovery.ts index 317b1e7f0..46636239a 100644 --- a/src/resources/extensions/gsd/marketplace-discovery.ts +++ b/src/resources/extensions/gsd/marketplace-discovery.ts @@ -4,9 +4,14 @@ * Reads marketplace.json from Claude marketplace repos, resolves plugin source paths, * parses plugin.json manifests, and inventories available components (skills, agents, commands, MCP servers, LSP servers, hooks). * - * Handles two marketplace formats: - * 1. jamie-style (../claude_skills): marketplace.json has {name, source} entries; plugins have .claude-plugin/plugin.json - * 2. official-style (../claude-plugins-official): marketplace.json entries contain inline metadata + * Marketplace roots should reflect the Claude Code model documented by Anthropic: + * users add a marketplace source with `/plugin marketplace add ...`, Claude stores + * marketplace sources under `~/.claude/plugins/marketplaces/`, and installed plugin + * payloads are copied into `~/.claude/plugins/cache/`. + * + * Handles two marketplace catalog shapes observed in the wild: + * 1. jamie-style: marketplace.json has {name, source} entries; plugins have .claude-plugin/plugin.json + * 2. official-style: marketplace.json entries contain inline metadata */ import * as fs from 'node:fs'; diff --git a/src/resources/extensions/gsd/tests/claude-import-tui.test.ts b/src/resources/extensions/gsd/tests/claude-import-tui.test.ts index fc9ae3db8..51b62c8d8 100644 --- a/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +++ b/src/resources/extensions/gsd/tests/claude-import-tui.test.ts @@ -1,10 +1,14 @@ /** * TUI Command Flow Tests for import-claude * - * Tests R015: Validates the TUI command flow for /gsd prefs import-claude - * Uses mock UI to simulate user selections. + * Tests R015: validates the TUI command flow for /gsd prefs import-claude. + * These tests currently use mock UI, and marketplace availability is still + * derived from real/local marketplace roots. Follow-up work should route these + * through portable marketplace fixtures that mirror Claude Code's + * `/plugin marketplace add ...` source model. */ + import { describe, it, before, after, mock } from 'node:test'; import assert from 'node:assert'; import { existsSync, mkdtempSync, rmSync, writeFileSync, readFileSync, mkdirSync } from 'node:fs'; diff --git a/src/resources/extensions/gsd/tests/plugin-importer-live.test.ts b/src/resources/extensions/gsd/tests/plugin-importer-live.test.ts index b7caf1dab..6971a6209 100644 --- a/src/resources/extensions/gsd/tests/plugin-importer-live.test.ts +++ b/src/resources/extensions/gsd/tests/plugin-importer-live.test.ts @@ -1,10 +1,12 @@ /** * Live E2E Tests Against Real Marketplace Repos * - * Tests R014: Validates PluginImporter pipeline against real marketplace data. - * Uses ../claude_skills and ../claude-plugins-official directories. + * Tests R014: validates PluginImporter against real marketplace data. * - * Skips gracefully when repos are absent (CI-safe). + * Source model alignment: + * - Prefer Claude Code managed marketplace locations when available + * - Fall back to cloned fixture repos for portability + * - Never require a contributor's personal sibling repo layout */ import { describe, it, before, after } from 'node:test';