feat: replace marketplace with repo-first apc install (GitHub skill installer) - #13
Merged
Conversation
The marketplace feature (source management + skill install from GitHub) is outdated and no longer needed. Removes all references: - Delete src/marketplace.py — marketplace source management module - Delete src/share.py — install + marketplace Click commands - Remove apc install command from CLI (main.py) - Remove marketplace and share from pyproject.toml py-modules - Move get_skills_dir() into config.py (still used by sync_helpers) - Update sync_helpers.py import to use config.get_skills_dir - Delete tests/test_marketplace.py - Remove TestInstall from tests/test_docker_integration.py Closes #1
Keep the install command but remove the marketplace concept entirely: - apc install <skill> still works (defaults to anthropics/skills) - apc install <skill> --repo owner/repo still works for custom sources - No apc marketplace add/list/delete — source management is gone marketplace.py split into: - src/skills.py — skill fetching/install logic (no source CRUD) - src/share.py — just the install Click command
apc install now works like npx skills add — repo is the primary arg,
with options to list, filter by skill name, and target specific agents.
Usage:
apc install owner/repo --list
apc install owner/repo --skill frontend-design
apc install owner/repo --skill frontend-design --skill skill-creator
apc install owner/repo --skill '*'
apc install owner/repo --all
apc install owner/repo --skill frontend-design -a claude-code -a cursor
apc install owner/repo --all -a claude-code -y
apc install owner/repo --agent '*' --skill frontend-design
Changes:
- REPO is now the first arg (not skill name)
- --list: shows available skills without installing
- --skill / -s: one or more skill names to install ('*' = all)
- --all: install everything in the repo
- --agent / -a: target specific tools ('*' = all detected)
- -y / --yes: non-interactive mode for CI/CD
- skills.py: added list_skills_in_repo() via GitHub tree API
- No --repo flag needed — repo is always the first positional arg
8 tests covering: - Invalid repo format rejection (URL, no-slash) - --list with mocked GitHub response - --list on empty repo - Single skill install (mocked fetch + agent apply) - Skill not found in repo - --all installs everything from repo - -y flag skips confirmation prompts Patches target share.* (not skills.*) since share.py imports at load time.
Bugs fixed: - openclaw applier missing 'override' param on apply_mcp_servers (broke apc sync for any openclaw target) - skill show crashing with MarkupError when body contains Rich markup characters like [/* content */] — now escapes body before rendering Tests added (TestInstallThenSync): - install writes skill to local cache and ~/.apc/skills/ - install creates correct SKILL.md source file - sync --dry-run picks up installed skills from ~/.apc/skills/ - install multiple skills → skill list shows all of them
share.py no longer fits — the file only contains the install command. Renamed to install.py for clarity. Updated references in main.py, pyproject.toml, and tests.
* Add apc export/import with age-encrypted secrets, fix MCP secrets bug
Implement portable config migration between machines via `apc export`
and `apc import`. Secrets (API keys, MCP tokens) are field-level
encrypted with age (pyrage) so exports can safely live in Git repos.
Non-secret data stays in cleartext for diff-friendliness.
Also fix a bug where sync_helpers.py always passed {} for secrets to
appliers, so MCP server env placeholders (${TOKEN}) were never resolved
from the OS keychain during sync.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix ruff formatting in export_import.py and test_docker_integration.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Test changes: - Replace all mock/patch in TestInstall and TestInstallThenSync with real GitHub network calls against anthropics/skills - Tests now verify actual file-system results (SKILL.md written, .mdc symlinked into tool dir, skill list, status after sync) Applier fix: - cursor.py: replace module-level Path.home() constants (evaluated once at import) with lazy _cursor_dir/rules/mcp_json() helper functions evaluated at call time — required for HOME isolation in tests - SKILL_DIR changed from class attribute to @Property so it respects the current /Users/frank at sync time Unit test fix: - test_appliers.py: patch _cursor_rules_dir/_cursor_mcp_json functions instead of removed module-level constants
…name - pyproject.toml: merged module list — kept install/skills (our rename), added export_import (from main), dropped marketplace/share - src/main.py: kept both 'from install import install' and 'from export_import import export_cmd, import_cmd' - src/sync_helpers.py: kept 'from skills import get_skills_dir' (our rename from marketplace) and added 'from secrets_manager import retrieve_secret' (from main) - src/export_import.py: updated marketplace→skills import (consistency with branch rename), fixed ruff import order 207 tests passing, 0 failures, ruff clean
.cursor/rules/*.mdc are generated output from apc sync — they should never be committed. Added .cursor/, .claude/, .gemini/, .codeium/ to .gitignore so sync output stays local.
Previously 41 tests verified terminal output only. Now 82/93 tests assert on actual file-system side effects: - TestStatus: detect_* tests check tool dirs exist (.claude/, .cursor/, etc.) - TestCollect: verify cache/ dir + all 3 JSON files created - TestSkill: verify skills.json contains expected entries - TestMemory: verify memory.json written and contains added entries - TestMcp: verify mcp_servers.json reflects add/remove operations - TestSync: verify .claude.json mcpServers written; .cursor/rules/*.mdc created - TestSubSync: verify mcp/skill sync writes to tool dirs - TestInstall: verify SKILL.md written to ~/.apc/skills/<name>/ - TestInstallThenSync: verify .mdc files land in cursor rules dir - TestExport: verify export dir structure created - TestImport: verify cache files restored - TestConfigure: verify auth-profiles.json written with correct provider 5 tests intentionally output-only (error/rejection paths): test_exits_zero, test_detects_copilot, test_mcp_remove_nonexistent, test_install_invalid_repo_url, test_install_nonexistent_skill
FZ2000
force-pushed
the
chore/remove-marketplace
branch
from
March 6, 2026 05:50
cb70e00 to
8692331
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes the old marketplace/share system and replaces it with a cleaner repo-first
apc installcommand that fetches skills directly from any GitHub repository.What changed
Removed
src/marketplace.py— marketplace source managementsrc/share.py— oldapc install/apc marketplacecommandstests/test_marketplace.py— marketplace unit testsNew:
src/install.py— Repo-first GitHub skill installer--list— browse available skills in any GitHub repo before installing--skill NAME— install one or more specific skills (repeatable flag)--all— install every skill in the repo-t TOOL/--target TOOL— target a specific tool (or*for all detected)-y— skip confirmation prompt (useful for scripting)Skills are fetched from
https://github.com/<owner>/<repo>/tree/main/<skill>/SKILL.mdand written to~/.apc/skills/<name>/SKILL.mdas the source of truth.Fixed:
src/appliers/cursor.py— lazy path resolutionModule-level
CURSOR_DIR,CURSOR_RULES_DIR,CURSOR_MCP_JSONwere evaluated once at import time againstPath.home(), making HOME isolation in tests impossible. Replaced with lazy helper functions (_cursor_dir(),_cursor_rules_dir(),_cursor_mcp_json()) evaluated at call time.SKILL_DIRchanged from a class attribute to a@property.Tests:
tests/test_docker_integration.pyReplaced all mocked
TestInstallandTestInstallThenSynctests with real end-to-end flows:anthropics/skills.mdcsynced to cursor tool dir)monkeypatch.setenv— no mocks, no patchingResult
apc install,apc skill,apc sync,apc collect,apc statusall workingapc installare immediately available toapc sync