feat(plugins): Support hybrid plugin bundles - #169
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| const plugin = plugins.find((plugin) => plugin.name === entry.name); | ||
| if ( | ||
| plugin?.nativeSource === target.agent || | ||
| plugin?.authoredNativeInterfaces?.[target.agent] !== undefined || | ||
| !plugin && await hasRecordedAuthoredPluginInterface( | ||
| join(canonicalPluginDir, entry.name), | ||
| target.agent, | ||
| ) | ||
| ) {continue;} |
There was a problem hiding this comment.
Bug: An uncaught exception in prunePluginOutputs can crash CLI commands like sync and remove if a plugin's marker file is corrupted. The call to hasRecordedAuthoredPluginInterface should be wrapped in a try-catch block.
Severity: HIGH
Suggested Fix
Wrap the call to hasRecordedAuthoredPluginInterface within the loop in prunePluginOutputs in a try-catch block. This will prevent a corrupted marker file for a single plugin from crashing the entire command. The error should be handled gracefully, for example by logging a warning and continuing the pruning process.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/dotagents/src/plugins/runtime/writer.ts#L276-L284
Potential issue: The `prunePluginOutputs` function does not handle errors that may arise
from its call to `hasRecordedAuthoredPluginInterface`. This downstream function can
throw an error if it encounters a corrupted plugin marker file (e.g.,
`.dotagents-authored-interfaces`). Because the call is not wrapped in a `try-catch`
block, the error propagates uncaught up the call stack. This will crash user-facing CLI
commands like `dotagents sync`, `dotagents remove`, or `dotagents install` when they
operate on a plugin with a corrupted marker file that is being removed or is otherwise
not in the current configuration.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 486d280. Configure here.
…ndles # Conflicts: # packages/dotagents/src/cli/index.test.ts # packages/dotagents/src/plugins/store.ts
| installedPlugin?.nativeSource === target.agent || | ||
| installedPlugin?.authoredNativeInterfaces?.[target.agent]?.fallback === true || | ||
| !installedPlugin && await hasRecordedNativePluginFallback( | ||
| join(canonicalPluginDir, entry.name), | ||
| target.agent, | ||
| ) |
There was a problem hiding this comment.
Bug: The sync and remove commands can crash due to an unhandled exception when pruning an orphaned plugin with a corrupted .dotagents-native-fallbacks marker file.
Severity: MEDIUM
Suggested Fix
Wrap the call to hasRecordedNativePluginFallback within the prunePluginOutputs function in a try-catch block. Log the error and continue the pruning process instead of allowing the command to crash.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/dotagents/src/plugins/runtime/writer.ts#L279-L284
Potential issue: The `prunePluginOutputs` function calls
`hasRecordedNativePluginFallback` for orphaned plugin directories that are not listed in
`agents.toml`. If the `.dotagents-native-fallbacks` marker file in one of these
directories is corrupted, for instance through manual user edits, the
`hasRecordedNativePluginFallback` function will throw an exception. This exception is
not caught, which causes the `sync` or `remove` command to crash, preventing the cleanup
of orphaned plugin artifacts if a marker file has become invalid.

Allow valid Agent Plugins v1 roots to coexist with authored Claude, Cursor, or Codex manifests and legacy root resources instead of rejecting migration bundles. The portable root remains the source of truth for identity, metadata, skills, MCP, and target output. Target adapters ignore reproducible native manifests and generate managed adapters; they retain native manifests byte-for-byte only as matching-client fallbacks for commands, hooks, custom fields, or other behavior the portable model cannot express. Native-only imports keep their existing conservative behavior, and generated adapters are never read back as source input.
Discovery and installed-bundle provenance now track retained fallbacks explicitly, validate fallback identity and paths at the matching selected-target boundary, and prevent native resources from leaking into other clients. Install, sync, list, and doctor expose the durable compatibility state, while lifecycle reconciliation handles managed-to-fallback and fallback-to-managed transitions without changing
agents.tomloragents.lock. Invalid portable roots still fail without downgrading to native or generalized legacy parsing.Fixes #161