Skip to content

Feat/upstream/skills marketplace#1530

Open
futuremeng wants to merge 4 commits intoagentscope-ai:mainfrom
futuremeng:feat/upstream/skills-marketplace
Open

Feat/upstream/skills marketplace#1530
futuremeng wants to merge 4 commits intoagentscope-ai:mainfrom
futuremeng:feat/upstream/skills-marketplace

Conversation

@futuremeng
Copy link
Contributor

Description

Add a Git-backed Skills Marketplace across backend, console UI, tests, and docs, so users can configure multiple market sources, validate market entries, browse aggregated skills, and install with overwrite confirmation when conflicts exist.

This PR also includes a follow-up UX fix:

  • Market URL example changed to openclaw/openclaw
  • Default market index path changed to skills

Related Issue: Relates to #TBD
Security Considerations: No new auth surface introduced. Market config is handled via existing config flow. Error mapping was tightened to avoid unstructured 500 responses.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Refactoring

Component(s) Affected

  • Core / Backend (app, agents, config, providers, utils, local_models)
  • Console (frontend web UI)
  • Channels (DingTalk, Feishu, QQ, Discord, iMessage, etc.)
  • Skills
  • CLI
  • Documentation (website)
  • Tests
  • CI/CD
  • Scripts / Deploy

Checklist

  • I ran pre-commit run --all-files locally and it passes
  • If pre-commit auto-fixed files, I committed those changes and reran checks
  • I ran tests locally (pytest or as relevant) and they pass
  • Documentation updated (if needed)
  • Ready for review

Testing

Backend

  1. Configure one or more markets through Skills market APIs or Console market management.
  2. Validate markets; verify validation failures return structured 4xx/5xx responses.
  3. Load aggregated marketplace list and confirm response contract includes items, market_errors, and meta.
  4. Install a marketplace skill:
  • when not installed: install succeeds
  • when installed: UI asks for overwrite confirmation; confirm path sends overwrite=true

Frontend

  1. Open Skills page and switch to Marketplace tab.
  2. Open Manage Markets modal and add a market.
  3. Confirm URL example text shows openclaw/openclaw.
  4. Confirm new market default path is skills.

Local Verification Evidence

pre-commit run --all-files
Not completed in this session due local pre-commit environment/bootstrap interruption.

pytest tests/unit/ -q
90 passed in local run

npm --prefix console run -s tsc -- --noEmit
pass

Additional Notes

Commits were split atomically (backend, console, docs, follow-up fix), and the same follow-up fix was synchronized on both dual-track branches.

… config model, exception mapping, and tests

- Add SkillMarketSpec, SkillsMarketConfig Pydantic models to config.py
  with support for ttl_sec, overwrite_default, per-market trust/enable/order
- Add /skills/markets (GET/PUT), /skills/markets/validate (POST),
  /skills/marketplace (GET), /skills/marketplace/install (POST) endpoints
- Map _load_market_index() exceptions to structured HTTP errors:
  json.JSONDecodeError/ValueError → 400, RuntimeError/OSError → 502
- Return 409 SKILL_NAME_CONFLICT when skill already installed (overwrite=False)
- Add 12 unit + contract tests covering URL normalisation, path safety,
  exception mapping, and endpoint response shapes
…18n, and overwrite confirmation

- Add API types (SkillsMarketSpec, MarketplaceItem, etc.) and methods
  (getSkillsMarkets, validateSkillsMarket, getMarketplace, installMarketplaceSkill)
- Add marketplace tab to Skills page with skill cards grid and refresh progress bar
- Add market management modal (add/edit/delete markets, validate URLs)
- Add overwrite confirmation dialog: checks installed skills before install;
  shows Modal.confirm with danger button; passes overwrite=true on confirm
- Replace all hardcoded English toast strings with i18n t() calls
- Add 12 new i18n keys under skills.* namespace (en + zh)
…(en + zh)

- Add skills_market section to config.en/zh.md with JSON example and field table
  covering version, cache.ttl_sec, install.overwrite_default, markets[] fields
- Add 'Skills Marketplace (Git repositories)' subsection to skills.en/zh.md
  with 4-step usage walkthrough and notes on config location, auto-scan, cache
- Change market URL example from futuremeng/editor-skills to openclaw/openclaw
- Set new market default path to skills
- Use skills as fallback display value for empty market path input
Copilot AI review requested due to automatic review settings March 15, 2026 13:53
@github-actions github-actions bot added the first-time-contributor PR created by a first time contributor label Mar 15, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a significant new feature: a Git-backed Skills Marketplace. It provides a robust system for users to discover, manage, and install skills from various Git repositories directly within the application. The changes span across the backend, console UI, and documentation, ensuring a seamless experience for configuring market sources, validating their integrity, and handling skill installations, including conflict resolution. This enhancement aims to broaden the accessibility and expandability of available skills.

