Platform
Other (please specify)
Feature description
OMP plugin install does not load extension — omp.hooks manifest key targets unwired resolver
Summary
After installing context-mode via omp plugin install context-mode, the plugin's event handlers (tool_call, tool_result, session_start, session_before_compact) never run. The MCP server, session continuity, and routing enforcement are all non-functional. Installing the same package in Pi (pi install npm:context-mode) works correctly.
Environment
- Platform: OMP (Oh My Pi) v3.20.1+
- context-mode: v1.0.146
- OS: Linux (Ubuntu, kernel 6.17)
- Node: v24.15.0
- Install method:
omp plugin install context-mode
Steps to Reproduce
- Run
omp plugin install context-mode
- Restart OMP
- Run
ctx doctor — observe the MCP tools respond, but the Hook support check warns: "context-mode delivers via MCP for OMP. Native OMP pre/post tool-call hooks are not yet wired by this adapter."
- Run a bash command containing
curl or wget — it is not blocked (no tool_call interception)
- Run
ctx stats after several tool calls — zero events captured (no tool_result interception)
Root Cause
The bug is a manifest key mismatch in package.json. context-mode's omp field declares:
"omp": {
"name": "context-mode",
"description": "Save 98% of your context window in OMP ...",
"hooks": "./build/adapters/omp/plugin.js"
}
OMP's plugin runtime has two separate resolvers for plugin manifests:
| Resolver |
Manifest key |
Wired to runtime? |
resolvePluginExtensionPaths() |
omp.extensions / pi.extensions |
Yes — loaded and executed via discoverAndLoadExtensions() |
resolvePluginHookPaths() |
omp.hooks / pi.hooks |
No — resolver exists but is not connected to any runtime loader |
Source: OMP's plugin-manager docs (plugin-manager-installer-plumbing.md):
"Hooks/commands resolvers exist and are exported, but this code path does not currently wire them into a runtime registry in the same way tools and extensions are wired."
Because context-mode uses omp.hooks (the unwired key), the resolver returns the path but nothing acts on it — no import, no factory call, no pi.on(...) registrations.
The plugin code itself (src/adapters/omp/plugin.ts) is already written as an extension factory:
export default function ompPlugin(pi: MinimalHookAPI): void {
pi.on("session_start", ...);
pi.on("tool_call", ...);
pi.on("tool_result", ...);
pi.on("session_before_compact", ...);
}
This is the same pattern as the Pi extension, which uses the pi.extensions key and works correctly.
Why Pi Works
Pi uses the pi manifest field:
"pi": {
"extensions": ["./build/adapters/pi/extension.js"],
"skills": ["./skills"]
}
resolvePluginExtensionPaths() picks up pi.extensions, and since extensions are wired to the runtime, the factory runs and all event handlers register.
Note: OMP's manifest resolution is omp first, fallback to pi (loader.ts:75: const manifest = pluginPkg.omp || pluginPkg.pi). Since omp exists (with hooks), it never falls through to pi (which has extensions). Even if it did fall through, the Pi extension path is different from the OMP one.
Fix
Change the omp manifest key in package.json from hooks to extensions (array format):
"omp": {
"name": "context-mode",
"description": "Save 98% of your context window in OMP — sandboxed code execution, FTS5 search, hard-block curl/wget, session continuity across compaction.",
"extensions": ["./build/adapters/omp/plugin.js"]
}
This is the only change needed. The plugin code (src/adapters/omp/plugin.ts) is already a valid extension factory — it just needs to be discovered through the extensions key so OMP's extension loader imports and executes it.
Workaround (for users now)
Apply the manifest fix locally on the installed package:
cd ~/.omp/plugins/node_modules/context-mode
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
if (pkg.omp && pkg.omp.hooks) {
pkg.omp.extensions = [pkg.omp.hooks];
delete pkg.omp.hooks;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
console.log('Fixed: omp.hooks -> omp.extensions');
}
"
Also ensure the MCP server is configured (the plugin install path does not create this automatically):
mkdir -p ~/.omp/agent
echo '{"mcpServers":{"context-mode":{"command":"context-mode"}}}' > ~/.omp/agent/mcp.json
And copy the routing rules:
cp ~/.omp/plugins/node_modules/context-mode/configs/omp/SYSTEM.md ~/.omp/agent/SYSTEM.md
Then restart OMP.
Note: This workaround will be overwritten on any omp plugin install context-mode or version upgrade until the upstream fix lands.
Additional Note
The README's OMP install section (omp plugin install context-mode) implies the plugin path handles everything including routing, but it does not create the MCP config file. Users following the "plugin path (recommended)" instructions get a plugin that appears enabled but is functionally inert. The MCP-only path (documented separately) at least provides the 11 ctx_* tools, though without routing enforcement
Use case
install the plugin in omp
Proposed solution
all in description
Platform
Other (please specify)
Feature description
OMP plugin install does not load extension —
omp.hooksmanifest key targets unwired resolverSummary
After installing context-mode via
omp plugin install context-mode, the plugin's event handlers (tool_call,tool_result,session_start,session_before_compact) never run. The MCP server, session continuity, and routing enforcement are all non-functional. Installing the same package in Pi (pi install npm:context-mode) works correctly.Environment
omp plugin install context-modeSteps to Reproduce
omp plugin install context-modectx doctor— observe the MCP tools respond, but theHook supportcheck warns: "context-mode delivers via MCP for OMP. Native OMP pre/post tool-call hooks are not yet wired by this adapter."curlorwget— it is not blocked (notool_callinterception)ctx statsafter several tool calls — zero events captured (notool_resultinterception)Root Cause
The bug is a manifest key mismatch in
package.json. context-mode'sompfield declares:OMP's plugin runtime has two separate resolvers for plugin manifests:
resolvePluginExtensionPaths()omp.extensions/pi.extensionsdiscoverAndLoadExtensions()resolvePluginHookPaths()omp.hooks/pi.hooksSource: OMP's plugin-manager docs (
plugin-manager-installer-plumbing.md):Because context-mode uses
omp.hooks(the unwired key), the resolver returns the path but nothing acts on it — no import, no factory call, nopi.on(...)registrations.The plugin code itself (
src/adapters/omp/plugin.ts) is already written as an extension factory:This is the same pattern as the Pi extension, which uses the
pi.extensionskey and works correctly.Why Pi Works
Pi uses the
pimanifest field:resolvePluginExtensionPaths()picks uppi.extensions, and since extensions are wired to the runtime, the factory runs and all event handlers register.Note: OMP's manifest resolution is
ompfirst, fallback topi(loader.ts:75:const manifest = pluginPkg.omp || pluginPkg.pi). Sinceompexists (withhooks), it never falls through topi(which hasextensions). Even if it did fall through, the Pi extension path is different from the OMP one.Fix
Change the
ompmanifest key inpackage.jsonfromhookstoextensions(array format):This is the only change needed. The plugin code (
src/adapters/omp/plugin.ts) is already a valid extension factory — it just needs to be discovered through theextensionskey so OMP's extension loader imports and executes it.Workaround (for users now)
Apply the manifest fix locally on the installed package:
Also ensure the MCP server is configured (the plugin install path does not create this automatically):
And copy the routing rules:
Then restart OMP.
Note: This workaround will be overwritten on any
omp plugin install context-modeor version upgrade until the upstream fix lands.Additional Note
The README's OMP install section (
omp plugin install context-mode) implies the plugin path handles everything including routing, but it does not create the MCP config file. Users following the "plugin path (recommended)" instructions get a plugin that appears enabled but is functionally inert. The MCP-only path (documented separately) at least provides the 11ctx_*tools, though without routing enforcementUse case
install the plugin in omp
Proposed solution
all in description