Skip to content

fix(marketplace): restore gaia entry lost to duplicate JSON keys#119

Merged
lsetiawan merged 2 commits into
mainfrom
fix/marketplace-duplicate-key-scan-coverage
Jul 9, 2026
Merged

fix(marketplace): restore gaia entry lost to duplicate JSON keys#119
lsetiawan merged 2 commits into
mainfrom
fix/marketplace-duplicate-key-scan-coverage

Conversation

@lsetiawan

@lsetiawan lsetiawan commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

  • .claude-plugin/marketplace.json had a single object with duplicate keys: gaia-data-downloader's name/source/description were merged into the zarr-chunk-optimization object. JSON last-wins parsing collapsed the two into one entry, so gaia-data-downloader silently vanished from the catalog and zarr's keywords were overwritten with gaia's.
  • This broke copilot plugin install gaia-data-downloader@rse-plugins (used in .devcontainer/post-create.sh) — see bug: plugin@marketplace not working for gaia_data_downloader #105 — and, because every CI security scan builds its target list from jq -r '.plugins[].source', it also dropped gaia's files out of scan scope while it was missing from the catalog.
  • Fix restores the catalog and adds a duplicate-key CI guard (jq empty accepts duplicate keys, so this defect class passed validation). With the entry restored and the guard in place, gaia stays in the catalog and therefore in scan scope.

Changes

Catalog (.claude-plugin/marketplace.json)

  • Split the merged object into two well-formed entries; jq -r '.plugins[].name' now lists 9 plugins including both gaia-data-downloader and zarr-chunk-optimization.
  • Restored each plugin's own keywords (zarr had been carrying gaia's keywords after the merge). Values recovered from git history (feat: Add gaia-data-downloader community plugin #77) and the plugins' plugin.json manifests.

CI (.github/workflows/validate-plugins.yml)

  • New "Check for duplicate JSON keys" step running .github/scripts/check_duplicate_json_keys.py, which uses Python's object_pairs_hook to reject duplicate keys (jq empty cannot detect them).
  • Added community-plugins/** and .github/scripts/** to the pull_request paths: filter so community-plugin and CI-script changes trigger the workflow (previously community-only PRs skipped it entirely).

New file

  • .github/scripts/check_duplicate_json_keys.py — walks all *.json (skipping tsconfig*, .git, node_modules) and fails on any duplicate key, emitting a GitHub Actions error annotation.

Test plan

  • jq -r '.plugins[].name' lists 9 plugins incl. gaia-data-downloader and zarr-chunk-optimization
  • jq -r '.plugins[].source' includes ./community-plugins/gaia-data-downloader; zarr keywords restored to its own (not gaia's)
  • Duplicate-key guard fails on the pre-fix file and passes across the whole repo (23 JSON files)
  • Catalog-based security scans verified clean over all 9 cataloged sources (regex checked with GNU \s semantics)
  • Structure/catalog validation passes for all 9 sources (each has plugin.json + README.md)
  • CI Validate Plugins workflow green on this PR

Notes / follow-up

  • The security scans remain catalog-based by design. I explored switching them to enumerate plugins/* + community-plugins/* from the filesystem (so unlisted plugins are scanned too), but that pulls the unlisted supply-chain-security plugin into scope, whose incident-response runbooks legitimately document attack patterns (base64 -d, eval(...)) and trip the dangerous-pattern heuristics. Since this repo's plugins are largely Markdown, cleanly separating security documentation from dangerous code is a separate design change and is left as a follow-up. The duplicate-key guard already closes the reported gap (a plugin can no longer silently drop out of the catalog).

Closes #105

🤖 Generated with Claude Code

lsetiawan added 2 commits July 8, 2026 16:47
The gaia-data-downloader entry in .claude-plugin/marketplace.json was
merged into the zarr-chunk-optimization object, so that one object held
duplicate "name"/"source"/"description" keys. JSON last-wins parsing
collapsed the two into a single entry (zarr), silently dropping
gaia-data-downloader from the catalog; the merge also overwrote
zarr-chunk-optimization's keywords with gaia's.

Impacts:
- `copilot plugin install gaia-data-downloader@rse-plugins` failed with
  "not found in marketplace", breaking .devcontainer/post-create.sh (#105).
- Security: every scan in validate-plugins.yml built its target list from
  `jq -r '.plugins[].source'` of the catalog, so gaia's files were excluded
  from the secret, dangerous-pattern, suspicious-URL, and MCP dependency
  scans. A secret or malicious pattern under community-plugins/
  gaia-data-downloader/ would have passed CI unscanned.

Fixes:
- Split the merged object into well-formed gaia-data-downloader and
  zarr-chunk-optimization entries, restoring each plugin's own keywords.
- Add a duplicate-JSON-key CI guard (check_duplicate_json_keys.py); the
  existing `jq empty` check accepts duplicate keys.
- Enumerate plugin directories from the filesystem (plugins/*,
  community-plugins/*) in the four security scans instead of the catalog,
  so unlisted/mis-cataloged plugins are still scanned. This newly covers
  containerization, supply-chain-security, and uiux-design-team, which the
  catalog-driven scans had been skipping entirely.
- Add community-plugins/** and .github/scripts/** to the pull_request
  paths filter so community-only changes trigger these checks.
Enumerating plugins/* and community-plugins/* from the filesystem pulled the
unlisted supply-chain-security plugin into scan scope, whose incident-response
runbooks legitimately document attack patterns (e.g. `base64 -d`, `eval(...)`),
tripping the dangerous-pattern scan and failing CI.

Revert the four security scans to the catalog-based target list. The new
duplicate-key guard already prevents a plugin from silently dropping out of the
catalog (and thus out of scan scope), which was the actual reported defect, so
gaia is scanned again now that it is a valid catalog entry.

Extending scan coverage to unlisted plugins is worthwhile but requires the
heuristics to tell security documentation apart from dangerous code; left as a
follow-up rather than weakening the checks here.
@lsetiawan
lsetiawan merged commit 9a74bb3 into main Jul 9, 2026
2 checks passed
@lsetiawan
lsetiawan deleted the fix/marketplace-duplicate-key-scan-coverage branch July 9, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: plugin@marketplace not working for gaia_data_downloader

1 participant