Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "agent-guild",
"owner": {
"name": "AgentTanuki",
"url": "https://github.com/AgentTanuki"
},
"description": "Trust and settlement tools for autonomous agents.",
"version": "1.0.0",
"plugins": [
{
"name": "agent-guild",
"source": "./plugins/agent-guild",
"description": "Vet agents, verify portable passports, use escrow, and record signed outcomes.",
"version": "1.0.0",
"author": {
"name": "AgentTanuki"
}
}
]
}
27 changes: 27 additions & 0 deletions .github/workflows/plugin-security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Plugin security

on:
push:
# The repository's machine ship loop opens PRs with GITHUB_TOKEN. GitHub
# holds pull_request workflows from that actor for human approval, so run
# on the exact authenticated branch SHA instead (the same model as ci.yml).
branches: [main, "ship/**"]
paths:
- ".claude-plugin/**"
- "plugins/agent-guild/**"
- ".github/workflows/plugin-security.yml"
workflow_dispatch:

permissions:
contents: read
security-events: write

jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashgraph-online/ai-plugin-scanner-action@v1
with:
plugin_dir: "plugins/agent-guild"
fail_on_severity: high
2 changes: 2 additions & 0 deletions live/guild/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4504,6 +4504,7 @@ def _serve_paid_offer(source: str, actor: Optional[str] = _SENTINEL):
_MANIFEST_ALLOWED_SRC = {
"paid_offer:registry",
"paid_offer:clawhub_skill",
"paid_offer:codex_plugin",
"paid_offer:agent_skills",
}

Expand All @@ -4513,6 +4514,7 @@ def wellknown_manifest(src: Optional[str] = Query(
None, description="closed attribution source; recognised values are "
"'paid_offer:registry' and "
"'paid_offer:clawhub_skill' and "
"'paid_offer:codex_plugin' and "
"'paid_offer:agent_skills'. Any other value is "
"ignored.")):
# the manifest leads with the passport claim — count the offer per serve.
Expand Down
1 change: 1 addition & 0 deletions live/guild/app/paidcatalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"paid_offer:llms_txt", # /llms.txt
"paid_offer:registry", # MCP Registry publisher metadata
"paid_offer:clawhub_skill", # installed ClawHub agent policy skill
"paid_offer:codex_plugin", # installed Codex/Claude plugin bundle
"paid_offer:agent_skills", # domain-owned Agent Skills policy
"paid_offer:x402_challenge", # the 402 itself (a caller already on a route)
)
Expand Down
57 changes: 57 additions & 0 deletions live/guild/tests/test_installable_agent_skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,63 @@ def test_clawhub_skill_is_a_source_tagged_policy_parity_copy():
"*\n!SKILL.md\n"


def test_codex_plugin_is_installable_and_source_tagged():
import json

plugin = ROOT / "plugins" / "agent-guild"
manifest = json.loads(
(plugin / ".codex-plugin" / "plugin.json").read_text())
assert manifest["name"] == "agent-guild"
assert manifest["version"] == "1.0.0"
assert manifest["skills"] == "./skills/"
assert manifest["mcpServers"] == "./.mcp.json"
assert manifest["interface"]["developerName"] == "AgentTanuki"
assert len(manifest["interface"]["defaultPrompt"]) == 3

claude_manifest = json.loads(
(plugin / ".claude-plugin" / "plugin.json").read_text())
assert claude_manifest["name"] == manifest["name"]
assert claude_manifest["version"] == manifest["version"]
assert claude_manifest["mcpServers"] == "./.mcp.json"

marketplace = json.loads(
(ROOT / ".claude-plugin" / "marketplace.json").read_text())
assert marketplace["name"] == "agent-guild"
assert marketplace["plugins"] == [{
"name": "agent-guild",
"source": "./plugins/agent-guild",
"description": "Vet agents, verify portable passports, use escrow, "
"and record signed outcomes.",
"version": "1.0.0",
"author": {"name": "AgentTanuki"},
}]

mcp = json.loads((plugin / ".mcp.json").read_text())
assert mcp == {"mcpServers": {"agent-guild": {
"type": "http",
"url": "https://agent-guild-5d5r.onrender.com/mcp",
}}}

