Add Claude Code plugin marketplace#147
Conversation
Make the repo installable as a Claude Code plugin in addition to the existing `npx skills` flow: - .claude-plugin/marketplace.json: marketplace `flutter` listing one plugin, `flutter-skills`, sourced from the repo root. - .claude-plugin/plugin.json: manifest for the `flutter-skills` plugin. No version field, so the commit SHA drives updates. - README.md: document `/plugin marketplace add flutter/skills` and `/plugin install flutter-skills@flutter`.
There was a problem hiding this comment.
Code Review
This pull request introduces support for Claude Code by adding marketplace.json and plugin.json configuration files and updating the README.md with installation instructions. The review feedback identifies a potential path resolution issue for the plugin source and suggests reducing metadata redundancy between the configuration files to improve maintainability.
| "plugins": [ | ||
| { | ||
| "name": "flutter-skills", | ||
| "source": "./", |
There was a problem hiding this comment.
The source path is set to "./". Since marketplace.json is located within the .claude-plugin/ directory, a relative path of ./ typically resolves to the .claude-plugin/ directory itself. If the intention is for the repository root to be the plugin root (to include the skills/ directory), this path might need to be "../" to point to the parent directory.
While your local testing with claude plugin marketplace add ./ succeeded, it's possible the tool resolved the path relative to your current working directory. Please verify if this works correctly when the marketplace is added via a remote repository reference (e.g., /plugin marketplace add flutter/skills) to ensure the skills/ directory is correctly included in the installation for end users.
| "description": "Task-based skills that teach coding agents happy-path Flutter workflows: widget and integration tests, widget previews, responsive layouts, declarative routing, localization, HTTP networking, JSON serialization, and layered architecture best practices.", | ||
| "author": { | ||
| "name": "The Flutter Authors" | ||
| }, | ||
| "homepage": "https://github.com/flutter/skills", | ||
| "repository": "https://github.com/flutter/skills", | ||
| "license": "BSD-3-Clause", | ||
| "keywords": ["flutter", "dart", "mobile", "testing", "ui", "skills"], |
There was a problem hiding this comment.
The plugin metadata (description, author, homepage, repository, license, and keywords) is duplicated between this file and .claude-plugin/plugin.json. This redundancy increases the maintenance effort and the risk of the two files falling out of sync. Consider if the marketplace schema allows omitting these fields in favor of the values defined in the plugin manifest.
| npx skills add flutter/skills --skill '*' --agent universal | ||
| ``` | ||
|
|
||
| ### Install with Claude Code |
There was a problem hiding this comment.
If you want to test before merging use /plugin marketplace add flutter/skills@add-claude-plugin-marketplace
No code change required.
Keep the marketplace plugin entry to what the catalog needs (name, source, description, category) and let plugin.json be the single source of truth for author, homepage, repository, license, and keywords.
Move the plugin into plugins/flutter-skills/ and point the marketplace source there. A skills symlink to ../../skills lets Claude Code dereference it on install and copy only the skills, instead of copying the entire repo (tool/, resources/, .agents/) as source: "./" did. The top-level skills/ directory is unchanged, so the `npx skills` flow is unaffected.
New standalone tool/marketplace_check package plus a marketplace workflow (ubuntu/macOS/windows matrix). The test asserts: - marketplace.json declares the flutter-skills plugin with source ./plugins/flutter-skills (guards against regressing to "./", which would copy the whole repo into users' caches), - the source resolves to a dir containing plugin.json, - the skills symlink resolves to the top-level skills/ directory, - every top-level skill is reachable through that symlink. The windows matrix leg also exercises whether the symlink survives checkout on Windows.
Run the canonical Claude Code validator (schema, duplicate names, path traversal, version mismatches) in CI on top of the Dart structural test. It runs offline, so no API key is needed; installed via npm on an ubuntu-only job. Verified headless (fresh HOME, no auth) exits 0.
Makes
flutter/skillsinstallable as a Claude Code plugin, in addition to the existingnpx skillsflow. Adds a.claude-plugin/marketplace catalog and aflutter-skillsplugin, documents the new install path in the README, and adds CI to keep the wiring honest.Why a symlink instead of
source: "./"The skills have to stay in the top-level
skills/directory — thenpx skills add flutter/skillsinstaller and the README both depend on it. So the plugin lives in its own directory and links back to them:On install Claude Code dereferences a symlink that resolves elsewhere in the same marketplace and copies the target's content in its place (docs), so the cache gets only the 10 skills — not
tool/,resources/, or.agents/. An earlier revision usedsource: "./"(repo root as the plugin); it worked but copied the entire repo into every user's cache, includingtool/dart_skills_lint's own skills. The symlink keeps one canonicalskills/for both install paths — same idea as the.claude/skills→.agents/skillssymlink from #141.marketplace.jsonis trimmed to the catalog essentials (name/source/description/category);plugin.jsonowns the rest of the metadata. Noversionfield, so the commit SHA is the version and every push ships as the latest.Manual validation steps I took
claude plugin validate .andclaude plugin validate ./plugins/flutter-skills→ pass.claude plugin marketplace add flutter/skills@add-claude-plugin-marketplace && claude plugin install flutter-skills@flutter→ installs; the cache held only the 10 skills (tool/,resources/,.agents/absent).CI
tool/marketplace_check/— a standalone Dart test (ubuntu/macOS/windows matrix) that pins the wiring:sourceis./plugins/flutter-skills(guards against regressing to"./"), it resolves to a dir withplugin.json, theskillssymlink resolves to the top-levelskills/, and every skill is reachable through it.validatejob that installs the CLI and runsclaude plugin validate(offline, no API key).actions/checkouton Windows, not just Linux/macOS.Notes:
/plugin marketplace add flutter/skillswon't resolve (the manifest is only on this branch) — use@add-claude-plugin-marketplaceor a local./checkout../add skips them.