Highlights

  • Skills Marketplace Introduction: Introduced a new Git-backed Skills Marketplace feature, allowing users to configure multiple market sources, validate entries, browse aggregated skills, and install them with overwrite confirmation.
  • Backend API Enhancements: Added new API endpoints for managing skill markets, validating market configurations, aggregating marketplace items, and installing skills from the marketplace.
  • Console UI Implementation: Developed a new user interface within the console for the Skills Marketplace, including market management, skill browsing, and installation flows.
  • Configuration Updates: Extended the application's configuration to support skills_market settings, defining how skill markets are discovered, cached, and installed.
  • Documentation and Localization: Updated both English and Chinese documentation to reflect the new Skills Marketplace feature and added corresponding localization strings for the console UI.
  • UX Fixes: Implemented a follow-up UX fix to change the market URL example to 'openclaw/openclaw' and set the default market index path to 'skills'.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • console/src/api/modules/skill.ts
    • Added new API calls for fetching, updating, validating skill markets, and interacting with the marketplace.
  • console/src/api/types/skill.ts
    • Defined new TypeScript interfaces for SkillsMarketSpec, SkillsMarketsPayload, ValidateMarketResponse, MarketError, MarketplaceItem, MarketplaceMeta, InstallMarketplacePayload, and InstallSkillResult.
  • console/src/locales/en.json
    • Added numerous new English localization strings for the Skills Marketplace UI, including tabs, search, market management, and installation messages.
  • console/src/locales/zh.json
    • Added numerous new Chinese localization strings for the Skills Marketplace UI, covering similar functionalities as the English version.
  • console/src/pages/Agent/Skills/index.module.less
    • Added new CSS classes and styles to support the layout and appearance of the Skills Marketplace, including market cards, management modals, and progress indicators.
  • console/src/pages/Agent/Skills/index.tsx
    • Implemented the frontend logic and components for the Skills Marketplace, including view switching between local and marketplace skills, market search, market management modal, and skill card rendering.
  • console/src/pages/Agent/Skills/useSkills.ts
    • Extended the useSkills hook to manage state and provide functions for fetching markets, validating markets, saving market configurations, fetching marketplace items, and installing marketplace skills.
  • src/copaw/app/routers/skills.py
    • Added new Pydantic models for SkillsMarketPayload, ValidateMarketRequest, MarketError, MarketplaceItem, and InstallMarketplaceRequest.
    • Implemented helper functions for normalizing Git URLs, validating market configurations, and generating market indexes from directories.
    • Added API endpoints for GET /skills/markets, PUT /skills/markets, POST /skills/markets/validate, GET /skills/marketplace, and POST /skills/marketplace/install.
  • src/copaw/config/config.py
    • Defined new Pydantic models SkillMarketSpec, SkillsMarketCacheConfig, SkillsMarketInstallConfig, and SkillsMarketConfig to structure skill market configurations.
  • tests/unit/app/routers/test_skills_market.py
    • Added new unit tests to verify the functionality of skill market URL normalization, index path validation, item extraction, market validation, and marketplace aggregation/installation endpoints.
  • website/public/docs/config.en.md
    • Updated the English configuration documentation to include details about the new skills_market section and its sub-fields.
  • website/public/docs/config.zh.md
    • Updated the Chinese configuration documentation to include details about the new skills_market section and its sub-fields.
  • website/public/docs/skills.en.md
    • Updated the English skills documentation to describe how to use the new Skills Marketplace feature, including managing markets and installing skills.
  • website/public/docs/skills.zh.md
    • Updated the Chinese skills documentation to describe how to use the new Skills Marketplace feature, including managing markets and installing skills.
Activity
  • The pull request was created by futuremeng.
  • The changes introduce a new feature, update documentation, and include refactoring.
  • Components affected include Core/Backend, Console (frontend web UI), Skills, Documentation, and Tests.
  • The author confirmed running local tests and updating documentation.
  • Backend testing involved configuring and validating markets, loading the aggregated marketplace, and installing skills with overwrite confirmation.
  • Frontend testing involved interacting with the Skills page, managing markets, and verifying URL examples and default paths.
  • Commits were split atomically across backend, console, and docs, with a follow-up fix synchronized on dual-track branches.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive Skills Marketplace feature, allowing users to browse and install skills from configured Git repositories. The changes are extensive, touching the backend API, frontend UI, configuration, tests, and documentation. The implementation is robust, with new API endpoints for managing markets, a rich console UI for browsing and configuration, and thorough backend logic for aggregation and installation. The addition of unit tests for the new backend logic and updates to documentation are also commendable. I've provided a couple of suggestions on the frontend to improve maintainability and user experience.

