Plugin introspection CLI and visualization #54

Open
opened 2026-02-22 09:20:44 +00:00 by nazim · 1 comment
Contributor

Problem

Cobot has 22 plugins with complex interdependencies (hard deps, extension point contracts, runtime coupling, capability provisions). There's no way to:

  1. Query the plugin graph programmatically — agents can't ask "what breaks if I remove config?"
  2. Visualize the architecture — humans have to read every plugin.py to understand the structure
  3. See coverage gaps — which plugins have web panels? CLI? Tools? Hooks?

As the plugin count grows (vault, activity loop, etc.), this becomes unmanageable.

What We Have

PluginMeta already contains everything needed:

  • id, version, priority
  • capabilities (what it provides)
  • dependencies (what it requires)
  • extension_points (contracts it defines)
  • implements (contracts it fulfills)

The data is there — we just need renderers.

Current Plugin Landscape (22 plugins)

By Layer (priority)

Layer Priority Plugins
Foundation 1-5 config, workspace, pairing, logger
Core 10-18 security, memory-files, persistence, compaction, context
Services 20-30 ollama, ppq, knowledge, nostr, telegram, filedrop, wallet, tools
Orchestration 50-90 loop, session, memory, communication, web

Edge Types

Type Meaning Example
dependency Hard requirement, won't start without telegram → session
implements Fulfills an extension point contract soul → context.system_prompt
calls_extension Runtime coupling telegram → telegram.on_message
capability Provides a named capability ppq → llm, ollama → llm

Surface Coverage

Surface Plugins
Web panels config, communication, logger, knowledge, ppq, security, tools, wallet, nostr
CLI memory, nostr, pairing, telegram, tools, wallet
Hooks pairing, persistence, ppq, security, telegram

loop is the central orchestrator — defines 11 extension points that most plugins implement.

Proposed Solution

Phase 1: cobot plugins inspect CLI command

Outputs the full plugin graph as JSON from the live registry:

cobot plugins inspect              # JSON (agent-facing)
cobot plugins inspect --format mermaid  # Mermaid diagram (human-facing)
cobot plugins inspect --format dot      # Graphviz DOT
cobot plugins inspect --format table    # Summary table

JSON schema:

{
  "plugins": {
    "<id>": {
      "id": "string",
      "version": "string",
      "priority": 0,
      "capabilities": [],
      "dependencies": [],
      "extension_points": [],
      "implements": {},
      "surfaces": ["web", "cli", "tools"],
      "hooks": []
    }
  },
  "edges": [
    {"from": "soul", "to": "context", "kind": "implements", "point": "context.system_prompt"}
  ]
}

Phase 2: Web admin panel

Interactive D3.js force-directed graph in the web plugin:

  • Nodes = plugins (sized by connection count, colored by layer)
  • Edges = colored by type (dependency/implements/capability)
  • Click node to see details (surfaces, hooks, extension points)
  • Filter by layer, surface, or edge type

Phase 3: docs/architecture.md

Auto-generated Mermaid diagram + manually curated narrative. Regenerated on each release.

Acceptance Criteria

  • cobot plugins inspect outputs valid JSON matching schema above
  • --format mermaid produces a renderable Mermaid graph
  • Edge types are correctly classified (dependency, implements, capability)
  • Surface detection is accurate (web, cli, tools, hooks)
  • Output is generated from live registry, not static extraction
