You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cursor target artifacts don't match how Cursor actually loads local plugins (manifest location, hooks doc collision, root tokens) #126
Installing a built plugin/cursor artifact into ~/.cursor/plugins/local/<name> per the generated AGENTS.md instructions produces a plugin Cursor never loads. Verified against a current Cursor build (Linux, Aug 2026) by comparing with two locally working plugins.
Evidence from working local plugins
Manifest location: both working local plugins use a rootplugin.json (one has no manifest at all and loads purely by convention). Nothing reads .cursor-plugin/plugin.json, which is where the adapter puts the Cursor manifest (with hooks and mcpServers pointers that are therefore dead).
Hooks document collision (unified plugin target): under convention loading, Cursor would discover hooks/hooks.json — but in the unified bundle that file is the Claude/Codex document (PascalCase SessionStart/PreToolUse, ${CLAUDE_PLUGIN_ROOT} commands). The actual Cursor document is at hooks/hooks-cursor.json, referenced only from the unread .cursor-plugin/plugin.json. Net effect: silently zero Cursor hooks (or worse, a Claude-format doc parsed and ignored).
Event schema itself is correct: Cursor's current first-party hook documentation confirms preToolUse + matcher: "^Shell$" + permission/updated_input/additional_context — the codec output is right; only packaging/discovery is wrong.
${CURSOR_PLUGIN_ROOT} expansion is unproven for local plugins: if Cursor doesn't export it, the emitted node "${CURSOR_PLUGIN_ROOT}/hooks/x.cursor.mjs" commands can't resolve, and AGENT_BUNDLE_PLUGIN_ROOT-anchored state resolution falls back to PATH lookups. Working local plugins use absolute or plugin-root-relative commands (user hooks run from ~/.cursor/).
Working plugins also declare MCP via a root mcp.json, not .cursor-plugin/mcp.json.
Workaround used
A hand-built install directory in the tracedecay-plugin shape: root plugin.json ("hooks": "hooks/hooks.json", "skills": "skills/"), a Cursor-format hooks/hooks.json whose commands are absolute-path sh shims exporting AGENT_BUNDLE_PLUGIN_ROOT/CURSOR_PLUGIN_ROOT before exec'ing the generated *.cursor.mjs wrappers, root mcp.json with absolute args + env anchor, and a copied skills/. The generated wrappers themselves work perfectly once reachable.
Suggested fixes
Standalone cursor target: emit root plugin.json + root mcp.json (keep .cursor-plugin/ only if some Cursor surface actually consumes it).
Unified plugin target: don't let the Claude-format hooks/hooks.json shadow the Cursor doc — either a per-host hooks dir or a root Cursor manifest pointing at hooks/hooks-cursor.json explicitly.
Re-verify ${CURSOR_PLUGIN_ROOT} against a real local-plugin install (the capability provenance cites docs + installed marketplace plugins; local-dir plugins appear to behave differently), or emit env-pinning wrapper commands.
Observed with agent-bundle preview 560124af; consumer repo: cargo-conductor.
Additional confirmation: Cursor local plugins register with ZERO settings entries — ~/.config/Cursor/User/settings.json on this machine contains no plugin references, yet the root-manifest local plugins load (their MCP servers appear as plugin-- namespaces). Discovery is purely the ~/.cursor/plugins/local/ directory scan reading root plugin.json / conventions, apparently at app startup. So the adapter's .cursor-plugin/ output is invisible to the only mechanism that exists; emitting root plugin.json + root mcp.json is the whole fix for local installs.
Additional production evidence from tonight's cargo-conductor rollout confirms the silent-failure impact of the packaging/discovery defect:
A large Cursor-managed agent fleet ran hundreds of plain cargo … and kache cargo -- … commands over several hours.
Zero commands showed a [cargo-conductor] ticket line, and the real workspace /fast/projects/tracedecay had no corresponding ledger entries under the default /fast/cache/cargo-conductor state root.
In the same environment, direct conductor proof sessions for Claude, Codex, and Cursor (proof-*, demo-*, and batch*) brokered correctly. This isolates the observed gap to host hook registration/discovery rather than daemon admission.
The current fail-open is invisible to the agent/operator, so prolonged unbrokered operation looks healthy.
This strengthens the case for an install/doctor probe that verifies each host actually discovered and invoked its generated hooks, plus a visible warning when a plugin has been installed but no hook invocation is observed across N eligible shell calls.
There is also a separate command-shape caveat for the conductor consumer: its current hook matcher recognizes cargo (including supported prefixes) but not kache cargo -- … (findCargoIndex). Once Cursor hook registration is fixed, rustc-wrapper users still need either explicit kache cargo -- … matching or documentation that this shape bypasses brokering.
Activity
ScriptedAlchemy commentedon Sep 1, 2026
Additional confirmation: Cursor local plugins register with ZERO settings entries — ~/.config/Cursor/User/settings.json on this machine contains no plugin references, yet the root-manifest local plugins load (their MCP servers appear as plugin-- namespaces). Discovery is purely the ~/.cursor/plugins/local/ directory scan reading root plugin.json / conventions, apparently at app startup. So the adapter's .cursor-plugin/ output is invisible to the only mechanism that exists; emitting root plugin.json + root mcp.json is the whole fix for local installs.
ScriptedAlchemy commentedon Sep 1, 2026
Additional production evidence from tonight's cargo-conductor rollout confirms the silent-failure impact of the packaging/discovery defect:
cargo …andkache cargo -- …commands over several hours.[cargo-conductor] ticketline, and the real workspace/fast/projects/tracedecayhad no corresponding ledger entries under the default/fast/cache/cargo-conductorstate root.proof-*,demo-*, andbatch*) brokered correctly. This isolates the observed gap to host hook registration/discovery rather than daemon admission.This strengthens the case for an install/doctor probe that verifies each host actually discovered and invoked its generated hooks, plus a visible warning when a plugin has been installed but no hook invocation is observed across N eligible shell calls.
There is also a separate command-shape caveat for the conductor consumer: its current hook matcher recognizes
cargo(including supported prefixes) but notkache cargo -- …(findCargoIndex). Once Cursor hook registration is fixed, rustc-wrapper users still need either explicitkache cargo -- …matching or documentation that this shape bypasses brokering.