#+TITLE: Comparative Extension Architecture Study #+FILETAGS: :notes:comparative-study:extensibility:skills:plugins:hooks:mcp: * Purpose Compare extension/skill/plugin/hook architectures across Claude Code, OpenCode, OpenClaw, and Hermes Agent. Inform Passepartout's skill system and planned MCP integration (v0.10.0). Identify whether Passepartout needs hooks or plugins in addition to skills. * Findings Summary | Dimension | Claude Code | OpenCode | OpenClaw | Hermes | Passepartout | |-----------+-------------+----------+----------+--------+--------------| | Extension mechanisms | 4 (MCP, plugins, skills, hooks) | 2 (plugins + skills) | 1 (plugins — everything) | 2 (skills + plugins) | 1 (skills) + planned MCP | | Skills format | SKILL.md with YAML frontmatter | SKILL.md with YAML frontmatter | None (plugins serve role) | SKILL.md with YAML frontmatter | .org files with defskill | | Skill security | Path-conditional, symlink-safe, MCP shell inj disabled | None | N/A | Static analysis + trust levels + quarantine | Jail-loaded packages + sandbox check | | Plugins | npm packages, manifest JSON, 3 scopes | npm packages, Effect functions | npm packages, manifest JSON | Bundled/user/project/Pip chain | Not implemented | | Hooks | 27 events, 4 types (cmd/prompt/agent/http) | ~10 events via plugin functions | 36 events via plugin hooks | 20 events via plugin callbacks | defskill triggers only | | Lifecycle | PreToolUse, PostToolUse, Session*, etc. | tool.definition, session.*, etc. | before_* , after_*, session_*, etc. | pre_tool_call, post_tool_call, etc. | None beyond trigger | | MCP | Deepest: stdio/SSE/WS, OAuth, MCP skills, enterprise | Minimal: MCP web search only | Bidirectional: serve + consume MCP | Deep: stdio/HTTP, auto-reload, OSV check | Planned v0.10.0 | | Tool registration | TypeScript Tool objects, Zod schemas | Effect Tool.Def, plugin + file glob | Plugin tool factories | Self-registration at import, AST discovery | def-cognitive-tool (never called) | * Claude Code — Four Mechanisms, Clear Boundaries **Skills**: Two types — Bundled (TypeScript, compiled in, feature-flagged) and File-based (SKILL.md in .claude/skills//). YAML frontmatter with: name, description, when_to_use, allowed-tools, model, user-invocable, paths (conditional activation), hooks, context, agent, effort. Path-conditional: skills activate only when matching files are touched (gitignore-style matching). Dynamic discovery walking up from file paths. **Plugins**: package.json manifest + Bun plugin ecosystem. PluginDefinition unifies skills, hooks, MCP servers, LSP servers, agents, output styles. Three scopes (user/project/local) with precedence. Settings-first installation: intent written before materialization. Enterprise policy blocking. **Hooks**: 27 lifecycle events in HOOK_EVENTS. Four types: command (shell), prompt (LLM), agent (subagent), http (callback). JSON protocol: stdin→stdout structured communication. Permission decisions (allow/deny/ask) with updatedInput. Trust dialog gate. 10-minute timeout. Async backgrounding support. **MCP**: stdio, SSE, WebSocket, in-process transports. Tool naming: mcp____. MCP servers can provide skills (loaded from MCP, shell injection disabled). OAuth 2.1. Connection management with background reconnection. **Why 4 mechanisms?** The paper (arXiv:2604.14228v1) explains: different trade-offs. MCP = process isolation, highest safety. Plugins = npm ecosystem, maximum capability. Skills = markdown files, zero-install, lowest context cost. Hooks = intercept behavior without defining full tools. Each addresses a different point on the safety↔capability spectrum. * OpenCode — Simple, Functional **Plugins**: Effect-TS functions. (PluginInput) → Hooks. Fires on bus events. Tool provisioning: plugins contribute Tool.Def entries. File-based tool discovery: Glob.scanSync("{tool,tools}/*.{js,ts}"). **TUI plugins (separate system)**: Slot-based JSX rendering. 10+ named slots. SolidJS reactive. Full API: route, theme, keymap, sdk, dialog, toast, slot, sync, lifecycle, kv. **Skills**: SKILL.md files from .opencode/skills/, .claude/skills/, .agents/skills/. Simple YAML frontmatter (name, description). Loaded lazily, cached. Content injected as blocks. **Hooks**: ~10 hook events. Tool definition mutation (plugin.trigger("tool.definition")). Message transform. Session lifecycle. **Unique**: Effect-TS DI makes cancellation/safety composable. TUI slot system enables rich terminal UI extensions. Tool definition mutation at registration time. * OpenClaw — Everything is a Plugin **Unified plugin system**: Everything is a plugin — providers, tools, memory, context engines, channels, web search, speech, TTS, video, image, transcription, migration, CLI backends. One mechanism to rule them all. **Plugin entry**: definePluginEntry({id, name, description, kind?, configSchema?, register}). The register(api) callback receives the full API surface. Kind declaration in manifest. **36 lifecycle hooks**: Most extensive hook surface of all agents. before_model_resolve, agent_turn_prepare, before_prompt_build, before_tool_call, after_tool_call, session_start/end, subagent_spawning/spawned/ended, gateway_start/stop, heartbeat_prompt_contribution, before_install, and more. **Tool factories**: (ctx: OpenClawPluginToolContext) => AnyAgentTool[]. Tools auto-exposed as MCP server. Plugin tool MCP for other agents to consume. **Isolation**: SQLite-backed plugin state store. Path traversal protection. Activation gating. Memory slot competition (only one memory plugin). Security audit collector interface. **Auto-enable**: Complex detection rules (e.g., "auto-enable this plugin when using the OpenAI provider"). Manifest-first: capabilities declared in openclaw.plugin.json. **Unique**: Universal plugin mechanism eliminates concept count. Auto-enable rules. Plugin tools available as MCP to external agents. Most granular isolation. * Hermes Agent — Skills with Security Scanning **Skills**: SKILL.md with rich YAML frontmatter (name, description, version, license, platforms, prerequisites, compatibility, metadata.tags). Progressive disclosure (list metadata → view content → load references). Agentskills.io compatible. Skill Hub with multiple sources (bundled, GitHub, extensible SkillSource ABC). Hub directory with lock file, quarantine, audit log, taps. **Skill security (most sophisticated of all)**: Static analysis scanner detecting data exfiltration, prompt injection, destructive commands, persistence, network access, obfuscation. Trust level matrix (builtin/trusted/community/agent-created × safe/caution/dangerous → allow/block/ask). Quarantine before install. **Plugins**: Four-source chain (bundled → user → project → Pip). Manifest: plugin.yaml + __init__.py with register(ctx). 20 hooks (pre/post tool call, pre/post LLM call, session start/end, subagent, transform hooks, gateway hooks, config loaded). **Toolsets**: Composable tool groups (define → include → resolve). Probability-based distribution for batch runs. AST-based auto-discovery of tool registrations. **MCP**: stdio + HTTP transports. Background asyncio event loop. Auto-reconnect with exponential backoff. Auto-reload on config.yaml change. OSV malware check for npx/uvx packages. **Unique**: Skill security scanner. Skill hub with quarantine. Toolset composability. MCP auto-reload. * Skills vs Hooks — The Distinction | Agent | Skills (Instruction Injection) | Hooks (Behavior Interception) | Unified? | |-------|-------------------------------|------------------------------|----------| | Claude Code | Command objects, inject markdown into context | 27 lifecycle events, 4 types, JSON protocol | Blurred — skills CAN have hooks in frontmatter | | OpenCode | Markdown files loaded as | Plugin functions on lifecycle names | Separate — skills are content, hooks are code | | OpenClaw | No concept — everything is a plugin | 36 events, everything is a hook | Unified — no distinction exists | | Hermes | SKILL.md with security scanning | 20 events via plugin callbacks | Separate — different formats | | **Passepartout** | defskill with trigger + deterministic | **None** | **Skills only — missing hooks entirely** | * Passepartout Blindspot Assessment 1. **No hooks** — Passepartout's skills fire on triggers but can't intercept tool execution, model calls, or session lifecycle. All 4 competitors have hooks. This is the biggest extension architecture gap. Claude Code's PreToolUse hook pattern is the cleanest: a registered function that can inspect a tool call before execution and return allow/deny/ask with optional input modification. [Action: add Hook system to v0.8.0+] 2. **def-cognitive-tool never called** — The macro and registry exist but are empty. Claude Code's Tool interface with 10+ methods (call, isEnabled, isReadOnly, isConcurrencySafe, checkPermissions, validateInput) is a richer model. [Action: fill registry in v0.4.1 already planned] 3. **No skill security scanning** — Hermes's static analysis scanner is the gold standard. Passepartout's jail-loading + sandbox check is good but could be augmented with regex-based content scanning. [Action: add to security study] 4. **No plugin system** — OpenClaw's universal plugin system proves one mechanism can serve all extensibility needs. Passepartout should consider whether skills + hooks + MCP is sufficient, or whether a plugin manifest is needed. [Action: decision point for v0.10.0] 5. **Skills are Lisp-specific** — All competitors use markdown/JSON for skills (language-agnostic). Passepartout's .org files with defskill macros require knowing Common Lisp. For the Skill Creator (v0.11.0), this is fine (LLM writes Lisp). For user-authored skills, markdown frontmatter with Lisp code blocks would lower the barrier. [Action: consider dual format] 6. **MCP integration planned but not prioritized** — Claude Code and Hermes both have deep MCP. Passepartout's v0.10.0 placement is correct. No action needed, just schedule awareness. * Recommended Architecture for Passepartout Based on competitive analysis, Passepartout should converge on 3 mechanisms (not Claude Code's 4, not OpenClaw's 1): 1. **Skills** (defskill, .org format) — Instruction injection. Current state: working, needs security scanning + dual format option. 2. **Hooks** (new, PreToolUse/PostToolUse/Session*) — Behavior interception. Missing entirely. Add as slots on the defskill struct: :pre-tool-hook, :post-tool-hook, :on-session-start, :on-heartbeat. 3. **MCP** (planned v0.10.0) — External tool ecosystem. Process-isolated, community-maintained. This avoids the complexity of plugins (Claude Code/OpenClaw) while covering the essential extension surface. The key addition is hooks — without them, Passepartout can't intercept tool execution or respond to lifecycle events.