{"id":"e47db1a1-2da4-4e01-b95a-d81440ee3525","shortId":"mWbwhX","kind":"skill","title":"agent-supply-chain","tagline":"Verify supply chain integrity for AI agent plugins, tools, and dependencies. Use this skill when:\n- Generating SHA-256 integrity manifests for agent plugins or tool packages\n- Verifying that installed plugins match their published manifests\n- Detecting tampered, modified, or untr","description":"# Agent Supply Chain Integrity\n\nGenerate and verify integrity manifests for AI agent plugins and tools. Detect tampering, enforce version pinning, and establish supply chain provenance.\n\n## Overview\n\nAgent plugins and MCP servers have the same supply chain risks as npm packages or container images — except the ecosystem has no equivalent of npm provenance, Sigstore, or SLSA. This skill fills that gap.\n\n```\nPlugin Directory → Hash All Files (SHA-256) → Generate INTEGRITY.json\n                                                    ↓\nLater: Plugin Directory → Re-Hash Files → Compare Against INTEGRITY.json\n                                                    ↓\n                                          Match? VERIFIED : TAMPERED\n```\n\n## When to Use\n\n- Before promoting a plugin from development to production\n- During code review of plugin PRs\n- As a CI step to verify no files were modified after review\n- When auditing third-party agent tools or MCP servers\n- Building a plugin marketplace with integrity requirements\n\n---\n\n## Pattern 1: Generate Integrity Manifest\n\nCreate a deterministic `INTEGRITY.json` with SHA-256 hashes of all plugin files.\n\n```python\nimport hashlib\nimport json\nfrom datetime import datetime, timezone\nfrom pathlib import Path\n\nEXCLUDE_DIRS = {\".git\", \"__pycache__\", \"node_modules\", \".venv\", \".pytest_cache\"}\nEXCLUDE_FILES = {\".DS_Store\", \"Thumbs.db\", \"INTEGRITY.json\"}\n\ndef hash_file(path: Path) -> str:\n    \"\"\"Compute SHA-256 hex digest of a file.\"\"\"\n    h = hashlib.sha256()\n    with open(path, \"rb\") as f:\n        for chunk in iter(lambda: f.read(8192), b\"\"):\n            h.update(chunk)\n    return h.hexdigest()\n\ndef generate_manifest(plugin_dir: str) -> dict:\n    \"\"\"Generate an integrity manifest for a plugin directory.\"\"\"\n    root = Path(plugin_dir)\n    files = {}\n\n    for path in sorted(root.rglob(\"*\")):\n        if not path.is_file():\n            continue\n        if path.name in EXCLUDE_FILES:\n            continue\n        if any(part in EXCLUDE_DIRS for part in path.relative_to(root).parts):\n            continue\n        rel = path.relative_to(root).as_posix()\n        files[rel] = hash_file(path)\n\n    # Chain hash: SHA-256 of all file hashes concatenated in sorted order\n    chain = hashlib.sha256()\n    for key in sorted(files.keys()):\n        chain.update(files[key].encode(\"ascii\"))\n\n    manifest = {\n        \"plugin_name\": root.name,\n        \"generated_at\": datetime.now(timezone.utc).isoformat(),\n        \"algorithm\": \"sha256\",\n        \"file_count\": len(files),\n        \"files\": files,\n        \"manifest_hash\": chain.hexdigest(),\n    }\n    return manifest\n\n# Generate and save\nmanifest = generate_manifest(\"my-plugin/\")\nPath(\"my-plugin/INTEGRITY.json\").write_text(\n    json.dumps(manifest, indent=2) + \"\\n\"\n)\nprint(f\"Generated manifest: {manifest['file_count']} files, \"\n      f\"hash: {manifest['manifest_hash'][:16]}...\")\n```\n\n**Output (`INTEGRITY.json`):**\n```json\n{\n  \"plugin_name\": \"my-plugin\",\n  \"generated_at\": \"2026-04-01T03:00:00+00:00\",\n  \"algorithm\": \"sha256\",\n  \"file_count\": 12,\n  \"files\": {\n    \".claude-plugin/plugin.json\": \"a1b2c3d4...\",\n    \"README.md\": \"e5f6a7b8...\",\n    \"skills/search/SKILL.md\": \"c9d0e1f2...\",\n    \"agency.json\": \"3a4b5c6d...\"\n  },\n  \"manifest_hash\": \"7e8f9a0b1c2d3e4f...\"\n}\n```\n\n---\n\n## Pattern 2: Verify Integrity\n\nCheck that current files match the manifest.\n\n```python\n# Requires: hash_file() and generate_manifest() from Pattern 1 above\nimport json\nfrom pathlib import Path\n\ndef verify_manifest(plugin_dir: str) -> tuple[bool, list[str]]:\n    \"\"\"Verify plugin files against INTEGRITY.json.\"\"\"\n    root = Path(plugin_dir)\n    manifest_path = root / \"INTEGRITY.json\"\n\n    if not manifest_path.exists():\n        return False, [\"INTEGRITY.json not found\"]\n\n    manifest = json.loads(manifest_path.read_text())\n    recorded = manifest.get(\"files\", {})\n    errors = []\n\n    # Check recorded files\n    for rel_path, expected_hash in recorded.items():\n        full = root / rel_path\n        if not full.exists():\n            errors.append(f\"MISSING: {rel_path}\")\n            continue\n        actual = hash_file(full)\n        if actual != expected_hash:\n            errors.append(f\"MODIFIED: {rel_path}\")\n\n    # Check for new untracked files\n    current = generate_manifest(plugin_dir)\n    for rel_path in current[\"files\"]:\n        if rel_path not in recorded:\n            errors.append(f\"UNTRACKED: {rel_path}\")\n\n    return len(errors) == 0, errors\n\n# Verify\npassed, errors = verify_manifest(\"my-plugin/\")\nif passed:\n    print(\"VERIFIED: All files match manifest\")\nelse:\n    print(f\"FAILED: {len(errors)} issue(s)\")\n    for e in errors:\n        print(f\"  {e}\")\n```\n\n**Output on tampered plugin:**\n```\nFAILED: 3 issue(s)\n  MODIFIED: skills/search/SKILL.md\n  MISSING: agency.json\n  UNTRACKED: backdoor.py\n```\n\n---\n\n## Pattern 3: Dependency Version Audit\n\nCheck that agent dependencies use pinned versions.\n\n```python\nimport re\n\ndef audit_versions(config_path: str) -> list[dict]:\n    \"\"\"Audit dependency version pinning in a config file.\"\"\"\n    findings = []\n    path = Path(config_path)\n    content = path.read_text()\n\n    if path.name == \"package.json\":\n        data = json.loads(content)\n        for section in (\"dependencies\", \"devDependencies\"):\n            for pkg, ver in data.get(section, {}).items():\n                if ver.startswith(\"^\") or ver.startswith(\"~\") or ver == \"*\" or ver == \"latest\":\n                    findings.append({\n                        \"package\": pkg,\n                        \"version\": ver,\n                        \"severity\": \"HIGH\" if ver in (\"*\", \"latest\") else \"MEDIUM\",\n                        \"fix\": f'Pin to exact: \"{pkg}\": \"{ver.lstrip(\"^~\")}\"'\n                    })\n\n    elif path.name in (\"requirements.txt\", \"pyproject.toml\"):\n        for line in content.splitlines():\n            line = line.strip()\n            if \">=\" in line and \"<\" not in line:\n                findings.append({\n                    \"package\": line.split(\">=\")[0].strip(),\n                    \"version\": line,\n                    \"severity\": \"MEDIUM\",\n                    \"fix\": f\"Add upper bound: {line},<next_major\"\n                })\n\n    return findings\n```\n\n---\n\n## Pattern 4: Promotion Gate\n\nUse integrity verification as a gate before promoting plugins.\n\n```python\ndef promotion_check(plugin_dir: str) -> dict:\n    \"\"\"Check if a plugin is ready for production promotion.\"\"\"\n    checks = {}\n\n    # 1. Integrity manifest exists and verifies\n    passed, errors = verify_manifest(plugin_dir)\n    checks[\"integrity\"] = {\n        \"passed\": passed,\n        \"errors\": errors\n    }\n\n    # 2. Required files exist\n    root = Path(plugin_dir)\n    required = [\"README.md\"]\n    missing = [f for f in required if not (root / f).exists()]\n\n    # Require at least one plugin manifest (supports both layouts)\n    manifest_paths = [\n        root / \".github/plugin/plugin.json\",\n        root / \".claude-plugin/plugin.json\",\n    ]\n    if not any(p.exists() for p in manifest_paths):\n        missing.append(\".github/plugin/plugin.json (or .claude-plugin/plugin.json)\")\n\n    checks[\"required_files\"] = {\n        \"passed\": len(missing) == 0,\n        \"missing\": missing\n    }\n\n    # 3. No unpinned dependencies\n    mcp_path = root / \".mcp.json\"\n    if mcp_path.exists():\n        config = json.loads(mcp_path.read_text())\n        unpinned = []\n        for server in config.get(\"mcpServers\", {}).values():\n            if isinstance(server, dict):\n                for arg in server.get(\"args\", []):\n                    if isinstance(arg, str) and \"@latest\" in arg:\n                        unpinned.append(arg)\n        checks[\"pinned_deps\"] = {\n            \"passed\": len(unpinned) == 0,\n            \"unpinned\": unpinned\n        }\n\n    # Overall\n    all_passed = all(c[\"passed\"] for c in checks.values())\n    return {\"ready\": all_passed, \"checks\": checks}\n\nresult = promotion_check(\"my-plugin/\")\nif result[\"ready\"]:\n    print(\"Plugin is ready for production promotion\")\nelse:\n    print(\"Plugin NOT ready:\")\n    for name, check in result[\"checks\"].items():\n        if not check[\"passed\"]:\n            print(f\"  FAILED: {name}\")\n```\n\n---\n\n## CI Integration\n\nAdd to your GitHub Actions workflow:\n\n```yaml\n- name: Verify plugin integrity\n  run: |\n    PLUGIN_DIR=\"${{ matrix.plugin || '.' }}\"\n    cd \"$PLUGIN_DIR\"\n    python -c \"\n    from pathlib import Path\n    import json, hashlib, sys\n\n    def hash_file(p):\n        h = hashlib.sha256()\n        with open(p, 'rb') as f:\n            for c in iter(lambda: f.read(8192), b''):\n                h.update(c)\n        return h.hexdigest()\n\n    manifest = json.loads(Path('INTEGRITY.json').read_text())\n    errors = []\n    for rel, expected in manifest['files'].items():\n        p = Path(rel)\n        if not p.exists():\n            errors.append(f'MISSING: {rel}')\n        elif hash_file(p) != expected:\n            errors.append(f'MODIFIED: {rel}')\n    if errors:\n        for e in errors:\n            print(f'::error::{e}')\n        sys.exit(1)\n    print(f'Verified {len(manifest[\\\"files\\\"])} files')\n    \"\n```\n\n---\n\n## Best Practices\n\n| Practice | Rationale |\n|----------|-----------|\n| **Generate manifest after code review** | Ensures reviewed code matches production code |\n| **Include manifest in the PR** | Reviewers can verify what was hashed |\n| **Verify in CI before deploy** | Catches post-review modifications |\n| **Chain hash for tamper evidence** | Single hash represents entire plugin state |\n| **Exclude build artifacts** | Only hash source files — .git, __pycache__, node_modules excluded |\n| **Pin all dependency versions** | Unpinned deps = different code on every install |\n\n---\n\n## Related Resources\n\n- [OpenSSF SLSA](https://slsa.dev/) — Supply-chain Levels for Software Artifacts\n- [npm Provenance](https://docs.npmjs.com/generating-provenance-statements) — Sigstore-based package provenance\n- [Agent Governance Toolkit](https://github.com/microsoft/agent-governance-toolkit) — Includes integrity verification and plugin signing\n- [OWASP ASI-09: Supply Chain Integrity](https://owasp.org/www-project-agentic-ai-threats/)","tags":["agent","supply","chain","awesome","copilot","github","agent-skills","agents","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"capabilities":["skill","source-github","skill-agent-supply-chain","topic-agent-skills","topic-agents","topic-awesome","topic-custom-agents","topic-github-copilot","topic-hacktoberfest","topic-prompt-engineering"],"categories":["awesome-copilot"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/github/awesome-copilot/agent-supply-chain","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add github/awesome-copilot","source_repo":"https://github.com/github/awesome-copilot","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 30743 github stars · SKILL.md body (10,056 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T00:52:03.176Z","embedding":null,"createdAt":"2026-04-18T21:48:07.509Z","updatedAt":"2026-04-22T00:52:03.176Z","lastSeenAt":"2026-04-22T00:52:03.176Z","tsv":"'+00':410 '-01':406 '-04':405 '-09':1164 '-256':22,110,183,226,316 '/)':1132 '/generating-provenance-statements)':1144 '/integrity.json':372 '/microsoft/agent-governance-toolkit)':1155 '/plugin.json':421,823,839 '/www-project-agentic-ai-threats/)':1170 '0':566,720,846,895 '00':408,409,411 '1':173,453,767,1048 '12':416 '16':393 '2':378,434,785 '2026':404 '3':604,614,849 '3a4b5c6d':428 '4':737 '7e8':431 '8192':246,998 'a1b2c3d4':422 'action':956 'actual':523,528 'add':728,952 'agency.json':427,610 'agent':2,11,26,44,55,70,160,620,1150 'agent-supply-chain':1 'ai':10,54 'algorithm':346,412 'arg':875,878,881,886,888 'artifact':1105,1139 'ascii':336 'asi':1163 'audit':156,617,629,636 'b':247,999 'backdoor.py':612 'base':1147 'best':1056 'bool':468 'bound':730 'build':165,1104 'c':902,905,971,993,1001 'c9d0e1f2':426 'cach':211 'catch':1087 'cd':967 'chain':4,7,46,67,79,313,325,1092,1135,1166 'chain.hexdigest':356 'chain.update':332 'check':437,500,536,618,752,757,766,779,840,889,912,913,916,937,940,944 'checks.values':907 'chunk':241,249 'ci':145,950,1084 'claud':419,821,837 'claude-plugin':418,820,836 'code':138,1063,1067,1070,1122 'compar':120 'comput':224 'concaten':321 'config':631,642,647,859 'config.get':867 'contain':85 'content':649,657 'content.splitlines':707 'continu':281,287,301,522 'count':349,386,415 'creat':177 'current':439,541,550 'data':655 'data.get':667 'datetim':195,197 'datetime.now':343 'def':218,252,461,628,750,980 'dep':891,1120 'depend':15,615,621,637,661,852,1117 'deploy':1086 'detect':39,59 'determinist':179 'devdepend':662 'develop':134 'dict':258,635,756,873 'differ':1121 'digest':228 'dir':204,256,270,293,465,479,545,754,778,792,965,969 'directori':105,115,266 'docs.npmjs.com':1143 'docs.npmjs.com/generating-provenance-statements)':1142 'ds':214 'e':593,598,1040,1046 'e5f6a7b8':424 'ecosystem':89 'elif':699,1028 'els':584,690,930 'encod':335 'enforc':61 'ensur':1065 'entir':1100 'equival':92 'error':499,565,567,570,589,595,774,783,784,1010,1038,1042,1045 'errors.append':517,531,558,1024,1033 'establish':65 'everi':1124 'evid':1096 'exact':696 'except':87 'exclud':203,212,285,292,1103,1114 'exist':770,788,805 'expect':506,529,1013,1032 'f':239,381,388,518,532,559,586,597,693,727,796,798,804,947,991,1025,1034,1044,1050 'f.read':245,997 'f9a0b1c2d3e4f':432 'fail':587,603,948 'fals':488 'file':108,119,150,188,213,220,231,271,280,286,308,311,319,333,348,351,352,353,385,387,414,417,440,447,473,498,502,525,540,551,581,643,787,842,982,1016,1030,1054,1055,1109 'files.keys':331 'fill':101 'find':644,735 'findings.append':679,717 'fix':692,726 'found':491 'full':510,526 'full.exists':516 'gap':103 'gate':739,745 'generat':20,48,111,174,253,259,341,359,363,382,402,449,542,1060 'git':205,1110 'github':955 'github.com':1154 'github.com/microsoft/agent-governance-toolkit)':1153 'github/plugin/plugin.json':818,834 'govern':1151 'h':232,984 'h.hexdigest':251,1003 'h.update':248,1000 'hash':106,118,184,219,310,314,320,355,389,392,430,446,507,524,530,981,1029,1081,1093,1098,1107 'hashlib':191,978 'hashlib.sha256':233,326,985 'hex':227 'high':685 'imag':86 'import':190,192,196,201,455,459,626,974,976 'includ':1071,1156 'indent':377 'instal':33,1125 'integr':8,23,47,51,170,175,261,436,741,768,780,951,962,1157,1167 'integrity.json':112,122,180,217,395,475,483,489,1007 'isinst':871,880 'isoformat':345 'issu':590,605 'item':669,941,1017 'iter':243,995 'json':193,396,456,977 'json.dumps':375 'json.loads':493,656,860,1005 'key':328,334 'lambda':244,996 'later':113 'latest':678,689,884 'layout':814 'least':808 'len':350,564,588,844,893,1052 'level':1136 'line':705,708,712,716,723,731 'line.split':719 'line.strip':709 'list':469,634 'major':733 'manifest':24,38,52,176,254,262,337,354,358,362,364,376,383,384,390,391,429,443,450,463,480,492,543,572,583,769,776,811,815,831,1004,1015,1053,1061,1072 'manifest.get':497 'manifest_path.exists':486 'manifest_path.read':494 'marketplac':168 'match':35,123,441,582,1068 'matrix.plugin':966 'mcp':73,163,853 'mcp.json':856 'mcp_path.exists':858 'mcp_path.read':861 'mcpserver':868 'medium':691,725 'miss':519,609,795,845,847,848,1026 'missing.append':833 'modif':1091 'modifi':41,152,533,607,1035 'modul':208,1113 'my-plugin':365,369,399,573,917 'n':379 'name':339,398,936,949,959 'new':538 'next':732 'node':207,1112 'npm':82,94,1140 'one':809 'open':235,987 'openssf':1128 'order':324 'output':394,599 'overal':898 'overview':69 'owasp':1162 'owasp.org':1169 'owasp.org/www-project-agentic-ai-threats/)':1168 'p':829,983,988,1018,1031 'p.exists':827,1023 'packag':30,83,680,718,1148 'package.json':654 'part':290,295,300 'parti':159 'pass':569,577,773,781,782,843,892,900,903,911,945 'path':202,221,222,236,268,273,312,368,460,477,481,505,513,521,535,548,554,562,632,645,646,648,790,816,832,854,975,1006,1019 'path.is':279 'path.name':283,653,700 'path.read':650 'path.relative':297,303 'pathlib':200,458,973 'pattern':172,433,452,613,736 'pin':63,623,639,694,890,1115 'pkg':664,681,697 'plugin':12,27,34,56,71,104,114,132,141,167,187,255,265,269,338,367,371,397,401,420,464,472,478,544,575,602,748,753,760,777,791,810,822,838,919,924,932,961,964,968,1101,1160 'posix':307 'post':1089 'post-review':1088 'pr':1075 'practic':1057,1058 'print':380,578,585,596,923,931,946,1043,1049 'product':136,764,928,1069 'promot':130,738,747,751,765,915,929 'proven':68,95,1141,1149 'prs':142 'publish':37 'pycach':206,1111 'pyproject.toml':703 'pytest':210 'python':189,444,625,749,970 'rational':1059 'rb':237,989 're':117,627 're-hash':116 'read':1008 'readi':762,909,922,926,934 'readme.md':423,794 'record':496,501,557 'recorded.items':509 'rel':302,309,504,512,520,534,547,553,561,1012,1020,1027,1036 'relat':1126 'repres':1099 'requir':171,445,786,793,800,806,841 'requirements.txt':702 'resourc':1127 'result':914,921,939 'return':250,357,487,563,734,908,1002 'review':139,154,1064,1066,1076,1090 'risk':80 'root':267,299,305,476,482,511,789,803,817,819,855 'root.name':340 'root.rglob':276 'run':963 'save':361 'section':659,668 'server':74,164,865,872 'server.get':877 'sever':684,724 'sha':21,109,182,225,315 'sha256':347,413 'sign':1161 'sigstor':96,1146 'sigstore-bas':1145 'singl':1097 'skill':18,100 'skill-agent-supply-chain' 'skills/search/skill.md':425,608 'slsa':98,1129 'slsa.dev':1131 'slsa.dev/)':1130 'softwar':1138 'sort':275,323,330 'sourc':1108 'source-github' 'state':1102 'step':146 'store':215 'str':223,257,466,470,633,755,882 'strip':721 'suppli':3,6,45,66,78,1134,1165 'supply-chain':1133 'support':812 'sys':979 'sys.exit':1047 't03':407 'tamper':40,60,125,601,1095 'text':374,495,651,862,1009 'third':158 'third-parti':157 'thumbs.db':216 'timezon':198 'timezone.utc':344 'tool':13,29,58,161 'toolkit':1152 'topic-agent-skills' 'topic-agents' 'topic-awesome' 'topic-custom-agents' 'topic-github-copilot' 'topic-hacktoberfest' 'topic-prompt-engineering' 'tupl':467 'unpin':851,863,894,896,897,1119 'unpinned.append':887 'untr':43 'untrack':539,560,611 'upper':729 'use':16,128,622,740 'valu':869 'venv':209 'ver':665,675,677,683,687 'ver.lstrip':698 'ver.startswith':671,673 'verif':742,1158 'verifi':5,31,50,124,148,435,462,471,568,571,579,772,775,960,1051,1078,1082 'version':62,616,624,630,638,682,722,1118 'workflow':957 'write':373 'yaml':958","prices":[{"id":"55aed2cb-3be0-4fe6-8021-31e9c6397f58","listingId":"e47db1a1-2da4-4e01-b95a-d81440ee3525","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"github","category":"awesome-copilot","install_from":"skills.sh"},"createdAt":"2026-04-18T21:48:07.509Z"}],"sources":[{"listingId":"e47db1a1-2da4-4e01-b95a-d81440ee3525","source":"github","sourceId":"github/awesome-copilot/agent-supply-chain","sourceUrl":"https://github.com/github/awesome-copilot/tree/main/skills/agent-supply-chain","isPrimary":false,"firstSeenAt":"2026-04-18T21:48:07.509Z","lastSeenAt":"2026-04-22T00:52:03.176Z"}],"details":{"listingId":"e47db1a1-2da4-4e01-b95a-d81440ee3525","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"github","slug":"agent-supply-chain","github":{"repo":"github/awesome-copilot","stars":30743,"topics":["agent-skills","agents","ai","awesome","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"license":"mit","html_url":"https://github.com/github/awesome-copilot","pushed_at":"2026-04-21T22:20:21Z","description":"Community-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.","skill_md_sha":"995c87835577fc396d31ff4447cea9d91ca61484","skill_md_path":"skills/agent-supply-chain/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/github/awesome-copilot/tree/main/skills/agent-supply-chain"},"layout":"multi","source":"github","category":"awesome-copilot","frontmatter":{"name":"agent-supply-chain","description":"Verify supply chain integrity for AI agent plugins, tools, and dependencies. Use this skill when:\n- Generating SHA-256 integrity manifests for agent plugins or tool packages\n- Verifying that installed plugins match their published manifests\n- Detecting tampered, modified, or untracked files in agent tool directories\n- Auditing dependency pinning and version policies for agent components\n- Building provenance chains for agent plugin promotion (dev → staging → production)\n- Any request like \"verify plugin integrity\", \"generate manifest\", \"check supply chain\", or \"sign this plugin\""},"skills_sh_url":"https://skills.sh/github/awesome-copilot/agent-supply-chain"},"updatedAt":"2026-04-22T00:52:03.176Z"}}