diff --git a/.github/brand/social.png b/.github/brand/social.png new file mode 100644 index 0000000..a96057e Binary files /dev/null and b/.github/brand/social.png differ diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 53dc8c1..ecc8342 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -21,6 +21,7 @@ jobs: python-version: '3.13' - name: Verify deterministic declaration package run: | + python3 Scripts/check-brand.py python3 -m unittest discover -s Tests -p 'test_*.py' python3 Scripts/build_package.py dist > package-receipt.json - uses: actions/upload-artifact@v7 diff --git a/AGENTS.md b/AGENTS.md index 1cc8695..0638bc7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -162,3 +162,11 @@ Read `README.md` and `computer-mcp-plugin.toml` before changing this package. without explicit authorization. - Preserve native AX fallback and never replay an uncertain write through a second backend. Real GUI verification requires a disposable, authorized target. + +## Brand delivery + +The main Computer MCP repository owns ProductIdentity and BRAND. Imported +`Documentation/Brand/header.svg` travels with the packaged manual; +`.github/brand/social.png` supplies the repository preview. `brand.lock.json` +binds both to canonical exports. Run `python3 Scripts/check-brand.py` locally +and in CI. Update imports with the main repository's `Scripts/brand.py sync`. diff --git a/Documentation/Brand/header.svg b/Documentation/Brand/header.svg new file mode 100644 index 0000000..db4fa76 --- /dev/null +++ b/Documentation/Brand/header.svg @@ -0,0 +1,13 @@ + + Computer MCP — Computer Use + + + + + First-party plugin + Computer MCP + Computer Use + + Native desktop observation and actions + + diff --git a/README.md b/README.md index 3a6c906..d98033a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# Computer Use Plugin +![Computer MCP — Computer Use](Documentation/Brand/header.svg) + +# Computer MCP — Computer Use + +Part of the [Computer MCP](https://computer-mcp.github.io/) family. +**Let ChatGPT use your local tools.** A declarative Computer MCP package that connects to the vendor's native Computer Use MCP server and supplies observation/action verification guidance. diff --git a/Scripts/check-brand.py b/Scripts/check-brand.py new file mode 100644 index 0000000..1cb6c74 --- /dev/null +++ b/Scripts/check-brand.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +"""Verify a repository's locked Computer MCP brand delivery without a source checkout.""" + +import hashlib +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +LOCK = ROOT / "brand.lock.json" +if not LOCK.exists(): + LOCK = ROOT / "public/brand/brand.lock.json" +record = json.loads(LOCK.read_text()) +assert record["schema_version"] == 1, "Unsupported brand lock" +assert record["source"] == "https://github.com/computer-mcp/computer-mcp", "Unexpected brand authority" +for name, expected in record["files"].items(): + path = ROOT / name + assert path.resolve().is_relative_to(ROOT), f"Invalid delivery path: {name}" + assert hashlib.sha256(path.read_bytes()).hexdigest() == expected, f"Brand delivery drift: {name}" +if record["consumer"] == "computer-mcp.github.io": + text = (ROOT / "index.html").read_text() + for promise in record["promise"].values(): + assert promise in text, "Website promise differs from the imported brand" + assert 'brand/social-en.png' in text, "Website sharing artwork differs" +else: + manual = ROOT / ("profile/README.md" if record["consumer"] == ".github" else "README.md") + text = manual.read_text() + assert record["name"] in text, "Master name missing from public entry point" + assert record["promise"]["en"] in text, "Master promise missing from public entry point" + header = "brand/header.svg" if record["consumer"] == ".github" else "Documentation/Brand/header.svg" + assert header in text, "Family header missing from public entry point" +print(f"Locked Computer MCP brand verified for {record['consumer']}") diff --git a/Tests/test_build_package.py b/Tests/test_build_package.py index d1400cc..75b2573 100644 --- a/Tests/test_build_package.py +++ b/Tests/test_build_package.py @@ -28,6 +28,7 @@ def test_reproducible_owned_contents(self): "Documentation/Architecture/README.md", "Documentation/Architecture/Package.md", "Documentation/Architecture/Documentation.md", + "Documentation/Brand/header.svg", "skills/observe-act-verify/SKILL.md", "skills/observe-act-verify/agents/openai.yaml", }) diff --git a/brand.lock.json b/brand.lock.json new file mode 100644 index 0000000..a1642cf --- /dev/null +++ b/brand.lock.json @@ -0,0 +1,16 @@ +{ + "schema_version": 1, + "source": "https://github.com/computer-mcp/computer-mcp", + "revision": "3c498108b1b847ae126fd2593cd0d3ddb4d0d9858d0dae214b1439ff69226e50", + "consumer": "plugin-computer-use", + "name": "Computer MCP", + "promise": { + "en": "Let ChatGPT use your local tools.", + "zh-CN": "\u8ba9 ChatGPT\uff0c\u7528\u4e0a\u4f60\u7684\u672c\u673a\u5de5\u5177\u3002" + }, + "files": { + "Documentation/Brand/header.svg": "5594001e817a193ddf54aecdfe95f68e63f27f6398889135a0664f9d5ca7a7ee", + ".github/brand/social.png": "c5aaa0fe908d812b78597478d8b5c21edc30f98ae007de1461bde95dc39fa2cf", + "Scripts/check-brand.py": "2ec3c64469774b48fbfa6fbfa7f6a35c6a172fe4de347beb1881766632fbfdde" + } +}