Skip to content

Plugin System

CodexA provides a plugin architecture with 22 hook points for extending and customizing every stage of the pipeline.

Quick Start

Create a plugin:

bash
codex plugin new my-formatter --hooks POST_SEARCH,POST_AI

This generates a ready-to-use plugin file in .codex/plugins/.

Plugin Base Class

All plugins extend PluginBase:

python
from semantic_code_intelligence.plugins import PluginBase, PluginMetadata, PluginHook

class MyPlugin(PluginBase):
    def metadata(self) -> PluginMetadata:
        return PluginMetadata(
            name="my-plugin",
            version="0.1.0",
            description="My custom plugin",
            author="Your Name",
            hooks=[PluginHook.POST_SEARCH, PluginHook.POST_AI],
        )

    def activate(self, context: dict) -> None:
        """Called when the plugin is activated."""
        pass

    def deactivate(self) -> None:
        """Called when the plugin is deactivated."""
        pass

    def on_hook(self, hook: PluginHook, data: dict) -> dict:
        """Called when a registered hook fires."""
        if hook == PluginHook.POST_SEARCH:
            # Modify search results
            data["results"] = self.filter_results(data["results"])
        return data

def create_plugin():
    return MyPlugin()

Hook Points

Indexing

HookWhenData
PRE_INDEXBefore indexing startsFile list, config
POST_INDEXAfter indexing completesIndex stats
ON_CHUNKEach chunk is createdChunk content, metadata
HookWhenData
PRE_SEARCHBefore search executionQuery, parameters
POST_SEARCHAfter results rankedResults list

Analysis

HookWhenData
PRE_ANALYSISBefore code analysisTarget info
POST_ANALYSISAfter analysis completesAnalysis results

AI

HookWhenData
PRE_AIBefore LLM callPrompt, context
POST_AIAfter LLM responseResponse text
ON_STREAMEach streaming tokenToken event

Workflow Intelligence

HookWhenData
PRE_HOTSPOT_ANALYSISBefore hotspot scoringSymbols, config
POST_HOTSPOT_ANALYSISAfter hotspot reportReport
PRE_IMPACT_ANALYSISBefore impact BFSTarget, graph
POST_IMPACT_ANALYSISAfter impact reportReport
PRE_TRACEBefore symbol traceTarget, graph
POST_TRACEAfter trace resultResult

Tools

HookWhenData
REGISTER_TOOLPlugin can register toolsTool list
PRE_TOOL_INVOKEBefore tool executionInvocation
POST_TOOL_INVOKEAfter tool executionResult

Other

HookWhenData
ON_FILE_CHANGEFile change detectedFile path, event
CUSTOM_VALIDATIONCustom validation passValidation data
CUSTOMUser-definedUser-defined

Plugin Discovery

Plugins are discovered from .codex/plugins/. Each file must export a create_plugin() factory function.

Plugin Lifecycle

  1. RegisterPluginManager.register(plugin) adds the plugin
  2. ActivatePluginManager.activate(name, context) calls plugin.activate()
  3. Dispatch — Hooks are dispatched in registration order; each plugin can modify data
  4. DeactivatePluginManager.deactivate(name) calls plugin.deactivate()

CLI Management

bash
codex plugin list              # List discovered plugins
codex plugin info my-plugin    # Plugin details
codex plugin new name          # Scaffold new plugin

Custom Tool Registration

Plugins can register tools exposed via CLI, HTTP bridge, and MCP:

python
def on_hook(self, hook, data):
    if hook == PluginHook.REGISTER_TOOL:
        data["tools"].append({
            "name": "my_custom_search",
            "description": "Domain-specific search",
            "parameters": {
                "query": {"type": "string", "required": True},
                "domain": {"type": "string", "required": False},
            },
            "handler": self.custom_search,
        })
    return data

Plugin tools cannot overwrite built-in tool names.

Released under the MIT License.