adyen/agent-marketplace/agent-marketplace-development
Claude Code and agent skill by adyen/agent-marketplace
- community
- ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
Checking that the SKILL.md file is still in the repository.
How to develop on the agent-marketplace codebase itself: architecture tour, testing workflow, TUI (Bubble Tea) and CLI (Cobra) conventions, and the config/resolver/materialization invariants that every change must preserve. Use when adding features, fixing bugs, or reviewing changes to the agent-marketplace Go binary, running local TUI QA, or maintaining harness compatibility validation. Every TUI change must ship a real-terminal TUI QA journey that proves the changed flow.
Install
npx vskill@latest install adyen/agent-marketplace/agent-marketplace-developmentSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
agent-marketplace-development
How to be productive working on the agent-marketplace Go binary. This is about contributing to the tool itself, not about using it to sync skills (that's the agent-marketplace skill next to this one).
Orient Yourself First
Before touching anything, read these in order:
AGENTS.md— spec authority, build/test/validation gates, command-test
isolation, session-completion rules. It owns the Make targets and test selection rules; this skill does not repeat them.
openspec/specs/— the normative behavior. A behavior change needs an
OpenSpec change with a spec delta, and every scenario needs a // spec: <capability>/<scenario> test binding.
CODING_STANDARDS.md— design, security-boundary, testing, and logging
requirements.
- The
agent-marketplaceskill next door — the user-facing contract.
Then skim:
cmd/agent-marketplace/main.go— Cobra root, subcommand wiring,
TUI launch on bare TTY invocation.
internal/config/v4.go— the strict v4sources/resourcesmodel
(V4Config) and its runtime adapter into the internal Config/RegistryEntry model the resolver consumes. The adapter is not legacy consumer-format support.
internal/config/effective_config.go—LoadEffectiveloads the four
layers (and their includes and locks).
internal/config/merge.go—MergeLayersandresolveInheritedList
(runtime requirement inheritance; not an on-disk consumer schema).
internal/pipeline/pipeline.go—Resolve,ResolveWithExactLockLease,
and Sync: the one pipeline both CLI and TUI call.
internal/resolver/resolver.go— selects which resources are enabled.internal/harness/roots.go,registry.go,destinations.go—
TargetInfo metadata, the Devin/Codex installation adapters, and single-root vs. Codex-partitioned destinations.
internal/tui/state.go—Modelandrowshape used by the TUI.
Build and smoke test
Use the Make targets and scoped TEST_PACKAGES invocations in AGENTS.md. To smoke-test the TUI against the current checkout:
A smoke launch or Go test run does not exercise the real-terminal journeys. Every TUI change must add or extend one; see Every TUI change ships a TUI QA journey and Local TUI QA below.
Pre-commit (.pre-commit-config.yaml) runs make test, make lint, and make build. make lint rewrites files (go mod tidy, go fmt); re-stage and commit again when it does.
Architecture: Two Entry Points, One Data Flow
Both the CLI subcommands and the TUI drive internal/pipeline:
- CLI (
cmd/agent-marketplace/) runs this pipeline once, prints,
exits. Mutating commands (install, remove, update) go through pipeline.Install/Remove/Update, which publish config and the layer lock in one dependency transaction (internal/dependencytxn).
- TUI (
internal/tui/) runs it on startup and after every config
write, keeping a Model in memory and re-rendering.
Everything below this line — resource selection rules, symlink targets, name collision behavior — is shared. Fixes at the internal/* layer fix both surfaces at once. Features that only make sense in one surface belong in cmd/agent-marketplace/ or internal/tui/.
Resolver invariants
resolver.Resolvemay receive catalog entries whoseResourceis nil through
legacy discovery. When the caller has the corresponding IR map, pass it via resolver.WithResources; resolution attaches those resources before nested collection expansion so materialization does not lose the definition.
- Nested collection ownership is selected from configured registry metadata,
not catalog/cache-key iteration order. Required policy and config source/file precedence win; ties prefer the containing URL/ref/path and then stable URL/path ordering. Registry subpaths are slash-separated artifact paths: equivalent spellings (such as ./foo/, repeated separators, or backslashes) share one identity, while config editors retain authored URL/path spelling.
- Nested collection harnesses inherit the containing collection's effective
targets, and an explicitly configured nested list is intersected with them. A nested owner can narrow but never widen its parent; explicit empty remains an opt-out. Include ancestry is branch-local, so shared DAG nodes are valid while an ancestor repeated on one branch is a cycle.
Materialization Invariants
internal/materialize is the authoritative sync/drift engine. It consumes resolver.ResolvedArtifact values with attached IR resources, compiles non-skill artifacts through harness-compilation, and writes target roots for repo and machine scopes.
Preserve these invariants:
- Skills link by default; file mode copies. Default-mode harness skill
entries are symlinks to files/directories under ~/.cache/agent-marketplace. File mode writes regular files/trees for every target through the generic materializer, including Devin regular skill/command trees and subagent files; aggregate ownership reconciliation remains independent of installation mode. TargetInfo.FileCopyKinds is the one declared exception (Factory commands are always copied because the Droid CLI does not follow symlinked command files).
- **Non-skills are compiled artifacts, unless a target declares
otherwise.** Commands, subagents, hooks, and MCP servers are selected like skills and are normally materialized through HCC into the target harness' native files instead of skill symlinks. The exception is declared, never hard-coded: harness.TargetInfo.SkillDirKinds names the kinds that take the skill-directory path instead. Devin and Codex set it for ir.KindCommand, because their commands are skill directories containing SKILL.md with x-agent-marketplace-kind: command. Default mode links those directories; file mode writes them as regular trees for both targets through the generic materializer.
- No harness-specific skill-link allowlists. Decide whether a
resource is a skill by the compiled/source artifact shape, the resource kind, and declarative harness.TargetInfo metadata — not by hard-coded target names like Claude, Factory, Cursor, Windsurf, Gemini, Devin, or Codex.
- `AggregateFiles` must match what the compilers emit.
harness.TargetInfo.AggregateFiles is the single declaration both materialization routing and pipeline.CollectManagedPaths (safety backup coverage) read for which files a target merges into, per scope. Codex, Devin, and Claude derive the set from their registered native-layout descriptor in pkg/harness-compilation/target/native_layout.go, the topology authority; the remaining targets declare it literally in internal/harness/roots.go. Either way the value is not editorial: it must equal "every compiled artifact with MergeWithExisting == true, at the output-root-relative path the planner writes it to, in that scope". materialize.TestAggregateFilesMatchMaterializedMergeArtifacts measures that set from real compilation and fails on any difference in either direction — never satisfy it by restating a list. An undeclared aggregate is a file mutated with no safety backup.
- Shared aggregate files use an explicit reconciliation policy.
Marker-reconciled targets use their declared marker metadata and remain eligible for marker-based stale-entry pruning. Devin and Codex instead declare harness.TargetInfo.OwnershipReconciledAggregates and are fenced out of the marker-strip prune walk by aggregateProtectedPaths on that field alone. They go through internal/ownership plus their format-preserving JSONC/TOML patchers, in the sequence the ownership package doc names (Open, Recover once before any mutation, Proof, Classify, patch, Apply). Never inject a _managed_by marker into an externally reconciled file and never infer its ownership from bytes: ownership is proven from durable state under $XDG_STATE_HOME/agent-marketplace, and missing or corrupt state must fail closed (every entry unmanaged; preserve everything, prune nothing). Gemini MCP servers in settings.json use the same ownership store (internal/materialize/gemini_native.go) while Gemini hooks keep markers; aggregates installed outside the target root (Claude .mcp.json / ~/.claude.json, Gemini settings.json, Windsurf hooks) are routed by nativeAggregateInstalls in internal/harness/native_aggregates.go.
- Codex has two resolved destinations per scope. Repo output splits
between <repo>/.agents and <repo>/.codex; machine output splits between ~/.agents and an absolute $CODEX_HOME (default ~/.codex). Route artifacts by their .agents/.codex prefix through ResolveDestinations; never flatten Codex into one root or let a repo symlink escape the repository. .agents/skills alone is not Codex installation evidence.
- Installation mode is generic distribution policy. Every target uses
the same file-copy or symlink materializer, selected by configuration. Compilers describe native artifact paths and contents, not installation mode. Shared-entry reconciliation remains independent: never infer OwnershipReconciledAggregates from how resource files are installed.
- Gemini is not a skill-link exception. Gemini CLI discovers native
Agent Skills from .gemini/skills and the generic .agents/skills alias; within a tier, .agents/skills takes precedence over .gemini/skills. Treat Gemini skill directories like other native skill-directory harnesses unless current vendor docs prove otherwise.
- Keep pruning scoped. Never run stale-file pruning at a repo root
or home root. Split generated artifacts into safe component roots (for example skills, commands, agents, hooks, .windsurf) before pruning.
- Cache namespaces matter. If materialization creates derived cache
entries under ~/.cache/agent-marketplace, protect that namespace from agent-marketplace gc or installed symlinks can become broken.
- Test one invariant across all targets. When the same behavior applies to
several harnesses, write a table-driven regression test spanning all affected targets before adding target-specific branches.
Config Invariants You Must Not Break
These are load-bearing. Every PR must preserve them.
Four-layer precedence (most → least specific)
.agents/config.local.yaml(gitignored personal overrides; no
harnesses or allowlists).
.agents/config.yaml(committed repo config).~/.agents/config.yaml(user-personal machine config)./etc/agent-marketplace/config.yaml(organization-managed machine config;
root-owned trust rules; required: true groups are org-mandatory).
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/agent-marketplace-development/SKILL.md
Popularity
- Repository stars
- 15
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Extension points
hookPre/post lifecycle hooks
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/adyen/agent-marketplace/agent-marketplace-development)