## Problem Cobot has 22 plugins with complex interdependencies (hard deps, extension point contracts, runtime coupling, capability provisions). There's no way to: 1. **Query the plugin graph programmatically** — agents can't ask "what breaks if I remove `config`?" 2. **Visualize the architecture** — humans have to read every `plugin.py` to understand the structure 3. **See coverage gaps** — which plugins have web panels? CLI? Tools? Hooks? As the plugin count grows (vault, activity loop, etc.), this becomes unmanageable. ## What We Have `PluginMeta` already contains everything needed: - `id`, `version`, `priority` - `capabilities` (what it provides) - `dependencies` (what it requires) - `extension_points` (contracts it defines) - `implements` (contracts it fulfills) The data is there — we just need renderers. ## Current Plugin Landscape (22 plugins) ### By Layer (priority) | Layer | Priority | Plugins | |-------|----------|---------| | Foundation | 1-5 | config, workspace, pairing, logger | | Core | 10-18 | security, memory-files, persistence, compaction, context | | Services | 20-30 | ollama, ppq, knowledge, nostr, telegram, filedrop, wallet, tools | | Orchestration | 50-90 | loop, session, memory, communication, web | ### Edge Types | Type | Meaning | Example | |------|---------|---------| | `dependency` | Hard requirement, won't start without | telegram → session | | `implements` | Fulfills an extension point contract | soul → context.system_prompt | | `calls_extension` | Runtime coupling | telegram → telegram.on_message | | `capability` | Provides a named capability | ppq → llm, ollama → llm | ### Surface Coverage | Surface | Plugins | |---------|---------| | Web panels | config, communication, logger, knowledge, ppq, security, tools, wallet, nostr | | CLI | memory, nostr, pairing, telegram, tools, wallet | | Hooks | pairing, persistence, ppq, security, telegram | `loop` is the central orchestrator — defines 11 extension points that most plugins implement. ## Proposed Solution ### Phase 1: `cobot plugins inspect` CLI command Outputs the full plugin graph as JSON from the live registry: ```bash cobot plugins inspect # JSON (agent-facing) cobot plugins inspect --format mermaid # Mermaid diagram (human-facing) cobot plugins inspect --format dot # Graphviz DOT cobot plugins inspect --format table # Summary table ``` JSON schema: ```json { "plugins": { "<id>": { "id": "string", "version": "string", "priority": 0, "capabilities": [], "dependencies": [], "extension_points": [], "implements": {}, "surfaces": ["web", "cli", "tools"], "hooks": [] } }, "edges": [ {"from": "soul", "to": "context", "kind": "implements", "point": "context.system_prompt"} ] } ``` ### Phase 2: Web admin panel Interactive D3.js force-directed graph in the web plugin: - Nodes = plugins (sized by connection count, colored by layer) - Edges = colored by type (dependency/implements/capability) - Click node to see details (surfaces, hooks, extension points) - Filter by layer, surface, or edge type ### Phase 3: `docs/architecture.md` Auto-generated Mermaid diagram + manually curated narrative. Regenerated on each release. ## Acceptance Criteria - [ ] `cobot plugins inspect` outputs valid JSON matching schema above - [ ] `--format mermaid` produces a renderable Mermaid graph - [ ] Edge types are correctly classified (dependency, implements, capability) - [ ] Surface detection is accurate (web, cli, tools, hooks) - [ ] Output is generated from live registry, not static extraction
Collaborator

🔌 Plugin Architecture Review — Issue #54

Issue: Plugin introspection CLI and visualization
Scope: 3 phases — CLI inspect command, D3 web visualization, auto-generated architecture docs


Architectural Assessment

1. Does it follow the plugin pattern?

Phase 1 (CLI inspect): Should be a CLI extension point implementation — implements: {"cli.commands": "register_commands"}. This is the correct pattern (same as wallet, nostr, tools CLI commands). The inspection logic should live in PluginRegistry, not in the CLI plugin itself — the CLI just wires the command.

Phase 2 (D3 web viz): Already lives in the web plugin via get_plugin_graph_data(). This is the right place — web plugin owns the visualization, registry owns the data.

Phase 3 (auto docs): Should be a cron job or release script, not a plugin. Generates static Mermaid from the same graph data.

2. Does it conflict with existing plugins? ⚠️ Partial overlap

get_plugin_graph_data() already exists in web/plugin.py (lines 189+). It generates nodes and edges (dependency, optional, implements). PR #88 adds consumes edges.

Concern: The issue proposes the inspection logic in a CLI command, but the graph data generation is currently embedded in the web plugin. This should be refactored to PluginRegistry so both CLI and web can use it. PR #77 ("move plugin graph inspection into PluginRegistry") was attempting exactly this but is currently not mergeable.

Recommendation: The correct architecture is:

  • PluginRegistry.get_graph_data() → canonical source of truth
  • web/plugin.py → calls registry.get_graph_data() for visualization
  • cli inspect → calls registry.get_graph_data() for JSON/mermaid output

3. Scope appropriate? ⚠️ Too broad for one ticket

The issue mixes 3 distinct concerns:

  • Data extraction (registry method) — infrastructure
  • CLI rendering (JSON, mermaid, dot, table) — user-facing
  • Web visualization (D3) — user-facing
  • Doc generation (mermaid in architecture.md) — build tooling

These should be separate stories with clear dependencies.

4. Alignment with Cobot philosophy?

Self-sovereign introspection is very aligned — agents should be able to understand their own architecture. The JSON output for agents + visual output for humans is a good dual approach.

5. Missing from the proposal

  • consumes edge type — Not mentioned in the original issue but added in PR #88. The issue lists "capability" edges but consumes (reverse direction: who aggregates what) is distinct and valuable. Should be in the spec.
  • optional_dependencies edges — Listed in PluginMeta but not in the issue's edge types table.
  • Surface detection — The AC mentions detecting surfaces (web, cli, tools, hooks) but there's no surfaces field on PluginMeta. How would this be detected? By inspecting which extension points a plugin implements? This needs design.
  • No mention of calls_extension detection — The issue lists this edge type but there's no metadata for it. It would require static analysis or runtime tracing. Is this in scope?

Verdict: APPROVE with revisions

