Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "dacli"
version = "0.4.27"
version = "0.4.26"
description = "Documentation Access CLI - Navigate and query large documentation projects"
readme = "README.md"
license = { text = "MIT" }
Expand Down
2 changes: 1 addition & 1 deletion src/dacli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"""


__version__ = "0.4.27"
__version__ = "0.4.26"
14 changes: 9 additions & 5 deletions src/dacli/api/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,22 @@

# Mapping from internal element types to API types
ELEMENT_TYPE_TO_API = {
"plantuml": "diagram",
"admonition": "admonition",
"code": "code",
"table": "table",
"image": "image",
"list": "list",
"plantuml": "plantuml",
"table": "table",
}

# Reverse mapping from API types to internal types
API_TYPE_TO_ELEMENT = {
"diagram": ["plantuml"], # plantuml maps to diagram
"admonition": ["admonition"],
"code": ["code"],
"table": ["table"],
"image": ["image"],
"list": ["list"],
"plantuml": ["plantuml"],
"table": ["table"],
}


Expand Down Expand Up @@ -112,7 +116,7 @@ def search_content(request: SearchRequest) -> SearchResponse:
)
def get_elements(
type: str = Query(
description="Element type: diagram, table, code, list, image"
description="Element type: admonition, code, image, list, plantuml, table"
),
path: str | None = Query(
default=None,
Expand Down
4 changes: 2 additions & 2 deletions src/dacli/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pydantic import BaseModel, Field

# Valid element types for GET /elements endpoint
VALID_ELEMENT_TYPES = frozenset(["diagram", "table", "code", "list", "image"])
VALID_ELEMENT_TYPES = frozenset(["admonition", "code", "image", "list", "plantuml", "table"])


class LocationResponse(BaseModel):
Expand Down Expand Up @@ -119,7 +119,7 @@ class ElementLocation(BaseModel):
class ElementItem(BaseModel):
"""A single element in the response."""

type: str = Field(description="Element type (diagram, table, code, list, image)")
type: str = Field(description="Element type (admonition, code, image, list, plantuml, table)")
path: str = Field(description="Section path containing this element")
index: int = Field(description="Index of element within its section")
location: ElementLocation
Expand Down
2 changes: 1 addition & 1 deletion src/dacli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ def search(ctx: CliContext, query: str, scope: str | None, max_results: int):
""")
@click.argument("section_path", required=False, default=None)
@click.option("--type", "element_type", default=None,
help="Element type: code, table, image, diagram, list")
help="Element type: admonition, code, image, list, plantuml, table")
@click.option("--recursive", is_flag=True, default=False,
help="Include elements from child sections")
@click.option("--include-content", is_flag=True, default=False,
Expand Down
4 changes: 2 additions & 2 deletions src/dacli/mcp_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ def get_elements(
the documentation, such as code examples, tables, or diagrams.

Args:
element_type: Filter by type - 'code', 'table', 'image',
'diagram', 'list'. None returns all elements.
element_type: Filter by type - 'admonition', 'code', 'image',
'list', 'plantuml', 'table'. None returns all elements.
section_path: Filter by section path (e.g., '/architecture').
recursive: If True, include elements from child sections.
If False (default), only exact section matches.
Expand Down
2 changes: 1 addition & 1 deletion src/docs/50-user-manual/20-mcp-tools.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Get code blocks, tables, images, and other elements.
|===
| Parameter | Type | Default | Description

| `element_type` | string \| null | null | Filter by type: `code`, `table`, `image`, `diagram`, `list`
| `element_type` | string \| null | null | Filter by type: `admonition`, `code`, `image`, `list`, `plantuml`, `table`
| `section_path` | string \| null | null | Filter by section path
|===

Expand Down
4 changes: 2 additions & 2 deletions src/docs/spec/02_api_specification.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Represents a special element (table, code, diagram).
[source,json]
----
{
"type": "string", // "table" | "code" | "diagram" | "list" | "image"
"type": "string", // "admonition" | "code" | "image" | "list" | "plantuml" | "table"
"path": "string", // Path to containing section
"index": "integer", // Index within section
"location": "SectionLocation"
Expand Down Expand Up @@ -413,7 +413,7 @@ For `admonition` elements, it includes `admonition_type` and `content`.
"code": "INVALID_TYPE",
"message": "Unknown element type 'charts'",
"details": {
"valid_types": ["diagram", "table", "code", "list", "image"]
"valid_types": ["admonition", "code", "image", "list", "plantuml", "table"]
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/docs/spec/03_acceptance_criteria.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,10 @@ Feature: Filter elements by type
| table | 8 |
| code | 12 |

Scenario: Retrieve all diagrams
When I call GET /elements?type=diagram
Scenario: Retrieve all PlantUML diagrams
When I call GET /elements?type=plantuml
Then I receive HTTP Status 200
And the field "type" is "diagram"
And the field "type" is "plantuml"
And "count" is 5
And each element has a "path"
And each element has a "location"
Expand Down
9 changes: 4 additions & 5 deletions tests/test_content_access_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,13 @@ def test_get_table_elements(self, client: TestClient):
assert data["type"] == "table"
assert data["count"] == 2 # Two tables in fixture

def test_get_diagram_elements(self, client: TestClient):
"""Get diagram elements (mapped from plantuml)."""
response = client.get("/api/v1/elements?type=diagram")
def test_get_plantuml_elements(self, client: TestClient):
"""Get plantuml elements."""
response = client.get("/api/v1/elements?type=plantuml")
data = response.json()

assert response.status_code == 200
assert data["type"] == "diagram"
# plantuml type should map to diagram
assert data["type"] == "plantuml"
assert data["count"] == 1

def test_get_image_elements(self, client: TestClient):
Expand Down
77 changes: 77 additions & 0 deletions tests/test_elements_help_types_259.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Tests for Issue #259: elements help text lists incorrect element types.

The help text for `dacli elements --type` should list the actual valid types:
admonition, code, image, list, plantuml, table (not 'diagram').
"""

from pathlib import Path

import pytest
from click.testing import CliRunner

from dacli.cli import cli
from dacli.mcp_app import create_mcp_server


@pytest.fixture
def docs_dir(tmp_path: Path) -> Path:
"""Create minimal docs for testing."""
(tmp_path / "test.md").write_text("# Test\n\nContent.\n", encoding="utf-8")
return tmp_path


class TestElementsHelpTypes:
"""Test that element type help texts match actual valid types."""

VALID_TYPES = {"admonition", "code", "image", "list", "plantuml", "table"}

def test_cli_help_lists_correct_types(self, docs_dir: Path):
"""CLI help for elements should list all valid types including plantuml/admonition."""
runner = CliRunner()
result = runner.invoke(cli, ["--docs-root", str(docs_dir), "elements", "--help"])
assert result.exit_code == 0
# Should contain the correct types
assert "plantuml" in result.output
assert "admonition" in result.output
# Should NOT contain 'diagram' as a type
assert "diagram" not in result.output

def test_mcp_tool_docstring_lists_correct_types(self, docs_dir: Path):
"""MCP get_elements tool docstring should list correct types in Args section."""
mcp = create_mcp_server(docs_dir)
elements_tool = None
for tool in mcp._tool_manager._tools.values():
if tool.name == "get_elements":
elements_tool = tool
break
assert elements_tool is not None
docstring = elements_tool.fn.__doc__
# The Args section listing valid types should include the correct ones
assert "'plantuml'" in docstring
assert "'admonition'" in docstring
# The type listing should NOT contain 'diagram' as a quoted type
assert "'diagram'" not in docstring

def test_cli_accepts_plantuml_type(self, docs_dir: Path):
"""CLI should accept plantuml as a valid element type without warning."""
runner = CliRunner()
result = runner.invoke(
cli, ["--docs-root", str(docs_dir), "elements", "--type", "plantuml"]
)
assert "Warning" not in result.output

def test_cli_accepts_admonition_type(self, docs_dir: Path):
"""CLI should accept admonition as a valid element type without warning."""
runner = CliRunner()
result = runner.invoke(
cli, ["--docs-root", str(docs_dir), "elements", "--type", "admonition"]
)
assert "Warning" not in result.output

def test_cli_warns_on_diagram_type(self, docs_dir: Path):
"""CLI should warn when 'diagram' is used as element type."""
runner = CliRunner()
result = runner.invoke(
cli, ["--docs-root", str(docs_dir), "elements", "--type", "diagram"]
)
assert "Warning" in result.output
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading