Relevant source files
The following files were used as context for generating this wiki page:
- integrations/agent-plugin-core/conformance/run.py
- integrations/agent-plugin-core/python/memory_core.py
- integrations/claude-code-plugin/core/memory_core.py
- integrations/claude-code-plugin/core/hook_runner.py
- integrations/agent-plugin-core/python/hook_runner.py
- integrations/antigravity-plugin/core/hook_runner.py
- integrations/codex-plugin/core/hook_runner.py
- integrations/cursor-plugin/core/hook_runner.py
- integrations/codex-plugin/core/memory_core.py
- integrations/mem0-agent-plugin/core/memory_core.py
- integrations/antigravity-plugin/core/memory_core.py
- integrations/cursor-plugin/core/memory_core.py
- integrations/kimi-plugin/core/memory_core.py
- integrations/agent-plugin-core/conformance/artifacts.py
- integrations/claude-code-plugin/core/memory_cli.py
- integrations/mem0-agent-plugin/core/memory_cli.py
- integrations/agent-plugin-core/python/memory_cli.py
- integrations/deepseek-plugin/src/index.ts
- integrations/openclaw/index.ts
- integrations/antigravity-plugin/hooks/adapter.py
- integrations/codex-plugin/hooks/adapter.py
- integrations/claude-code-plugin/core/_harness_id.py
- integrations/antigravity-plugin/hooks.json
- integrations/cursor-plugin/hooks/adapter.py
- integrations/codex-plugin/core/_harness_id.py
- integrations/mem0-agent-plugin/core/_harness_id.py
- integrations/claude-code-plugin/adapters/claude/hook.py
- integrations/kimi-plugin/hooks/adapter.py
- integrations/antigravity-plugin/core/_harness_id.py
Overview
Plugin conformance testing provides a unified verification framework to validate coding-agent memory plugins, ensuring bundle integrity, contract adherence, and cross-platform runtime stability across Python and TypeScript implementations. The suite systematically exercises both the shared core logic and individual plugin wrappers to guarantee that interactions with host environments remain predictable and consistent.
Sources: integrations/agent-plugin-core/conformance/run.py:1-30, integrations/agent-plugin-core/conformance/artifacts.py:1-24
The framework coordinates automated test suites, command execution checks, and artifact inspections for hosts such as Claude Code Plugin, Cursor, Codex, Kimi, and Antigravity, alongside portable plugins and platform integrations. It prevents subtle behavioral divergence across the diverse host environments by establishing strict runtime and build constraints that each implementation must satisfy.
Sources: integrations/agent-plugin-core/conformance/run.py:19-29, integrations/agent-plugin-core/conformance/artifacts.py:15-23
By centralizing test orchestration, artifact validation, hook normalization contracts, and harness segregation checks into a single runner architecture, the test suite catches regression issues and verifies distribution readiness prior to deployment. This guarantees that built plugins remain self-contained, free of monorepo path leaks, and fully capable of operating within host-specific sandbox limitations.
Sources: integrations/agent-plugin-core/conformance/run.py:38-133, integrations/agent-plugin-core/conformance/artifacts.py:29-44
Conformance Suite Test Runner Architecture
Suite Orchestration and Python Hosts
The conformance runner uses Python path resolution via CORE_ROOT and REPOSITORY_ROOT to locate plugin directories, importing redact from memory_core, build from build.build, and artifact verifiers from conformance.artifacts. Python host integrations cover five coding-agent environments: claude-code, cursor, codex, kimi, and antigravity.
CORE_ROOT = Path(__file__).resolve().parents[1]
REPOSITORY_ROOT = CORE_ROOT.parents[1]
PYTHON_HOSTS = ("claude-code", "cursor", "codex", "kimi", "antigravity")
GROUPS = (
"python-bundles",
"python-tests",
"typescript-core",
"openclaw",
"opencode",
"pi-agent",
"deepseek",
)
LIVE_GROUP = "live-platform"
sys.path.insert(0, str(CORE_ROOT))
sys.path.insert(0, str(CORE_ROOT / "python"))
from memory_core import redact # noqa: E402
from build.build import build # noqa: E402
from conformance.artifacts import TYPESCRIPT_ARTIFACTS, verify_artifact as _typescript_artifact_check # noqa: E402Sources: integrations/agent-plugin-core/conformance/run.py:17-36
Group execution encompasses seven static validation groups alongside a live platform integration target.
Sources: integrations/agent-plugin-core/conformance/run.py:19-96
Check Planning and Execution
The check planning phase dynamically aggregates tasks based on selected groups. For python-bundles, it schedules native and portable bundle targets across all defined python hosts. For runtime command groups, it maps each command entry to a numbered check identifier and appends artifact verification checks if the group exists in TYPESCRIPT_ARTIFACTS.
def _planned_checks(groups: set[str]) -> list[dict[str, Any]]:
checks: list[dict[str, Any]] = []
if "python-bundles" in groups:
checks.append(
{
"name": "python-bundles",
"group": "python-bundles",
"status": "planned",
"hosts": list(PYTHON_HOSTS),
"kinds": {"native": list(PYTHON_HOSTS), "portable": ["mem0-agent-plugin"]},
}
)
for group, commands in _runtime_commands().items():
if group not in groups:
continue
for index, command in enumerate(commands, start=1):
checks.append(
{
"name": f"{group}-{index}",
"group": group,
"status": "planned",
"command": command,
}
)
if group in TYPESCRIPT_ARTIFACTS:
_, required = TYPESCRIPT_ARTIFACTS[group]
checks.append(
{
"name": f"{group}-artifact",
"group": group,
"status": "planned",
"required": list(required),
}
)
return checksSources: integrations/agent-plugin-core/conformance/run.py:99-133
Command execution is handled by _command_check, which records monotonic duration, merges environment overrides, and redacts sensitive data from both the command arguments and captured standard output and error streams. Output capture truncates the response text to the final 8,000 characters when populated.
def _command_check(
name: str,
group: str,
command: list[str],
*,
cwd: Path,
environment_overrides: dict[str, str] | None = None,
) -> dict[str, Any]:
started = time.monotonic()
environment = dict(os.environ)
environment.update(environment_overrides or {})
safe_command = [redact(part) for part in command]
try:
result = subprocess.run(
command,
cwd=cwd,
env=environment,
text=True,
capture_output=True,
check=False,
)
output = redact((result.stdout + result.stderr).strip())
return {
"name": name,
"group": group,
"status": "passed" if result.returncode == 0 else "failed",
"duration_seconds": round(time.monotonic() - started, 3),
"command": safe_command,
"exit_code": result.returncode,
**({"output": output[-8_000:]} if output else {}),
}
except OSError as exc:
return {
"name": name,
"group": group,
"status": "failed",
"duration_seconds": round(time.monotonic() - started, 3),
"command": safe_command,
"exit_code": None,
"output": redact(str(exc)),
}Sources: integrations/agent-plugin-core/conformance/run.py:136-177
Note
Command checks execute with check=False to capture non-zero exit codes as failed status outcomes without throwing exceptions prematurely during test suite execution.
Sources: integrations/agent-plugin-core/conformance/run.py:149-166
Artifact Validation and Build Inspection
TypeScript Artifact Definitions
The conformance framework verifies that built TypeScript packages contain all required distribution files and do not leak internal monorepo dependencies. The TYPESCRIPT_ARTIFACTS mapping defines the root paths and mandatory build outputs for each integration package.
| Plugin Group | Package Path | Required Artifacts |
|---|---|---|
openclaw | integrations/openclaw | dist/index.js, dist/index.d.ts |
opencode | integrations/opencode-plugin | dist/index.js, index.d.ts |
pi-agent | integrations/pi-agent-plugin | dist/index.js, dist/index.d.ts, dist/entry.js, dist/entry.d.ts |
deepseek | integrations/deepseek-plugin | dist/index.js, dist/index.d.ts |
TYPESCRIPT_ARTIFACTS = {
"openclaw": (INTEGRATIONS_ROOT / "openclaw", ("dist/index.js", "dist/index.d.ts")),
"opencode": (INTEGRATIONS_ROOT / "opencode-plugin", ("dist/index.js", "index.d.ts")),
"pi-agent": (
INTEGRATIONS_ROOT / "pi-agent-plugin",
("dist/index.js", "dist/index.d.ts", "dist/entry.js", "dist/entry.d.ts"),
),
"deepseek": (INTEGRATIONS_ROOT / "deepseek-plugin", ("dist/index.js", "dist/index.d.ts")),
}Sources: integrations/agent-plugin-core/conformance/artifacts.py:15-23
Verification Logic and Monorepo Leak Detection
The verify_artifact function checks for the physical presence of every required file within the package directory. It then recursively scans compiled JavaScript and declaration files (*.js, *.mjs, *.cjs, *.d.ts) inside the dist directory using a regular expression pattern that detects unbundled monorepo imports referencing agent-plugin-core.
MONOREPO_IMPORT = re.compile(
r"(?:from\s+|import\s*\(|require\s*\()\s*['\"][^'\"]*agent-plugin-core"
)
def verify_artifact(group: str, package: Path, required: tuple[str, ...]) -> dict[str, Any]:
started = time.monotonic()
errors = [f"missing package artifact: {name}" for name in required if not (package / name).is_file()]
dist = package / "dist"
for pattern in ("*.js", "*.mjs", "*.cjs", "*.d.ts"):
for artifact in dist.rglob(pattern) if dist.is_dir() else ():
if MONOREPO_IMPORT.search(artifact.read_text(encoding="utf-8")):
errors.append(f"monorepo source import in package artifact: {artifact.relative_to(package)}")
return {
"name": f"{group}-artifact",
"group": group,
"status": "failed" if errors else "passed",
"duration_seconds": round(time.monotonic() - started, 3),
**({"output": "\n".join(errors)} if errors else {}),
}Sources: integrations/agent-plugin-core/conformance/artifacts.py:24-43
Warning
Any matching agent-plugin-core import found inside built distribution files causes the artifact verification check to fail, ensuring that distributed packages remain entirely self-contained.
Sources: integrations/agent-plugin-core/conformance/artifacts.py:33-36
Python Hook Runner Contract Conformance
Hook Input Handling and Session Orchestration
The shared Python hook runner implementations across agent variants orchestrate event hooks via standard input parsing and background worker handoffs (see Python Agent Core). The read_hook_input function parses JSON payloads from standard input, returning an empty dictionary upon encountering json.JSONDecodeError or OSError.
def read_hook_input() -> dict:
try:
value = json.load(sys.stdin)
return value if isinstance(value, dict) else {}
except (json.JSONDecodeError, OSError):
return {}Sources: integrations/claude-code-plugin/core/hook_runner.py:44-50
| Constant | Value | Purpose |
|---|---|---|
STALE_RUNNING_SECONDS | 300 | Threshold in seconds before a running handoff file is considered stale and reset. |
PENDING_EXPIRY_SECONDS | 604800 (7 days) | Maximum age for pending handoff files before unlinking. |
PENDING_LAUNCH_LIMIT | 5 | Maximum number of pending handoffs launched per recovery cycle. |
DEFAULT_IDLE_FLUSH_SECONDS | 300 | Default idle duration triggering flush execution. |
STALE_RUNNING_SECONDS = 300
PENDING_EXPIRY_SECONDS = 7 * 24 * 60 * 60
PENDING_LAUNCH_LIMIT = 5
DEFAULT_IDLE_FLUSH_SECONDS = 300Sources: integrations/claude-code-plugin/core/hook_runner.py:36-40
Note
Automatic flushing relies on MEM0_CODE_AUTO_FLUSH environment variable settings, matching values "1", "true", "yes", or "on" case-insensitively.
Sources: integrations/claude-code-plugin/core/hook_runner.py:193-196
First Prompt Memory Injection and Handoff Lifecycle
When evaluating initial user prompts, first_prompt_memory_output retrieves query parameters from environment variables and checks length bounds before querying vector stores.
def first_prompt_memory_output(store: EvidenceStore, hook_input: dict) -> dict:
"""Search once before the agent handles the first prompt in a session."""
repo, session_id, prompt, is_first_prompt = record_user_prompt(store, hook_input)
if not is_first_prompt:
return {}
try:
minimum_query_chars = int(os.environ.get("MEM0_CODE_MIN_QUERY_CHARS", "20"))
except ValueError:
minimum_query_chars = 20
if len(prompt.strip()) < max(minimum_query_chars, 1):
return {}
result = search_memories(
store, repo, session_id, bounded(prompt, 6000),
top_k=5, operation="first-prompt-search", timeout=2,
)Sources: integrations/claude-code-plugin/core/hook_runner.py:62-76
Sources: integrations/claude-code-plugin/core/hook_runner.py:64-94, integrations/claude-code-plugin/core/hook_runner.py:170-191
Warning
Handoff files are written atomically using a .tmp suffix before replacing the target .json file to prevent partial read states during concurrent worker launches.
Sources: integrations/claude-code-plugin/core/hook_runner.py:180-190
Plugin Adapter Hook Normalization Testing
Native Event Mapping and Payload Translation
Plugin adapters translate proprietary agent harness event streams into standardized arguments for the shared Mem0 runtime. Each adapter processes raw JSON inputs from standard input and maps harness-specific keys to common payload structures recognized by hook_runner and memory_core.
Sources: integrations/cursor-plugin/hooks/adapter.py:25-34, integrations/kimi-plugin/hooks/adapter.py:22-30
Note
The antigravity-plugin adapter configures execution through hooks.json mapping PreInvocation, PostToolUse, and Stop commands directly to adapter.py entry points with strict timeout limits.
Sources: integrations/antigravity-plugin/hooks.json:3-16
Transcript Stream Parsing and Session Reconstruction
Adapters for harnesses like Antigravity and Kimi Code inspect local transcript file paths to extract structured conversation turns when direct message fields are missing from hook payloads. The Antigravity adapter reads newline-delimited JSON step objects, filtering for items where status == "DONE" and extracting redacted user requests enclosed within <USER_REQUEST> tags or planner response models.
def _read_transcript(path: str) -> list[dict[str, str]]:
messages = []
try:
with open(path, encoding="utf-8") as transcript:
for line in transcript:
try:
step = json.loads(line)
except json.JSONDecodeError:
continue
content = step.get("content")
if not isinstance(content, str) or step.get("status") != "DONE":
continue
if step.get("type") == "USER_INPUT":
match = re.search(r"<USER_REQUEST>\s*(.*?)\s*</USER_REQUEST>", content, re.DOTALL)
messages.append({"role": "user", "content": redact(match.group(1) if match else content).strip()})
elif step.get("source") == "MODEL" and step.get("type") == "PLANNER_RESPONSE":
messages.append({"role": "assistant", "content": redact(content).strip()})
except (OSError, TypeError):
pass
return messagesSources: integrations/antigravity-plugin/hooks/adapter.py:28-47
Similarly, the Kimi Code adapter resolves session directories through session_index.jsonl lookups or globbing under sessions/*/ to locate wire transcripts (wire.jsonl), aggregating text parts across loop events while skipping error or interrupted finish reasons.
def _session_dir(session_id: str) -> Path | None:
home = Path(os.environ.get("KIMI_CODE_HOME", Path.home() / ".kimi-code")).expanduser()
found = None
try:
with (home / "session_index.jsonl").open(encoding="utf-8") as index:
for line in index:
try:
entry = json.loads(line)
except json.JSONDecodeError:
continue
if entry.get("sessionId") == session_id and isinstance(entry.get("sessionDir"), str):
found = Path(entry["sessionDir"])
except OSError:
pass
if found:
return found
if not session_id or Path(session_id).name != session_id:
return None
return next((path for path in (home / "sessions").glob(f"*/{session_id}") if path.is_dir()), None)
def _last_assistant_message(transcript: Path) -> str:
message = ""
step_id = None
parts = []
try:
lines = transcript.read_text(encoding="utf-8").splitlines()
except OSError:
return ""
for line in lines:
try:
record = json.loads(line)
except json.JSONDecodeError:
continue
if record.get("type") != "context.append_loop_event" or not isinstance(record.get("event"), dict):
continue
event = record["event"]
if event.get("type") == "step.begin":
step_id = event.get("uuid")
parts = []
elif event.get("type") == "content.part" and event.get("stepUuid") == step_id:
part = event.get("part")
if isinstance(part, dict) and part.get("type") == "text" and isinstance(part.get("text"), str):
parts.append(part["text"])
elif event.get("type") == "step.end" and event.get("uuid") == step_id:
if event.get("finishReason") not in {"error", "interrupted"} and parts:
message = "".join(parts)
step_id = None
parts = []
return messageSources: integrations/kimi-plugin/hooks/adapter.py:33-82
Warning
Transcript parsing fails silently on OSError, TypeError, or json.JSONDecodeError, returning empty message lists or falling back to default runner implementations to prevent hook crashes.
Sources: integrations/antigravity-plugin/hooks/adapter.py:35-46, integrations/kimi-plugin/hooks/adapter.py:38-61
Harness Identity and Multi-Agent Environments
Harness Identity Configuration and Source Tagging
The plugin core initializes runtime behavior using harness-specific identity parameters. Through configure_harness, plugins define their unique execution context including name, env_prefix, data_dir_name, and source_tag. When left unconfigured, defaults fallback to generic with standard MEM0_PLUGIN environment variables.
| Harness Identifier | Platform Source | Platform Application | Source Reference |
|---|---|---|---|
claude-code | MEM0_PLUGIN | claude-code | integrations/claude-code-plugin/core/_harness_id.py:3-11 |
codex | MEM0_PLUGIN | codex | integrations/codex-plugin/core/_harness_id.py:3-11 |
coding-agent | MEM0_PLUGIN | None | integrations/mem0-agent-plugin/core/_harness_id.py:3-11 |
antigravity | MEM0_PLUGIN | antigravity | integrations/antigravity-plugin/core/_harness_id.py:3-11 |
Sources: integrations/claude-code-plugin/core/_harness_id.py:3-11, integrations/codex-plugin/core/_harness_id.py:3-11, integrations/mem0-agent-plugin/core/_harness_id.py:3-11, integrations/antigravity-plugin/core/_harness_id.py:3-11
Note
The platform-side vocabulary separates the overarching source family (MEM0_PLUGIN) from the specific editor application header (X-Application). If the application field is empty, memory_core omits the application header entirely rather than transmitting a placeholder string.
Sources: integrations/claude-code-plugin/core/_harness_id.py:6-11
Multi-Agent Environment Scoping and CLI Integration
Multi-agent runtimes configure telemetry initialization (see Telemetry and Metrics) and CLI parameter parsing dynamically based on command-line arguments. When executing diagnostics or control commands via memory_cli.py, operators can supply explicit --harness flags to override default source tags and bind the telemetry collector to the target environment.
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--plugin-data-dir", default="")
parser.add_argument("--harness", default="")
subparsers = parser.add_subparsers(dest="command", required=True)
status = subparsers.add_parser("status")
status.add_argument("--json", action="store_true")
doctor_parser = subparsers.add_parser("doctor")
doctor_parser.add_argument("--json", action="store_true")
subparsers.add_parser("pause")
subparsers.add_parser("resume")
forget = subparsers.add_parser("forget")
forget.add_argument("--remote", action="store_true")
forget.add_argument("--yes", action="store_true")
forget.add_argument("--include-project-memory", action="store_true")
args = parser.parse_args()
if args.harness:
source_tag = f"{args.harness.replace('-', '_')}_plugin"
configure_harness(args.harness, source_tag=source_tag)
telemetry.init(harness=args.harness, source_tag=source_tag.upper())
if args.plugin_data_dir:Sources: integrations/claude-code-plugin/core/memory_cli.py:61-86, integrations/mem0-agent-plugin/core/memory_cli.py:61-86
Warning
Failing to pass matching harness identifiers during concurrent multi-agent executions risks cross-contamination of local evidence stores when multiple plugins share an unsegmented root directory. Always set explicit MEM0_CODE_DATA_DIR overrides or plugin data path flags.
Sources: integrations/claude-code-plugin/core/memory_cli.py:86-88, integrations/mem0-agent-plugin/core/memory_cli.py:86-88
Related
On This Page
OverviewConformance Suite Test Runner ArchitectureSuite Orchestration and Python HostsCheck Planning and ExecutionArtifact Validation and Build InspectionTypeScript Artifact DefinitionsVerification Logic and Monorepo Leak DetectionPython Hook Runner Contract ConformanceHook Input Handling and Session OrchestrationFirst Prompt Memory Injection and Handoff LifecyclePlugin Adapter Hook Normalization TestingNative Event Mapping and Payload TranslationTranscript Stream Parsing and Session ReconstructionHarness Identity and Multi-Agent EnvironmentsHarness Identity Configuration and Source TaggingMulti-Agent Environment Scoping and CLI IntegrationRelated