Comment on lines +353 to +409
const applyMarketUrlDerivation = (id: string) => {
if (!autoParseEnabled) {
return;
}
setMarketDraft((prev) => {
let changed = false;
let changedBranch = "";
let changedPath = "";
const nextDraft = prev.map((item) => {
if (item.id !== id) {
return item;
}

const parsed = parseMarketUrlInput(item.url);
if (!parsed) {
return item;
}

const nextUrl = parsed.repoUrl;
const nextBranch = parsed.branch ?? item.branch;
const nextPath = parsed.path ?? item.path;
const nextName = item.name.trim() ? item.name : parsed.ownerRepo;
changed =
nextUrl !== item.url ||
nextBranch !== item.branch ||
nextPath !== item.path ||
nextName !== item.name;
changedBranch = nextBranch || "";
changedPath = nextPath || "";

return {
...item,
url: nextUrl,
name: nextName,
branch: nextBranch,
path: nextPath,
};
});

setMarketValidation((current) => {
const next = { ...current };
next[id] = { ok: false, warnings: [] };
return next;
});

if (changed) {
message.success(
t("skills.marketUrlAutoParsed", {
branch: changedBranch || "-",
path: changedPath || "-",
}),
);
}

return nextDraft;
});
};
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic inside this function is very similar to the logic inside handleMarketUrlInput (lines 411-471) when autoParseEnabled is true. This duplication can make future maintenance harder as changes would need to be applied in two places.

Consider refactoring this shared logic into a helper function to keep the code DRY (Don't Repeat Yourself) and improve maintainability.

</div>
) : null}
{marketDraft.map((market) => (
<div className={styles.marketManageCard} key={market.id}>
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Using market.id as the key here can lead to a poor user experience. Since the market.id is editable in the form below, changing it will cause React to see a new component, unmounting the old one and mounting a new one. This will cause the input field for the ID to lose focus while the user is typing in it.

To fix this, you should use a stable identifier for the key that does not change during the lifetime of the component in the list. One approach is to generate a unique, internal ID for each draft item when it's created and use that for the key, while the user-editable id remains a separate property.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a Git-backed Skills Marketplace feature to CoPaw, spanning backend APIs/config, Console UI, unit tests, and docs so users can configure multiple market sources, browse aggregated skills, and install skills with conflict/overwrite handling.

Changes:

  • Backend: introduce skills_market config schema and new /skills/markets, /skills/marketplace, and install/validate endpoints with aggregation + caching.
  • Console: add Marketplace tab, market management modal (add/validate/save), marketplace browsing, and install flow with overwrite confirmation.
  • Docs/tests: document marketplace/config fields (EN/ZH) and add unit tests for market parsing, validation, aggregation, and install not-found behavior.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
website/public/docs/skills.zh.md Adds Chinese docs for the Git skills marketplace UI and behavior.
website/public/docs/skills.en.md Adds English docs for the Git skills marketplace UI and behavior.
website/public/docs/config.zh.md Documents skills_market config schema (ZH) with example.
website/public/docs/config.en.md Documents skills_market config schema (EN) with example.
tests/unit/app/routers/test_skills_market.py Adds backend unit tests covering normalization, validation error mapping, and endpoint shapes.
src/copaw/config/config.py Adds Pydantic models for skills_market and wires it into root Config.
src/copaw/app/routers/skills.py Implements market config endpoints, validation, aggregation/caching, and marketplace install endpoint.
console/src/pages/Agent/Skills/useSkills.ts Adds hook logic for markets CRUD, marketplace fetch/refresh, and install flow.
console/src/pages/Agent/Skills/index.tsx Adds Marketplace UI (tab switch, manage markets modal, search, cards, install/view-source).
console/src/pages/Agent/Skills/index.module.less Styles new marketplace and market management UI components.
console/src/locales/zh.json Adds ZH i18n strings for marketplace/markets UI.
console/src/locales/en.json Adds EN i18n strings for marketplace/markets UI.
console/src/api/types/skill.ts Adds API types for markets, marketplace responses, and install payload/results.
console/src/api/modules/skill.ts Adds API client methods for markets, validate, marketplace fetch, and marketplace install.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +506 to +512
if source_path:
branch = source_branch or "main"
source_url = source_url.replace(".git", "")
if "github.com/" in source_url:
install_url = (
f"{source_url}/tree/{branch}/{source_path.lstrip('/')}"
)
Comment on lines +522 to +525
source_url=source_url,
install_url=install_url,
tags=tags if isinstance(tags, list) else [],
),
Comment on lines +588 to +592
meta = {
"refreshed_at": int(now),
"cache_hit": False,
"enabled_market_count": len(enabled_markets),
"success_market_count": success_count,
Comment on lines +91 to +98
const base = (item.install_url || item.source_url || "").trim();
if (!base) {
return "";
}
if (base.endsWith("/SKILL.md") || base.endsWith("SKILL.md")) {
return base;
}
return `${base.replace(/\/$/, "")}/SKILL.md`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

first-time-contributor PR created by a first time contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants