diff --git a/.github/brand/social.png b/.github/brand/social.png new file mode 100644 index 0000000..596cd54 Binary files /dev/null and b/.github/brand/social.png differ diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 30539a4..a535d34 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -23,6 +23,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 diff --git a/AGENTS.md b/AGENTS.md index f273b63..8d50532 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,3 +11,11 @@ Keep vendor installation, authentication, subscription/API usage, updates, plugi Use Python standard library only unless a dependency demonstrably removes required complexity. Tests must cover MCP initialization, tool discovery, stream-json parsing, permission-boundary rejection, cancellation, deterministic package contents, and executable archive mode. Before handoff run unit tests, the native non-model interface check, deterministic package build, Computer MCP package validation/doctor where available, and git status. Do not publish or create a release implicitly. + +## 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..3e4bfb1 --- /dev/null +++ b/Documentation/Brand/header.svg @@ -0,0 +1,13 @@ + + Computer MCP — Claude Code + + + + + First-party plugin + Computer MCP + Claude Code + + Claude Code CLI and streaming MCP adapter + + diff --git a/README.md b/README.md index 3118448..c9e7c67 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# Claude Code Plugin +![Computer MCP — Claude Code](Documentation/Brand/header.svg) + +# Computer MCP — Claude Code + +Part of the [Computer MCP](https://computer-mcp.github.io/) family. +**Let ChatGPT use your local tools.** An independent Computer MCP plugin for Claude Code. The same package contributes a canonical CLI Tree, a stdio MCP adapter and client-neutral usage Skills. It does not link Computer MCP Core or require a host release to add vendor behavior. 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/brand.lock.json b/brand.lock.json new file mode 100644 index 0000000..745410d --- /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-claude", + "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": "713529d7dc33dc58f41057da09a346955cb6fcb6a5cc4e1aff1939c51bf7f6c2", + ".github/brand/social.png": "52692bada153a18888d7bd37eb39c87d269f1b7e351f53b13d2f12d8ac069e61", + "Scripts/check-brand.py": "2ec3c64469774b48fbfa6fbfa7f6a35c6a172fe4de347beb1881766632fbfdde" + } +}