canonical = (ROOT / "SKILL.md").read_text()
published = (
plugin / "skills" / "agent-guild-trust" / "SKILL.md"
).read_text()
expected = canonical.replace(
"name: agent-guild\n",
"name: agent-guild-trust\n",
1,
).replace(
"agentguild-skill/1.0 (host=<runtime>)",
"agentguild-skill/1.0 (host=<runtime>; source=codex-plugin)",
).replace(
"https://agent-guild-5d5r.onrender.com/.well-known/agent-guild.json",
"https://agent-guild-5d5r.onrender.com/.well-known/agent-guild.json"
"?src=paid_offer:codex_plugin",
1,
)
assert published == expected


def test_canonical_origin_serves_repository_policy_through_agent_skills():
from fastapi.testclient import TestClient
from app.main import app
Expand Down
11 changes: 11 additions & 0 deletions live/guild/tests/test_paid_discovery_surfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ def test_agent_skills_source_is_closed_and_attributable():
"paid_offer:agent_skills"


def test_codex_plugin_source_is_closed_and_attributable():
assert "paid_offer:codex_plugin" in paidcatalog.SOURCE_IDS

tagged = client.get(
"/.well-known/agent-guild.json",
params={"src": "paid_offer:codex_plugin"},
).json()
assert tagged["paid_operations"]["source"] == \
"paid_offer:codex_plugin"


# --------------------------------------------------------------------------
# telemetry
# --------------------------------------------------------------------------
Expand Down
25 changes: 25 additions & 0 deletions plugins/agent-guild/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "agent-guild",
"displayName": "Agent Guild",
"version": "1.0.0",
"description": "Vet autonomous agents before delegating work or money, verify portable passports, and record evidence-backed outcomes.",
"author": {
"name": "AgentTanuki",
"url": "https://github.com/AgentTanuki"
},
"homepage": "https://agent-guild-5d5r.onrender.com/for-agents",
"repository": "https://github.com/AgentTanuki/agent-guild",
"license": "Apache-2.0",
"keywords": [
"agent-trust",
"safe-delegation",
"reputation",
"mcp",
"a2a",
"x402",
"verifiable-credentials"
],
"skills": "./skills/",
"mcpServers": "./.mcp.json"
}
44 changes: 44 additions & 0 deletions plugins/agent-guild/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "agent-guild",
"version": "1.0.0",
"description": "Vet autonomous agents before delegating work or money, verify portable passports, and record evidence-backed outcomes.",
"author": {
"name": "AgentTanuki",
"url": "https://github.com/AgentTanuki"
},
"homepage": "https://agent-guild-5d5r.onrender.com/for-agents",
"repository": "https://github.com/AgentTanuki/agent-guild",
"license": "Apache-2.0",
"keywords": [
"agent-trust",
"safe-delegation",
"reputation",
"mcp",
"a2a",
"x402",
"verifiable-credentials"
],
"skills": "./skills/",
"mcpServers": "./.mcp.json",
"interface": {
"displayName": "Agent Guild",
"shortDescription": "Trust checks and payment safety for autonomous agents.",
"longDescription": "Check an unfamiliar agent before delegating work or money, verify portable Agent Passports, use escrow, and record signed outcomes through Agent Guild's public MCP service.",
"developerName": "AgentTanuki",
"category": "Tools & Integrations",
"capabilities": [
"Agent discovery",
"Counterparty risk checks",
"Credential verification",
"Escrow",
"Signed outcome records"
],
"websiteURL": "https://agent-guild-5d5r.onrender.com",
"brandColor": "#7C3AED",
"defaultPrompt": [
"Find the safest agent for this task.",
"Vet this agent before I delegate work.",
"Verify this Agent Passport before I trust it."
]
}
}
3 changes: 3 additions & 0 deletions plugins/agent-guild/.codexignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
__pycache__/
*.pyc
8 changes: 8 additions & 0 deletions plugins/agent-guild/.mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"agent-guild": {
"type": "http",
"url": "https://agent-guild-5d5r.onrender.com/mcp"
}
}
}
Loading
Loading