The concept is sound and well-aligned. Before breaking into stories:

  1. Refactor graph data to PluginRegistry — This is the foundation. Both CLI and web depend on it. (PR #77 attempted this — check if salvageable)
  2. Add consumes and optional_dependencies to the edge type spec — Already implemented in code but missing from issue
  3. Drop or defer calls_extension and surfaces detection — No metadata support exists. Either add PluginMeta fields first, or defer to a future issue
  4. Vendor D3.js — No CDN dependencies (already flagged in PR #88 review)
  5. Clarify Phase 3 scope — Is this a plugin, a CLI command, or a build script?

Suggested Story Breakdown (after revisions)

Story Description Depends on
S1 Refactor: move get_plugin_graph_data() to PluginRegistry
S2 CLI: cobot plugins inspect (JSON + mermaid + table) S1
S3 Web: D3 force-directed graph (PR #88 scope) S1
S4 Docs: auto-generate architecture.md mermaid S2
## 🔌 Plugin Architecture Review — Issue #54 **Issue:** Plugin introspection CLI and visualization **Scope:** 3 phases — CLI inspect command, D3 web visualization, auto-generated architecture docs --- ### Architectural Assessment #### 1. Does it follow the plugin pattern? ✅ **Phase 1 (CLI inspect):** Should be a CLI extension point implementation — `implements: {"cli.commands": "register_commands"}`. This is the correct pattern (same as wallet, nostr, tools CLI commands). The inspection logic should live in **PluginRegistry**, not in the CLI plugin itself — the CLI just wires the command. **Phase 2 (D3 web viz):** Already lives in the web plugin via `get_plugin_graph_data()`. This is the right place — web plugin owns the visualization, registry owns the data. **Phase 3 (auto docs):** Should be a cron job or release script, not a plugin. Generates static Mermaid from the same graph data. #### 2. Does it conflict with existing plugins? ⚠️ Partial overlap `get_plugin_graph_data()` already exists in `web/plugin.py` (lines 189+). It generates nodes and edges (dependency, optional, implements). PR #88 adds `consumes` edges. **Concern:** The issue proposes the inspection logic in a CLI command, but the graph data generation is currently embedded in the web plugin. This should be **refactored to PluginRegistry** so both CLI and web can use it. PR #77 ("move plugin graph inspection into PluginRegistry") was attempting exactly this but is currently not mergeable. **Recommendation:** The correct architecture is: - `PluginRegistry.get_graph_data()` → canonical source of truth - `web/plugin.py` → calls `registry.get_graph_data()` for visualization - `cli inspect` → calls `registry.get_graph_data()` for JSON/mermaid output #### 3. Scope appropriate? ⚠️ Too broad for one ticket The issue mixes 3 distinct concerns: - **Data extraction** (registry method) — infrastructure - **CLI rendering** (JSON, mermaid, dot, table) — user-facing - **Web visualization** (D3) — user-facing - **Doc generation** (mermaid in architecture.md) — build tooling These should be separate stories with clear dependencies. #### 4. Alignment with Cobot philosophy? ✅ Self-sovereign introspection is very aligned — agents should be able to understand their own architecture. The JSON output for agents + visual output for humans is a good dual approach. #### 5. Missing from the proposal - **`consumes` edge type** — Not mentioned in the original issue but added in PR #88. The issue lists "capability" edges but `consumes` (reverse direction: who aggregates what) is distinct and valuable. Should be in the spec. - **`optional_dependencies` edges** — Listed in PluginMeta but not in the issue's edge types table. - **Surface detection** — The AC mentions detecting surfaces (web, cli, tools, hooks) but there's no `surfaces` field on PluginMeta. How would this be detected? By inspecting which extension points a plugin implements? This needs design. - **No mention of `calls_extension` detection** — The issue lists this edge type but there's no metadata for it. It would require static analysis or runtime tracing. Is this in scope? --- ### Verdict: **APPROVE with revisions** The concept is sound and well-aligned. Before breaking into stories: 1. **Refactor graph data to PluginRegistry** — This is the foundation. Both CLI and web depend on it. (PR #77 attempted this — check if salvageable) 2. **Add `consumes` and `optional_dependencies` to the edge type spec** — Already implemented in code but missing from issue 3. **Drop or defer `calls_extension` and `surfaces` detection** — No metadata support exists. Either add PluginMeta fields first, or defer to a future issue 4. **Vendor D3.js** — No CDN dependencies (already flagged in PR #88 review) 5. **Clarify Phase 3 scope** — Is this a plugin, a CLI command, or a build script? ### Suggested Story Breakdown (after revisions) | Story | Description | Depends on | |-------|-------------|------------| | S1 | Refactor: move `get_plugin_graph_data()` to PluginRegistry | — | | S2 | CLI: `cobot plugins inspect` (JSON + mermaid + table) | S1 | | S3 | Web: D3 force-directed graph (PR #88 scope) | S1 | | S4 | Docs: auto-generate architecture.md mermaid | S2 |
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ultanio/cobot#54
No description provided.