Browse AI Catalog skills

Why are we doing this work

A published Skill is currently invisible. Slice D creates the Catalog Item and slice E creates it automatically, but the only way to confirm either worked is a rails console. This slice makes Skills readable over GraphQL and then renders them, so pushing a SKILL.md has somewhere to point.

It is also where the user-facing documentation gets written. This is the first point at which a reader could follow the documentation end to end — commit a file, push it, open the catalog and see it — so writing the page any earlier would describe something nobody could try.

The work splits cleanly into a read surface and a UI, so it is two merge requests.

There are two things worth knowing before starting. Enabling a Skill reuses the existing Item Consumer path, with entries added to the consumer label and disclaimer maps. That writes an Item Consumer which nothing reads — there is no Consumption of a Skill by any agent yet, and the UI must not imply there is. Separately, isItemTypeEnabledInDuoSettings hardcodes true for skills because no Duo governance setting exists for them. Without that entry the type falls through to false and the page renders a misleading "inactive" alert. The governance work is tracked on a sibling issue of the epic and is out of scope here.

Two registration traps to watch. The GraphQL interfaces raise on an unregistered type, so a missed entry fails loudly, but EE::Gitlab::UrlBuilder and the frontend DETAILS_COMPONENT_MAP both fail quietly — a missing URL arm renders web_path as /explore/ai-catalog//123, and a missing map entry renders a blank page with no error.

The proof of concept merge request is where to read the whole thing end to end. The domain glossary (CONTEXT.md) and the two architecture decision records under docs/adr/ live on that branch, not on master.

Non-functional requirements

  • Documentation: this slice writes the user-facing page covering the skills/<name>/SKILL.md convention, the metadata.gitlab.visibility front matter key, and what Stale means once slice G lands.
  • Feature flag: ai_catalog_skills, project actor, checked on the route and navigation surfaces.
  • Performance: read-only GraphQL surface; the details page fetches blob content and a directory tree per skill view.
  • Testing: request specs, a feature spec against a real repository, and the type, controller, routing and Jest specs listed below.

Implementation plan

MR 1: Expose skills over GraphQL

  • backend Add Types::Ai::Catalog::SkillType with authorize :read_ai_catalog_item and authorize_granular_token permissions: :read_ai_catalog_item, implementing the AiCatalogItem interface, with fields path, directory, gitRef, blobSha, commitSha and authorName.
  • backend Add Types::Ai::Catalog::SkillVersionType implementing the AiCatalogItemVersion interface, with fields path, gitRef, blobSha, commitSha and authorName reading the def_* accessors.
  • backend Register the new types in all four places: ItemInterface RESOLVE_TYPES and orphan_types, VersionInterface RESOLVE_TYPES and orphan_types, and CustomAndFoundationalItemType RESOLVE_TYPES and possible_types. Three of these raise on an unregistered type. The AiCatalogItemType enum picks up SKILL from the model enum with no change.
  • backend Add a 'skills' arm to EE::Gitlab::UrlBuilder.
  • backend Add the request spec skill_spec.rb.
  • backend Add type unit specs for SkillType and SkillVersionType, and an EE::Gitlab::UrlBuilder spec covering the skills arm. Neither exists in the proof of concept.

MR 2: Render the skills UI

  • backend Add index and show routes in ee/config/routes/explore.rb, ee/config/routes/group.rb and ee/config/routes/project.rb, under Explore and under each namespace's automate section. Regenerate config/routing/gitlab_routes.json.
  • backend Add 'skills' to specific_vueroute? and read_ai_catalog_item to authorized_for_route? in Groups::DuoAgentsPlatformController and Projects::DuoAgentsPlatformController.
  • backend Add the explore path to both the project and group datasets in ee/app/helpers/ee/projects/duo_agents_platform_helper.rb.
  • backend Add sidebar entries in ee/lib/sidebars/groups/super_sidebar_menus/duo_agents_menu.rb and the projects equivalent.
  • backend Add controller specs for the new vueroute and routing specs for the new routes.
  • frontend Add ai_catalog_skill_details.vue showing managed-by, visibility, file path, git reference, blob SHA and last commit, a flat directory listing from paginatedTree, and the SKILL.md body rendered as markdown with the YAML front matter fenced.
  • frontend Add the GraphQL documents ai_catalog_skill.query.graphql, skill_blob_content.query.graphql, skill_directory_tree.query.graphql and ai_catalog_skill_version.fragment.graphql.
  • frontend Wire the type through constants.js, messages.js, item_type_registry.js, permissions.js, the routers, ai_catalog_nav_tabs.vue, ai_catalog_nav_actions.vue, ai_catalog_item_consumer_disclaimer.vue, and DETAILS_COMPONENT_MAP in ai_catalog_item_view.vue.
  • frontend Hardcode true for skills in isItemTypeEnabledInDuoSettings, with a comment pointing at the governance issue.
  • frontend Make ai_catalog_item_user_attribution.vue fall back to the Item Version's authorName before showing Unknown.
  • frontend Add a Jest spec for ai_catalog_skill_details.vue. It is the largest new component and has no spec in the proof of concept.
  • backend Add the feature spec ai_catalog_skill_details_spec.rb, exercising the page against a real repository.
  • Confirm the list and index pages need no changes — both derive item types from the model enum.
  • Write the user-facing documentation page.
Edited by 🤖 GitLab Bot 🤖