-
Notifications
You must be signed in to change notification settings - Fork 1
feat(descriptions): intent-first tool descriptions with dynamic Related resolution #169
Description
Summary
Rewrite all 32 remaining tool descriptions from old UPPERCASE PREFIX format to intent-first agentic format with dynamic cross-references. The "Related:" section in descriptions must be resolved at runtime — references to disabled tools (via USE_*, GITLAB_DENIED_TOOLS_REGEX, tier/version gating, or all-actions-denied) are automatically stripped.
Scope: 32 tool descriptions + 1 implementation change + ~60 test assertions + documentation
Problem
After partial implementation in #149 (commit 82718ab), only 10/44 tools have the new intent-first format. The remaining 32 use old UPPERCASE PREFIX style ("BROWSE labels...", "MANAGE pipelines..."), which:
- Wastes context — "BROWSE" and "MANAGE" prefixes are redundant (tool names already contain this info)
- Missing disambiguation — agents confuse
browse_usersvsbrowse_members,browse_commitsvsbrowse_refs - No cross-references — agents don't discover related tools (e.g., don't know
manage_pipeline_jobexists when looking atbrowse_pipelines) - Static references — current "Related:" in the 10 updated tools reference tools that may be disabled, creating dead-end hints
Implementation: Dynamic Related Resolution
Architecture
Add a second pass to buildToolLookupCache() in src/registry-manager.ts that strips "Related:" references to unavailable tools:
private buildToolLookupCache(): void {
this.toolLookupCache.clear();
// ... existing first pass: filter tools and add to cache ...
// Second pass: resolve Related references against available tools
const availableToolNames = new Set(this.toolLookupCache.keys());
for (const [toolName, tool] of this.toolLookupCache) {
const resolved = resolveRelatedReferences(tool.description, availableToolNames);
if (resolved !== tool.description) {
this.toolLookupCache.set(toolName, { ...tool, description: resolved });
}
}
}Resolution Function
New utility in src/utils/description-utils.ts:
/**
* Strip "Related:" section references to unavailable tools.
* If all referenced tools are unavailable, the entire "Related:" clause is removed.
*
* Format: "... Related: tool_name purpose, tool_name2 purpose."
* Multiple items separated by commas. Each starts with a tool name (browse_*/manage_*).
*/
export function resolveRelatedReferences(
description: string,
availableTools: Set<string>
): string {
const relatedMatch = description.match(/\s*Related:\s*(.+?)\.?\s*$/);
if (!relatedMatch) return description;
const baseDescription = description.substring(0, relatedMatch.index!);
const relatedContent = relatedMatch[1];
// Split by comma, keep only items whose tool is available
const items = relatedContent.split(",").map((s) => s.trim());
const available = items.filter((item) => {
const toolRef = item.match(/^((?:browse|manage)_\w+)\b/);
return toolRef && availableTools.has(toolRef[1]);
});
if (available.length === 0) {
return baseDescription.trimEnd();
}
return `${baseDescription.trimEnd()} Related: ${available.join(", ")}.`;
}Gating Scenarios Handled
| Scenario | Effect on Related |
|---|---|
USE_MRS=false |
browse_pipelines description drops "Related: manage_pipeline..." since manage_pipeline is also gated |
GITLAB_DENIED_TOOLS_REGEX="manage_.*" |
All "Related: manage_X..." references stripped |
GITLAB_READ_ONLY_MODE=true |
All manage_* tools filtered, so "Related: manage_X..." stripped |
| Tier gating removes tool | Related reference stripped |
GITLAB_DENIED_ACTIONS removes ALL actions |
Tool effectively removed, Related stripped |
Custom GITLAB_TOOL_* override |
Overrides entire description including Related (user controls) |
New Tool Descriptions (32 tools)
Format Rules
[Intent verb phrase]. Actions: [action (explanation), ...]. [Related: tool_name purpose, tool_name2 purpose.]
- Intent first: what the agent should use this tool for (verb phrase)
- Actions: concise parenthetical explanations, no quotes around action names
- Related: only for disambiguation or non-obvious pairings; omit trailing period if removed at runtime
Files Entity (src/entities/files/registry.ts)
browse_files:
Explore project file structure and read source code. Actions: tree (list directory contents with recursive depth control), content (read file at specific ref/branch), download_attachment (get uploaded file by secret+filename). Related: manage_files to create/update files.
manage_files:
Create, update, or upload repository files. Actions: single (create/update one file with commit message), batch (atomic multi-file commit), upload (add attachment returning markdown link). Related: browse_files to read existing files.
MRs Entity (src/entities/mrs/registry.ts)
browse_merge_requests:
Find and inspect merge requests. Actions: list (filter by state/author/reviewer/labels/branch), get (MR details by IID or source branch), diffs (file-level changes with inline suggestions), compare (diff between any two refs). Related: manage_merge_request to create/update/merge.
browse_mr_discussions:
Read discussion threads and draft review notes on merge requests. Actions: list (all threads with resolution status), drafts (unpublished draft notes), draft (single draft details). Related: manage_mr_discussion to comment, manage_draft_notes to create drafts.
manage_merge_request:
Create, update, merge, or approve merge requests. Actions: create (new MR from source to target), update (title/description/assignees/reviewers/labels), merge (into target branch), approve/unapprove (review approval), get_approval_state (current approvals). Related: browse_merge_requests for discovery.
manage_mr_discussion:
Post comments, start threads, and suggest code changes on merge requests. Actions: comment (simple note), thread (line-level discussion), reply (to existing thread), update (edit note text), resolve (toggle thread resolution), suggest (code suggestion block), apply_suggestion/apply_suggestions (accept code suggestions). Related: browse_mr_discussions to read threads.
manage_draft_notes:
Create and manage unpublished review comments on merge requests. Actions: create (new draft), update (modify text), publish (make single draft visible), publish_all (submit entire review), delete (discard draft). Related: browse_mr_discussions action 'drafts' to list existing drafts.
Labels Entity (src/entities/labels/registry.ts)
browse_labels:
List and inspect project or group labels. Actions: list (all labels with search filtering), get (single label by ID or name). Related: manage_label to create/update/delete.
manage_label:
Create, update, or delete project/group labels. Actions: create (name + hex color required), update (modify properties), delete (remove permanently). Related: browse_labels for discovery.
Pipelines Entity (src/entities/pipelines/registry.ts)
browse_pipelines:
Monitor CI/CD pipelines and read job logs. Actions: list (filter by status/ref/source/username), get (pipeline details), jobs (list pipeline jobs), triggers (bridge/trigger jobs), job (single job details), logs (job console output). Related: manage_pipeline to trigger/retry/cancel, manage_pipeline_job for individual jobs.
manage_pipeline:
Trigger, retry, or cancel CI/CD pipelines. Actions: create (run pipeline on ref with variables), retry (re-run failed jobs), cancel (stop running pipeline). Related: browse_pipelines for monitoring.
manage_pipeline_job:
Control individual CI/CD jobs within a pipeline. Actions: play (trigger manual/delayed job with variables), retry (re-run single job), cancel (stop running job). Related: browse_pipelines actions 'job'/'logs' for job details.
Snippets Entity (src/entities/snippets/registry.ts)
browse_snippets:
Find and read code snippets with versioning support. Actions: list (personal/project/public scope with filtering), get (snippet metadata or raw file content). Related: manage_snippet to create/update.
manage_snippet:
Create, update, or delete code snippets with multi-file support. Actions: create (new snippet with files and visibility), update (modify content/metadata, file operations), delete (remove permanently). Related: browse_snippets for discovery.
Variables Entity (src/entities/variables/registry.ts)
browse_variables:
List and inspect CI/CD variables for projects or groups. Actions: list (all variables with pagination), get (single variable by key with environment scope filter). Related: manage_variable to create/update/delete.
manage_variable:
Create, update, or delete CI/CD variables with environment scoping. Actions: create (key + value, set scope/protection/masking), update (modify value or settings), delete (remove permanently). Related: browse_variables for discovery.
Wiki Entity (src/entities/wiki/registry.ts)
browse_wiki:
Read wiki pages in projects or groups. Actions: list (all pages with metadata), get (page content by slug). Related: manage_wiki to create/update/delete.
manage_wiki:
Create, update, or delete wiki pages. Actions: create (new page with title/content/format), update (modify content or title), delete (remove permanently). Related: browse_wiki to read pages.
Releases Entity (src/entities/releases/registry.ts)
browse_releases:
View project releases and asset download links. Actions: list (releases sorted by date), get (release details by tag name), assets (download link list for release). Related: manage_release to create/publish.
manage_release:
Create, update, or delete project releases with asset management. Actions: create (release from tag with notes/assets), update (modify metadata), delete (remove release, tag preserved), create_link (add asset URL), delete_link (remove asset). Related: browse_releases for discovery.
Refs Entity (src/entities/refs/registry.ts)
browse_refs:
Inspect branches, tags, and their protection rules. Actions: list_branches, get_branch, list_tags, get_tag, list_protected_branches, get_protected_branch, list_protected_tags (protection details and access levels). Related: manage_ref to create/delete/protect, browse_commits for commit history.
manage_ref:
Create, delete, and protect branches and tags. Actions: create_branch (from ref), delete_branch, protect_branch (set allowed roles), unprotect_branch, update_branch_protection, create_tag (annotated or lightweight), delete_tag, protect_tag, unprotect_tag. Related: browse_refs for inspection.
Members Entity (src/entities/members/registry.ts)
browse_members:
View team members and access levels in projects or groups. Actions: list_project, list_group, get_project, get_group (direct members), list_all_project, list_all_group (includes inherited). Levels: Guest(10), Reporter(20), Developer(30), Maintainer(40), Owner(50). Related: manage_member to add/remove, browse_users to find users by name.
manage_member:
Add, remove, or update access levels for project/group members. Actions: add_to_project, add_to_group (with access level + optional expiry), remove_from_project, remove_from_group, update_project, update_group (change access level). Related: browse_members for current membership.
Milestones Entity (src/entities/milestones/registry.ts)
browse_milestones:
Track milestone progress with associated issues and MRs. Actions: list (filter by state/title/search), get (milestone details), issues (items in milestone), merge_requests (MRs targeting milestone), burndown (chart data for sprint tracking). Related: manage_milestone to create/update.
manage_milestone:
Create, update, or delete project/group milestones. Actions: create (title + optional dates/description), update (modify properties or close/activate), delete (remove permanently), promote (elevate project milestone to group). Related: browse_milestones for progress tracking.
Integrations Entity (src/entities/integrations/registry.ts)
browse_integrations:
Discover active project integrations and their configuration. Actions: list (all active: Slack, Jira, Discord, Teams, Jenkins, etc.), get (specific integration settings by slug). Related: manage_integration to configure/disable.
manage_integration:
Configure or disable project integrations (50+ supported). Actions: update (enable/modify with integration-specific config), disable (deactivate integration). Note: gitlab-slack-application requires OAuth install from GitLab UI. Related: browse_integrations for discovery.
Webhooks Entity (src/entities/webhooks/registry.ts)
browse_webhooks:
List and inspect webhook configurations for projects or groups. Actions: list (all webhooks with event types and status), get (webhook details by ID). Related: manage_webhook to create/update/delete/test.
manage_webhook:
Create, update, delete, or test webhooks for event-driven automation. Actions: create (URL + event types + optional secret), update (modify settings), delete (remove), test (trigger delivery for specific event). Related: browse_webhooks for inspection.
Work Items Entity (src/entities/workitems/registry.ts)
browse_work_items:
Find and inspect issues, epics, tasks, and other work items. Actions: list (groups return epics, projects return issues/tasks, filter by type/state/labels), get (by numeric ID or namespace+iid from URL path). Related: manage_work_item to create/update/delete.
manage_work_item:
Create, update, delete, or link work items (issues, epics, tasks). Actions: create (epics need GROUP namespace, issues/tasks need PROJECT), update (widgets: dates, time tracking, weight, iterations, health, progress, hierarchy), delete (permanent), add_link/remove_link (BLOCKS/IS_BLOCKED_BY/RELATES_TO). Related: browse_work_items for discovery.
Search Entity (src/entities/search/registry.ts)
browse_search:
Search across GitLab resources globally or within a scope. Actions: global (entire instance), project (within specific project), group (within specific group). Searchable: projects, issues, merge_requests, milestones, users, blobs (code), commits, wiki_blobs, notes.
Context Entity (src/entities/context/registry.ts)
manage_context:
View and manage runtime session configuration. Actions: show (current host/preset/scope/mode), list_presets (available tool configurations), list_profiles (OAuth users), switch_preset (change active preset), switch_profile (change OAuth user), set_scope (restrict to namespace), reset (restore initial state).
Test Changes
Strategy
Replace old UPPERCASE checks with entity-keyword and action-word assertions. New tests verify:
- Description contains the entity domain keyword (not the prefix)
- Description mentions all expected actions
- Description format starts with intent verb (not uppercase label)
Files to Update (21 test files, ~80 assertions)
tests/unit/entities/files/registry.test.ts
- expect(tool?.description).toContain("BROWSE");
+ expect(tool?.description).toContain("file structure");
+ expect(tool?.description).toContain("tree");
+ expect(tool?.description).toContain("content");
- expect(tool?.description).toContain("MANAGE");
+ expect(tool?.description).toContain("Create, update, or upload");
+ expect(tool?.description).toContain("single");
+ expect(tool?.description).toContain("batch");tests/unit/entities/mrs/registry.test.ts
# browse_merge_requests
- expect(tool!.description).toContain("BROWSE");
+ expect(tool!.description).toContain("merge requests");
expect(tool!.description).toContain("list");
expect(tool!.description).toContain("get");
expect(tool!.description).toContain("diffs");
expect(tool!.description).toContain("compare");
# browse_mr_discussions
- expect(tool!.description).toContain("BROWSE");
+ expect(tool!.description).toContain("discussion threads");
expect(tool!.description).toContain("list");
expect(tool!.description).toContain("drafts");
expect(tool!.description).toContain("draft");
# manage_merge_request
- expect(tool!.description).toContain("MANAGE");
+ expect(tool!.description).toContain("merge requests");
expect(tool!.description).toContain("create");
expect(tool!.description).toContain("update");
expect(tool!.description).toContain("merge");
expect(tool!.description).toContain("approve");
expect(tool!.description).toContain("unapprove");
expect(tool!.description).toContain("get_approval_state");
# manage_mr_discussion
- expect(tool!.description).toContain("MANAGE");
+ expect(tool!.description).toContain("comments"); // or "threads"
expect(tool!.description).toContain("comment");
expect(tool!.description).toContain("thread");
expect(tool!.description).toContain("reply");
# ... actions stay the same
# manage_draft_notes
- expect(tool!.description).toContain("MANAGE");
+ expect(tool!.description).toContain("draft");
expect(tool!.description).toContain("create");
expect(tool!.description).toContain("publish");
expect(tool!.description).toContain("delete");tests/unit/entities/labels/registry.test.ts
- expect(tool?.description).toContain("BROWSE labels");
+ expect(tool?.description).toContain("labels");
expect(tool?.description).toContain("list");
expect(tool?.description).toContain("get");
- expect(tool?.description).toContain("MANAGE labels");
+ expect(tool?.description).toContain("labels");
expect(tool?.description).toContain("create");
expect(tool?.description).toContain("update");
expect(tool?.description).toContain("delete");tests/unit/entities/pipelines/registry.test.ts
- expect(tool?.description).toContain("BROWSE pipelines");
+ expect(tool?.description).toContain("CI/CD pipelines");
expect(tool?.description).toContain("list");
expect(tool?.description).toContain("get");
expect(tool?.description).toContain("jobs");
expect(tool?.description).toContain("triggers");
expect(tool?.description).toContain("logs");
- expect(tool?.description).toContain("MANAGE pipelines");
+ expect(tool?.description).toContain("pipelines");
expect(tool?.description).toContain("create");
expect(tool?.description).toContain("retry");
expect(tool?.description).toContain("cancel");
- expect(tool?.description).toContain("MANAGE pipeline jobs");
+ expect(tool?.description).toContain("individual CI/CD jobs");
expect(tool?.description).toContain("play");
expect(tool?.description).toContain("retry");
expect(tool?.description).toContain("cancel");tests/unit/entities/variables/registry.test.ts
- expect(tool?.description).toContain("BROWSE");
- expect(tool?.description).toContain("CI/CD variables");
+ expect(tool?.description).toContain("CI/CD variables");
- expect(tool?.description).toContain("MANAGE");
- expect(tool?.description).toContain("CI/CD variables");
+ expect(tool?.description).toContain("CI/CD variables");
+ expect(tool?.description).toContain("environment scoping");tests/unit/entities/wiki/registry.test.ts
- expect(tool?.description).toContain("BROWSE wiki");
+ expect(tool?.description).toContain("wiki pages");
expect(tool?.description).toContain("list");
expect(tool?.description).toContain("get");
- expect(tool?.description).toContain("MANAGE wiki");
+ expect(tool?.description).toContain("wiki pages");
expect(tool?.description).toContain("create");
expect(tool?.description).toContain("update");
expect(tool?.description).toContain("delete");tests/unit/entities/releases/registry.test.ts
- expect(tool!.description).toContain("BROWSE");
+ expect(tool!.description).toContain("releases");
+ expect(tool!.description).toContain("assets");
- expect(tool!.description).toContain("MANAGE");
+ expect(tool!.description).toContain("releases");
+ expect(tool!.description).toContain("create");tests/unit/entities/webhooks/registry.test.ts
- expect(tool!.description).toContain("BROWSE webhooks");
+ expect(tool!.description).toContain("webhook configurations");
- expect(tool!.description).toContain("Manage webhooks with full CRUD");
+ expect(tool!.description).toContain("webhooks");
+ expect(tool!.description).toContain("create");
+ expect(tool!.description).toContain("test");tests/unit/entities/integrations/registry.test.ts
- expect(tool!.description).toContain("BROWSE project integrations");
+ expect(tool!.description).toContain("integrations");
+ expect(tool!.description).toContain("list");
- expect(tool!.description).toContain("MANAGE project integrations");
+ expect(tool!.description).toContain("integrations");
+ expect(tool!.description).toContain("update");
expect(tool!.description).toContain("Slack");
expect(tool!.description).toContain("Jira");
expect(tool!.description).toContain("Discord");
expect(tool!.description).toContain("gitlab-slack-application cannot be created via API");tests/unit/entities/milestones/registry.test.ts
- expect(tool?.description).toContain("BROWSE milestones");
+ expect(tool?.description).toContain("milestone");
expect(tool?.description).toContain("list");
expect(tool?.description).toContain("get");
expect(tool?.description).toContain("issues");
expect(tool?.description).toContain("merge_requests");
expect(tool?.description).toContain("burndown");
- expect(tool?.description).toContain("MANAGE milestones");
+ expect(tool?.description).toContain("milestone");
expect(tool?.description).toContain("create");
expect(tool?.description).toContain("update");
expect(tool?.description).toContain("delete");
expect(tool?.description).toContain("promote");tests/unit/entities/milestones/index.test.ts
- expect(browseTool?.description).toContain("BROWSE");
+ expect(browseTool?.description).toContain("milestone");
- expect(manageTool?.description).toContain("MANAGE");
+ expect(manageTool?.description).toContain("milestone");tests/unit/entities/workitems/registry.test.ts
- expect(tool?.description).toContain("BROWSE work items");
+ expect(tool?.description).toContain("work items");
expect(tool?.description).toContain("list");
expect(tool?.description).toContain("get");
- expect(tool?.description).toContain("MANAGE work items");
+ expect(tool?.description).toContain("work items");
expect(tool?.description).toContain("create");
expect(tool?.description).toContain("update");
expect(tool?.description).toContain("delete");tests/unit/entities/search/registry.test.ts
- expect(browseSearchTool?.description).toContain("SEARCH GitLab resources");
+ expect(browseSearchTool?.description).toContain("Search across GitLab");
expect(browseSearchTool?.description).toContain("global");
expect(browseSearchTool?.description).toContain("project");
expect(browseSearchTool?.description).toContain("group");tests/unit/entities/context/registry.test.ts
- expect(tool?.description).toContain("CONTEXT");
+ expect(tool?.description).toContain("session configuration");
+ expect(tool?.description).toContain("show");
+ expect(tool?.description).toContain("switch_preset");New Tests Required
tests/unit/utils/description-utils.test.ts (new file)
describe("resolveRelatedReferences", () => {
it("returns description unchanged when no Related section", () => {
const desc = "Find projects. Actions: search, list, get.";
expect(resolveRelatedReferences(desc, new Set(["manage_project"]))).toBe(desc);
});
it("keeps Related when referenced tool is available", () => {
const desc = "Find projects. Related: manage_project to create.";
const result = resolveRelatedReferences(desc, new Set(["manage_project"]));
expect(result).toContain("Related: manage_project");
});
it("strips Related when referenced tool is unavailable", () => {
const desc = "Find projects. Related: manage_project to create.";
const result = resolveRelatedReferences(desc, new Set(["browse_labels"]));
expect(result).toBe("Find projects.");
});
it("keeps only available tools from comma-separated list", () => {
const desc = "Read discussions. Related: manage_mr_discussion to comment, manage_draft_notes to create.";
const result = resolveRelatedReferences(desc, new Set(["manage_mr_discussion"]));
expect(result).toBe("Read discussions. Related: manage_mr_discussion to comment.");
expect(result).not.toContain("manage_draft_notes");
});
it("handles all tools unavailable in multi-reference", () => {
const desc = "Monitor CI/CD. Related: manage_pipeline to retry, manage_pipeline_job for jobs.";
const result = resolveRelatedReferences(desc, new Set(["browse_labels"]));
expect(result).toBe("Monitor CI/CD.");
});
it("handles browse_ references correctly", () => {
const desc = "Create refs. Related: browse_refs for inspection.";
const result = resolveRelatedReferences(desc, new Set(["browse_refs"]));
expect(result).toContain("browse_refs");
});
});tests/unit/registry-manager.test.ts (add to existing)
describe("dynamic Related resolution", () => {
it("strips Related references when USE_* disables referenced tool", () => {
// With USE_MRS=false, manage_merge_request is unavailable
// browse_files description should NOT reference manage_files if USE_FILES=false
// Test by checking description after cache build with specific flags
});
it("preserves Related when referenced tool is available", () => {
// Default config: all tools enabled
// browse_labels should contain "Related: manage_label"
});
it("strips Related when GITLAB_DENIED_TOOLS_REGEX matches referenced tool", () => {
// GITLAB_DENIED_TOOLS_REGEX=manage_label
// browse_labels should NOT contain "Related:"
});
it("strips Related in read-only mode for manage_ references", () => {
// GITLAB_READ_ONLY_MODE=true
// All "Related: manage_*" should be stripped
});
});Documentation Changes
1. Auto-generated: docs/TOOLS.md
No manual action. Regenerated by yarn list-tools --export --toc during semantic-release.
2. Manual: docs/public/llms.txt
Update descriptions to match new wording. Current descriptions are already reasonably aligned but should be refreshed after the description changes are implemented.
3. New section in docs/advanced/customization.md
Add after the "Dynamic Tool Descriptions" section:
## Dynamic Cross-References
Tool descriptions include "Related:" hints that reference complementary tools. These references are **automatically resolved at runtime** — if a referenced tool is disabled, the reference is stripped from the description.
### How It Works
When the tool cache is built, each description's "Related:" section is checked against available tools:
- If the referenced tool is enabled → reference appears in description
- If the referenced tool is disabled → reference is stripped
- If ALL references are disabled → entire "Related:" clause removed
### Example
With default configuration, `browse_labels` description includes:List and inspect project or group labels. Actions: list, get. Related: manage_label to create/update/delete.
With `GITLAB_READ_ONLY_MODE=true` (all manage_* tools disabled):
List and inspect project or group labels. Actions: list, get.
### Why This Matters
AI agents receive tool descriptions via `list_tools`. Dead references to unavailable tools:
- Waste context tokens
- Confuse routing (agent tries to call unavailable tool)
- Create poor user experience (agent suggests actions that fail)
Dynamic resolution ensures descriptions always reflect the actual tool surface available to the agent.
### Interaction with Custom Descriptions
Custom descriptions set via `GITLAB_TOOL_*` environment variables **override the entire description** including any "Related:" section. Dynamic resolution only applies to default (built-in) descriptions.
File Change Summary
| File | Change Type |
|---|---|
src/utils/description-utils.ts |
New file — resolveRelatedReferences() |
src/registry-manager.ts |
Add second pass calling resolveRelatedReferences() |
src/entities/files/registry.ts |
Update 2 descriptions |
src/entities/mrs/registry.ts |
Update 5 descriptions |
src/entities/labels/registry.ts |
Update 2 descriptions |
src/entities/pipelines/registry.ts |
Update 3 descriptions |
src/entities/snippets/registry.ts |
Update 2 descriptions |
src/entities/variables/registry.ts |
Update 2 descriptions |
src/entities/wiki/registry.ts |
Update 2 descriptions |
src/entities/releases/registry.ts |
Update 2 descriptions |
src/entities/refs/registry.ts |
Update 2 descriptions |
src/entities/members/registry.ts |
Update 2 descriptions |
src/entities/milestones/registry.ts |
Update 2 descriptions |
src/entities/integrations/registry.ts |
Update 2 descriptions |
src/entities/webhooks/registry.ts |
Update 2 descriptions |
src/entities/workitems/registry.ts |
Update 2 descriptions |
src/entities/search/registry.ts |
Update 1 description |
src/entities/context/registry.ts |
Update 1 description |
tests/unit/utils/description-utils.test.ts |
New file — unit tests for resolver |
tests/unit/entities/files/registry.test.ts |
Update assertions |
tests/unit/entities/mrs/registry.test.ts |
Update assertions |
tests/unit/entities/labels/registry.test.ts |
Update assertions |
tests/unit/entities/pipelines/registry.test.ts |
Update assertions |
tests/unit/entities/variables/registry.test.ts |
Update assertions |
tests/unit/entities/wiki/registry.test.ts |
Update assertions |
tests/unit/entities/releases/registry.test.ts |
Update assertions |
tests/unit/entities/webhooks/registry.test.ts |
Update assertions |
tests/unit/entities/integrations/registry.test.ts |
Update assertions |
tests/unit/entities/milestones/registry.test.ts |
Update assertions |
tests/unit/entities/milestones/index.test.ts |
Update assertions |
tests/unit/entities/workitems/registry.test.ts |
Update assertions |
tests/unit/entities/search/registry.test.ts |
Update assertions |
tests/unit/entities/context/registry.test.ts |
Update assertions |
tests/unit/entities/members/registry.test.ts |
Add description assertions |
tests/unit/entities/snippets/registry.test.ts |
Add description assertions |
tests/unit/entities/refs/registry.test.ts |
Add description assertions |
tests/unit/registry-manager.test.ts |
Add Related resolution tests |
docs/advanced/customization.md |
Add "Dynamic Cross-References" section |
docs/public/llms.txt |
Refresh descriptions |
Semver Impact
MINOR version bump (feat:):
- No tools renamed or removed
- No breaking schema changes
- Description text changes are non-breaking (informational only)
- New runtime behavior (Related stripping) is additive
Acceptance Criteria
- All 44 tools use intent-first descriptions (zero UPPERCASE PREFIX remaining)
- All descriptions include
Related:where disambiguation is valuable -
resolveRelatedReferences()strips dead references when tools are gated -
GITLAB_READ_ONLY_MODE=truestrips allRelated: manage_*references -
GITLAB_DENIED_TOOLS_REGEXstrips matching Related references - Unit tests for
resolveRelatedReferences()pass (6+ cases) - Registry manager integration tests for dynamic resolution pass
- All existing description assertions updated and passing
-
docs/advanced/customization.mddocuments the behavior -
docs/public/llms.txtrefreshed with new wording -
yarn lintpasses -
yarn testpasses (unit tests)