Skip to content

feat(duplo-extension-dev): file extensions under a root-level agent - #34

Open
aboutte wants to merge 3 commits into
devfrom
feature/extension-agent-field
Open

aboutte wants to merge 3 commits into
devfrom
feature/extension-agent-field

Conversation

@aboutte

@aboutte aboutte commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

When an author builds an extension, the extension skills now ask which agent it should be filed under. The answer is written as an optional agent field at the root of the manifest, next to id, name and version:

"agent": "Release Management"
// or, to suggest where the agent's heading sits in the left nav:
"agent": { "name": "Release Management", "order": 3 }
  • Starter list: DevOps, Compliance, Observability, Release Management, or a custom name the author types. A heading order is asked for only if the author wants one.
  • Grouping: the portal groups every extension with the same agent under one left-nav heading, titled with the agent's name and marked with a shared agent icon. "DevOps" merges into the existing built-in DevOps group instead of creating a second one.
  • Menus: every top-level frontend.menus[] node becomes a child of the agent's heading. Don't wrap menus in a node titled after the agent.
  • Order: a menu node's order positions it under the heading. The agent's order suggests the heading's own position; when extensions disagree, the lowest wins. The deployment's config.json ai-menu.order overrides it, keyed by the heading id (ai-suite-agent-<slug>, e.g. ai-suite-agent-release-management).
  • One agent per extension. If the author doesn't pick an agent, the field is left out. It is never written as agent: "".

Why the root, not the menu node

An earlier commit in this PR put agent on the top-level menu node. That mixed two levels in one object: the agent describes the extension, but it sat on one of its menus. It also needed a title-matching rule (a node titled like its agent became the heading), which made a node's order mean either the heading's position or the node's own. Moving agent to the root removes both.

Changes

  • reference/08-parent-child-and-menus.md: the "Filing under an agent" section now covers the root field (string or { name, order }), the starter list, menus as children of the heading, menu order vs. agent order, the config.json override, the DevOps merge, and an example manifest.
  • reference/02-authoring-guide.md: shows the optional root agent in the example manifest.
  • duplo-extension-dev/SKILL.md: "Agent" is a Phase 1 item to settle before scaffolding, including the optional heading order.
  • .claude/commands/duplo-extension.md: "agent" is in the command's clarifying-questions list.
  • templates/helloworld/manifest.json: the scaffold has "agent": "DevOps" at the root, and its DevOps wrapper node is gone, so Hello World is the top-level menu.

Depends on

The platform reads the root field only with these two PRs (same ticket, DUPLOAI-3907):

  • duplocloud-internal/duplo-ai-helpdesk#701: stores the root agent and returns it from the UI manifest endpoint. Until then, the backend drops unknown root fields when it saves an extension's manifest.
  • duplocloud-internal/duplo-ui#5280: groups the left nav and the Activated Agents page by the root agent.

Testing

  • Ten local demo extensions were converted to the root field, and each manifest validated as JSON.
  • The UI and backend behaviour is covered by unit tests in the two PRs above.
  • Not yet done: loading the converted extensions onto a platform running both PRs and checking the left nav.

🤖 Generated with Claude Code

@aboutte
aboutte requested a review from gk-duplo as a code owner October 10, 2026 00:13
@aboutte aboutte changed the title feat(duplo-extension-dev): ask which agent an extension files under feat(duplo-extension-dev): file extensions under a root-level agent Oct 12, 2026
The extension skills now ask which agent an extension is filed under and
write it as an optional `agent` field at the manifest root, beside id,
name and version: a plain string, or { name, order } where order
suggests the agent heading's position in the left nav.

- The portal groups every extension sharing an agent under one heading;
  "DevOps" merges into the built-in DevOps group
- Every top-level frontend.menus[] node renders as a child of the
  heading; a menu node's order positions it under the heading only
- The agent order suggests the heading's own position (lowest wins),
  overridable via config.json ai-menu.order keyed by the heading id
- One agent per extension; omitted rather than written as agent: ""
- The helloworld template carries { "name": "DevOps", "order": 30 } at
  the root and drops its DevOps wrapper node

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@aboutte
aboutte force-pushed the feature/extension-agent-field branch from 3e8496d to dcf9796 Compare October 12, 2026 14:50
aboutte and others added 2 commits October 12, 2026 23:02
The console now decides agent, heading order and position; the
manifest agent is the backup and the way customer extensions get their
own heading. Document validation and config.json override keys, and
update the template and samples to a root agent with no DevOps wrapper.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The backend validates the manifest agent only on new input: an upload
is rejected with HTTP 400, a deploy through an extension resource fails
its provisioning, and an extension already installed with a bad agent
still loads, re-enables and rolls back. Say so, and limit the object
form to customer extensions that set a heading order, matching the
customer bullet. Note that an agent merged into a built-in heading is
moved by the built-in's config key.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant