fix(scripts): re-inject .mcp.json as a pointer, not resolved content
reinject_mcp_servers copied .mcp.json's mcpServers into the compiled Copilot
manifest verbatim via jq. apm's own path does not: collect_mcp_servers runs
_sanitize_mcp_servers(), which drops env/headers/authorization and redacts
secret-shaped keys, because copying them into a committed manifest exfiltrates
them into the distributed artefact. The re-injection was the only route around
that sanitizer, and it wrote to a tracked, marketplace-distributed file.
Both host schemas document mcpServers as "string or object -- config path or
inline definitions", so the pointer form is valid and carries no resolved
content. It also preserves the ${VAR} indirection the sanitizer strips.
Also in this pass:
- mktemp+mv left the manifest at 0600 while --check compared content only, so
a real sync silently demoted a mode the gate could not see
- --check --all exited 0 when the marketplace yielded zero plugins, including
on unparseable JSON: the one gate whose work list comes from a generated file
could be silenced by regenerating its own input
- sync_dir took an unguarded $target_dir despite a comment claiming otherwise
- basename '.'/'..' escaped $SCRATCH_ROOT and made bundle selection arbitrary
- path_manifest compared only the exec bit, so check and sync disagreed
- sync-marketplace-mirror.sh fell back to pwd outside a worktree and reported
no drift on a tree it never identified
Mode comparison is deliberately files-only: directory modes come from umask on
one side and checkout on the other and git tracks neither, so comparing them
reports the runner's umask rather than a property of the mirror.
Tests: 44 -> 67 and 15 -> 19 assertions, each verified to fail under the
mutation it exists to catch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7GvKuJfy2WrdBmUttV4DT
This commit is contained in:
@@ -12,7 +12,18 @@ set -euo pipefail
|
||||
# script keeps that legacy mirror byte-identical to .claude-plugin/marketplace.json
|
||||
# instead of letting it silently drift (see issue #90 comment thread).
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
||||
# Hard error, not a `|| pwd` fallback. Every path this script touches hangs off
|
||||
# REPO_ROOT, and both of its exits-0 paths are "the files agree" or "neither file
|
||||
# exists" -- so a REPO_ROOT pointing somewhere that is not this repo reports "no
|
||||
# drift" over a tree it never looked at. Run `--check` from an empty directory
|
||||
# outside any worktree and the fallback made that the literal outcome: rev-parse
|
||||
# failed, REPO_ROOT became $PWD, neither file was there, exit 0. Refusing to guess
|
||||
# is the only answer that cannot be silently wrong; the `-f "$DST"` branch below
|
||||
# covers a genuinely stale mirror, which is a different condition.
|
||||
if ! REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || [[ -z "$REPO_ROOT" ]]; then
|
||||
echo "Error: not inside a git worktree -- cannot locate the repository root, and guessing \$PWD would let --check report \"no drift\" over a tree it never inspected. Run this from within the repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
SRC="$REPO_ROOT/.claude-plugin/marketplace.json"
|
||||
DST="$REPO_ROOT/.github/plugin/marketplace.json"
|
||||
|
||||
@@ -32,9 +43,9 @@ if [[ ! -f "$SRC" ]]; then
|
||||
# A missing source with a surviving mirror is drift, not absence: the mirror
|
||||
# can only be stale (nothing is left for it to be byte-identical to), which is
|
||||
# precisely the silent divergence this script exists to prevent. Exiting 0
|
||||
# here would report "no drift" over a mirror of a file that no longer exists,
|
||||
# and would also swallow the case where REPO_ROOT resolved to the wrong tree —
|
||||
# `git rev-parse --show-toplevel` falls back to `pwd` outside a worktree.
|
||||
# here would report "no drift" over a mirror of a file that no longer exists.
|
||||
# (An unresolvable REPO_ROOT is handled above and is a hard error; this branch
|
||||
# is only about a source file that is genuinely gone from a real worktree.)
|
||||
# scripts/sync-plugin-content.sh --check --all already errors on the same
|
||||
# condition ("requires .../marketplace.json"); this matches it.
|
||||
# Neither file present stays a genuine no-op: nothing to mirror, nothing stale.
|
||||
|
||||
Reference in New Issue
Block a user