feat(packaging): record Devin's native plugin layout - #156
Merged
Merged
Conversation
Moves devin out of packaging-limits.json's unrecorded map and into
packaging.json, in the existing entries' shape. The native layout
(.devin-plugin/plugin.json > .claude-plugin/plugin.json > root
plugin.json precedence) gives skills/{name}/SKILL.md, agents/{name}.md,
and a root-level hooks.json -- deliberately distinct from the shared
hooks/hooks.json every other recorded format uses here, since that path
belongs to the Claude-fallback layout one rung down the chain. command
and executable stay null: neither location is documented for this
layout, and plugin_root stays empty since no plugin-root expansion
token is documented inside a hooks.json command string (only a
same-named environment variable handed to hook processes). The
precedence chain, the marketplace convention, and the vendor's
best-effort/fail-open wording for plugin hooks live in the entry's
notes rather than new fields, matching codex_cli's Legacy-vs-AgentPlugin
story.
Regenerates examples/generated/devin.md and adds a devin-specific test
alongside the two shared-path assertions it now joins.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Moves
devinout ofpackaging-limits.json'sunrecordedmap and intopackaging.json, in the existing entries' exact shape, so chock's emitter (chock-devin-plugins) can source Devin's plugin layout from agentseam instead of hand-writing it. No version bump; no core or consumer changes.Field-by-field basis (vendor-docs, page text read 2026-09-21)
Sources:
https://docs.devin.ai/cli/extensibility/plugins/overview,https://docs.devin.ai/cli/changelog/stable.unit: "plugin"— "the plugin is the unit of installation."manifest: ".devin-plugin/plugin.json"— the native layout only. Devin's own precedence chain is native →.claude-plugin/plugin.json(Claude fallback) → a rootplugin.jsonin the open Agent Plugins 1.0.0 spec. Per the plan's guidance, the current schema has no home for a fallback chain, so the entry records the native layout and carries the chain innotes, the waycodex_cli's notes carry its Legacy-vs-AgentPlugin story.parts.skill: "skills/{name}/SKILL.md"— matches the documented tree (skills/review/SKILL.md) and is byte-identical to every other recorded plugin format's skill path (nowclaude_code, codex_cli, copilot, cursor, devin, gemini_cli).parts.subagent: "agents/{name}.md"— matches the documented tree (agents/reviewer.md); the docs notereviewer/AGENT.mdalso works, recorded innotessince the flat form matches the shape every other agent here uses.parts.hooks: "hooks.json"— at the plugin root, not the nestedhooks/hooks.jsonevery other recorded format shares. The CLI changelog's "hooks are also loaded fromhooks/hooks.json" (under "Broader Claude plugin compatibility") is the Claude-fallback layout's path, kept distinct here on purpose.parts.mcp: ".mcp.json"— "Optional MCP servers" in the documented tree.parts.command: null,parts.executable: null— no slash-command location and no bundled-executable/scripts folder is documented anywhere for the native or Claude-fallback layouts; only the Agent Plugins 1.0.0 manifest's./-prefixed MCP servercommandresolves against the plugin root, and that convention is stated to apply "only to plugins whose manifest is the root plugin.json" — not this one.PART_LIMITSreasons added for both, matching thecodex_cli/copilot/cursorpattern.plugin_root: []— hook commands do receive aDEVIN_PLUGIN_ROOTenvironment variable (CLI changelog), but whether${DEVIN_PLUGIN_ROOT}expands inside ahooks.jsoncommand string is not documented, so no expansion token is claimed.notesalso carries: therequiredPlugins/optionalPlugins/forbiddenPluginsmarketplace convention standing in for an index file (agit-subdirsource pointing atplugins/<name>/, merge-to-default-branch as the release); the vendor's own words that plugin hooks are "currently best effort and fail open ... don't rely on them for crucial guardrails yet," documented for "local Devin sessions (the CLI and Devin Desktop)" only (cloud-session andSessionStart/SessionEndfiring not established here); and that the schema has no part forrules/or the optional always-onAGENTS.md.verified: page text read 2026-09-21, both URLs cited.Vendors / matrix re-check
Checked
src/agentseam/data/vendors/devin.jsonandmatrix.jsonagainst the same vendor pages (plus the hook-surface pages:/cli/extensibility/hooks/overview,/lifecycle-hooks). No contradiction found — nothing changed. Specifically:config_path: ".devin/hooks.v1.json"matches "standalone, recommended."matrix-notes.json's "reads.claude/settings.jsonfor hooks by default" agrees with the fuller.claude/settings.json/.claude/settings.local.json/ user-level fallback list now read (read_config_from.claude, default enabled) — an elaboration, not a correction.0success,2block, other non-zero logged-not-blocking) agree withmatrix.json'sfail_mode: "open"anddevin.json'sbare_allow: "unverified".hookSpecificOutput.updatedInputatPreToolUseonly,additionalContextatPostToolUse/SessionStart/UserPromptSubmit) agree withdevin.json'sgatesandcontext_events.claims.accept_namesalready listsPermissionRequestandPostCompactionas Devin-only markers; the docs now corroborate both are real Devin hook events Claude Code never sends.Two gaps observed, left unrecorded as out of this PR's scope (packaging, not the hook/dispatch primitive):
PostCompactionhas no family-event slot in this codebase (onlypre_compact/PreCompactexists) sodevin.json'seventsmap has no key for it; and the Aug 21 changelog'sPreToolUsetool_provenancefield andStop'slast_assistant_messageaddition aren't modeled infields/verdicts. Neither is a false claim by an existing row — just unmodeled — so nothing was changed.Tests
devinfrom the "unlocated" tuple intest_proven_but_unlocated_parts_are_distinguished_from_absent_ones.test_every_matrix_agent_is_accounted_forandtest_an_agent_is_never_both_recorded_and_unrecordedpass unedited.same_path_forassertions intest_a_skill_is_literally_the_same_file_in_every_bundle_format— devin now shares the skill and subagent paths, which the generic tests caught immediately.test_devin_native_hooks_path_differs_from_the_claude_fallback_one(native hooks path, distinctness from the sharedhooks/hooks.json,executableunrecorded, emptyplugin_root) andtest_devin_plan_renders_the_native_layout_and_drops_commands(manifest render, skill/subagent paths, command dropped with its own reason) — in the shape oftest_codex_declares_its_components_and_only_one_format_carries_hooks.examples/generated/devin.md(python3 examples/generate.py) since its packaging section was stale.## [Unreleased]/### AddedCHANGELOG.mdentry, matching house convention.Verification
Checks
MATRIXrow carries averifiedrecord (version, date, method) — n/a,matrix.jsonunchanged; the newpackaging.jsonrow carries its ownverifiedrecordhttps://docs.devin.ai/cli/extensibility/plugins/overview,https://docs.devin.ai/cli/changelog/stablepytest -qpassesruff check .andruff format --check .passgit commit -s)Notes for the reviewer
Left
commandandexecutableasnullrather than guessing — no location is documented for either in the native layout.plugin_rootis an empty tuple for the same reason: the docs giveDEVIN_PLUGIN_ROOTas an environment variable, not a${...}-style string token, and only forMCPserver configs in the other two fallback layouts, not this one. Happy to widen either the moment a vendor page documents them.🤖 Generated with Claude Code